Présentation Gypais

Bonjour à tous, initialement je cherchais une solution pour grapher l’humidité et déclencher un déshumidificateur …un raspberry et une sonde dth22 et voila … sauf que la sonde n’a pas aimé traverser la moitié du monde. Au lieu de recommander une sonde, j’ai acheter un sonoff TH qui fait nativement ce que je voulais, il ne restait plus qu’a grapher pour voir l’évolution sur plusieurs jour de mon % d’humidité. Après avoir été tenté par un flash en tasmota de mon sonoff, j’ai vu qu’on pouvait les piloter avec HA via sonoff-lan. J’ai donc repris mon raspberry et booté un HA. Tout ca marche très bien …et donc me voila en train de capitaliser sur HA.
Je ressorti de mon placard un vieux projet de graph de conso via teleinfo du compteur électrique. J’ai une carte qui n’existe plus : https://domogik-plugin-teleinfo.readthedocs.io/en/1.1/teleinfo.html mais qui marche !
une fois branché sur le raspberry et fait un peu de conf, j’arrive à voir les trames passer, mais impossible de trouver une conf pour extraire les valeurs des chaines caractères, sniff …
Pour illustrer le pb voici ce que je vois passer … https://photos.app.goo.gl/MWL85mJsYBZETqLs7 petite vidéo pour illustrer.
Voila ou j’en suis. Je vais poster mon pb dans la rubrique adéquate.
Bonne soirée.

1 « J'aime »

Bienvenue parmi nous ! :+1:

Bienvenu et bon amusement parmi nous

Pour ta carte si elle fonctionnait sous domogik tu peux la faire fonctionner sous nodered sans souci.
Je passe tout en mqtt via ce flow là:

[{"id":"c6d9a87b.f76598","type":"tab","label":"Teleinformation To mqtt in json","disabled":false,"info":""},{"id":"adb1266d.080eb","type":"serial in","z":"c6d9a87b.f76598","name":"/dev/ttyUSB0","serial":"c9aa239e.7fca1","x":90,"y":40,"wires":[["78e636e8.2b0f08","a1886994.1cbd78"]]},{"id":"1475494f.a32897","type":"function","z":"c6d9a87b.f76598","name":"toJSON","func":"function computeChecksum(etiquette, valeur) {\n    // Calcul de la checksum sur ce qu'on a reçu, on balaye tous les caractères\n\tvar sum = 32;\n  \tfor (i = 0; i < etiquette.length; i++) sum += etiquette.charCodeAt(i);\n  \tfor (i = 0; i < valeur.length; i++) sum += valeur.charCodeAt(i);\n \tsum = ((sum % 256) & 63) + 32;\n \treturn String.fromCharCode(sum);\n}\n\nvar payload = {\n    timestamp: new Date().getTime()\n};\n \n// Enlever les codes début et fin de trame\nvar lines = msg.payload.toString().replace(\"\\u0002\\n\", \"\").replace(\"\\r\\u0003\", \"\");\n \n// Récupérer chaque ligne une à une\nlines.split(\"\\r\\n\").forEach(line => {\n\n  \tnode.debug(`Ligne à décoder : ${line}`);\n  \t\n  \tvar groups = line.match(/^([^ ]+)\\s([^ ]+)\\s(.)$/i);\n  \t\n  \tif (groups === null) {\n  \t    node.warn(`Impossible de décoder la ligne '${line}'`);\n  \t} else {\n      \tvar etiquette = groups[1];\n      \tvar valeur = groups[2];\n      \tvar checksum = groups[3];\n      \t\n        var computedChecksum = computeChecksum(etiquette, valeur);\n     \n        // Checksum correcte ?\n        if (computedChecksum === checksum) {\n            \n            // Suppression des points en fin de chaîne (pour tout ce qui est période et option tarifaire)\n            valeur = valeur.replace(/\\.+$/g, '');\n            \n            // Si c'est une chaîne numérique, on la transforme en int\n            if (valeur.match(/^\\d+$/)) {\n                valeur = parseInt(valeur);\n            }\n    \n            node.debug(`Etiquette : ${etiquette} / Valeur : ${valeur}`);\n     \n            payload[etiquette] = valeur;\n    \t} else {\n    \t\tnode.warn(`Mauvais checksum pour la ligne '${line}'`);\n    \t}\n  \t}\n})\n\nreturn [{ payload }];","outputs":1,"noerr":0,"x":540,"y":40,"wires":[["fef36dab.9afe18","3bfdc49d.002ddc"]]},{"id":"3bfdc49d.002ddc","type":"debug","z":"c6d9a87b.f76598","name":"Debug payload","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":740,"y":100,"wires":[]},{"id":"fef36dab.9afe18","type":"mqtt out","z":"c6d9a87b.f76598","name":"","topic":"teleinfo","qos":"1","retain":"","broker":"b01df0f3.54d7d","x":720,"y":40,"wires":[]},{"id":"78e636e8.2b0f08","type":"delay","z":"c6d9a87b.f76598","name":"","pauseType":"queue","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"x":310,"y":40,"wires":[["1475494f.a32897"]]},{"id":"a1886994.1cbd78","type":"trigger","z":"c6d9a87b.f76598","name":"","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"500","extend":false,"units":"ms","reset":"","bytopic":"all","outputs":1,"x":300,"y":100,"wires":[[]]},{"id":"c9aa239e.7fca1","type":"serial-port","serialport":"/dev/ttyUSB0","serialbaud":"1200","databits":"7","parity":"even","stopbits":"1","waitfor":"0x2","newline":"0x3","bin":"false","out":"char","addchar":"","responsetimeout":"10000"},{"id":"b01df0f3.54d7d","type":"mqtt-broker","name":"mosquito","broker":"mosquito.poudot.fr","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Plus qu’a récupérer les topcis mqtt dans HA

Bonjour, je pensais que j’étais plus proche du but !
soit, j’ai commencé à regarder rednode, j’arrive bien a reformater les trames, mais à la fin du processus ça tombe sur du mqtt. Est-ce vraiment obligé ? on ne peut pas formater les trames sous la forme en json pour qu’elles soient directement compréhensibles par HA ?

J’ai bien essayé d’installer mosquitto, mais il crash au démarrage. Bon si vous me confirmez que c’est la seule voie pour avancer, je vais chercher de l’aide sur mon pb de démarrage de mqtt.
merci

Alors je pense que oui c’est faisable de parler la réponse json directement en élément ha.
Je ne sais pas faire par contre.
Et le mqtt sera à mon avis impératif a moyen long terme donc il faudra que tu résolves tes deux souci pour avancer correctement

Effectivement on peut se passer de mqtt, en finissant le flux par un node « entity », il faut faire un peut de conf en rajoutant un add-on node-red dans HA. Ça permet de créer un sensor.
Mais faut encore que je bataille avec le split de ma trame !

Tu me sembles sur la Bonne voie de tous les cas. Si tu n’y arrives pas refais signe je regarderai de plus prêt.

Salut, je bloque un peu, si je prends ton flux et que je replace le node mqtt en entity, je pensais être très proche, mais ça veux pas :
Entity API error. Error Message: expected bool for dictionary value @ data[‹ state ›]. Got {‹ timestamp ›: 1607636944980, ‹ ADCO ›: 31861579938, ‹ OPTARIF ›: ‹ HC ›, ‹ ISOUSC ›: 60, ‹ HCHC ›: 7467580, ‹ HCHP ›: 11166883, ‹ PTEC ›: ‹ HP ›, ‹ IINST ›: 3, ‹ IMAX ›: 90, ‹ PAPP ›: 620, ‹ HHPHC ›: ‹ A ›, ‹ MOTDETAT ›: 0}

et aussi à quoi sert le trigger ?
Merci.

Bonjour, je suis partir d’un autre code qui formatait déjà les sorties, j’ai juste rajouté le node entity.
Pb réglé !
Merci à tous.

Tu peux partager que je compare stp. Ça m’évitera de chercher si je veux changer :slight_smile:

et voila ma conf

[{"id":"735fffc.03b29","type":"tab","label":"HC HP","disabled":false,"info":""},{"id":"dc5193dd.31241","type":"function","z":"735fffc.03b29","name":"Structure payload","func":"function isNumeric(n) { \n      return !isNaN(parseFloat(n)) && isFinite(n); \n}\n\n// Pour tous les labels \nfor (var label in msg.payload ) {\n    var value = msg.payload[label];\n    \n\t// Correction des valeurs type string en numérique \t\t\n\tif (label == \"OPTARIF\")\t{\n  \t\t// L'option tarifaire choisie (Groupe \"OPTARIF\") est codée sur 4 caractères alphanumériques \n  \t\t// J'ai pris un nombre arbitraire codé dans l'ordre ci-dessous \n  \t\t// je mets le 4eme char à 0, trop de possibilités \n      \tvalue = value.substring(0, 3);\n    \n       \tif      (value==\"BAS\") value=1;// BASE => Option Base. \n  \t\telse if (value==\"HC.\") value=2;// HC.. => Option Heures Creuses. \n  \t\telse if (value==\"EJP\") value=3;// EJP. => Option EJP. \n  \t\telse if (value==\"BBR\") value=4;// BBRx => Option Tempo\n  \t\telse value = 0;\n  \t\t\n  \t\tmsg.payload[label] = value;\n\t} else if (label==\"HHPHC\") {\n      // L'horaire heures pleines/heures creuses (Groupe \"HHPHC\") est codé par un caractère A à Y \n      // J'ai choisi de prendre son code ASCII\n      msg.payload[label] = value.charCodeAt();\n    } else if ( label == \"PTEC\") {\n      // La période tarifaire en cours (Groupe \"PTEC\"), est codée sur 4 caractères \n      // J'ai pris un nombre arbitraire codé dans l'ordre ci-dessous\n      if      (value==\"TH..\") value= 1; // Toutes les Heures. \n      else if (value==\"HC..\") value= \"Heures Creuses\"; // Heures Creuses. \n      else if (value==\"HP..\") value= \"Heures Pleines\"; // Heures Pleines. \n      else if (value==\"HN..\") value= 4; // Heures Normales. \n      else if (value==\"PM..\") value= 5; // Heures de Pointe Mobile. \n      else if (value==\"HCJB\") value= 6; // Heures Creuses Jours Bleus. \n      else if (value==\"HCJW\") value= 7; // Heures Creuses Jours Blancs (White). \n      else if (value==\"HCJR\") value= 8; // Heures Creuses Jours Rouges. \n      else if (value==\"HPJB\") value= 9; // Heures Pleines Jours Bleus. \n      else if (value==\"HPJW\") value= 10;// Heures Pleines Jours Blancs (White). \n      else if (value==\"HPJR\") value= 11;// Heures Pleines Jours Rouges. \n      else value = 0;\n      \n      msg.payload[label] = value;\n    } else if ( label == \"IINST\") {\n        delete msg.payload.IINST;\n        msg.payload.IINST = Number(value)\n    } else if ( label == \"IMAX\") {\n        delete msg.payload.IMAX;\n        msg.payload.IMAX1 = Number(value);\n    } else if ( isNumeric(value) && label != \"ADCO\" ) {\n        // Transformer les valeurs numériques\n        msg.payload[label] = Number(value);\n    }\n}\n\n// Sauvegarde dans le contexte global\ncontext.global.teleinfo = msg.payload;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":650,"y":460,"wires":[["6ddb61d.7de3da","a7352aec.7cc578"]]},{"id":"a36e7648.2f6928","type":"serial in","z":"735fffc.03b29","name":"","serial":"3b2a542e.d3dabc","x":70,"y":460,"wires":[["310addc1.ff9122"]]},{"id":"25c2fa1d.b33cf6","type":"function","z":"735fffc.03b29","name":"valide trame","func":"// La trame complète est reçue dans 'msg'\nvar teleinfo={};\n\n// Enlever les codes début et fin de trame et récupérer les lignes 1 à 1\nvar lines = msg.payload.toString().replace(\"\\u0002\\n\",\"\").replace(\"\\r\\u0003\",\"\");\nlines = lines.split(\"\\r\\n\");\n\n// Pour chaque ligne\nfor (var line in lines) {\n\tvar i;\n  \tvar checksum = 32;\n  \t\n  \t// Recupérer le label, la valeur et la checksum\n  \t// si la checksum est un espace on le remplace par un caractère non \n  \t// autorisé en checksum (ici 's') pour eviter pb de split\n  \t// donc espace espace devient espace s\n\tvar myline = lines[line].toString().replace(\"  \",\" s\").split(\" \");\n\t\n\t// on dépile nos 3 valeurs\n\tvar check = myline.pop();\n\tvar value = myline.pop();\n\tvar label = myline.pop();\n\t\n\t// On peu repositionner la checksum à espace si c'était le cas\n\tif (check == \"s\") check = \" \";\n\n\t// Calcul de la checksum sur ce qu'on a reçu, on balaye tous les caractères\t\t\n  \tfor (i = 0; i < label.length; i++) checksum += label.charCodeAt(i);\n  \tfor (i = 0; i < value.length; i++) checksum += value.charCodeAt(i);\n \tchecksum = ((checksum%256) & 63) + 32;\n \tchecksum = String.fromCharCode(checksum);\n\t\n\t// Checksum correcte ?\n \tif (checksum == check ) {\n\t\tteleinfo[label] = value;\n\t} else {\n\t\tconsole.log(\"'%s' '%s' '%s' => Bad Checksum '%s'\", label, value, check, checksum );\n\t}\n}\nreturn [ { payload: teleinfo } ];","outputs":1,"noerr":0,"x":450,"y":460,"wires":[["dc5193dd.31241"]]},{"id":"6ddb61d.7de3da","type":"function","z":"735fffc.03b29","name":"IINST","func":"var IINST = msg.payload.IINST\n\nmsg.payload = IINST\nreturn msg;","outputs":1,"noerr":0,"x":870,"y":380,"wires":[["d6a59cbc.6ffb8"]]},{"id":"310addc1.ff9122","type":"delay","z":"735fffc.03b29","name":"","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"x":260,"y":460,"wires":[["25c2fa1d.b33cf6"]]},{"id":"a7352aec.7cc578","type":"function","z":"735fffc.03b29","name":"PTEC","func":"var PTEC = msg.payload.PTEC\n\nmsg.payload = PTEC\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":850,"y":540,"wires":[["7f876aa6.9480f4"]]},{"id":"7f876aa6.9480f4","type":"ha-entity","z":"735fffc.03b29","name":"sensor type heure","server":"3a242263.00b87e","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":""},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","x":1090,"y":540,"wires":[["e2e6c9ca.384758"]]},{"id":"d6a59cbc.6ffb8","type":"ha-entity","z":"735fffc.03b29","name":"sensor intensity inst","server":"3a242263.00b87e","version":1,"debugenabled":false,"outputs":1,"entityType":"sensor","config":[{"property":"name","value":""},{"property":"device_class","value":""},{"property":"icon","value":""},{"property":"unit_of_measurement","value":""}],"state":"payload","stateType":"msg","attributes":[],"resend":true,"outputLocation":"","outputLocationType":"none","inputOverride":"allow","x":1100,"y":380,"wires":[["cb09d9dc.120138"]]},{"id":"cb09d9dc.120138","type":"debug","z":"735fffc.03b29","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1260,"y":280,"wires":[]},{"id":"e2e6c9ca.384758","type":"debug","z":"735fffc.03b29","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":1300,"y":500,"wires":[]},{"id":"3b2a542e.d3dabc","type":"serial-port","serialport":"/dev/ttyUSB0","serialbaud":"1200","databits":"7","parity":"even","stopbits":"1","waitfor":"","newline":"0x3","bin":"false","out":"char","addchar":"","responsetimeout":"10000"},{"id":"3a242263.00b87e","type":"server","name":"Home Assistant","addon":true}]

donc tout ça sans mqtt !

1 « J'aime »