Pekaway Connect: die neue App

Amerkung: Dieser Post ist geteilt in mehrere Posts, nichtmal ich darf hier so viel auf einmal posten :smiley:

Hey Leute,

nochmal vielen Dank für die rege Teilnahme an unserem Livestream, hat uns sehr gefreut :slight_smile:

Unsere neue App ist wie gesagt online und kann heruntergeladen werden:

Apple App Store

Google Playstore

Die App ist zweisprachig und richtet sich nach der Systemsprache eures Smartphones. Also entweder euer Handy hat Deutsch als Systemsprache eingestellt, dann ist die App auf deutsch, bei allen anderen Sprachen ist die App auf Englisch.

Dem aufmerksamen iOS-User wird vielleicht auch schon aufgefallen sein, dass die App im (deutschen) App Store nur “Pekaway” und nicht “Pekaway Connect” heißt. Naja, als ich die App zur Überprüfung eingereicht habe, habe ich nur den Titel für den englischssprachigen Store geändert… Klassiker :smiley: Wird dann mit einem zukünftigen Update umbenannt.

Die App holt sich alle Daten aus der HTTP-Api, für den Zugriff aus der Ferne gibt es eine Erweiterung über MQTT, die dann intern wieder auf die HTTP -Api zugreift.
Aktuell funktioniert das allerdings noch nicht mit der IoT-Bridge! Also nur lokal oder ihr habt schon eine bestehende Internetverbindung.

Also jetzt zu den wichtigen Themen. Wenn ihr die App bereits geladen habt, dann funktioniert so ziemlich alles nicht so richtig mit der aktuell veröffentlichten Software. Es gibt dafür ein paar neue Variablen und HTTP Endpunkte. Konkret müssen die Flows “Heater Controls”, “HTTP Api”, “MQTT Api”, “Init” & “Monit” angepasst werden (und “Connections” für die kommende GPS Antenne). Dazu kommt ein neuer Flow für den Lagesensor, der ist noch nicht finalisiert, funktioniert aber prinzipiell und vielleicht will ja schon jemand darauf aufbauen.

Der Reihe nach:

HTTP-API Flow:

Wie angesprochen gibt es ein bisschen was neues, ein paar Änderungen um die Daten für die App vorzubereiten, etc. etc.
Ganz unten im Flow gibt es die Funktion für den Lagesensor, da haben wir 3 Link Out Nodes, die im Flow für den Lagesensor entsprechend verbunden werden müssen. Dazu später mehr.
Ebenfalls seht ihr eine kleine Beispielfunktion für die GPS Daten, im Großen und Ganzen werden nur die globalen Variablen “latitude”, “longitude” und “gps_updated” geschrieben.

Der (komplette) HTTP-Api Flow:

[{"id":"42fae630.bb5488","type":"comment","z":"e78e73d3.53155","name":"endpoints general ","info":"","x":130,"y":400,"wires":[]},{"id":"d88508e9.959f68","type":"http in","z":"e78e73d3.53155","name":"","url":"batt","method":"get","upload":false,"swaggerDoc":"","x":100,"y":440,"wires":[["bfac6a8c.d2ccf8"]]},{"id":"bfac6a8c.d2ccf8","type":"function","z":"e78e73d3.53155","name":"get battery stats","func":"msg.payload = {\n    \"VoltB\":global.get(\"MainBattVolt\"),\n    \"Ampere\":global.get(\"MainBattAmps\"),\n    \"battsoc\":global.get(\"MainBattSoc\"),\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":440,"wires":[["b21dc5aa.b70b18"]]},{"id":"b21dc5aa.b70b18","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":450,"y":440,"wires":[]},{"id":"ff26b15d.781d2","type":"http in","z":"e78e73d3.53155","name":"","url":"level","method":"get","upload":false,"swaggerDoc":"","x":100,"y":480,"wires":[["23326e88.54d5b2"]]},{"id":"23326e88.54d5b2","type":"function","z":"e78e73d3.53155","name":"get level stats","func":"msg.payload = {\n    \"level1\": {\n        \"state\":global.get(\"Level1\"),\n        \"name\":global.get(\"NLevel1\")\n    },\n    \"level2\": {\n        \"state\": global.get(\"Level2\"),\n        \"name\":global.get(\"NLevel2\")\n    },\n     \"level3\": {\n         \"state\": global.get(\"Level3\"),\n        \"name\":global.get(\"NLevel3\")\n    },\n    \"level4\": {\n        \"state\": global.get(\"Level4\"),\n        \"name\":global.get(\"NLevel4\")\n    }\n} ;   \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":480,"wires":[["37f32fd8.9748e"]]},{"id":"37f32fd8.9748e","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":450,"y":480,"wires":[]},{"id":"782c51e6.7fe59","type":"http in","z":"e78e73d3.53155","name":"","url":"names","method":"get","upload":false,"swaggerDoc":"","x":110,"y":560,"wires":[["5d23d85a.2ca3b8"]]},{"id":"5d23d85a.2ca3b8","type":"function","z":"e78e73d3.53155","name":"get all names","func":"msg.payload = {\n    \"Relay1\": {\n        \"name\":global.get(\"None\"),\n        \"globalVariable\":\"None\"\n    },\n    \"Relay2\": {\n        \"name\":global.get(\"Ntwo\"),\n        \"globalVariable\":\"Ntwo\"\n    },\n    \"Relay3\": {\n        \"name\":global.get(\"Nthree\"),\n        \"globalVariable\":\"Nthree\"\n    },\n    \"Relay4\": {\n        \"name\":global.get(\"Nfour\"),\n        \"globalVariable\":\"Nfour\"\n    },\n    \"Relay5\": {\n        \"name\":global.get(\"Nfive\"),\n        \"globalVariable\":\"Nfive\"\n    },\n    \"Relay6\": {\n        \"name\":global.get(\"Nsix\"),\n        \"globalVariable\":\"Nsix\"\n    },\n    \"Relay7\": {\n        \"name\":global.get(\"Nseven\"),\n        \"globalVariable\":\"Nseven\"\n    },\n    \"Relay8\": {\n        \"name\":global.get(\"Neight\"),\n        \"globalVariable\":\"Neight\"\n    },\n    \"Relay9\": {\n        \"name\":global.get(\"Nnine\"),\n        \"globalVariable\":\"Nnine\"\n    },\n    \"Relay10\": {\n        \"name\":global.get(\"Nten\"),\n        \"globalVariable\":\"Nten\"\n    },\n    \"WifiRelay1\": {\n        \"name\":global.get(\"NWone\"),\n        \"globalVariable\":\"NWone\"\n    },\n    \"WifiRelay2\": {\n        \"name\":global.get(\"NWtwo\"),\n        \"globalVariable\":\"NWtwo\"\n    },\n    \"WifiRelay3\": {\n        \"name\":global.get(\"NWthree\"),\n        \"globalVariable\":\"NWthree\"\n    },\n    \"WifiRelay4\": {\n        \"name\":global.get(\"NWfour\"),\n        \"globalVariable\":\"NWfour\"\n    },\n    \"WifiRelay5\": {\n        \"name\":global.get(\"NWfive\"),\n        \"globalVariable\":\"NWfive\"\n    },\n    \"WifiRelay6\": {\n        \"name\":global.get(\"NWsix\"),\n        \"globalVariable\":\"NWsix\"\n    },\n    \"WifiRelay7\": {\n        \"name\":global.get(\"NWseven\"),\n        \"globalVariable\":\"NWseven\"\n    },\n    \"WifiRelay8\": {\n        \"name\":global.get(\"NWeight\"),\n        \"globalVariable\":\"NWeight\"\n    },\n    \"Temp1\":{\n        \"name\":global.get(\"Ntemp1\"),\n        \"globalVariable\":\"NTemp1\"\n    },\n    \"Temp2\":{\n        \"name\":global.get(\"Ntemp2\"),\n        \"globalVariable\":\"NTemp2\"\n    },\n    \"Temp3\":{\n        \"name\":global.get(\"Ntemp3\"),\n        \"globalVariable\":\"NTemp3\"\n    },\n    \"Temp4\":{\n        \"name\":global.get(\"Ntemp4\"),\n        \"globalVariable\":\"NTemp4\"\n    },\n    \"Level1\": {\n        \"name\":global.get(\"NLevel1\"),\n        \"globalVariable\":\"NLevel1\"\n    },\n    \"Level2\": {\n        \"name\":global.get(\"NLevel2\"),\n        \"globalVariable\":\"NLevel2\"\n    },\n    \"Level3\": {\n        \"name\":global.get(\"NLevel3\"),\n        \"globalVariable\":\"NLevel3\"\n    },\n    \"Level4\": {\n        \"name\":global.get(\"NLevel4\"),\n        \"globalVariable\":\"NLevel4\"\n    },\n    \"Dimmer1\": {\n        \"name\":global.get(\"Ndimmer0\"),\n        \"globalVariable\":\"Ndimmer0\"\n    },\n    \"Dimmer2\": {\n        \"name\":global.get(\"Ndimmer1\"),\n        \"globalVariable\":\"Ndimmer1\"\n    },\n    \"Dimmer3\": {\n        \"name\":global.get(\"Ndimmer2\"),\n        \"globalVariable\":\"Ndimmer2\"\n    },\n    \"Dimmer4\": {\n        \"name\":global.get(\"Ndimmer3\"),\n        \"globalVariable\":\"Ndimmer3\"\n    },\n    \"Dimmer5\": {\n        \"name\":global.get(\"Ndimmer4\"),\n        \"globalVariable\":\"Ndimmer4\"\n    },\n    \"Dimmer6\": {\n        \"name\":global.get(\"Ndimmer5\"),\n        \"globalVariable\":\"Ndimmer5\"\n    },\n    \"Dimmer7\": {\n        \"name\":global.get(\"Ndimmer6\"),\n        \"globalVariable\":\"Ndimmer6\"\n    },\n    \"Dimmer8\": {\n        \"name\":global.get(\"Ndimmer7\"),\n        \"globalVariable\":\"Ndimmer7\"\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":270,"y":560,"wires":[["359a0021.f59c1"]]},{"id":"359a0021.f59c1","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":450,"y":560,"wires":[]},{"id":"f43c42b0.3680f","type":"http in","z":"e78e73d3.53155","name":"","url":"heater","method":"get","upload":false,"swaggerDoc":"","x":110,"y":520,"wires":[["ef5df576.d9abc8"]]},{"id":"ef5df576.d9abc8","type":"function","z":"e78e73d3.53155","name":"get heater stats","func":"if (global.get(\"heater_runtime\") == undefined || global.get(\"heater_runtime\") == null || global.get(\"heater_runtime\") == \"cancel\") {global.set(\"heater_runtime\", 0)}\nmsg.payload = {\n    \"heatertoggle\":global.get(\"HeaterToggle\"),\n    \"heatstatus\":global.get(\"heatstatus\"),\n    \"heattemp\":global.get(\"heattemp\"),\n    \"heatvolt\":global.get(\"heatvolt\"),\n    \"heatfan\":global.get(\"heatfan\"),\n    \"heatglow\":global.get(\"heatpump\"),\n    \"heatwpump\":global.get(\"heatwpump\"),\n    \"heaterror\":global.get(\"heaterror\"),\n    \"targettemp_vanpi\":Number(global.get(\"settemp\")),\n    \"runtime\":Number(global.get(\"heater_runtime\"))\n};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":520,"wires":[["e9020de4.de6d4"]]},{"id":"e9020de4.de6d4","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":450,"y":520,"wires":[]},{"id":"9ddd5b7.518bea8","type":"http in","z":"e78e73d3.53155","name":"","url":"temp","method":"get","upload":false,"swaggerDoc":"","x":100,"y":600,"wires":[["4cf7aa4a.c5c784"]]},{"id":"4cf7aa4a.c5c784","type":"function","z":"e78e73d3.53155","name":"get temp stats","func":"if (global.get(\"temp1\") == null || global.get(\"temp1\") == \"\") {\n    global.set(\"temp1\", \"0\")   \n}\nif (global.get(\"temp1\") == \"not connected\" || global.get(\"temp1\") == \"\") {\n    global.set(\"temp1\", \"0\")   \n}\nif (global.get(\"temp2\") == null || global.get(\"temp2\") == \"\") {\n    global.set(\"temp2\", \"0\")   \n}\nif (global.get(\"temp3\") == null || global.get(\"temp3\") == \"\") {\n    global.set(\"temp3\", \"0\")   \n}\nif (global.get(\"temp4\") == null || global.get(\"temp4\") == \"\") {\n    global.set(\"temp4\", \"0\")   \n}\nif (global.get(\"dimmytemp\") == true) {\n    if (global.get(\"dimmytemp1\") == null || global.get(\"dimmytemp1\") == \"\") {\n        global.set(\"dimmytemp1\", \"0\")\n    }\n    if (global.get(\"dimmytemp2\") == null || global.get(\"dimmytemp2\") == \"\") {\n        global.set(\"dimmytemp2\", \"0\")\n    }\n    msg.payload = {\n        \"temp1\": {\n            \"state\": global.get(\"temp1\").toString(),\n            \"name\": global.get(\"Ntemp1\"),\n        },\n        \"temp2\": {\n            \"state\": global.get(\"temp2\").toString(),\n            \"name\": global.get(\"Ntemp2\"),\n        },\n        \"temp3\": {\n            \"state\": global.get(\"temp3\").toString(),\n            \"name\": global.get(\"Ntemp3\"),\n        },\n        \"temp4\": {\n            \"state\": global.get(\"temp4\").toString(),\n            \"name\": global.get(\"Ntemp4\"),\n        },\n        \"dimmytemp1\": {\n            \"state\": global.get(\"dimmytemp1\").toString(),\n            \"name\": global.get(\"Ndimmytemp1\"),\n        },\n        \"dimmytemp2\": {\n            \"state\": global.get(\"dimmytemp2\").toString(),\n            \"name\": global.get(\"Ndimmytemp2\"),\n        }\n    }    \n}\nelse {\n    msg.payload = {\n        \"temp1\": {\n            \"state\":global.get(\"temp1\").toString(),\n            \"name\":global.get(\"Ntemp1\"),\n        },\n        \"temp2\": {\n            \"state\": global.get(\"temp2\").toString(),\n            \"name\":global.get(\"Ntemp2\"),\n        },\n        \"temp3\": {\n            \"state\": global.get(\"temp3\").toString(),\n            \"name\":global.get(\"Ntemp3\"),\n        },\n        \"temp4\": {\n            \"state\": global.get(\"temp4\").toString(),\n            \"name\":global.get(\"Ntemp4\"),\n        },\n    }\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":600,"wires":[["aa3a9dde.7746a"]]},{"id":"aa3a9dde.7746a","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":450,"y":600,"wires":[]},{"id":"01c1b0774a7ce1c5","type":"http in","z":"e78e73d3.53155","name":"","url":"relay/:input/:value","method":"put","upload":false,"swaggerDoc":"","x":140,"y":1260,"wires":[["d705cc504a44adc6"]]},{"id":"7352a6468ee7758c","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":550,"y":1300,"wires":[]},{"id":"d705cc504a44adc6","type":"function","z":"e78e73d3.53155","name":"check input and switch state","func":"function number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nif (isNaN(parseInt(msg.req.params.input)) == false){\n    var num = \"zero one two three four five six seven eight nine ten\".split(\" \");\n    msg.req.params.input = parseInt(msg.req.params.input)\n    msg.req.params.input = number2words(msg.req.params.input)\n}\n\nmsg.relay = msg.req.params.input;\n\nif (msg.req.params.value === \"true\") {\n    msg.payload = true\n    msg.relaystate = msg.payload\n    return [msg, msg];\n}\nelse if (msg.req.params.value === \"false\") {\n    msg.payload = false\n    msg.relaystate = msg.payload\n    return [msg, msg];\n}\nelse {\n    msg.payload = \"value can only be true or false\"\n    return [null, msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":1260,"wires":[["1cb3c5e476649f72"],["1682ab47f11056de"]]},{"id":"1cb3c5e476649f72","type":"switch","z":"e78e73d3.53155","name":"","property":"relay","propertyType":"msg","rules":[{"t":"cont","v":"one","vt":"str"},{"t":"cont","v":"two","vt":"str"},{"t":"cont","v":"three","vt":"str"},{"t":"cont","v":"four","vt":"str"},{"t":"cont","v":"five","vt":"str"},{"t":"cont","v":"six","vt":"str"},{"t":"cont","v":"seven","vt":"str"},{"t":"cont","v":"eight","vt":"str"},{"t":"cont","v":"nine","vt":"str"},{"t":"cont","v":"ten","vt":"str"}],"checkall":"false","repair":false,"outputs":10,"x":750,"y":1320,"wires":[["a04b3614573af150"],["11075381c9dd3e27"],["d1c38a7c4b408418"],["bee832ef9e0bbec5"],["27e4acfea3f8598a"],["e0771acc5d3182c3"],["cf7080d88a760efb"],["c51c399bbe263fb6"],[],[]]},{"id":"a04b3614573af150","type":"link out","z":"e78e73d3.53155","name":"switch connect 1","mode":"link","links":["e9ffa3ef.cde5d"],"x":995,"y":1140,"wires":[]},{"id":"bee832ef9e0bbec5","type":"link out","z":"e78e73d3.53155","name":"switch connect 4","links":["f14867fc.930ab8"],"x":995,"y":1260,"wires":[]},{"id":"27e4acfea3f8598a","type":"link out","z":"e78e73d3.53155","name":"switch connect 5","links":["8cde3678.94ac88","1d05179e.1f1a78","1e0f28f7.6b3347","a17061ed.e682d"],"x":995,"y":1300,"wires":[]},{"id":"e0771acc5d3182c3","type":"link out","z":"e78e73d3.53155","name":"switch connect 6","links":["a45ee432.b7ef98","c9adec52.63ae6","f4303c75.d5b1c","31dcf86e.085898"],"x":995,"y":1340,"wires":[]},{"id":"cf7080d88a760efb","type":"link out","z":"e78e73d3.53155","name":"switch connect 7","links":["e97a5ba1.09c7e8","38796905.f4b7f6","de881e69.90777","3f2d3621.ced3da"],"x":995,"y":1380,"wires":[]},{"id":"c51c399bbe263fb6","type":"link out","z":"e78e73d3.53155","name":"switch connect 8","links":["95089e82.5785e","2840c10.f61294","f38ca7b2.7594d8","c946b435.21b198"],"x":995,"y":1420,"wires":[]},{"id":"11075381c9dd3e27","type":"link out","z":"e78e73d3.53155","name":"switch connect 2","links":["7255f9f4.6304d8"],"x":995,"y":1180,"wires":[]},{"id":"d1c38a7c4b408418","type":"link out","z":"e78e73d3.53155","name":"switch connect 3","links":["c698c6e8.416b58"],"x":995,"y":1220,"wires":[]},{"id":"1682ab47f11056de","type":"function","z":"e78e73d3.53155","name":"set answer","func":"if (msg.payload.toString().includes(\"can only be\")){\n    return msg\n}\nelse {\n    var autooff = global.get(msg.relay+\"offauto\")\n    msg.payload = {\n        \"relay\": msg.relay,\n        \"state\": msg.relaystate,\n        \"autooff\": autooff\n    }\n    return msg\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":1300,"wires":[["7352a6468ee7758c"]]},{"id":"857bd591a72db827","type":"http in","z":"e78e73d3.53155","name":"","url":"relay/:input","method":"get","upload":false,"swaggerDoc":"","x":120,"y":1400,"wires":[["3f8e55018a683876"]]},{"id":"24ec5317eca5f0fb","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":610,"y":1400,"wires":[]},{"id":"3f8e55018a683876","type":"function","z":"e78e73d3.53155","name":"check input and get relay","func":"function number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nvar globalVar = msg.req.params.input\n\nif (isNaN(parseInt(msg.req.params.input)) == false){\n    var num = \"zero one two three four five six seven eight nine ten\".split(\" \");\n    msg.req.params.input = parseInt(msg.req.params.input)\n    msg.req.params.input = number2words(msg.req.params.input)\n    globalVar = msg.req.params.input\n}\n\nif (msg.req.params.input==\"all\") {\n    msg.payload = {\n        \"Relay1\": {\n            \"state\":global.get(\"one\"),            \n            \"name\":global.get(\"None\"),\n            //\"autooff\": global.get(\"oneoffauto\")\n        },\n        \"Relay2\": {\n            \"state\":global.get(\"two\"),            \n            \"name\":global.get(\"Ntwo\"),\n            //\"autooff\": global.get(\"twooffauto\")\n        },\n        \"Relay3\": {\n            \"state\":global.get(\"three\"),            \n            \"name\":global.get(\"Nthree\"),\n            //\"autooff\": global.get(\"threeoffauto\")\n        },\n        \"Relay4\": {\n            \"state\":global.get(\"four\"),            \n            \"name\":global.get(\"Nfour\"),\n            //\"autooff\": global.get(\"fouroffauto\")\n        },\n        \"Relay5\": {\n            \"state\":global.get(\"five\"),            \n            \"name\":global.get(\"Nfive\"),\n            //\"autooff\": global.get(\"fiveoffauto\")\n        },\n        \"Relay6\": {\n            \"state\":global.get(\"six\"),            \n            \"name\":global.get(\"Nsix\"),\n            //\"autooff\": global.get(\"sixoffauto\")\n        },\n        \"Relay7\": {\n            \"state\":global.get(\"seven\"),            \n            \"name\":global.get(\"Nseven\"),\n            //\"autooff\": global.get(\"sevenoffauto\")\n        },\n        \"Relay8\": {\n            \"state\":global.get(\"eight\"),            \n            \"name\":global.get(\"Neight\"),\n            //\"autooff\": global.get(\"eightoffauto\")\n        }\n\n    };\n}\nelse if (global.get(msg.req.params.input)!==undefined) {\n    var n = \"N\"+msg.req.params.input\n    var autooff = global.get(msg.req.params.input+\"offauto\")\n    msg.payload = {\n        \"relay\":msg.req.params.input,\n        \"state\":global.get(msg.req.params.input),\n        \"name\":global.get(n),\n        //\"autooff\": autooff\n    };\n}\nelse {\n    msg.payload = \"relay \" + msg.req.params.input + \" does not exist\"\n}\n    \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":1400,"wires":[["24ec5317eca5f0fb"]]},{"id":"86bc478d69c132c1","type":"http in","z":"e78e73d3.53155","name":"","url":"toggle/relay/:input","method":"put","upload":false,"swaggerDoc":"","x":140,"y":1340,"wires":[["57fd6373ec601066"]]},{"id":"57fd6373ec601066","type":"function","z":"e78e73d3.53155","name":"check input and switch state","func":"function number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nif (isNaN(parseInt(msg.req.params.input)) == false){\n    var num = \"zero one two three four five six seven eight nine ten\".split(\" \");\n    msg.req.params.input = parseInt(msg.req.params.input)\n    msg.req.params.input = number2words(msg.req.params.input)\n}\n\nmsg.relay = msg.req.params.input;\n\nif (global.get(msg.relay) == true) {\n    msg.payload = false\n    msg.relaystate = msg.payload\n}\nelse if (global.get(msg.relay) == false) {\n    msg.payload = true\n    msg.relaystate = msg.payload\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":380,"y":1340,"wires":[["1cb3c5e476649f72","1682ab47f11056de"]]},{"id":"94700921f269acea","type":"http in","z":"e78e73d3.53155","name":"","url":"relay/","method":"get","upload":false,"swaggerDoc":"","x":110,"y":1440,"wires":[["85a890eb47b407a0"]]},{"id":"85a890eb47b407a0","type":"change","z":"e78e73d3.53155","name":"","rules":[{"t":"set","p":"req.params.input","pt":"msg","to":"all","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":1440,"wires":[["3f8e55018a683876"]]},{"id":"10071c4e6ed27059","type":"http in","z":"e78e73d3.53155","name":"","url":"names/:input","method":"put","upload":false,"swaggerDoc":"","x":130,"y":280,"wires":[["0e42267ed02c70bb"]]},{"id":"0e42267ed02c70bb","type":"function","z":"e78e73d3.53155","name":"check input and set name","func":"if (msg.req.params.input == \"update\") {\n    msg.payload = \"names have been updated\"\n    return [msg, null]\n}\n\nmsg.globalVar = \"N\"+msg.req.params.input;\n\nif (global.get(msg.globalVar)!==undefined) {\n    global.set(msg.globalVar, msg.payload)\n\n    msg.payload = {\n            \"description\":msg.globalVar,\n            \"name\":global.get(msg.globalVar)\n    }\n    //answer http request\n    node.send([msg, null])\n    //set payload for textfield in dashboard\n    msg.payload = global.get(msg.globalVar)\n    return [null, msg]\n}\nelse {\n    msg.payload = \"global variable \" + msg.req.params.input + \" is not defined\";\n    return [msg, null]\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":280,"wires":[["e9be18c319bccfd1","961a8b6d41509271"],["34ed1bb765acddd3"]]},{"id":"e9be18c319bccfd1","type":"http response","z":"e78e73d3.53155","name":"answer","statusCode":"200","headers":{},"x":680,"y":280,"wires":[]},{"id":"34ed1bb765acddd3","type":"switch","z":"e78e73d3.53155","name":"","property":"globalVar","propertyType":"msg","rules":[{"t":"eq","v":"Ntemp1","vt":"str"},{"t":"eq","v":"Ntemp2","vt":"str"},{"t":"eq","v":"Ntemp3","vt":"str"},{"t":"eq","v":"Ntemp4","vt":"str"},{"t":"eq","v":"NLevel1","vt":"str"},{"t":"eq","v":"NLevel2","vt":"str"},{"t":"eq","v":"NLevel3","vt":"str"},{"t":"eq","v":"NLevel4","vt":"str"},{"t":"eq","v":"None","vt":"str"},{"t":"eq","v":"Ntwo","vt":"str"},{"t":"eq","v":"Nthree","vt":"str"},{"t":"eq","v":"Nfour","vt":"str"},{"t":"eq","v":"Nfive","vt":"str"},{"t":"eq","v":"Nsix","vt":"str"},{"t":"eq","v":"Nseven","vt":"str"},{"t":"eq","v":"Neight","vt":"str"},{"t":"eq","v":"Nnine","vt":"str"},{"t":"eq","v":"Nten","vt":"str"},{"t":"eq","v":"NWone","vt":"str"},{"t":"eq","v":"NWtwo","vt":"str"},{"t":"eq","v":"NWthree","vt":"str"},{"t":"eq","v":"NWfour","vt":"str"},{"t":"eq","v":"NWfive","vt":"str"},{"t":"eq","v":"NWsix","vt":"str"},{"t":"eq","v":"NWseven","vt":"str"},{"t":"eq","v":"NWeight","vt":"str"},{"t":"eq","v":"Ndimmer0","vt":"str"},{"t":"eq","v":"Ndimmer1","vt":"str"},{"t":"eq","v":"Ndimmer2","vt":"str"},{"t":"eq","v":"Ndimmer3","vt":"str"},{"t":"eq","v":"Ndimmer4","vt":"str"},{"t":"eq","v":"Ndimmer5","vt":"str"},{"t":"eq","v":"Ndimmer6","vt":"str"},{"t":"eq","v":"Ndimmer7","vt":"str"},{"t":"eq","v":"Ndimmytemp1","vt":"str"},{"t":"eq","v":"Ndimmytemp2","vt":"str"}],"checkall":"false","repair":false,"outputs":36,"x":810,"y":360,"wires":[["8f3c59a42992518b"],["1ca17d1277c17055"],["e2d931c67b5038fe"],["967fa4e3178fb82b"],["4d1b006b57d6ef45"],["45bba022abc3c534"],["dcebcef7012c7f07"],["c693ba0e60a42a37"],["2215762d38495713"],["523289f1d05dad12"],["3a8124b501346d8b"],["fd6bfa7ca31c97fa"],["6f9b853e331a293a"],["004c62c10b636096"],["3a493f6979414933"],["ec202c43ad863b73"],["3818a04b207aea8c"],["3966ddcffc558c87"],["d7a9ec06ef6a2f8f"],["d74657bdf8030b2f"],["da2cf914da6895c2"],["06e51df7bb811802"],["ea39a7c19379ec5a"],["22bb0428f7f4d15b"],["ba8e80a7849282a2"],["d9fdbbd1cd30f63e"],["c26a4b876c4901c9"],["c9ed3e060355439a"],["130f980449b663c9"],["b84b7db4506f8198"],["b84c1e8756a08551"],["058bad9790e5e006"],["cd383f78ea1aa841"],["d9a0767fc8e50b76"],["6f7685fb79ce0438"],["761da5923e187298"]]},{"id":"8f3c59a42992518b","type":"link out","z":"e78e73d3.53155","name":"Ntemp1","links":["1a8794f31a3f9ddb"],"x":1015,"y":20,"wires":[]},{"id":"1ca17d1277c17055","type":"link out","z":"e78e73d3.53155","name":"Ntemp2","links":["dc783718278813d6"],"x":1015,"y":40,"wires":[]},{"id":"e2d931c67b5038fe","type":"link out","z":"e78e73d3.53155","name":"Ntemp3","links":["cfb819effd2aef27"],"x":1015,"y":60,"wires":[]},{"id":"967fa4e3178fb82b","type":"link out","z":"e78e73d3.53155","name":"Ntemp4","links":["d2008d5c540c4214"],"x":1015,"y":80,"wires":[]},{"id":"4d1b006b57d6ef45","type":"link out","z":"e78e73d3.53155","name":"NLevel1","links":["2fd913aba86f7a79"],"x":1015,"y":100,"wires":[]},{"id":"45bba022abc3c534","type":"link out","z":"e78e73d3.53155","name":"NLevel2","links":["3332389371230b20"],"x":1015,"y":120,"wires":[]},{"id":"dcebcef7012c7f07","type":"link out","z":"e78e73d3.53155","name":"NLevel3","links":["4c35af4930ed3a51"],"x":1015,"y":140,"wires":[]},{"id":"c693ba0e60a42a37","type":"link out","z":"e78e73d3.53155","name":"NLevel4","links":["9fa5ed9642841cac"],"x":1015,"y":160,"wires":[]},{"id":"2215762d38495713","type":"link out","z":"e78e73d3.53155","name":"None","links":["7e3adb9d283ce234"],"x":1015,"y":180,"wires":[]},{"id":"523289f1d05dad12","type":"link out","z":"e78e73d3.53155","name":"Ntwo","links":["ca585a03f0fe6085"],"x":1015,"y":200,"wires":[]},{"id":"3a8124b501346d8b","type":"link out","z":"e78e73d3.53155","name":"Nthree","links":["d24286c0f1f05cf1"],"x":1015,"y":220,"wires":[]},{"id":"fd6bfa7ca31c97fa","type":"link out","z":"e78e73d3.53155","name":"Nfour","links":["1bbf9074b56672aa"],"x":1015,"y":240,"wires":[]},{"id":"6f9b853e331a293a","type":"link out","z":"e78e73d3.53155","name":"Nfive","links":["ffdfcbf3d0444b71"],"x":1015,"y":260,"wires":[]},{"id":"004c62c10b636096","type":"link out","z":"e78e73d3.53155","name":"Nsix","links":["f77512a00db0f317"],"x":1015,"y":280,"wires":[]},{"id":"3a493f6979414933","type":"link out","z":"e78e73d3.53155","name":"Nseven","links":["01d48cd43596ed13"],"x":1015,"y":300,"wires":[]},{"id":"ec202c43ad863b73","type":"link out","z":"e78e73d3.53155","name":"Neight","links":["a4c1332f59457b49"],"x":1015,"y":320,"wires":[]},{"id":"3818a04b207aea8c","type":"link out","z":"e78e73d3.53155","name":"Nnine","links":["5d29a3a442f887f7"],"x":1015,"y":340,"wires":[]},{"id":"3966ddcffc558c87","type":"link out","z":"e78e73d3.53155","name":"Nten","links":["82c952ea0eeb0aca"],"x":1015,"y":360,"wires":[]},{"id":"d7a9ec06ef6a2f8f","type":"link out","z":"e78e73d3.53155","name":"NWone","links":["473f2db910e74f46"],"x":1015,"y":380,"wires":[]},{"id":"d74657bdf8030b2f","type":"link out","z":"e78e73d3.53155","name":"NWtwo","links":["dc023f5d7a61c9d9"],"x":1015,"y":400,"wires":[]},{"id":"da2cf914da6895c2","type":"link out","z":"e78e73d3.53155","name":"NWthree","links":["2110d5ae121a4453"],"x":1015,"y":420,"wires":[]},{"id":"06e51df7bb811802","type":"link out","z":"e78e73d3.53155","name":"NWfour","links":["5d624ae1b18443db"],"x":1015,"y":440,"wires":[]},{"id":"ea39a7c19379ec5a","type":"link out","z":"e78e73d3.53155","name":"NWfive","links":["665af31eeae91d53"],"x":1015,"y":460,"wires":[]},{"id":"22bb0428f7f4d15b","type":"link out","z":"e78e73d3.53155","name":"NWsix","links":["5a630b11c01d184b"],"x":1015,"y":480,"wires":[]},{"id":"d9fdbbd1cd30f63e","type":"link out","z":"e78e73d3.53155","name":"NWeight","links":["d3dc38692edfe006"],"x":1015,"y":520,"wires":[]},{"id":"ba8e80a7849282a2","type":"link out","z":"e78e73d3.53155","name":"NWseven","links":["01d48cd43596ed13"],"x":1015,"y":500,"wires":[]},{"id":"c26a4b876c4901c9","type":"link out","z":"e78e73d3.53155","name":"Ndimmer0","links":["c66a52b7774be47b"],"x":1015,"y":540,"wires":[]},{"id":"c9ed3e060355439a","type":"link out","z":"e78e73d3.53155","name":"Ndimmer1","links":["4086c55304ba32ae"],"x":1015,"y":560,"wires":[]},{"id":"130f980449b663c9","type":"link out","z":"e78e73d3.53155","name":"Ndimmer2","links":["d65b3469341a8601"],"x":1015,"y":580,"wires":[]},{"id":"b84b7db4506f8198","type":"link out","z":"e78e73d3.53155","name":"Ndimmer3","links":["38fd2c83faf60559"],"x":1015,"y":600,"wires":[]},{"id":"b84c1e8756a08551","type":"link out","z":"e78e73d3.53155","name":"Ndimmer4","links":["24787a551c032712"],"x":1015,"y":620,"wires":[]},{"id":"058bad9790e5e006","type":"link out","z":"e78e73d3.53155","name":"Ndimmer5","links":["702959d76f03f238"],"x":1015,"y":640,"wires":[]},{"id":"cd383f78ea1aa841","type":"link out","z":"e78e73d3.53155","name":"Ndimmer6","links":["32079052da4028df"],"x":1015,"y":660,"wires":[]},{"id":"d9a0767fc8e50b76","type":"link out","z":"e78e73d3.53155","name":"Ndimmer7","mode":"link","links":["34ce2bd2a0b794e4"],"x":1015,"y":680,"wires":[]},{"id":"f9ca9d33383d5220","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":590,"y":1620,"wires":[]},{"id":"5d26899bef877b6f","type":"switch","z":"e78e73d3.53155","name":"","property":"relay","propertyType":"msg","rules":[{"t":"cont","v":"one","vt":"str"},{"t":"cont","v":"two","vt":"str"},{"t":"cont","v":"three","vt":"str"},{"t":"cont","v":"four","vt":"str"},{"t":"cont","v":"five","vt":"str"},{"t":"cont","v":"six","vt":"str"},{"t":"cont","v":"seven","vt":"str"},{"t":"cont","v":"eight","vt":"str"}],"checkall":"false","repair":false,"outputs":8,"x":750,"y":1620,"wires":[["937d5e03dd599a61"],["80da336a069ba2df"],["80cd2ca9be046404"],["236f17a63794e768"],["7cb5ca22f1c184e8"],["8c23965172e6d81f"],["c4e1e5d7a9f81b29"],["0bf4c82c6cb860c4"]]},{"id":"236f17a63794e768","type":"link out","z":"e78e73d3.53155","name":"switch connect 4","links":["d2ce5044.ef8af"],"x":995,"y":1580,"wires":[]},{"id":"7cb5ca22f1c184e8","type":"link out","z":"e78e73d3.53155","name":"switch connect 5","links":["9f1c7c65c2da2d42"],"x":995,"y":1620,"wires":[]},{"id":"8c23965172e6d81f","type":"link out","z":"e78e73d3.53155","name":"switch connect 6","links":["d76c3b78c0f14e69"],"x":995,"y":1660,"wires":[]},{"id":"c4e1e5d7a9f81b29","type":"link out","z":"e78e73d3.53155","name":"switch connect 7","links":["34f49f08e1a06032"],"x":995,"y":1700,"wires":[]},{"id":"0bf4c82c6cb860c4","type":"link out","z":"e78e73d3.53155","name":"switch connect 8","links":["1be6547089f6e149"],"x":995,"y":1740,"wires":[]},{"id":"80da336a069ba2df","type":"link out","z":"e78e73d3.53155","name":"switch connect 2","links":["33a5d09e.6cc14"],"x":995,"y":1500,"wires":[]},{"id":"80cd2ca9be046404","type":"link out","z":"e78e73d3.53155","name":"switch connect 3","links":["428f4d48.86eaf4"],"x":995,"y":1540,"wires":[]},{"id":"56e1abb5b2e7247e","type":"function","z":"e78e73d3.53155","name":"set answer","func":"if (msg.payload.toString().includes(\"can only be\")){\n    return msg\n}\nelse {\n    var autooff = global.get(msg.relay.toLowerCase()+\"offauto\")\n    msg.payload = {\n        \"relay\": msg.relay,\n        \"state\": msg.relaystate,\n        \"autooff\": autooff\n    }\n    return msg\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":1620,"wires":[["f9ca9d33383d5220"]]},{"id":"a454928c0a2e740d","type":"http in","z":"e78e73d3.53155","name":"","url":"wrelay/:input","method":"get","upload":false,"swaggerDoc":"","x":130,"y":1720,"wires":[["9c197e66867dcb29"]]},{"id":"a2c7311476d4c970","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":670,"y":1720,"wires":[]},{"id":"9c197e66867dcb29","type":"function","z":"e78e73d3.53155","name":"check input and get wrelay","func":"function number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nvar globalVar = \"W\"+msg.req.params.input\n\nif (isNaN(parseInt(msg.req.params.input)) == false){\n    var num = \"zero one two three four five six seven eight nine ten\".split(\" \");\n    msg.req.params.input = parseInt(msg.req.params.input)\n    msg.req.params.input = number2words(msg.req.params.input)\n    globalVar = \"W\"+msg.req.params.input\n}\n\nif (msg.req.params.input==\"all\") {\n    msg.payload = {\n        \"WifiRelay1\": {\n            \"state\":global.get(\"Wone\"),            \n            \"name\":global.get(\"NWone\"),\n            \"firmware\":global.get(\"wrelay1_firmware\"),\n            \"autooff\": global.get(\"woneoffauto\")\n        },\n        \"WifiRelay2\": {\n            \"state\":global.get(\"Wtwo\"),            \n            \"name\":global.get(\"NWtwo\"),\n            \"firmware\":global.get(\"wrelay2_firmware\"),\n            \"autooff\": global.get(\"wtwooffauto\")\n        },\n        \"WifiRelay3\": {\n            \"state\":global.get(\"Wthree\"),            \n            \"name\":global.get(\"NWthree\"),\n            \"firmware\":global.get(\"wrelay3_firmware\"),\n            \"autooff\": global.get(\"wthreeoffauto\")\n        },\n        \"WifiRelay4\": {\n            \"state\":global.get(\"Wfour\"),            \n            \"name\":global.get(\"NWfour\"),\n            \"firmware\":global.get(\"wrelay4_firmware\"),\n            \"autooff\": global.get(\"wfouroffauto\")\n        },\n        \"WifiRelay5\": {\n            \"state\":global.get(\"Wfive\"),            \n            \"name\":global.get(\"NWfive\"),\n            \"firmware\":global.get(\"wrelay5_firmware\"),\n            \"autooff\": global.get(\"wfiveoffauto\")\n        },\n        \"WifiRelay6\": {\n            \"state\":global.get(\"Wsix\"),            \n            \"name\":global.get(\"NWsix\"),\n            \"firmware\":global.get(\"wrelay6_firmware\"),\n            \"autooff\": global.get(\"wsixoffauto\")\n        },\n        \"WifiRelay7\": {\n            \"state\":global.get(\"Wseven\"),            \n            \"name\":global.get(\"NWseven\"),\n            \"firmware\":global.get(\"wrelay7_firmware\"),\n            \"autooff\": global.get(\"wsevenoffauto\")\n        },\n        \"WifiRelay8\": {\n            \"state\":global.get(\"Weight\"),            \n            \"name\":global.get(\"NWeight\"),\n            \"firmware\":global.get(\"wrelay8_firmware\"),\n            \"autooff\": global.get(\"weightoffauto\")\n        }\n    };\n}\n\nelse if (global.get(globalVar)!==undefined) {\n    var autooff = global.get(\"w\"+msg.req.params.input+\"offauto\")\n    var n = \"NW\"+msg.req.params.input\n    msg.payload = {\n        \"wifirelay\":globalVar,\n        \"state\":global.get(globalVar),\n        \"name\":global.get(n),\n        \"autooff\": autooff\n    };\n}\nelse {\n    msg.payload = \"wifirelay \" + msg.req.params.input + \" does not exist\"\n}\n    \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":1720,"wires":[["a2c7311476d4c970"]]},{"id":"ac3c4fe5cd58e530","type":"http in","z":"e78e73d3.53155","name":"","url":"/toggle/wrelay/:input","method":"put","upload":false,"swaggerDoc":"","x":150,"y":1660,"wires":[["3afd7417681bcb87"]]},{"id":"3afd7417681bcb87","type":"function","z":"e78e73d3.53155","name":"check input and switch state","func":"function number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nif (isNaN(parseInt(msg.req.params.input)) == false){\n    var num = \"zero one two three four five six seven eight nine ten\".split(\" \");\n    msg.req.params.input = parseInt(msg.req.params.input)\n    msg.req.params.input = number2words(msg.req.params.input)\n}\n\nmsg.relay = \"W\"+msg.req.params.input;\n\nif (global.get(msg.relay) == true) {\n    msg.payload = false\n    msg.relaystate = msg.payload\n}\nelse if (global.get(msg.relay) == false) {\n    msg.payload = true\n    msg.relaystate = msg.payload\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":1660,"wires":[["5d26899bef877b6f","56e1abb5b2e7247e"]]},{"id":"5aec9fd67fb417a3","type":"http in","z":"e78e73d3.53155","name":"","url":"wrelay/","method":"get","upload":false,"swaggerDoc":"","x":110,"y":1760,"wires":[["8ab619cea79ce0b1"]]},{"id":"8ab619cea79ce0b1","type":"change","z":"e78e73d3.53155","name":"","rules":[{"t":"set","p":"req.params.input","pt":"msg","to":"all","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":1760,"wires":[["9c197e66867dcb29"]]},{"id":"937d5e03dd599a61","type":"link out","z":"e78e73d3.53155","name":"switch connect 1","links":["afbb8dda.ffe6c"],"x":995,"y":1460,"wires":[]},{"id":"1ef68c5891594021","type":"comment","z":"e78e73d3.53155","name":"endpoints relays","info":"","x":120,"y":1220,"wires":[]},{"id":"90aaa84e3c4647b5","type":"comment","z":"e78e73d3.53155","name":"endpoints wifirelays","info":"","x":130,"y":1540,"wires":[]},{"id":"b87b808afe6eb9ed","type":"comment","z":"e78e73d3.53155","name":"endpoints names","info":"","x":120,"y":240,"wires":[]},{"id":"04e90dc1676dd13a","type":"http in","z":"e78e73d3.53155","name":"","url":"dimmer/:input/:value","method":"put","upload":false,"swaggerDoc":"","x":150,"y":1900,"wires":[["4731f46fb5c68aa6"]]},{"id":"b987d9635c725793","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":570,"y":1940,"wires":[]},{"id":"4731f46fb5c68aa6","type":"function","z":"e78e73d3.53155","name":"check input and set global var","func":"function text2num(s) {\n    a = s.toString().split(/[\\s-]+/);\n    n = 0;\n    g = 0;\n    a.forEach(feach);\n    return n + g;\n}\n\nfunction feach(w) {\n    var x = input[w];\n    g = g + x;\n}\n\nfunction number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nvar num = \"zero one two three four five six seven eight nine ten\".split(\" \");\nvar input = { 'one': 0, 'two': 1, 'three': 2, 'four': 3, 'five': 4, 'six': 5, 'seven': 6, 'eight': 7};\nvar a, n, g, dimmerno;\n\n//check if input is a number\nif (isNaN(parseInt(msg.req.params.input)) == false) {\n    if (parseInt(msg.req.params.input) < 9 && parseInt(msg.req.params.input) > 0) {\n        msg.req.params.input = parseInt(msg.req.params.input)-1\n        msg.targetdimmerno = \"Ndimmer\"+msg.req.params.input.toString()\n        msg.req.params.input = parseInt(msg.req.params.input)+1\n        msg.dimmer = number2words(msg.req.params.input);\n        msg.newValue = parseInt(msg.req.params.value);\n    }\n    else {\n        msg.payload = \"dimmer \" + msg.req.params.input + \" does not exist\"\n        return [null, msg];\n    }\n}\nelse if (isNaN(parseInt(msg.req.params.input)) == true){\n    msg.dimmerno = text2num(msg.req.params.input);\n    msg.targetdimmerno = \"Ndimmer\"+msg.dimmerno.toString()\n    msg.dimmer = msg.req.params.input;\n    msg.newValue = parseInt(msg.req.params.value);\n}\n\nif (isNaN(msg.newValue) || msg.newValue < 0 || msg.newValue > 100) {\n    msg.payload = \"value type must be numeric and between 0-100\"\n    return [null, msg]\n}\nelse if (global.get(msg.targetdimmerno)!==undefined) {\n    msg.payload = msg.newValue\n    msg.label = global.get(msg.targetdimmerno)\n    return [msg, msg]\n}\nelse {\n    msg.payload = \"dimmer \" + msg.req.params.input + \" does not exist\"\n    return [null, msg];\n    \n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":1900,"wires":[["eaef487a095f1941"],["fc065be1e2a2befc"]]},{"id":"eaef487a095f1941","type":"switch","z":"e78e73d3.53155","name":"","property":"dimmer","propertyType":"msg","rules":[{"t":"cont","v":"one","vt":"str"},{"t":"cont","v":"two","vt":"str"},{"t":"cont","v":"three","vt":"str"},{"t":"cont","v":"four","vt":"str"},{"t":"cont","v":"five","vt":"str"},{"t":"cont","v":"six","vt":"str"},{"t":"cont","v":"seven","vt":"str"},{"t":"cont","v":"eight","vt":"str"}],"checkall":"false","repair":false,"outputs":8,"x":750,"y":1920,"wires":[["5c11b83dee20395c"],["943b6d53caa983d3"],["d237df5591cd888b"],["59f8057dce575916"],["d34f3ab8abe848f6"],["439c5c6219f2ad26"],["7cbbc3bbc7cca512"],["fa5e454b2672161d"]]},{"id":"5c11b83dee20395c","type":"link out","z":"e78e73d3.53155","name":"dimmer0 http","links":["a4c0fd66546e7864"],"x":995,"y":1800,"wires":[]},{"id":"943b6d53caa983d3","type":"link out","z":"e78e73d3.53155","name":"dimmer1 http","links":["1db51e9f7fe5ebea"],"x":995,"y":1840,"wires":[]},{"id":"d237df5591cd888b","type":"link out","z":"e78e73d3.53155","name":"dimmer2 http","links":["09bf8b5862924eed"],"x":995,"y":1880,"wires":[]},{"id":"59f8057dce575916","type":"link out","z":"e78e73d3.53155","name":"dimmer3 http","links":["4896e98db77c2f91"],"x":995,"y":1920,"wires":[]},{"id":"d34f3ab8abe848f6","type":"link out","z":"e78e73d3.53155","name":"dimmer4 http","links":["77683cc8a2a2dd71"],"x":995,"y":1960,"wires":[]},{"id":"439c5c6219f2ad26","type":"link out","z":"e78e73d3.53155","name":"dimmer5 http","links":["2530d817d07d6ef2"],"x":995,"y":2000,"wires":[]},{"id":"7cbbc3bbc7cca512","type":"link out","z":"e78e73d3.53155","name":"dimmer6 http","links":["d4e73c36b453526a"],"x":995,"y":2040,"wires":[]},{"id":"fa5e454b2672161d","type":"link out","z":"e78e73d3.53155","name":"dimmer7 http","links":["bd1237489ec8e5f3"],"x":995,"y":2080,"wires":[]},{"id":"fc065be1e2a2befc","type":"function","z":"e78e73d3.53155","name":"set answer","func":"if (msg.payload.toString().includes(\" must be numeric\") || msg.payload.toString().includes(\" does not exist\")){\n    return msg\n}\nelse {\n    msg.payload = {\n        \"dimmer\": msg.dimmer,\n        \"state\": msg.newValue\n    }\n    return msg\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":1940,"wires":[["b987d9635c725793"]]},{"id":"53e6240e6b18b304","type":"http in","z":"e78e73d3.53155","name":"","url":"dimmer/:input","method":"get","upload":false,"swaggerDoc":"","x":130,"y":2000,"wires":[["7fe809b2f568b3ee"]]},{"id":"f684785ea126e942","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":670,"y":2000,"wires":[]},{"id":"7fe809b2f568b3ee","type":"function","z":"e78e73d3.53155","name":"check input and get dimmer","func":"var a \nvar n \nvar g\n\nfunction text2num(s) {\n    a = s.toString().split(/[\\s-]+/);\n    n = 0;\n    g = 0;\n    a.forEach(feach);\n    return n + g;\n}\nfunction feach(w) {\n    var x = input[w];\n    g = g + x;\n}\nvar input = {'one': 0, 'two': 1, 'three': 2, 'four': 3, 'five': 4, 'six': 5, 'seven': 6, 'eight': 7};\nvar targetdimmerno;\nmsg.targetdimmerno = \"\"\n\n//check if input is a number\nif (isNaN(parseInt(msg.req.params.input)) == false) {\n    if (parseInt(msg.req.params.input) < 9) {\n        msg.req.params.input = parseInt(msg.req.params.input)-1\n        targetdimmerno = \"dimmer\"+msg.req.params.input.toString()\n        msg.req.params.input = parseInt(msg.req.params.input)+1\n    }\n}\nelse if (isNaN(parseInt(msg.req.params.input)) == true){\n    msg.dimmerno = text2num(msg.req.params.input);\n    targetdimmerno = \"dimmer\"+msg.dimmerno.toString()\n}\n\nif (msg.req.params.input==\"all\") {\n    msg.payload = {\n        \"dimmer1\": {\n            \"state\": parseInt(global.get(\"dimmer0\")),\n            \"name\":global.get(\"Ndimmer0\"),\n        },\n        \"dimmer2\": {\n            \"state\": parseInt(global.get(\"dimmer1\")),\n            \"name\":global.get(\"Ndimmer1\"),\n        },\n        \"dimmer3\": {\n            \"state\": parseInt(global.get(\"dimmer2\")),\n            \"name\":global.get(\"Ndimmer2\"),\n        },\n        \"dimmer4\": {\n            \"state\": parseInt(global.get(\"dimmer3\")),\n            \"name\":global.get(\"Ndimmer3\"),\n        },\n        \"dimmer5\": {\n            \"state\": parseInt(global.get(\"dimmer4\")),\n            \"name\":global.get(\"Ndimmer4\"),\n        },\n        \"dimmer6\": {\n            \"state\": parseInt(global.get(\"dimmer5\")),\n            \"name\":global.get(\"Ndimmer5\"),\n        },\n        \"dimmer7\": {\n            \"state\": parseInt(global.get(\"dimmer6\")),\n            \"name\": global.get(\"Ndimmer6\"),\n        }\n    }\n}\nelse if (global.get(targetdimmerno)!==undefined) {\n    msg.payload = {\n        \"dimmer\":msg.req.params.input,\n        \"state\": parseInt(global.get(targetdimmerno)),\n        \"name\":global.get(\"N\"+targetdimmerno)\n    };\n}\nelse {\n    msg.payload = \"dimmer \" + msg.req.params.input + \" does not exist\"\n}\nmsg.targetdimmerno = targetdimmerno\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":2000,"wires":[["f684785ea126e942"]]},{"id":"93928c757eed6cfd","type":"http in","z":"e78e73d3.53155","name":"","url":"dimmer/","method":"get","upload":false,"swaggerDoc":"","x":110,"y":2040,"wires":[["cca88e865aa363ef"]]},{"id":"cca88e865aa363ef","type":"change","z":"e78e73d3.53155","name":"","rules":[{"t":"set","p":"req.params.input","pt":"msg","to":"all","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":2040,"wires":[["7fe809b2f568b3ee"]]},{"id":"d0b5af1299c04c81","type":"comment","z":"e78e73d3.53155","name":"endpoints dimmers","info":"","x":130,"y":1860,"wires":[]},{"id":"2f5ffaba89fd012e","type":"http in","z":"e78e73d3.53155","name":"","url":"wrelay/:input/:value","method":"put","upload":false,"swaggerDoc":"","x":150,"y":1580,"wires":[["766532c5bcc4ca2d"]]},{"id":"766532c5bcc4ca2d","type":"function","z":"e78e73d3.53155","name":"check input and switch state","func":"function number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nif (isNaN(parseInt(msg.req.params.input)) == false){\n    var num = \"zero one two three four five six seven eight nine ten\".split(\" \");\n    msg.req.params.input = parseInt(msg.req.params.input)\n    msg.req.params.input = number2words(msg.req.params.input)\n}\n\nmsg.relay = \"W\"+msg.req.params.input;\n\nif (msg.req.params.value === \"true\") {\n    msg.payload = true\n    msg.relaystate = msg.payload\n    return [msg, msg];\n}\nelse if (msg.req.params.value === \"false\") {\n    msg.payload = false\n    msg.relaystate = msg.payload\n    return [msg, msg];\n}\nelse {\n    msg.payload = \"value can only be true or false\"\n    return [null, msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":1580,"wires":[["5d26899bef877b6f"],["56e1abb5b2e7247e"]]},{"id":"4ce25de51b4fb126","type":"http in","z":"e78e73d3.53155","name":"","url":"names/:input/:value","method":"put","upload":false,"swaggerDoc":"","x":150,"y":320,"wires":[["8baf068e4ca359dc"]]},{"id":"8baf068e4ca359dc","type":"function","z":"e78e73d3.53155","name":"check input and set name","func":"if (msg.req.params.input == \"level\") {\n    msg.req.params.input = \"Level\"\n}\n\nmsg.globalVar = \"N\"+msg.req.params.input;\n\nif (global.get(msg.globalVar)!==undefined) {\n    global.set(msg.globalVar, msg.req.params.value)\n\n    msg.payload = {\n            \"description\":msg.globalVar,\n            \"name\":global.get(msg.globalVar)\n    }\n    //answer http request\n    node.send([msg, null])\n    //set payload for textfield in dashboard\n    msg.payload = global.get(msg.globalVar)\n    return [null, msg]\n}\nelse {\n    msg.payload = \"global variable \" + msg.req.params.input + \" is not defined\";\n    return [msg, null]\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":320,"wires":[["e9be18c319bccfd1"],["34ed1bb765acddd3"]]},{"id":"961a8b6d41509271","type":"link out","z":"e78e73d3.53155","name":"http update names","links":["32ccfc50.e148f4","3f4ef597.ad8bba","478c01f0.b35c1","7e47707c.5fe7b"],"x":635,"y":240,"wires":[]},{"id":"6a2642e3f0b97b0e","type":"comment","z":"e78e73d3.53155","name":"endpoints heater","info":"","x":120,"y":2140,"wires":[]},{"id":"aadd4382540212d4","type":"http in","z":"e78e73d3.53155","name":"","url":"heater/:truefalse","method":"put","upload":false,"swaggerDoc":"","x":140,"y":2180,"wires":[["f485bcc1320b9dc1"]]},{"id":"29f59ca8fbe82d23","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":1050,"y":2220,"wires":[]},{"id":"8cc4bb4336555b86","type":"http in","z":"e78e73d3.53155","name":"","url":"heater/:truefalse/:temp","method":"put","upload":false,"swaggerDoc":"","x":160,"y":2300,"wires":[["e5286c54434be8bb"]]},{"id":"ce11f3c7edd3025d","type":"http in","z":"e78e73d3.53155","name":"","url":"heater/:truefalse/:temp/:time","method":"put","upload":false,"swaggerDoc":"","x":170,"y":2460,"wires":[["97686d9a1e813337"]]},{"id":"f97d3e1199c2bd50","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":1050,"y":2460,"wires":[]},{"id":"9218ac0d4df78330","type":"link out","z":"e78e73d3.53155","name":"http heater on","links":["eb1e92403a6a4490"],"x":995,"y":2140,"wires":[]},{"id":"25bbb2b2adaf0cf8","type":"link out","z":"e78e73d3.53155","name":"http heater off","links":["8114989ad3d836db"],"x":995,"y":2180,"wires":[]},{"id":"f485bcc1320b9dc1","type":"function","z":"e78e73d3.53155","name":"set heater settings","func":"if (msg.req.params.truefalse == \"true\") {\n    msg.payload = \"heater \" + msg.req.params.truefalse\n    node.send([msg, null, null])\n}\nelse if (msg.req.params.truefalse == \"false\") {\n    msg.payload = \"heater \" + msg.req.params.truefalse\n    node.send([null, msg, null])\n}\nelse {\n    msg.payload = \"heater can only be true or false\"\n}\nreturn [null, null, msg]","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":2180,"wires":[["9218ac0d4df78330"],["25bbb2b2adaf0cf8","c46d7b1dcb708251"],["29f59ca8fbe82d23","c46d7b1dcb708251"]]},{"id":"e5286c54434be8bb","type":"function","z":"e78e73d3.53155","name":"set heater settings w/ temp","func":"msg.req.params.temp = parseInt(msg.req.params.temp)\n\nif (msg.req.params.truefalse == \"true\") {\n    if (isNaN(msg.req.params.temp) == false) {\n        if (msg.req.params.temp < 2 || msg.req.params.temp > 35) {\n            msg.payload = \"temp value must be within 2 and 35\"\n        }\n        else {\n            msg.payload = parseInt(msg.req.params.temp)\n            node.send([msg, null, null])\n            msg.payload = \"heater \" + msg.req.params.truefalse + \" with target temperature \" + msg.req.params.temp    \n        }\n    }\n    else if (isNaN(msg.req.params.temp) == true) {\n        msg.payload = \"temp value must be numeric and between 12 and 35\"\n    }\n}\nelse if (msg.req.params.truefalse == \"false\") {\n    msg.payload = \"heater \" + msg.req.params.truefalse\n    node.send([null, msg, null])\n}\nelse {\n    msg.payload = \"heater can only be true or false\"\n}\nreturn [null, null, msg]","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":480,"y":2300,"wires":[["026555e3ad71e0cf"],["5776c022733c4136","c46d7b1dcb708251"],["5697815ee2579fe5","c46d7b1dcb708251"]]},{"id":"026555e3ad71e0cf","type":"link out","z":"e78e73d3.53155","name":"http heater on w/ temp","mode":"link","links":["788088e08e7292d0","eb1e92403a6a4490"],"x":995,"y":2260,"wires":[]},{"id":"5697815ee2579fe5","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":1050,"y":2340,"wires":[]},{"id":"5776c022733c4136","type":"link out","z":"e78e73d3.53155","name":"http heater off","mode":"link","links":["8114989ad3d836db"],"x":995,"y":2300,"wires":[]},{"id":"97686d9a1e813337","type":"function","z":"e78e73d3.53155","name":"set heater settings w/ temp & timer","func":"msg.req.params.temp = parseInt(msg.req.params.temp)\nmsg.req.params.time = parseInt(msg.req.params.time)\n\nif (msg.req.params.truefalse == \"true\") {\n    if (isNaN(msg.req.params.temp) == false) {\n        if (msg.req.params.temp < 2 || msg.req.params.temp > 35) {\n            msg.payload = \"temp value must be within 2 and 35\"\n        }\n        else {\n            if (isNaN(msg.req.params.time) == false) {\n                if (msg.req.params.time < 0 || msg.req.params.time > 600) {\n                    msg.payload = \"time value must be within 0 and 600\"\n                }\n                else {\n                    node.send([null, null, null, null, msg, null])\n                    if (msg.req.params.time == 0 || msg.req.params.time == 0.0) {\n                        msg.payload = msg.req.params.time\n                        node.send([null, null, null, null, null, msg])\n                        msg.payload = parseInt(msg.req.params.temp)\n                        node.send([msg, null, null, null, null, null])\n                        msg.payload = \"heater \" + msg.req.params.truefalse + \" with target temperature \" + msg.req.params.temp + \"°C, timer reset\"\n                        return[null, null, msg, null, null, null]\n                    }\n                    msg.timer = msg.req.params.time\n                    msg.delay = msg.timer*60000\n                    msg.payload = msg.req.params.time\n                    node.send([null, null, null, msg, null, msg])\n                    msg.payload = parseInt(msg.req.params.temp)\n                    node.send([msg, null, null, null, null, null])\n                    msg.payload = \"heater \" + msg.req.params.truefalse + \" with target temperature \" + msg.req.params.temp + \"°C and duration \" + msg.req.params.time + \"m\"\n                }\n            }\n        }\n    }\n    else if (isNaN(msg.req.params.temp) == true) {\n        msg.payload = \"temp value must be numeric and between 2 and 35\"\n    }\n}\nelse if (msg.req.params.truefalse == \"false\") {\n    msg.payload = \"heater \" + msg.req.params.truefalse\n    node.send([null, msg, null, null, msg, null])\n}\nelse {\n    msg.payload = \"heater can only be true or false\"\n}\nreturn [null, null, msg, null, null, null]","outputs":6,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":2460,"wires":[["e342e6035235dcf4"],["8d54b616c7e8feb5"],["f97d3e1199c2bd50"],["cf0e7d919697d7f9"],["c46d7b1dcb708251"],["8976e469b15db9cc"]]},{"id":"de9391849ee092b5","type":"delay","z":"e78e73d3.53155","name":"","pauseType":"delayv","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1040,"y":2500,"wires":[["9fb866bf4390d8d3"]]},{"id":"e342e6035235dcf4","type":"link out","z":"e78e73d3.53155","name":"http heater on w/ temp","mode":"link","links":["788088e08e7292d0","eb1e92403a6a4490"],"x":995,"y":2380,"wires":[]},{"id":"8d54b616c7e8feb5","type":"link out","z":"e78e73d3.53155","name":"http heater off","links":["8114989ad3d836db"],"x":995,"y":2420,"wires":[]},{"id":"c46d7b1dcb708251","type":"change","z":"e78e73d3.53155","name":"","rules":[{"t":"set","p":"reset","pt":"msg","to":"true","tot":"bool"}],"action":"","property":"","from":"","to":"","reg":false,"x":840,"y":2540,"wires":[["de9391849ee092b5"]]},{"id":"cf0e7d919697d7f9","type":"delay","z":"e78e73d3.53155","name":"","pauseType":"delay","timeout":"200","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":860,"y":2500,"wires":[["de9391849ee092b5"]]},{"id":"9fb866bf4390d8d3","type":"link out","z":"e78e73d3.53155","name":"http heater off","links":["8114989ad3d836db"],"x":1135,"y":2500,"wires":[]},{"id":"13b5cefbcd42f35a","type":"comment","z":"e78e73d3.53155","name":"API timer is not visible in dashboard!","info":"","x":180,"y":2400,"wires":[]},{"id":"4bdada802e6896da","type":"http in","z":"e78e73d3.53155","name":"","url":"names/:device/:input/:value","method":"put","upload":false,"swaggerDoc":"","x":170,"y":360,"wires":[["8527f2998f5d4380"]]},{"id":"8527f2998f5d4380","type":"function","z":"e78e73d3.53155","name":"check input and set name","func":"function text2numD(s) {\n    a = s.toString().split(/[\\s-]+/);\n    n = 0;\n    g = 0;\n    a.forEach(feachD);\n    return n + g;\n}\nfunction text2numT(s) {\n    a = s.toString().split(/[\\s-]+/);\n    n = 0;\n    g = 0;\n    a.forEach(feachT);\n    return n + g;\n}\n\nfunction feachD(w) {\n    var x = inputDimmer[w];\n    g = g + x;\n}\nfunction feachT(w) {\n    var x = inputOther[w];\n    g = g + x;\n}\n\nfunction number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nvar inputDimmer = {'one': 0, 'two': 1, 'three': 2, 'four': 3, 'five': 4, 'six': 5, 'seven': 6, 'eight': 7};\nvar inputOther = {'one': 1, 'two': 2, 'three': 3, 'four': 4, 'five': 5, 'six': 6, 'seven': 7, 'eight': 8, 'nine': 9, 'ten': 10};\nvar targetdevice;\nvar num;\nmsg.targetdevice = \"\"\nmsg.globalVar = \"\"\n\n//--------------------------------------------------------------\n//only use lower case letters when accessing API!\n\nif (msg.req.params.device == \"level\") {\n    msg.req.params.device = \"Level\"\n}\nif (msg.req.params.device == \"Wrelay\") {\n    msg.req.params.device = \"wrelay\"\n}\n\nif (msg.req.params.device == \"Level\" || msg.req.params.device == \"temp\" || msg.req.params.device == \"relay\" || msg.req.params.device == \"wrelay\" || msg.req.params.device == \"dimmer\") {\n    \n    \n    //check if device is \"dimmer\"\n    if (msg.req.params.device == \"dimmer\") {\n        if (isNaN(parseInt(msg.req.params.input)) == false) {\n            num = \"one two three four five six seven eight\".split(\" \");\n            if (parseInt(msg.req.params.input) < 9 && parseInt(msg.req.params.input) > 0) {\n                msg.req.params.input = parseInt(msg.req.params.input)-1\n                targetdevice = \"Ndimmer\"+msg.req.params.input.toString()\n                msg.req.params.input = parseInt(msg.req.params.input)+1\n                msg.dimmer = number2words(parseInt(msg.req.params.input));\n            }\n            else {\n                msg.payload = \"dimmer \" + msg.req.params.input + \" does not exist\"\n                return [msg, null];\n            }\n        }\n        else if (isNaN(parseInt(msg.req.params.input)) == true){\n            targetdevice = text2numD(msg.req.params.input);\n            targetdevice = \"Ndimmer\"+targetdevice.toString()\n            msg.dimmer = msg.req.params.input;\n            //msg.newValue = parseInt(msg.req.params.value);\n        }\n    }\n    \n    //check if device is \"temp\" or \"level\"\n    if (msg.req.params.device == \"temp\" || msg.req.params.device == \"Level\") {\n        if (isNaN(parseInt(msg.req.params.input)) == false) {\n            num = \"one two three four\".split(\" \");\n            if (parseInt(msg.req.params.input) < 5 && parseInt(msg.req.params.input) > 0) {\n                targetdevice = \"N\"+msg.req.params.device+msg.req.params.input.toString()\n                msg.temporlevel = number2words(parseInt(msg.req.params.input));\n            }\n            else {\n                msg.payload = msg.req.params.device+ \" \" + msg.req.params.input + \" does not exist\"\n                return [msg, null];\n            }\n        }\n        else if (isNaN(parseInt(msg.req.params.input)) == true){\n            targetdevice = text2numT(msg.req.params.input);\n            targetdevice = \"N\"+msg.req.params.device+targetdevice.toString()\n            msg.temporlevel = msg.req.params.input;\n            //msg.newValue = parseInt(msg.req.params.value);\n        }\n    }\n    // else (if device is \"relay\" or \"Wrelay\")\n    else {\n        if (isNaN(parseInt(msg.req.params.input)) == false){\n            num = \"zero one two three four five six seven eight nine ten\".split(\" \");\n            msg.req.params.input = parseInt(msg.req.params.input)\n            msg.req.params.input = number2words(msg.req.params.input)\n                if (msg.req.params.device === \"wrelay\") {\n                    targetdevice = \"NW\" + msg.req.params.input\n                }\n                else if (msg.req.params.device === \"relay\") {\n                    targetdevice = \"N\" + msg.req.params.input\n                }\n        }\n        else if (isNaN(parseInt(msg.req.params.input)) == true){\n                if (msg.req.params.device === \"wrelay\") {\n                    targetdevice = \"NW\" + msg.req.params.input\n                }\n                else if (msg.req.params.device === \"relay\") {\n                    targetdevice = \"N\" + msg.req.params.input\n                }\n        }\n    }\n    \n//--------------------------------------------------------------\n    \n    msg.globalVar = targetdevice\n    \n    if (global.get(msg.globalVar)!= undefined) {\n        global.set(msg.globalVar, msg.req.params.value)\n    \n        msg.payload = {\n                \"description\":msg.globalVar,\n                \"name\":global.get(msg.globalVar)\n        }\n        //answer http request\n        node.send([msg, null])\n        //set payload for textfield in dashboard\n        msg.payload = global.get(msg.globalVar)\n        return [null, msg]\n    }\n    else {\n        msg.payload = \"global variable \" + msg.req.params.input + \" is not defined for \" + msg.req.params.device;\n        return [msg, null]\n    }\n}\nelse {\n        msg.payload = \"device can only be 'temp', 'level', 'relay', 'wrelay' or 'dimmer'\"\n        return [msg, null]\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":360,"wires":[["e9be18c319bccfd1"],["34ed1bb765acddd3"]]},{"id":"dfe6ac35b535e163","type":"http in","z":"e78e73d3.53155","name":"","url":"bms","method":"get","upload":false,"swaggerDoc":"","x":100,"y":640,"wires":[["235bf538c950ef47"]]},{"id":"235bf538c950ef47","type":"function","z":"e78e73d3.53155","name":"get battery stats","func":"let bmsjson = {\n    \"BMSamps\":global.get(\"BMSamps\"),\n    \"BMScap\":global.get(\"BMScap\"),\n    \"BMScell1\":(global.get(\"BMScell1\")/1000).toFixed(2),\n    \"BMScell2\":(global.get(\"BMScell2\")/1000).toFixed(2),\n    \"BMScell3\":(global.get(\"BMScell3\")/1000).toFixed(2),\n    \"BMScell4\":(global.get(\"BMScell4\")/1000).toFixed(2),\n    \"BMSmaxcap\":global.get(\"BMSmaxcap\"),\n    \"BMSmaxvolt\":global.get(\"BMSmaxvolt\"),\n    \"BMSminvolt\":global.get(\"BMSminvolt\"),\n    \"BMSpower\":global.get(\"BMSpower\"),\n    \"BMSsoc\":global.get(\"BMSsoc\"),\n    \"BMStemp\":global.get(\"BMStemp\"),\n    \"BMSvolt\":global.get(\"BMSvolt\"),\n} ;   \n    msg.payload = bmsjson;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":640,"wires":[["15a044e2c38d465e"]]},{"id":"15a044e2c38d465e","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":450,"y":640,"wires":[]},{"id":"fd04752f42acafc2","type":"http in","z":"e78e73d3.53155","name":"","url":"conniot","method":"get","upload":false,"swaggerDoc":"","x":110,"y":680,"wires":[["b5fa3f5283a0028c"]]},{"id":"b5fa3f5283a0028c","type":"function","z":"e78e73d3.53155","name":"get connection","func":"let connectionjson = {\n    \"connection\": {\n        \"state\": true\n    }\n\n};   \nmsg.payload = connectionjson;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":680,"wires":[["23d691c5507e32d3"]]},{"id":"23d691c5507e32d3","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":450,"y":680,"wires":[]},{"id":"890d1f2042565f42","type":"http in","z":"e78e73d3.53155","name":"","url":"wrelayiot/","method":"get","upload":false,"swaggerDoc":"","x":120,"y":1800,"wires":[["e81813357c4b008d"]]},{"id":"636d5ddd84294f7f","type":"function","z":"e78e73d3.53155","name":"check input and get wrelay","func":"function number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nvar globalVar = \"W\"+msg.req.params.input\n\nif (isNaN(parseInt(msg.req.params.input)) == false){\n    var num = \"zero one two three four five six seven eight nine ten\".split(\" \");\n    msg.req.params.input = parseInt(msg.req.params.input)\n    msg.req.params.input = number2words(msg.req.params.input)\n    globalVar = \"W\"+msg.req.params.input\n}\n\nif (msg.req.params.input==\"all\") {\n    msg.payload = {\n        \"WifiRelay1\": {\n            \"state\":global.get(\"Wone\"),            \n            \"name\":global.get(\"NWone\"),\n        },\n        \"WifiRelay2\": {\n            \"state\":global.get(\"Wtwo\"),            \n            \"name\":global.get(\"NWtwo\"),\n        },\n        \"WifiRelay3\": {\n            \"state\":global.get(\"Wthree\"),            \n            \"name\":global.get(\"NWthree\"),\n        },\n        \"WifiRelay4\": {\n            \"state\":global.get(\"Wfour\"),            \n            \"name\":global.get(\"NWfour\"),\n        },\n        \"WifiRelay5\": {\n            \"state\":global.get(\"Wfive\"),            \n            \"name\":global.get(\"NWfive\"),\n        },\n        \"WifiRelay6\": {\n            \"state\":global.get(\"Wsix\"),            \n            \"name\":global.get(\"NWsix\"),\n        },\n        \"WifiRelay7\": {\n            \"state\":global.get(\"Wseven\"),            \n            \"name\":global.get(\"NWseven\"),\n        },\n        \"WifiRelay8\": {\n            \"state\":global.get(\"Weight\"),            \n            \"name\":global.get(\"NWeight\"),\n        }\n    };\n}\n\nelse if (global.get(globalVar)!==undefined) {\n    var n = \"NW\"+msg.req.params.input\n    msg.payload = {\n        \"wifirelay\":globalVar,\n        \"state\":global.get(globalVar),\n        \"name\":global.get(n),\n    };\n}\nelse {\n    msg.payload = \"wifirelay \" + msg.req.params.input + \" does not exist\"\n}\n    \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":620,"y":1800,"wires":[["a2c7311476d4c970"]]},{"id":"e81813357c4b008d","type":"change","z":"e78e73d3.53155","name":"","rules":[{"t":"set","p":"req.params.input","pt":"msg","to":"all","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":1800,"wires":[["636d5ddd84294f7f"]]},{"id":"ab37cf757e8ab171","type":"http in","z":"e78e73d3.53155","name":"","url":"wrelayiot/:input/:value","method":"put","upload":false,"swaggerDoc":"","x":150,"y":1620,"wires":[["766532c5bcc4ca2d"]]},{"id":"5f3b4ca1f4773780","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":450,"y":760,"wires":[]},{"id":"d02d07dd336ca10f","type":"function","z":"e78e73d3.53155","name":"reboot rpi","func":"let rebootjson = {\n    \"reboot_rpi\": {\n        \"state\": true\n    }\n\n};   \nmsg.payload = rebootjson;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":760,"wires":[["5f3b4ca1f4773780","033f10b03f32200b"]]},{"id":"4b522f61da35eaa9","type":"http in","z":"e78e73d3.53155","name":"","url":"reboot","method":"get","upload":false,"swaggerDoc":"","x":110,"y":760,"wires":[["d02d07dd336ca10f"]]},{"id":"0eb0f3ca8bced55d","type":"exec","z":"e78e73d3.53155","command":"sudo reboot","addpay":"","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":590,"y":800,"wires":[[],[],[]]},{"id":"033f10b03f32200b","type":"delay","z":"e78e73d3.53155","name":"5s","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":430,"y":800,"wires":[["0eb0f3ca8bced55d"]]},{"id":"e0d0fb4aa408cd1e","type":"http in","z":"e78e73d3.53155","name":"","url":"relayiot/","method":"get","upload":false,"swaggerDoc":"","x":110,"y":1480,"wires":[["3cc12295a0acee87"]]},{"id":"3cc12295a0acee87","type":"change","z":"e78e73d3.53155","name":"","rules":[{"t":"set","p":"req.params.input","pt":"msg","to":"all","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":320,"y":1480,"wires":[["55775742497477e5"]]},{"id":"55775742497477e5","type":"function","z":"e78e73d3.53155","name":"check input and get relay","func":"function number2words(n){\n    if (n < 20) return num[n];\n    var digit = n%10;\n    return number2words(~~(n/1000)) + \" thousand\" + (n%1000 != 0? \" \" + number2words(n%1000): \"\");\n}\n\nvar globalVar = msg.req.params.input\n\nif (isNaN(parseInt(msg.req.params.input)) == false){\n    var num = \"zero one two three four five six seven eight nine ten\".split(\" \");\n    msg.req.params.input = parseInt(msg.req.params.input)\n    msg.req.params.input = number2words(msg.req.params.input)\n    globalVar = msg.req.params.input\n}\n\nif (msg.req.params.input==\"all\") {\n    msg.payload = {\n        \"Relay1\": {\n            \"state\":global.get(\"one\"),            \n            \"name\":global.get(\"None\"),\n            //\"autooff\": global.get(\"oneoffauto\")\n        },\n        \"Relay2\": {\n            \"state\":global.get(\"two\"),            \n            \"name\":global.get(\"Ntwo\"),\n            //\"autooff\": global.get(\"twooffauto\")\n        },\n        \"Relay3\": {\n            \"state\":global.get(\"three\"),            \n            \"name\":global.get(\"Nthree\"),\n            //\"autooff\": global.get(\"threeoffauto\")\n        },\n        \"Relay4\": {\n            \"state\":global.get(\"four\"),            \n            \"name\":global.get(\"Nfour\"),\n            //\"autooff\": global.get(\"fouroffauto\")\n        },\n        \"Relay5\": {\n            \"state\":global.get(\"five\"),            \n            \"name\":global.get(\"Nfive\"),\n            //\"autooff\": global.get(\"fiveoffauto\")\n        },\n        \"Relay6\": {\n            \"state\":global.get(\"six\"),            \n            \"name\":global.get(\"Nsix\"),\n            //\"autooff\": global.get(\"sixoffauto\")\n        },\n        \"Relay7\": {\n            \"state\":global.get(\"seven\"),            \n            \"name\":global.get(\"Nseven\"),\n            //\"autooff\": global.get(\"sevenoffauto\")\n        },\n        \"Relay8\": {\n            \"state\":global.get(\"eight\"),            \n            \"name\":global.get(\"Neight\"),\n            //\"autooff\": global.get(\"eightoffauto\")\n        },\n        \"Relay9\": {\n            \"state\":global.get(\"nine\"),            \n            \"name\":global.get(\"Nnine\"),\n            //\"autooff\": global.get(\"oneoffauto\")\n        },\n        \"Relay10\": {\n            \"state\":global.get(\"ten\"),            \n            \"name\":global.get(\"Nten\"),\n            //\"autooff\": global.get(\"oneoffauto\")\n        }\n    };\n}\nelse if (global.get(msg.req.params.input)!==undefined) {\n    var n = \"N\"+msg.req.params.input\n    var autooff = global.get(msg.req.params.input+\"offauto\")\n    msg.payload = {\n        \"relay\":msg.req.params.input,\n        \"state\":global.get(msg.req.params.input),\n        \"name\":global.get(n),\n        //\"autooff\": autooff\n    };\n}\nelse {\n    msg.payload = \"relay \" + msg.req.params.input + \" does not exist\"\n}\n    \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":630,"y":1480,"wires":[["24ec5317eca5f0fb"]]},{"id":"a2480738462df03d","type":"http in","z":"e78e73d3.53155","name":"","url":"debug","method":"get","upload":false,"swaggerDoc":"","x":110,"y":720,"wires":[["a19d1bc659618942"]]},{"id":"a19d1bc659618942","type":"function","z":"e78e73d3.53155","name":"debug info","func":"msg.payload = {\n    \"version\":global.get(\"currentVersion\"),\n    \"wifiIP\":global.get(\"wifiIP\"),\n    \"eth0IP\":global.get(\"eth0IP\"),\n    \"BatteryDataDelivery\":global.get(\"BatteryDataDelivery\"),\n    \"accesspoint\":global.get(\"accesspoint\"),\n    \"pkwshuntactive\":global.get(\"pkwshuntactive\"),\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":270,"y":720,"wires":[["6f4b1984b6b545ed"]]},{"id":"6f4b1984b6b545ed","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":450,"y":720,"wires":[]},{"id":"d6896f1d6e9fe09d","type":"http in","z":"e78e73d3.53155","name":"","url":"/attime","method":"put","upload":false,"swaggerDoc":"","x":110,"y":3100,"wires":[["e60a32d21c8c4492"]]},{"id":"01a934bba9cede4c","type":"http response","z":"e78e73d3.53155","name":"http (200)","statusCode":"200","headers":{},"x":460,"y":3140,"wires":[]},{"id":"73015f47095b7f66","type":"split","z":"e78e73d3.53155","name":"","splt":"=","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":450,"y":3100,"wires":[["f3881285a5493a26"]]},{"id":"f3881285a5493a26","type":"split","z":"e78e73d3.53155","name":"","splt":"&","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":570,"y":3100,"wires":[["026b2fbf4f2571af"]]},{"id":"026b2fbf4f2571af","type":"change","z":"e78e73d3.53155","name":"","rules":[{"t":"change","p":"payload","pt":"msg","from":"date","fromt":"str","to":"","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"time","fromt":"str","to":"","tot":"str"},{"t":"change","p":"payload","pt":"msg","from":"gmt","fromt":"str","to":"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":730,"y":3100,"wires":[["a2d9b11cf030ea23"]]},{"id":"a2d9b11cf030ea23","type":"function","z":"e78e73d3.53155","name":"reformat","func":"if (msg.payload == \"\") {\n    return null\n}\nif (msg.payload.includes(\"/\")) {\n    msg.topic = \"date\"\n    var year = msg.payload.substring(0,2)\n    var month = msg.payload.substring(3,5)\n    var day = msg.payload.substring(6,8)\n    msg.payload = day + \".\" + month + \".\" + year\n}\nif (msg.payload.includes(\":\")) {\n    msg.topic = \"time\"\n}\nif (msg.payload.includes(\"+\") || msg.payload.includes(\"-\")) {\n    msg.topic = \"gmt\"\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":900,"y":3100,"wires":[["efcc9f88eab5bc52"]]},{"id":"efcc9f88eab5bc52","type":"join","z":"e78e73d3.53155","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"","count":"3","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":1030,"y":3100,"wires":[["818b23cfc9267063"]]},{"id":"818b23cfc9267063","type":"function","z":"e78e73d3.53155","name":"set exec payload","func":"var year = \"20\"+msg.payload.date.substring(msg.payload.date.length-2)\nvar month = msg.payload.date.substring(3,5)\nvar day = msg.payload.date.substring(0,2)\n\nmsg.payload = \"sudo date -s '\" +year + \"-\" + month + \"-\" + day + \" \" + msg.payload.time +\"'\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1190,"y":3100,"wires":[["60fdd0513d372a74"]]},{"id":"60fdd0513d372a74","type":"exec","z":"e78e73d3.53155","command":"","addpay":"payload","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"set date/time","x":1370,"y":3100,"wires":[[],[],[]]},{"id":"77d6cd751c9186e1","type":"comment","z":"e78e73d3.53155","name":"(click for instructions) Set system time (Turn off network time sync in frontend!)","info":"Format needs to be\n\nIP:PORT/attime?date=YY/MM/DD&time=hh:mm:ss&gmt=+04\n\nwith gmt being 15min steps, so range is -48 to +48\n\nHeaders are \"Content-Type: text/html; charset=utf-8\"","x":310,"y":3060,"wires":[]},{"id":"e60a32d21c8c4492","type":"function","z":"e78e73d3.53155","name":"check payload","func":"if (global.get(\"timesyncd\") == \"inactive\") {\n    msg.payload = (msg.payload == \"\" ? msg.req.url : msg.payload)\n    return [msg, null]\n}\nelse if (global.get(\"timesyncd\") == \"active\") {\n    msg.payload = \"network timesync is active\"\n    return [null, msg]\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":3100,"wires":[["73015f47095b7f66","01a934bba9cede4c"],["01a934bba9cede4c"]]},{"id":"542a2c9f0ca623ea","type":"http in","z":"e78e73d3.53155","name":"","url":"switchall/:truefalse","method":"put","upload":false,"swaggerDoc":"","x":140,"y":2840,"wires":[["616ae227b7d1006f","fcbb89cd0e972cfa"]]},{"id":"f50fd70f9c6826f3","type":"comment","z":"e78e73d3.53155","name":"endpoint toggle all on/off (relays, w-relays, dimmers)","info":"","x":230,"y":2800,"wires":[]},{"id":"a87e79fb235e68f4","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":550,"y":2900,"wires":[]},{"id":"616ae227b7d1006f","type":"function","z":"e78e73d3.53155","name":"check true or false","func":"if (msg.req.params.truefalse == \"false\") {\n    return [msg, null]\n}\nelse if (msg.req.params.truefalse ==  \"true\") {\n    return [null, msg]\n}\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":2840,"wires":[["de95656a18aa0369"],["3ae13fe66c9c4fd2"]]},{"id":"fcbb89cd0e972cfa","type":"function","z":"e78e73d3.53155","name":"set answer","func":"if (msg.req.params.truefalse == \"false\") {\n    msg.payload = {\n        \"switchall\":\"false\"\n    }\n}\nelse if (msg.req.params.truefalse == \"true\") {\n    msg.payload = \"turning everything back on from memory is yet not implemented!\"   \n}\n\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":2900,"wires":[["a87e79fb235e68f4"]]},{"id":"3fe38c2d6edc0c84","type":"link out","z":"e78e73d3.53155","name":"http switchall relays/wrelays off","mode":"link","links":["1be6547089f6e149","1d05179e.1f1a78","2840c10.f61294","33a5d09e.6cc14","34f49f08e1a06032","38796905.f4b7f6","428f4d48.86eaf4","7255f9f4.6304d8","9f1c7c65c2da2d42","afbb8dda.ffe6c","c698c6e8.416b58","c9adec52.63ae6","d2ce5044.ef8af","d76c3b78c0f14e69","e9ffa3ef.cde5d","f14867fc.930ab8"],"x":1115,"y":2800,"wires":[]},{"id":"de95656a18aa0369","type":"function","z":"e78e73d3.53155","name":"set globals","func":"//save current global states\nmsg.payload = {\n    \"one\": global.get(\"one\"),\n    \"two\": global.get(\"two\"),\n    \"three\": global.get(\"three\"),\n    \"four\": global.get(\"four\"),\n    \"five\": global.get(\"five\"),\n    \"six\": global.get(\"six\"),\n    \"seven\": global.get(\"seven\"),\n    \"eight\": global.get(\"eight\"),\n    \"Wone\": global.get(\"Wone\"),\n    \"Wtwo\": global.get(\"Wtwo\"),\n    \"Wthree\": global.get(\"Wthree\"),\n    \"Wfour\": global.get(\"Wfour\"),\n    \"Wfive\": global.get(\"Wfive\"),\n    \"Wsix\": global.get(\"Wsix\"),\n    \"Wseven\": global.get(\"Wseven\"),\n    \"Weight\": global.get(\"Weight\"),\n    \"dimmer0\": global.get(\"dimmer0\"),\n    \"dimmer1\": global.get(\"dimmer1\"),\n    \"dimmer2\": global.get(\"dimmer2\"),\n    \"dimmer3\": global.get(\"dimmer3\"),\n    \"dimmer4\": global.get(\"dimmer4\"),\n    \"dimmer5\": global.get(\"dimmer5\"),\n    \"dimmer6\": global.get(\"dimmer6\"),\n    \"dimmer7\": global.get(\"dimmer7\")\n}\n\n//turn all globals off\nglobal.set(\"one\", false)\nglobal.set(\"two\", false)\nglobal.set(\"three\", false)\nglobal.set(\"four\", false)\nglobal.set(\"five\", false)\nglobal.set(\"six\", false)\nglobal.set(\"seven\", false)\nglobal.set(\"eight\", false)\nglobal.set(\"Wone\", false)\nglobal.set(\"Wtwo\", false)\nglobal.set(\"Wthree\", false)\nglobal.set(\"Wfour\", false)\nglobal.set(\"Wfive\", false)\nglobal.set(\"Wsix\", false)\nglobal.set(\"Wseven\", false)\nglobal.set(\"Weight\", false)\nglobal.set(\"dimmer0\", 0)\nglobal.set(\"dimmer1\", 0)\nglobal.set(\"dimmer2\", 0)\nglobal.set(\"dimmer3\", 0)\nglobal.set(\"dimmer4\", 0)\nglobal.set(\"dimmer5\", 0)\nglobal.set(\"dimmer6\", 0)\nglobal.set(\"dimmer7\", 0)\n    \nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":630,"y":2820,"wires":[["8c191f1ddb4a9e61"]]},{"id":"8c191f1ddb4a9e61","type":"file","z":"e78e73d3.53155","name":"","filename":"pekaway/switchall","appendNewline":false,"createDir":true,"overwriteFile":"true","encoding":"none","x":830,"y":2820,"wires":[["d3f7d57b888ae358"]]},{"id":"3ae13fe66c9c4fd2","type":"file in","z":"e78e73d3.53155","name":"","filename":"pekaway/switchall","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":650,"y":2860,"wires":[["fbb0856682157ebe"]]},{"id":"fbb0856682157ebe","type":"json","z":"e78e73d3.53155","name":"","property":"payload","action":"","pretty":false,"x":830,"y":2860,"wires":[["b29bf552eb93a13b"]]},{"id":"d3f7d57b888ae358","type":"function","z":"e78e73d3.53155","name":"turn off","func":"//turn off relays & w-relays\nmsg.payload = false\nnode.send([msg, null])\n//turn off dimmers\nvar dimmervalue = 0\nvar i = 1\nwhile (i < 9) {\n    msg.url = \"http://127.0.0.1:1880/dimmer/\" + i +\"/\" + dimmervalue\n    msg.payload = \"\"\n    node.send([null, msg])\n    i = i + 1\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":990,"y":2820,"wires":[["3fe38c2d6edc0c84"],["d6c0637581ab0b06"]]},{"id":"d6c0637581ab0b06","type":"http request","z":"e78e73d3.53155","name":"dimmers off","method":"PUT","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":1170,"y":2840,"wires":[[]]},{"id":"af04e125a02e7e81","type":"http in","z":"e78e73d3.53155","name":"","url":"info/","method":"get","upload":false,"swaggerDoc":"","x":100,"y":3000,"wires":[["3610a0e28dfa7021"]]},{"id":"3610a0e28dfa7021","type":"function","z":"e78e73d3.53155","name":"get variables","func":"msg.payload = {\n    \"VanPi_Ctrl\": global.get(\"currentVersion\"),\n    \"install_date\": global.get(\"installdate\"),\n    \"current_date\": new Date().toLocaleString(),\n    \"uptime\": global.get(\"uptime\").trim(),\n    \"van_name\": global.get(\"van_name\"),\n    \"cpu_temp\": global.get(\"rpi_cpu_temp\"),\n    \"cpu_usage\": global.get(\"rpi_cpu_usage\"),\n    \"ttgo\": global.get(\"ttgo\"),\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":290,"y":3000,"wires":[["c1249b3174e91f47"]]},{"id":"fd8dd0dde3d5c912","type":"comment","z":"e78e73d3.53155","name":"endpoint get some general information about the system","info":"","x":240,"y":2960,"wires":[]},{"id":"c1249b3174e91f47","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":470,"y":3000,"wires":[]},{"id":"6f7685fb79ce0438","type":"link out","z":"e78e73d3.53155","name":"Ndimmytemp1","mode":"link","links":["e5ec8a87df41929d"],"x":1015,"y":700,"wires":[]},{"id":"761da5923e187298","type":"link out","z":"e78e73d3.53155","name":"Ndimmytemp2","mode":"link","links":["e834be69d9ff260b"],"x":1015,"y":720,"wires":[]},{"id":"42e02e39624a5cb2","type":"http in","z":"e78e73d3.53155","name":"","url":"reset_wifi_ap/:input","method":"put","upload":false,"swaggerDoc":"","x":150,"y":900,"wires":[["6a5a6cd3aad7c7e9","328d22e9e47a30a2"]]},{"id":"328d22e9e47a30a2","type":"function","z":"e78e73d3.53155","name":"check input","func":"if (msg.req.params.input == \"true\") {\n    let resetjson = {\n        \"reset_wifiAP\": {\n            \"state\": true\n        }\n    };   \n    msg.payload = resetjson;\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":940,"wires":[["b110837e6b592954"]]},{"id":"d955441457ae8497","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":650,"y":900,"wires":[]},{"id":"8a6bd10dd566d096","type":"link out","z":"e78e73d3.53155","name":"reset wifiAP","mode":"link","links":["53610bbf2e35371a"],"x":745,"y":940,"wires":[]},{"id":"b110837e6b592954","type":"function","z":"e78e73d3.53155","name":"set payload OK","func":"msg.payload = \"OK\";\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":520,"y":940,"wires":[["8a6bd10dd566d096"]]},{"id":"6a5a6cd3aad7c7e9","type":"delay","z":"e78e73d3.53155","name":"3s","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":330,"y":900,"wires":[["cf9884f4e4493203"]]},{"id":"cf9884f4e4493203","type":"function","z":"e78e73d3.53155","name":"check input","func":"if (msg.req.params.input == \"true\") {\n    let resetjson = {\n        \"reset_wifiAP\": {\n            \"state\": true,\n            \"ssid\": global.get(\"ssid\").substring(5),\n            \"wpa\": global.get(\"wpa\")\n        }\n    };\n    msg.payload = resetjson;\n    return msg;\n}\nelse {\n    let resetjson = {\n        \"reset_wifiAP\": {\n            \"state\": false,\n            \"error\": \"endpoint to hit needs parameter true ('<ip>:1880/reset_wifiAP/true')\"\n        }\n    };\n    msg.payload = resetjson;\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":900,"wires":[["d955441457ae8497"]]},{"id":"c3e884d6b59ebf48","type":"http in","z":"e78e73d3.53155","name":"","url":"network","method":"get","upload":false,"swaggerDoc":"","x":110,"y":860,"wires":[["252b57b56a81916a"]]},{"id":"252b57b56a81916a","type":"exec","z":"e78e73d3.53155","command":"sudo ifconfig wlan0 | sed -En -e 's/.*inet ([0-9.]+).*/\\1/p'","addpay":false,"append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"check ip wlan0","x":280,"y":860,"wires":[["68b73acc3c84685f"],[],[]]},{"id":"68b73acc3c84685f","type":"function","z":"e78e73d3.53155","name":"set payload","func":"msg.wlan0 = msg.payload\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":860,"wires":[["138895d07b51385c"]]},{"id":"2d5f44fe81f2fc48","type":"exec","z":"e78e73d3.53155","command":"sudo ifconfig eth0 | sed -En -e 's/.*inet ([0-9.]+).*/\\1/p'","addpay":false,"append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"check ip eth0","x":910,"y":860,"wires":[["ddd02c9281315ad3"],[],[]]},{"id":"ddd02c9281315ad3","type":"function","z":"e78e73d3.53155","name":"set payload","func":"msg.eth0 = msg.payload\n\nlet networkjson = {\n    \"network\": {\n        \"ap_state\": global.get(\"accesspoint\"),\n        \"ap_ssid\": global.get(\"ssid\"),\n        \"ap_wpa\": global.get(\"wpa\"),\n        \"wlan0_ip\": msg.wlan0.trim(),\n        \"connected to\": msg.ssid,\n        \"eth0_ip\": msg.eth0.trim()\n    }\n};\nmsg.payload = networkjson;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1070,"y":860,"wires":[["5adccb99ea240bab"]]},{"id":"138895d07b51385c","type":"exec","z":"e78e73d3.53155","command":"iwgetid | cut -d \":\" -f2-","addpay":"","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"get SSID","x":600,"y":860,"wires":[["007593b8fcfe63cb"],[],[]]},{"id":"007593b8fcfe63cb","type":"function","z":"e78e73d3.53155","name":"set payload","func":"if (msg.payload != \"\") {\n    msg.ssid = msg.payload.trim()\n}\nelse {\n    msg.ssid = \"\"\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":750,"y":860,"wires":[["2d5f44fe81f2fc48"]]},{"id":"5adccb99ea240bab","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":1230,"y":860,"wires":[]},{"id":"3c9c6cc3bf6fee8e","type":"comment","z":"e78e73d3.53155","name":"endpoints network","info":"","x":130,"y":820,"wires":[]},{"id":"049e2d2e9ab3c402","type":"http in","z":"e78e73d3.53155","name":"","url":"update_wifi_ap/:ssid/:wpa","method":"put","upload":false,"swaggerDoc":"","x":170,"y":980,"wires":[["c30a5229b4c47747"]]},{"id":"c30a5229b4c47747","type":"function","z":"e78e73d3.53155","name":"check input","func":"let ssid = msg.req.params.ssid + \"_pekaway.com\"\nlet wpa = msg.req.params.wpa\nlet wifiAPjson = {}\n    \nif (wpa.length < 8 || wpa.length > 63) {\n    wifiAPjson = {\n        \"wifiAP\": {\n            \"updated\": false,\n            \"ssid\": ssid,\n            \"wpa\": wpa,\n            \"error\":\"Passphrase needs to be between 8 and 63 characters long!\"\n        }\n    }\n    msg.payload = wifiAPjson\n    return [msg, null]\n}\n\nelse {\n    wifiAPjson = {\n        \"wifiAP\": {\n            \"updated\": true,\n            \"ssid\": ssid,\n            \"wpa\": wpa,\n            \"reboot\": true\n        }\n    }\n    global.set(\"wpa\", wpa)\n    global.set(\"ssid\", ssid)\n    msg.payload = wifiAPjson\n\n    return [null, msg]\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":980,"wires":[["b1ee1c2b5aabc9dd"],["b1ee1c2b5aabc9dd","349299c7e8f20aec"]]},{"id":"b1ee1c2b5aabc9dd","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":610,"y":980,"wires":[]},{"id":"3568302164bf5c67","type":"link out","z":"e78e73d3.53155","name":"update wifiAP","mode":"link","links":["4db059e1118648d3"],"x":745,"y":1020,"wires":[]},{"id":"349299c7e8f20aec","type":"function","z":"e78e73d3.53155","name":"set payload OK","func":"msg = {\n    \"payload\": \"OK\",\n    \"ssid\": global.get(\"ssid\"),\n    \"wpa\": global.get(\"wpa\")\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":620,"y":1020,"wires":[["3568302164bf5c67"]]},{"id":"badd957725934738","type":"http in","z":"e78e73d3.53155","name":"","url":"activate_wifi_ap/:input","method":"put","upload":false,"swaggerDoc":"","x":160,"y":1080,"wires":[["127692c2434841af"]]},{"id":"127692c2434841af","type":"function","z":"e78e73d3.53155","name":"check input","func":"let input = msg.req.params.input\nmsg.input = input,\nmsg.ap_state_old = global.get(\"accesspoint\")\nnode.send([msg, null, null])\n\nif (input == \"true\") {\n    msg.payload = \"Ok!\"\n    return [null, msg, null]\n}\nelse if (input == \"false\") {\n    msg.payload = \"Ok!\"\n    return [null, null, msg]\n}","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":1080,"wires":[["a45f20d3a8342422"],["284f7d986075218f"],["4251953a5d2e02b9"]]},{"id":"284f7d986075218f","type":"link out","z":"e78e73d3.53155","name":"switch to access point","mode":"link","links":["f466a3bb3fc1964f"],"x":635,"y":1100,"wires":[]},{"id":"4251953a5d2e02b9","type":"link out","z":"e78e73d3.53155","name":"turn off access point","mode":"link","links":["ac75384ae361d2e5"],"x":635,"y":1140,"wires":[]},{"id":"18e6f26f455ccfec","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":890,"y":1060,"wires":[]},{"id":"ffe2c321ba6998f1","type":"function","z":"e78e73d3.53155","name":"set answer","func":"msg.payload.ap_state_new = global.get(\"accesspoint\")\nlet ap_state_old = msg.ap_state_old\nlet input = msg.input;\nlet reboot\n\nif (input == \"false\" ||input == false) {\n    reboot = \"false\"\n    msg.payload = {\n        \"input\": input,\n        \"ap_state_old\": ap_state_old,\n        \"ap_state_new\": global.get(\"accesspoint\"),\n        \"reboot\": reboot\n    }\n}\nelse if (input == \"true\" || input == true) {\n    reboot = true\n    msg.payload = {\n        \"input\": input,\n        \"ap_state_old\": ap_state_old,\n        \"ap_state_new\": global.get(\"accesspoint\"),\n        \"reboot\": reboot\n    }\n}\n\nelse {\n    msg.payload = {\n        \"input\": input,\n        \"error\": \"input can only be 'true' or 'false'\"\n    }\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":1060,"wires":[["18e6f26f455ccfec"]]},{"id":"a45f20d3a8342422","type":"delay","z":"e78e73d3.53155","name":"0.5s","pauseType":"delay","timeout":"0.5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":550,"y":1060,"wires":[["ffe2c321ba6998f1"]]},{"id":"18248bd261f66d64","type":"http in","z":"e78e73d3.53155","name":"","url":"autoterm/:ventilation_heatingpower/:value","method":"put","upload":false,"swaggerDoc":"","x":220,"y":2620,"wires":[["2848c586d7fef769"]]},{"id":"f9d7671cd7a7eb65","type":"comment","z":"e78e73d3.53155","name":"endpoint autoterm specific (ventilation, heatingpower) (EXPERIMENTAL)","info":"","x":300,"y":2580,"wires":[]},{"id":"2848c586d7fef769","type":"function","z":"e78e73d3.53155","name":"set heater settings w/ temp","func":"msg.req.params.value = parseInt(msg.req.params.value)\n\nif (msg.req.params.ventilation_heatingpower == \"ventilation\") {\n    if (isNaN(msg.req.params.value) == false) {\n        if (msg.req.params.temp < 11 || msg.req.params.temp >= 0) {\n            msg.payload = \"ventilation value must be within 0 and 10\"\n        }\n        else {\n            msg.payload = parseInt(msg.req.params.value)\n            node.send([msg, null, null])\n            msg.payload = \"autoterm \" + msg.req.params.ventilation_heatingpower + \" with target value \" + msg.req.params.value    \n        }\n    }\n    else if (isNaN(msg.req.params.temp) == true) {\n        msg.payload = \"ventilation value must be numeric and between 0 and 10\"\n    }\n}\nelse if (msg.req.params.ventilation_heatingpower == \"heatingpower\") {\n    if (isNaN(msg.req.params.value) == false) {\n        if (msg.req.params.temp < 11 || msg.req.params.temp >= 0) {\n            msg.payload = \"heatingpower value must be within 0 and 10\"\n        }\n        else {\n            msg.payload = parseInt(msg.req.params.value)\n            node.send([msg, null, null])\n            msg.payload = \"autoterm \" + msg.req.params.ventilation_heatingpower + \" with target value \" + msg.req.params.value\n        }\n    }\n    else if (isNaN(msg.req.params.temp) == true) {\n        msg.payload = \"heatingpower value must be numeric and between 0 and 10\"\n    }\n}\n\nelse {\n    msg.payload = \"autoterm specific commands can only be 'ventilation' or 'heatingpower'\"\n}\nreturn [null, null, msg]","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":680,"y":2620,"wires":[["5be81bd5b43f94d0"],["572f63b680e321fc"],["9b9f0894ba084cdf"]]},{"id":"9b9f0894ba084cdf","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":1039,"y":2658,"wires":[]},{"id":"5be81bd5b43f94d0","type":"link out","z":"e78e73d3.53155","name":"http autoterm ventilation","mode":"link","links":["f9d784ab7f323cf6"],"x":985,"y":2580,"wires":[]},{"id":"572f63b680e321fc","type":"link out","z":"e78e73d3.53155","name":"http autoterm heatingpower","mode":"link","links":["e6f5d17b430ade7b"],"x":985,"y":2620,"wires":[]},{"id":"8976e469b15db9cc","type":"link out","z":"e78e73d3.53155","name":"http heater on w/ temp for runtime","mode":"link","links":["093319b1a513fb43"],"x":775,"y":2580,"wires":[]},{"id":"be4eb9d57f984b56","type":"http in","z":"e78e73d3.53155","name":"","url":"gps","method":"get","upload":false,"swaggerDoc":"","x":100,"y":3240,"wires":[["d7ba0acc80ad79e7"]]},{"id":"d7ba0acc80ad79e7","type":"function","z":"e78e73d3.53155","name":"get variables","func":"msg.payload = {\n    \"lat\": parseFloat(global.get(\"latitude\")),\n    \"lon\": parseFloat(global.get(\"longitude\")),\n    \"date\": global.get(\"gps_updated\") || \"\",\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":290,"y":3240,"wires":[["0c08bcc5d5494f65"]]},{"id":"07ea2b2a8b03c5ac","type":"comment","z":"e78e73d3.53155","name":"endpoint gps position","info":"","x":140,"y":3200,"wires":[]},{"id":"0c08bcc5d5494f65","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":470,"y":3240,"wires":[]},{"id":"866cbbd5709bd9dc","type":"inject","z":"e78e73d3.53155","name":"Halle","props":[{"p":"lat","v":"51.483334","vt":"num"},{"p":"topic","vt":"str"},{"p":"lon","v":"11.966667","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":990,"y":3520,"wires":[["23e278c7fc4c6dfe"]]},{"id":"23e278c7fc4c6dfe","type":"function","z":"e78e73d3.53155","name":"gps pos test","func":"let date = new Date()\nglobal.set(\"gps_updated\", date)\nglobal.set(\"latitude\", msg.lat)\nglobal.set(\"longitude\", msg.lon)\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1310,"y":3520,"wires":[["9ba48d39cbfd747d"]]},{"id":"47fd747da834db6b","type":"inject","z":"e78e73d3.53155","name":"Rostock","props":[{"p":"lat","v":"54.146520","vt":"num"},{"p":"topic","vt":"str"},{"p":"lon","v":"12.134871","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"60","topic":"","x":1000,"y":3560,"wires":[["23e278c7fc4c6dfe"]]},{"id":"3063741daa56f462","type":"inject","z":"e78e73d3.53155","name":"Malaga","props":[{"p":"lat","v":"36.703500","vt":"num"},{"p":"topic","vt":"str"},{"p":"lon","v":"-4.439922","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"120","topic":"","x":990,"y":3600,"wires":[["23e278c7fc4c6dfe"]]},{"id":"9ba48d39cbfd747d","type":"debug","z":"e78e73d3.53155","name":"debug 73","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1520,"y":3520,"wires":[]},{"id":"fea43e57ef1419d6","type":"inject","z":"e78e73d3.53155","name":"Griechenland","props":[{"p":"lat","v":"37.489407","vt":"num"},{"p":"topic","vt":"str"},{"p":"lon","v":"22.380565","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"180","topic":"","x":1010,"y":3640,"wires":[["23e278c7fc4c6dfe"]]},{"id":"d885ec0c2280eac3","type":"inject","z":"e78e73d3.53155","name":"Kuala Lumpur","props":[{"p":"lat","v":"3.145933","vt":"num"},{"p":"topic","vt":"str"},{"p":"lon","v":"101.700522","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"240","topic":"","x":1010,"y":3680,"wires":[["23e278c7fc4c6dfe"]]},{"id":"349412d68089639d","type":"inject","z":"e78e73d3.53155","d":true,"name":"random lat/lon","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"60","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1020,"y":3480,"wires":[["8a02b8332fd301f4"]]},{"id":"8a02b8332fd301f4","type":"function","z":"e78e73d3.53155","name":"function 4","func":"let date = new Date()\nglobal.set(\"gps_updated\", date) // needed for smartphone app!\n\nlet lat = Math.round((Math.random() * 10+ 44) * 1000000) / 1000000\nlet lon = Math.round((Math.random() * 15 + 1) * 1000000) / 1000000\n\n//set lat&lon to the global variables to make them accessable through the HTTP API\nglobal.set(\"latitude\", lat)\nglobal.set(\"longitude\", lon)\n\nmsg.lat = lat,\nmsg.lon = lon\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1300,"y":3480,"wires":[["9ba48d39cbfd747d"]]},{"id":"85b194725e15adc0","type":"http in","z":"e78e73d3.53155","name":"","url":"app_home/","method":"get","upload":false,"swaggerDoc":"","x":120,"y":3340,"wires":[["9ed748e450026407"]]},{"id":"e5df736feee72178","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":990,"y":3340,"wires":[]},{"id":"9ed748e450026407","type":"function","z":"e78e73d3.53155","name":"reformat payload","func":"var num = \"zero one two three four five six seven eight nine ten\".split(\" \");\nfunction number2words(n) {\n    if (n < 20) return num[n];\n    var digit = n % 10;\n    return number2words(~~(n / 1000)) + \" thousand\" + (n % 1000 != 0 ? \" \" + number2words(n % 1000) : \"\");\n}\n\n// let relays = msg.req.query.r ?? 0\n// let wrelays = msg.req.query.w ?? 0\n// let dimmer = msg.req.query.d ?? 0\nlet temp = msg.req.query.t ?? 0\nlet batt = msg.req.query.b ?? 0\nlet level = msg.req.query.l ?? 0\n\n//check for string \"undefined\"\ntemp = (temp == \"undefined\") ? 0 : temp\nbatt = (batt == \"undefined\") ? 0 : batt\nlevel = (level == \"undefined\") ? 0 : level\n\n// if (relays != null && relays != undefined && relays != \"0\") {\n//     relays = relays.split(\",\")\n//     let i = 0\n//     while (i< relays.length) {\n//         relays[i] = parseInt(relays[i])\n//         relays[i] = number2words(relays[i])\n//         i++\n//     }\n// }\n// if (wrelays != null && wrelays != undefined && wrelays != \"0\") {\n//     wrelays = wrelays.split(\",\")\n//     let i = 0\n//     while (i < wrelays.length) {\n//         wrelays[i] = parseInt(wrelays[i])\n//         wrelays[i] = \"W\"+number2words(wrelays[i])\n//         i++\n//     }\n// }\n// if (dimmer != null && dimmer != undefined && dimmer != \"0\") {\n//     dimmer = dimmer.split(\",\")\n//     let i = 0\n//     while (i < dimmer.length) {\n//         dimmer[i] = parseInt(dimmer[i]) - 1 // dimmer index starts at 0 internally!\n//         dimmer[i] = \"dimmer\"+dimmer[i]\n//         i++\n//     }\n// }\nif (temp != null && temp != undefined && temp != \"0\") {\n    temp = temp.split(\",\")\n    let i = 0\n    while (i < temp.length) {\n        temp[i] = \"temp\" + temp[i]\n        i++\n    }\n}\nif (level != null && level != undefined && level != \"0\") {\n    level = level.split(\",\")\n    let i = 0\n    while (i < level.length) {\n        level[i] = \"level\" + level[i]\n        i++\n    }\n}\nif (batt != null && batt != undefined) {\n    batt = batt == \"1\" ? 1:0;\n}\n\nmsg.payload = {\n    // \"relays\": relays,\n    // \"wrelays\": wrelays,\n    // \"dimmer\": dimmer,\n    \"temp\": temp,\n    \"batt\": batt,\n    \"level\": level\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":3340,"wires":[["266381b96a593915"]]},{"id":"266381b96a593915","type":"function","z":"e78e73d3.53155","name":"generate objects","func":"let relays = msg.payload.relays ?? 0;\nlet wrelays = msg.payload.wrelays ?? 0;\nlet dimmer = msg.payload.dimmer ?? 0;\nlet temp = msg.payload.temp ?? 0;\nlet batt = msg.payload.batt ?? 0;\nlet level = msg.payload.level ?? 0;\n\n\nfunction wordToNumber(word) {\n    const numberWords = {\n        zero: 0,\n        one: 1,\n        two: 2,\n        three: 3,\n        four: 4,\n        five: 5,\n        six: 6,\n        seven: 7,\n        eight: 8,\n        nine: 9,\n        ten: 10, // Add more as needed\n    };\n\n    const lowerCaseWord = word.toLowerCase();\n    return numberWords[lowerCaseWord] || NaN;\n}\n\n// if (relays != null && relays != undefined && relays != \"0\") {\n//     let i = 0;\n//     msg.payload.relays = [];\n\n//     while (i < relays.length) {\n//         msg.payload.relays[i] = {};\n//         msg.payload.relays[i].id = \"Relay\"+wordToNumber(relays[i])\n//         msg.payload.relays[i].state = global.get(relays[i]);\n//         msg.payload.relays[i].name = global.get(\"N\" + relays[i]);\n//         //msg.payload.relays[i].autooff = global.get(relays[i] + \"offauto\") ?? 0;\n//         i++;\n//     }\n// }\n\n// if (wrelays != null && wrelays != undefined && wrelays != \"0\") {\n//     let i = 0;\n//     msg.payload.wrelays = [];\n\n//     while (i < wrelays.length) {\n//         msg.payload.wrelays[i] = {};\n//         msg.payload.wrelays[i].id = \"WifiRelay\"+wordToNumber(wrelays[i].substring(1))\n//         msg.payload.wrelays[i].state = global.get(wrelays[i]);\n//         msg.payload.wrelays[i].name = global.get(\"N\" + wrelays[i]);\n//         msg.payload.wrelays[i].firmware = global.get(\"wrelay\" + wordToNumber(wrelays[i].substring(1))+\"_firmware\");\n//         //msg.payload.wrelays[i].autooff = global.get(wrelays[i] + \"offauto\") ?? 0;\n//         i++;\n//     }\n// }\n\n// if (dimmer != null && dimmer != undefined && dimmer != \"0\") {\n//     let i = 0;\n//     msg.payload.dimmer = [];\n\n//     while (i < dimmer.length) {\n//         msg.payload.dimmer[i] = {};\n//         msg.payload.dimmer[i].id = \"dimmer\"+(parseInt(dimmer[i].substring(6))+1)\n//         msg.payload.dimmer[i].state = global.get(dimmer[i]);\n//         msg.payload.dimmer[i].name = global.get(\"N\" + dimmer[i]);\n//         //msg.payload.dimmer[i].autooff = global.get(dimmer[i] + \"offauto\") ?? 0;\n//         i++;\n//     }\n// }\n\nif (temp != null && temp != undefined && temp != \"0\") {\n    let i = 0;\n    msg.payload.temp = [];\n\n    while (i < temp.length) {\n        msg.payload.temp[i] = {};\n        msg.payload.temp[i].id = \"temp\"+parseInt(temp[i].substring(4))\n        msg.payload.temp[i].state = global.get(temp[i]);\n        msg.payload.temp[i].name = global.get(\"N\" + temp[i]);\n        i++;\n    }\n}\nif (level != null && level != undefined && level != \"0\") {\n    let i = 0;\n    msg.payload.level = [];\n\n    while (i < level.length) {\n        msg.payload.level[i] = {};\n        msg.payload.level[i].id = \"level\"+parseInt(level[i].substring(5))\n        msg.payload.level[i].state = global.get(\"Level\"+level[i].substring(level[i].length-1));\n        msg.payload.level[i].name = global.get(\"NLevel\" + level[i].substring(level[i].length - 1));\n        i++;\n    }\n}\nif (batt != null && batt != undefined && batt != \"0\" || batt != 0 && batt == 1) {\n        msg.payload.batt = {\n        \"VoltB\": global.get(\"MainBattVolt\"),\n        \"Ampere\": global.get(\"MainBattAmps\"),\n        \"battsoc\": global.get(\"MainBattSoc\")\n        }\n}\n\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":3340,"wires":[["081e13488093c513"]]},{"id":"081e13488093c513","type":"function","z":"e78e73d3.53155","name":"create response object","func":"//Create new object and respond\n\nmsg.newObject = {\n    // \"relays\": {},\n    // \"wrelays\": {},\n    // \"dimmer\": {},\n    \"temp\": {},\n    \"batt\": {},\n    \"level\": {},\n}\n\n// for (var i = 0; i < msg.payload.relays.length; i++) {\n//     msg.newObject.relays[msg.payload.relays[i].id] = msg.payload.relays[i]\n// }\n// for (var i = 0; i < msg.payload.wrelays.length; i++) {\n//     msg.newObject.wrelays[msg.payload.wrelays[i].id] = msg.payload.wrelays[i]\n// }\n// for (var i = 0; i < msg.payload.dimmer.length; i++) {\n//     msg.newObject.dimmer[msg.payload.dimmer[i].id] = msg.payload.dimmer[i]\n// }\nfor (var i = 0; i < msg.payload.temp.length; i++) {\n    msg.newObject.temp[msg.payload.temp[i].id] = msg.payload.temp[i]\n}\nfor (var i = 0; i < msg.payload.level.length; i++) {\n    msg.newObject.level[msg.payload.level[i].id] = msg.payload.level[i]\n}\nmsg.newObject.batt = msg.payload.batt\n\nmsg.payload = msg.newObject\n\nif (msg.payload.batt == 0) {\n    delete msg.payload.batt\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":760,"y":3340,"wires":[["e5df736feee72178"]]},{"id":"65e561c5aa1b380a","type":"http in","z":"e78e73d3.53155","name":"","url":"position_sensor/","method":"get","upload":false,"swaggerDoc":"","x":140,"y":3500,"wires":[["fb780f6a94877b94"]]},{"id":"fb780f6a94877b94","type":"function","z":"e78e73d3.53155","name":"get variables","func":"if (msg.payload.request == \"true\" && (flow.get(\"mpuRequestStarted\") == false || flow.get(\"mpuRequestStarted\") == undefined)) {\n    flow.set(\"mpuRequestStarted\", true)\n    node.send([null, msg, null, null])\n}\nif (msg.payload.request == \"calibrate\") {\n    msg.payload = {\n        \"calibration\": true\n    }\n    return [ msg, null, msg, null]\n}\nif (msg.payload.request == \"true\" && flow.get(\"mpuRequestStarted\") == true){ \n    msg.payload = {\n    \"x_angle\": global.get(\"x_angle\"),\n    \"y_angle\": global.get(\"y_angle\"),\n    }\n    return [null, null, msg, null];\n}\nelse if (msg.payload.request == \"false\") {\n    flow.set(\"mpuRequestStarted\", false)\n    msg.payload = { \"request\": false}\n    return[null, null, msg, msg]\n}","outputs":4,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":3500,"wires":[["46505864c3d9e739"],["44b78f2a6ec1dafb"],["be6a1f7f781fb604"],["ebdf10e1d4ee8666"]]},{"id":"be6a1f7f781fb604","type":"http response","z":"e78e73d3.53155","name":"send answer","statusCode":"200","headers":{},"x":635,"y":3507,"wires":[]},{"id":"8ddf79b96a97f756","type":"comment","z":"e78e73d3.53155","name":"endpoint for widgets on the app homescreen","info":"","x":210,"y":3300,"wires":[]},{"id":"e1c574b320512f5b","type":"comment","z":"e78e73d3.53155","name":"endpoint position sensor mpu6050","info":"","x":180,"y":3460,"wires":[]},{"id":"44b78f2a6ec1dafb","type":"link out","z":"e78e73d3.53155","name":"positionSensor start","mode":"link","links":["6619f21f66ccc3a3"],"x":535,"y":3480,"wires":[]},{"id":"ebdf10e1d4ee8666","type":"link out","z":"e78e73d3.53155","name":"positionSensor stop","mode":"link","links":["be30fa7396b2172a"],"x":535,"y":3540,"wires":[]},{"id":"46505864c3d9e739","type":"link out","z":"e78e73d3.53155","name":"positionSensor calibrate","mode":"link","links":["a32a3d5947c57eb9"],"x":535,"y":3440,"wires":[]},{"id":"b29bf552eb93a13b","type":"debug","z":"e78e73d3.53155","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":990,"y":2860,"wires":[]}]

MQTT-API Flow:

Hier brauchen wir eine Erweiterung für die remote Verbindung. Aktuell wird hier auch der User, den ihr evtl. in der App registriert, hardgecodet. Es gibt noch keine benutzerfreundliche Funktion für das Frontend um seine Daten eingeben zu können. (Generell sind alle flows noch nicht für das Frontend vorbereitet worden.)

In der Function Node “set broker & pass” tragt ihr eure Logindaten ein:

die gezeigten Nodes:

[{"id":"45ebfa4a65c76716","type":"mqtt in","z":"d9b2c7637c5fbdae","name":"","topic":"","qos":"2","datatype":"auto-detect","broker":"9fe87c77918c0349","nl":false,"rap":true,"rh":0,"inputs":1,"x":790,"y":4200,"wires":[["2f70b0aa27a1e535"]]},{"id":"8d51b81cb50f5d4b","type":"inject","z":"d9b2c7637c5fbdae","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"21600","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":410,"y":4200,"wires":[["3c169b426820743c"]]},{"id":"5a9c262069d66549","type":"inject","z":"d9b2c7637c5fbdae","name":"disconnect","props":[{"p":"action","v":"disconnect","vt":"str"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"2","topic":"","x":620,"y":4160,"wires":[["45ebfa4a65c76716"]]},{"id":"2f70b0aa27a1e535","type":"function","z":"d9b2c7637c5fbdae","name":"get topics and respond","func":"msg.function = msg.topic.split(\"/\")\nlet topic = msg.function[0]\nmsg.function = msg.function[1];\n\nif (msg.topic.includes(\"ans\") || msg.topic.includes(\"NRconnection\")) {\n    return null\n}\n\n// direct answers to broker (first output)\n\n// connection check\nif (msg.function == \"iotcheck\") {\n    msg.topic = topic\n    return [msg, null]\n}\n\n//check http api before responding to broker (second output)\n\n// reboot\nif (msg.function == \"reboot\" && msg.payload.reboot == true) {\n    msg.url = \"http://127.0.0.1:1880/reboot/\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\n//heater\nif (msg.function == \"heat\" && (msg.payload.heat == true || msg.payload.heat == false)) {\n    msg.url = \"http://127.0.0.1:1880/heater/\" + msg.payload.heat.toString() + \"/\" + msg.payload.temp.toString() + \"/\" + msg.payload.time.toString()\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.heater = msg.payload\n    msg.method = \"PUT\"\n    return [null, msg]\n}\n\n// needed for Smartphone App homescreen\nif (msg.function == \"info\") {\n    msg.url = \"http://127.0.0.1:1880/info\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\n// needed for Smartphone App homescreen\nif (msg.function == \"appHome\") {\n    let query = \"?t=\" + msg.payload.queryParams.t + \"&b=\" + msg.payload.queryParams.b + \"&l=\" + msg.payload.queryParams.l\n    msg.url = \"http://127.0.0.1:1880/app_Home\" + query\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\n//dimmer\nif (msg.payload.includes(\"dimmerId\")) {\n    let Donoff = \"\"\n    var split_colon = msg.payload.split(\":\")\n    Donoff = parseInt(split_colon[2].substring(0, msg.payload.length - 1))\n\n    msg.payload = msg.payload.split(\",\")\n    msg.payload = msg.payload[0].substring(13, msg.payload[0].length - 1)\n    msg.url = \"http://127.0.0.1:1880/dimmer/\" + msg.payload + \"/\" + Donoff\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"PUT\"\n    if (msg.payload == \"one\") { msg.payload = \"0\" }\n    else if (msg.payload == \"two\") { msg.payload = \"1\" }\n    else if (msg.payload == \"three\") { msg.payload = \"2\" }\n    else if (msg.payload == \"four\") { msg.payload = \"3\" }\n    else if (msg.payload == \"five\") { msg.payload = \"4\" }\n    else if (msg.payload == \"six\") { msg.payload = \"5\" }\n    else if (msg.payload == \"seven\") { msg.payload = \"6\" }\n    else if (msg.payload == \"eight\") { msg.payload = \"7\" }\n    msg.payload = \"dimmer\" + msg.payload\n    global.set(msg.payload, Donoff)\n    return [null, msg]\n}\n\n//wrelays\nif (msg.payload.includes(\"wrelayId\")) {\n    var Wonoff = false\n    if (msg.payload.includes(\"false\")) {\n        Wonoff = false\n    }\n    else if (msg.payload.includes(\"true\")) {\n        Wonoff = true\n    }\n    msg.payload = msg.payload.split(\",\")\n    msg.payload = msg.payload[0].substring(13, msg.payload[0].length - 1)\n    msg.url = \"http://127.0.0.1:1880/wrelay/\" + msg.payload + \"/\" + Wonoff\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"PUT\"\n    msg.payload = \"W\" + msg.payload\n    global.set(msg.payload, Wonoff)\n    return [null, msg]\n}\n\n//relays\nif (msg.payload.includes(\"relayId\")) {\n    var onoff = false\n    if (msg.payload.includes(\"false\")) {\n        onoff = false\n    }\n    else if (msg.payload.includes(\"true\")) {\n        onoff = true\n    }\n    msg.payload = msg.payload.split(\",\")\n    msg.payload = msg.payload[0].substring(12, msg.payload[0].length - 1)\n    msg.url = \"http://127.0.0.1:1880/relay/\" + msg.payload + \"/\" + onoff\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"PUT\"\n    global.set(msg.payload, onoff)\n    return [null, msg]\n}\n\n//battery\nif (msg.function == \"batt\") {\n    msg.url = \"http://127.0.0.1:1880/batt\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\n//bms\nif (msg.function == \"bms\") {\n    msg.url = \"http://127.0.0.1:1880/bms\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\n//connection check IoT Bridge\nif (msg.function == \"conniot\") {\n    msg.url = \"http://127.0.0.1:1880/conniot\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\nif (msg.function == \"heat\") {\n    msg.url = \"http://127.0.0.1:1880/heater\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\nif (msg.function == \"temp\") {\n    msg.url = \"http://127.0.0.1:1880/temp\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\nif (msg.function == \"relay\") {\n    msg.url = \"http://127.0.0.1:1880/relay\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\nif (msg.function == \"wrelay\") {\n    msg.url = \"http://127.0.0.1:1880/wrelay\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\nif (msg.function == \"dimmer\") {\n    msg.url = \"http://127.0.0.1:1880/dimmer\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\nif (msg.function == \"level\") {\n    msg.url = \"http://127.0.0.1:1880/level\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\nif (msg.function == \"gps\") {\n    msg.url = \"http://127.0.0.1:1880/gps\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\nif (msg.function == \"positionSensor\") {\n    msg.url = \"http://127.0.0.1:1880/position_sensor?request=true\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}\n\nif (msg.function == \"stopPositionSensor\") {\n    msg.url = \"http://127.0.0.1:1880/position_sensor?request=false\"\n    msg.topic = topic + \"/\" + msg.function + \"ans\"\n    msg.method = \"GET\"\n    return [null, msg]\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":980,"y":4200,"wires":[["6f81e3c40c08d661"],["cb626ed6a072f8df"]]},{"id":"cb626ed6a072f8df","type":"http request","z":"d9b2c7637c5fbdae","name":"","method":"use","ret":"txt","paytoqs":"ignore","url":"","tls":"","persist":false,"proxy":"","authType":"","senderr":false,"x":630,"y":4260,"wires":[["cb275fd5a2b50a9a"]]},{"id":"1eba6f11d5df21fe","type":"mqtt out","z":"d9b2c7637c5fbdae","name":"","topic":"","qos":"","retain":"","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"9fe87c77918c0349","x":1210,"y":4260,"wires":[]},{"id":"0db06b4a741f79ed","type":"json","z":"d9b2c7637c5fbdae","name":"","property":"payload","action":"","pretty":true,"x":1030,"y":4260,"wires":[["1eba6f11d5df21fe"]]},{"id":"3c169b426820743c","type":"function","z":"d9b2c7637c5fbdae","name":"set broker & pass","func":"let broker =  \"mqttapi-emqx-vanpi.pekaway.de\" // set broker\nlet username = \"\"  // set username (email adress)\nlet password = \"\" // set password\nlet port = 8883 // or no ssl with port 1883 \n\nmsg.action = \"connect\"\nmsg.broker = {\n    \"broker\": broker, \n    \"port\": port, \n    \"force\": true,\n    \"username\": username,\n    \"password\": password\n}\nnode.send(msg)\nmsg.action = \"subscribe\"\nmsg.topic = username + \"/#\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":610,"y":4200,"wires":[["45ebfa4a65c76716"]]},{"id":"cb275fd5a2b50a9a","type":"function","z":"d9b2c7637c5fbdae","name":"check http ans","func":"if (msg.payload.includes(\"<!DOCTYPE html>\")) {\n    return null\n}\nelse {\n    if(msg.payload.includes(\"heater true with\") || msg.payload.includes(\"heater false\")) {\n    msg.payload = msg.heater\n    }\n    return msg\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":800,"y":4260,"wires":[["0db06b4a741f79ed"]]},{"id":"6f81e3c40c08d661","type":"function","z":"d9b2c7637c5fbdae","name":"instant response","func":"if (msg.function == \"iotcheck\") {\n    msg.topic = msg.topic + \"/iotcheckans\"\n    msg.payload = {\n        iotcheck: true\n        }\n    return msg;   \n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1220,"y":4180,"wires":[["0db06b4a741f79ed"]]},{"id":"9fe87c77918c0349","type":"mqtt-broker","name":"","broker":"0.0.0.0","port":"8883","tls":"4230868a2749a2ba","clientid":"","autoConnect":true,"usetls":true,"protocolVersion":"5","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"4230868a2749a2ba","type":"tls-config","name":"","cert":"","key":"","ca":"","certname":"","keyname":"","caname":"","servername":"","verifyservercert":false,"alpnprotocol":""}]

Heater Controls Flow:

Wenn ich mich recht erinnere, kommt hier nur ein Link-In neu dazu um die Laufzeit per Api zu setzen:

Verbindungen gibt es hier zum HTTP-Api Flow:

Und zum MQTT-Api Flow:

Zur Sicherheit nochmal der komplette Flow:

[{"id":"b6cd7d08.34935","type":"tab","label":" HeaterControls + MaxxFan","disabled":false,"info":""},{"id":"5b3b97b1.6de818","type":"ui_time_scheduler","z":"b6cd7d08.34935","group":"4d6141426495610b","name":"","startDay":0,"refresh":60,"devices":["heater timer"],"singleOff":false,"onlySendChange":false,"customPayload":false,"eventMode":false,"eventOptions":[],"sendTopic":false,"lat":"","lon":"","customContextStore":"","outputs":2,"order":2,"width":"0","height":"0","x":750,"y":140,"wires":[["500dcb53.aa8be4"],["690de17f.50198"]]},{"id":"ea5a2dfa.55b8d","type":"switch","z":"b6cd7d08.34935","name":"","property":"payload","propertyType":"msg","rules":[{"t":"false"},{"t":"true"}],"checkall":"true","repair":false,"outputs":2,"x":1110,"y":140,"wires":[["4c10aed4e90a4dc5","5512cedcef6cc468"],["356b5c202c275946","b4ad41f3.50b6"]]},{"id":"34624a1b.a87556","type":"switch","z":"b6cd7d08.34935","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"2","vt":"str"},{"t":"eq","v":"3","vt":"str"},{"t":"eq","v":"4","vt":"str"},{"t":"eq","v":"5","vt":"str"},{"t":"eq","v":"6","vt":"str"},{"t":"eq","v":"7","vt":"str"},{"t":"eq","v":"8","vt":"str"},{"t":"eq","v":"9","vt":"str"},{"t":"eq","v":"10","vt":"str"}],"checkall":"true","repair":false,"outputs":10,"x":1670,"y":300,"wires":[["465e74df.ffe5dc"],["189823aa.9f6a6c"],["a1b15bff.4c9678"],["564b57df.6e9b08"],["1216bfcc.c7794"],["d3fd292f.6dc8f8"],["7be33174.95ab7"],["eb14dc86.2a0cb"],[],[]]},{"id":"9de8f7f3.70a038","type":"file in","z":"b6cd7d08.34935","name":"","filename":"pekaway/savetimer","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":570,"y":140,"wires":[["5b3b97b1.6de818"]]},{"id":"2d9011c1.bd074e","type":"inject","z":"b6cd7d08.34935","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":210,"y":140,"wires":[["a3e77227.9bb0d"]]},{"id":"a3e77227.9bb0d","type":"delay","z":"b6cd7d08.34935","name":"","pauseType":"delay","timeout":"7","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"outputs":1,"x":380,"y":140,"wires":[["9de8f7f3.70a038"]]},{"id":"465e74df.ffe5dc","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"one\", true);\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1970,"y":60,"wires":[[]]},{"id":"189823aa.9f6a6c","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"two\", true);\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1970,"y":100,"wires":[[]]},{"id":"a1b15bff.4c9678","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"three\", true);\n","outputs":1,"noerr":0,"x":1970,"y":140,"wires":[[]]},{"id":"564b57df.6e9b08","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"four\", true);\n","outputs":1,"noerr":0,"x":1970,"y":180,"wires":[[]]},{"id":"1216bfcc.c7794","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"five\", true);\n","outputs":1,"noerr":0,"x":1970,"y":220,"wires":[[]]},{"id":"d3fd292f.6dc8f8","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"six\", true);\n","outputs":1,"noerr":0,"x":1970,"y":260,"wires":[[]]},{"id":"7be33174.95ab7","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"seven\", true);\n","outputs":1,"noerr":0,"x":1970,"y":300,"wires":[[]]},{"id":"eb14dc86.2a0cb","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"eight\", true);\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1970,"y":340,"wires":[[]]},{"id":"2dfc457a.e9c54a","type":"ui_switch","z":"b6cd7d08.34935","name":"","label":"Timer Off/On","tooltip":"","group":"4d6141426495610b","order":1,"width":0,"height":0,"passthru":true,"decouple":"false","topic":"","topicType":"str","style":"","onvalue":"true","onvalueType":"bool","onicon":"","oncolor":"","offvalue":"false","offvalueType":"bool","officon":"","offcolor":"","animate":true,"className":"","x":430,"y":40,"wires":[["b21062ea.3f207"]]},{"id":"b21062ea.3f207","type":"function","z":"b6cd7d08.34935","name":"","func":"global.set(\"heattimeronoff\", msg.payload)\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":680,"y":40,"wires":[[]]},{"id":"b4769425.119548","type":"switch","z":"b6cd7d08.34935","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"str"},{"t":"eq","v":"2","vt":"str"},{"t":"eq","v":"3","vt":"str"},{"t":"eq","v":"4","vt":"str"},{"t":"eq","v":"5","vt":"str"},{"t":"eq","v":"6","vt":"str"},{"t":"eq","v":"7","vt":"str"},{"t":"eq","v":"8","vt":"str"},{"t":"eq","v":"9","vt":"str"},{"t":"eq","v":"10","vt":"str"}],"checkall":"true","repair":false,"outputs":10,"x":1670,"y":440,"wires":[["ed9dd7.d7600228"],["9bd0ef2a.d2d7c"],["1639c11a.f3c2ef"],["d4250ab3.c49fd8"],["6fed735c.73c61c"],["aa0eb423.e311a8"],["cf219215.b54dd"],["856ce5c1.0275b8"],[],[]]},{"id":"ed9dd7.d7600228","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"one\", false);\n","outputs":1,"noerr":0,"x":1970,"y":380,"wires":[[]]},{"id":"9bd0ef2a.d2d7c","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"two\", false);\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1970,"y":420,"wires":[[]]},{"id":"1639c11a.f3c2ef","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"three\", false);\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1970,"y":460,"wires":[[]]},{"id":"d4250ab3.c49fd8","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"four\", false);\n","outputs":1,"noerr":0,"x":1970,"y":500,"wires":[[]]},{"id":"6fed735c.73c61c","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"five\", false);\n","outputs":1,"noerr":0,"x":1970,"y":540,"wires":[[]]},{"id":"aa0eb423.e311a8","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"six\", false);\n","outputs":1,"noerr":0,"x":1970,"y":580,"wires":[[]]},{"id":"cf219215.b54dd","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"seven\", false);\n","outputs":1,"noerr":0,"x":1970,"y":620,"wires":[[]]},{"id":"856ce5c1.0275b8","type":"function","z":"b6cd7d08.34935","name":"globalVariable set","func":"\nglobal.set(\"eight\", false);\n","outputs":1,"noerr":0,"x":1970,"y":660,"wires":[[]]},{"id":"690de17f.50198","type":"function","z":"b6cd7d08.34935","name":"check timer on/off","func":"var check = global.get(\"heattimeronoff\");\nif(check === true)\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":950,"y":140,"wires":[["ea5a2dfa.55b8d"]]},{"id":"ad8ca5a.78d6058","type":"inject","z":"b6cd7d08.34935","name":"","repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"false","payloadType":"bool","x":150,"y":40,"wires":[["2dfc457a.e9c54a"]]},{"id":"b4ad41f3.50b6","type":"delay","z":"b6cd7d08.34935","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1340,"y":400,"wires":[["bf97c6b00ba3ecec"]]},{"id":"a431cd5.b84203","type":"comment","z":"b6cd7d08.34935","name":"Timer with connect relays","info":"","x":230,"y":100,"wires":[]},{"id":"356b5c202c275946","type":"ui_button","z":"b6cd7d08.34935","name":"","group":"2bd22a1d380636dc","order":1,"width":0,"height":0,"passthru":true,"label":"Start","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"\"\"","payloadType":"str","topic":"topic","topicType":"msg","x":430,"y":300,"wires":[["5c6aeef08e518260","8e2cf1affb32e884","3d09a72b0b542224","6d184978e23c3d8f","e1020f2c893d1432","5512cedcef6cc468","689f7af0527c84bb","9f5aa5c71fdca150","e567390c9e2d4bbc"]]},{"id":"4c10aed4e90a4dc5","type":"ui_button","z":"b6cd7d08.34935","name":"","group":"2bd22a1d380636dc","order":2,"width":0,"height":0,"passthru":true,"label":"Stop","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"\"\"","payloadType":"str","topic":"topic","topicType":"msg","x":430,"y":420,"wires":[["8c2f419ba40a5988","5aaf037cba0e1470","357c036bfc1f8f60","b5deeec3b50476e6","a7073406bb997adb","bf97c6b00ba3ecec","6c2b9df588efbd44","4c2ff550cab39384","df953ef470f7b6b5","e567390c9e2d4bbc"]]},{"id":"8a3d57c0caabb452","type":"comment","z":"b6cd7d08.34935","name":"Buttons and Temperature","info":"","x":230,"y":220,"wires":[]},{"id":"65f0fb14cb2fbb3d","type":"ui_slider","z":"b6cd7d08.34935","name":"","label":"Set Temperatur","tooltip":"please select tempsensor in config","group":"2bd22a1d380636dc","order":3,"width":"6","height":"1","passthru":true,"outs":"end","topic":"","topicType":"str","min":"2","max":"35","step":1,"className":"","x":1200,"y":700,"wires":[["f8d3f1dc.c595b","28ad7f42cfe2b944","6170c7bb5afa2ee0"]]},{"id":"1174fcf84dd5fb9f","type":"file","z":"b6cd7d08.34935","name":"","filename":"pekaway/settemp","appendNewline":false,"createDir":true,"overwriteFile":"true","encoding":"none","x":1550,"y":660,"wires":[[]]},{"id":"28ad7f42cfe2b944","type":"function","z":"b6cd7d08.34935","name":"set global ","func":"msg.topic = Number(msg.payload);\nglobal.set(\"settemp\", msg.topic);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1380,"y":660,"wires":[["1174fcf84dd5fb9f"]]},{"id":"498d730f825a09cd","type":"file in","z":"b6cd7d08.34935","name":"","filename":"pekaway/settemp","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":970,"y":660,"wires":[["65f0fb14cb2fbb3d","28ad7f42cfe2b944"]]},{"id":"58e1147861231c57","type":"inject","z":"b6cd7d08.34935","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":750,"y":660,"wires":[["498d730f825a09cd","334c388fdbc1a546"]]},{"id":"60bf4bd87920e78f","type":"ui_text","z":"b6cd7d08.34935","group":"2bd22a1d380636dc","order":4,"width":"6","height":"1","name":"","label":"Tempsensor: ","format":"{{msg.payload}}","layout":"row-spread","className":"","x":1290,"y":780,"wires":[]},{"id":"334c388fdbc1a546","type":"function","z":"b6cd7d08.34935","name":"get inside tempsensor","func":"msg.payload = global.get(\"heattempsensor\");\n\nif(msg.payload != 1 && msg.payload != 2 && msg.payload != 3 && msg.payload != 4 && msg.payload != 5 && msg.payload != 6)\nmsg.payload=\"no sensor\"\n\nif(msg.payload == 1)\nmsg.payload = global.get(\"temp1\");\n\nif(msg.payload == 2)\nmsg.payload = global.get(\"temp2\");\n\nif(msg.payload == 3)\nmsg.payload = global.get(\"temp3\");\n\nif(msg.payload == 4)\nmsg.payload = global.get(\"temp4\");\n\nif(msg.payload == 5)\nmsg.global.get(\"dimmytemp1\")\n\nif (msg.payload == 6)\n    msg.global.get(\"dimmytemp2\")\n\n\nif (global.get(\"temp1\") == \"\" && global.get(\"temp2\") == \"\" && global.get(\"temp3\") == \"\" && global.get(\"temp4\") == \"\" && global.get(\"dimmytemp1\") == \"\" && global.get(\"dimmytemp2\") == \"\")\n{\n    msg.payload =\"no TempSensor\"\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":980,"y":780,"wires":[["60bf4bd87920e78f","7bc1539d.3c518c"]]},{"id":"f598506a66563ad0","type":"link in","z":"b6cd7d08.34935","name":"heatertempsensor","links":["2d96e8.2c96e918"],"x":805,"y":740,"wires":[["334c388fdbc1a546"]]},{"id":"a2a42c0f4d6f393e","type":"inject","z":"b6cd7d08.34935","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"10","crontab":"","once":true,"onceDelay":"30","topic":"","payload":"","payloadType":"date","x":750,"y":780,"wires":[["334c388fdbc1a546"]]},{"id":"eb1e92403a6a4490","type":"link in","z":"b6cd7d08.34935","name":"touch heater Start","links":["026555e3ad71e0cf","9218ac0d4df78330","9b3fc01458c8cf09","bdc02207fedba353","e342e6035235dcf4","e4d6be1f0b1154d3","ef215dab8a56ed9f","ef794877a1b58355","7e4dd6723e584edd"],"x":235,"y":300,"wires":[["356b5c202c275946"]]},{"id":"8114989ad3d836db","type":"link in","z":"b6cd7d08.34935","name":"touch heater stop","links":["737b0da3.aadc14","25bbb2b2adaf0cf8","5776c022733c4136","8d54b616c7e8feb5","9fb866bf4390d8d3","bd58df4c860a250e","f4c77d50408aeea4","be6c3d30a055ba91","7362857190ef0666","174fb16fd5db99e5","780a0e0968fb8eba","9fae8927d8332b8a","c6090d9c764b972b","21c530bf32661bd8","cd8aee961c1b28ab"],"x":235,"y":420,"wires":[["4c10aed4e90a4dc5"]]},{"id":"5c6aeef08e518260","type":"link out","z":"b6cd7d08.34935","name":"autoterm start","links":["3ffd20e3.bd23a","4fee13e9cef62a8a","38064e3aeee910e3","19329e2e2ff5c04a"],"x":705,"y":280,"wires":[]},{"id":"8e2cf1affb32e884","type":"link out","z":"b6cd7d08.34935","name":"webasto start","links":["2df448d30c5fc031","3aec10b81cfcbc6f"],"x":705,"y":320,"wires":[]},{"id":"3d09a72b0b542224","type":"link out","z":"b6cd7d08.34935","name":"china diesel start","links":["777866f44d62b0d8"],"x":705,"y":360,"wires":[]},{"id":"8c2f419ba40a5988","type":"link out","z":"b6cd7d08.34935","name":"autoterm stop","links":["98cdb5de.55bcd8","6073c0d66934134f","4da81b1bed60b194","4c1999d33c313348"],"x":705,"y":480,"wires":[]},{"id":"5aaf037cba0e1470","type":"link out","z":"b6cd7d08.34935","name":"webasto stop","links":["385e6fbc28cf0f96","9fa1b8aab7d6ac39"],"x":705,"y":520,"wires":[]},{"id":"357c036bfc1f8f60","type":"link out","z":"b6cd7d08.34935","name":"china heater stop","links":["25c3852715792925"],"x":705,"y":560,"wires":[]},{"id":"941d174a.01c348","type":"ui_template","z":"b6cd7d08.34935","group":"2a7d142135bfa4c0","name":"Nest","order":1,"width":"0","height":"0","format":"<div id=\"thermostat\"></div>\n\n<style>\n\n@import url(http://fonts.googleapis.com/css?family=Open+Sans:300);\n\n#thermostat {\n margin: 0 auto;\n -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\n.dial {\n    -webkit-user-select: none;\n    -moz-user-select: none;\n    -ms-user-select: none;\n    user-select: none;\n}\n.dial.away .dial__ico__leaf {\n    visibility: hidden;\n}\n.dial.away .dial__lbl--target {\n    visibility: hidden;\n}\n.dial.away .dial__lbl--target--half {\n    visibility: hidden;\n}\n.dial.away .dial__lbl--away {\n    opacity: 1;\n}\n.dial .dial__shape {\n    -webkit-transition: fill 0.5s;\n    transition: fill 0.5s;\n}\n.dial path.dial__ico__leaf {\n    fill: #13EB13;\n    opacity: 0;\n    -webkit-transition: opacity 0.5s;\n    transition: opacity 0.5s;\n    pointer-events: none;\n}\n.dial.has-leaf .dial__ico__leaf {\n    display: block;\n    opacity: 1;\n    pointer-events: initial;\n}\n.dial__editableIndicator {\n    fill-rule: evenodd;\n    opacity: 0;\n    -webkit-transition: opacity 0.5s;\n    transition: opacity 0.5s;\n}\n.dial--edit path.dial__editableIndicator {\n    fill: white;\n}\n.dial--edit .dial__editableIndicator {\n    opacity: 1;\n}\n.dial--state--off .dial__shape {\n    fill: #3d3c3c;\n}\n.dial--state--heating .dial__shape {\n    fill: #E36304;\n}\n.dial--state--cooling .dial__shape {\n    fill: #007AF1;\n}\n.dial .dial__ticks path {\n    fill: rgba(255, 255, 255, 0.3);\n}\n.dial .dial__ticks path.active {\n    fill: rgba(255, 255, 255, 0.8);\n}\n.dial text {\n    fill: white;\n    text-anchor: middle;\n    font-family: Helvetica, sans-serif;\n    alignment-baseline: central;\n}\n.dial__lbl--target {\n    font-size: 120px;\n    font-weight: bold;\n}\n.dial__lbl--target--half {\n    font-size: 40px;\n    font-weight: bold;\n    opacity: 0;\n    -webkit-transition: opacity 0.1s;\n    transition: opacity 0.1s;\n}\n.dial__lbl--target--half.shown {\n    opacity: 1;\n    -webkit-transition: opacity 0s;\n    transition: opacity 0s;\n}\n.dial__lbl--ambient {\n    font-size: 22px;\n    font-weight: bold;\n}\n.dial__lbl--away {\n    font-size: 72px;\n    font-weight: bold;\n    opacity: 0;\n    pointer-events: none;\n}\n#controls {\n    font-family: Open Sans;\n    background-color: rgba(255, 255, 255, 0.25);\n    padding: 20px;\n    border-radius: 5px;\n    position: absolute;\n    left: 50%;\n    -webkit-transform: translatex(-50%);\n    transform: translatex(-50%);\n    margin-top: 20px;\n}\n#controls label {\n    text-align: left;\n    display: block;\n}\n#controls label span {\n    display: inline-block;\n    width: 200px;\n    text-align: right;\n    font-size: 0.8em;\n    text-transform: uppercase;\n}\n#controls p {\n    margin: 0;\n    margin-bottom: 1em;\n    padding-bottom: 1em;\n    border-bottom: 2px solid #ccc;\n}\n</style>\n<script>\n    var thermostatDial = (function() {\n\t\n\t/*\n\t * Utility functions\n\t */\n\t\n\t// Create an element with proper SVG namespace, optionally setting its attributes and appending it to another element\n\tfunction createSVGElement(tag,attributes,appendTo) {\n\t\tvar element = document.createElementNS('http://www.w3.org/2000/svg',tag);\n\t\tattr(element,attributes);\n\t\tif (appendTo) {\n\t\t\tappendTo.appendChild(element);\n\t\t}\n\t\treturn element;\n\t}\n\t\n\t// Set attributes for an element\n\tfunction attr(element,attrs) {\n\t\tfor (var i in attrs) {\n\t\t\telement.setAttribute(i,attrs[i]);\n\t\t}\n\t}\n\t\n\t// Rotate a cartesian point about given origin by X degrees\n\tfunction rotatePoint(point, angle, origin) {\n\t\tvar radians = angle * Math.PI/180;\n\t\tvar x = point[0]-origin[0];\n\t\tvar y = point[1]-origin[1];\n\t\tvar x1 = x*Math.cos(radians) - y*Math.sin(radians) + origin[0];\n\t\tvar y1 = x*Math.sin(radians) + y*Math.cos(radians) + origin[1];\n\t\treturn [x1,y1];\n\t}\n\t\n\t// Rotate an array of cartesian points about a given origin by X degrees\n\tfunction rotatePoints(points, angle, origin) {\n\t\treturn points.map(function(point) {\n\t\t\treturn rotatePoint(point, angle, origin);\n\t\t});\n\t}\n\t\n\t// Given an array of points, return an SVG path string representing the shape they define\n\tfunction pointsToPath(points) {\n\t\treturn points.map(function(point, iPoint) {\n\t\t\treturn (iPoint>0?'L':'M') + point[0] + ' ' + point[1];\n\t\t}).join(' ')+'Z';\n\t}\n\t\n\tfunction circleToPath(cx, cy, r) {\n\t\treturn [\n\t\t\t\"M\",cx,\",\",cy,\n\t\t\t\"m\",0-r,\",\",0,\n\t\t\t\"a\",r,\",\",r,0,1,\",\",0,r*2,\",\",0,\n\t\t\t\"a\",r,\",\",r,0,1,\",\",0,0-r*2,\",\",0,\n\t\t\t\"z\"\n\t\t].join(' ').replace(/\\s,\\s/g,\",\");\n\t}\n\t\n\tfunction donutPath(cx,cy,rOuter,rInner) {\n\t\treturn circleToPath(cx,cy,rOuter) + \" \" + circleToPath(cx,cy,rInner);\n\t}\n\t\n\t// Restrict a number to a min + max range\n\tfunction restrictToRange(val,min,max) {\n\t\tif (val < min) return min;\n\t\tif (val > max) return max;\n\t\treturn val;\n\t}\n\t\n\t// Round a number to the nearest 0.5\n\tfunction roundHalf(num) {\n\t\treturn Math.round(num*2)/2;\n\t}\n\t\n\tfunction setClass(el, className, state) {\n\t\tel.classList[state ? 'add' : 'remove'](className);\n\t}\n\t\n\t/*\n\t * The \"MEAT\"\n\t */\n\n\treturn function(targetElement, options) {\n\t\tvar self = this;\n\t\t\n\t\t/*\n\t\t * Options\n\t\t */\n\t\toptions = options || {};\n\t\toptions = {\n\t\t\tdiameter: options.diameter || 400,\n\t\t\tminValue: options.minValue || 2, // Minimum value for target temperature\n\t\t\tmaxValue: options.maxValue || 35, // Maximum value for target temperature\n\t\t\tnumTicks: options.numTicks || 200, // Number of tick lines to display around the dial\n\t\t\tonSetTargetTemperature: options.onSetTargetTemperature || function() {}, // Function called when new target temperature set by the dial\n\t\t};\n\t\t\n\t\t/*\n\t\t * Properties - calculated from options in many cases\n\t\t */\n\t\tvar properties = {\n\t\t\ttickDegrees: 300, // Degrees of the dial that should be covered in tick lines\n\t\t\trangeValue: options.maxValue - options.minValue,\n\t\t\tradius: options.diameter/2,\n\t\t\tticksOuterRadius: options.diameter / 30,\n\t\t\tticksInnerRadius: options.diameter / 8,\n\t\t\thvac_states: ['off', 'heating', 'cooling'],\n\t\t\tdragLockAxisDistance: 15,\n\t\t}\n\t\tproperties.lblAmbientPosition = [properties.radius, properties.ticksOuterRadius-(properties.ticksOuterRadius-properties.ticksInnerRadius)/2]\n\t\tproperties.offsetDegrees = 180-(360-properties.tickDegrees)/2;\n\t\t\n\t\t/*\n\t\t * Object state\n\t\t */\n\t\tvar state = {\n\t\t\ttarget_temperature: options.minValue,\n\t\t\tambient_temperature: options.minValue,\n\t\t\thvac_state: properties.hvac_states[0],\n\t\t\thas_leaf: false,\n\t\t\taway: false\n\t\t};\n\t\t\n\t\t/*\n\t\t * Property getter / setters\n\t\t */\n\t\tObject.defineProperty(this,'target_temperature',{\n\t\t\tget: function() {\n\t\t\t\treturn state.target_temperature;\n\t\t\t},\n\t\t\tset: function(val) {\n\t\t\t\tstate.target_temperature = restrictTargetTemperature(+val);\n\t\t\t\trender();\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(this,'ambient_temperature',{\n\t\t\tget: function() {\n\t\t\t\treturn state.ambient_temperature;\n\t\t\t},\n\t\t\tset: function(val) {\n\t\t\t\tstate.ambient_temperature = roundHalf(+val);\n\t\t\t\trender();\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(this,'hvac_state',{\n\t\t\tget: function() {\n\t\t\t\treturn state.hvac_state;\n\t\t\t},\n\t\t\tset: function(val) {\n\t\t\t\tif (properties.hvac_states.indexOf(val)>=0) {\n\t\t\t\t\tstate.hvac_state = val;\n\t\t\t\t\trender();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\tfunction str2bool(strvalue){\n          return (strvalue && typeof strvalue == 'string') ? (strvalue.toLowerCase() == 'true') : (strvalue == true);\n        }\n\t\tObject.defineProperty(this,'has_leaf',{\n\t\t\tget: function() {\n\t\t\t\treturn state.has_leaf;\n\t\t\t},\n\t\t\tset: function(val) {\n\t\t\t\tstate.has_leaf = !!str2bool(val);\n\t\t\t\trender();\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(this,'away',{\n\t\t\tget: function() {\n\t\t\t\treturn state.away;\n\t\t\t},\n\t\t\tset: function(val) {\n\t\t\t\tstate.away = !!str2bool(val);\n\t\t\t\trender();\n\t\t\t}\n\t\t});\n\t\t\n\t\t/*\n\t\t * SVG\n\t\t */\n\t\tvar svg = createSVGElement('svg',{\n\t\t\twidth: '100%', //options.diameter+'px',\n\t\t\theight: '100%', //options.diameter+'px',\n\t\t\tviewBox: '0 0 '+options.diameter+' '+options.diameter,\n\t\t\tclass: 'dial'\n\t\t},targetElement);\n\t\t// CIRCULAR DIAL\n\t\tvar circle = createSVGElement('circle',{\n\t\t\tcx: properties.radius,\n\t\t\tcy: properties.radius,\n\t\t\tr: properties.radius,\n\t\t\tclass: 'dial__shape'\n\t\t},svg);\n\t\t// EDITABLE INDICATOR\n\t\tvar editCircle = createSVGElement('path',{\n\t\t\td: donutPath(properties.radius,properties.radius,properties.radius-4,properties.radius-8),\n\t\t\tclass: 'dial__editableIndicator',\n\t\t},svg);\n\t\t\n\t\t/*\n\t\t * Ticks\n\t\t */\n\t\tvar ticks = createSVGElement('g',{\n\t\t\tclass: 'dial__ticks'\t\n\t\t},svg);\n\t\tvar tickPoints = [\n\t\t\t[properties.radius-1, properties.ticksOuterRadius],\n\t\t\t[properties.radius+1, properties.ticksOuterRadius],\n\t\t\t[properties.radius+1, properties.ticksInnerRadius],\n\t\t\t[properties.radius-1, properties.ticksInnerRadius]\n\t\t];\n\t\tvar tickPointsLarge = [\n\t\t\t[properties.radius-1.5, properties.ticksOuterRadius],\n\t\t\t[properties.radius+1.5, properties.ticksOuterRadius],\n\t\t\t[properties.radius+1.5, properties.ticksInnerRadius+20],\n\t\t\t[properties.radius-1.5, properties.ticksInnerRadius+20]\n\t\t];\n\t\tvar theta = properties.tickDegrees/options.numTicks;\n\t\tvar tickArray = [];\n\t\tfor (var iTick=0; iTick<options.numTicks; iTick++) {\n\t\t\ttickArray.push(createSVGElement('path',{d:pointsToPath(tickPoints)},ticks));\n\t\t};\n\t\t\n\t\t/*\n\t\t * Labels\n\t\t */\n\t\tvar lblTarget = createSVGElement('text',{\n\t\t\tx: properties.radius,\n\t\t\ty: properties.radius,\n\t\t\tclass: 'dial__lbl dial__lbl--target'\n\t\t},svg);\n\t\tvar lblTarget_text = document.createTextNode('');\n\t\tlblTarget.appendChild(lblTarget_text);\n\t\t//\n\t\tvar lblTargetHalf = createSVGElement('text',{\n\t\t\tx: properties.radius + properties.radius/2.5,\n\t\t\ty: properties.radius - properties.radius/8,\n\t\t\tclass: 'dial__lbl dial__lbl--target--half'\n\t\t},svg);\n\t\tvar lblTargetHalf_text = document.createTextNode('5');\n\t\tlblTargetHalf.appendChild(lblTargetHalf_text);\n\t\t//\n\t\tvar lblAmbient = createSVGElement('text',{\n\t\t\tclass: 'dial__lbl dial__lbl--ambient'\n\t\t},svg);\n\t\tvar lblAmbient_text = document.createTextNode('');\n\t\tlblAmbient.appendChild(lblAmbient_text);\n\t\t//\n\t\tvar lblAway = createSVGElement('text',{\n\t\t\tx: properties.radius,\n\t\t\ty: properties.radius,\n\t\t\tclass: 'dial__lbl dial__lbl--away'\n\t\t},svg);\n\t\tvar lblAway_text = document.createTextNode('AWAY');\n\t\tlblAway.appendChild(lblAway_text);\n\t\t//\n\t\tvar icoLeaf = createSVGElement('path',{\n\t\t\tclass: 'dial__ico__leaf'\n\t\t},svg);\n\t\t\n\t\t/*\n\t\t * LEAF\n\t\t */\n\t\tvar leafScale = properties.radius/5/100;\n\t\tvar leafDef = [\"M\", 3, 84, \"c\", 24, 17, 51, 18, 73, -6, \"C\", 100, 52, 100, 22, 100, 4, \"c\", -13, 15, -37, 9, -70, 19, \"C\", 4, 32, 0, 63, 0, 76, \"c\", 6, -7, 18, -17, 33, -23, 24, -9, 34, -9, 48, -20, -9, 10, -20, 16, -43, 24, \"C\", 22, 63, 8, 78, 3, 84, \"z\"].map(function(x) {\n\t\t\treturn isNaN(x) ? x : x*leafScale;\n\t\t}).join(' ');\n\t\tvar translate = [properties.radius-(leafScale*100*0.5),properties.radius*1.5]\n\t\tvar icoLeaf = createSVGElement('path',{\n\t\t\tclass: 'dial__ico__leaf',\n\t\t\td: leafDef,\n\t\t\ttransform: 'translate('+translate[0]+','+translate[1]+')'\n\t\t},svg);\n\t\t\t\n\t\t/*\n\t\t * RENDER\n\t\t */\n\t\tfunction render() {\n\t\t\trenderAway();\n\t\t\trenderHvacState();\n\t\t\trenderTicks();\n\t\t\trenderTargetTemperature();\n\t\t\trenderAmbientTemperature();\n\t\t\trenderLeaf();\n\t\t}\n\t\trender();\n\n\t\t/*\n\t\t * RENDER - ticks\n\t\t */\n\t\tfunction renderTicks() {\n\t\t\tvar vMin, vMax;\n\t\t\tif (self.away) {\n\t\t\t\tvMin = self.ambient_temperature;\n\t\t\t\tvMax = vMin;\n\t\t\t} else {\n\t\t\t\tvMin = Math.min(self.ambient_temperature, self.target_temperature);\n\t\t\t\tvMax = Math.max(self.ambient_temperature, self.target_temperature);\n\t\t\t}\n\t\t\tvar min = restrictToRange(Math.round((vMin-options.minValue)/properties.rangeValue * options.numTicks),0,options.numTicks-1);\n\t\t\tvar max = restrictToRange(Math.round((vMax-options.minValue)/properties.rangeValue * options.numTicks),0,options.numTicks-1);\n\t\t\t//\n\t\t\ttickArray.forEach(function(tick,iTick) {\n\t\t\t\tvar isLarge = iTick==min || iTick==max;\n\t\t\t\tvar isActive = iTick >= min && iTick <= max;\n\t\t\t\tattr(tick,{\n\t\t\t\t\td: pointsToPath(rotatePoints(isLarge ? tickPointsLarge: tickPoints,iTick*theta-properties.offsetDegrees,[properties.radius, properties.radius])),\n\t\t\t\t\tclass: isActive ? 'active' : ''\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t\n\t\t/*\n\t\t * RENDER - ambient temperature\n\t\t */\n\t\tfunction renderAmbientTemperature() {\n\t\t\tlblAmbient_text.nodeValue = Math.floor(self.ambient_temperature);\n\t\t\tif (self.ambient_temperature%1!=0) {\n\t\t\t\tlblAmbient_text.nodeValue += '⁵';\n\t\t\t}\n\t\t\tvar peggedValue = restrictToRange(self.ambient_temperature, options.minValue, options.maxValue);\n\t\t\tdegs = properties.tickDegrees * (peggedValue-options.minValue)/properties.rangeValue - properties.offsetDegrees;\n\t\t\tif (peggedValue > self.target_temperature) {\n\t\t\t\tdegs += 8;\n\t\t\t} else {\n\t\t\t\tdegs -= 8;\n\t\t\t}\n\t\t\tvar pos = rotatePoint(properties.lblAmbientPosition,degs,[properties.radius, properties.radius]);\n\t\t\tattr(lblAmbient,{\n\t\t\t\tx: pos[0],\n\t\t\t\ty: pos[1]\n\t\t\t});\n\t\t}\n\n\t\t/*\n\t\t * RENDER - target temperature\n\t\t */\n\t\tfunction renderTargetTemperature() {\n\t\t\tlblTarget_text.nodeValue = Math.floor(self.target_temperature);\n\t\t\tsetClass(lblTargetHalf,'shown',self.target_temperature%1!=0);\n\t\t}\n\t\t\n\t\t/*\n\t\t * RENDER - leaf\n\t\t */\n\t\tfunction renderLeaf() {\n\t\t\tsetClass(svg,'has-leaf',self.has_leaf);\n\t\t}\n\t\t\n\t\t/*\n\t\t * RENDER - HVAC state\n\t\t */\n\t\tfunction renderHvacState() {\n\t\t\tArray.prototype.slice.call(svg.classList).forEach(function(c) {\n\t\t\t\tif (c.match(/^dial--state--/)) {\n\t\t\t\t\tsvg.classList.remove(c);\n\t\t\t\t};\n\t\t\t});\n\t\t\tsvg.classList.add('dial--state--'+self.hvac_state);\n\t\t}\n\t\t\n\t\t/*\n\t\t * RENDER - away\n\t\t */\n\t\tfunction renderAway() {\n\t\t\tsvg.classList[self.away ? 'add' : 'remove']('away');\n\t\t}\n\t\t\n\t\t/*\n\t\t * Drag to control\n\t\t */\n\t\tvar _drag = {\n\t\t\tinProgress: false,\n\t\t\tstartPoint: null,\n\t\t\tstartTemperature: 0,\n\t\t\tlockAxis: undefined\n\t\t};\n\t\t\n\t\tfunction eventPosition(ev) {\n\t\t\tif (ev.targetTouches && ev.targetTouches.length) {\n\t\t\t\treturn [ev.targetTouches[0].clientX, ev.targetTouches[0].clientY];\n\t\t\t} else {\n\t\t\t\treturn [ev.x, ev.y];\n\t\t\t};\n\t\t}\n\t\t\n\t\tvar startDelay;\n\t\tfunction dragStart(ev) {\n\t\t\tstartDelay = setTimeout(function() {\n\t\t\t\tsetClass(svg, 'dial--edit', true);\n\t\t\t\t_drag.inProgress = true;\n\t\t\t\t_drag.startPoint = eventPosition(ev);\n\t\t\t\t_drag.startTemperature = self.target_temperature || options.minValue;\n\t\t\t\t_drag.lockAxis = undefined;\n\t\t\t},1000);\n\t\t};\n\t\t\n\t\tfunction dragEnd (ev) {\n\t\t\tclearTimeout(startDelay);\n\t\t\tsetClass(svg, 'dial--edit', false);\n\t\t\tif (!_drag.inProgress) return;\n\t\t\t_drag.inProgress = false;\n\t\t\tif (self.target_temperature != _drag.startTemperature) {\n\t\t\t\tif (typeof options.onSetTargetTemperature == 'function') {\n\t\t\t\t\toptions.onSetTargetTemperature(self.target_temperature);\n\t\t\t\t};\n\t\t\t};\n\t\t};\n\t\t\n\t\tfunction dragMove(ev) {\n\t\t\tev.preventDefault();\n\t\t\tif (!_drag.inProgress) return;\n\t\t\tvar evPos = eventPosition(ev);\n\t\t\tvar dy = _drag.startPoint[1]-evPos[1];\n\t\t\tvar dx = evPos[0] - _drag.startPoint[0];\n\t\t\tvar dxy;\n\t\t\tif (_drag.lockAxis == 'x') {\n\t\t\t\tdxy = dx;\n\t\t\t} else if (_drag.lockAxis == 'y') {\n\t\t\t\tdxy = dy;\n\t\t\t} else if (Math.abs(dy) > properties.dragLockAxisDistance) {\n\t\t\t\t_drag.lockAxis = 'y';\n\t\t\t\tdxy = dy;\n\t\t\t} else if (Math.abs(dx) > properties.dragLockAxisDistance) {\n\t\t\t\t_drag.lockAxis = 'x';\n\t\t\t\tdxy = dx;\n\t\t\t} else {\n\t\t\t\tdxy = (Math.abs(dy) > Math.abs(dx)) ? dy : dx;\n\t\t\t};\n\t\t\tvar dValue = (dxy*getSizeRatio())/(options.diameter)*properties.rangeValue;\n\t\t\tself.target_temperature = roundHalf(_drag.startTemperature+dValue);\n\t\t}\n\t\t\n\t\tsvg.addEventListener('mousedown',dragStart);\n\t\tsvg.addEventListener('touchstart',dragStart);\n\t\t\n\t\tsvg.addEventListener('mouseup',dragEnd);\n\t\tsvg.addEventListener('mouseleave',dragEnd);\n\t\tsvg.addEventListener('touchend',dragEnd);\n\t\t\n\t\tsvg.addEventListener('mousemove',dragMove);\n\t\tsvg.addEventListener('touchmove',dragMove);\n\t\t//\n\t\t\n\t\t/*\n\t\t * Helper functions\n\t\t */\n\t\tfunction restrictTargetTemperature(t) {\n\t\t\treturn restrictToRange(roundHalf(t),options.minValue,options.maxValue);\n\t\t}\n\t\t\n\t\tfunction angle(point) {\n\t\t\tvar dx = point[0] - properties.radius;\n\t\t\tvar dy = point[1] - properties.radius;\n\t\t\tvar theta = Math.atan(dx/dy) / (Math.PI/180);\n\t\t\tif (point[0]>=properties.radius && point[1] < properties.radius) {\n\t\t\t\ttheta = 90-theta - 90;\n\t\t\t} else if (point[0]>=properties.radius && point[1] >= properties.radius) {\n\t\t\t\ttheta = 90-theta + 90;\n\t\t\t} else if (point[0]<properties.radius && point[1] >= properties.radius) {\n\t\t\t\ttheta = 90-theta + 90;\n\t\t\t} else if (point[0]<properties.radius && point[1] < properties.radius) {\n\t\t\t\ttheta = 90-theta+270;\n\t\t\t}\n\t\t\treturn theta;\n\t\t};\n\t\t\n\t\tfunction getSizeRatio() {\n\t\t\treturn options.diameter / targetElement.clientWidth;\n\t\t}\n\t\t\n\t};\n})();\n\n/* ==== */\nvar initializing = true;\n\n(function(scope) {\n    var nest = new thermostatDial(document.getElementById('thermostat'),{\n    \tonSetTargetTemperature: function(v) {\n    \t    var p = {\n    \t        \"ambient_temperature\":nest.ambient_temperature,\n    \t        \"target_temperature\":v,\n    \t        \"hvac_state\":nest.hvac_state,\n    \t        \"has_leaf\": nest.has_leaf,\n    \t        \"away\":nest.away\n    \t    };\n    \t\tscope.send({topic: \"target_temperature\", payload: p});\n    \t}\n    });\n    \n    scope.$watch('msg', function(data) {\n        if (initializing) {\n            initializing = false;\n            } else {\n            nest.ambient_temperature = data.payload.ambient_temperature || 0;\n            nest.target_temperature = data.payload.target_temperature || 0;\n            nest.hvac_state = data.payload.hvac_state || \"off\";\n            nest.has_leaf = data.payload.has_leaf || false;\n            nest.away = data.payload.away || false;\n        }\n        \n    });\n})(scope);\n\n</script>","storeOutMessages":true,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","className":"","x":1730,"y":820,"wires":[["9e88fc65.058ff"]]},{"id":"7bc1539d.3c518c","type":"function","z":"b6cd7d08.34935","name":"ambient_temperature","func":"msg.topic = 'ambient_temperature';\nglobal.set(\"nest1_ambient_temperature\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1260,"y":820,"wires":[["dd0f0b69.bbee28"]]},{"id":"f8d3f1dc.c595b","type":"function","z":"b6cd7d08.34935","name":"target_temperature","func":"msg.topic = 'target_temperature';\nglobal.set(\"nest1_target_temperature\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1410,"y":700,"wires":[["dd0f0b69.bbee28"]]},{"id":"b0b241af.71eba","type":"function","z":"b6cd7d08.34935","name":"hvac_state","func":"msg.topic = \"hvac_state\";\nglobal.set(\"nest1_hvac_state\",msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1290,"y":900,"wires":[["dd0f0b69.bbee28"]]},{"id":"fab31610.ac3148","type":"inject","z":"b6cd7d08.34935","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"hvac_state","payload":"off","payloadType":"str","x":1090,"y":940,"wires":[["b0b241af.71eba"]]},{"id":"d38502bb.a2c3e","type":"inject","z":"b6cd7d08.34935","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"","topic":"hvac_state","payload":"heating","payloadType":"str","x":1070,"y":980,"wires":[["b0b241af.71eba"]]},{"id":"4b80260.58428dc","type":"inject","z":"b6cd7d08.34935","name":"","repeat":"","crontab":"","once":false,"topic":"hvac_state","payload":"cooling","payloadType":"str","x":1070,"y":1020,"wires":[["b0b241af.71eba"]]},{"id":"dd0f0b69.bbee28","type":"function","z":"b6cd7d08.34935","name":"Data","func":"if (msg.topic == \"target_temperature\") {\n    global.set(\"nest1_target_temperature\",msg.payload);\n}\nmsg.topic = \"update\";\nvar data = {\n    'ambient_temperature': global.get(\"nest1_ambient_temperature\") || 20,\n    'target_temperature': global.get(\"nest1_target_temperature\") || 21,\n    'hvac_state': global.get(\"nest1_hvac_state\") || 'off',\n    'has_leaf': global.get(\"nest1_has_leaf\") || 'false',\n    'away': global.get(\"nest1_away\") || 'false'\n}\nmsg.payload = data;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1610,"y":820,"wires":[["941d174a.01c348"]]},{"id":"9e88fc65.058ff","type":"function","z":"b6cd7d08.34935","name":"New setpoint from UI","func":"if (msg.topic == \"target_temperature\") {\n    global.set(\"nest1_target_temperature\",msg.payload.target_temperature);\n    return msg;\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1900,"y":820,"wires":[[]]},{"id":"6ac1c80c.e83808","type":"inject","z":"b6cd7d08.34935","name":"Load values on node-red startup","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":1230,"y":860,"wires":[["dd0f0b69.bbee28"]]},{"id":"69b0a346e1f18ec6","type":"comment","z":"b6cd7d08.34935","name":"TEMPERATURE VIEW","info":"","x":760,"y":860,"wires":[]},{"id":"6d184978e23c3d8f","type":"function","z":"b6cd7d08.34935","name":"set heater globalVal on","func":"global.set(\"HeaterToggle\",true);\nflow.set(\"tophyst\",false)\nflow.set(\"bottomhyst\",false)\nflow.set(\"hyststart\",true)\nflow.set(\"oldstatus\",true)\n\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":400,"wires":[[]]},{"id":"b5deeec3b50476e6","type":"function","z":"b6cd7d08.34935","name":"set heater globalVal off","func":"global.set(\"HeaterToggle\",false);\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":780,"y":600,"wires":[[]]},{"id":"9f1c91319ecf0146","type":"function","z":"b6cd7d08.34935","name":"Check Heater on/off","func":"if( global.get(\"HeaterToggle\") === true )\n{\n    msg.payload=\"heating\";\n    msg.topic = \"hvac_state\";\n}\nelse\n{\n    msg.payload=\"off\";\n    msg.topic = \"hvac_state\";\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1060,"y":900,"wires":[["b0b241af.71eba"]]},{"id":"4a35f559b4690901","type":"inject","z":"b6cd7d08.34935","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"5","crontab":"","once":true,"onceDelay":"30","topic":"","payload":"","payloadType":"date","x":750,"y":980,"wires":[["9f1c91319ecf0146"]]},{"id":"e1020f2c893d1432","type":"delay","z":"b6cd7d08.34935","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":740,"y":940,"wires":[["9f1c91319ecf0146"]]},{"id":"a7073406bb997adb","type":"delay","z":"b6cd7d08.34935","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":740,"y":900,"wires":[["9f1c91319ecf0146"]]},{"id":"788088e08e7292d0","type":"link in","z":"b6cd7d08.34935","name":"heater set temp","links":["026555e3ad71e0cf","e342e6035235dcf4","204604583c498134","a5478aaf4daf1591"],"x":1045,"y":700,"wires":[["65f0fb14cb2fbb3d"]]},{"id":"5512cedcef6cc468","type":"function","z":"b6cd7d08.34935","name":"get connected relay","func":"msg.payload=global.get(\"heatconnectrelay\");\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1350,"y":300,"wires":[["96d4c4cb45422986"]]},{"id":"bf97c6b00ba3ecec","type":"function","z":"b6cd7d08.34935","name":"get connected relay","func":"msg.payload=global.get(\"heatconnectrelay\");\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1350,"y":440,"wires":[["0d014a2349bcc90e"]]},{"id":"96d4c4cb45422986","type":"split","z":"b6cd7d08.34935","name":"","splt":",","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":1530,"y":300,"wires":[["34624a1b.a87556"]]},{"id":"0d014a2349bcc90e","type":"split","z":"b6cd7d08.34935","name":"","splt":",","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":1530,"y":440,"wires":[["b4769425.119548"]]},{"id":"6c2b9df588efbd44","type":"trigger","z":"b6cd7d08.34935","name":"","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"2","extend":false,"overrideDelay":false,"units":"s","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":220,"y":460,"wires":[["e9309852d4d1c582","4c10aed4e90a4dc5"]]},{"id":"441094683e241bdf","type":"function","z":"b6cd7d08.34935","name":"reset","func":"\nmsg.reset=true;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":90,"y":500,"wires":[["6c2b9df588efbd44"]]},{"id":"e9309852d4d1c582","type":"delay","z":"b6cd7d08.34935","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":280,"y":500,"wires":[["441094683e241bdf"]]},{"id":"ba62da446374db41","type":"link in","z":"b6cd7d08.34935","name":"HeaterSollTemp","links":["174fb16fd5db99e5","117583829b1c4858"],"x":1045,"y":740,"wires":[["65f0fb14cb2fbb3d"]]},{"id":"500dcb53.aa8be4","type":"file","z":"b6cd7d08.34935","name":"","filename":"pekaway/savetimer","filenameType":"str","appendNewline":true,"createDir":true,"overwriteFile":"true","encoding":"none","x":950,"y":100,"wires":[[]]},{"id":"689f7af0527c84bb","type":"function","z":"b6cd7d08.34935","name":"check timer on/off","func":"var check = global.get(\"heattimeronoff\");\n\nmsg.payload = \"Attention: Heater-Timer is set, Heater will act according to the timers! Manual Start/Stop will be overrriden!\"\n\nif(check === true)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":180,"wires":[["6337e5982e12f4a6"]]},{"id":"6337e5982e12f4a6","type":"ui_toast","z":"b6cd7d08.34935","position":"dialog","displayTime":"3","highlight":"","sendall":false,"outputs":1,"ok":"OK","cancel":"Cancel","raw":false,"className":"","topic":"","name":"","x":750,"y":180,"wires":[[]]},{"id":"9f5aa5c71fdca150","type":"trigger","z":"b6cd7d08.34935","name":"","op1":"1","op2":"0","op1type":"str","op2type":"str","duration":"-1","extend":false,"overrideDelay":false,"units":"min","reset":"","bytopic":"all","topic":"topic","outputs":1,"x":950,"y":1060,"wires":[["7e02bb7764c543cb"]]},{"id":"f8a9b2341db30a2b","type":"comment","z":"b6cd7d08.34935","name":"Hysterese Check","info":"","x":460,"y":1020,"wires":[]},{"id":"7e02bb7764c543cb","type":"function","z":"b6cd7d08.34935","name":"get inside tempsensor","func":"if (global.get(\"hysteresis\") == false) {\n    return null\n}\n\nmsg.payload = global.get(\"heattempsensor\");\n\nif(msg.payload != 1 && msg.payload != 2 && msg.payload != 3 && msg.payload != 4)\nmsg.payload=\"no sensor\"\n\nif(msg.payload == 1)\nmsg.payload = global.get(\"temp1\");\n\nif(msg.payload == 2)\nmsg.payload = global.get(\"temp2\");\n\nif(msg.payload == 3)\nmsg.payload = global.get(\"temp3\");\n\nif(msg.payload == 4)\nmsg.payload = global.get(\"temp4\");\n\nif(global.get(\"temp1\") == \"\" && global.get(\"temp2\") == \"\" &&global.get(\"temp3\") == \"\" && global.get(\"temp4\") == \"\")\n{\n    msg.payload =\"no TempSensor\"\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1200,"y":1060,"wires":[["6bdde55840e63aaf"]]},{"id":"6bdde55840e63aaf","type":"function","z":"b6cd7d08.34935","name":"check hysteresis","func":"var hyst = global.get(\"hysteresis\");\nvar settemp = global.get(\"settemp\");\nvar temp =Number(msg.payload);\n\n\n\n//top point\nif((settemp+hyst)<= temp )\n{\nflow.set(\"tophyst\",true)\nflow.set(\"bottomhyst\",false)\nflow.set(\"hyststart\",false)\n}\n\n\n//bottom point\nif((settemp-hyst)>= temp && flow.get(\"hyststart\")==false)\n{\nflow.set(\"tophyst\",false)\nflow.set(\"bottomhyst\",true)\n}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1400,"y":1060,"wires":[["e22aabf7c2710f99"]]},{"id":"e22aabf7c2710f99","type":"function","z":"b6cd7d08.34935","name":"switch on/off","func":"var top = flow.get(\"tophyst\");\n\nif(top == true)\nmsg.payload = false; \n\nif(top == false)\nmsg.payload = true; \n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1570,"y":1060,"wires":[["4a99f4f3dd2ab9f2"]]},{"id":"4a99f4f3dd2ab9f2","type":"function","z":"b6cd7d08.34935","name":"change?","func":"var oldstatus = flow.get(\"oldstatus\"); \nif(msg.payload != oldstatus)\n{\n    flow.set(\"oldstatus\",msg.payload); \n    return msg;\n}\n\n\n\n\n\n\n\n\n\n\n\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1720,"y":1060,"wires":[["463a2a21d6db0ed8"]]},{"id":"463a2a21d6db0ed8","type":"switch","z":"b6cd7d08.34935","name":"","property":"payload","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}],"checkall":"true","repair":false,"outputs":2,"x":1850,"y":1060,"wires":[["9b3fc01458c8cf09"],["9fae8927d8332b8a","36db7746bfc6449c"]]},{"id":"9b3fc01458c8cf09","type":"link out","z":"b6cd7d08.34935","name":"hyst-timer start","mode":"link","links":["eb1e92403a6a4490"],"x":1975,"y":1020,"wires":[]},{"id":"9fae8927d8332b8a","type":"link out","z":"b6cd7d08.34935","name":"hyst timer off","mode":"link","links":["8114989ad3d836db"],"x":1975,"y":1060,"wires":[]},{"id":"de017432cf865f01","type":"function","z":"b6cd7d08.34935","name":"check Heatertoggle false","func":"if(global.get(\"HeaterToggle\") == false) {\n    msg.reset=true;\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":1060,"wires":[["9f5aa5c71fdca150"]]},{"id":"4c2ff550cab39384","type":"delay","z":"b6cd7d08.34935","name":"","pauseType":"delay","timeout":"25","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":470,"y":1060,"wires":[["de017432cf865f01"]]},{"id":"2f7f98c2133c3722","type":"function","z":"b6cd7d08.34935","name":"set Heatertoggle true","func":"global.set(\"HeaterToggle\", true);\nmsg.payload = global.get(\"HeaterToggle\")\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":2260,"y":1100,"wires":[[]]},{"id":"36db7746bfc6449c","type":"delay","z":"b6cd7d08.34935","name":"","pauseType":"delay","timeout":"20","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":2050,"y":1100,"wires":[["2f7f98c2133c3722"]]},{"id":"6170c7bb5afa2ee0","type":"link out","z":"b6cd7d08.34935","name":"Update Autoterm","mode":"link","links":["d4f5fa9c86e1dffc"],"x":1335,"y":740,"wires":[]},{"id":"b8e3ecee0b573c95","type":"ui_slider","z":"b6cd7d08.34935","name":"","label":"Set Runtime (min)","tooltip":"set a runtime in min (max 600)","group":"2bd22a1d380636dc","order":5,"width":0,"height":0,"passthru":true,"outs":"end","topic":"topic","topicType":"msg","min":0,"max":"600","step":"10","className":"","x":450,"y":1140,"wires":[["be0516f5cab3eb3e","2a218bb3d3288432"]]},{"id":"e258c939e86e4b99","type":"countdown","z":"b6cd7d08.34935","name":"","topic":"","payloadTimerStart":"true","payloadTimerStartType":"bool","payloadTimerStop":"false","payloadTimerStopType":"bool","timer":30,"resetWhileRunning":false,"setTimeToNewWhileRunning":true,"startCountdownOnControlMessage":true,"minuteCounter":false,"x":910,"y":1140,"wires":[["9c31f6ddfb094bea"],["9c31f6ddfb094bea","14c0b5ae132daa0a"]]},{"id":"be0516f5cab3eb3e","type":"function","z":"b6cd7d08.34935","name":"set Topic to Control","func":"if (msg.payload == 0) {\n    global.set(\"heater_runtime\", msg.payload)\n    msg.payload = \"cancel\"\n    msg.topic = \"control\"\n    global.set(\"heater_runtime\", msg.payload)\n    return msg\n}\nelse {\n    global.set(\"heater_runtime\", msg.payload)\n    msg.payload = Number(msg.payload*60)\n    msg.topic=\"control\";\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":1140,"wires":[["e258c939e86e4b99","c4866e1a5477f481"]]},{"id":"9c31f6ddfb094bea","type":"function","z":"b6cd7d08.34935","name":"turn heater off","func":"if(msg.payload==false)\n{\nmsg.payload=\"Off\";\nreturn msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1140,"wires":[["4c10aed4e90a4dc5"]]},{"id":"a3bc533422d7b201","type":"ui_text","z":"b6cd7d08.34935","group":"2bd22a1d380636dc","order":6,"width":0,"height":0,"name":"","label":"remaining time:","format":"{{msg.payload}}","layout":"row-spread","className":"","x":1300,"y":1180,"wires":[]},{"id":"14c0b5ae132daa0a","type":"function","z":"b6cd7d08.34935","name":"remaining time","func":"if (msg.payload == -1 || msg.payload == -0) {\n    return null\n}\n\nif (msg.payload == \"cancel\") {\n    msg.payload = \" \"\n    return msg\n}\nelse {\n    let minutes = Math.floor(msg.payload / 60);\n    minutes = (minutes < 10) ? \"0\" + minutes : minutes;\n    let seconds = msg.payload - minutes * 60;\n    seconds = (seconds < 10) ? \"0\" + seconds : seconds;\n    msg.payload = minutes + \":\" + seconds\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1180,"wires":[["a3bc533422d7b201"]]},{"id":"2a218bb3d3288432","type":"delay","z":"b6cd7d08.34935","d":true,"name":"","pauseType":"delay","timeout":"500","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":700,"y":1100,"wires":[["e258c939e86e4b99"]]},{"id":"8af79106108d6249","type":"ui_button","z":"b6cd7d08.34935","name":"","group":"7a4cccdc02082fbb","order":1,"width":"3","height":"2","passthru":false,"label":"On","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"on","payloadType":"str","topic":"maxxair","topicType":"msg","x":210,"y":1260,"wires":[["080e681788bd8398"]]},{"id":"080e681788bd8398","type":"function","z":"b6cd7d08.34935","name":"filter commands","func":"if (msg.payload == \"on\") {\n    msg.payload = \"b\"\n    global.set(\"maxxair\", true)\n    global.set(\"maxxair_lid\", \"open\")\n}\nelse if (msg.payload == \"off\") {\n    msg.payload = \"a\"\n    global.set(\"maxxair\", false)\n    global.set(\"maxxair_lid\", \"close\")\n}\nelse if (msg.payload == \"open\") {\n    msg.payload = \"d\"\n    global.set(\"maxxair_lid\", \"open\")\n}\nelse if (msg.payload == \"close\") {\n    msg.payload = \"a\"\n    global.set(\"maxxair\", false)\n    //msg.payload = \"c\"\n    global.set(\"maxxair_lid\", \"close\")\n}\nelse if (msg.payload == \"in\") {\n    msg.payload = \"f\"\n    global.set(\"maxxair_direction\", \"in\")\n}\nelse if (msg.payload == \"out\") {\n    msg.payload = \"e\"\n    global.set(\"maxxair_direction\", \"out\")\n}\nelse if (msg.payload == 1) {\n    msg.payload = \"0\"\n    global.set(\"maxxair_speed\", 10)\n}\nelse if (msg.payload == 2) {\n    msg.payload = \"1\"\n    global.set(\"maxxair_speed\", 20)\n}\nelse if (msg.payload == 3) {\n    msg.payload = \"2\"\n    global.set(\"maxxair_speed\", 30)\n}\nelse if (msg.payload == 4) {\n    msg.payload = \"3\"\n    global.set(\"maxxair_speed\", 40)\n}\nelse if (msg.payload == 5) {\n    msg.payload = \"4\"\n    global.set(\"maxxair_speed\", 50)\n}\nelse if (msg.payload == 6) {\n    msg.payload = \"5\"\n    global.set(\"maxxair_speed\", 60)\n}\nelse if (msg.payload == 7) {\n    msg.payload = \"6\"\n    global.set(\"maxxair_speed\", 70)\n}\nelse if (msg.payload == 8) {\n    msg.payload = \"7\"\n    global.set(\"maxxair_speed\", 80)\n}\nelse if (msg.payload == 9) {\n    msg.payload = \"8\"\n    global.set(\"maxxair_speed\", 90)\n}\nelse if (msg.payload == 10) {\n    msg.payload = \"9\"\n    global.set(\"maxxair_speed\", 100)\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":420,"y":1300,"wires":[["7d6ea3fe6beaf3ba","9e18aeadb5fa422c"]]},{"id":"8702063255977846","type":"ui_button","z":"b6cd7d08.34935","name":"","group":"7a4cccdc02082fbb","order":2,"width":"3","height":"2","passthru":false,"label":"Off","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"off","payloadType":"str","topic":"maxxair","topicType":"msg","x":210,"y":1300,"wires":[["080e681788bd8398"]]},{"id":"27076aefceb7ca3d","type":"link out","z":"b6cd7d08.34935","name":"maxxfan on/off","mode":"link","links":["631e04e732bc5864"],"x":974,"y":1269,"wires":[]},{"id":"44e7b0c37ef1a392","type":"ui_button","z":"b6cd7d08.34935","name":"","group":"7a4cccdc02082fbb","order":3,"width":"3","height":"1","passthru":false,"label":"Open","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"open","payloadType":"str","topic":"maxxair","topicType":"msg","x":210,"y":1340,"wires":[["080e681788bd8398"]]},{"id":"f01c7d69ce4ee6b2","type":"ui_button","z":"b6cd7d08.34935","name":"","group":"7a4cccdc02082fbb","order":4,"width":"3","height":"1","passthru":false,"label":"Close","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"close","payloadType":"str","topic":"maxxair","topicType":"msg","x":210,"y":1380,"wires":[["080e681788bd8398"]]},{"id":"c0564d2fee99bdff","type":"ui_button","z":"b6cd7d08.34935","name":"","group":"7a4cccdc02082fbb","order":5,"width":"3","height":"1","passthru":false,"label":"In","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"in","payloadType":"str","topic":"maxxair","topicType":"msg","x":210,"y":1420,"wires":[["080e681788bd8398"]]},{"id":"0dc1dc5e48f5c773","type":"ui_button","z":"b6cd7d08.34935","name":"","group":"7a4cccdc02082fbb","order":6,"width":"3","height":"1","passthru":false,"label":"Out","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"out","payloadType":"str","topic":"maxxair","topicType":"msg","x":210,"y":1460,"wires":[["080e681788bd8398"]]},{"id":"a0c11aceb7452753","type":"ui_slider","z":"b6cd7d08.34935","name":"","label":"speed","tooltip":"","group":"7a4cccdc02082fbb","order":7,"width":0,"height":0,"passthru":true,"outs":"end","topic":"maxxair","topicType":"msg","min":"1","max":10,"step":1,"className":"","x":210,"y":1500,"wires":[["080e681788bd8398"]]},{"id":"7d6ea3fe6beaf3ba","type":"function","z":"b6cd7d08.34935","d":true,"name":"","func":"msg.payload = global.get(\"maxxair\")\nnode.send([msg, null, null])\nmsg.payload = global.get(\"maxxair_lid\")\nnode.send([null, msg, null])\nmsg.payload = global.get(\"maxxair_direction\")\nnode.send([null, null, msg])","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":1340,"wires":[[],[],[]]},{"id":"dd397f67ce5d21fd","type":"comment","z":"b6cd7d08.34935","name":"MaxxAir Fan Controller","info":"","x":440,"y":1260,"wires":[]},{"id":"1140e78f8a3923c0","type":"switch","z":"b6cd7d08.34935","name":"ROUTER","property":"topic","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"2","vt":"num"},{"t":"eq","v":"3","vt":"num"},{"t":"eq","v":"4","vt":"num"}],"checkall":"true","repair":false,"outputs":4,"x":840,"y":1300,"wires":[["27076aefceb7ca3d"],["0cc59064c3a278d6"],["3b407df01a5b9435"],["42589028751521b8"]]},{"id":"9e18aeadb5fa422c","type":"function","z":"b6cd7d08.34935","name":"check uart settings","func":"if (global.get(\"usb1uart\") == \"9\") {\n    msg.topic=1;\n    node.send(msg);\n}\nif (global.get(\"usb2uart\") == \"9\") {\n    msg.topic=2;\n    node.send(msg);\n}\nif (global.get(\"usb3uart\") == \"9\") {\n    msg.topic=3;\n    node.send(msg);\n}\nif (global.get(\"usb4uart\") == \"9\"){\n    msg.topic=4;\n    node.send(msg);\n}\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":630,"y":1300,"wires":[["1140e78f8a3923c0"]]},{"id":"0cc59064c3a278d6","type":"link out","z":"b6cd7d08.34935","name":"maxxfan on/off","mode":"link","links":["e1b033b72073b492"],"x":974,"y":1289,"wires":[]},{"id":"3b407df01a5b9435","type":"link out","z":"b6cd7d08.34935","name":"maxxfan on/off","mode":"link","links":["1b1168f8607d8205"],"x":974,"y":1309,"wires":[]},{"id":"42589028751521b8","type":"link out","z":"b6cd7d08.34935","name":"maxxfan on/off","mode":"link","links":["38cb32c06a098f9e"],"x":974,"y":1329,"wires":[]},{"id":"df953ef470f7b6b5","type":"function","z":"b6cd7d08.34935","name":"stop countdown","func":"msg.payload = \"cancel\"\nmsg.topic = \"control\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":700,"y":1180,"wires":[["e258c939e86e4b99","cec20f1d4df6a5aa"]]},{"id":"cec20f1d4df6a5aa","type":"delay","z":"b6cd7d08.34935","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":700,"y":1220,"wires":[["3a6f6d04dbcf7cc9","14c0b5ae132daa0a"]]},{"id":"3a6f6d04dbcf7cc9","type":"function","z":"b6cd7d08.34935","name":"stop countdown","func":"msg.payload = 0\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":260,"y":1140,"wires":[["b8e3ecee0b573c95"]]},{"id":"c4866e1a5477f481","type":"delay","z":"b6cd7d08.34935","name":"400ms","pauseType":"delay","timeout":"400","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":890,"y":1180,"wires":[["14c0b5ae132daa0a"]]},{"id":"093319b1a513fb43","type":"link in","z":"b6cd7d08.34935","name":"heater runtime","links":["204604583c498134","a5478aaf4daf1591","8976e469b15db9cc"],"x":325,"y":1100,"wires":[["b8e3ecee0b573c95"]]},{"id":"e567390c9e2d4bbc","type":"debug","z":"b6cd7d08.34935","name":"debug 96","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":640,"y":260,"wires":[]},{"id":"4d6141426495610b","type":"ui_group","name":"Timer","tab":"5007f157b6c708d0","order":3,"disp":true,"width":"6","collapse":true,"className":""},{"id":"2bd22a1d380636dc","type":"ui_group","name":"Controls","tab":"5007f157b6c708d0","order":2,"disp":true,"width":"6","collapse":true,"className":""},{"id":"2a7d142135bfa4c0","type":"ui_group","name":"Temperature","tab":"5007f157b6c708d0","order":1,"disp":true,"width":"6","collapse":true,"className":""},{"id":"7a4cccdc02082fbb","type":"ui_group","name":"MaxxAir MaxxFan","tab":"fe23d70511f62324","order":1,"disp":true,"width":"6","collapse":true,"className":""},{"id":"5007f157b6c708d0","type":"ui_tab","name":"Heater","icon":"mi-whatshot","order":3,"disabled":false,"hidden":false},{"id":"fe23d70511f62324","type":"ui_tab","name":"MaxxFan","icon":"mi-toys","order":5,"disabled":false,"hidden":false}]

Init Flow:

Die neuen Variablen werden entsprechend geladen beim Systemstart:

die Node:

[{"id":"bb0abe7e.248eb","type":"function","z":"1f780f8f.dbcd5","name":"init values","func":"//boot process\nglobal.set(\"boot_process\", true);\nglobal.set(\"rpi_cpu_temp\", 0)\nglobal.set(\"rpi_cpu_usage\", 0)\n\n//Relays\nglobal.set(\"one\", false);\nglobal.set(\"two\", false);\nglobal.set(\"three\", false);\nglobal.set(\"four\", false);\nglobal.set(\"five\", false);\nglobal.set(\"six\", false);\nglobal.set(\"seven\", false);\nglobal.set(\"eight\", false);\nglobal.set(\"nine\", false);\nglobal.set(\"ten\", false);\nglobal.set(\"Wone\", false);\nglobal.set(\"Wtwo\", false);\nglobal.set(\"Wthree\", false);\nglobal.set(\"Wfour\", false);\nglobal.set(\"Wfive\", false);\nglobal.set(\"Wsix\", false);\nglobal.set(\"Wseven\", false);\nglobal.set(\"Weight\", false);\n\n//name variables\nglobal.set(\"None\", \"wait\");\nglobal.set(\"Ntwo\", \"wait\");\nglobal.set(\"Nthree\", \"wait\");\nglobal.set(\"Nfour\", \"wait\");\nglobal.set(\"Nfive\", \"wait\");\nglobal.set(\"Nsix\", \"wait\");\nglobal.set(\"Nseven\", \"wait\");\nglobal.set(\"Neight\", \"wait\");\nglobal.set(\"Nnine\", \"wait\");\nglobal.set(\"Nten\", \"wait\");\nglobal.set(\"Ntemp1\",\"wait\");\nglobal.set(\"Ntemp2\",\"wait\");\nglobal.set(\"Ntemp3\",\"wait\");\nglobal.set(\"Ntemp4\",\"wait\");\nglobal.set(\"NLevel1\",\"wait\");\nglobal.set(\"NLevel2\",\"wait\");\nglobal.set(\"NLevel3\",\"wait\");\nglobal.set(\"NLevel4\",\"wait\");\nglobal.set(\"NWone\", \"wait\");\nglobal.set(\"NWtwo\", \"wait\");\nglobal.set(\"NWthree\", \"wait\");\nglobal.set(\"NWfour\", \"wait\");\nglobal.set(\"NWfive\", false);\nglobal.set(\"NWsix\", false);\nglobal.set(\"NWseven\", false);\nglobal.set(\"NWeight\", false);\n\n//temp\nglobal.set(\"temp1\",\"\");\nglobal.set(\"temp2\",\"\");\nglobal.set(\"temp3\",\"\");\nglobal.set(\"temp4\",\"\");\nglobal.set(\"dimmytemp1\",\"\");\nglobal.set(\"dimmytemp2\",\"\");\nglobal.set(\"temp1_offset\", 0);\nglobal.set(\"temp2_offset\", 0);\nglobal.set(\"temp3_offset\", 0);\nglobal.set(\"temp4_offset\", 0);\nglobal.set(\"dimmytemp1_offset\", 0)\nglobal.set(\"dimmytemp2_offset\", 0)\n\n//Heater\nglobal.set(\"heatstatus\",\"wait\");\nglobal.set(\"heattemp\",\"wait\");\nglobal.set(\"heatvolt\",0);\nglobal.set(\"heatfan\",\"wait\");\nglobal.set(\"heatglow\",\"wait\");\nglobal.set(\"heatpump\",0);\nglobal.set(\"heatwpump\",0);\nglobal.set(\"heaterror\",\"no\");\nglobal.set(\"heattempsensor\",0);\nglobal.set(\"hysteresis\",5);\nglobal.set(\"HeaterToggle\",false);\nglobal.set(\"Autotermheatingpower\",0);\n//heatconnect\nglobal.set(\"heatconnectrelay\",\"-1\");\nglobal.set(\"heattimeronoff\",false);\n\n//WaterLevel\nglobal.set(\"Level1\",0);\nglobal.set(\"Level2\",0);\nglobal.set(\"Level3\",0);\nglobal.set(\"Level4\",0);\nglobal.set(\"levelfull\",\"wait\");\nglobal.set(\"levelempty\",\"wait\");\n\n////battery\nglobal.set(\"BATTsoc\",\"wait\");\nglobal.set(\"BATTvolt\",\"wait\");\nglobal.set(\"BATTamps\",\"wait\");\nglobal.set(\"ttgo\", \"0\")\n\n//pekawayshunt\nglobal.set(\"pkwshuntWatthours\",\"wait\");\nglobal.set(\"pkwshunttyp\",\"wait\");\nglobal.set(\"pkwshuntamps\",\"wait\");\nglobal.set(\"pkwshuntMAXWatthours\",\"wait\");\nglobal.set(\"pkwshuntvolt\",\"wait\");\nglobal.set(\"pkwshuntSOC\",\"wait\");\nglobal.set(\"pkwshuntactive\",\"wait\");\nglobal.set(\"shuntcalibrate\",1);\n\n//BMS - Daly-Liontron-jbd-xiaoxing\nglobal.set(\"BMSamps\",\"wait\");\nglobal.set(\"BMSsoc\",\"wait\");\nglobal.set(\"BMSvolt\",\"wait\");\nglobal.set(\"BMScap\",\"wait\");\nglobal.set(\"BMSmaxcap\",\"wait\");\nglobal.set(\"BMScell1\",\"wait\");\nglobal.set(\"BMScell2\",\"wait\");\nglobal.set(\"BMScell3\",\"wait\");\nglobal.set(\"BMScell4\",\"wait\");\nglobal.set(\"BMScell4\",\"wait\");\nglobal.set(\"BMSminvolt\",\"wait\");\nglobal.set(\"BMSmaxvolt\",\"wait\");\n\n//victronSHUNT\n\n//system\nglobal.set(\"shunt\",\"200\");\nglobal.set(\"USB\",true);\nglobal.set(\"ssid\",\"\");\nglobal.set(\"wpa\",\"\");\nglobal.set(\"IPWIFI4Port\",0);\nglobal.set(\"wifirelay\",false)\nglobal.set(\"stdrelay\",false)\nglobal.set(\"settemp\",20)\nglobal.set(\"multiuart\",0)\n//1 DALY  - 2 VICTRON\nglobal.set(\"usb1uart\",0)\nglobal.set(\"usb2uart\",0)\n//1 DALY  - 2 VICTRON - 3 webasto - 4 chinaheater\nglobal.set(\"PKWshunt\",false);\nglobal.set(\"usb1status\",\"0\")\nglobal.set(\"usb2status\",\"0\")\nglobal.set(\"usbPortcheck_victron\",false)\nglobal.set(\"usbPortcheck_DALYmonit\",false)\nglobal.set(\"usbPortcheck_DALYblue\",false)\nglobal.set(\"currentVersion\",\"0.0.0\");\nglobal.set(\"wifiIP\",\"0.0.0.0\");\nglobal.set(\"eth0IP\",\"0.0.0.0\");\n\n/////VE.direct\n//Inverter\nglobal.set(\"VE_AC_V\",0);\nglobal.set(\"VE_AC_i\",0);\nglobal.set(\"VE_Vin\",0);\n//SmartSolar\nglobal.set(\"VE_PanelVolt\",0);\nglobal.set(\"VE_PanelPower\",0);\nglobal.set(\"VE_BatteryVolt\",0);\nglobal.set(\"VE_solarCurrent\",0);\n//Shunt\nglobal.set(\"VE_Mainbattery\",0);\nglobal.set(\"VE_StarterBattery\",0);\nglobal.set(\"VE_Current\",0);\nglobal.set(\"VE_Power\",0);\nglobal.set(\"VE_consumedAH\",0);\nglobal.set(\"VE_SOC\",0);\nglobal.set(\"VE_maxVolt\",0);\nglobal.set(\"VE_minVolt\",0);\nglobal.set(\"VE_timetogo\",0);\n\n//BLE\nglobal.set(\"BLEdevice\",\"0\");\nglobal.set(\"MACliontron\",\"\");\nglobal.set(\"btbms_type\", \"\")\nglobal.set(\"ble_bms_empty_counter\", 0)\nglobal.set(\"ble_retry\", 0)\n\n//BMS max-min values\nglobal.set(\"BMSmaxvolthighest\", \"wait\")\nglobal.set(\"BMSminvoltlowest\", \"wait\")\nglobal.set(\"BMSmaxcaphighest\", \"wait\")\n\n// Boiler\nglobal.set(\"boiler_visibility\", false)","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":300,"wires":[[]]}]

Und nochmal der komplette Init Flow:

[{"id":"1f780f8f.dbcd5","type":"tab","label":"Init_flow","disabled":false,"info":"### "},{"id":"bb0abe7e.248eb","type":"function","z":"1f780f8f.dbcd5","name":"init values","func":"//boot process\nglobal.set(\"boot_process\", true);\nglobal.set(\"rpi_cpu_temp\", 0)\nglobal.set(\"rpi_cpu_usage\", 0)\n\n//Relays\nglobal.set(\"one\", false);\nglobal.set(\"two\", false);\nglobal.set(\"three\", false);\nglobal.set(\"four\", false);\nglobal.set(\"five\", false);\nglobal.set(\"six\", false);\nglobal.set(\"seven\", false);\nglobal.set(\"eight\", false);\nglobal.set(\"nine\", false);\nglobal.set(\"ten\", false);\nglobal.set(\"Wone\", false);\nglobal.set(\"Wtwo\", false);\nglobal.set(\"Wthree\", false);\nglobal.set(\"Wfour\", false);\nglobal.set(\"Wfive\", false);\nglobal.set(\"Wsix\", false);\nglobal.set(\"Wseven\", false);\nglobal.set(\"Weight\", false);\n\n//name variables\nglobal.set(\"None\", \"wait\");\nglobal.set(\"Ntwo\", \"wait\");\nglobal.set(\"Nthree\", \"wait\");\nglobal.set(\"Nfour\", \"wait\");\nglobal.set(\"Nfive\", \"wait\");\nglobal.set(\"Nsix\", \"wait\");\nglobal.set(\"Nseven\", \"wait\");\nglobal.set(\"Neight\", \"wait\");\nglobal.set(\"Nnine\", \"wait\");\nglobal.set(\"Nten\", \"wait\");\nglobal.set(\"Ntemp1\",\"wait\");\nglobal.set(\"Ntemp2\",\"wait\");\nglobal.set(\"Ntemp3\",\"wait\");\nglobal.set(\"Ntemp4\",\"wait\");\nglobal.set(\"NLevel1\",\"wait\");\nglobal.set(\"NLevel2\",\"wait\");\nglobal.set(\"NLevel3\",\"wait\");\nglobal.set(\"NLevel4\",\"wait\");\nglobal.set(\"NWone\", \"wait\");\nglobal.set(\"NWtwo\", \"wait\");\nglobal.set(\"NWthree\", \"wait\");\nglobal.set(\"NWfour\", \"wait\");\nglobal.set(\"NWfive\", false);\nglobal.set(\"NWsix\", false);\nglobal.set(\"NWseven\", false);\nglobal.set(\"NWeight\", false);\n\n//temp\nglobal.set(\"temp1\",\"\");\nglobal.set(\"temp2\",\"\");\nglobal.set(\"temp3\",\"\");\nglobal.set(\"temp4\",\"\");\nglobal.set(\"dimmytemp1\",\"\");\nglobal.set(\"dimmytemp2\",\"\");\nglobal.set(\"temp1_offset\", 0);\nglobal.set(\"temp2_offset\", 0);\nglobal.set(\"temp3_offset\", 0);\nglobal.set(\"temp4_offset\", 0);\nglobal.set(\"dimmytemp1_offset\", 0)\nglobal.set(\"dimmytemp2_offset\", 0)\n\n//Heater\nglobal.set(\"heatstatus\",\"wait\");\nglobal.set(\"heattemp\",\"wait\");\nglobal.set(\"heatvolt\",0);\nglobal.set(\"heatfan\",\"wait\");\nglobal.set(\"heatglow\",\"wait\");\nglobal.set(\"heatpump\",0);\nglobal.set(\"heatwpump\",0);\nglobal.set(\"heaterror\",\"no\");\nglobal.set(\"heattempsensor\",0);\nglobal.set(\"hysteresis\",5);\nglobal.set(\"HeaterToggle\",false);\nglobal.set(\"Autotermheatingpower\",0);\n//heatconnect\nglobal.set(\"heatconnectrelay\",\"-1\");\nglobal.set(\"heattimeronoff\",false);\n\n//WaterLevel\nglobal.set(\"Level1\",0);\nglobal.set(\"Level2\",0);\nglobal.set(\"Level3\",0);\nglobal.set(\"Level4\",0);\nglobal.set(\"levelfull\",\"wait\");\nglobal.set(\"levelempty\",\"wait\");\n\n////battery\nglobal.set(\"BATTsoc\",\"wait\");\nglobal.set(\"BATTvolt\",\"wait\");\nglobal.set(\"BATTamps\",\"wait\");\nglobal.set(\"ttgo\", \"0\")\n\n//pekawayshunt\nglobal.set(\"pkwshuntWatthours\",\"wait\");\nglobal.set(\"pkwshunttyp\",\"wait\");\nglobal.set(\"pkwshuntamps\",\"wait\");\nglobal.set(\"pkwshuntMAXWatthours\",\"wait\");\nglobal.set(\"pkwshuntvolt\",\"wait\");\nglobal.set(\"pkwshuntSOC\",\"wait\");\nglobal.set(\"pkwshuntactive\",\"wait\");\nglobal.set(\"shuntcalibrate\",1);\n\n//BMS - Daly-Liontron-jbd-xiaoxing\nglobal.set(\"BMSamps\",\"wait\");\nglobal.set(\"BMSsoc\",\"wait\");\nglobal.set(\"BMSvolt\",\"wait\");\nglobal.set(\"BMScap\",\"wait\");\nglobal.set(\"BMSmaxcap\",\"wait\");\nglobal.set(\"BMScell1\",\"wait\");\nglobal.set(\"BMScell2\",\"wait\");\nglobal.set(\"BMScell3\",\"wait\");\nglobal.set(\"BMScell4\",\"wait\");\nglobal.set(\"BMScell4\",\"wait\");\nglobal.set(\"BMSminvolt\",\"wait\");\nglobal.set(\"BMSmaxvolt\",\"wait\");\n\n//victronSHUNT\n\n//system\nglobal.set(\"shunt\",\"200\");\nglobal.set(\"USB\",true);\nglobal.set(\"ssid\",\"\");\nglobal.set(\"wpa\",\"\");\nglobal.set(\"IPWIFI4Port\",0);\nglobal.set(\"wifirelay\",false)\nglobal.set(\"stdrelay\",false)\nglobal.set(\"settemp\",20)\nglobal.set(\"multiuart\",0)\n//1 DALY  - 2 VICTRON\nglobal.set(\"usb1uart\",0)\nglobal.set(\"usb2uart\",0)\n//1 DALY  - 2 VICTRON - 3 webasto - 4 chinaheater\nglobal.set(\"PKWshunt\",false);\nglobal.set(\"usb1status\",\"0\")\nglobal.set(\"usb2status\",\"0\")\nglobal.set(\"usbPortcheck_victron\",false)\nglobal.set(\"usbPortcheck_DALYmonit\",false)\nglobal.set(\"usbPortcheck_DALYblue\",false)\nglobal.set(\"currentVersion\",\"0.0.0\");\nglobal.set(\"wifiIP\",\"0.0.0.0\");\nglobal.set(\"eth0IP\",\"0.0.0.0\");\n\n/////VE.direct\n//Inverter\nglobal.set(\"VE_AC_V\",0);\nglobal.set(\"VE_AC_i\",0);\nglobal.set(\"VE_Vin\",0);\n//SmartSolar\nglobal.set(\"VE_PanelVolt\",0);\nglobal.set(\"VE_PanelPower\",0);\nglobal.set(\"VE_BatteryVolt\",0);\nglobal.set(\"VE_solarCurrent\",0);\n//Shunt\nglobal.set(\"VE_Mainbattery\",0);\nglobal.set(\"VE_StarterBattery\",0);\nglobal.set(\"VE_Current\",0);\nglobal.set(\"VE_Power\",0);\nglobal.set(\"VE_consumedAH\",0);\nglobal.set(\"VE_SOC\",0);\nglobal.set(\"VE_maxVolt\",0);\nglobal.set(\"VE_minVolt\",0);\nglobal.set(\"VE_timetogo\",0);\n\n//BLE\nglobal.set(\"BLEdevice\",\"0\");\nglobal.set(\"MACliontron\",\"\");\nglobal.set(\"btbms_type\", \"\")\nglobal.set(\"ble_bms_empty_counter\", 0)\nglobal.set(\"ble_retry\", 0)\n\n//BMS max-min values\nglobal.set(\"BMSmaxvolthighest\", \"wait\")\nglobal.set(\"BMSminvoltlowest\", \"wait\")\nglobal.set(\"BMSmaxcaphighest\", \"wait\")\n\n// Boiler\nglobal.set(\"boiler_visibility\", false)","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":300,"wires":[[]]},{"id":"c7cbcff5.db10e","type":"inject","z":"1f780f8f.dbcd5","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"2","topic":"","payload":"","payloadType":"date","x":230,"y":220,"wires":[["bb0abe7e.248eb","c3e179f9.47e318","14b4a7d6.23a9e8","72204697.5e7d18","71e76301.9a03bc","cb58f8fd7638bcad","73133552bf558250","e88d437867a17dad"]]},{"id":"a47e398b.260cf8","type":"comment","z":"1f780f8f.dbcd5","name":"set global variables ","info":"","x":210,"y":160,"wires":[]},{"id":"211d8ec8.f10ef2","type":"exec","z":"1f780f8f.dbcd5","command":"sudo as'1-1'|sudo tee /sys/bus/usb/drivers/usb/unbind","addpay":false,"append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":860,"y":260,"wires":[[],[],[]]},{"id":"c3e179f9.47e318","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"outputs":1,"x":540,"y":260,"wires":[["211d8ec8.f10ef2"]]},{"id":"19d15ad5.eedeb5","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/shunt","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1580,"y":880,"wires":[["c1e31cfa.c8417"]]},{"id":"c1e31cfa.c8417","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n  str = str.substring(0, 3);\n\n global.set(\"shunt\", str);\n  \n \n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1810,"y":880,"wires":[[]]},{"id":"9800eddd.497e3","type":"comment","z":"1f780f8f.dbcd5","name":"get config","info":"","x":980,"y":300,"wires":[]},{"id":"14b4a7d6.23a9e8","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"8","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1000,"y":340,"wires":[["423cba0.d02e248","e1afddf0.78e6","df9f0e4b.b9826","54053996dab16093"]]},{"id":"7cf8e3cf.bc282c","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" global.set(\"heatconnectrelay\", msg.payload);","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1820,"y":380,"wires":[[]]},{"id":"423cba0.d02e248","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/heatconnect","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1640,"y":380,"wires":[["7cf8e3cf.bc282c"]]},{"id":"3a9b9ea5.0a4972","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name1","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":640,"wires":[["d4687fdb.22778"]]},{"id":"c025819e.880ba","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name2","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":680,"wires":[["8c200c55.44ac"]]},{"id":"634eed34.7dcfd4","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name3","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":720,"wires":[["7ea32a4e.584854"]]},{"id":"1569b76c.efab19","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name4","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":760,"wires":[["f3703803.f35e48"]]},{"id":"a240ee.09a0ff1","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name5","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":800,"wires":[["689aa7cb.2b4bf8"]]},{"id":"d62b8787.eaca38","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name6","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":840,"wires":[["3995db45.c47ce4"]]},{"id":"727b414a.735f6","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name8","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":920,"wires":[["4275d2e2.10131c"]]},{"id":"4b3355df.7c4eec","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name7","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":880,"wires":[["b4954b5.80b80b8"]]},{"id":"72204697.5e7d18","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":534,"y":592,"wires":[["3a9b9ea5.0a4972","c025819e.880ba","634eed34.7dcfd4","1569b76c.efab19","a240ee.09a0ff1","d62b8787.eaca38","4b3355df.7c4eec","727b414a.735f6","fb96a8d.fbd7358","da33619d.3d9d2","20ccae05.153222","11227dd8.aa7b82","9c8a60af.99a87","d1e57b73.4b3768","6fa7559b.332e6c","e4ca4d64a82b0cea","137dc61d3bb3ac88","fdf2f349a4240f48","15c2f2cd8f954356","5d3d4dc1100a682d","0fc45db90a975e40","1f68b0852ec01670","ea056e6598b5f8c6","36c5ccc88d0205ae","e9dcf377ec0880b3"]]},{"id":"d4687fdb.22778","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"None\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":640,"wires":[[]]},{"id":"8c200c55.44ac","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Ntwo\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":680,"wires":[[]]},{"id":"7ea32a4e.584854","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Nthree\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":720,"wires":[[]]},{"id":"f3703803.f35e48","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Nfour\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":760,"wires":[[]]},{"id":"689aa7cb.2b4bf8","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Nfive\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":800,"wires":[[]]},{"id":"3995db45.c47ce4","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Nsix\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":840,"wires":[[]]},{"id":"b4954b5.80b80b8","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Nseven\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":880,"wires":[[]]},{"id":"4275d2e2.10131c","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Neight\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":920,"wires":[[]]},{"id":"fb96a8d.fbd7358","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"outputs":1,"x":1300,"y":600,"wires":[["8b309d8e.6cd56","9a88743c.68fa38","7ff8e4b2.107fdc","bdb8bf58.43036","8e00c712.f86328","19d15ad5.eedeb5","5819a0db.4a5","8e51d29c.77794","8c189fcd.f8fcf","1cb3ca1c.f0b016","e87b8a50.8ed2a8","9aff28b6.f43488","2c477caf.7c93c4","6f5fed3f.137ccc","4bd6c460.a3a10c","859d8785.a2172","5f216baf.6787b4","f61cdd44.42f2f8","220644bf.30e02c","b86ea0b125621f58","035656429896a1c4","3662f4b64c29ef86","f00e1cecb961a7d2","9a9a0ebb49c374e4","3fda7a71ddd689cc","b0313ebc854f1a83","7eeb589679842223","7837779df3405f84","ee3f0c6c5f5b75ce"]]},{"id":"8b309d8e.6cd56","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/tempsensor1","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":640,"wires":[["14ce71ae.07c87e"]]},{"id":"9a88743c.68fa38","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/tempsensor2","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":680,"wires":[["e189b915.9ca968"]]},{"id":"bdb8bf58.43036","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/tempsensor4","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":760,"wires":[["fe0f6dc5.83424"]]},{"id":"7ff8e4b2.107fdc","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/tempsensor3","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":720,"wires":[["f94c98b3.80d0d8"]]},{"id":"14ce71ae.07c87e","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Ntemp1\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1810,"y":640,"wires":[[]]},{"id":"e189b915.9ca968","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Ntemp2\", str);\n  \n ","outputs":1,"noerr":0,"x":1810,"y":680,"wires":[[]]},{"id":"f94c98b3.80d0d8","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Ntemp3\", str);\n  \n ","outputs":1,"noerr":0,"x":1810,"y":720,"wires":[[]]},{"id":"fe0f6dc5.83424","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Ntemp4\", str);\n  \n ","outputs":1,"noerr":0,"x":1810,"y":760,"wires":[[]]},{"id":"8e00c712.f86328","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"outputs":1,"x":1980,"y":600,"wires":[["83c6afe8.0eb37","45effa91.0d3944","26ac7f51.a0509","cb20bc1a.47f41"]]},{"id":"83c6afe8.0eb37","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/level1","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":2220,"y":600,"wires":[["d6a2fc2.bfca5"]]},{"id":"45effa91.0d3944","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/level2","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":2220,"y":640,"wires":[["248fb81f.6f6b18"]]},{"id":"cb20bc1a.47f41","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/level4","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":2220,"y":720,"wires":[["23231e80.b64132"]]},{"id":"26ac7f51.a0509","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/level3","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":2220,"y":680,"wires":[["38401a24.12f1e6"]]},{"id":"d6a2fc2.bfca5","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NLevel1\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":2410,"y":600,"wires":[[]]},{"id":"248fb81f.6f6b18","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NLevel2\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2410,"y":640,"wires":[[]]},{"id":"38401a24.12f1e6","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NLevel3\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":2410,"y":680,"wires":[[]]},{"id":"23231e80.b64132","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NLevel4\", str);\n  \n ","outputs":1,"noerr":0,"x":2410,"y":720,"wires":[[]]},{"id":"20ccae05.153222","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wrelay_name1","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":850,"y":1040,"wires":[["5956311.74dbcd"]]},{"id":"da33619d.3d9d2","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wrelay_name2","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":850,"y":1080,"wires":[["f8448ec2.bf3f5"]]},{"id":"11227dd8.aa7b82","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wrelay_name3","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":850,"y":1120,"wires":[["a53afab2.319868"]]},{"id":"9c8a60af.99a87","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wrelay_name4","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":850,"y":1160,"wires":[["7cc94b6.5dd00b4"]]},{"id":"5956311.74dbcd","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NWone\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1040,"wires":[[]]},{"id":"f8448ec2.bf3f5","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NWtwo\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":1080,"wires":[[]]},{"id":"a53afab2.319868","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NWthree\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":1120,"wires":[[]]},{"id":"7cc94b6.5dd00b4","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NWfour\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":1160,"wires":[[]]},{"id":"6fa7559b.332e6c","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name10","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":850,"y":1000,"wires":[["a7b55aab.700688"]]},{"id":"d1e57b73.4b3768","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relay_name9","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":960,"wires":[["23db853c.100dfa"]]},{"id":"23db853c.100dfa","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Nnine\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":960,"wires":[[]]},{"id":"a7b55aab.700688","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"Nten\", str);\n  \n ","outputs":1,"noerr":0,"x":1100,"y":1000,"wires":[[]]},{"id":"e1afddf0.78e6","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/stdrelay","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1630,"y":340,"wires":[["fa38e293.32267"]]},{"id":"71e76301.9a03bc","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/heattempsensor","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":860,"y":400,"wires":[["23687cb9.0c9ae4"]]},{"id":"23687cb9.0c9ae4","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"heattempsensor\", str);\n  \n \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1060,"y":400,"wires":[[]]},{"id":"fa38e293.32267","type":"function","z":"1f780f8f.dbcd5","name":"hide/show relays & set globals","func":"if(msg.payload == \"true\"){\n    global.set(\"stdrelay\", true);\n    msg.payload = { \"group\": { \"show\": [\"Switches_Switches\", \"Switches_Settings_Relay_Name\"] } };\n}\nif(msg.payload == \"false\"){\n    global.set(\"stdrelay\", false);\n    msg.payload = { \"group\": { \"hide\": [\"Switches_Switches\", \"Switches_Settings_Relay_Name\"] } };\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1890,"y":340,"wires":[["21d02601345bcaa5"]]},{"id":"38596061.39c32","type":"comment","z":"1f780f8f.dbcd5","name":"build UI","info":"","x":1590,"y":180,"wires":[]},{"id":"df9f0e4b.b9826","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1360,"y":300,"wires":[["2d440d485e71d1bb"]]},{"id":"5819a0db.4a5","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelfull","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1590,"y":920,"wires":[["d623500e.d1ff"]]},{"id":"d623500e.d1ff","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n\n global.set(\"levelfull\", str);\n  \n \n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1810,"y":920,"wires":[[]]},{"id":"16700731.7ef189","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n global.set(\"levelempty\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1810,"y":1120,"wires":[[]]},{"id":"8e51d29c.77794","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelempty","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":1120,"wires":[["16700731.7ef189"]]},{"id":"6505a36d.7dd13c","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"var str = Number(msg.payload);\nglobal.set(\"hysteresis\", str);\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1810,"y":1320,"wires":[["e7f163efc71ccc07"]]},{"id":"8c189fcd.f8fcf","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/hysteresis","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1590,"y":1320,"wires":[["6505a36d.7dd13c"]]},{"id":"1cb3ca1c.f0b016","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/pekwayShuntactive","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1620,"y":1360,"wires":[["d2680bbf.1e5cb8","eb009e6dc5ee5d3d"]]},{"id":"d2680bbf.1e5cb8","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"\nif(msg.payload == \"true\") \n global.set(\"pkwshuntactive\", true);\n  else\n  global.set(\"pkwshuntactive\", false);\n  \n return msg\n ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1810,"y":1360,"wires":[[]]},{"id":"63c460c.44d7ba","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"\n\n global.set(\"pkwshunttyp\", msg.payload);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1810,"y":1420,"wires":[[]]},{"id":"e87b8a50.8ed2a8","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/pkwshunttyp","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":1420,"wires":[["63c460c.44d7ba","3c454549156f593a"]]},{"id":"9aff28b6.f43488","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelfull1","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1590,"y":960,"wires":[["6bd0e728.cf2148"]]},{"id":"6bd0e728.cf2148","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n\n global.set(\"levelfull1\", str);\n  \n \n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1810,"y":960,"wires":[[]]},{"id":"2c477caf.7c93c4","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelfull2","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1590,"y":1000,"wires":[["544f680c.b6f77"]]},{"id":"544f680c.b6f77","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n\n global.set(\"levelfull2\", str);\n  \n \n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1810,"y":1000,"wires":[[]]},{"id":"6f5fed3f.137ccc","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelfull3","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1590,"y":1040,"wires":[["1843e417.bd2e5c"]]},{"id":"1843e417.bd2e5c","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n\n global.set(\"levelfull3\", str);\n  \n \n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1810,"y":1040,"wires":[[]]},{"id":"4bd6c460.a3a10c","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelfull4","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1590,"y":1080,"wires":[["3ddec7d5.8514b8"]]},{"id":"3ddec7d5.8514b8","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n\n global.set(\"levelfull4\", str);\n  \n \n","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1810,"y":1080,"wires":[[]]},{"id":"377c7c5.1f00e04","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n global.set(\"levelempty1\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1810,"y":1160,"wires":[[]]},{"id":"859d8785.a2172","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelempty1","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":1160,"wires":[["377c7c5.1f00e04"]]},{"id":"97f13303.a31568","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n global.set(\"levelempty2\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1810,"y":1200,"wires":[[]]},{"id":"5f216baf.6787b4","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelempty2","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":1200,"wires":[["97f13303.a31568"]]},{"id":"47e250fc.aff328","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n global.set(\"levelempty3\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1810,"y":1240,"wires":[[]]},{"id":"f61cdd44.42f2f8","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelempty3","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":1240,"wires":[["47e250fc.aff328"]]},{"id":"93b88d8c.0bded8","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = Number(msg.payload);\n\n global.set(\"levelempty4\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1810,"y":1280,"wires":[[]]},{"id":"220644bf.30e02c","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/levelempty4","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":1280,"wires":[["93b88d8c.0bded8"]]},{"id":"01052110d8b72b04","type":"comment","z":"1f780f8f.dbcd5","name":"Pekaway Control v1.1.2 changelog","info":"# Update 1.1.2 (21 November 2023)\n- changed wifi firmware to firmware-brcm80211_20190114-1+rpt4_all.deb to increase stability when bluetooth is used\n- changed the delay that checks the second NR instance from 10s to 15s\n- added a function to switch between wifis and delete configured wifis (does not work in access point mode!)\n- added a function that shows the connected SSID when checking IP-address\n- added a function that checks if the configured wifi access point passphrase is between 8 and 63 characters\n- added http endpoint /reset_wifiAP/true to reset the access point\n- added http endpoint /network to show network info\n- added http endpoint /update_wifi_ap/:ssid/:wpa to update the wifi access point\n- added http endpoint /activate_wifi_ap/:input (:input has to be true or false) to de-/activate the wifi access point\n- added a sleep 1s function to the NonAPtoAP.sh script to compare old/new access point mode status (active/inactive, used in http endpoint /activate_wifi_ap)\n- added the possibility to use hidden networks when inserting wifi data manually\n- added a funtion that initialises the dropdown value for Main battdata\n- added a function to show the van name in the title bar\n- changed the charts in the Monitor tab for better visibility:\n    > chart titles always show current values accordingly\n    > temp charts now draw one point for every 15 incoming values (mean value)\n    > SoC chart now draws one point for every 5 incoming values (lowest value seen)\n    > Volt chart now draws one point for every 3 incoming values (mean value)\n    > Amp chart now draws one point for every 3 incoming values (mean value)\n    > CPU usage chart now draws one point for every 3 incoming values (highest value seen)\n    > TTGO field now shows the mean value for every 5 incoming values and minutes are rounded to the nearest quarter hour (15min)\n- removed dimmer 8 from the switch schedulers (Dimmy supports only 7 dimmer channels)\n- changed appendix for wifi SSID from \"_VanPI\" to \"_pekaway.com\"\n- rewrote the relay controller to only switch relays on actual change instead of constant updating\n- added a sleep timer in loops of python ads script to reduce CPU usage\n- added the option to show ttgo on the info tab (see Config > System)\n- switched groups RPI and BLE in System Config\n- added a function that shows overall CPU usage since boot in Monitor tab\n- fixed the tempsensor function not showing doubledigit numbers when temperature is below zero\n- fixed the default baudrate not being 115200 for MaxxFan UART\n- added a function to use a variable baudrate on USB4 (will reset on reboot)\n- fixed the function that hides Dimmers & W-Relays on first boot\n- added a function to controll dimmers via the MCP inputs\n- added offsets to all 4 temp and 2 dimmytemp sensors, so that displayed temps can be adjusted individually\n- added a function thats asks to turn everything off before shutting down (relays, w-relays & dimmers)\n- added a function to control a boiler with a relay and DS18B20 tempsensor\n- changed all groups in the frontend to now be collapsible\n- changed the update functions to use https://github.com/Pekaway/VAN_PI as server instead of git.pekaway.de\n- added a function that shows the state of the update process\n- added new HTTP and MQTT endpoints to set autoterm specific heatingpower and ventilation\n- deactivated automatic search for BMS (too many errors)\n- added support for SuperVolt & FlyBat Batteries (BLE)\n- fixed BLE scan function, was sometimes showing results as buffer instead of string\n- added .bin files to be flashed to ESP devices for dimmy (now supports ESP8266 & ESP32, Dimmy for VANPI & Standalone)\n\n\n# Update 1.1.1 (05 May 2023)\n- fixed mcp inputs not being displayed correctly\n- fixed water level 1 error which kept it from taking other values than 0\n- fixed error which prevented \"main battdata\" to be initialised on boot\n- changed sampling frequency of PCA9685 to 200 (dimmer section)\n- changed http request nodes in Pekaway Shunt flow to use 127.0.0.1 instead of localhost\n- added function to start a second Node-RED instance, using a backup flows file\n- added a timezone picker in Frontend (Config > System)\n- added function that displays the system time in the info tab & altered format of system time in frontend (Config)\n\n# Update 1.1.0 (31 Mar 2023) >> changes mentioned here also include BETA updates for this version!\n- added a precompiled .tft file (VanPI_NSPANEL.tft) for the Sonoff NS Panel to ~/pekaway together with the berry driver (autoexec.be), which is needed for the flashing process\n    > quickstart NSPanel:\n        > install Tasmota via https://tasmota.github.io/install/ (choose \"Tasmota32 Sonoff-NSPanel(englisch)\" to be flashed)\n        > connect the panel to the wifi accesspoint of your RPI\n        > use configs as described here: https://docs.nspanel.pky.eu/prepare_nspanel/\n        > set MQTT-Broker to \"pekaway.local\" and topic to \"WifiTouch\" (case sensitive)\n        > go back to the console in tasmota and type:\n            > \"Backlog UrlFetch http://pekaway.local/autoexec.be; Restart 1\" -> downloads the driver from the local filestorage via nginx\n            > \"FlashNextion http://pekaway.local/nspaneltft\" -> flashes the precompiled .tft file\n    > a new flow \"Wifi TOUCHPANEL\" has been added to Node-RED, which also includes examples for the two hardware buttons on the panel\n    > added a function to upload your own .tft file to the raspberry (Config > System > System Update > NS Panel)\n    > added functions to install the berry driver and flash the .tft file (Config > System System Update > NS Panel)\n- added code to the nginx server block to make the berry driver and the .tft file accessible via http\n- added check for i2c devices in dimmer flow to prevent showing error messages if Dimmy is not hardwired\n    > messages to PCA9865-Node are limited to 10msg/s (1msg every 0.1s)\n- added slider to set max_pwm in % as overvoltage protection (config > switches > dimmer section)\n- added dimmytemp sensor data to http endpoint /temp (only when set to active in config)\n- reworked the function that generates the default wifi ssid to be a bit more randomized\n- reworked the function to reset the wifi to use the same process that generates the default wifi ssid\n- reworked the update function \n    > it will now download a script from the Pekaway servers and execute to keep it seperated from Node-RED\n    > the script can be found at git.pekaway.de\n- fixed error that sometimes displayed ble-bms info in textfield for \"currently set battery\" (config)\n- fixed error with libevdev2:armhf package\n______________________________________________________________________________________________________________\n# Update 1.1.0 BETA2 (09 Feb 2023)\n- added functions to control MaxxAir MaxxFan via IR-Transmitter in combination with ESP device\n    > Arduino code still needs to be finalized and published\n- disabled all LFBros functions systemwide and purged WiringPi to make UART-Port available\n- disabled \"gpio readall\" function from debug tab\n- disabled Dimmer 8 (Dimmy board has only 7 channels available)\n- added \"dimmytemp1/2\" to be set as option for inside temp sensor (2 DS18B20 sensors can be connected to the Dimmy board and will sent their data via MQTT)\n- added a PCA9865 node to the dimmer section >> Dimmy can now be connected hardwired without the need for an extra Microcontroller (Wemos)\n    > if you want to, you can disable the mqtt outputs for the dimmers and set the slider to send data continously instead of \"only on release\"\n- added function to insert SSID for existing Wifi manually\n- fixed errors in ~/ble_py/goksens4s.py (was only showing initial values before)\n- fixed function to initialise GokSenso4S on startup\n- disabled update via USB function in frontend (was leading to errors in some cases)\n- added function to turn off BLE Bat/BMS if not reachable\n    > will turn off after 6 failed attempts, then try again after 1 hour (can be turned on again by setting the MAC-adress in the config settings)\n    > info: if BLE cannot establish a connection, it will kick out Wifi-clients and block new wifi connections as long as the BLE-requests is running\n- prepared flows to use a custom cloud mqtt server (see the flow \"MQTT API\" at the bottom) \n- added Autoterm 4D to the list of supported heaters (not all status info is delivered via the protocol though)\n- added a one-time runtimer to the heater controls >> Start the heater, set the timer, heater will stop when time is over\n- changed some settings in the \"Chinese Diesel Heater\" flow, it now works properly with both types of USB-connectors\n- reworked display communication to reduce bandwith\n- new beta file for touchdisplay (1.0.3B) is also available\n\n#    new packages/installations\n    - node-red-contrib-PCA9865\n    - node-red-contrib-countdown-2\n______________________________________________________________________________________________________________\n# Update 1.1.0 BETA (02 Dec 2022)\n- Updated Node-RED core to latest version v3.0.2\n > NOTICE: Node-RED hast to be updated manually (\"bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)\") when using the update function!\n- updated npm packages for Node-RED to latest versions\n- updated rpi packages to latest versions (\"sudo apt upgrade\")\n- added link in update checker to read full changelog\n- set global variable BatteryDataDelivery to empty (\"\") on first boot\n- added some logic to improve the function that rebuilds the UI\n- slightly altered notification message when MainBattData is set to \"off\"\n- fixed error when searching for bluetooth battery (liontron/JBD) automatically (the found battery will now also be set automatically)\n- added functions to switch relays when using MCP input to have an option to add hardwired buttons/switches to the board\n- changed title \"WasserLevel Names\" to \"Water Level Names\"\n- reworked system time in toolbar to show client time instead of system time (JS function that executes on the client browser)\n- changed request interval for bluetooth scale from 20 seconds to 180 minutes so that the scale's battery will not be drained that heavily\n- added function to convert the data from gok-senso4s from hexadecimal to decimal\n- created HTTP endpoint to set the system time (preparation for IoT-bridge update)\n- created HTTP endpoint to turn everything off (relays, w-relays, dimmers)\n > added UI button to turn everything off in Switches Settings\n > added function to save current state before turning everything off in preparation for function to turn everything back on in last known state\n > added MQTT topic to turn everything off\n- added switch to enable/disable Zigbee2MQTT\n- added button to reach Zigbee2MQTT dashboard directly from NR-Frontend (Wifi Config)\n- Zigbee2MQTT dashboard is available on port 8099 (Zigbee2mQTT service will fail to start if no coordinator is connected! It will try to restart every 10s, check the systemd.service for details)\n- the auto turn off function in Switch Scheduler/Timer tab now shows the values of the gobal variables as names, instead of \"Relay 1, Relay 2...\"\"\n- dimmer names now default to \"Dimmer 1, Dimmer 2, etc.\" if names are left empty in frontend\n- deactivated USB-update function\n- added endpoints to get software version in http/mqtt\n- changed monitor chart ranges for temperatures from 6h to 10h\n- updated Homebridge to version 1.6.0, updated plugins to latest versions\n- fixed error that stopped the update function from working\n- fixed error on wifi-relays and homebridge (when firmware is set to shelly, then hb was not notified when w-relay is switched in NR frontend)\n- fixed error that last temperature value was kept after sensor was removed, value is now set to \"\" after removing the sensor\n- changed global variable \"version\" to \"currentVersion\"\n- added two more temperature sensors to be used with the Dimmy board. They can be activated and named in Config -> Sensors tab\n > check flow \"Temperature/DS18B20\" in Node-RED Backend for details\n- error generating new hostkeys on firstboot may appear in v1.0.4 -> fixed by adding a button (\"Generate new SSH hostkey\") to Config -> Debug -> RPI general information\n- disabled swapping system-wide and deleted swapfile /var/swap\n- added function to save install date of current version to file and retrieve when checking for updates\n\n#    new packages/installations\n    - node-red-node-ui-list\n    - node-red-contrib-zigbee2mqtt\n    - zigbee2mqtt (https://www.zigbee2mqtt.io/guide/installation/01_linux.html)\n______________________________________________________________________________________________________________\n# Update 1.0.4 (07 Sep 2022)\n- added callback query when resetting water level calibration\n- fixed function \"searching for backup files\" when folder is empty\n- reworked upload/download UserData functions\n- fixed function for relays \"autoturnoff\" to work properly after rebooting (delay restarts at time of boot)\n- fixed relay tabs showing up properly when deploying while Switches tab is in focus\n- fixed function sending MQTT stats every 5min (Wifi-Config -> \"Send stats via MQTT\")\n______________________________________________________________________________________________________________\n# Update 1.0.3\n- fixed monitoring waterlevels to not show more than 100%\n- changed touchdisplay switch (page) from number to string\n- reworked building of UI to be more stable\n- changed temp2 global variable to be stored as string (fixed to be shown in mobile app, was integer before)\n- added global variables to show BMSmax/min data in mobile app from JBD BL/UART BMS\n- JBD BMS is now available for usage on all 4 USB ports\n- fixed JBD BMS settings (UART)\n- fixed JBD BMS calculations for USB and BL connections\n- changed Daly BMS flow to show capacity in ampere hours\n- added function to generate a new ssh host key on first boot\n- added function to clear bash history when generating new image\n- added function to clear system volume information when generating new image\n- added function to show/hide system time in the toolbar\n- changed uptime function for better visibility in monitor tab\n- deactivated function that updates relay/wifi-relay labels every 3min\n- reworked functions that update switches labels in frontend (update happens when changing to switches tab)\n- switches labels now return to default value when names are deleted (instead of showing nothing)\n- added function to automatically turn off respective switches after a custom set time\n- added schedulers for relays, wifi-relays and dimmers (automatically turn on/off at given times) -> remember to set system time properly or synchronize it automatically (internet access needed)\n    - for dimmer events use true/false for fully on/off, or set a value from 0 to 100\n- prepared \"autooff\" variable in HTTP endpoints (not yet in use, will be used when code for IoT-bridge is updated)\n- prepared new HTTP endpoint \"relayiot\" to be used in futere IoT-bridge code update\n- added usability off payloads \"true\"/\"false\" to be used when switching states of relays/w-relays/dimmers via MQTT\n- fixed PIN numbers in \"/home/pi/pekaway/433Utils/RPi_utils/codesend.cpp\" (line 27) to PIN 4 and \"/home/pi/pekaway/433Utils/RPi_utils/RFSniffer.cpp\" (line 26) to PIN 3 for 433MHz sender/receiver to work with VANPI Relayboard\n______________________________________________________________________________________________________________\n# Update 1.0.2\n- changed relative paths to absolute paths in ~/pekaway/ads_py/web1.py to resolve issues with database\n- created files \"ohm1empty\" & \"ohm1full\" (up to #4) to fix error when calibrating water tank sensors\n- added function to write ohm data before using the adjustment slider\n- changed function to hide/show bms info to fix error when updating UI\n______________________________________________________________________________________________________________\n# Update 1.0.1\n- downgraded OS back to Debian 10 Buster due to problems with ADS packages\n- changed user back to pi to simplify filepaths\n- changed DHCP range to 192.168.4.2-192.168.4.50\n- added van.pi to dnsmasq.conf\n- installed bottle webserver (python) as user pi\n- fixed paths in wifi-scripts (to be used via NR frontend)\n- changed ads_py script to use relative paths\n- renamed button \"Relays\" to \"Switches\" in config menu\n- fixed udev rules (usb connection status)\n- minor bugfixes\n______________________________________________________________________________________________________________\n# Major Update 1.0.0\n- updated OS to Debian 11 Bullseye\n- updated Node-Red to version 2.2.2\n- removed function to auto rebuilt  UI when changing to info tab\n- added function to rebuilt UI when changing to config tab\n- added query for bluetooth battery to built UI accordingly\n- fixed battery (bluetooth) function to correctly show/hide bms info\n- added function to automatically update relay names when entering tabs (debug, heater, settings, switches)\n- changed absolute paths to relative paths in .sh files\n- changed monitor timestamp interval to 60s for waterlevels and 30s for rpi usage\n- added bms info to HTTP API and MQTT API\n- added reboot function to HTTP API\n- added topic 'conniot' to HTTP API for IoT Bridge\n- added topic 'wrelayiot' to HTTP API for IoT Bridge (same as 'wrelay' but without firmware info)\n- optimized dimmer label functions\n- optimized wrelay I/O for touchdisplay\n- added option to reset bluetooth devices\n- removed DS18B20 node and added DS18B20.py instead\n______________________________________________________________________________________________________________\n# Update 0.9.1\n- bug fixes from v0.9.0\n- change Temperature node\n- DALY MONIT Issuse solved\n- name PKW Shunt to VANPI SHUNT\n\n# Update 0.9.0 \n- Display Version 0.6b - improved communication\n- Heater hysteresis is working\n- added reset waterlevel calibration\n- fixed cell voltage for daly\n- changed Victron name in the UART menus to \"Ve.Direct\"\n- added wemos d1 flasher\n- added names api\n- added flows to rebuild ui when opening tabs\n- seperated config into tabs for better overview\n- rearranged all nodes in all flows for better backend overview\n- source folder for pekaway data changed to /home/pi/pekaway\n- seperated init_flow >> init_flow and connections (USB/UART connections)\n- added new global variables \"MainBattAmps\", \"MainBattVolts\" & \"MainBattSoc\", battery values from all source destinations will be copied into these variables\n- added new option to set battery stats in the config (frontend) for \"MainBattDelivery\" - HAS TO BE SET!!\n- Display flow is now seperated into two flows for better overview\n- Dimmer Controller for Mosfetboard (to be released soon -> 7 mosfets for dimmable lights etc.)\n- integrated flasher mode to easily flash Wemos D1 directly from the Pi\n- integrated JDB/GENERIC BMS to be used with the system\n- new \"ConnectedRelay\" variable for turning heater on/off via relay (including hysteresis check)\n- added LFBros Heater (433Mhz remote control), 433Mhz receiver and sender for raspberry needed! installed WiringPi for realisation\n- included HTTP API to toggle relays get information about the system, rename names, set heater etc.\n- included MQTT API to toggle relays get information about the system, rename names, set heater etc.\n- changed the timing interval for monitor tab from 20s to 25s and less datapoints in charts (from 1000 to 600)\n- added a new flow BLE Connections to connect BLE devices, currently supported: LIONTRON/JBD bluetooth Battery, GOK Senso4s Bluetooth scale\n- added options in config to set dimmer names, added a debug option for Mosfetboard to show connection and MQTT stats\n- added toggable function to send all stats via MQTT every 5min\n- added template controls to open desired tabs when pressing buttons (menu navigation) leading to better overview\n- added a debug tab with several functions to get information about the system and the Raspberry Pi itself\n- update function is now capable of installing new packages via apt-get/apt and npm (lists are publicly available at git.pekaway.de, please make sure to read through them before using any download automations)\n- wifi relays do now support tasmota and shelly\n- the protocol used for the touchdisplay has been changed to run more smoothly and stable, already set names have to be set again as they will show weird stuff when upgrading from the old version\n- touchdisplay v0.6b only compatible with RPI-Image v0.9.0 BETA and above!!\n- buttons and waterlevels that are not being used can be disabled on the touchdisplay\n- Votronic tank sensors can be calibrated directly (up to 2.4V max!)\n- Water tank calibrations can be resetted\n- serial USB connections are fixed via a new set of udev rules\n\n# Update 0.8.0\n- added package esptool\n\tnew package \"esptool\" can be installed with `sudo apt-get install esptool`\n- added ESP32&ESP8266 Tasmota Mosfet bins to disk\n- added Flashermode to Node-Red -> enables flashing of ESP32/ESP8266 directly on the pi with the tasmota bins to control the mosfetboard (upcoming)\n- added a \"restart web1.py after crash\" function\n- added flow Dimmer Controller (controls dimmers in dashboard and Homebridge)\n- added dimmer logic in config flow (hide/show dimmers and debug mode)\n- added watchdog for mosfetboard (ESP32/8266)\n- added Homebridge support for dimmers\n- updated Homebridge to v1.4.0\n- added npm install node-red-contrib-mcp23017chip\n- added bmv 712 victron pid\n- added pekaway display 2 -> add slider to display\n- added jbd/generic BMS (basic)\n- added LionTron Battery Bluetooth\n- remove new version from PID Controll Autoterm\n- add connection flow for all serial/bluetooth connections\n- add rules for portbinding serialconnections\n- remove usb serial swap \n- \n\n# Update 0.7.4\n- improved PID Controll Autoterm\n- added \"check for update\" button in update flow to check if an update is available\n- hotfix for the Wifi scan problem from v0.7.3\n\n\n# Update 0.7.3\n- added PID Controller npm install node-red-contrib-pid-controller\n\tNew npm module needed! Use `cd .node-red && npm install node-red-contrib-pid-controller`\n- PID Heatcontroller Autoterm\n- added backup and restore userData\n\tnew packages \"zip\" & \"unzip\" are required! Use `sudo apt-get install zip unzip` to install them\n- added Nest-style heattemperature-Widget\n\n\n# Update 0.7.2\n - add pekawaydisplay UserData Flow\n - improve DisplaySettings -> show ips\n - new display version 0.4\n\n\n\n# Update 0.7.1\n - update tab fix\n - autoterm temperaturemode added\n\n\n# Update 0.7.0\n- webasto flow improvements \n- autoterm improvements\n- SET PARITY WEBASTO not fixed\n- display switch error fix\n\n\n# Update 0.6.9\n- added homebridge reset function\n- fixed voltage calibration function\n\n# Update 0.6.8\n- calbriate voltfactor function\n- integrated update notification\n- remove redbot and telegram flow (flow to be found on gitlab )\n- added MQTT Broker to switch relays via Tasmota/Apple Home\n- added homebridge support to use Apple Home via MQTT (homebridge running on port 8581 with login admin:pekawayfetzt)\n- added function to resize filesystem in config (if SD-card not using full size for some reason)\n- added rpi monitoring to the monitor tab\n- added button to show ip-adress of both, wlan0 and eth0\n\n\nimage 0.6.7\n- added possibilities to update the flows with USB-device and/or with internet connection (via curl git.pekaway.de/...)\n- added option to create backups manually\n- added option to delete existing backups to save space\n- added a function to load existing backups\n- added delay before restarting hostapd and dnsmasq when switching between Access Point modes\n- change Heater flow - each heater has now one flow\n- relayorder issue solved\n- usb swap detection \n\n\nimage 0.6.6\n\n- add watchdog to shunt script\n- increase voltage reading\n- add custom batterySize (watthours)\n- load shunt config after start\n- add Monitor Tab for Battery and Temperatur\n- reload old relay status after reboot\n- remove network time snyc -> time from display or realtime clock \n      ->sudo systemctl stop systemd-timesyncd\n      ->sudo systemctl disable systemd-timesyncd\n- add telegram bot flow\n\n\nimage 0.6.5\n\n- adjusted timezone to CEST/Berlin\n- solved issue with custom wifi connection not working because of double quotation marks\n- removed duplicate textfield of version info in config tab\n- changed slider to set state of charge to dropdown menu\n- changed methods to calibrate water sensors to have better feedback visibility (pop-up) on smaller displays\n\n\nimage 0.6.4\n\n- ADS1115 gain change -> Votronic Sensor\n- Level2 issue solved\n- VersionInfo -> config\n\n\nimage 0.6.3\n\n### Major Changes ###\n- updated Node-Red to v2.0.6\n- updated dashboard to v3.0.4\n- added template node to generate stylesheet for the dashboard\n- added control for autoterm heater\n\n### Minor Changes ###\n- changed width of battery widget to 6\n- cleaned flow 'VE.Direct' in backend\n- access point name will now include parts (3 chars) of the RPI's hardware serial, so AP-names will be  unique\n--> AP-name is set on first boot only\n- unchecked 'send to all browser sessions' on all notification nodes\n- added a version number with changelog to the 'init' flow\n- changed baudrate on china heater to 9600\n- added favicon for dashboard\n- changed a line of text in index.html (appears when the dashboard is loading)\n- added connection status of USB ports to dashboard config","x":160,"y":40,"wires":[]},{"id":"eb009e6dc5ee5d3d","type":"link out","z":"1f780f8f.dbcd5","name":"loadconfig_shunt","links":["b09f2cdaf0ee0dad"],"x":1769,"y":1392,"wires":[]},{"id":"3c454549156f593a","type":"link out","z":"1f780f8f.dbcd5","name":"loadconfig_shunttype","links":["e28fa7093a1bacde"],"x":1769,"y":1452,"wires":[]},{"id":"bbb4f216c9f2bdc0","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/relaystatusload","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":860,"y":440,"wires":[["cc347c1fbe034eec"]]},{"id":"cb58f8fd7638bcad","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"200","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":560,"y":440,"wires":[["bbb4f216c9f2bdc0","e5c2f0cbb66d6012"]]},{"id":"9852ba41c78b50e7","type":"function","z":"1f780f8f.dbcd5","name":"set globals","func":"\nglobal.set(\"one\", msg.payload.one);\nglobal.set(\"two\", msg.payload.two);\nglobal.set(\"three\", msg.payload.three);\nglobal.set(\"four\", msg.payload.four);\nglobal.set(\"five\", msg.payload.five);\nglobal.set(\"six\", msg.payload.six);\nglobal.set(\"seven\", msg.payload.seven);\nglobal.set(\"eight\", msg.payload.eight);\nglobal.set(\"nine\", msg.payload.nine);\nglobal.set(\"ten\", msg.payload.ten);","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1210,"y":440,"wires":[[]]},{"id":"cc347c1fbe034eec","type":"json","z":"1f780f8f.dbcd5","name":"","property":"payload","action":"","pretty":false,"x":1050,"y":440,"wires":[["9852ba41c78b50e7"]]},{"id":"b86ea0b125621f58","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/shuntcalibrate","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1610,"y":1480,"wires":[["ac3802fca739de4e"]]},{"id":"ac3802fca739de4e","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"shuntcalibrate\",parseFloat(msg.payload)); ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1814,"y":1480,"wires":[[]]},{"id":"4116525141cf4e0c","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/update","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":740,"y":60,"wires":[["3d2e48e57ecaef28"]]},{"id":"73133552bf558250","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":540,"y":60,"wires":[["4116525141cf4e0c","1ba3c6dea8b0a688"]]},{"id":"3d2e48e57ecaef28","type":"function","z":"1f780f8f.dbcd5","name":"get update","func":"msg.payload = msg.payload.trim()\nif(msg.payload == \"1\")\n{\n    msg.payload = \"Welcome to \" + global.get(\"currentVersion\") +\"!\";\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":922,"y":59,"wires":[["5dc2da41dbe73329","39b5a752a2e9a352","9e4bf54088d5fb75"]]},{"id":"f20ab50e68e5fcca","type":"file","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/update","filenameType":"str","appendNewline":false,"createDir":true,"overwriteFile":"true","encoding":"none","x":1140,"y":100,"wires":[[]]},{"id":"5dc2da41dbe73329","type":"ui_toast","z":"1f780f8f.dbcd5","position":"dialog","displayTime":"3","highlight":"","sendall":false,"outputs":1,"ok":"OK","cancel":"","raw":false,"className":"","topic":"","name":"","x":1130,"y":60,"wires":[[]]},{"id":"39b5a752a2e9a352","type":"function","z":"1f780f8f.dbcd5","name":"set update","func":"msg.payload = \"0\";\nvar date = new Date().toLocaleString()\nglobal.set(\"installdate\", date)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":920,"y":100,"wires":[["f20ab50e68e5fcca","eedd3d20cd755a80"]]},{"id":"fab97a324452bd5c","type":"comment","z":"1f780f8f.dbcd5","name":"show update info","info":"","x":540,"y":20,"wires":[]},{"id":"e4ca4d64a82b0cea","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/version","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":830,"y":1380,"wires":[["ed4a9e392e2f8b61"]]},{"id":"ed4a9e392e2f8b61","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"var str = msg.payload.trim();\nglobal.set(\"currentVersion\", str);\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1380,"wires":[["5741e6776c25282c"]]},{"id":"137dc61d3bb3ac88","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wrelay_name5","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":851,"y":1211,"wires":[["570cffdb99b158ae"]]},{"id":"fdf2f349a4240f48","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wrelay_name6","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":851,"y":1251,"wires":[["0b84b35d019401ea"]]},{"id":"15c2f2cd8f954356","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wrelay_name7","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":851,"y":1291,"wires":[["fb92fca3b8c3ce59"]]},{"id":"5d3d4dc1100a682d","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wrelay_name8","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":850,"y":1340,"wires":[["5794b81b612420cb"]]},{"id":"570cffdb99b158ae","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NWfive\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1101,"y":1211,"wires":[[]]},{"id":"0b84b35d019401ea","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NWsix\", str);\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1101,"y":1251,"wires":[[]]},{"id":"fb92fca3b8c3ce59","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NWseven\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1101,"y":1291,"wires":[[]]},{"id":"5794b81b612420cb","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"NWeight\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1340,"wires":[[]]},{"id":"29969bdc2439facd","type":"inject","z":"1f780f8f.dbcd5","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"10","topic":"","payload":"","payloadType":"date","x":210,"y":1860,"wires":[["1c055936a2e014f3","8281f5e3445976ed","d8bae22f106f42ee","3e22301fc280edae","0b0bf2f8411ab2d9","a3e2be16c098d54b","9bf6cd1f5e6db3b4","f7df9191a870e9ac"]]},{"id":"1c055936a2e014f3","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmer0","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":420,"y":1740,"wires":[["ac0f7957fe6cc9e4"]]},{"id":"8281f5e3445976ed","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmer1","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":420,"y":1780,"wires":[["9ef973f2cfd5a2ac"]]},{"id":"d8bae22f106f42ee","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmer2","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":420,"y":1820,"wires":[["0d13cbbba95009dc"]]},{"id":"3e22301fc280edae","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmer3","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":420,"y":1860,"wires":[["2bc92131e105b3d8"]]},{"id":"0b0bf2f8411ab2d9","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmer4","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":420,"y":1900,"wires":[["f134938ea464ea31"]]},{"id":"a3e2be16c098d54b","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmer5","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":420,"y":1940,"wires":[["4a466d477623ab89"]]},{"id":"9bf6cd1f5e6db3b4","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmer6","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":420,"y":1980,"wires":[["0cb19945b6676572"]]},{"id":"f7df9191a870e9ac","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmer7","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":420,"y":2020,"wires":[["f9a49e26f32fa4d9"]]},{"id":"ac0f7957fe6cc9e4","type":"function","z":"1f780f8f.dbcd5","name":"set state","func":"global.set(\"dimmer0\", msg.payload.trim());\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":1740,"wires":[["3bef611ac27c4ed4"]]},{"id":"9ef973f2cfd5a2ac","type":"function","z":"1f780f8f.dbcd5","name":"set state","func":"global.set(\"dimmer1\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":1780,"wires":[["5e23f61d43b8c56a"]]},{"id":"0d13cbbba95009dc","type":"function","z":"1f780f8f.dbcd5","name":"set state","func":"global.set(\"dimmer2\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":1820,"wires":[["cb72631b3282606a"]]},{"id":"2bc92131e105b3d8","type":"function","z":"1f780f8f.dbcd5","name":"set state","func":"global.set(\"dimmer3\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":1860,"wires":[["fe0bbd93a9ece46a"]]},{"id":"f134938ea464ea31","type":"function","z":"1f780f8f.dbcd5","name":"set state","func":"global.set(\"dimmer4\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":1900,"wires":[["19755d460a1db476"]]},{"id":"4a466d477623ab89","type":"function","z":"1f780f8f.dbcd5","name":"set state","func":"global.set(\"dimmer5\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":1940,"wires":[["c5d24e06df20609e"]]},{"id":"0cb19945b6676572","type":"function","z":"1f780f8f.dbcd5","name":"set state","func":"global.set(\"dimmer6\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":1980,"wires":[["84f7287a1ce17812"]]},{"id":"f9a49e26f32fa4d9","type":"function","z":"1f780f8f.dbcd5","name":"set state","func":"global.set(\"dimmer7\", Number(msg.payload.trim()));\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":600,"y":2020,"wires":[["c97946cee763f094"]]},{"id":"0c595208ab3e7738","type":"comment","z":"1f780f8f.dbcd5","name":"set global variables for dimmer values and names on boot","info":"","x":570,"y":1700,"wires":[]},{"id":"3bef611ac27c4ed4","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/Ndimmer0","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":780,"y":1740,"wires":[["439f988a62781d9b"]]},{"id":"5e23f61d43b8c56a","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/Ndimmer1","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":780,"y":1780,"wires":[["27e88c5f1b4f7b8f"]]},{"id":"cb72631b3282606a","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/Ndimmer2","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":780,"y":1820,"wires":[["6ee1990c7bc23253"]]},{"id":"fe0bbd93a9ece46a","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/Ndimmer3","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":780,"y":1860,"wires":[["0e8d5edd11fb430a"]]},{"id":"19755d460a1db476","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/Ndimmer4","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":780,"y":1900,"wires":[["beed325372b08af7"]]},{"id":"c5d24e06df20609e","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/Ndimmer5","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":780,"y":1940,"wires":[["c5c0659bee5a566e"]]},{"id":"84f7287a1ce17812","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/Ndimmer6","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":780,"y":1980,"wires":[["12ebe1bb933fe94a"]]},{"id":"c97946cee763f094","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/Ndimmer7","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":780,"y":2020,"wires":[["31741cc9faf9c7cc"]]},{"id":"439f988a62781d9b","type":"function","z":"1f780f8f.dbcd5","name":"set label","func":"if (msg.payload == \"\") {\n    msg.payload = \"Dimmer 1\"\n}\nmsg.updatelabel = true\nglobal.set(\"Ndimmer0\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":1740,"wires":[["8162b2e36e019a1e"]]},{"id":"27e88c5f1b4f7b8f","type":"function","z":"1f780f8f.dbcd5","name":"set label","func":"if (msg.payload == \"\") {\n    msg.payload = \"Dimmer 2\"\n}\nmsg.updatelabel = true\nglobal.set(\"Ndimmer1\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":1780,"wires":[["976581f8be965e6a"]]},{"id":"6ee1990c7bc23253","type":"function","z":"1f780f8f.dbcd5","name":"set label","func":"if (msg.payload == \"\") {\n    msg.payload = \"Dimmer 3\"\n}\nmsg.updatelabel = true\nglobal.set(\"Ndimmer2\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":1820,"wires":[["166539673334fc31"]]},{"id":"0e8d5edd11fb430a","type":"function","z":"1f780f8f.dbcd5","name":"set label","func":"if (msg.payload == \"\") {\n    msg.payload = \"Dimmer 4\"\n}\nmsg.updatelabel = true\nglobal.set(\"Ndimmer3\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":1860,"wires":[["ada5534e827912c9"]]},{"id":"beed325372b08af7","type":"function","z":"1f780f8f.dbcd5","name":"set label","func":"if (msg.payload == \"\") {\n    msg.payload = \"Dimmer 5\"\n}\nmsg.updatelabel = true\nglobal.set(\"Ndimmer4\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":1900,"wires":[["11f2bc5db5792cae"]]},{"id":"c5c0659bee5a566e","type":"function","z":"1f780f8f.dbcd5","name":"set label","func":"if (msg.payload == \"\") {\n    msg.payload = \"Dimmer 6\"\n}\nmsg.updatelabel = true\nglobal.set(\"Ndimmer5\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":1940,"wires":[["18220fbc9894788e"]]},{"id":"12ebe1bb933fe94a","type":"function","z":"1f780f8f.dbcd5","name":"set label","func":"if (msg.payload == \"\") {\n    msg.payload = \"Dimmer 7\"\n}\nmsg.updatelabel = true\nglobal.set(\"Ndimmer6\", msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":1980,"wires":[["223ffefbbe8f3d72"]]},{"id":"31741cc9faf9c7cc","type":"function","z":"1f780f8f.dbcd5","name":"set label","func":"if (msg.payload == \"\") {\n    msg.payload = \"Dimmer 8\"\n}\nmsg.updatelabel = true\nglobal.set(\"Ndimmer7\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":960,"y":2020,"wires":[["3325ea1d31b73cc9"]]},{"id":"ee271eb64628fc0a","type":"link out","z":"1f780f8f.dbcd5","name":"dimmer0 value/name","links":["ee045ba769a41128"],"x":1345,"y":1740,"wires":[]},{"id":"c6b55fd009e69ef0","type":"link out","z":"1f780f8f.dbcd5","name":"dimmer1 value/name","links":["7916894a389bbd36"],"x":1347,"y":1780,"wires":[]},{"id":"325d9614f6237827","type":"link out","z":"1f780f8f.dbcd5","name":"dimmer2 value/name","links":["7fcbf6231d98df8e"],"x":1345,"y":1820,"wires":[]},{"id":"31f94e298e95c2b4","type":"link out","z":"1f780f8f.dbcd5","name":"dimmer3 value/name","links":["264c1e36b77d07f6"],"x":1345,"y":1860,"wires":[]},{"id":"9d8da021cba66085","type":"link out","z":"1f780f8f.dbcd5","name":"dimmer4 value/name","links":["d2e1bd3b20beb5d3"],"x":1345,"y":1900,"wires":[]},{"id":"3b589471ad93efe2","type":"link out","z":"1f780f8f.dbcd5","name":"dimmer5 value/name","links":["1ec7e2b03700d11d"],"x":1345,"y":1940,"wires":[]},{"id":"6ce111f8c4860e01","type":"link out","z":"1f780f8f.dbcd5","name":"dimmer6 value/name","links":["344ccfe7251b8276"],"x":1345,"y":1980,"wires":[]},{"id":"fa4a585a780c2772","type":"link out","z":"1f780f8f.dbcd5","name":"dimmer7 value/name","links":["d8546b510132caa3"],"x":1345,"y":2020,"wires":[]},{"id":"0fc45db90a975e40","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/MACbtbat","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":830,"y":1420,"wires":[["3cad05fe6ab03550"]]},{"id":"3cad05fe6ab03550","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":" var str = msg.payload;\n\n global.set(\"btbat\", str);\n  \n ","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1420,"wires":[[]]},{"id":"478ea3480d266c95","type":"link in","z":"1f780f8f.dbcd5","name":"nameupdate","links":["c3680b88.1a7378","88ee532e.6c2ce"],"x":389,"y":592,"wires":[["72204697.5e7d18"]]},{"id":"e5c2f0cbb66d6012","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wrelaystatusload","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":860,"y":480,"wires":[["b29548a803830230"]]},{"id":"80bcb9cb22d8419c","type":"function","z":"1f780f8f.dbcd5","name":"set globals","func":"global.set(\"Wone\", msg.payload.Wone);\nglobal.set(\"Wtwo\", msg.payload.Wtwo);\nglobal.set(\"Wthree\", msg.payload.Wthree);\nglobal.set(\"Wfour\", msg.payload.Wfour);\nglobal.set(\"Wfive\", msg.payload.Wfive);\nglobal.set(\"Wsix\", msg.payload.Wsix);\nglobal.set(\"Wseven\", msg.payload.Wseven);\nglobal.set(\"Weight\", msg.payload.Weight);","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1210,"y":480,"wires":[[]]},{"id":"b29548a803830230","type":"json","z":"1f780f8f.dbcd5","name":"","property":"payload","action":"","pretty":false,"x":1050,"y":480,"wires":[["80bcb9cb22d8419c"]]},{"id":"5741e6776c25282c","type":"link out","z":"1f780f8f.dbcd5","name":"version","mode":"link","links":["75c69cd8e59757aa"],"x":1215,"y":1380,"wires":[]},{"id":"9a12b5a4245f0b37","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"var str = msg.payload;\nglobal.set(\"BatteryDataDelivery\", str);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1500,"wires":[["15d0f3207d03c2e2"]]},{"id":"1f68b0852ec01670","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/BatteryDataDelivery","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":870,"y":1500,"wires":[["9a12b5a4245f0b37"]]},{"id":"0a02f7cfae77fb05","type":"inject","z":"1f780f8f.dbcd5","d":true,"name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"5","topic":"","payload":"","payloadType":"date","x":230,"y":2140,"wires":[["e5eb59f27e6502f6","7bbf89d1e1bb86be","64d7cc531e66ad56","4783839267bc05c2","eab92dedca085a2c"]]},{"id":"e5eb59f27e6502f6","type":"file in","z":"1f780f8f.dbcd5","d":true,"name":"","filename":"pekaway/LFBrosON","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":440,"y":2140,"wires":[["4b77e0f00a7c546e"]]},{"id":"7bbf89d1e1bb86be","type":"file in","z":"1f780f8f.dbcd5","d":true,"name":"","filename":"pekaway/LFBrosOFF","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":440,"y":2180,"wires":[["b10c0ec6b8844c73"]]},{"id":"64d7cc531e66ad56","type":"file in","z":"1f780f8f.dbcd5","d":true,"name":"","filename":"pekaway/LFBrosPLUS","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":440,"y":2220,"wires":[["af203fc68c772999"]]},{"id":"4783839267bc05c2","type":"file in","z":"1f780f8f.dbcd5","d":true,"name":"","filename":"pekaway/LFBrosMINUS","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":440,"y":2260,"wires":[["16445c868358cc73"]]},{"id":"4b77e0f00a7c546e","type":"function","z":"1f780f8f.dbcd5","d":true,"name":"","func":"global.set(\"LFBrosON\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":659,"y":2141,"wires":[[]]},{"id":"b10c0ec6b8844c73","type":"function","z":"1f780f8f.dbcd5","d":true,"name":"","func":"global.set(\"LFBrosOFF\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":659,"y":2181,"wires":[[]]},{"id":"af203fc68c772999","type":"function","z":"1f780f8f.dbcd5","d":true,"name":"","func":"global.set(\"LFBrosPLUS\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":659,"y":2221,"wires":[[]]},{"id":"16445c868358cc73","type":"function","z":"1f780f8f.dbcd5","d":true,"name":"","func":"global.set(\"LFBrosMINUS\", msg.payload.trim());\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":659,"y":2261,"wires":[[]]},{"id":"723466d08215ca17","type":"comment","z":"1f780f8f.dbcd5","d":true,"name":"set global variables for LFBros on boot","info":"","x":494,"y":2098,"wires":[]},{"id":"eab92dedca085a2c","type":"file in","z":"1f780f8f.dbcd5","d":true,"name":"","filename":"pekaway/LFBros","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":441,"y":2302,"wires":[["f02debf3912b2522"]]},{"id":"f02debf3912b2522","type":"function","z":"1f780f8f.dbcd5","d":true,"name":"function","func":"global.set(\"LFBros\", msg.payload)\nif(msg.payload==\"true\") {\n    msg.payload = {\"group\":{\"show\":[\"Heater_LFBros\"]}};\n    return msg\n}\nelse if(msg.payload==\"false\") {\n    msg.payload = {\"group\":{\"hide\":[\"Heater_LFBros\"]}};\n    return msg\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":660,"y":2302,"wires":[["b50410d3e957e6cd"]]},{"id":"b50410d3e957e6cd","type":"ui_ui_control","z":"1f780f8f.dbcd5","d":true,"name":"","events":"all","x":807,"y":2302,"wires":[[]]},{"id":"e7f163efc71ccc07","type":"link out","z":"1f780f8f.dbcd5","name":"hyst","mode":"link","links":["24f4c8cbd1618d02"],"x":1905,"y":1320,"wires":[]},{"id":"8162b2e36e019a1e","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"25","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1170,"y":1740,"wires":[["ee271eb64628fc0a"]]},{"id":"976581f8be965e6a","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"50","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1170,"y":1780,"wires":[["c6b55fd009e69ef0"]]},{"id":"166539673334fc31","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"75","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1170,"y":1820,"wires":[["325d9614f6237827"]]},{"id":"ada5534e827912c9","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1180,"y":1860,"wires":[["31f94e298e95c2b4"]]},{"id":"11f2bc5db5792cae","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"125","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1180,"y":1900,"wires":[["9d8da021cba66085"]]},{"id":"18220fbc9894788e","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"150","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1180,"y":1940,"wires":[["3b589471ad93efe2"]]},{"id":"223ffefbbe8f3d72","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"175","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1180,"y":1980,"wires":[["6ce111f8c4860e01"]]},{"id":"3325ea1d31b73cc9","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"200","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1180,"y":2020,"wires":[["fa4a585a780c2772"]]},{"id":"875ded8b4dcda778","type":"inject","z":"1f780f8f.dbcd5","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":"300","topic":"","payload":"","payloadType":"date","x":210,"y":1940,"wires":[["1c055936a2e014f3","8281f5e3445976ed","3e22301fc280edae","d8bae22f106f42ee","0b0bf2f8411ab2d9","a3e2be16c098d54b","9bf6cd1f5e6db3b4","f7df9191a870e9ac","ac79c3719507c3c0"]]},{"id":"5fd0885ad13b0245","type":"comment","z":"1f780f8f.dbcd5","name":"(2nd inject to sync homebridge on boot)","info":"","x":950,"y":1700,"wires":[]},{"id":"4c283893c7f0d26d","type":"link in","z":"1f780f8f.dbcd5","name":"change tab 1 dimmer names","links":["f5a2124f9c3ff250"],"x":265,"y":1820,"wires":[["1c055936a2e014f3","8281f5e3445976ed","d8bae22f106f42ee","3e22301fc280edae","0b0bf2f8411ab2d9","a3e2be16c098d54b","9bf6cd1f5e6db3b4","f7df9191a870e9ac"]]},{"id":"ea056e6598b5f8c6","type":"link out","z":"1f780f8f.dbcd5","name":"systemtime_init_init","mode":"link","links":["2d030be61cb338ee","44fee5509dc48b5b","7bb31b614ef172bc","f1e046474c1c0973","fb38cd254a7a2c32"],"x":705,"y":560,"wires":[]},{"id":"068ec4f6bd7a5f66","type":"function","z":"1f780f8f.dbcd5","name":"MUART, USB, BTbatt, Shunt","func":"/*\nUSB UART:\n0 = nothing\n1 = Daly BMS Bluetooth\n2 = VE.Direct\n3 = Webasto\n4 = China Diesel Heater\n5 = Autoterm 2D\n6 = Daly Monit\n7 = JBD Generic\n8 = Autoterm 4D\n9 = MaxxAir MaxxFan\n*/\nvar multiuart = global.get(\"multiuart1\");\nvar multiuart2 = global.get(\"multiuart2\");\nvar BLE = global.get(\"BLEdevice\");\nvar usb1 = parseInt(global.get(\"usb1uart\"));\nvar usb2 = parseInt(global.get(\"usb2uart\"));\nvar usb3 = parseInt(global.get(\"usb3uart\"));\nvar usb4 = parseInt(global.get(\"usb4uart\"));\nvar btbat = global.get(\"btbat\");\nvar btbat1 = 1;\n\nvar bms_info = {\"group\":{\"hide\":[\"Info_BMS_INFO\"]}};\nvar victron = {\"tabs\":{\"hide\":[\"Victron\"]}};\nlet maxxfan = {\"tabs\":{\"hide\":[\"MaxxFan\"]}};\nvar webasto = {\"group\":{\"hide\":[\"Heater_Info_Webasto\"]}};\nvar chinaheater = {\"group\":{\"hide\":[\"Heater_Info_China_Heater\"]}};\nvar autoterm = {\"group\":{\"hide\":[\"Heater_Info_Autoterm\"]}};\nvar vanpishunt = {\"group\":{\"hide\":[\"Info_VanPI_Shunt\"]}};\nvar victronshunt = {\"group\":{\"hide\":[\"Info_Victron_Shunt\"]}};\nvar dimmytemp = {\"group\":{\"hide\":[\"Info_Dimmy_Temperature\", \"Sensors_Dimmy_Temperature_Names\"]}};\n\nif (btbat == 0 || btbat == \"\" || btbat == undefined || btbat == \"turn off\" || btbat == \"turned off\" || btbat == \"Scan Bluetooth first\") {\n    btbat1 = 0;   \n}\n\n//USB-Ports + Bluetooth Batt/BMS\nif (usb1 == 0 && usb2 == 0 && usb3 == 0 && usb4 == 0) {\n    if(btbat == 0 || btbat == \"\" || btbat == undefined || btbat == \"turn off\" || btbat == \"turned off\" || btbat == \"Scan Bluetooth first\") {\n        bms_info = {\"group\":{\"hide\":[\"Info_BMS_INFO\"]}};\n    }\n    else {\n        bms_info = { \"group\": { \"show\": [\"Info_BMS_INFO\"], \"hide\": []}};\n    }\n}\n\nif(usb1==1 || usb1==6 || usb1 == 7 || usb2==1 || usb2==6 || usb2 == 7 || usb3==1 || usb3==6 || usb3 == 7 || usb4==1 || usb4==6 || usb4 == 7 || multiuart==1 || multiuart==6 || multiuart == 7 || BLE == 1 || multiuart2 == 1 || multiuart2 == 6 || multiuart2 == 7 || btbat1 == 1) {\n    bms_info = { \"group\": { \"show\": [\"Info_BMS_INFO\"], \"hide\": []}};\n}\nif(usb1==2 || usb2==2 || usb3==2 || usb4==2) {\n    victron = { \"tabs\": { \"show\": [\"Victron\"], \"hide\": []}};\n}\nif(usb1==3 || usb2==3 || usb3==3 || usb4==3) {\n    webasto = { \"group\": { \"show\": [\"Heater_Info_Webasto\"], \"hide\": []}};\n}\nif(usb1==4 || usb2==4 || usb3==4 || usb4==4) {\n    chinaheater = { \"group\": { \"show\": [\"Heater_Info_China_Heater\"], \"hide\": []}};\n}\nif (usb1 == 5 || usb2 == 5 || usb3 == 5 || usb4 == 5 || usb1 == 8 || usb2 == 8 || usb3 == 8 || usb4 == 8) {\n    autoterm = { \"group\": { \"show\": [\"Heater_Info_Autoterm\"], \"hide\": []}};\n}\n\n//MUART\nif(multiuart==2 || multiuart2==2) {\n    victron = { \"tabs\": { \"show\": [\"Victron\"], \"hide\": []}};\n}\n\n//Shunt\nif(global.get(\"pkwshuntactive\")==true) {\n    vanpishunt = { \"group\": { \"show\": [\"Info_VanPI_Shunt\"], \"hide\": []}};\n}\nif(global.get(\"BatteryDataDelivery\")==\"VICTRON\") {\n    victronshunt = { \"group\": { \"show\": [\"Info_Victron_Shunt\"], \"hide\": []}};\n}\n\n//Dimmy temp sensors\nif (global.get(\"dimmytemp\") == true) {\n    dimmytemp = { \"group\": { \"show\": [\"Info_Dimmy_Temperature\", \"Sensors_Dimmy_Temperature_Names\"], \"hide\": []}};\n}\n\n//MaxFan Tab\nif (usb1 == 9 || usb2 == 9 || usb3 == 9 || usb4 == 9) {\n    maxxfan = {\"tabs\":{\"show\":[\"MaxxFan\"], \"hide\":[]}};\n}\n\n//send variables to build ui\nmsg.payload = bms_info\nnode.send(msg)\nmsg.payload = victron\nnode.send(msg)\nmsg.payload = webasto\nnode.send(msg)\nmsg.payload = chinaheater\nnode.send(msg)\nmsg.payload = autoterm\nnode.send(msg)\nmsg.payload = vanpishunt\nnode.send(msg)\nmsg.payload = victronshunt\nnode.send(msg)\nmsg.payload = dimmytemp\nnode.send(msg)\nmsg.payload = maxxfan\nnode.send(msg)","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1660,"y":220,"wires":[["21d02601345bcaa5"]]},{"id":"2d440d485e71d1bb","type":"function","z":"1f780f8f.dbcd5","name":"hide","func":"msg.payload={\"group\":{\"hide\":[\"Info_BMS_INFO\",\"Heater_Info_China_Heater\",\"Heater_Info_Webasto\",\"Heater_Info_Autoterm\",\"Info_VanPI_Shunt\",\"Info_Victron_Shunt\",\"Heater_LFBros\"]}};\nnode.send([null, msg])\nmsg.payload={\"tabs\":{\"show\":[\"Heater\"]}};\nnode.send([null, msg])\nmsg.payload={\"tabs\":{\"hide\":[\"Victron\"]}};\nnode.send([null, msg])\nmsg.payload={\"tabs\":{\"hide\":[\"MaxxFan\"]}};\nnode.send([null, msg])\n\nreturn [msg, null];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1590,"y":300,"wires":[["1da88df1378741fc"],["21d02601345bcaa5"]]},{"id":"1da88df1378741fc","type":"delay","z":"1f780f8f.dbcd5","name":"25ms","pauseType":"delay","timeout":"25","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1610,"y":260,"wires":[["068ec4f6bd7a5f66"]]},{"id":"21d02601345bcaa5","type":"ui_ui_control","z":"1f780f8f.dbcd5","name":"","x":2200,"y":280,"wires":[[]]},{"id":"9c3fb485dd0c5376","type":"link in","z":"1f780f8f.dbcd5","name":"build uart ui","links":["40a4699153812269","476c314c5bcfdce5","6b6e79e3f626c4d5","82cba0c9acde2538","a1ec3f80405825b1","ae435be872a3cfff","e07ca4c4ccc47d5a","e46645f35f31054d","ad41b6bbb9a8c4a8"],"x":1435,"y":220,"wires":[["068ec4f6bd7a5f66"]]},{"id":"e88d437867a17dad","type":"link out","z":"1f780f8f.dbcd5","name":"initi autooff switches vars","mode":"link","links":["78f68e6f8e856e41"],"x":715,"y":360,"wires":[]},{"id":"ac79c3719507c3c0","type":"function","z":"1f780f8f.dbcd5","name":"hb_sync true","func":"global.set(\"hb_sync\", true)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":2060,"wires":[["f8c032b12ad00c5b"]]},{"id":"f8c032b12ad00c5b","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"2","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":620,"y":2060,"wires":[["dfd1982f20469c0d"]]},{"id":"dfd1982f20469c0d","type":"function","z":"1f780f8f.dbcd5","name":"hb_sync false","func":"global.set(\"hb_sync\", false)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":800,"y":2060,"wires":[[]]},{"id":"035656429896a1c4","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/mcpinput1_type","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1610,"y":1540,"wires":[["a5b77d08c3d7d569"]]},{"id":"3662f4b64c29ef86","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/mcpinput2_type","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1610,"y":1580,"wires":[["bc1aefd81eed7e85"]]},{"id":"f00e1cecb961a7d2","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/mcpinput3_type","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1610,"y":1620,"wires":[["a62b83997ca592de"]]},{"id":"9a9a0ebb49c374e4","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/mcpinput4_type","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1610,"y":1660,"wires":[["9cc3e40661c80b7f"]]},{"id":"3fda7a71ddd689cc","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/mcpinput5_type","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1610,"y":1700,"wires":[["2db14857746e2a4c"]]},{"id":"b0313ebc854f1a83","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/mcpinput6_type","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1610,"y":1740,"wires":[["5cffb6cad058bf0d"]]},{"id":"a5b77d08c3d7d569","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"mcpinput1_type\",msg.payload);\nmsg.mcpno = 1\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1820,"y":1540,"wires":[["d369278b4d05c2b5"]]},{"id":"bc1aefd81eed7e85","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"mcpinput2_type\",msg.payload);\nmsg.mcpno = 2\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1820,"y":1580,"wires":[["d369278b4d05c2b5"]]},{"id":"a62b83997ca592de","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"mcpinput3_type\",msg.payload);\nmsg.mcpno = 3\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1820,"y":1620,"wires":[["d369278b4d05c2b5"]]},{"id":"9cc3e40661c80b7f","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"mcpinput4_type\",msg.payload);\nmsg.mcpno = 4\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1820,"y":1660,"wires":[["d369278b4d05c2b5"]]},{"id":"2db14857746e2a4c","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"mcpinput5_type\",msg.payload);\nmsg.mcpno = 5\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1820,"y":1700,"wires":[["d369278b4d05c2b5"]]},{"id":"5cffb6cad058bf0d","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"mcpinput6_type\",msg.payload);\nmsg.mcpno = 6\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1820,"y":1740,"wires":[["d369278b4d05c2b5"]]},{"id":"d369278b4d05c2b5","type":"link out","z":"1f780f8f.dbcd5","name":"mcpinput type","mode":"link","links":["88627c67148a916a"],"x":1965,"y":1640,"wires":[]},{"id":"9e4bf54088d5fb75","type":"link out","z":"1f780f8f.dbcd5","name":"check zigbee","mode":"link","links":["64bf592b6afeb651"],"x":1075,"y":20,"wires":[]},{"id":"7eeb589679842223","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmytemp1name","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1620,"y":800,"wires":[["09a60d13659e6052"]]},{"id":"7837779df3405f84","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmytemp2name","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1620,"y":840,"wires":[["6652f9106812c970"]]},{"id":"09a60d13659e6052","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"Ndimmytemp1\", msg.payload);","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1810,"y":800,"wires":[[]]},{"id":"6652f9106812c970","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"Ndimmytemp2\", msg.payload);","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1810,"y":840,"wires":[[]]},{"id":"eedd3d20cd755a80","type":"function","z":"1f780f8f.dbcd5","name":"set installdate","func":"var date = new Date().toLocaleString()\nglobal.set(\"installdate\", date)\nmsg.payload = date\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":930,"y":140,"wires":[["10c82a3fe0351a0a"]]},{"id":"10c82a3fe0351a0a","type":"file","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/installdate","filenameType":"str","appendNewline":false,"createDir":true,"overwriteFile":"true","encoding":"none","x":1150,"y":140,"wires":[[]]},{"id":"453fcc44d10b694f","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/installdate","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":730,"y":180,"wires":[["d9614f9e50d768b2"]]},{"id":"d9614f9e50d768b2","type":"function","z":"1f780f8f.dbcd5","name":"save installdate to var","func":"if ( msg.payload != \"\") {\n    global.set(\"installdate\", msg.payload)\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":952,"y":180,"wires":[[]]},{"id":"1ba3c6dea8b0a688","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":720,"y":140,"wires":[["453fcc44d10b694f"]]},{"id":"36c5ccc88d0205ae","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/dimmer_maxpercent","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":870,"y":1540,"wires":[["440f7a9f89b2f7c0"]]},{"id":"440f7a9f89b2f7c0","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"dimmer_maxpercent\", msg.payload);\nmsg.payload = parseInt(msg.payload)\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1540,"wires":[["509babed283534d1"]]},{"id":"509babed283534d1","type":"link out","z":"1f780f8f.dbcd5","name":"dimmer_maxpercent","mode":"link","links":["12ca99015ff02121"],"x":1215,"y":1540,"wires":[]},{"id":"15d0f3207d03c2e2","type":"link out","z":"1f780f8f.dbcd5","name":"init Main BattData","mode":"link","links":["a578e9ea280452d0"],"x":1215,"y":1500,"wires":[]},{"id":"e81293f8afe6d202","type":"comment","z":"1f780f8f.dbcd5","name":"(<- dimmers & wifirelays init happens in config flow)","info":"","x":2250,"y":340,"wires":[]},{"id":"ee3f0c6c5f5b75ce","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/wpasettings","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":1600,"y":560,"wires":[["a853a6451c0a8ace"]]},{"id":"a853a6451c0a8ace","type":"json","z":"1f780f8f.dbcd5","name":"","property":"payload","action":"","pretty":false,"x":1770,"y":560,"wires":[["c4bb28c83d8f89e3"]]},{"id":"c4bb28c83d8f89e3","type":"function","z":"1f780f8f.dbcd5","name":"set payload","func":"global.set(\"ssid\", msg.payload.ssid.split('=').pop())\nglobal.set(\"wpa\", msg.payload.wpa.split('=').pop())","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1930,"y":560,"wires":[[]]},{"id":"e9dcf377ec0880b3","type":"file in","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/van_name","filenameType":"str","format":"utf8","chunk":false,"sendError":false,"encoding":"none","allProps":false,"x":840,"y":1580,"wires":[["0f61efeb44829727"]]},{"id":"0f61efeb44829727","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"global.set(\"van_name\", msg.payload);\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1580,"wires":[["2d5a0a61997ce3d1"]]},{"id":"2d5a0a61997ce3d1","type":"link out","z":"1f780f8f.dbcd5","name":"van_name","mode":"link","links":["f32f2c0c499aed04"],"x":1215,"y":1580,"wires":[]},{"id":"6d55d8a67c4a486f","type":"file","z":"1f780f8f.dbcd5","name":"","filename":"pekaway/btbms_type","filenameType":"str","appendNewline":false,"createDir":true,"overwriteFile":"true","encoding":"none","x":840,"y":1460,"wires":[["4048b584bfb0d3a4"]]},{"id":"4048b584bfb0d3a4","type":"function","z":"1f780f8f.dbcd5","name":"set global","func":"var str = msg.payload;\nglobal.set(\"btbms_type\", str);","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1100,"y":1460,"wires":[[]]},{"id":"2623b2af19d2f764","type":"function","z":"1f780f8f.dbcd5","name":"set boot false","func":"global.set(\"boot_process\", false);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1620,"y":420,"wires":[[]]},{"id":"54053996dab16093","type":"delay","z":"1f780f8f.dbcd5","name":"","pauseType":"delay","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1380,"y":420,"wires":[["2623b2af19d2f764"]]},{"id":"54253f1194a8f79a","type":"inject","z":"1f780f8f.dbcd5","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":300,"y":80,"wires":[["eedd3d20cd755a80"]]},{"id":"7c2ace427a9c5210","type":"ui_spacer","z":"1f780f8f.dbcd5","name":"spacer","group":"00c90244e8033802","order":5,"width":6,"height":1},{"id":"84ad469212f41640","type":"ui_spacer","z":"1f780f8f.dbcd5","name":"spacer","group":"1032e8ff.e5a657","order":6,"width":6,"height":1},{"id":"00c90244e8033802","type":"ui_group","name":"VANPI Shunt","tab":"1b7846a35b09245e","order":2,"disp":true,"width":"6","collapse":true,"className":""},{"id":"1032e8ff.e5a657","type":"ui_group","name":"Water Level Names","tab":"53ef2f8d6450b467","order":3,"disp":true,"width":"6","collapse":true,"className":""},{"id":"1b7846a35b09245e","type":"ui_tab","name":"Shunt","icon":"dashboard","order":14,"disabled":false,"hidden":true},{"id":"53ef2f8d6450b467","type":"ui_tab","name":"Sensors","icon":"dashboard","order":12,"disabled":false,"hidden":true}]

Monit Flow

Die ttgo Funktion wurde etwas umgeschrieben und es gibt eine neue globale ttgo Variable:

die Node:

[{"id":"7e06940daf37a32e","type":"function","z":"527dade3be53f8eb","name":"format values","func":"var volt = global.get(\"MainBattVolt\");\nvar soc = global.get(\"MainBattSoc\");\nvar amps = msg.payload\nvar cap = global.get(\"BMScap\");\nmsg.amps = amps;\nmsg.cap = cap;\n\nif (amps > 0) {\n    msg.payload = \"charging\"\n}\nelse if (amps == 0) {\n    msg.payload = \"not using power\";\n}\nelse {\n    amps = amps * -1\n    msg.ttgo = Number((cap / amps).toFixed(2));\n\n    let hours = Math.floor(msg.ttgo); // Extract the whole number part (20)\n    let rawMinutes = Math.round((msg.ttgo - hours) * 60); // Extract the fractional part (0.8), convert to minutes, and round\n\n    // Round minutes to the nearest 15-minute interval\n    let roundedMinutes = Math.round(rawMinutes / 15) * 15;\n\n    // Adjust hours if rounding up results in 60 minutes\n    if (roundedMinutes === 60) {\n        hours += 1;\n        roundedMinutes = 0;\n    }\n\n    // Format the result\n    let result = hours + 'h ';\n    if (roundedMinutes > 0) {\n        result += roundedMinutes + 'min';\n    }\n\n    // Return the formatted result\n    msg.payload = result;\n}\nglobal.set(\"ttgo\", msg.payload)\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":793,"y":840,"wires":[["0501371eb97401c5","25e5a65c9c817408"]]}]

der gesamte Monit Flow:

[{"id":"527dade3be53f8eb","type":"tab","label":"Monit","disabled":false,"info":""},{"id":"b1a7918a8c55b102","type":"inject","z":"527dade3be53f8eb","name":"1m","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"60","crontab":"","once":true,"onceDelay":"25","topic":"","payload":"","payloadType":"date","x":250,"y":140,"wires":[["cc06bc613a170d3c","d47210a741fbe0dc","5c218770f9f2b821","ac87db133ad0c376","7b54fecb489e1f48","a614c55d3cecf54e","5e70c85953b01d59"]]},{"id":"117df5814ca8e4a6","type":"ui_chart","z":"527dade3be53f8eb","name":"Temp2","group":"84acc58546c6e0c3","order":2,"width":"6","height":"4","label":"{{topic}}: {{msg.value}}°C","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"cubic","nodata":"waiting for readings","dot":false,"ymin":"","ymax":"","removeOlder":"10","removeOlderPoints":"600","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":790,"y":100,"wires":[[]]},{"id":"a6dd3816242a16fc","type":"ui_chart","z":"527dade3be53f8eb","name":"Temp3","group":"84acc58546c6e0c3","order":3,"width":"6","height":"4","label":"{{topic}}: {{msg.value}}°C","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"cubic","nodata":"waiting for readings","dot":false,"ymin":"","ymax":"","removeOlder":"10","removeOlderPoints":"600","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":790,"y":140,"wires":[[]]},{"id":"cc06bc613a170d3c","type":"function","z":"527dade3be53f8eb","name":"get temp2","func":"var temp = global.get(\"temp2\");\nvar name = global.get(\"Ntemp2\");\n\ntemp = parseFloat(temp);\ntemp = Math.round(temp * 10.0) / 10.0;\n\nmsg.topic = name;\nmsg.value = temp;\nmsg.payload = {};\nnode.send([msg, null]);\n\nmsg.payload = temp;\nmsg.topic = name;\n\nif (temp == \"\") {\n    return null\n}\n\nreturn [null, msg]","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":120,"wires":[["117df5814ca8e4a6"],["8026924790f12de7"]]},{"id":"d47210a741fbe0dc","type":"function","z":"527dade3be53f8eb","name":"get temp3","func":"var temp = global.get(\"temp3\");\nvar name = global.get(\"Ntemp3\");\n\ntemp = parseFloat(temp);\ntemp = Math.round(temp * 10.0) / 10.0;\n\nmsg.topic = name;\nmsg.value = temp;\nmsg.payload = {};\nnode.send([msg, null]);\n\nmsg.payload = temp;\nmsg.topic = name;\n\nif (temp == \"\") {\n    return null\n}\n\nreturn [null, msg]","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":160,"wires":[["a6dd3816242a16fc"],["6b16668cc62cb923"]]},{"id":"5c218770f9f2b821","type":"function","z":"527dade3be53f8eb","name":"get temp4","func":"var temp = global.get(\"temp4\");\nvar name = global.get(\"Ntemp4\");\n\ntemp = parseFloat(temp);\ntemp = Math.round(temp * 10.0) / 10.0;\n\nmsg.topic = name;\nmsg.value = temp;\nmsg.payload = {};\nnode.send([msg, null]);\n\nmsg.payload = temp;\nmsg.topic = name;\n\nif (temp == \"\") {\n    return null\n}\n\nreturn [null, msg]","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":200,"wires":[["b3972853af65c53f"],["c231e369d93e92ce"]]},{"id":"b3972853af65c53f","type":"ui_chart","z":"527dade3be53f8eb","name":"Temp4","group":"84acc58546c6e0c3","order":4,"width":"6","height":"4","label":"{{topic}}: {{msg.value}}°C","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"cubic","nodata":"waiting for readings","dot":false,"ymin":"","ymax":"","removeOlder":"10","removeOlderPoints":"600","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":790,"y":180,"wires":[[]]},{"id":"419e0eda07d88b5d","type":"comment","z":"527dade3be53f8eb","name":"battery stats","info":"","x":500,"y":260,"wires":[]},{"id":"3381b8e66b5f861b","type":"comment","z":"527dade3be53f8eb","name":"temp stats","info":"","x":490,"y":40,"wires":[]},{"id":"225aca95bb7ddf93","type":"function","z":"527dade3be53f8eb","name":"format","func":"msg.payload = parseFloat(msg.payload).toFixed(1)\nglobal.set(\"rpi_cpu_temp\", msg.payload)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":677,"y":440,"wires":[["167b13aa19eb6288"]]},{"id":"167b13aa19eb6288","type":"ui_gauge","z":"527dade3be53f8eb","name":"","group":"e1aef104cda6dd6b","order":1,"width":"3","height":"4","gtype":"donut","title":"CPU Temp","label":"","format":"{{value}}°C","min":"20","max":"90","colors":["#00b500","#e6e600","#ca3838"],"seg1":"50","seg2":"65","className":"","x":837,"y":440,"wires":[]},{"id":"64722222f15de962","type":"cpu","z":"527dade3be53f8eb","name":"","msgCore":false,"msgOverall":true,"msgArray":false,"msgTemp":false,"x":497,"y":480,"wires":[["2771cf0f4f491204","14667a8aa185b6d6"]]},{"id":"c723b90d714a39e0","type":"cpu","z":"527dade3be53f8eb","name":"","msgCore":false,"msgOverall":false,"msgArray":false,"msgTemp":true,"x":497,"y":440,"wires":[["225aca95bb7ddf93"]]},{"id":"2771cf0f4f491204","type":"ui_gauge","z":"527dade3be53f8eb","name":"","group":"e1aef104cda6dd6b","order":2,"width":"3","height":"4","gtype":"donut","title":"CPU Usage","label":"","format":"{{value}}%","min":"0","max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"35","seg2":"80","className":"","x":837,"y":480,"wires":[]},{"id":"ad45411ee62ca659","type":"ui_chart","z":"527dade3be53f8eb","name":"CPU usage chart","group":"e1aef104cda6dd6b","order":3,"width":0,"height":0,"label":"CPU usage (overall: {{msg.cpu}})","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"bezier","nodata":"waiting for readings","dot":false,"ymin":"0","ymax":"","removeOlder":"3","removeOlderPoints":"160","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":857,"y":520,"wires":[[]]},{"id":"7ca6ecb.7512014","type":"ui_gauge","z":"527dade3be53f8eb","name":"","group":"e1aef104cda6dd6b","order":5,"width":"3","height":"4","gtype":"donut","title":"Disk","label":"Usage","format":"{{value}} %","min":0,"max":"100","colors":["#00b500","#e6e600","#ca3838"],"seg1":"70","seg2":"90","className":"","x":1150,"y":620,"wires":[]},{"id":"3283a8b7dccf942b","type":"memory","z":"527dade3be53f8eb","name":"","relativeValues":false,"unitType":"gb","totalMemory":true,"usedMemory":false,"freeMemory":true,"availableMemory":false,"activeMemory":true,"buffersMemory":false,"cachedMemory":false,"slabMemory":false,"buffcacheMemory":false,"freeAvailableMemory":false,"swapTotalMemory":false,"swapUsedMemory":false,"swapFreeMemory":false,"x":480,"y":680,"wires":[["4e97fc1244330caa"]]},{"id":"59fb6bdf4316a12e","type":"function","z":"527dade3be53f8eb","name":"format","func":"var memory_free = (msg.payload.memory_total-msg.payload.memory_active)\nvar memory_active = msg.payload.memory_active\nvar memory_total = parseFloat(msg.payload.memory_total).toFixed(2)\nvar seq1 = parseFloat(memory_total)*0.5;\nvar seq2 = parseFloat(memory_total)-(parseFloat(memory_total)*0.15)\n\nmsg = {\n    ui_control:{\n    max:memory_total,\n    seg1:seq1,\n    seg2:seq2\n    },\n    payload: parseFloat(memory_active).toFixed(2)\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":680,"wires":[["e4a287bfd075cc14"]]},{"id":"4e97fc1244330caa","type":"join","z":"527dade3be53f8eb","name":"","mode":"custom","build":"object","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":false,"timeout":"2","count":"","reduceRight":false,"reduceExp":"","reduceInit":"","reduceInitType":"num","reduceFixup":"","x":610,"y":680,"wires":[["59fb6bdf4316a12e"]]},{"id":"e4a287bfd075cc14","type":"ui_gauge","z":"527dade3be53f8eb","name":"","group":"e1aef104cda6dd6b","order":4,"width":"3","height":"4","gtype":"donut","title":"Memory used","label":"RAM","format":"{{value}} GB","min":0,"max":"8","colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","className":"","x":900,"y":680,"wires":[]},{"id":"41894d2f19885c65","type":"function","z":"527dade3be53f8eb","name":"filter","func":"if (msg.payload != \"\" && msg.payload.includes(\"%\")) {\n    msg.payload = msg.payload.substring(0, msg.payload.length-1)\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1010,"y":620,"wires":[["7ca6ecb.7512014"]]},{"id":"1f8f4c57afedb27c","type":"split","z":"527dade3be53f8eb","name":"","splt":" ","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":890,"y":620,"wires":[["41894d2f19885c65"]]},{"id":"8a83977ee0a05493","type":"switch","z":"527dade3be53f8eb","name":"","property":"payload","propertyType":"msg","rules":[{"t":"cont","v":"/dev/root","vt":"str"}],"checkall":"true","repair":false,"outputs":1,"x":770,"y":620,"wires":[["1f8f4c57afedb27c"]]},{"id":"f2719bd23e8e4d8a","type":"split","z":"527dade3be53f8eb","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":640,"y":620,"wires":[["8a83977ee0a05493"]]},{"id":"40e5e17a7246a1b8","type":"exec","z":"527dade3be53f8eb","command":"df -h","addpay":"","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"Disk Usage","x":490,"y":620,"wires":[["f2719bd23e8e4d8a"],[],[]]},{"id":"745d3a2d6d5592da","type":"exec","z":"527dade3be53f8eb","command":"uptime -p | sed 's/up //g'","addpay":"","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"Uptime","x":470,"y":738,"wires":[["a9abad096a58e5fb"],[],[]]},{"id":"f0744f664c4052e6","type":"ui_text","z":"527dade3be53f8eb","group":"e1aef104cda6dd6b","order":5,"width":"6","height":"2","name":"Uptime","label":"System Uptime","format":"{{msg.payload}}","layout":"col-center","className":"","x":882,"y":741,"wires":[]},{"id":"2f3d2efb794fee4c","type":"ui_ui_control","z":"527dade3be53f8eb","name":"","events":"change","x":100,"y":180,"wires":[["b169b4f3be799217"]]},{"id":"b169b4f3be799217","type":"function","z":"527dade3be53f8eb","name":"check tab","func":"if (msg.payload == \"change\" && msg.name == \"Monitor\") {\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":240,"y":180,"wires":[["cc06bc613a170d3c","d47210a741fbe0dc","5c218770f9f2b821","ac87db133ad0c376","7b54fecb489e1f48","a614c55d3cecf54e","5e70c85953b01d59","cb0ed5111f24ef0c"]]},{"id":"f8149639d5c33863","type":"inject","z":"527dade3be53f8eb","name":"30s","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"30","crontab":"","once":true,"onceDelay":"25","topic":"","payload":"","payloadType":"date","x":217,"y":440,"wires":[["c723b90d714a39e0","64722222f15de962","40e5e17a7246a1b8","3283a8b7dccf942b","745d3a2d6d5592da","cb0ed5111f24ef0c"]]},{"id":"e7f029f566aa24f4","type":"comment","z":"527dade3be53f8eb","name":"RPI stats (30s)","info":"","x":230,"y":400,"wires":[]},{"id":"db80af084c544e62","type":"inject","z":"527dade3be53f8eb","name":"1min","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"60","crontab":"","once":true,"onceDelay":"20","topic":"","payload":"","payloadType":"str","x":213,"y":840,"wires":[["ba2ea807dde5dbd0"]]},{"id":"5dee0368d5acdea1","type":"comment","z":"527dade3be53f8eb","name":"calculate ttgo","info":"","x":213,"y":800,"wires":[]},{"id":"a9abad096a58e5fb","type":"function","z":"527dade3be53f8eb","name":"","func":"global.set(\"uptime\", msg.payload)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":726,"y":741,"wires":[["f0744f664c4052e6"]]},{"id":"e1f80057fc98defb","type":"ui_chart","z":"527dade3be53f8eb","name":"Temp1","group":"84acc58546c6e0c3","order":1,"width":"6","height":"4","label":"{{topic}}: {{msg.value}}°C","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"cubic","nodata":"waiting for readings","dot":false,"ymin":"","ymax":"","removeOlder":"10","removeOlderPoints":"600","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":790,"y":60,"wires":[[]]},{"id":"b77826589c1354a6","type":"smooth","z":"527dade3be53f8eb","name":"","property":"payload","action":"mean","count":"15","round":"1","mult":"single","reduce":true,"x":660,"y":80,"wires":[["e1f80057fc98defb"]]},{"id":"ac87db133ad0c376","type":"function","z":"527dade3be53f8eb","name":"get temp1","func":"var temp = global.get(\"temp1\");\nvar name = global.get(\"Ntemp1\");\n\ntemp = parseFloat(temp);\ntemp = Math.round(temp * 10.0) / 10.0;\n\nmsg.topic = name;\nmsg.value = temp;\nmsg.payload = {};\nnode.send([msg, null]);\n\nmsg.payload = temp;\nmsg.topic = name;\n\nif (temp == \"\") {\n    return null\n}\n\nreturn [null, msg]","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":80,"wires":[["e1f80057fc98defb"],["b77826589c1354a6"]]},{"id":"8026924790f12de7","type":"smooth","z":"527dade3be53f8eb","name":"","property":"payload","action":"mean","count":"15","round":"1","mult":"single","reduce":true,"x":660,"y":120,"wires":[["117df5814ca8e4a6"]]},{"id":"6b16668cc62cb923","type":"smooth","z":"527dade3be53f8eb","name":"","property":"payload","action":"mean","count":"15","round":"1","mult":"single","reduce":true,"x":660,"y":160,"wires":[["a6dd3816242a16fc"]]},{"id":"c231e369d93e92ce","type":"smooth","z":"527dade3be53f8eb","name":"","property":"payload","action":"mean","count":"15","round":"1","mult":"single","reduce":true,"x":660,"y":200,"wires":[["b3972853af65c53f"]]},{"id":"84811174ac4bdddd","type":"ui_chart","z":"527dade3be53f8eb","name":"SoC","group":"592e6d4c2e6f23cb","order":1,"width":"6","height":"4","label":"SoC: {{msg.soc}}%","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"cubic","nodata":"waiting for readings","dot":false,"ymin":"0","ymax":"100","removeOlder":"10","removeOlderPoints":"120","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":790,"y":280,"wires":[[]]},{"id":"7b54fecb489e1f48","type":"function","z":"527dade3be53f8eb","name":"get SoC","func":"var check = global.get(\"MainBattSoc\");\nvar soc = global.get(\"MainBattSoc\");\n\nmsg.payload = {}\nmsg.soc = soc\nnode.send([msg, null])\n\nmsg.payload = Number(check);\nreturn [null, msg];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":300,"wires":[["84811174ac4bdddd"],["4a4345430566d960"]]},{"id":"a614c55d3cecf54e","type":"function","z":"527dade3be53f8eb","name":"get volts","func":"var check2 = global.get(\"MainBattVolt\");\ncheck2 = parseFloat(check2)\ncheck2 = Math.round(check2 * 10.0) / 10.0;\n\nmsg.payload = {}\nmsg.label = check2\nnode.send([msg, null])\n\nmsg.payload = Number(check2);\nreturn [null, msg];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":340,"wires":[["f3b6576efadaf26f"],["ae282e0a097ce20d"]]},{"id":"f3b6576efadaf26f","type":"ui_chart","z":"527dade3be53f8eb","name":"Volts","group":"592e6d4c2e6f23cb","order":2,"width":"6","height":"4","label":"Volts: {{msg.label}}V","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"cubic","nodata":"waiting for readings","dot":false,"ymin":"7","ymax":"15","removeOlder":"10","removeOlderPoints":"200","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":790,"y":320,"wires":[[]]},{"id":"5e70c85953b01d59","type":"function","z":"527dade3be53f8eb","name":"get amps","func":"var check1 = global.get(\"MainBattAmps\");\ncheck1 = parseFloat(check1)\ncheck1 = Math.round(check1 * 100.0) / 100.0;\n\nmsg.payload = {}\nmsg.label = check1\nnode.send([msg, null])\n\nmsg.payload = Number(check1);\nreturn [null, msg];","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":380,"wires":[["d85adf6e33ca6505"],["0f417d805b5915c1"]]},{"id":"d85adf6e33ca6505","type":"ui_chart","z":"527dade3be53f8eb","name":"Amps","group":"592e6d4c2e6f23cb","order":3,"width":"6","height":"4","label":"Amps: {{msg.label}}A","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"cubic","nodata":"waiting for readings","dot":false,"ymin":"-100","ymax":"","removeOlder":"10","removeOlderPoints":"600","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"useUTC":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"outputs":1,"useDifferentColor":false,"className":"","x":790,"y":360,"wires":[[]]},{"id":"4a4345430566d960","type":"smooth","z":"527dade3be53f8eb","name":"","property":"payload","action":"min","count":"5","round":"0","mult":"single","reduce":true,"x":660,"y":300,"wires":[["84811174ac4bdddd"]]},{"id":"ae282e0a097ce20d","type":"smooth","z":"527dade3be53f8eb","name":"","property":"payload","action":"mean","count":"3","round":"1","mult":"single","reduce":true,"x":660,"y":340,"wires":[["f3b6576efadaf26f"]]},{"id":"0f417d805b5915c1","type":"smooth","z":"527dade3be53f8eb","name":"","property":"payload","action":"mean","count":"3","round":"1","mult":"single","reduce":true,"x":660,"y":380,"wires":[["d85adf6e33ca6505"]]},{"id":"7e06940daf37a32e","type":"function","z":"527dade3be53f8eb","name":"format values","func":"var volt = global.get(\"MainBattVolt\");\nvar soc = global.get(\"MainBattSoc\");\nvar amps = msg.payload\nvar cap = global.get(\"BMScap\");\nmsg.amps = amps;\nmsg.cap = cap;\n\nif (amps > 0) {\n    msg.payload = \"charging\"\n}\nelse if (amps == 0) {\n    msg.payload = \"not using power\";\n}\nelse {\n    amps = amps * -1\n    msg.ttgo = Number((cap / amps).toFixed(2));\n\n    let hours = Math.floor(msg.ttgo); // Extract the whole number part (20)\n    let rawMinutes = Math.round((msg.ttgo - hours) * 60); // Extract the fractional part (0.8), convert to minutes, and round\n\n    // Round minutes to the nearest 15-minute interval\n    let roundedMinutes = Math.round(rawMinutes / 15) * 15;\n\n    // Adjust hours if rounding up results in 60 minutes\n    if (roundedMinutes === 60) {\n        hours += 1;\n        roundedMinutes = 0;\n    }\n\n    // Format the result\n    let result = hours + 'h ';\n    if (roundedMinutes > 0) {\n        result += roundedMinutes + 'min';\n    }\n\n    // Return the formatted result\n    msg.payload = result;\n}\nglobal.set(\"ttgo\", msg.payload)\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":793,"y":840,"wires":[["0501371eb97401c5","25e5a65c9c817408"]]},{"id":"0501371eb97401c5","type":"ui_text","z":"527dade3be53f8eb","group":"592e6d4c2e6f23cb","order":7,"width":0,"height":0,"name":"","label":"TTGO","format":"{{msg.payload}}","layout":"row-spread","className":"","x":1163,"y":840,"wires":[]},{"id":"ba2ea807dde5dbd0","type":"function","z":"527dade3be53f8eb","name":"get amps","func":"msg.payload = parseFloat(global.get(\"MainBattAmps\"));\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":393,"y":840,"wires":[["aee85a34e1e34549"]]},{"id":"aee85a34e1e34549","type":"smooth","z":"527dade3be53f8eb","name":"mean of 5 values","property":"payload","action":"mean","count":"5","round":"2","mult":"single","reduce":true,"x":583,"y":840,"wires":[["7e06940daf37a32e"]]},{"id":"14667a8aa185b6d6","type":"smooth","z":"527dade3be53f8eb","name":"","property":"payload","action":"max","count":"3","round":"2","mult":"single","reduce":true,"x":677,"y":520,"wires":[["ad45411ee62ca659"]]},{"id":"25e5a65c9c817408","type":"ui_text","z":"527dade3be53f8eb","group":"dcfc4576570aad18","order":7,"width":0,"height":0,"name":"ttgo (info tab)","label":"","format":"{{msg.payload}}","layout":"col-center","className":"","x":1193,"y":880,"wires":[]},{"id":"cb0ed5111f24ef0c","type":"exec","z":"527dade3be53f8eb","command":"grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage}'","addpay":"","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"cpu usage since boot","x":520,"y":560,"wires":[["d112ef62638b4a48"],[],[]]},{"id":"d112ef62638b4a48","type":"function","z":"527dade3be53f8eb","name":"format value","func":"msg.cpu = msg.payload.trim()\nmsg.cpu = Number(msg.cpu).toFixed(2) + \"%\"\nmsg.payload = {}\nglobal.set(\"rpi_cpu_usage\", msg.cpu)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":560,"wires":[["ad45411ee62ca659","6cc8e012dfe69994"]]},{"id":"6cc8e012dfe69994","type":"debug","z":"527dade3be53f8eb","name":"debug 55","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":900,"y":560,"wires":[]},{"id":"84acc58546c6e0c3","type":"ui_group","name":"Temperature","tab":"72361f1d56c6ed7e","order":2,"disp":true,"width":"6","collapse":true,"className":""},{"id":"e1aef104cda6dd6b","type":"ui_group","name":"Raspberry","tab":"72361f1d56c6ed7e","order":4,"disp":true,"width":"6","collapse":true,"className":""},{"id":"592e6d4c2e6f23cb","type":"ui_group","name":"Battery","tab":"72361f1d56c6ed7e","order":1,"disp":true,"width":"6","collapse":true,"className":""},{"id":"dcfc4576570aad18","type":"ui_group","name":"Time to Go","tab":"deee53a800de461d","order":1,"disp":true,"width":"6","collapse":true,"className":""},{"id":"72361f1d56c6ed7e","type":"ui_tab","name":"Monitor","icon":"mi-history","order":6,"disabled":false,"hidden":false},{"id":"deee53a800de461d","type":"ui_tab","name":"Info","icon":"mi-info","order":1,"disabled":false,"hidden":false}]

Lagesensor Flow:

Dieser Flow ist komplett neu und noch nicht fertig(!), da fehlen noch einige Einstellungsmöglichkeiten und Anzeigen für das Frontend, aber im Prinzip läuft er schon, wenn ihr einen MPU6050 habt könnt ihr mit dem dazugehörigen PythonScript die Werte auslesen:

[{"id":"3739bebe6c778cd3","type":"tab","label":"position sensor","disabled":false,"info":"","env":[]},{"id":"f50f27a0bc038b47","type":"function","z":"3739bebe6c778cd3","name":"Offset hinzufügen","func":"// Erhalten der Eingangsdaten\nvar eingangsdaten = msg.payload;\n\n// Kalibrierungswert aus der globalen Variable verwenden\nvar kalibrierungswert = global.get(\"calibration_value_x\") || 0; // Standardwert ist 0, falls nicht gesetzt\n\n// Anpassen der Daten um den Kalibrierungswert\nvar datenMitKalibrierung = eingangsdaten - kalibrierungswert;\n\n// Auf eine Dezimalstelle runden\nvar gerundeteDaten = datenMitKalibrierung.toFixed(1); // 1 steht für eine Dezimalstelle\n\n// Wenn der gerundete Wert 0 ist, auf 0.0 ändern\nif (Number(gerundeteDaten) === 0) {\n    gerundeteDaten = \"0.0\";\n}\n\n// Weiterleiten der modifizierten und gerundeten Daten\nmsg.payload = parseFloat(gerundeteDaten); // Als Zahl statt String zurückgeben\n\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1410,"y":300,"wires":[["eb2be90032ddbb37","5d2e0c6b945bb6ca"]]},{"id":"99c6d65d1486302f","type":"smooth","z":"3739bebe6c778cd3","name":"","property":"payload","action":"mean","count":"2","round":"1","mult":"single","reduce":false,"x":1220,"y":300,"wires":[["f50f27a0bc038b47"]]},{"id":"e46980325aa122bc","type":"function","z":"3739bebe6c778cd3","name":"Offset hinzufügen","func":"// Erhalten der Eingangsdaten\nvar eingangsdaten = msg.payload;\n\n// Kalibrierungswert aus der globalen Variable verwenden\nvar kalibrierungswert = global.get(\"calibration_value_y\") || 0; // Standardwert ist 0, falls nicht gesetzt\n\n// Anpassen der Daten um den Kalibrierungswert\nvar datenMitKalibrierung = eingangsdaten - kalibrierungswert;\n\n// Auf eine Dezimalstelle runden\nvar gerundeteDaten = datenMitKalibrierung.toFixed(1); // 1 steht für eine Dezimalstelle\n\n// Wenn der gerundete Wert 0 ist, auf \"0.0\" ändern\nif (Number(gerundeteDaten) === 0) {\n    gerundeteDaten = \"0.0\";\n}\n\n// Weiterleiten der modifizierten und gerundeten Daten\nmsg.payload = parseFloat(gerundeteDaten); // Als Zahl statt String zurückgeben\n\nreturn msg;\n\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1410,"y":360,"wires":[["b848e084c8135cb7","eb0e4d09392a8a43"]]},{"id":"02a45f9f766e8ed7","type":"smooth","z":"3739bebe6c778cd3","name":"","property":"payload","action":"mean","count":"2","round":"1","mult":"single","reduce":false,"x":1220,"y":360,"wires":[["e46980325aa122bc"]]},{"id":"1f78a9c366e84c7e","type":"ui_template","z":"3739bebe6c778cd3","group":"f89e1392760d829e","name":"IMG NICK","order":1,"width":6,"height":4,"format":"\n\n<div style='width:100%; height:100%; display:flex; justify-content:center; align-items:center;'>\n    <div id='image-container' style='position: relative;'>\n        <img id='image-to-rotate' src='http://pekaway.local/images/van_side' style='transform: rotate({{msg.payload}}deg);' />\n        <div id='line'\n            style='position: absolute; width: 100%; height: 3px; background-color: grey; top: 96%; transform: translateY(-50%); z-index: -1;'>\n        </div>\n    </div>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":2130,"y":400,"wires":[[]]},{"id":"b848e084c8135cb7","type":"function","z":"3739bebe6c778cd3","name":"Rotate Image","func":"// Erhalten der Winkelinformation (z. B. über MQTT)\nvar angle = msg.payload; // Der Rotationswinkel in Grad\n\n// Wert des Payloads verdoppeln\nmsg.deg = msg.payload * 3;\n\n// CSS-Transformation zur Rotation des Bilds\nvar transformation = \"rotate(\" + msg.deg + \"deg)\";\n\n// Senden Sie die Transformation zurück\nmsg.ui_control = {\n    \"angular\": true,\n    \"rotate\": transformation\n};\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1620,"y":360,"wires":[[]]},{"id":"dba3eb11dced800d","type":"ui_text","z":"3739bebe6c778cd3","group":"f89e1392760d829e","order":2,"width":6,"height":1,"name":"Winkel Nick","label":"","format":"← {{msg.payload}} →","layout":"row-center","className":"","x":1910,"y":360,"wires":[]},{"id":"dcb2407493d93563","type":"ui_template","z":"3739bebe6c778cd3","group":"","name":"Stylesheet Winkel","order":5,"width":0,"height":0,"format":"<style>\n[node-id=\"3409d4236d412e95\"] .value {\nfont-size: 2.9em;\nfont-weight: 100;\n}\n\n</style>\n\n\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","className":"","x":2110,"y":360,"wires":[[]]},{"id":"7689c36c4b4dc602","type":"ui_button","z":"3739bebe6c778cd3","name":"Start Calibration","group":"f89e1392760d829e","order":5,"width":6,"height":1,"passthru":true,"label":"Calibrate position sensor","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"start_calibration","payloadType":"str","topic":"start_calibration","topicType":"str","x":240,"y":180,"wires":[["736e6e74dd4099c1","7625b64c194676df","ea251b4e38d7ad0e","295e95de4318d1b8","8d6625f941a1734f"]]},{"id":"736e6e74dd4099c1","type":"function","z":"3739bebe6c778cd3","name":"Kalibrierungsfunktion X","func":"// Variablen für die Kalibrierung\nlet calibrationDatax = context.get(\"calibrationData_x\") || [];\nlet timer = context.get(\"timer\") || null;\n\n// Startet die Kalibrierung bei einer Nachricht vom Button\nif (msg.topic === \"start_calibration\" && !timer) {\n    calibrationDatax = [];\n    context.set(\"calibrationData_x\", calibrationDatax);\n\n    timer = setTimeout(() => {\n        let sum = calibrationDatax.reduce((a, b) => a + b, 0);\n        let avg = calibrationDatax.length > 0 ? sum / calibrationDatax.length : 0;\n        global.set(\"calibration_value_x\", avg); // Speichert das Ergebnis in der globalen Variable\n        context.set(\"timer\", null);\n        node.send({ payload: avg });\n    }, 5000); // Kalibrierungszeitraum: 5 Sekunden\n\n    context.set(\"timer\", timer);\n    return;\n}\n\n// Sammelt Daten, wenn eine Nachricht vom Sensor empfangen wird\nif (msg.topic === \"x_angle\"&& timer) {\n    let value = parseFloat(msg.payload);\n    if (!isNaN(value)) {\n        calibrationDatax.push(value);\n        context.set(\"calibrationData_x\", calibrationDatax);\n    }\n}\n\nreturn null; // Sendet keine Nachricht, bis der Timer abläuft\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1250,"y":140,"wires":[[]]},{"id":"7625b64c194676df","type":"function","z":"3739bebe6c778cd3","name":"Kalibrierungsfunktion Y","func":"// Variablen für die Kalibrierung\nlet calibrationData = context.get(\"calibrationData_y\") || [];\nlet timer = context.get(\"timer\") || null;\n\n// Startet die Kalibrierung bei einer Nachricht vom Button\nif (msg.topic === \"start_calibration\" && !timer) {\n    calibrationData = [];\n    context.set(\"calibrationData_y\", calibrationData);\n\n    timer = setTimeout(() => {\n        let sum = calibrationData.reduce((a, b) => a + b, 0);\n        let avg = calibrationData.length > 0 ? sum / calibrationData.length : 0;\n        global.set(\"calibration_value_y\", avg); // Speichert das Ergebnis in der globalen Variable\n        context.set(\"timer\", null);\n        node.send({ payload: avg });\n    }, 5000); // Kalibrierungszeitraum: 5 Sekunden\n\n    context.set(\"timer\", timer);\n    return;\n}\n\n// Sammelt Daten, wenn eine Nachricht vom Sensor empfangen wird\nif (msg.topic === \"y_angle\" && timer) {\n    let value = parseFloat(msg.payload);\n    if (!isNaN(value)) {\n        calibrationData.push(value);\n        context.set(\"calibrationData_y\", calibrationData);\n    }\n}\n\nreturn null; // Sendet keine Nachricht, bis der Timer abläuft\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1250,"y":180,"wires":[["de3b646ac20702e7"]]},{"id":"e1981fc3d5bd5dcd","type":"ui_toast","z":"3739bebe6c778cd3","position":"top right","displayTime":"5","highlight":"","sendall":false,"outputs":0,"ok":"OK","cancel":"","raw":false,"className":"","topic":"","name":"","x":690,"y":100,"wires":[]},{"id":"ea251b4e38d7ad0e","type":"function","z":"3739bebe6c778cd3","name":"calibrating...","func":"msg.payload = \"Calibrating position sensor...\"\ndelete msg.topic\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":140,"wires":[["e1981fc3d5bd5dcd"]]},{"id":"eaf79c9ddd746cfb","type":"ui_template","z":"3739bebe6c778cd3","group":"f89e1392760d829e","name":"IMG ROLL","order":3,"width":6,"height":4,"format":"\n\n<div style='width:100%; height:100%; display:flex; justify-content:center; align-items:center;'>\n    <div id='image-container' style='position: relative;'>\n        <img id='image-to-rotate' src='http://pekaway.local/images/van_back' style='transform: rotate({{msg.deg}}deg);' />\n        <div id='line'\n            style='position: absolute; width: 100%; height: 3px; background-color: grey; top: 96%; transform: translateY(-50%); z-index: -1;'>\n        </div>\n    </div>\n</div>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":2130,"y":260,"wires":[[]]},{"id":"5d2e0c6b945bb6ca","type":"function","z":"3739bebe6c778cd3","name":"Rotate Image","func":"// Erhalten der Winkelinformation (z. B. über MQTT)\nvar angle = msg.payload; // Der Rotationswinkel in Grad\n\n// Wert des Payloads verdoppeln\nmsg.deg = msg.payload * 3;\n\n// CSS-Transformation zur Rotation des Bilds\nvar transformation = \"rotate(\" + msg.deg + \"deg)\";\n\n// Senden Sie die Transformation zurück\nmsg.ui_control = {\n    \"angular\": true,\n    \"rotate\": transformation\n};\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1620,"y":300,"wires":[[]]},{"id":"3fbb529e13212092","type":"ui_text","z":"3739bebe6c778cd3","group":"f89e1392760d829e","order":4,"width":6,"height":1,"name":"Winkel ROLL","label":"","format":"← {{msg.payload}} →","layout":"row-center","className":"","x":1930,"y":300,"wires":[]},{"id":"0eb6abde1cefb6f2","type":"ui_template","z":"3739bebe6c778cd3","group":"","name":"Stylesheet Winkel","order":5,"width":0,"height":0,"format":"<style>\n[node-id=\"b0736d584b4ecc68\"] .value {\nfont-size: 2.9em;\nfont-weight: 100;\n}\n\n</style>\n\n\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","className":"","x":2110,"y":300,"wires":[[]]},{"id":"e661be93174a3c06","type":"exec","z":"3739bebe6c778cd3","command":"python3 pekaway/mpu_py/mpuAngle.py","addpay":"payload","append":"","useSpawn":"true","timer":"","winHide":false,"oldrc":false,"name":"mpuAngle.py","x":670,"y":280,"wires":[["d793139abfd73467"],[],[]]},{"id":"d793139abfd73467","type":"json","z":"3739bebe6c778cd3","name":"","property":"payload","action":"","pretty":false,"x":850,"y":280,"wires":[["b5902b221bf2671b","215de84e496cf31f"]]},{"id":"b5902b221bf2671b","type":"function","z":"3739bebe6c778cd3","name":"filter values","func":"let msgX = {}\nlet msgY = {}\nlet msgT = {}\nmsgX.payload = Number(msg.payload.x_angle);\nmsgX.topic = \"x_angle\";\n//node.send([msg, null, null])\nmsgY.payload = Number(msg.payload.y_angle);\nmsgY.topic = \"y_angle\";\n//node.send([null, msg, null])\nmsgT.payload = msg.payload.mpu_temp.toFixed(1);\n//node.send([null, null, msg])\nreturn [msgX, msgY, msgT]","outputs":3,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1010,"y":280,"wires":[["736e6e74dd4099c1","99c6d65d1486302f"],["7625b64c194676df","02a45f9f766e8ed7"],[]]},{"id":"de3b646ac20702e7","type":"function","z":"3739bebe6c778cd3","name":"kill then => time 5","func":"msg.kill = \"SIGKILL\";\nnode.send(msg);\n\nsetTimeout(function () {\n    delete msg.kill;\n    msg.payload = \"--time 5\";\n    node.send(msg);\n}, 500);  // milliseconds delay","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1470,"y":180,"wires":[["e661be93174a3c06"]]},{"id":"215de84e496cf31f","type":"debug","z":"3739bebe6c778cd3","name":"debug 98","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1000,"y":320,"wires":[]},{"id":"9405f0312e7b530c","type":"function","z":"3739bebe6c778cd3","name":"time 5","func":"delete msg.kill\nmsg.payload = \"--time 5\"\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1130,"y":520,"wires":[["c72e374c3e18cf30"]]},{"id":"295e95de4318d1b8","type":"function","z":"3739bebe6c778cd3","name":"kill then => time 0.5","func":"msg.kill = \"SIGKILL\";\nnode.send(msg);\n\nsetTimeout(function () {\n    delete msg.kill;\n    msg.payload = \"--time 0.5\";\n    node.send(msg);\n}, 1000);  // milliseconds delay","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":470,"y":200,"wires":[["e661be93174a3c06"]]},{"id":"8d6625f941a1734f","type":"delay","z":"3739bebe6c778cd3","name":"5.3s","pauseType":"delay","timeout":"5.3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":390,"y":100,"wires":[["ef2c0086391012ae"]]},{"id":"ef2c0086391012ae","type":"function","z":"3739bebe6c778cd3","name":"done","func":"msg.payload = \"Calibration done\"\ndelete msg.topic\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":100,"wires":[["e1981fc3d5bd5dcd"]]},{"id":"2f39cbd1b882b3e5","type":"inject","z":"3739bebe6c778cd3","name":"","props":[{"p":"payload"},{"p":"name","v":"Position Sensor","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":"15","topic":"","payload":"","payloadType":"date","x":130,"y":540,"wires":[["2c56fd6e65d34c56"]]},{"id":"e3cd1d26208cb692","type":"exec","z":"3739bebe6c778cd3","command":"","addpay":"payload","append":"","useSpawn":"false","timer":"","winHide":false,"oldrc":false,"name":"","x":510,"y":540,"wires":[["28d29a321847e02c"],[],[]]},{"id":"2c56fd6e65d34c56","type":"function","z":"3739bebe6c778cd3","name":"check processes","func":"delete msg.reset\nmsg.payload = \"ps aux | grep mpuAngle\"\nreturn msg","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":540,"wires":[["e3cd1d26208cb692"]]},{"id":"28d29a321847e02c","type":"split","z":"3739bebe6c778cd3","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":630,"y":540,"wires":[["e88f4ba0f4d1d09e"]]},{"id":"e88f4ba0f4d1d09e","type":"function","z":"3739bebe6c778cd3","name":"kill?","func":"if (msg.payload.includes(\"mpuAngle.py --time\")) {\n    const match = msg.payload.match(/\\b\\w+\\s+(\\d+)/)\n    msg.pid = match ? parseInt(match[1], 10) : null\n    if (msg.pid == null) {\n        return [msg, null]\n    }\n    else {\n        msg.kill = \"SIGKILL\";\n        // msg.payload = \"sudo pkill -f 'python3.*mpuAngle.py.*'\"\n        return [msg, msg]\n    }\n}\nelse return [msg, null ]","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":750,"y":540,"wires":[["0123f1a21f90df33"],["8efd01a8cc1df5c1"]]},{"id":"0123f1a21f90df33","type":"delay","z":"3739bebe6c778cd3","name":"","pauseType":"rate","timeout":"0.1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"2","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":940,"y":520,"wires":[["9405f0312e7b530c"]]},{"id":"526759393f6f5f68","type":"ui_button","z":"3739bebe6c778cd3","name":"Start reading","group":"f89e1392760d829e","order":5,"width":6,"height":1,"passthru":true,"label":"Start reading values","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"start_fast_read","payloadType":"str","topic":"","topicType":"str","x":230,"y":280,"wires":[["339615045b1bfa7f","8d848d0e113ab89e"]]},{"id":"339615045b1bfa7f","type":"function","z":"3739bebe6c778cd3","name":"kill then => time 0.25","func":"msg.kill = \"SIGKILL\";\nnode.send(msg);\n\nsetTimeout(function () {\n    delete msg.kill;\n    msg.payload = \"--time 0.25\";\n    node.send(msg);\n}, 500);  // milliseconds delay","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":440,"y":280,"wires":[["e661be93174a3c06","c24897059bbc9fcb"]]},{"id":"c645aa409e021565","type":"ui_button","z":"3739bebe6c778cd3","name":"Stop reading","group":"f89e1392760d829e","order":5,"width":6,"height":1,"passthru":true,"label":"Stop reading values","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"stop_fast_read","payloadType":"str","topic":"","topicType":"str","x":230,"y":380,"wires":[["a25b0d3ed530fb58"]]},{"id":"a25b0d3ed530fb58","type":"function","z":"3739bebe6c778cd3","name":"reset","func":"\nmsg.reset = true\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":390,"y":380,"wires":[["2c56fd6e65d34c56","8d848d0e113ab89e"]]},{"id":"c72e374c3e18cf30","type":"delay","z":"3739bebe6c778cd3","name":"2s","pauseType":"delay","timeout":"3","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":1290,"y":520,"wires":[["e661be93174a3c06"]]},{"id":"6619f21f66ccc3a3","type":"link in","z":"3739bebe6c778cd3","name":"positionSensor start","links":["44b78f2a6ec1dafb"],"x":115,"y":280,"wires":[["526759393f6f5f68"]]},{"id":"be30fa7396b2172a","type":"link in","z":"3739bebe6c778cd3","name":"positionSensor stop","links":["ebdf10e1d4ee8666"],"x":115,"y":380,"wires":[["c645aa409e021565"]]},{"id":"4845fbb606ccbbb6","type":"ui_ui_control","z":"3739bebe6c778cd3","name":"","events":"all","x":220,"y":420,"wires":[["91b91b7cc974da25","1f9e364f2c365707"]]},{"id":"91b91b7cc974da25","type":"function","z":"3739bebe6c778cd3","name":"check tab","func":"if (msg.name != \"Position Sensor\" && flow.get(\"tabname\") == \"Position Sensor\") {\n    node.send(msg);\n}\nflow.set(\"tabname\", msg.name);","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":400,"y":420,"wires":[["2c56fd6e65d34c56"]]},{"id":"1f9e364f2c365707","type":"function","z":"3739bebe6c778cd3","name":"check tab","func":"if (msg.payload == \"change\" && msg.name == \"Position Sensor\") {\n    msg.reset = true\n    return msg;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":240,"y":320,"wires":[["339615045b1bfa7f"]]},{"id":"7b0d6cce040ff728","type":"comment","z":"3739bebe6c778cd3","name":"mpuAngle.py running with 5s when tab not opened","info":"","x":230,"y":500,"wires":[]},{"id":"e7b8b47f1654f01f","type":"comment","z":"3739bebe6c778cd3","name":"mpuAngle.py running with 0.5s when tab active","info":"","x":320,"y":240,"wires":[]},{"id":"eb0e4d09392a8a43","type":"range","z":"3739bebe6c778cd3","minin":"-45","maxin":"45","minout":"-10","maxout":"10","action":"scale","round":false,"property":"payload","name":"","x":1600,"y":400,"wires":[["4f3b8fba418c2d7d"]]},{"id":"4f3b8fba418c2d7d","type":"function","z":"3739bebe6c778cd3","name":"function 5","func":"msg.payload = Number(msg.payload.toFixed(1))*-1;\nglobal.set(\"y_angle\", msg.payload)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1740,"y":400,"wires":[["5fc2a31f4d9810ef","dba3eb11dced800d"]]},{"id":"5fc2a31f4d9810ef","type":"function","z":"3739bebe6c778cd3","name":"Rotate Image","func":"// Erhalten der Winkelinformation (z. B. über MQTT)\nvar angle = msg.payload; // Der Rotationswinkel in Grad\n\n// Wert des Payloads verdoppeln\nmsg.deg = msg.payload * 4;\n\n// CSS-Transformation zur Rotation des Bilds\nvar transformation = \"rotate(\" + msg.deg + \"deg)\";\n\n// Senden Sie die Transformation zurück\nmsg.ui_control = {\n    \"angular\": true,\n    \"rotate\": transformation\n};\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1920,"y":400,"wires":[["1f78a9c366e84c7e","dba3eb11dced800d"]]},{"id":"eb2be90032ddbb37","type":"range","z":"3739bebe6c778cd3","minin":"-45","maxin":"45","minout":"-10","maxout":"10","action":"scale","round":false,"property":"payload","name":"","x":1600,"y":260,"wires":[["b834a73edcc9df3a"]]},{"id":"b834a73edcc9df3a","type":"function","z":"3739bebe6c778cd3","name":"function 6","func":"msg.payload = Number(msg.payload.toFixed(1));\nglobal.set(\"x_angle\", msg.payload)\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1760,"y":260,"wires":[["4c75eab53d356616","3fbb529e13212092"]]},{"id":"4c75eab53d356616","type":"function","z":"3739bebe6c778cd3","name":"Rotate Image","func":"// Erhalten der Winkelinformation (z. B. über MQTT)\nvar angle = msg.payload; // Der Rotationswinkel in Grad\n\n// Wert des Payloads verdoppeln\nmsg.deg = msg.payload * 4;\n\n// CSS-Transformation zur Rotation des Bilds\nvar transformation = \"rotate(\" + msg.deg + \"deg)\";\n\n// Senden Sie die Transformation zurück\nmsg.ui_control = {\n    \"angular\": true,\n    \"rotate\": transformation\n};\n\nreturn msg;\n","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1940,"y":260,"wires":[["eaf79c9ddd746cfb","3fbb529e13212092"]]},{"id":"8d848d0e113ab89e","type":"delay","z":"3739bebe6c778cd3","name":"5m","pauseType":"delay","timeout":"5","timeoutUnits":"minutes","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":390,"y":320,"wires":[["a674e27aa3a674b7"]]},{"id":"a674e27aa3a674b7","type":"delay","z":"3739bebe6c778cd3","name":"1msg/5m","pauseType":"rate","timeout":"0.1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"5","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":520,"y":320,"wires":[["2c56fd6e65d34c56"]]},{"id":"c24897059bbc9fcb","type":"debug","z":"3739bebe6c778cd3","name":"debug 113","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":690,"y":220,"wires":[]},{"id":"8efd01a8cc1df5c1","type":"delay","z":"3739bebe6c778cd3","name":"1msg/0.3s","pauseType":"rate","timeout":"0.1","timeoutUnits":"seconds","rate":"1","nbRateUnits":"0.3","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":true,"allowrate":false,"outputs":1,"x":910,"y":560,"wires":[["c237ca3c3d06f36d"]]},{"id":"c237ca3c3d06f36d","type":"function","z":"3739bebe6c778cd3","name":"set cmd","func":"delete msg.kill\ndelete msg.pid\nmsg.payload = \"/usr/bin/sudo pkill -f \\'python3.\\*mpuAngle.py\\'\"\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1140,"y":560,"wires":[["9c8fa4b038815cd0"]]},{"id":"9c8fa4b038815cd0","type":"exec","z":"3739bebe6c778cd3","command":"","addpay":"payload","append":"","useSpawn":"false","timer":"2.5","winHide":false,"oldrc":false,"name":"kill mpuAngle.py","x":1320,"y":560,"wires":[[],[],[]]},{"id":"a32a3d5947c57eb9","type":"link in","z":"3739bebe6c778cd3","name":"positionSensor calibrate","links":["46505864c3d9e739"],"x":115,"y":180,"wires":[["7689c36c4b4dc602"]]},{"id":"f89e1392760d829e","type":"ui_group","name":"NICK","tab":"44c44161193a7be6","order":1,"disp":false,"width":"6","collapse":false,"className":""},{"id":"44c44161193a7be6","type":"ui_tab","name":"Position Sensor","icon":"fa-arrows","order":4,"disabled":false,"hidden":false}]

Die drei Link-In Nodes

werden mit den Link-Out Nodes im HTTP-Api Flow verbunden (von oben nach unten):

Das Python Script dazu sieht folgendermaßen aus:

import smbus
import math
import time
import json
import argparse

# MPU6050 Registers
MPU6050_ADDR = 0x69
MPU6050_PWR_MGMT_1 = 0x6B
MPU6050_TEMP_OUT_H = 0x41
MPU6050_TEMP_OUT_L = 0x42
MPU6050_ACCEL_XOUT_H = 0x3B
MPU6050_ACCEL_YOUT_H = 0x3D
MPU6050_ACCEL_ZOUT_H = 0x3F
MPU6050_GYRO_XOUT_H = 0x43
MPU6050_GYRO_YOUT_H = 0x45
MPU6050_GYRO_ZOUT_H = 0x47

# Configuration
bus = smbus.SMBus(1)  # or 0 for RPi 1
bus.write_byte_data(MPU6050_ADDR, MPU6050_PWR_MGMT_1, 0)

def read_raw_data(addr):
    high = bus.read_byte_data(MPU6050_ADDR, addr)
    low = bus.read_byte_data(MPU6050_ADDR, addr + 1)
    value = (high << 8) | low
    if value > 32768:
        value -= 65536
    return value

def get_temp():
    raw_temp = read_raw_data(MPU6050_TEMP_OUT_H)
    temp = (raw_temp / 340.0) + 36.53  # Temperature formula for MPU6050
    return temp

def get_accel_data():
    accel_xout = read_raw_data(MPU6050_ACCEL_XOUT_H)
    accel_yout = read_raw_data(MPU6050_ACCEL_YOUT_H)
    accel_zout = read_raw_data(MPU6050_ACCEL_ZOUT_H)
    return accel_xout, accel_yout, accel_zout

def get_gyro_data():
    gyro_xout = read_raw_data(MPU6050_GYRO_XOUT_H)
    gyro_yout = read_raw_data(MPU6050_GYRO_YOUT_H)
    gyro_zout = read_raw_data(MPU6050_GYRO_ZOUT_H)
    return gyro_xout, gyro_yout, gyro_zout
    
def parse_args():
    parser = argparse.ArgumentParser(description="MPU6050 Data Logger")
    parser.add_argument("--time", type=float, default=1, help="Sleep time in seconds (default: 1)")
    return parser.parse_args()

args = parse_args()

while True:
    temp = get_temp()
    accel_x, accel_y, accel_z = get_accel_data()
    gyro_x, gyro_y, gyro_z = get_gyro_data()
    
    x_angle = math.atan(accel_x / 16384.0) * (180 / math.pi)
    y_angle = math.atan(accel_y / 16384.0) * (180 / math.pi)
    
    data = {
        "x_angle": x_angle,
        "y_angle": y_angle,
        "accel_x_raw": accel_x,
        "accel_y_raw": accel_y,
        "accel_z_raw": accel_z,
        "gyro_x_raw": gyro_x,
        "gyro_y_raw": gyro_y,
        "gyro_z_raw": gyro_z,
        "mpu_temp": temp
    }
    
    print(json.dumps(data))
    
    time.sleep(args.time)

Das Script muss den folgenden Pfad haben: /home/pi/pekaway/mpu_py/mpuAngle.py

(An dieser Stelle übrigens auch ein Dankeschön an @Bock.auf.Raus :slight_smile: )

In der App könnt ihr eure eigenen Bilder für den Lagesensor einstellen (nur bei einer lokalen Verbindung), diese Bilder müssen ebenfalls in den Ordner wie das Python Script und die Namen van_back.png und van_side.png haben.

Um die Bilder laden zu können, muss Nginx noch leicht angepasst werden, der Serverblock sieht jetzt folgendermaßen aus (/etc/nginx/sites-available/pekaway1):

server {
	listen 80;
	 server_name peka.way van.pi pekaway.local;
	
	 location / {
		 proxy_pass http://127.0.0.1:1880/ui/;
	}
	location /autoexec.be {
		alias /home/pi/pekaway/autoexec.be; 
		add_header Content-Disposition 'attachment; filename="autoexec.be"';
	}
	location /nspaneltft {	
		alias /home/pi/pekaway/VanPI_NSPANEL.tft; 
		add_header Content-Disposition 'attachment; filename="VanPI_NSPANEL.tft"';
	}
	 location /images/van_side { 
		alias /home/pi/pekaway/mpu_py/van_side.png;
	}
	location /images/van_back {
	alias /home/pi/pekaway/mpu_py/van_front.png;
	}
}

server {
	listen 80;
	server_name homebridge.peka.way;

	 location / {
		proxy_pass http://127.0.0.1:8581/;
	}
}

server {
	listen 80 default_server; 
	listen [::]:80 default_server;
	server_name _;
	
	        
         location /images/van_side {
                alias /home/pi/pekaway/mpu_py/van_side.png;
        }
        location /images/van_back {
        alias /home/pi/pekaway/mpu_py/van_back.png;
        }

	
	# Redirect all requests to pekaway.local
	#return 301 $scheme://pekaway.local$request_uri;
}

Nicht vergessen Nginx neuzustarten:

sudo systemctl restart nginx

Ich hoffe ich habe nichts vergessen…
Zu guter Letzt habt ihr hier nochmal die kompletten Flows (also alle, nicht nur die genannten) als Download (Datei umbenennen und Node-RED neustarten):

Diese Flows haben aber Entwicklungsstatus, sind nicht clean und können Fehler und Bugs enthalten!

Dazu noch folgende Infos:

Ihr könnt ganz einfach mehr Temperatursensoren, Wasserlevel, Relays und DImmer hinzufügen. Hier mal am Beispiel der Relays.
Im Bild seht ihr wie die Daten vorbereitet sind, damit die App sie verarbeiten kann.

Dort könnt ihr jetzt einfach mehr Relays hinzufügen, indem ihr das ganze erweitert:

In dem JSON, was zur App geschickt wird muss aber alles passen, also Kommas etc. Sobald das Format kein gültiges JSON ist zeigt die App nichts an.

1 Like

Für alle die einen mpu6050 anschließen, der mpu6050 hat ohne + auf AD0 die Adresse 68. Im Script wird auf die Adress 69 zugreifen. Also AD0 mit + belegen
Gruß Arno

1 Like

Sehr gut Arno, Test bestanden :smiley:

Hallo Vincent
ich hätte da einen Verbesserungsvorschlag
Die Namen der Sensoren in den vordergrund rücken, und direkt unter die Zahl.
so wie du das bei den Dimmern gemacht hast.
Und im Heizungs Bild die Temperatur einblenden die ausgewählt wurde.

gefällt mir immer besser die App :wink:
Und wenn es noch einen GPS Alarm in der App gibt :+1: :+1:
Gruß Arno

Hallo Arno

Sehe ich das Richtig das man die Heizung nur auf Temperatur und Laufzeit laufen lassen kann ?

Gibt es den Powermodus nicht mehr oder ist dieser anders Hinterlegt und man muss ihr aktivieren ?

Wollte mich die Tage auch an die App machen um sie am laufen zu bekommen bis dann das neue Board hier ist.

Moin Sascha
Du weißt doch, das Projekt lebt!!!
Der ein oder andere Vorschlag kommt sicher noch rein.
Rom ist auch nicht an einem Tag erbaut :joy:
Gruß Arno

@ahtdf hatte halt nur mal so durch die App geschaut und dein Bild gesehen und da ist mir aufgefallen das halt kein Powermodus angezeigt wird.

Wäre auf jedenfall wieder wichtig für das kommende Projekt.
Werde dann das RelaisBoard im Kleinen Van lassen und das neue Board dann ins große Projekt einbauen.

Ich weiß halt nicht wo der Fehler bei mir liegt, das ich den Home Screen nicht bekomme, und der mpu6050 nicht funktioniert samt Webserver für die Bilder, ich hatte den mpu ja schon mal am laufen, halt mit einer anderen python datei.
@SaschaKorn
Webserver funktioniert jetzt. Schaust du hier

Was muss ich einstellen, um den Demo Modus der App (IOS) zu aktivieren?
Habe bereits Demo Daten laden gemacht, geht aber nicht…

Demo Modus weiß ich nicht, aber geh doch lokal auf dein System. Oder online wenn du internet hast.
Funktioniert zum Teil ohne das du im flow was machst.

Mein System ist alles für den Einbau vorbereitet, aber das dauert noch. Aktuell noch nicht online.
Ich dachte man geht mit den Demo Daten auf einen Demo Server, der im Internet erreichbar ist.

Aber egal, dann warte ich, bis ich online bin.

Das ist auch so, demodaten laden klicken, dann Speichern und Verbindung testen, dann zurück zu dem “Keine Verbindung”-Screen und erneut testen klicken.

Oder die App neustarten nachdem die Daten gespeichert wurden

Ok, nach dem Neustartbfunktioniert die Demo, prima.

Funktioniert die App it dem Relayboard und der IOT box?
Was würdet ihr empfehlen, soll ich machen, wenn der 2 Jahres Vertrag ausläuft ?

Lieber ein LTE Modem verwenden, so dass ich auch via VPN auf VanPi komme ?
Geht die App dann noch ?

Gruss, Stefan

Die App funktioniert nicht mit der “alten” IoT-Bridge. Dafür wird es eine neue Software geben, die du dann auf die Bridge flashen kannst.

Die App greift immer nur auf die Software zu, nicht auf die Hardware. Soll heißen, wenn die entsprechenden Endpunkte erreichbar sind und Daten zur Verfügung stellen, dann funktioniert die App.

Wenn du dein aktuelles System startest und die neue App lokal verbindest, dann wirst du sehen dass da bereits einige Daten reinkommen. Für alles andere wird die Software erweitert.

Stand jetzt ist, dass wir ein Image für den neuen Core bereitstellen. Der Großteil wird auch auf dem Relayboard funktionieren, es gibt dann aber einige neue Funktionen, die aufgrund der Hardwareänderung nicht funktionieren können, zum Beispiel der Lagesensor, der ist ja standardmäßig nicht vorhanden beim Relayboard.
Trotzdem kannst du das natürlich integrieren, wenn du die entsprechenden Anpassungen vornimmst. Wir werden versuchen so viel wie möglich als Tutorial bereitzustellen.

Wenn dein Handy per VPN verbunden ist und die die Route in der App entsprechend einstellst, dann sollte das funktionieren. Ist ja dann wie eine lokale Nutzung. Einige Sachen, wie zum Beispiel die Anzeige der Karte, braucht aber eine Internetverbindung. Also wenn dein Handy in dem Moment keine Internetverbindung hat, dann lädt die Karte nicht.

Ist es eigentlich angedacht die App auch für Carplay weiterzuentwickeln? Das würde sehr sehr nice sein!

War bis jetzt noch nicht angedacht, aber kann mir sehr gut vorstellen dass das ein interessantes Feature wäre.
Hab mich noch nie mit Apple Carplay und Android Auto beschäftigt, aber kann ja nicht so schwer sein :smiley: :sweat_smile:
Mal schauen was sich da machen lässt, versprechen kann ich es erstmal noch nicht.