In order to prepare the data to be accepted by Domoticz, I modified the function node slightly.
1. I removed the obsolete elements of the array (Inverter ID B and the date/time stamp, as we will use the Domoticz date/time).
2. Deleted the "-A" after the Inverter ID.
3. Removed all the "Units" after the value, such as: W, Hz, V,
oC.
This creates a shorter array and is better suitable for Domoticz.
- Screenshot_APS-NodeRed-5.png (43.05 KiB) Viewed 1654 times
Please find the code below:
Code: Select all
var i;
for (i = 0; i < msg.payload.length/9; i++) {
var InverterIDA = msg.payload[9*i+0];
var CurrentPowerA = msg.payload[9*i+1];
var GridFreq = msg.payload[9*i+2];
var GridVoltageA = msg.payload[9*i+3];
var GridTemp = msg.payload[9*i+4];
var GridReportTime = msg.payload[9*i+5];
var InverterIDB = msg.payload[9*i+6];
var CurrentPowerB = msg.payload[9*i+7];
var GridVoltageB = msg.payload[9*i+8];
newMsg = {payload: ([InverterIDA.substr(0,12),CurrentPowerA.substr(0,1),GridVoltageA.substr(0,3),CurrentPowerB.substr(0,1),GridVoltageB.substr(0,3),GridFreq.substr(0,4),GridTemp.substr(0,2)])}
node.send(newMsg);
}
As earlier mentioned I suggested the following:
I suggest the following flow:
- inject node with 5 minute tick (can be faster, up to you), followed by timer node.
- timer node (moment), which will pass the flow (5 min. tick) between 30 minutes before sunrise until 30 minutes after sunset). It is useless to poll the inverters at night.
- next node will be the http request node, to poll the (local) url.
- html node to sort the received data.
- function node to prepare the data for domoticz.
- the last node will be mqtt-out to domoticz/in.
After studying the details I have decided not to use 1 function node, but 2. So we will have 7 nodes in the flow (beside optionally "debug" nodes).
The first function node is only used for handling the data, received from the web page and put it in an array.
The advantage is that:
- If the manufacturer (AP Systems) decides to change/update the web page, it only is necessary to do the changes in the first "function" node.
- This node can be untouched, regardless of the number of inverters and/or solar panels.
The second function node contains the conversion from the array to the suitable Domoticz commands.
The results you see below:
- Screenshot_APS-NodeRed-7.png (47.69 KiB) Viewed 1654 times
The result for the first inverter is shown.
See the code below:
Code: Select all
var msg1 = {};
var msg2 = {};
var msg3 = {};
var msg4 = {};
var msg5 = {};
var msg6 = {};
switch (msg.payload[0]) {
case "404000191265": //Inverter 1
msg1.payload = {"command":"udevice","idx":1001,"nvalue":0,"svalue":(msg.payload[1] + ";0")}; //Current Power A
msg2.payload = {"command":"udevice","idx":1002,"nvalue":0,"svalue":(msg.payload[2])}; //Voltage A
msg3.payload = {"command":"udevice","idx":1003,"nvalue":0,"svalue":(msg.payload[3] + ";0")}; //Current Power B
msg4.payload = {"command":"udevice","idx":1004,"nvalue":0,"svalue":(msg.payload[4])}; //Voltage B
msg5.payload = {"command":"udevice","idx":1005,"nvalue":0,"svalue":(msg.payload[5])}; //Frequency
msg6.payload = {"command":"udevice","idx":1006,"nvalue":0,"svalue":(msg.payload[6])}; //Temperature
break;
case "404000191123": //Inverter 2
msg1.payload = {"command":"udevice","idx":2001,"nvalue":0,"svalue":(msg.payload[1] + ";0")}; //Current Power A
msg2.payload = {"command":"udevice","idx":2002,"nvalue":0,"svalue":(msg.payload[2])}; //Voltage A
msg3.payload = {"command":"udevice","idx":2003,"nvalue":0,"svalue":(msg.payload[3] + ";0")}; //Current Power B
msg4.payload = {"command":"udevice","idx":2004,"nvalue":0,"svalue":(msg.payload[4])}; //Voltage B
msg5.payload = {"command":"udevice","idx":2005,"nvalue":0,"svalue":(msg.payload[5])}; //Frequency
msg6.payload = {"command":"udevice","idx":2006,"nvalue":0,"svalue":(msg.payload[6])}; //Temperature
break;
case "404000193004": //Inverter 3
msg1.payload = {"command":"udevice","idx":3001,"nvalue":0,"svalue":(msg.payload[1] + ";0")}; //Current Power A
msg2.payload = {"command":"udevice","idx":3002,"nvalue":0,"svalue":(msg.payload[2])}; //Voltage A
msg3.payload = {"command":"udevice","idx":3003,"nvalue":0,"svalue":(msg.payload[3] + ";0")}; //Current Power B
msg4.payload = {"command":"udevice","idx":3004,"nvalue":0,"svalue":(msg.payload[4])}; //Voltage B
msg5.payload = {"command":"udevice","idx":3005,"nvalue":0,"svalue":(msg.payload[5])}; //Frequency
msg6.payload = {"command":"udevice","idx":3006,"nvalue":0,"svalue":(msg.payload[6])}; //Temperature
break;
case "404000191257": //Inverter 4
msg1.payload = {"command":"udevice","idx":4001,"nvalue":0,"svalue":(msg.payload[1] + ";0")}; //Current Power A
msg2.payload = {"command":"udevice","idx":4002,"nvalue":0,"svalue":(msg.payload[2])}; //Voltage A
msg3.payload = {"command":"udevice","idx":4003,"nvalue":0,"svalue":(msg.payload[3] + ";0")}; //Current Power B
msg4.payload = {"command":"udevice","idx":4004,"nvalue":0,"svalue":(msg.payload[4])}; //Voltage B
msg5.payload = {"command":"udevice","idx":4005,"nvalue":0,"svalue":(msg.payload[5])}; //Frequency
msg6.payload = {"command":"udevice","idx":4006,"nvalue":0,"svalue":(msg.payload[6])}; //Temperature
break;
case "404000192992": //Inverter 5
msg1.payload = {"command":"udevice","idx":5001,"nvalue":0,"svalue":(msg.payload[1] + ";0")}; //Current Power A
msg2.payload = {"command":"udevice","idx":5002,"nvalue":0,"svalue":(msg.payload[2])}; //Voltage A
msg3.payload = {"command":"udevice","idx":5003,"nvalue":0,"svalue":(msg.payload[3] + ";0")}; //Current Power B
msg4.payload = {"command":"udevice","idx":5004,"nvalue":0,"svalue":(msg.payload[4])}; //Voltage B
msg5.payload = {"command":"udevice","idx":5005,"nvalue":0,"svalue":(msg.payload[5])}; //Frequency
msg6.payload = {"command":"udevice","idx":5006,"nvalue":0,"svalue":(msg.payload[6])}; //Temperature
break;
case "404000191779": //Inverter 6
msg1.payload = {"command":"udevice","idx":6001,"nvalue":0,"svalue":(msg.payload[1] + ";0")}; //Current Power A
msg2.payload = {"command":"udevice","idx":6002,"nvalue":0,"svalue":(msg.payload[2])}; //Voltage A
msg3.payload = {"command":"udevice","idx":6003,"nvalue":0,"svalue":(msg.payload[3] + ";0")}; //Current Power B
msg4.payload = {"command":"udevice","idx":6004,"nvalue":0,"svalue":(msg.payload[4])}; //Voltage B
msg5.payload = {"command":"udevice","idx":6005,"nvalue":0,"svalue":(msg.payload[5])}; //Frequency
msg6.payload = {"command":"udevice","idx":6006,"nvalue":0,"svalue":(msg.payload[6])}; //Temperature
break;
}
return [[msg1,msg2,msg3,msg4,msg5,msg6]];
In order to use this function node, each user has to made the following changes:
1. After each "case" statement, the user has to fill in its own Inverter ID/serial number (without the -A or -B suffix).
(Except Bernhard, he is a lucky guy
)
2. Each user has to replace the idx number (?001 - ?006) for his own idx number.
You made a table, where the relation between Name of the Domoticz Sensor and serial number has been put, didn't you?
3. If you have more than 6 inverters, copy the block between case and break;.
4. If you have less inverters than 6, delete the obsolete block(s) between case and break;,
The final flow will look like:
- Screenshot_APS-NodeRed-6.png (38.15 KiB) Viewed 1654 times
If the output corresponds with the screenshot, above, and your own, correct number, of indexes, you can connect the output of the second "function" node to the input of the MQTT output node.
The description, how to configure the MQTT output node, you will find in this post, dated Saturday 21 September 2019 21:54.
https://www.domoticz.com/forum/viewtopi ... 14&t=29331.
The complete code, you will find below:
Code: Select all
[{"id":"d243b84a.4ac438","type":"tab","label":"Test AP Systems","disabled":false,"info":""},{"id":"63bcbc31.eb708c","type":"http request","z":"d243b84a.4ac438","name":"HTTP AP Systems Production Request","method":"GET","ret":"txt","paytoqs":false,"url":"https://mbernard.home.xs4all.nl/youless/http%20_192.168.2.88_index.php_realtimedata.htm","tls":"","proxy":"","x":660,"y":240,"wires":[["c3df4a05.c383"]]},{"id":"9e970e24.f28508","type":"within-time-switch","z":"d243b84a.4ac438","name":"Day Timer","positionConfig":"2faec32b.cb2b74","startTime":"sunrise","startTimeType":"pdsTime","startOffset":"-30","startOffsetType":"num","startOffsetMultiplier":60000,"endTime":"sunset","endTimeType":"pdsTime","endOffset":"30","endOffsetType":"num","endOffsetMultiplier":60000,"propertyStart":"","propertyStartType":"none","propertyStartCompare":"true","propertyStartThreshold":"","propertyStartThresholdType":"num","startTimeAlt":"","startTimeAltType":"entered","startOffsetAlt":0,"startOffsetAltType":"none","startOffsetAltMultiplier":60000,"propertyEnd":"","propertyEndType":"none","propertyEndCompare":"true","propertyEndThreshold":"","propertyEndThresholdType":"num","endTimeAlt":"","endTimeAltType":"entered","endOffsetAlt":0,"endOffsetAltType":"none","endOffsetAltMultiplier":60000,"tsCompare":"0","lastMsgOnStartOut":false,"lastMsgOnEndOut":false,"x":370,"y":240,"wires":[["63bcbc31.eb708c"],[]]},{"id":"d5e45a3a.244e5","type":"debug","z":"d243b84a.4ac438","name":"HTML Output","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":380,"y":380,"wires":[]},{"id":"8501a12b.61eb4","type":"inject","z":"d243b84a.4ac438","name":"5 MIn Tick","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":"","x":180,"y":240,"wires":[["9e970e24.f28508"]]},{"id":"c3df4a05.c383","type":"html","z":"d243b84a.4ac438","name":"Parse inverter","property":"payload","outproperty":"payload","tag":"td","ret":"html","as":"single","x":180,"y":320,"wires":[["d5e45a3a.244e5","80391cd8.5820d8"]]},{"id":"80391cd8.5820d8","type":"function","z":"d243b84a.4ac438","name":"Create Inverter Array","func":"var i;\nfor (i = 0; i < msg.payload.length/9; i++) {\nvar InverterIDA = msg.payload[9*i+0];\nvar CurrentPowerA = msg.payload[9*i+1];\nvar GridFreq = msg.payload[9*i+2];\nvar GridVoltageA = msg.payload[9*i+3];\nvar GridTemp = msg.payload[9*i+4];\nvar GridReportTime = msg.payload[9*i+5];\nvar InverterIDB = msg.payload[9*i+6];\nvar CurrentPowerB = msg.payload[9*i+7];\nvar GridVoltageB = msg.payload[9*i+8];\nnewMsg = {payload: ([InverterIDA.substr(0,12),CurrentPowerA.substr(0,1),GridVoltageA.substr(0,3),CurrentPowerB.substr(0,1),GridVoltageB.substr(0,3),GridFreq.substr(0,4),GridTemp.substr(0,2)])}\nnode.send(newMsg);\n}","outputs":1,"noerr":0,"x":400,"y":320,"wires":[["7d148fd5.6837a8","752a8421.e09cf4"]]},{"id":"7d148fd5.6837a8","type":"debug","z":"d243b84a.4ac438","name":"Output APS Array","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":650,"y":380,"wires":[]},{"id":"752a8421.e09cf4","type":"function","z":"d243b84a.4ac438","name":"Solar Production Inverters to Domoticz","func":"var msg1 = {};\nvar msg2 = {};\nvar msg3 = {};\nvar msg4 = {};\nvar msg5 = {};\nvar msg6 = {};\n\nswitch (msg.payload[0]) {\n\n case \"404000191265\": //Inverter 1\n msg1.payload = {\"command\":\"udevice\",\"idx\":1001,\"nvalue\":0,\"svalue\":(msg.payload[1] + \";0\")}; //Current Power A\n msg2.payload = {\"command\":\"udevice\",\"idx\":1002,\"nvalue\":0,\"svalue\":(msg.payload[2])}; //Voltage A\n msg3.payload = {\"command\":\"udevice\",\"idx\":1003,\"nvalue\":0,\"svalue\":(msg.payload[3] + \";0\")}; //Current Power B\n msg4.payload = {\"command\":\"udevice\",\"idx\":1004,\"nvalue\":0,\"svalue\":(msg.payload[4])}; //Voltage B\n msg5.payload = {\"command\":\"udevice\",\"idx\":1005,\"nvalue\":0,\"svalue\":(msg.payload[5])}; //Frequency\n msg6.payload = {\"command\":\"udevice\",\"idx\":1006,\"nvalue\":0,\"svalue\":(msg.payload[6])}; //Temperature\n break;\n\n case \"404000191123\": //Inverter 2\n msg1.payload = {\"command\":\"udevice\",\"idx\":2001,\"nvalue\":0,\"svalue\":(msg.payload[1] + \";0\")}; //Current Power A\n msg2.payload = {\"command\":\"udevice\",\"idx\":2002,\"nvalue\":0,\"svalue\":(msg.payload[2])}; //Voltage A\n msg3.payload = {\"command\":\"udevice\",\"idx\":2003,\"nvalue\":0,\"svalue\":(msg.payload[3] + \";0\")}; //Current Power B\n msg4.payload = {\"command\":\"udevice\",\"idx\":2004,\"nvalue\":0,\"svalue\":(msg.payload[4])}; //Voltage B\n msg5.payload = {\"command\":\"udevice\",\"idx\":2005,\"nvalue\":0,\"svalue\":(msg.payload[5])}; //Frequency\n msg6.payload = {\"command\":\"udevice\",\"idx\":2006,\"nvalue\":0,\"svalue\":(msg.payload[6])}; //Temperature\n break;\n\n case \"404000193004\": //Inverter 3\n msg1.payload = {\"command\":\"udevice\",\"idx\":3001,\"nvalue\":0,\"svalue\":(msg.payload[1] + \";0\")}; //Current Power A\n msg2.payload = {\"command\":\"udevice\",\"idx\":3002,\"nvalue\":0,\"svalue\":(msg.payload[2])}; //Voltage A\n msg3.payload = {\"command\":\"udevice\",\"idx\":3003,\"nvalue\":0,\"svalue\":(msg.payload[3] + \";0\")}; //Current Power B\n msg4.payload = {\"command\":\"udevice\",\"idx\":3004,\"nvalue\":0,\"svalue\":(msg.payload[4])}; //Voltage B\n msg5.payload = {\"command\":\"udevice\",\"idx\":3005,\"nvalue\":0,\"svalue\":(msg.payload[5])}; //Frequency\n msg6.payload = {\"command\":\"udevice\",\"idx\":3006,\"nvalue\":0,\"svalue\":(msg.payload[6])}; //Temperature\n break;\n\n case \"404000191257\": //Inverter 4\n msg1.payload = {\"command\":\"udevice\",\"idx\":4001,\"nvalue\":0,\"svalue\":(msg.payload[1] + \";0\")}; //Current Power A\n msg2.payload = {\"command\":\"udevice\",\"idx\":4002,\"nvalue\":0,\"svalue\":(msg.payload[2])}; //Voltage A\n msg3.payload = {\"command\":\"udevice\",\"idx\":4003,\"nvalue\":0,\"svalue\":(msg.payload[3] + \";0\")}; //Current Power B\n msg4.payload = {\"command\":\"udevice\",\"idx\":4004,\"nvalue\":0,\"svalue\":(msg.payload[4])}; //Voltage B\n msg5.payload = {\"command\":\"udevice\",\"idx\":4005,\"nvalue\":0,\"svalue\":(msg.payload[5])}; //Frequency\n msg6.payload = {\"command\":\"udevice\",\"idx\":4006,\"nvalue\":0,\"svalue\":(msg.payload[6])}; //Temperature\n break;\n\n case \"404000192992\": //Inverter 5\n msg1.payload = {\"command\":\"udevice\",\"idx\":5001,\"nvalue\":0,\"svalue\":(msg.payload[1] + \";0\")}; //Current Power A\n msg2.payload = {\"command\":\"udevice\",\"idx\":5002,\"nvalue\":0,\"svalue\":(msg.payload[2])}; //Voltage A\n msg3.payload = {\"command\":\"udevice\",\"idx\":5003,\"nvalue\":0,\"svalue\":(msg.payload[3] + \";0\")}; //Current Power B\n msg4.payload = {\"command\":\"udevice\",\"idx\":5004,\"nvalue\":0,\"svalue\":(msg.payload[4])}; //Voltage B\n msg5.payload = {\"command\":\"udevice\",\"idx\":5005,\"nvalue\":0,\"svalue\":(msg.payload[5])}; //Frequency\n msg6.payload = {\"command\":\"udevice\",\"idx\":5006,\"nvalue\":0,\"svalue\":(msg.payload[6])}; //Temperature\n break;\n\n case \"404000191779\": //Inverter 6\n msg1.payload = {\"command\":\"udevice\",\"idx\":6001,\"nvalue\":0,\"svalue\":(msg.payload[1] + \";0\")}; //Current Power A\n msg2.payload = {\"command\":\"udevice\",\"idx\":6002,\"nvalue\":0,\"svalue\":(msg.payload[2])}; //Voltage A\n msg3.payload = {\"command\":\"udevice\",\"idx\":6003,\"nvalue\":0,\"svalue\":(msg.payload[3] + \";0\")}; //Current Power B\n msg4.payload = {\"command\":\"udevice\",\"idx\":6004,\"nvalue\":0,\"svalue\":(msg.payload[4])}; //Voltage B\n msg5.payload = {\"command\":\"udevice\",\"idx\":6005,\"nvalue\":0,\"svalue\":(msg.payload[5])}; //Frequency\n msg6.payload = {\"command\":\"udevice\",\"idx\":6006,\"nvalue\":0,\"svalue\":(msg.payload[6])}; //Temperature\n break;\n\n}\nreturn [[msg1,msg2,msg3,msg4,msg5,msg6]];","outputs":1,"noerr":0,"x":720,"y":320,"wires":[["5bea947.a4ba1ec"]]},{"id":"5bea947.a4ba1ec","type":"debug","z":"d243b84a.4ac438","name":"Domoticz Input","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","x":1020,"y":380,"wires":[]},{"id":"fdfef99c.3962f8","type":"mqtt out","z":"d243b84a.4ac438","name":"Domoticz In","topic":"domoticz/in","qos":"2","retain":"false","broker":"f9f13036.e28b58","x":1010,"y":320,"wires":[]},{"id":"2faec32b.cb2b74","type":"position-config","z":"","name":"","isValide":"true","longitude":"0","latitude":"0","angleType":"deg","timeZoneOffset":99,"timeZoneDST":0,"stateTimeFormat":"3","stateDateFormat":"12"},{"id":"f9f13036.e28b58","type":"mqtt-broker","z":"","name":"RPI1_ MQTT_Broker","broker":"192.168.10.51","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthRetain":"false","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
In order to get this all to work, it is essential that Bernhard (or someone else) changes the URL in the HTTP request node to a real value, such as:
http://< IP address ECU/index.php/realtimedata and checks the output of the "html" node.
It might be, that a small change in, either the "html" node or first "function"node is necessary.
Looking forward for reactions, comments or suggestions.
Best regards.