-
Notifications
You must be signed in to change notification settings - Fork 34
Node Red integration
- Node-RED is installed and configured
- MQTT broker (e.g. Mosquitto) is installed
- The CVE unit must be in "standard" or "medium" setting as per Itho design.
Import the Node-RED flow
You can also use "itho/#" where # is the wildcard for MQTT traffic so it captures all topics defined under "MQTT" in the add-on webpage, e.g. itho/ithostatus, itho/remotesinfo.
You get 2 nodes with flow down below that each listen to "state" and "sensor"
[
{
"id": "26a4fac610847e53",
"type": "tab",
"label": "ITHO Daalderop HVAC",
"disabled": false,
"info": "created for the nrg-addon"
},
{
"id": "41bbb41dd8645b46",
"type": "mqtt in",
"z": "26a4fac610847e53",
"name": "sensor-output",
"topic": "Itho/sensor",
"qos": "2",
"datatype": "auto",
"broker": "ff2de987.5f8a68",
"nl": false,
"rap": true,
"rh": 0,
"x": 410,
"y": 120,
"wires": [
[
"81c664d72f0c4396"
]
]
},
{
"id": "81c664d72f0c4396",
"type": "debug",
"z": "26a4fac610847e53",
"name": "debug-sensor-output",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 620,
"y": 120,
"wires": []
},
{
"id": "e755a4408c62afc9",
"type": "mqtt in",
"z": "26a4fac610847e53",
"name": "state-output",
"topic": "Itho/state",
"qos": "2",
"datatype": "auto",
"broker": "ff2de987.5f8a68",
"nl": false,
"rap": true,
"rh": 0,
"x": 390,
"y": 180,
"wires": [
[
"4f36ddf10333eba7"
]
]
},
{
"id": "4f36ddf10333eba7",
"type": "debug",
"z": "26a4fac610847e53",
"name": "debug-state-output",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "false",
"statusVal": "",
"statusType": "auto",
"x": 610,
"y": 180,
"wires": []
},
{
"id": "ff2de987.5f8a68",
"type": "mqtt-broker",
"name": "",
"broker": "localhost",
"port": "1883",
"clientid": "",
"usetls": false,
"protocolVersion": "4",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"sessionExpiry": ""
}
]
Extracting values from MQTT when labels have special characters (and for normal labels this works as well)
The most used notation to access elements of a JSON is using the dot notation. ie. to extract the key temperature
from the payload in node-red:
msg.payload.temperature
Although this works for normalized keys, this does not work for keys that have special characters. For this (but also for the mentioned example) the JavaScript bracket notation can be used.
ie. msg.payload['temperature']
instead of msg.payload.temperature
or
ie. payload['Fan speed (rpm)']
for the value of label 'Fan speed (rpm)'
of the JSON on the MQTT topic itho/ithostatus
This also works nested. For a msg of type JSON with the following content {"first level":{"nested level":10}}
the statement msg['first level']['nested level']
would pass the value 10 to the next node.
Simple example flow:
[{"id":"8d04620e7b4f9b97","type":"debug","z":"79360772.4553e8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1070,"y":1720,"wires":[]},{"id":"2cdc290bb8e51f85","type":"change","z":"79360772.4553e8","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"itho_co2","tot":"global"}],"action":"","property":"","from":"","to":"","reg":false,"x":860,"y":1720,"wires":[["8d04620e7b4f9b97"]]},{"id":"fdca1683f90c9be8","type":"trigger","z":"79360772.4553e8","name":"","op1":"","op2":"","op1type":"date","op2type":"nul","duration":"1","extend":true,"overrideDelay":false,"units":"ms","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":660,"y":1720,"wires":[["2cdc290bb8e51f85"]]},{"id":"a0b62caf5d330adb","type":"change","z":"79360772.4553e8","name":"","rules":[{"t":"set","p":"itho_co2","pt":"global","to":"payload['Highest CO2 concentration (ppm)']","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":1720,"wires":[["fdca1683f90c9be8"]]},{"id":"7a57ac91d3cbc894","type":"mqtt in","z":"79360772.4553e8","name":"","topic":"itho/ithostatus","qos":"2","datatype":"json","broker":"b4eed736.102278","nl":false,"rap":true,"rh":0,"x":160,"y":1540,"wires":[["c12148d5d894edb0","6c21177deab25ac7","358ac2eb91d89950","c022aa4e833f686d","f5dc2e7677773603","dc906465f5ca55d8","a0b62caf5d330adb"]]},{"id":"b4eed736.102278","type":"mqtt-broker","name":"MQTT server","broker":"192.168.1.1","port":"1883","clientid":"","usetls":false,"compatmode":false,"protocolVersion":4,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]
A function (node) contents to set values for Node-RED
var temp = msg.payload.temperature.value;
var humi = msg.payload.humidity.value;
var batt = msg.status.battery;
var idx = msg.payload.idx;
msg.payload = {}
// Humidity Status
if (humi < 31) {
humistat = "2";
} else if (humi > 69) {
humistat = "3";
} else if (humi > 34 && humi < 66 && temp > 21 && temp < 27) {
humistat = "1";
} else {
humistat = "0";
}
msg.payload.idx = idx;
msg.payload.nvalue = 0;
msg.payload.svalue = temp.toString()+";"+humi.toString()+";"+humistat;
if (typeof batt !== 'undefined' && batt !== null){
msg.payload.Battery = Math.round(batt/9*100);
}
return msg;
The result of the above payload is:
{
"idx":10,
"nvalue":0,
"svalue":"13.1;74;3",
"Battery":100
}
This script below communicates with the add-on through the api. An extended version has been published here: Node-red itho ventilation flow and monitors absolute humidity (shower) and presence (toilets), stops during the night, has night cooling and sends Telegram messages. Many variables are published to a Domoticz client. Interaction with the itho add-on is through web API calls.
[ { "id": "3dd6103ad43a8b44", "type": "tab", "label": "Flow 1", "disabled": false, "info": "" }, { "id": "46696f08d834fd2f", "type": "http request", "z": "3dd6103ad43a8b44", "name": "get ithostatus", "method": "GET", "ret": "obj", "paytoqs": "ignore", "url": "http://192.168.1.91/api.html?get=ithostatus", "tls": "", "persist": false, "proxy": "", "authType": "", "credentials": {}, "x": 150, "y": 860, "wires": [ [ "0a22200b47015429" ] ] }, { "id": "0a22200b47015429", "type": "change", "z": "3dd6103ad43a8b44", "name": "get ppmw", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "$round(payload.ppmw,0)", "tot": "jsonata" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 180, "y": 920, "wires": [ [ "7bdf7b699cbced84" ] ] }, { "id": "c936450d68b013d0", "type": "stoptimer-varidelay", "z": "3dd6103ad43a8b44", "duration": "40", "durationType": "num", "units": "Minute", "payloadtype": "num", "payloadval": "0", "name": "40 minutes", "reporting": "last_minute_seconds", "persist": true, "ignoretimerpass": false, "x": 1030, "y": 1100, "wires": [ [ "ddbace9092efa18e" ], [], [] ] }, { "id": "78d799b6d9b47f28", "type": "change", "z": "3dd6103ad43a8b44", "name": "set high, reset low", "rules": [ { "t": "set", "p": "state_high", "pt": "global", "to": "true", "tot": "bool" }, { "t": "set", "p": "low", "pt": "global", "to": "false", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1130, "y": 960, "wires": [ [ "c936450d68b013d0", "3694f7919ea84cb6" ] ] }, { "id": "8ae5216b24c3c7c2", "type": "change", "z": "3dd6103ad43a8b44", "name": "itho 180", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "180", "tot": "num" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1640, "y": 940, "wires": [ [ "1bda9d1733a2dbe1" ] ] }, { "id": "e18b3c7efa9e107d", "type": "change", "z": "3dd6103ad43a8b44", "name": "STOP", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "STOP", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 850, "y": 1100, "wires": [ [ "c936450d68b013d0" ] ] }, { "id": "ac07c02b2adcd330", "type": "switch", "z": "3dd6103ad43a8b44", "name": "> 1000?", "property": "payload.ppmw-1000", "propertyType": "jsonata", "rules": [ { "t": "gt", "v": "payload.min", "vt": "msg" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 920, "y": 960, "wires": [ [ "78d799b6d9b47f28" ] ] }, { "id": "425c75d9bfb84008", "type": "switch", "z": "3dd6103ad43a8b44", "name": "< -700?", "property": "payload.ppmw+700", "propertyType": "jsonata", "rules": [ { "t": "lt", "v": "payload.max", "vt": "msg" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 1000, "y": 1180, "wires": [ [ "e18b3c7efa9e107d", "d62f5496b1e62a62" ] ] }, { "id": "2aab351fedcf3146", "type": "smooth", "z": "3dd6103ad43a8b44", "name": "max 8min", "property": "payload.max", "action": "max", "count": "96", "round": "", "mult": "single", "reduce": false, "x": 540, "y": 1180, "wires": [ [ "78c383bc4475c8dd" ] ] }, { "id": "aea68bd37d56b2fc", "type": "smooth", "z": "3dd6103ad43a8b44", "name": "min 8min", "property": "payload.min", "action": "min", "count": "96", "round": "", "mult": "single", "reduce": false, "x": 620, "y": 920, "wires": [ [ "b187e4529b635424" ] ] }, { "id": "78c383bc4475c8dd", "type": "switch", "z": "3dd6103ad43a8b44", "name": "if high", "property": "state_high", "propertyType": "global", "rules": [ { "t": "true" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 690, "y": 1180, "wires": [ [ "80cba0d306d66dc8" ] ] }, { "id": "80cba0d306d66dc8", "type": "switch", "z": "3dd6103ad43a8b44", "name": "changed?", "property": "currentspeed", "propertyType": "global", "rules": [ { "t": "neq", "v": "180", "vt": "num" }, { "t": "eq", "v": "180", "vt": "num" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 840, "y": 1180, "wires": [ [ "a167ad5b2ed05eec" ], [ "425c75d9bfb84008" ] ] }, { "id": "b187e4529b635424", "type": "switch", "z": "3dd6103ad43a8b44", "name": "if low", "property": "low", "propertyType": "global", "rules": [ { "t": "true" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 770, "y": 940, "wires": [ [ "ac07c02b2adcd330", "bbbf2a481f165956" ] ] }, { "id": "7bdf7b699cbced84", "type": "smooth", "z": "3dd6103ad43a8b44", "name": "avg 3", "property": "payload", "action": "mean", "count": "3", "round": "0", "mult": "multi", "reduce": false, "x": 190, "y": 980, "wires": [ [ "5951881fb9214cef" ] ] }, { "id": "d06b64737c81ad83", "type": "stoptimer-varidelay", "z": "3dd6103ad43a8b44", "duration": "10", "durationType": "num", "units": "Minute", "payloadtype": "num", "payloadval": "0", "name": "10 minutes", "reporting": "last_minute_seconds", "persist": false, "ignoretimerpass": false, "x": 1330, "y": 1180, "wires": [ [ "f4cf8a6ceb9d16ec" ], [], [] ] }, { "id": "b55553cb678b6675", "type": "change", "z": "3dd6103ad43a8b44", "name": "save speed", "rules": [ { "t": "set", "p": "savedspeed", "pt": "global", "to": "currentspeed", "tot": "global" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1490, "y": 940, "wires": [ [ "8ae5216b24c3c7c2" ] ] }, { "id": "bbbf2a481f165956", "type": "switch", "z": "3dd6103ad43a8b44", "name": "ppmw >15000?", "property": "payload.ppmw", "propertyType": "msg", "rules": [ { "t": "gt", "v": "15000", "vt": "num" } ], "checkall": "true", "repair": true, "outputs": 1, "x": 940, "y": 920, "wires": [ [ "f5dd5a449658d0d9" ] ] }, { "id": "d62f5496b1e62a62", "type": "change", "z": "3dd6103ad43a8b44", "name": "reset high", "rules": [ { "t": "set", "p": "state_high", "pt": "global", "to": "false", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1160, "y": 1180, "wires": [ [ "d06b64737c81ad83" ] ] }, { "id": "ddbace9092efa18e", "type": "change", "z": "3dd6103ad43a8b44", "name": "reset high, set low", "rules": [ { "t": "set", "p": "state_high", "pt": "global", "to": "false", "tot": "bool" }, { "t": "set", "p": "low", "pt": "global", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1210, "y": 1080, "wires": [ [ "ac9a1187403536d8" ] ] }, { "id": "a167ad5b2ed05eec", "type": "change", "z": "3dd6103ad43a8b44", "name": "reset high, set low", "rules": [ { "t": "set", "p": "state_high", "pt": "global", "to": "false", "tot": "bool" }, { "t": "set", "p": "low", "pt": "global", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 670, "y": 1100, "wires": [ [ "e18b3c7efa9e107d" ] ] }, { "id": "f4cf8a6ceb9d16ec", "type": "change", "z": "3dd6103ad43a8b44", "name": "set low", "rules": [ { "t": "set", "p": "low", "pt": "global", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1500, "y": 1160, "wires": [ [ "ac9a1187403536d8" ] ] }, { "id": "f5dd5a449658d0d9", "type": "change", "z": "3dd6103ad43a8b44", "name": "set hum, reset low", "rules": [ { "t": "set", "p": "hum", "pt": "global", "to": "true", "tot": "bool" }, { "t": "set", "p": "low", "pt": "global", "to": "false", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1130, "y": 920, "wires": [ [ "3694f7919ea84cb6" ] ] }, { "id": "c4f252231f26bdc2", "type": "switch", "z": "3dd6103ad43a8b44", "name": "ppmw <14500", "property": "payload.ppmw", "propertyType": "msg", "rules": [ { "t": "lt", "v": "14500", "vt": "num" } ], "checkall": "true", "repair": true, "outputs": 1, "x": 940, "y": 1020, "wires": [ [ "f139fd931221c692" ] ] }, { "id": "f139fd931221c692", "type": "change", "z": "3dd6103ad43a8b44", "name": "reset hum, set low", "rules": [ { "t": "set", "p": "hum", "pt": "global", "to": "false", "tot": "bool" }, { "t": "set", "p": "low", "pt": "global", "to": "true", "tot": "bool" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1130, "y": 1020, "wires": [ [ "ac9a1187403536d8" ] ] }, { "id": "aeb4a69e4266862c", "type": "switch", "z": "3dd6103ad43a8b44", "name": "if hum", "property": "hum", "propertyType": "global", "rules": [ { "t": "true" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 610, "y": 1000, "wires": [ [ "c4f252231f26bdc2" ] ] }, { "id": "1bda9d1733a2dbe1", "type": "http request", "z": "3dd6103ad43a8b44", "name": "set speed", "method": "GET", "ret": "txt", "paytoqs": "ignore", "url": "http://192.168.1.91/api.html?speed={{{payload}}}", "tls": "", "persist": false, "proxy": "", "authType": "", "credentials": {}, "x": 1780, "y": 1000, "wires": [ [] ] }, { "id": "ac9a1187403536d8", "type": "change", "z": "3dd6103ad43a8b44", "name": "itho low", "rules": [ { "t": "set", "p": "payload", "pt": "msg", "to": "savedspeed", "tot": "global" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 1400, "y": 1040, "wires": [ [ "1bda9d1733a2dbe1" ] ] }, { "id": "5951881fb9214cef", "type": "function", "z": "3dd6103ad43a8b44", "name": "set min, max", "func": "ppmw=msg.payload;\nmsg.payload={ppmw:ppmw, max: ppmw,min:ppmw};\nmsg.payload.min=ppmw;\nmsg.payload.max=ppmw;\nreturn msg;", "outputs": 1, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 430, "y": 960, "wires": [ [ "2aab351fedcf3146", "aea68bd37d56b2fc", "aeb4a69e4266862c" ] ] }, { "id": "3694f7919ea84cb6", "type": "switch", "z": "3dd6103ad43a8b44", "name": "speed <180?", "property": "currentspeed", "propertyType": "global", "rules": [ { "t": "lt", "v": "180", "vt": "num" } ], "checkall": "true", "repair": false, "outputs": 1, "x": 1330, "y": 940, "wires": [ [ "b55553cb678b6675" ] ] } ]