Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
Node RED : Creation dun Device dans HA
#1
Hello

Bon je vous avez dit que je débutais dans HA, mais c'est aussi le cas pour Node RED

Je suis en train de me faire une borne de charge pour mon VE avec un controleur Etek EKEPC2-S, si certains sont interessé, je pourrais ouvrir un autre post pour expliqué un peu le projet.

Ce controleur dispose d'une liaison RS485, on peut donc le piloter a distance et récupérer certaines infos.

Pour la partie Comm je passe par un petit module Ethernet/RS485 qui me permet d'interroger le controleur en Modbus TCP. 

Ca fonctionne , comme je découvre les bloc dans node red c'est pas évident au début...

Maintenant je voudrais récupérer les valeur sous HA

Je me dis que ca serrait bien de créer du coup un device dans lequel j'aurais les sensors et quelques objet pour contrôler la borne.

Du coup est-ce que quelqu'un sait comment on pourrait faire ? (C'est a priori possible, mais je n'ai pas vue d'exemple)
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#2
Je sais que ce n'est pas tout à fait l'endroit, mais, ne créerais tu pas un dossier HA vu que nous sommes je crois nombreux à utiliser Home Assistant où l'on pourrait y mettre nos découvertes et programmation non KNX.
Le dossier Configuration me semble pas réellement du KNX dans ton message. Même si je suis intéressé.
KNX aficionado

Répondre
#3
Citation :Je sais que ce n'est pas tout à fait l'endroit, mais, ne créerais tu pas un dossier HA vu que nous sommes je crois nombreux à utiliser Home Assistant où l'on pourrait y mettre nos découvertes et programmation non KNX.

Oui l'idée avait germé il y a quelques temps, mais je n'ai pas les droits pour le faire  Big Grin , faut que je relance qui de droit.  Tongue

Citation :Le dossier Configuration me semble pas réellement du KNX dans ton message. Même si je suis intéressé.
J'ai pas trop compris le sens de ton message, si c'est l'emplacement du sujet. j'ai mis ici dans la partie supervision car NodeRED / MQTT / HA sont intimement lié et c'est l'endroit le plus judicieux actuellement pour ca.
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#4
Bonjour

Pourquoi ne pas utiliser l'intégration Modbus de HA https://www.home-assistant.io/integrations/modbus/ ?

Autrement je ne voudrais pas m'attirer les foudres des administrateurs mais très bon forum francophone pour les questions vraiment HA: Hacf http://www.hacf.fr Wink

Vincèn
Répondre
#5
(12/08/2024, 16:35:59)vincen a écrit : Pourquoi ne pas utiliser l'intégration Modbus de HA https://www.home-assistant.io/integrations/modbus/ ?
Toutes les suggestion sont bonne, j'y avais jeté un coup d'oeil mais elle ne m'inspire pas cette intégration.

J'ai une table de 81 registres a lire. 
J'effectue 2 requête de lecture uniquement pour lire cette table. Ce qui permet d'avoir un refresh ultra rapide avec très peu de requete de communication.

Avec cette intégration, je peux me tromper mais a vue de nez si je veux lire le mot 89 et le mot 91, j'aurais déjà 2 requetes.


Je suis en train de regarder si en passant par MQTT ca pourrait pas le faire. Car j'ai vue des sujets de création de device provenant de donnée plublié sur MQTT.
Bon maintenant je me heurte a un autre problème, j'ai pas pris option Javascript  Cool , ca existait pas dans mon cursus scolaire  Big Grin

Je publie facilement mes tableau sur MQTT, mais pour le moment mes topic comportent uniquement des index numériques
   
Faut que je trouve un moyen pour itéré le tableau et en fonction des index de nommer le topic 

Voici la fonction NodeRED que j'utilise actuellement : 

Code PHP :
// Input : msg.payload should be an arnay [442, e, 440 e, e ]
// Define the base MQTT topic and starting index
const baseTopic "ETEK Chargeur 1"// Replace with your base MQTT topic
const startIndex 0// Replace with your desired starting index

// Iterate through the array and publish each value to a unique topic with a custom index
const values msg.payload;
const 
topics values.map((valueindex) => `${baseTopic}/HR${startIndex index}` );

const 
messages values.map((valueindex) => ({
 
   topictopics[index],
 
   payloadvalue.toString(), // Convert the value to a string
}));
return [
messages] ; 



(12/08/2024, 16:35:59)vincen a écrit : Autrement je ne voudrais pas m'attirer les foudres des administrateurs mais très bon forum francophone pour les questions vraiment HA: Hacf http://www.hacf.fr Wink
Pas de soucis, le problème c'est que je pars de loin dans plein de domaine (HA/MQTT/NodeRED/Javascript... ) et qu'il me manque plein de base et que je commence pas forcément par les truc les plus simple.
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#6
(12/08/2024, 16:30:06)filou59 a écrit :
Citation :Je sais que ce n'est pas tout à fait l'endroit, mais, ne créerais tu pas un dossier HA vu que nous sommes je crois nombreux à utiliser Home Assistant où l'on pourrait y mettre nos découvertes et programmation non KNX.

Oui l'idée avait germé il y a quelques temps, mais je n'ai pas les droits pour le faire  Big Grin , faut que je relance qui de droit.  Tongue

Citation :Le dossier Configuration me semble pas réellement du KNX dans ton message. Même si je suis intéressé.
J'ai pas trop compris le sens de ton message, si c'est l'emplacement du sujet. j'ai mis ici dans la partie supervision car NodeRED / MQTT / HA sont intimement lié et c'est l'endroit le plus judicieux actuellement pour ca.

Je voulais dire que l'on pourrait créer un répertoire spécifique Home Assitant différent de Logiciel libre(Link.....). Sinon toujours super le forum.
KNX aficionado

Répondre
#7
En parallèle de ce post, je suis en train de découvrir Modbus au travers de ma nouvelle installation photovoltaïque Huawei avec 2 onduleurs 10ktl M1 et une batterie Luna 15KwH. J'utilise l'intégration HA Huwei Solar, mais j'ai un décalage des valeurs d'énergie (en dehors des durées de mises à jour différentes) entre l'application FusionSolar de Huawei et les données transmises en Modbus par l'intégration Huwei Solar de HA.
Du coup j'aimerai trouver un utilitaire (si possible gratuit) pour interroger en Modbus directement les registres de Huawei afin de vérifier d'où viennent les discordances.
le module Modbus de HA serait-il la solution??
Où peut-être faut-il passer par les nodes de Node-Red.
A terme je pense utiliser le module KNX-Modbus de chez wiezhert, mais j'aimerai bien valider les données Modbus avant cela.
Répondre
#8
Ca tombe bien je viens de faire une liste d'outil , tu trouveras ton bonheur ici : https://domosimple.eu/forum/thread-820-p...ml#pid6553
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#9
Super je file regarder cela.
Répondre
#10
Je suis parti sur un piste avec open Modsim et la Vidéo. Je commence à voir des choses intéressantes, bien que pour l'instant en mode simulation.
Modsim semble fonctionner, par contre pas de connexion directe pour l'instant.
J'ai lancé Modbus sur Node-red mais je n'ai pas encore de lecture de ce qui se passe sur Modbus!!
il va falloir comprendre la notion de maitre et d'esclave!!
Répondre
#11
Pour en revenir a mes moutons et donc au sujet principal.

Je suis en train d'opter pour la solution suivante : Creation d'un Device via MQTT

En gros voici comment ce décompose le truc : 

1.[OK] Mon Device Modbus RTU : MaBornedeCharge (Branché en Ethernet avec un Adapateur EE11a Convertisseur Ethernet/RS485)
2.[OK]NodeRED : Interrogation du Module de charge via Liaison Modbus TCP.
3.[OK]NodeRED : Lecture des Registre de la Table Modbus
4.[TODO]NodeRED : Sauvegarde des Valeurs de Registre
5.[OK]NodeRED : Publication des Valeurs sur MQTT
6.[EnCours...]NodeRED : Surveillance MQTT (Subscriber)
6.[TODO]NodeRED : Ecriture des Registre de la Table Modbus (Sur Changement d'etat)
7.[EnCours...]HA : Creation d'un Device via fichier.yaml

Je sais pas comment faire :
8.Changer l'icone de mon Device (Là actuellement le Device a l'icone MQTT, ca m'énerve  Big Grin )




A la base le programe Lecture/Ecriture Modbus/MQTT pourrait être très simple. 
Mais ... il y a un mais.

Lorsqu'on lit les valeurs sur le Modbus, si on les publies sur MQTT, deriere vue que l'on est abonné a un Topic qu'on veut aussi pouvoir ecrire, celui-ci nous génére un message, si je ferme les yeux, du coup ca déclenche une ecriture sur le modbus dans mon device.  Angry

Et ca il faut clairement éviter. Car on ne sait pas comment le device va gérer ca. 
Si il est intelligent et que la valeur ne change pas il ne fera rien.
Dans le pire des cas ca fait une ecriture, et une écriture dans de la mémoire non volatile, suivant le type de mémoire et bien on peut rapidement cramer une puce. Certains fabriquants s'en sont déjà mordus les doigts.


Du coup il faut que je j'implémente un système d'ecriture "OnChange", je dois donc mémoriser la derniere valeur, et la comparer avec celle que je viens de recevoir. 
Sur le papier c'est pas compliqué quand on connait bien un  langage de prog, mais là je débute avec Node-RED et c'est pas forcément le truc le plus simple a faire pour débuter...

Du coup je me pose la question aussi de mon Publish vers MQTT, je peux éventuellement faire aussi pareil, un Publish OnChange ou un mix [OnChange ou OnDelay]
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#12
J'ai avancé (une peu lentement Rolleyes ) sur mon truc

1.[OK] Mon Device Modbus RTU : MaBornedeCharge (Branché en Ethernet avec un Adapateur EE11a Convertisseur Ethernet/RS485)
2.[OK]NodeRED : Lecture de Fichier CSV pour Charger le nom des Registre a Lire et leur Addresse
3.[OK]NodeRED : Interrogation du Module de charge via Liaison Modbus TCP.
4.[OK]NodeRED : Lecture des Registres de la Table Modbus
5.[OK]NodeRED : Sauvegarde des Valeurs de Registre dans Flow pour Comparaison Etat
6.[OK]NodeRED : Publication des Valeurs sur MQTT
7.[OK][/color]NodeRED : Surveillance MQTT (Subscriber)
8.[OK][/color]NodeRED : Ecriture des Registres de la Table Modbus (Sur Changement d'etat)
9.[EnCours...]HA : Creation d'un Device via fichier.yaml

Je sais pas comment faire :
8.Changer l'icone de mon Device (Là actuellement le Device a l'icone MQTT, ca m'énerve  Big Grin )

Je vais probablement intégrer la gestion de la charge directement dans NodeRED : 
  • Mode de Charge : Instantané, Arret, Heure Creuse
  • Courant de Charge Maxi 
Me reste après a voir comment fonctionne la régulation interne du controleur, car il peut adapter le courant de charge afin de ne pas dépasser un courant défini.


Ca ressemble a ca : 
[Image: attachment.php?aid=2687]

Bon au final je me suis retrouvé a faire pas mal de code en JS.
Pour une 1ere expérience, je suis content car j'y suis arrivé, mais non sans mal. Ca m'a pris pas mal de temps, pour différente raison, j'ai essayé de ne pas brulé les étapes en tentant d'apprendre et en commençant par les bases, mais quand on a un objectif d'application en tete on a vite tendance de prendre des raccourcis et d'aller droit au but.
J'ai donc fait un mix, un peu de base et qq raccourci  Big Grin

Beaucoup plus de temps donc que si j'avais ca directement dans mon automate WAGO.


Pièces jointes Miniature(s)
   
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#13
Pourrais-tu partager le code de ton flux??
De mon côté, je rame encore pour avoir un retour de données de mon onduleur Huawei en Modbus tcp
Répondre
#14
Bonjour,

Concernant l'icône tu peux mettre ce que tu veux ; un exemple pour mon portail avec deux images png différentes pour les positions Ouvert et fermé.

[Image: 52r0.jpg]
Répondre
#15
@Yves :
Je parle de cet icone :     

@richardpub:
Je te le mets dans quelques heures, je suis en train de faire quelques ajustement.
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#16
Le voici :

Il de la config dans L'environnement du Flow
Puis dans le BP de config

Ce flux nécessite normalement ca :
node-red-contrib-config
node-red-contrib-modbus

Si j'ai oublié une palette faite moi signe.

Code :
[{"id":"e6cc81bb1a8448d6","type":"tab","label":"Etek Modbus Array","disabled":false,"info":"","env":[{"name":"BASETOPIC","value":"ETEK_Borne_v5","type":"str"},{"name":"BASETOPIC_CMD","value":"ETEK_Borne_v4/cmnd/#","type":"str"},{"name":"STAT_TOPIC_DIR","value":"stat","type":"str"},{"name":"CMD_TOPIC_DIR","value":"cmnd","type":"str"}]},{"id":"84f321f0363d90e4","type":"group","z":"e6cc81bb1a8448d6","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["f8885cff676d7ee6","8c6ac4abd4a328c1","8d8597b1d87ddb58","7f2b930738fa68b6","a08f964816cfd9d4","b45d8b1d9be983a8","c50b5d1d4ba4d2c1"],"x":14,"y":499,"w":892,"h":202},{"id":"3232febd0ceac99d","type":"group","z":"e6cc81bb1a8448d6","name":"Disable","style":{"label":true,"color":"#ff0000"},"nodes":["1a4764f4.e619eb","380c5600.15f6fa","2739cc04.8cf06c","2d480aced01a8fa5","afa54b6ffd63ad40","ac9be6c17b8657ee","f8322fedf7e9f6c9","e99afac59d8e06af","517233ca62784742"],"x":14,"y":1019,"w":512,"h":382},{"id":"f649032686964af1","type":"group","z":"e6cc81bb1a8448d6","name":"","style":{"label":true},"nodes":["3ff7506e5ad0789c","be3b1c0048b672e5","2f6bc9d894bc0427","e1594cca2a7a0a37","09dd89bd0c2a40df","9492194fe0848524","98c5e3067de3010c","c904a7a5adc39119","c96b65adde138cc0","04ceca3d66c81c9a","0ef11b69d8d3f797","97ce823cd7b43492","81caa59d31738555","1bb49a267954922d","d56d60035690d41c","45a9e341dfa4ab56","b0041bd54123aecc","dae53049f2af714b"],"x":14,"y":159,"w":1112,"h":322},{"id":"78d43f17836ec011","type":"group","z":"e6cc81bb1a8448d6","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["c6b457795af6de41","ea1f48037a3dcf6b","fdf2322b9ae1cd47","5b232547fbfd20be"],"x":314,"y":19,"w":492,"h":122},{"id":"619fc7581fbfc0d3","type":"group","z":"e6cc81bb1a8448d6","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["65dbc8d5f97deae6","cc97bf6ee14d9e4e"],"x":14,"y":19,"w":272,"h":122},{"id":"b04f4bef237d1990","type":"group","z":"e6cc81bb1a8448d6","style":{"stroke":"#999999","stroke-opacity":"1","fill":"none","fill-opacity":"1","label":true,"label-position":"nw","color":"#a4a4a4"},"nodes":["d92c65a4.566478","4e4829e3.eaeae8","b3b077c4f4020a03","ec2e03fa9fb04f11","327e3bdb553df041","4ae7a7804e28c4ef","bff8878355ae4279","bc234ce34d75c054","d3d99b7769fe85b9"],"x":14,"y":719,"w":1072,"h":242},{"id":"3ff7506e5ad0789c","type":"debug","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"Tableau de Valeurs Recu","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":970,"y":260,"wires":[]},{"id":"380c5600.15f6fa","type":"switch","z":"e6cc81bb1a8448d6","d":true,"g":"3232febd0ceac99d","name":"","property":"payload","propertyType":"msg","rules":[{"t":"jsonata_exp","v":"($count(payload))=40","vt":"jsonata"},{"t":"jsonata_exp","v":"($count(payload))=41","vt":"jsonata"}],"checkall":"false","repair":false,"outputs":2,"x":90,"y":1160,"wires":[["1a4764f4.e619eb"],["2739cc04.8cf06c"]]},{"id":"1a4764f4.e619eb","type":"debug","z":"e6cc81bb1a8448d6","d":true,"g":"3232febd0ceac99d","name":"Reponse Pool1[40]","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":290,"y":1060,"wires":[]},{"id":"2739cc04.8cf06c","type":"debug","z":"e6cc81bb1a8448d6","d":true,"g":"3232febd0ceac99d","name":"Reponse Pool2[41]","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":290,"y":1120,"wires":[]},{"id":"be3b1c0048b672e5","type":"debug","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"Taille Tableau Recu","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"($count(payload))","targetType":"jsonata","statusVal":"($count(payload))","statusType":"auto","x":930,"y":200,"wires":[]},{"id":"2f6bc9d894bc0427","type":"comment","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"Lecture de Toute la Table du Controleur ETEK","info":"","x":220,"y":200,"wires":[]},{"id":"65dbc8d5f97deae6","type":"comment","z":"e6cc81bb1a8448d6","g":"619fc7581fbfc0d3","name":"Reset/Init Config Variable : ","info":"","x":150,"y":60,"wires":[]},{"id":"2d480aced01a8fa5","type":"function","z":"e6cc81bb1a8448d6","d":true,"g":"3232febd0ceac99d","name":"fct PrepareData1toMQTT v2","func":"// Input : msg.payload should be an arnay [442, e, 440 e, e ]\n// Define the base MQTT topic and starting index\nconst baseTopic = \"ETEK Chargeur v2\"; // Replace with your base MQTT topic\nconst ListTopics = [\n\t\"R86_OV_protection_value\", \n\t\"R87_UV_protection_value\", \n\t\"R88_Current_protection_value\",\n\t\"R89_Remote_start & stop\", \n\t\"R90_kWH_meter_voltage_A_phase_address\",\n\t\"R91_kWH_meter_voltage_B_phase_address\",\n\t\"R92_kWH_meter_voltage_C_phase_address\",\n\t\"R93_kWH_meter_current_address\",\n\t\"R94_kWH_meter_power_address\",\n\t\"R95_kWH_meter_electricity_using_address\",\n\t\"R96_DLB_using_kWH_meter_address\",\n\t\"R97_Spare\",\n\t\"R98_Spare\",\n\t\"R99_Spare\",\n\t\"R100_Device_address_No\",\n\t\"R101_DLB_resume_work_current_value\",\n\t\"R102_DLB_protection_current\",\n\t\"R103_Ref_current_value\",\n\t\"R104_Ref_current_AD_value\",\n\t\"R105_Spare\",\n\t\"R106_Spare\",\n\t\"R107_Spare\",\n\t\"R108_Spare\",\n\t\"R109_Charger_PWM_Max_value\",\n\t\"R110_RCMU_function_choose\",\n\t\"R111_RFID_function_choose_\",\n\t\"R112_Lock_function_choose_\",\n\t\"R113_Cable_Socket_version_choose\", \n\t\"R114_DLB_function_choose\",\n\t\"R115_PID_control_parameter_KP\",\n\t\"R116_PID_control_parameter_KI\",\n\t\"R117_PID_control_parameter_KD\",\n\t\"R118_Controller_ID_number\",\n\t\"R119_Controller_ID_number\",\n\t\"R120_Temperature_correction\",\n\t\"R121_Temperature_correction\",\n\t\"R122_Overtemperature_protection_value_of_stop\",\n\t\"R123_Overtemperature_protection_value_of_start\",\n\t\"R124_Frequency_correction\",\n\t\"R125_Duty_cycle_correction\"]\n\nconst startIndex = 0; // Replace with your desired starting index\n\n// Iterate through the array and publish each value to a unique topic with a custom index\nconst values = msg.payload;\nconst topics = values.map((value, index) => `${baseTopic}/${ListTopics[index]}` );\n\nconst messages = values.map((value, index) => ({\n\ttopic: topics[index],\n\tpayload: value.toString(), // Convert the value to a string\n}));\nreturn [messages] ;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":1200,"wires":[[]]},{"id":"afa54b6ffd63ad40","type":"function","z":"e6cc81bb1a8448d6","d":true,"g":"3232febd0ceac99d","name":"fct PrepareData1toMQTT v1","func":"// Input : msg.payload should be an arnay [442, e, 440 e, e ]\n// Define the base MQTT topic and starting index\nconst baseTopic = \"ETEK Chargeur v1\"; // Replace with your base MQTT topic\nconst startIndex = 0; // Replace with your desired starting index\n\n// Iterate through the array and publish each value to a unique topic with a custom index\nconst values = msg.payload;\nconst topics = values.map((value, index) => `${baseTopic}/HR${startIndex + index}` );\n\nconst messages = values.map((value, index) => ({\n    topic: topics[index],\n    payload: value.toString(), // Convert the value to a string\n}));\nreturn [messages] ;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":1160,"wires":[[]]},{"id":"e1594cca2a7a0a37","type":"debug","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"Read Sortie Bas (msg.value=array)","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":900,"y":360,"wires":[]},{"id":"09dd89bd0c2a40df","type":"debug","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"Read Sortie Haut (msg.payload=array)","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":930,"y":320,"wires":[]},{"id":"9492194fe0848524","type":"inject","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"1 Cycle","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":110,"y":240,"wires":[["04ceca3d66c81c9a"]]},{"id":"98c5e3067de3010c","type":"function","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"fct2 ModbusValuetoMQTT v6","func":"/* ----------------------------------------------------------------------------\nDescription : Genere les Messages MQTT a partir des Valeurs Modbus\n\n-Charge la liste des Topic en fonction du Pool Actif\n-Filtre Les Topic envoyé vers MQTT \n\t-SR : Single Read  (16bits)\n\t-SW : Single Write (16bits)\n\t-XX / Rien ou Autre : Disable\n-Genere le Topic MQTT en fonction de la list des Topic \n-Affecte la Valeur au topic\n\n----------------------------------------------------------------------------\nChangelog :\nv6 : \n-Utilisation des Variable d'environnement\n-Publication vers MQTT en mode Retain si Activé\n---------------------------------------------------------------------------- */\n\n//Lecture des Variable d'environnement du Flow\nconst sBaseTopic=env.get(\"BASETOPIC\");\t\t\t\t// ETEK_Borne_v4\nconst sStatTopicDir = env.get(\"STAT_TOPIC_DIR\");\t// stat\nconst sCmdTopicDir = env.get(\"CMD_TOPIC_DIR\");\t\t// cmnd\n\n\nconst bSendSRasRetain=flow.get('bSendSRasRetain');\nconst bSendSWasRetain=flow.get('bSendSWasRetain');\n\n//List des Topics a Envoyer sur MQTT\nlet aListTopics;\n// Recupere Le Pool Actif (Saved in fct1)\nlet sThisPool = msg.topic;\nswitch (sThisPool) {\n\tcase 'Pool1':\n\t\taListTopics=flow.get('aListTopicsPool1');\n\tbreak;\n\tcase 'Pool2':\n\t\taListTopics=flow.get('aListTopicsPool2');\n\tbreak;\n\tdefault:\n\t\tnode.status({fill:\"red\",shape:\"ring\",text:\"Nom de Pool Incorrect : msg.topic[\" + msg.topic + \"]\"});\n\t\treturn null;\t\t\t\n}\n\nlet values = msg.payload;\nlet messages = {};\n\nlet count = 0;\t//Nb de Message Envoyé vers MQTT\n\n// Si les Tailles sont différentes, on change le Status de la fct\nif (aListTopics.length===values.length) {\n\tlet result =  values.reduce(function(result, field, index) {\n\t\tresult[aListTopics[index]] = field;\n\n\t\tlet sThisTopic = `${sBaseTopic}/${sStatTopicDir}/${aListTopics[index]}`;\n\t\tif (aListTopics[index].substring(0,2)===\"SR\" || aListTopics[index].substring(0,2)===\"SW\"){\t\t\t\n\t\t\tcount=count+1;\n\t\t\tmessages.topic=sThisTopic;\n\t\t\tmessages.payload=field.toString();\n\t\t\t/*\n\t\t\tif (aListTopics[index].substring(0,2)===\"SR\" && bSendSRasRetain) { messages.retain = true;} \n\t\t\telse if (aListTopics[index].substring(0,2)===\"SW\" && bSendSRasRetain) { messages.retain = true;} \n\t\t\telse {messages.retain = false;}\n\t\t\t*/\n\t\t\tnode.send(messages);\t\n\t\t}\t\t\t \n\t\treturn result;\n\t}, {})\n\n\tflow.set('aLastModbus',result);\n\tnode.status({fill:\"green\",shape:\"dot\",text:\"Read=\" + values.length + \" ,Send2MQTT=\" + count});\n} else {\n\t//Erreur : Nb de Topic <> Nb de Valeur\n\tnode.status({fill:\"red\",shape:\"ring\",text:\"Nb Valeur Recu=[\" + values.length + \"]<> Tableau Defini[\" + aListTopics.length + \"]\"});\n\treturn null;\t\n}","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":240,"y":440,"wires":[["97ce823cd7b43492","c904a7a5adc39119"]],"info":"v5 : \r\n-Combine Tableau (Key+Valeur) pour retrouver Comparer les Valeur avant Ecrire\r\n-Enregistre les Valeur lu dans : flow.set('aLastModbus',result);\r\n\r\nTODO :\r\nLire le Tableau de Key depuis un Fichier plutot que d'avoir ca en Variable"},{"id":"c904a7a5adc39119","type":"mqtt out","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"Publish Modbus2MQTT","topic":"","qos":"0","retain":"false","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"56f17224.5234f4","x":530,"y":440,"wires":[]},{"id":"f8885cff676d7ee6","type":"debug","z":"e6cc81bb1a8448d6","g":"84f321f0363d90e4","name":"debug fct MQTT Decoder","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":750,"y":600,"wires":[]},{"id":"ac9be6c17b8657ee","type":"function","z":"e6cc81bb1a8448d6","d":true,"g":"3232febd0ceac99d","name":"fct v4","func":"const baseTopic = \"ETEK_Borne_v4\";\nconst SensorTopic = \"stat\";\nconst CmdTopic = \"cmnd\";\n\n//List des Topic a Envoyer sur MQTT\nvar ListTopics = [\n\t\"SR86_OV_protection_value\", \n\t\"SR87_UV_protection_value\", \n\t\"SR88_Current_protection_value\",\n\t\"SW89_Remote_start_stop\",\n\t\"XX90_JenVeuxPas\"];\n\nvar values = msg.payload;\nvar messages = {};\n//msg.payload = ListTopics;\n//msg.newrows = ListTopics;\n\nvar count = 0;\n\nvar result =  values.reduce(function(result, field, index) {\n\tresult[ListTopics[index]] = field;\n\treturn result;\n}, {})\n\nflow.set('aLastModbus',result);\n\nvalues.forEach((value, index) => {\n\tvar ThisTopic = `${baseTopic}/${ListTopics[index]}`;\n\t//const ThisTopic = topics[index];\n\tif (ListTopics[index].substring(0,2)===\"SR\" || ListTopics[index].substring(0,2)===\"SW\"){\n\t\tcount=count+1;\n\t\tmessages.topic=ThisTopic;\n\t\tmessages.payload=value.toString();\n\n\t\tnode.send(messages);\n\t}\n});\n\nnode.status({fill:\"green\",shape:\"dot\",text:\"Read=\" + values.length + \" ,Send2MQTT=\" +count});\n\n//msg.aCurrentValuewKey=result;\n\n//return msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":250,"y":1280,"wires":[[]]},{"id":"f8322fedf7e9f6c9","type":"function","z":"e6cc81bb1a8448d6","d":true,"g":"3232febd0ceac99d","name":"fct PrepareData1toMQTT v3","func":"// Input : msg.payload should be an arnay [26500,16500,120,2,65535,65535,65535,65535,65535,65535,65535,0,0,0,255,3500,4500,10000,1270,0,0,0,0,9000,3,3,1,1,1,10,80,1,0,0,1024,65456,850,1000,0,0]\n// Define the base MQTT topic and starting index\nconst baseTopic = \"ETEK Chargeur v3\"; // Replace with your base MQTT topic\nconst ListTopics = [\n\t\"R86_OV_protection_value\", \n\t\"E87_UV_protection_value\", \n\t\"R88_Current_protection_value\",\n\t\"E89_Remote_start_stop\",\n\t\"XX\"]\n\n// Iterate through the array and publish each value to a unique topic with a custom index\nconst values = msg.payload;\nconst messages = [];\nvar LenValues = values.length;\n// Si les Tailles sont différentes, on change le Status de la fct\nif (ListTopics.length === LenValues) {\n\t//On a le même Nombre de Valeur que de Topic\n\tnode.status({fill:\"green\",shape:\"dot\",text:\"OK\"});\n\tvalues.forEach((value, index) => {\n\t\tconst ThisTopic = `${baseTopic}/${ListTopics[index]}`;\n\t\t//const ThisTopic = topics[index];\n\t\tif (ListTopics[index].substring(0,1)===\"E\" ){\n\t\t\tmessages.push({\n\t\t\t\ttopic: ThisTopic,\n\t\t\t\tpayload: value.toString()});\n\t\t}\n\t});\n\treturn [messages];\n} else {\n\t//Erreur : Nb de Topic <> Nb de Valeur\n\tnode.status({ fill: \"red\", shape: \"ring\", text: \"Nb Valeur Recu=[\" + LenValues + \"]<> Tableau Defini[\" + ListTopics.length + \"]\"});\n\treturn null;\t\n}\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":1240,"wires":[[]]},{"id":"8c6ac4abd4a328c1","type":"mqtt in","z":"e6cc81bb1a8448d6","g":"84f321f0363d90e4","name":"MQTT Subscrib Cmd","topic":"$(BASETOPIC_CMD)","qos":"2","datatype":"auto-detect","broker":"56f17224.5234f4","nl":false,"rap":true,"rh":0,"inputs":0,"x":140,"y":600,"wires":[["7f2b930738fa68b6","a08f964816cfd9d4"]]},{"id":"8d8597b1d87ddb58","type":"debug","z":"e6cc81bb1a8448d6","g":"84f321f0363d90e4","name":"debug complete msg","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":740,"y":540,"wires":[]},{"id":"7f2b930738fa68b6","type":"function","z":"e6cc81bb1a8448d6","g":"84f321f0363d90e4","name":"MQTT Decoder and Modbus Encoder","func":"/* ----------------------------------------------------------------------------\nDescription : Recupere les Publish From MQTT et Envoi vers Modbus si Changement de Valeur \n\nTODO : A Paufiner en cas d'echec de certains test\n---------------------------------------------------------------------------- */\n\nconst bDefaultWriteIfNoLastValue=false;  // Action a Faire si Ancienne Value Non Dispo (Ne Doit pas Arriver)\n\n// Example input message\n// msg.topic:ETEK_Borne_v4/cmnd/SW89_Remote_start_stop\n// msg.payload: 2\n\n//var sBaseTopic=flow.get('sBaseTopic') || \"\";\n//Lecture des Variable d'environnement du Flow\nconst sBaseTopic=env.get(\"BASETOPIC\");\t\t\t\t// ETEK_Borne_v4\nconst sStatTopicDir = env.get(\"STAT_TOPIC_DIR\");\t// stat\nconst sCmdTopicDir = env.get(\"CMD_TOPIC_DIR\");\t\t// cmnd\n\nlet sRegNumber = \"\";\n// Check if the topic matches the expected format for Holding Registers\nif (msg.topic.startsWith(sBaseTopic +\"/\" + sCmdTopicDir)) {\n    // Find Register Type \n    let PosTypeReg = msg.topic.indexOf(\"SW\");\n    \n    if (PosTypeReg > 0)  {\n        //Recherche \"_\" après le Type Registre\n        let PosEndAddr = msg.topic.indexOf(\"_\",PosTypeReg);\n        if (PosEndAddr>0) {\n            sRegNumber = msg.topic.substring(PosTypeReg+2,PosEndAddr);\n            //node.status({fill:\"green\",shape:\"ring\",text:\"RegNumber=[\" + sRegNumber + \"], PosTypeReg= [\" + PosTypeReg + \"], PosEndAddr= [\" + PosEndAddr + \"]\"});\n        }\n    }    \n    // GetRegisterName\n    let LenFullTopic = msg.topic.length;\n    let LenRegisterName= (LenFullTopic-PosTypeReg);\n    let sRegisterName = msg.topic.substring(PosTypeReg,LenFullTopic);\n    // Extract the value from the payload\n    let value = msg.payload;\n    // Convert String to Int\n    let iRegNumber = parseInt(sRegNumber,10);\n\n    //Compare ActualValue with aLastModbus\n\n    // Load Tableau des Dernieres Valeur si il existe\n    let aLastModbus=flow.get('aLastModbus') || {};\n\n    let bMbWriteNeeded = false; //Est-ce qu'il faut Faire un Write ?\n\n    let aLastModbusSize=Object.keys(aLastModbus).length; \n    if (aLastModbusSize>0) {\n        //La variable aLastModbus exist et contient au moins 1 Valeur\n\n        let bLastValueExist=aLastModbus.hasOwnProperty(sRegisterName);\n        if (bLastValueExist) {\n            // On a déjà Stocké une Valeur, on la Compare pour savoir si il faut faire un ModbusWrite            \n            if (aLastModbus[sRegisterName] != value) {\n                //Si la Derniere Valeur est Différente on fait un MB Write\n                bMbWriteNeeded=true;\n                node.status({ fill: \"green\", shape: \"dot\", text: \"Size of aLastModbus=\" + aLastModbusSize + \" ,RegName=\" + sRegisterName + \" ,Last=\" + aLastModbus[sRegisterName] + \"!= Current=\" + value + \", LastValueExist=\" + bLastValueExist});\n            }\n        } else {\n            // On a pas d'ancienne valeur\n            bMbWriteNeeded=bDefaultWriteIfNoLastValue;            \n        }\n    } else {\n        node.status({fill:\"red\",shape:\"ring\",text:\"La variable aLastModbus N'existe pas\"});\n    }\n\n    // Construct the message for the Modbus write node\n    msg.payload = {\n        value: value, // Wrap the value in an array\n        'fc': 6, // Function Code 16 (write multiple registers)\n        'unitid': flow.get('iUnitID'), // Modbus slave ID, adjust as necessary\n        'address': iRegNumber, // Register number\n        'quantity': 1, // Quantity is always 1\n        'PosTypeReg': PosTypeReg,\n        'LenFullTopic': LenFullTopic,\n        'LenRegisterName': LenRegisterName,\n        'sRegisterName': sRegisterName,\n        aLastModbus: aLastModbus,\n        'aLastModbusSize': aLastModbusSize\n    };\n    //node.status({fill:\"green\",shape:\"ring\",text:\"RegNumber=[\" + sRegNumber + \"], Valeur = [\" + value + \"]\"});\n} else {\n    // If the topic doesn't match any expected format, log an error and return null\n    node.error(\"Invalid topic format. Expected format: '\" + sBaseTopic + \"/cmnd/SW<number>'\");\n    return null; // Abort further processing\n}\n\n// Output the message\nreturn msg;\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":600,"wires":[["8d8597b1d87ddb58","f8885cff676d7ee6","b45d8b1d9be983a8"]]},{"id":"b45d8b1d9be983a8","type":"modbus-flex-write","z":"e6cc81bb1a8448d6","g":"84f321f0363d90e4","name":"","showStatusActivities":false,"showErrors":false,"showWarnings":true,"server":"ecdc236fcc845883","emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":730,"y":660,"wires":[[],[]]},{"id":"a08f964816cfd9d4","type":"debug","z":"e6cc81bb1a8448d6","g":"84f321f0363d90e4","name":"Subscriber MQTT debug payload ","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload ","targetType":"msg","statusVal":"","statusType":"auto","x":440,"y":540,"wires":[]},{"id":"cc97bf6ee14d9e4e","type":"config","z":"e6cc81bb1a8448d6","g":"619fc7581fbfc0d3","name":"","properties":[{"p":"iUnitID","pt":"flow","to":"1","tot":"num"},{"p":"iCurrentPoolNumber","pt":"flow","to":"1","tot":"num"},{"p":"bEnableAutoRepeat","pt":"flow","to":"true","tot":"bool"},{"p":"iNumberOfPool","pt":"flow","to":"2","tot":"num"},{"p":"bSendSRasRetain","pt":"flow","to":"false","tot":"bool"},{"p":"bSendSWasRetain","pt":"flow","to":"true","tot":"bool"},{"p":"bEnableAutoChangePool","pt":"flow","to":"true","tot":"bool"}],"active":true,"x":110,"y":100,"wires":[]},{"id":"c96b65adde138cc0","type":"modbus-flex-getter","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"","showStatusActivities":false,"showErrors":false,"showWarnings":true,"logIOActivities":false,"server":"ecdc236fcc845883","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"keepMsgProperties":false,"delayOnStart":false,"startDelayTime":"","x":660,"y":240,"wires":[["be3b1c0048b672e5","09dd89bd0c2a40df","81caa59d31738555","3ff7506e5ad0789c"],["e1594cca2a7a0a37"]]},{"id":"04ceca3d66c81c9a","type":"function","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"fct1 Select Pool1 or Pool2","func":"/* ----------------------------------------------------------------------------\nDescription : Defini la Requete Modbus en fonction du N° Pool Actif\n\n-Défini l'adresse de début\n-Défini la quantité de Mot a lire\n\nLe N° du Pool actif est récupéré dans la variable : iCurrentPoollNumber (flow)\n---------------------------------------------------------------------------- */\n\nlet iAddress=0;     //Address Modbus\nlet iQuantity=0;    //Nd de Mot a Lire\nlet iCurrentPoolNumber=flow.get('iCurrentPoolNumber');    //N° du Pool\n\nswitch (iCurrentPoolNumber) {\n    case 1:\n        // Pool N°1\n        iAddress=86;\n        iQuantity=40;\n        break;\n    case 2:\n        // Pool N°2\n        iAddress=126;\n        iQuantity=41;\n        break;\n    default:\n        //Error\n        node.status({fill: \"red\", shape: \"ring\", text: \"Error Pool undedined\"});\n        return null;\n};\n\nmsg.payload = { \n    value: msg.payload, \n    'fc': 3, \n    'unitid': flow.get('iUnitID'), \n    'address': iAddress , \n    'quantity': iQuantity,\n    'iCurrentPoollNumber' :iCurrentPoolNumber\n};\nnode.status({\n    fill: \"green\", shape: \"dot\", \n    text: \"Pool N°\" + iCurrentPoolNumber + \n        \" ,FC:3, unitid=\" + flow.get('iUnitID') +\n        \" ,address=\" + iAddress +\n        \" ,quantity=\" + iQuantity\n    });\n\n//Défini le Pool actif (Utilisé par fct2) pr Savoir d'ou Vient la Reponse\nmsg.topic = \"Pool\" + iCurrentPoolNumber;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":240,"wires":[["0ef11b69d8d3f797","c96b65adde138cc0"]]},{"id":"0ef11b69d8d3f797","type":"debug","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"debug fct1","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":710,"y":200,"wires":[]},{"id":"97ce823cd7b43492","type":"debug","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"fct2 PublishModbus2MQTT","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":540,"y":400,"wires":[]},{"id":"81caa59d31738555","type":"link out","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"link out MbRead","mode":"link","links":["d56d60035690d41c"],"x":825,"y":280,"wires":[]},{"id":"1bb49a267954922d","type":"function","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"fct3 AutoRepeat Pool (& NextPool)","func":"/* ----------------------------------------------------------------------------\nDescription : Ative le Pool Suivant / Declenche le Cycle Suivant si AutoRepeat=true\n\n---------------------------------------------------------------------------- */\n\n//Bascule sur le Pool Suivant\nlet iCurrentPoolNumber=flow.get('iCurrentPoolNumber');\nlet iNumberOfPool=flow.get('iNumberOfPool');\n\n//Changement Automatique de Pool (False: Pour le Debuggage)\nlet bEnableAutoChangePool=flow.get('bEnableAutoChangePool');\nif (bEnableAutoChangePool) {\niCurrentPoolNumber=iCurrentPoolNumber+1;\nif (iCurrentPoolNumber>iNumberOfPool) {\n    iCurrentPoolNumber=1;\n}\nflow.set('iCurrentPoolNumber',iCurrentPoolNumber);\n}\n\n//Lance le Prochain Cycle si bEnableAutoRepeat=true\nlet bEnableAutoRepeat=flow.get('bEnableAutoRepeat');\nif (bEnableAutoRepeat) {\n    node.status({fill: \"green\", shape: \"dot\", text: \"AutoRepeat=ON, NextPool=\"+iCurrentPoolNumber + \",NbPool=\"+ iNumberOfPool});\n    return msg;\n} else {\n    //node.status({fill: \"grey\", shape: \"ring\", text: \"AutoRepeat=OFF\"});\n    node.status({fill: \"grey\", shape: \"dot\", text: \"AutoRepeat=OFF, NextPool=\"+iCurrentPoolNumber + \",NbPool=\"+ iNumberOfPool});\n    return null;\n}\n\n\n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":360,"wires":[["dae53049f2af714b"]]},{"id":"d56d60035690d41c","type":"link in","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"link in fct3 AutoRepeat","links":["81caa59d31738555"],"x":65,"y":360,"wires":[["1bb49a267954922d","98c5e3067de3010c"]]},{"id":"c50b5d1d4ba4d2c1","type":"comment","z":"e6cc81bb1a8448d6","g":"84f321f0363d90e4","name":"Modbus Write OnChange","info":"A la reception d'un Publish depuis MQTT\n\nDecodage du Registre\nWrite OnChange vers Modbus","x":150,"y":540,"wires":[]},{"id":"c6b457795af6de41","type":"inject","z":"e6cc81bb1a8448d6","g":"78d43f17836ec011","name":"Set Pool N°1","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"1","payloadType":"num","x":430,"y":60,"wires":[["ea1f48037a3dcf6b"]]},{"id":"ea1f48037a3dcf6b","type":"change","z":"e6cc81bb1a8448d6","g":"78d43f17836ec011","name":"","rules":[{"t":"set","p":"iCurrentPoolNumber","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":660,"y":100,"wires":[[]]},{"id":"fdf2322b9ae1cd47","type":"inject","z":"e6cc81bb1a8448d6","g":"78d43f17836ec011","name":"Set Pool N°2","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"2","payloadType":"num","x":430,"y":100,"wires":[["ea1f48037a3dcf6b"]]},{"id":"5b232547fbfd20be","type":"comment","z":"e6cc81bb1a8448d6","g":"78d43f17836ec011","name":"Manu Set Pool Number","info":"","x":640,"y":60,"wires":[]},{"id":"d92c65a4.566478","type":"inject","z":"e6cc81bb1a8448d6","g":"b04f4bef237d1990","name":"Init","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"2","topic":"","payload":"","payloadType":"date","x":110,"y":800,"wires":[["4e4829e3.eaeae8"]]},{"id":"4e4829e3.eaeae8","type":"file in","z":"e6cc81bb1a8448d6","g":"b04f4bef237d1990","name":"","filename":"C:\\Users\\Pierre\\.node-red/TableEKEPC2 - Pool1.csv","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"utf8","allProps":false,"x":380,"y":800,"wires":[["ec2e03fa9fb04f11","4ae7a7804e28c4ef"]]},{"id":"b3b077c4f4020a03","type":"comment","z":"e6cc81bb1a8448d6","g":"b04f4bef237d1990","name":"Read CSV File (Pool1 & 2)","info":"","x":150,"y":760,"wires":[]},{"id":"ec2e03fa9fb04f11","type":"debug","z":"e6cc81bb1a8448d6","g":"b04f4bef237d1990","name":"debug Read CSV File","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":740,"y":760,"wires":[]},{"id":"4ae7a7804e28c4ef","type":"function","z":"e6cc81bb1a8448d6","g":"b04f4bef237d1990","name":"fct0 CSV to Array","func":"/* ---------------------------------------------------------------\nDescription : Converti le Contenu du Fichier CSV dans un Array\n\nOutput 1: Permet de lancer la Lecture du Pool N°2\nOutput 2: Permet de lancer le 1er Cycle de Lecture sur le Modbus\n--------------------------------------------------------------- */\n\n// Load CSV File Result to String\nlet str = msg.payload;\n\n// Load String (with Separator \\n) to Array\nlet aListTopics = str.split(\"\\n\");\n\nmsg.payload ={value:aListTopics};\nif (msg.filename.indexOf(\"Pool1\")>0) {\n\t//Read Pool1\n\tflow.set('aListTopicsPool1',aListTopics);\n    node.status({fill: \"green\", shape: \"dot\", text: \"Read OK Pool1\"});\n\t\n\treturn [msg,null];\n} else if (msg.filename.indexOf(\"Pool2\")>0) {\n\tflow.set('aListTopicsPool2',aListTopics);\n    node.status({fill: \"green\", shape: \"dot\", text: \"Read OK Pool2\"});\n\treturn [null,msg];\n} else {\n\tnode.status({fill: \"red\", shape: \"dot\", text: \"Error Read\"});\n\treturn [null,null];\n}\n\n","outputs":2,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":840,"wires":[["bff8878355ae4279","327e3bdb553df041"],["bc234ce34d75c054","bff8878355ae4279"]]},{"id":"bff8878355ae4279","type":"debug","z":"e6cc81bb1a8448d6","g":"b04f4bef237d1990","name":"debug CSV to Array","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":940,"y":800,"wires":[]},{"id":"327e3bdb553df041","type":"file in","z":"e6cc81bb1a8448d6","g":"b04f4bef237d1990","name":"","filename":"C:\\Users\\Pierre\\.node-red/TableEKEPC2 - Pool2.csv","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"utf8","allProps":false,"x":380,"y":840,"wires":[["4ae7a7804e28c4ef","ec2e03fa9fb04f11"]]},{"id":"bc234ce34d75c054","type":"link out","z":"e6cc81bb1a8448d6","g":"b04f4bef237d1990","name":"link out fct0 CSV to Array","mode":"link","links":["45a9e341dfa4ab56"],"x":865,"y":840,"wires":[]},{"id":"45a9e341dfa4ab56","type":"link in","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"link in fct0 CSV to Array","links":["bc234ce34d75c054"],"x":385,"y":300,"wires":[["04ceca3d66c81c9a"]]},{"id":"b0041bd54123aecc","type":"comment","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"Start Cycle after ofLoad CSVFile (On Init)","info":"","x":200,"y":300,"wires":[]},{"id":"dae53049f2af714b","type":"delay","z":"e6cc81bb1a8448d6","g":"f649032686964af1","name":"","pauseType":"delay","timeout":"1000","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":500,"y":340,"wires":[["04ceca3d66c81c9a"]]},{"id":"e99afac59d8e06af","type":"function","z":"e6cc81bb1a8448d6","d":true,"g":"3232febd0ceac99d","name":"fct Load Array of Topic (Tst)","func":"//Input from Modbus Flex Getter Ouput1\n\nlet aCurrentListOfTopic;\nlet sThisPool = msg.topic;\nswitch (sThisPool) {\n\tcase 'Pool1':\n\t\taCurrentListOfTopic=flow.get('aListTopicsPool1');\n\tbreak;\n\tcase 'Pool2':\n\t\taCurrentListOfTopic=flow.get('aListTopicsPool2');\n\tbreak;\n}\n\nmsg.payload = {\n        value: msg.payload, // Wrap the value in an array\n        aCurrentListOfTopic: aCurrentListOfTopic\n}\n\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":320,"y":1320,"wires":[["517233ca62784742"]]},{"id":"517233ca62784742","type":"debug","z":"e6cc81bb1a8448d6","d":true,"g":"3232febd0ceac99d","name":"debug fct Load Array of Topic","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":350,"y":1360,"wires":[]},{"id":"d3d99b7769fe85b9","type":"comment","z":"e6cc81bb1a8448d6","g":"b04f4bef237d1990","name":"Les Fichiers CSV doivent être au format Linux (LF)","info":"**Le format Windows CR LF n'est pas géré**","x":370,"y":920,"wires":[],"icon":"node-red/alert.svg"},{"id":"56f17224.5234f4","type":"mqtt-broker","name":"MQTT Pierre 192.168.20.5","broker":"192.168.20.5","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"autoUnsubscribe":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"ecdc236fcc845883","type":"modbus-client","name":"MB Slave P17","clienttype":"tcp","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"failureLogEnabled":true,"tcpHost":"127.0.0.1","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"0x3A","unit_id":"1","commandDelay":"1","clientTimeout":"1000","reconnectOnTimeout":true,"reconnectTimeout":"2000","parallelUnitIdsAllowed":true,"showErrors":false,"showWarnings":true,"showLogs":true}]
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#17
Je n'arrive pas à installer les nodes :
Flows stopped due to missing node types.

  • ioBroker out

  • ioBroker in

  • config
Faut-il passer par npm?? Je ne les trouve pas dans la palette pour les installer.


Sinon comme toi je cherche à rester simple avant d'aller plus loin.
Pour l'instant, je reste bloqué pour me connecter en Modbus à mon Dongle des onduleurs Huawei.
Je cherche à simplifier la connexion maximum en pouvoir interroger les adresses des enregistrements modbus défini par Huawei.
Répondre
#18
J'avais indiqué les dépendances pourtant  Big Grin

Citation :Ce flux nécessite normalement ca :
node-red-contrib-config
node-red-contrib-modbus


Tu dois installer la palette : node-red-contrib-config
Dans le menu a droite.

Après tu peux le faire aussi par npm, mais tu devras peu etre redémarrer NodeRED
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#19
J'ai tenté et j'ai planté mon conteneur.
Je vais faire pose et je reprend demain.
Bonne soirée
Répondre
#20
Ton Conteneur c'est quoi Docker ou LXC ?

Tu as fait quoi pour le planter ?

C'est conteneur qui fait quoi : que NodeRED ?
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#21
C'est un conteneur LXC avec uniquement Node-red. Comme j'étais planté, J'ai restauré le dernière sauvegarde fiable et là, le CT à disparu de proxmox. Jamais eu cela!!
Répondre
#22
Quand tu dis planté, c'est Node-RED qui était planté je supose ?
Pas le LXC ?

Si tu crées un Flow et qu'il provoque une erreur lors du déploiement, NodeRed va planter en permanence.
Dans ce cas il faut le lancer en mode secours : "SAFE MODE"

Node-RED redevient accessible mais les noeuds ne sont pas déployé.
Auparavant il vaut mieux consulté les log pour voir d'ou vient lerreur, pour ensuite corriger ou supprimer le truc qui bloque.

Ensuite on relancer Node RED en mode normal.
KNX Partner Base / Avancé

Ma boite de MP est pleine, merci de créer un post si vous avez une question, cela profitera a tout le monde.
Répondre
#23
Malheureusement c'est le conteneur qui après restauration (qui s'est mise en erreur en cours de route) de la dernière version stable a planté, et  a disparu de de mes conteneurs disponibles.

Heureusement pas trop de chose dedans juste des versions de test de modbus et de KNX Ultimate
Répondre


Atteindre :


Utilisateur(s) parcourant ce sujet :