Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
Node RED : Creation dun Device dans HA
#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


Messages dans ce sujet
Node RED : Creation dun Device dans HA - par filou59 - 12/08/2024, 14:46:23
RE: Node RED : Creation dun Device dans HA - par filou59 - 22/08/2024, 00:45:15

Atteindre :


Utilisateur(s) parcourant ce sujet : 7 visiteur(s)