Hi all ,
I'm developing a simple interface for home automation which has some logic behind , internal updates and calls to AI routines though APIs. I'm having problems probably cause a lack of knowledge in general javascript msg processing and how to avoid msg loops.-
The question is :
· How can I change the input of a dashboard component without get into an endless loop?
Example :
· UI slider for setting the temp of a heater manually.
· UI switch for enable/disable Automode.
· Internal Logic Function : When Automode is ON , a call to AI API will get temperature value and update the output heater , but I also want to update the slider , and this become into a enless loop.
What I tried :
· Keep the status in a State node between UI Dashboard , and Internal Logic function.
· Use MQTT to subscribe to changes.
Result :
· Allways endless loop or undesired behaviour .-
Thank you in advance .-
Here is the code :
[
{
"id": "f1210038.8be3d",
"type": "tab",
"label": "AIDomotics_CONTROL",
"disabled": false,
"info": ""
},
{
"id": "635efa24.63c424",
"type": "ui_switch",
"z": "f1210038.8be3d",
"name": "AT HOME",
"label": "AT HOME",
"tooltip": "Indicanos si estas en casa.",
"group": "e30fbbe1.4b2f68",
"order": 0,
"width": "2",
"height": "1",
"passthru": false,
"decouple": "false",
"topic": "athome",
"style": "",
"onvalue": "{\"athome\":1}",
"onvalueType": "json",
"onicon": "",
"oncolor": "",
"offvalue": "{\"athome\":0}",
"offvalueType": "json",
"officon": "",
"offcolor": "",
"x": 120,
"y": 280,
"wires": [
[
"c3ae7fc7.bb29f",
"e6699a51.498b18",
"69d0bdc2.08a544"
]
],
"icon": "font-awesome/fa-male"
},
{
"id": "c8d96722.8c5e58",
"type": "ui_switch",
"z": "f1210038.8be3d",
"name": "AUTO MODE",
"label": "AUTO MODE",
"tooltip": "",
"group": "e30fbbe1.4b2f68",
"order": 1,
"width": "2",
"height": "1",
"passthru": false,
"decouple": "false",
"topic": "automode",
"style": "",
"onvalue": "{\"automode\":1}",
"onvalueType": "json",
"onicon": "",
"oncolor": "",
"offvalue": "{\"automode\":0}",
"offvalueType": "json",
"officon": "",
"offcolor": "",
"x": 140,
"y": 340,
"wires": [
[
"c3ae7fc7.bb29f",
"e6699a51.498b18",
"69d0bdc2.08a544"
]
],
"icon": "node-red/cog.svg"
},
{
"id": "c9ae096d.2ceef8",
"type": "inject",
"z": "f1210038.8be3d",
"name": "5_MINS_SCHEDULER",
"topic": "",
"payload": "scheduller",
"payloadType": "flow",
"repeat": "300",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 170,
"y": 140,
"wires": [
[
"aeed1f62.35c4b"
]
]
},
{
"id": "aeed1f62.35c4b",
"type": "http request",
"z": "f1210038.8be3d",
"d": true,
"name": "PREDICTOR_API",
"method": "GET",
"ret": "obj",
"paytoqs": false,
"url": "aidomgw51.local:11000/api/1.0/prediction?time=15",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 470,
"y": 580,
"wires": [
[
"c2d0b145.77584"
]
]
},
{
"id": "6850a2dc.88f19c",
"type": "http request",
"z": "f1210038.8be3d",
"d": true,
"name": "SET_TEMPERATURE",
"method": "POST",
"ret": "txt",
"paytoqs": false,
"url": "10.254.254.1:5000/api/1.0/therm",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 1600,
"y": 720,
"wires": [
[]
]
},
{
"id": "c3ae7fc7.bb29f",
"type": "debug",
"z": "f1210038.8be3d",
"name": "USER INPUT MONITOR",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 750,
"y": 260,
"wires": []
},
{
"id": "4563ce00.eb65a",
"type": "http request",
"z": "f1210038.8be3d",
"d": true,
"name": "VENTILATION",
"method": "POST",
"ret": "txt",
"paytoqs": false,
"url": "10.254.254.1:5000/api/1.0/therm",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 1540,
"y": 840,
"wires": [
[]
]
},
{
"id": "cf061b07.e64808",
"type": "http request",
"z": "f1210038.8be3d",
"d": true,
"name": "DRY-HUMIDIFY",
"method": "POST",
"ret": "txt",
"paytoqs": false,
"url": "10.254.254.1:5000/api/1.0/therm",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 1580,
"y": 780,
"wires": [
[]
]
},
{
"id": "100a5123.6d199f",
"type": "ui_slider",
"z": "f1210038.8be3d",
"name": "TEMP SET",
"label": "SET MANUAL",
"tooltip": "",
"group": "e30fbbe1.4b2f68",
"order": 2,
"width": "6",
"height": "1",
"passthru": true,
"outs": "end",
"topic": "temperature",
"min": "0",
"max": "35",
"step": "0.5",
"x": 130,
"y": 460,
"wires": [
[
"b1af509c.63849",
"e6699a51.498b18"
]
]
},
{
"id": "2daa4254.3302de",
"type": "function",
"z": "f1210038.8be3d",
"name": "THERM_ENCODER",
"func": "var temperature = parseFloat(msg.payload.temperature);\n\nmsg.payload.temp = 2*temperature.toFixed(0);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 1340,
"y": 620,
"wires": [
[
"6850a2dc.88f19c"
]
]
},
{
"id": "8e2bbf11.0cc92",
"type": "http request",
"z": "f1210038.8be3d",
"d": true,
"name": "NOISE_THRESHOLD",
"method": "POST",
"ret": "txt",
"paytoqs": false,
"url": "10.254.254.1:5000/api/1.0/therm",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 1560,
"y": 960,
"wires": [
[]
]
},
{
"id": "2cc58dff.6c6332",
"type": "ui_switch",
"z": "f1210038.8be3d",
"name": "ECO MODE",
"label": "ECO MODE",
"tooltip": "",
"group": "e30fbbe1.4b2f68",
"order": 1,
"width": "2",
"height": "1",
"passthru": false,
"decouple": "false",
"topic": "ecomode",
"style": "",
"onvalue": "{\"ecomode\":1}",
"onvalueType": "json",
"onicon": "",
"oncolor": "",
"offvalue": "{\"ecomode\":0}",
"offvalueType": "json",
"officon": "",
"offcolor": "",
"x": 130,
"y": 400,
"wires": [
[
"c3ae7fc7.bb29f",
"e6699a51.498b18",
"69d0bdc2.08a544"
]
],
"icon": "node-red/white-globe.svg"
},
{
"id": "c2d0b145.77584",
"type": "function",
"z": "f1210038.8be3d",
"name": "AIDOMOTICS_LOGIC",
"func": "var athome = msg.payload.athome;\nvar automode = msg.payload.automode;\nvar ecomode = msg.payload.ecomode;\nvar temperature = msg.payload.temperature;\n\nvar msg2 = {payload : {}};\n\nif(ecomode ===1)\n{\n msg.payload.temperature=\"18\";\n msg2.payload.uitemperature=\"18\";\n msg2.payload.uiautomode=\"0\";\n}\n\nreturn [msg,msg2];\n",
"outputs": 2,
"noerr": 0,
"x": 760,
"y": 440,
"wires": [
[
"57933940.1d0518",
"34734116.d2d0ee"
],
[
"da7f3c94.98112"
]
],
"inputLabels": [
"IN"
],
"outputLabels": [
"GENERAL",
""
]
},
{
"id": "6d3315fa.2834ac",
"type": "ui_gauge",
"z": "f1210038.8be3d",
"name": "CURRENT TEMP",
"group": "e30fbbe1.4b2f68",
"order": 4,
"width": "3",
"height": "3",
"gtype": "gage",
"title": "CURRENT TEMP",
"label": "ºC",
"format": "{{msg.payload[0].last.toFixed(2)}}",
"min": "-10",
"max": "50",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "",
"seg2": "",
"x": 1570,
"y": 80,
"wires": [],
"inputLabels": [
"last"
]
},
{
"id": "f5776efb.ffe21",
"type": "ui_gauge",
"z": "f1210038.8be3d",
"name": "DESIRED_TEMP",
"group": "e30fbbe1.4b2f68",
"order": 4,
"width": "3",
"height": "3",
"gtype": "gage",
"title": "DESIRED TEMP",
"label": "ºC",
"format": "{{msg.payload.temperature}}",
"min": "-10",
"max": "50",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "",
"seg2": "",
"x": 1570,
"y": 240,
"wires": []
},
{
"id": "b3ac5890.ed3408",
"type": "http request",
"z": "f1210038.8be3d",
"d": true,
"name": "NOTIFICATION",
"method": "POST",
"ret": "txt",
"paytoqs": false,
"url": "10.254.254.1:5000/api/1.0/therm",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 1540,
"y": 900,
"wires": [
[]
]
},
{
"id": "55ce0abe.3427f4",
"type": "influxdb in",
"z": "f1210038.8be3d",
"influxdb": "ce36c9f.c159138",
"name": "SENSOR1",
"query": "SELECT last(temperature) FROM SENSOR1 WHERE time > now() - 1h LIMIT 1",
"rawOutput": false,
"precision": "s",
"retentionPolicy": "",
"x": 790,
"y": 80,
"wires": [
[
"6d3315fa.2834ac"
]
]
},
{
"id": "34734116.d2d0ee",
"type": "debug",
"z": "f1210038.8be3d",
"name": "LOGIC MONITOR",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1030,
"y": 240,
"wires": []
},
{
"id": "ef3c2d6.a363ed",
"type": "inject",
"z": "f1210038.8be3d",
"name": "5_SECONDS_SCHEDULER",
"topic": "",
"payload": "scheduller",
"payloadType": "flow",
"repeat": "5",
"crontab": "",
"once": false,
"onceDelay": 0.1,
"x": 180,
"y": 80,
"wires": [
[
"55ce0abe.3427f4",
"6e572061.38222"
]
]
},
{
"id": "b1af509c.63849",
"type": "template",
"z": "f1210038.8be3d",
"name": "ENCODER",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "{\"temperature\":{{payload}}}",
"output": "json",
"x": 330,
"y": 460,
"wires": [
[
"69d0bdc2.08a544"
]
]
},
{
"id": "6e572061.38222",
"type": "influxdb in",
"z": "f1210038.8be3d",
"influxdb": "ce36c9f.c159138",
"name": "SENSOR2",
"query": "SELECT last(temperature) FROM SENSOR2 WHERE time > now() - 1h LIMIT 1",
"rawOutput": false,
"precision": "s",
"retentionPolicy": "",
"x": 790,
"y": 140,
"wires": [
[
"c361c291.ac2a6"
]
]
},
{
"id": "c361c291.ac2a6",
"type": "ui_gauge",
"z": "f1210038.8be3d",
"name": "OUTSIDE TEMP",
"group": "e30fbbe1.4b2f68",
"order": 4,
"width": "6",
"height": "3",
"gtype": "gage",
"title": "OUTSIDE TEMP",
"label": "ºC",
"format": "{{msg.payload[0].last.toFixed(2)}}",
"min": "-10",
"max": "50",
"colors": [
"#00b500",
"#e6e600",
"#ca3838"
],
"seg1": "",
"seg2": "",
"x": 1570,
"y": 140,
"wires": [],
"inputLabels": [
"last"
]
},
{
"id": "ff8b7618.fe0c48",
"type": "function",
"z": "f1210038.8be3d",
"name": "THERM_ENCODER",
"func": "var temp = parseFloat(msg.payload.temperature);\n\nmsg.payload.temperature = temp.toFixed(1);\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"x": 1340,
"y": 500,
"wires": [
[
"f5776efb.ffe21"
]
]
},
{
"id": "cbbbee0b.b5173",
"type": "ui_toast",
"z": "f1210038.8be3d",
"position": "bottom left",
"displayTime": "3",
"highlight": "",
"sendall": true,
"outputs": 0,
"ok": "OK",
"cancel": "",
"raw": false,
"topic": "Notify : ",
"name": "SCREEN NOTIFICATION",
"x": 1590,
"y": 360,
"wires": []
},
{
"id": "82c10355.dd5de",
"type": "debug",
"z": "f1210038.8be3d",
"name": "NOTIFICATION MONITOR",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 1300,
"y": 240,
"wires": []
},
{
"id": "e4e4820a.a71fb",
"type": "comment",
"z": "f1210038.8be3d",
"name": "SCHEDULERS",
"info": "",
"x": 140,
"y": 20,
"wires": []
},
{
"id": "f1c68e40.5a044",
"type": "comment",
"z": "f1210038.8be3d",
"name": "USER INPUT",
"info": "",
"x": 130,
"y": 200,
"wires": []
},
{
"id": "93290370.5b384",
"type": "comment",
"z": "f1210038.8be3d",
"name": "INFLUXDB INPUTS",
"info": "",
"x": 790,
"y": 20,
"wires": []
},
{
"id": "20253cb5.c4b1f4",
"type": "comment",
"z": "f1210038.8be3d",
"name": "DASHBOARD",
"info": "",
"x": 1550,
"y": 20,
"wires": []
},
{
"id": "6f2b35e0.0a0f2c",
"type": "comment",
"z": "f1210038.8be3d",
"name": "ACTUATORS OUTPUT",
"info": "",
"x": 1600,
"y": 620,
"wires": []
},
{
"id": "d3483f7f.c3d2d",
"type": "comment",
"z": "f1210038.8be3d",
"name": "AI INPUTS",
"info": "",
"x": 440,
"y": 520,
"wires": []
},
{
"id": "e6699a51.498b18",
"type": "function",
"z": "f1210038.8be3d",
"name": "NOTIFICATIONS_LOGIC",
"func": "var athome = msg.payload.athome;\nvar automode = msg.payload.automode;\nvar ecomode = msg.payload.ecomode;\nvar aitemp = msg.payload.temperature;\nvar mtemp = msg.payload.mtemperature;\n\nif (athome === 1)\n{\n msg.payload.notification = {\"text\":\"Wellcome Home! \"}\n}\nif (athome === 0)\n{\n msg.payload.notification = {\"text\":\"GoodBye !\"}\n}\nif (automode === 1)\n{\n msg.payload.notification = {\"text\":\"Auto Mode ON\"}\n} \nif (automode === 0)\n{\n msg.payload.notification = {\"text\":\"Auto Mode OFF\"}\n} \nif (ecomode === 1)\n{\n msg.payload.notification = {\"text\":\"Eco Mode ON\"}\n} \nif (ecomode === 0)\n{\n msg.payload.notification = {\"text\":\"Eco Mode OFF\"}\n} \n\n\nreturn msg\n",
"outputs": 1,
"noerr": 0,
"x": 770,
"y": 340,
"wires": [
[
"5dfab07a.f2751"
]
],
"inputLabels": [
"IN"
],
"outputLabels": [
"GENERAL"
]
},
{
"id": "eebca861.150638",
"type": "template",
"z": "f1210038.8be3d",
"name": "TO_TEXT",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "{{payload.notification.text}}",
"output": "str",
"x": 1340,
"y": 340,
"wires": [
[
"cbbbee0b.b5173",
"82c10355.dd5de"
]
]
},
{
"id": "5dfab07a.f2751",
"type": "switch",
"z": "f1210038.8be3d",
"name": "EMPTYCHECK",
"property": "payload.notification.text",
"propertyType": "msg",
"rules": [
{
"t": "nempty"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 1020,
"y": 340,
"wires": [
[
"eebca861.150638"
]
]
},
{
"id": "f563c064.2ce2f",
"type": "debug",
"z": "f1210038.8be3d",
"name": "CUSTOM",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"x": 740,
"y": 580,
"wires": []
},
{
"id": "69d0bdc2.08a544",
"type": "set-shared-state",
"z": "f1210038.8be3d",
"state": "4a3b385a.53beb8",
"name": "USER_INPUT",
"triggerOnInit": true,
"provideOutput": false,
"outputs": 0,
"x": 440,
"y": 160,
"wires": []
},
{
"id": "34e3358e.39f77a",
"type": "get-shared-state",
"z": "f1210038.8be3d",
"state": "4a3b385a.53beb8",
"name": "USER_INPUT",
"triggerOnInit": true,
"x": 430,
"y": 220,
"wires": [
[
"f19d235b.0ff4"
]
]
},
{
"id": "57933940.1d0518",
"type": "function",
"z": "f1210038.8be3d",
"name": "MSG_SPLITTER",
"func": "// MQTT Parser\n// This script will extract 6 properties of a JSON Object\n// And generate 6 outputs one with each value\n\nvar temperature = msg.payload.temperature;\nvar humidity = msg.payload.humidity;\nvar co2 = msg.payload.co2;\nvar tvoc = msg.payload.tvoc;\nvar luminosity = msg.payload.luminosity;\nvar noise = msg.payload.noise;\n\nvar msg1 = {payload : {}};\nvar msg2 = {payload : {}};\nvar msg3 = {payload : {}};\nvar msg4 = {payload : {}};\nvar msg5 = {payload : {}};\nvar msg6 = {payload : {}};\n\nmsg1.payload.temperature = temperature;\nmsg2.payload.humidity = humidity;\nmsg3.payload.co2 = co2;\nmsg4.payload.tvoc = tvoc;\nmsg5.payload.luminosity = luminosity;\nmsg6.payload.noise = noise;\n\nreturn [msg1,msg2,msg3,msg4,msg5,msg6];",
"outputs": 6,
"noerr": 0,
"x": 1010,
"y": 440,
"wires": [
[
"ff8b7618.fe0c48",
"2daa4254.3302de"
],
[],
[],
[],
[],
[]
]
},
{
"id": "f19d235b.0ff4",
"type": "mqtt out",
"z": "f1210038.8be3d",
"name": "CONTROL",
"topic": "control/ui/",
"qos": "",
"retain": "true",
"broker": "6c7acc8b.c658b4",
"x": 630,
"y": 200,
"wires": []
},
{
"id": "1f562d2b.d910f3",
"type": "mqtt in",
"z": "f1210038.8be3d",
"name": "CONTROL",
"topic": "control/ui/#",
"qos": "2",
"datatype": "json",
"broker": "6c7acc8b.c658b4",
"x": 490,
"y": 680,
"wires": [
[
"c2d0b145.77584"
]
]
},
{
"id": "da7f3c94.98112",
"type": "template",
"z": "f1210038.8be3d",
"name": "DECODER",
"field": "payload",
"fieldType": "msg",
"format": "handlebars",
"syntax": "mustache",
"template": "{{payload.uitemperature}}",
"output": "str",
"x": 210,
"y": 560,
"wires": [
[
"f563c064.2ce2f",
"534590c8.509e8"
]
]
},
{
"id": "534590c8.509e8",
"type": "delay",
"z": "f1210038.8be3d",
"name": "",
"pauseType": "delay",
"timeout": "50",
"timeoutUnits": "milliseconds",
"rate": "1",
"nbRateUnits": "1",
"rateUnits": "second",
"randomFirst": "1",
"randomLast": "5",
"randomUnits": "seconds",
"drop": false,
"x": 170,
"y": 660,
"wires": [
[]
]
},
{
"id": "e30fbbe1.4b2f68",
"type": "ui_group",
"z": "",
"name": "AIDomotics",
"tab": "3db010d0.9406c",
"disp": true,
"width": "6",
"collapse": false
},
{
"id": "ce36c9f.c159138",
"type": "influxdb",
"z": "",
"hostname": "10.254.254.1",
"port": "8086",
"protocol": "http",
"database": "wisedomdb",
"name": "",
"usetls": false,
"tls": ""
},
{
"id": "4a3b385a.53beb8",
"type": "shared-state",
"z": "",
"name": "USER_INPUT",
"lbl": "",
"tags": "",
"historyCount": "4",
"dataType": "obj",
"boolType": "bool",
"boolStrTrue": "",
"boolStrFalse": "",
"precision": "",
"numMin": "",
"numMax": "",
"unit": ""
},
{
"id": "6c7acc8b.c658b4",
"type": "mqtt-broker",
"z": "",
"name": "wisedom_gw_51",
"broker": "10.254.254.1",
"port": "1883",
"clientid": "client1",
"usetls": false,
"compatmode": false,
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"willTopic": "",
"willQos": "0",
"willPayload": ""
},
{
"id": "3db010d0.9406c",
"type": "ui_tab",
"z": "",
"name": "IoT",
"icon": "dashboard",
"disabled": false,
"hidden": false
}
]