[ { "id": "a41c86b8.0e9e48", "type": "tab", "label": "PoolControlFlow", "disabled": false, "info": "" }, { "id": "74956623.f66a88", "type": "serial in", "z": "a41c86b8.0e9e48", "name": "ArduinoSerialGet", "serial": "2df3db69.684484", "x": 114, "y": 56, "wires": [ [ "b9aaa5da.9ee928" ] ] }, { "id": "21ead4cf.59b55c", "type": "ui_gauge", "z": "a41c86b8.0e9e48", "name": "", "group": "9be6d274.9dd69", "order": 0, "width": 0, "height": 0, "gtype": "gage", "title": "", "label": "", "format": "{{value}}", "min": 0, "max": "120", "colors": [ "#ca3838", "#e6e600", "#00b500" ], "seg1": "34", "seg2": "70", "x": 573, "y": 87, "wires": [] }, { "id": "c0b753e1.f5d7a", "type": "ui_gauge", "z": "a41c86b8.0e9e48", "name": "AirTemp", "group": "a85a0c1d.bc66f", "order": 0, "width": 0, "height": 0, "gtype": "gage", "title": "", "label": "", "format": "{{value}}", "min": 0, "max": "120", "colors": [ "#ca3838", "#e6e600", "#00b500" ], "seg1": "34", "seg2": "70", "x": 579, "y": 181, "wires": [] }, { "id": "b9aaa5da.9ee928", "type": "switch", "z": "a41c86b8.0e9e48", "name": "SerialMsgRouter", "property": "payload", "propertyType": "msg", "rules": [ { "t": "cont", "v": "H2O", "vt": "str" }, { "t": "cont", "v": "AIR", "vt": "str" } ], "checkall": "false", "repair": false, "outputs": 2, "x": 148, "y": 141, "wires": [ [ "5ea6cacd.ae6894" ], [ "808f3f4f.f4974" ] ] }, { "id": "5ea6cacd.ae6894", "type": "change", "z": "a41c86b8.0e9e48", "name": "H2Ovalue", "rules": [ { "t": "change", "p": "payload", "pt": "msg", "from": "H2O:([0-9]+)", "fromt": "re", "to": "$1", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 361, "y": 73, "wires": [ [ "21ead4cf.59b55c", "6732f3e.a6ede0c" ] ] }, { "id": "808f3f4f.f4974", "type": "change", "z": "a41c86b8.0e9e48", "name": "AIRvalue", "rules": [ { "t": "change", "p": "payload", "pt": "msg", "from": "AIR:", "fromt": "str", "to": "", "tot": "str" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 361, "y": 159, "wires": [ [ "c0b753e1.f5d7a", "569aa4ee.e07bfc" ] ] }, { "id": "8c064a13.979908", "type": "ui_dropdown", "z": "a41c86b8.0e9e48", "name": "", "label": "Off/Pool/Spa", "place": "Off", "group": "fc434b8d.100268", "order": 1, "width": 0, "height": 0, "passthru": false, "options": [ { "label": "", "value": "Off", "type": "str" }, { "label": "", "value": "Pool", "type": "str" }, { "label": "", "value": "Spa", "type": "str" } ], "payload": "", "topic": "", "x": 103.11111450195312, "y": 478.6666669845581, "wires": [ [ "9461d958.58d2a8" ] ] }, { "id": "f56e4375.2fbeb", "type": "ui_numeric", "z": "a41c86b8.0e9e48", "name": "PoolTempSetting", "label": "Pool Setting", "group": "9be6d274.9dd69", "order": 0, "width": 0, "height": 0, "passthru": false, "topic": "PoolTempSetting", "format": "{{value}}", "min": "34", "max": "90", "step": 1, "x": 402.6666717529297, "y": 289.5555582046509, "wires": [ [ "eb670a3a.a3efb8" ] ] }, { "id": "dfb4f912.821e28", "type": "ui_numeric", "z": "a41c86b8.0e9e48", "name": "SpaTempSetting", "label": "Spa Setting", "group": "9be6d274.9dd69", "order": 0, "width": 0, "height": 0, "passthru": false, "topic": "SpaTempSetting", "format": "{{value}}", "min": "34", "max": "106", "step": 1, "x": 410.11112213134766, "y": 393.3333435058594, "wires": [ [ "50285fa1.2e8dc" ] ] }, { "id": "f86a95ef.f7f198", "type": "inject", "z": "a41c86b8.0e9e48", "name": "DefaultPoolTemperature", "topic": "", "payload": "84", "payloadType": "num", "repeat": "", "crontab": "", "once": true, "onceDelay": 0.1, "x": 162.7777862548828, "y": 251.6666660308838, "wires": [ [ "f56e4375.2fbeb", "eb670a3a.a3efb8" ] ] }, { "id": "62c17999.f907e8", "type": "inject", "z": "a41c86b8.0e9e48", "name": "DefaultSpaTemperature", "topic": "", "payload": "100", "payloadType": "num", "repeat": "", "crontab": "", "once": true, "onceDelay": 0.1, "x": 165.66665649414062, "y": 352.9999752044678, "wires": [ [ "dfb4f912.821e28", "50285fa1.2e8dc" ] ] }, { "id": "bf1890da.372dd", "type": "ui_switch", "z": "a41c86b8.0e9e48", "name": "", "label": "Light", "group": "fc434b8d.100268", "order": 4, "width": 0, "height": 0, "passthru": true, "decouple": "false", "topic": "", "style": "", "onvalue": "true", "onvalueType": "bool", "onicon": "", "oncolor": "", "offvalue": "false", "offvalueType": "bool", "officon": "", "offcolor": "", "x": 676, "y": 776, "wires": [ [ "4b3b5e96.0f13e" ] ] }, { "id": "dc829300.dcf6d", "type": "ui_switch", "z": "a41c86b8.0e9e48", "name": "", "label": "Blower", "group": "fc434b8d.100268", "order": 3, "width": 0, "height": 0, "passthru": true, "decouple": "false", "topic": "", "style": "", "onvalue": "true", "onvalueType": "bool", "onicon": "", "oncolor": "", "offvalue": "false", "offvalueType": "bool", "officon": "", "offcolor": "", "x": 671, "y": 607, "wires": [ [ "ae55c03e.bf3fd" ] ] }, { "id": "b8f3e1e.cd3822", "type": "ui_switch", "z": "a41c86b8.0e9e48", "name": "", "label": "Cleaner", "group": "fc434b8d.100268", "order": 2, "width": 0, "height": 0, "passthru": true, "decouple": "false", "topic": "", "style": "", "onvalue": "true", "onvalueType": "bool", "onicon": "", "oncolor": "", "offvalue": "false", "offvalueType": "bool", "officon": "", "offcolor": "", "x": 670.6666259765625, "y": 491.22222900390625, "wires": [ [ "93acdfe9.77de7" ] ] }, { "id": "162e8fec.3cd55", "type": "ui_switch", "z": "a41c86b8.0e9e48", "name": "", "label": "Heater Enable", "group": "fc434b8d.100268", "order": 5, "width": 0, "height": 0, "passthru": true, "decouple": "false", "topic": "", "style": "", "onvalue": "true", "onvalueType": "bool", "onicon": "", "oncolor": "", "offvalue": "false", "offvalueType": "bool", "officon": "", "offcolor": "", "x": 706, "y": 727, "wires": [ [ "c19d6c59.a3fcd" ] ] }, { "id": "9461d958.58d2a8", "type": "switch", "z": "a41c86b8.0e9e48", "name": "OffPoolSpaSwitcher", "property": "payload", "propertyType": "msg", "rules": [ { "t": "eq", "v": "Off", "vt": "str" }, { "t": "eq", "v": "Pool", "vt": "str" }, { "t": "eq", "v": "Spa", "vt": "str" } ], "checkall": "false", "repair": false, "outputs": 3, "x": 150, "y": 632, "wires": [ [ "9c7def88.a3431", "d05d78b0.7de578", "aa3913f1.22108" ], [ "b4786af7.3438a8", "306d5cae.a3bef4", "1dc5b69c.721c69", "aa3913f1.22108" ], [ "72fe70e4.62713", "530d7cfb.589c84", "386cad5b.807aa2", "aa3913f1.22108" ] ] }, { "id": "d05d78b0.7de578", "type": "template", "z": "a41c86b8.0e9e48", "name": "msgenabledfalse", "field": "enabled", "fieldType": "msg", "format": "handlebars", "syntax": "plain", "template": "false", "output": "json", "x": 405.5555419921875, "y": 546, "wires": [ [ "b8f3e1e.cd3822", "dc829300.dcf6d" ] ] }, { "id": "b4786af7.3438a8", "type": "template", "z": "a41c86b8.0e9e48", "name": "msgenabledtrue", "field": "enabled", "fieldType": "msg", "format": "handlebars", "syntax": "plain", "template": "true", "output": "json", "x": 376.88890075683594, "y": 639.111083984375, "wires": [ [ "b8f3e1e.cd3822" ] ] }, { "id": "9c7def88.a3431", "type": "template", "z": "a41c86b8.0e9e48", "name": "msgpayloadfalse", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template": "false", "output": "json", "x": 421.6666564941406, "y": 510.77777099609375, "wires": [ [ "b8f3e1e.cd3822", "dc829300.dcf6d" ] ] }, { "id": "72fe70e4.62713", "type": "template", "z": "a41c86b8.0e9e48", "name": "msgenabledtrue", "field": "enabled", "fieldType": "msg", "format": "handlebars", "syntax": "plain", "template": "true", "output": "json", "x": 418.7777404785156, "y": 860.333251953125, "wires": [ [ "dc829300.dcf6d" ] ] }, { "id": "530d7cfb.589c84", "type": "template", "z": "a41c86b8.0e9e48", "name": "msgenabledfalse", "field": "enabled", "fieldType": "msg", "format": "handlebars", "syntax": "plain", "template": "false", "output": "json", "x": 387.88885498046875, "y": 791.6666870117188, "wires": [ [ "b8f3e1e.cd3822" ] ] }, { "id": "306d5cae.a3bef4", "type": "template", "z": "a41c86b8.0e9e48", "name": "msgenabledfalse", "field": "enabled", "fieldType": "msg", "format": "handlebars", "syntax": "plain", "template": "false", "output": "json", "x": 402.33331298828125, "y": 674, "wires": [ [ "dc829300.dcf6d" ] ] }, { "id": "9cf94b7c.50bbd8", "type": "inject", "z": "a41c86b8.0e9e48", "name": "PoolControlHeartbeat", "topic": "", "payload": "", "payloadType": "date", "repeat": "2", "crontab": "", "once": false, "onceDelay": 0.1, "x": 171.66665649414062, "y": 906.9999961853027, "wires": [ [ "3197156a.8fba3a" ] ] }, { "id": "3197156a.8fba3a", "type": "function", "z": "a41c86b8.0e9e48", "name": "RelaySetter", "func": "const setBit = (num, position) => {\n let mask = 1 << position;\n return num | mask;\n}\n\nconst clearBit = (num, position) => {\n let mask = 1 << position;\n return num & ~mask;\n}\n\nvar buf = Buffer.alloc(1);\nbuf[0] = 0;\n\nif (\"Off\" == flow.get(\"PoolSpaMode\")) {\n // Pump Off\n buf[0] = clearBit(buf[0], 0);\n // Set valves to pool position\n buf[0] = clearBit(buf[0], 3);\n buf[0] = clearBit(buf[0], 4);\n} else if (\"Pool\" == flow.get(\"PoolSpaMode\")) {\n // Pump On\n buf[0] = setBit(buf[0], 0);\n // Set valves to pool position\n buf[0] = clearBit(buf[0], 3);\n buf[0] = clearBit(buf[0], 4);\n} else { // Spa\n // Pump On\n buf[0] = setBit(buf[0], 0);\n // Set valves to spa position\n buf[0] = setBit(buf[0], 3);\n buf[0] = setBit(buf[0], 4);\n}\nbuf[0] = (flow.get(\"LightOnOff\") ? setBit(buf[0], 1) : clearBit(buf[0], 1));\nbuf[0] = (flow.get(\"BlowerOnOff\") ? setBit(buf[0], 2) : clearBit(buf[0], 2));\nbuf[0] = (flow.get(\"CleanerOnOff\") ? setBit(buf[0], 5) : clearBit(buf[0], 5));\n\n// The heater should be turned on only if:\n// - the heater control is on\n// - the pump is on\n// - the temp is below the target value for the current mode\nif (flow.get(\"HeaterOnOff\")) {\n if (\"Off\" != flow.get(\"PoolSpaMode\")) {\n var tempSetting = 0;\n if (\"Pool\" == flow.get(\"PoolSpaMode\")) {\n tempSetting = flow.get(\"PoolTempSetting\");\n } else {\n tempSetting = flow.get(\"SpaTempSetting\");\n }\n var h2otemp = flow.get(\"H2OTemp\");\n if (h2otemp < tempSetting) {\n buf[0] = setBit(buf[0], 6);\n } else {\n buf[0] = clearBit(buf[0], 6);\n }\n }\n}\n\nmsg.payload = buf;\n\nreturn msg;", "outputs": 1, "noerr": 0, "x": 422.44446563720703, "y": 907.8889045715332, "wires": [ [ "c8cd02ce.3d6b8" ] ] }, { "id": "c8cd02ce.3d6b8", "type": "serial out", "z": "a41c86b8.0e9e48", "name": "ArduinoSerialSet", "serial": "2df3db69.684484", "x": 693.3333549499512, "y": 908.3333015441895, "wires": [] }, { "id": "93acdfe9.77de7", "type": "function", "z": "a41c86b8.0e9e48", "name": "CleanerSetter", "func": "flow.set(\"CleanerOnOff\", msg.payload);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 844.111083984375, "y": 490.22216796875, "wires": [ [] ] }, { "id": "ae55c03e.bf3fd", "type": "function", "z": "a41c86b8.0e9e48", "name": "BlowerSetter", "func": "flow.set(\"BlowerOnOff\", msg.payload);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 858, "y": 607.7777709960938, "wires": [ [] ] }, { "id": "c19d6c59.a3fcd", "type": "function", "z": "a41c86b8.0e9e48", "name": "HeaterSetter", "func": "flow.set(\"HeaterOnOff\", msg.payload);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 885.2221527099609, "y": 726.7777452468872, "wires": [ [] ] }, { "id": "4b3b5e96.0f13e", "type": "function", "z": "a41c86b8.0e9e48", "name": "LightSetter", "func": "flow.set(\"LightOnOff\", msg.payload);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 846.2222290039062, "y": 776.3333129882812, "wires": [ [] ] }, { "id": "386cad5b.807aa2", "type": "template", "z": "a41c86b8.0e9e48", "name": "msgpayloadfalse", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template": "false", "output": "json", "x": 402.111083984375, "y": 826.4443969726562, "wires": [ [ "b8f3e1e.cd3822" ] ] }, { "id": "1dc5b69c.721c69", "type": "template", "z": "a41c86b8.0e9e48", "name": "msgpayloadfalse", "field": "payload", "fieldType": "msg", "format": "handlebars", "syntax": "mustache", "template": "false", "output": "json", "x": 415.99993896484375, "y": 709.7776489257812, "wires": [ [ "dc829300.dcf6d" ] ] }, { "id": "aa3913f1.22108", "type": "function", "z": "a41c86b8.0e9e48", "name": "ModeSetter", "func": "flow.set(\"PoolSpaMode\", msg.payload);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 632.9998779296875, "y": 434.33331298828125, "wires": [ [] ] }, { "id": "eb670a3a.a3efb8", "type": "function", "z": "a41c86b8.0e9e48", "name": "PoolTempSetter", "func": "flow.set(\"PoolTempSetting\", msg.payload);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 611.9999847412109, "y": 253.8888702392578, "wires": [ [] ] }, { "id": "50285fa1.2e8dc", "type": "function", "z": "a41c86b8.0e9e48", "name": "SpaTempSetter", "func": "flow.set(\"SpaTempSetting\", msg.payload);\nreturn msg;", "outputs": 1, "noerr": 0, "x": 613.6666374206543, "y": 353.77774143218994, "wires": [ [] ] }, { "id": "6732f3e.a6ede0c", "type": "function", "z": "a41c86b8.0e9e48", "name": "H2OTempSetter", "func": "flow.set(\"H2OTemp\", parseInt(msg.payload, 10));\nreturn msg;", "outputs": 1, "noerr": 0, "x": 594.9999389648438, "y": 51.44444274902344, "wires": [ [] ] }, { "id": "569aa4ee.e07bfc", "type": "function", "z": "a41c86b8.0e9e48", "name": "AIRTempSetter", "func": "flow.set(\"AIRTemp\", parseInt(msg.payload, 10));\nreturn msg;", "outputs": 1, "noerr": 0, "x": 595.6666259765625, "y": 145.11109924316406, "wires": [ [] ] }, { "id": "a62ce62c.17b7e8", "type": "comment", "z": "a41c86b8.0e9e48", "name": "Off", "info": "", "x": 370, "y": 474, "wires": [] }, { "id": "2651def1.2afd22", "type": "comment", "z": "a41c86b8.0e9e48", "name": "Pool", "info": "", "x": 397, "y": 599, "wires": [] }, { "id": "34745ab6.e43bf6", "type": "comment", "z": "a41c86b8.0e9e48", "name": "Spa", "info": "", "x": 385, "y": 755, "wires": [] }, { "id": "2df3db69.684484", "type": "serial-port", "z": "", "serialport": "/dev/ttyUSB0", "serialbaud": "9600", "databits": "8", "parity": "none", "stopbits": "1", "newline": "\\n", "bin": "false", "out": "char", "addchar": false, "responsetimeout": "10000" }, { "id": "9be6d274.9dd69", "type": "ui_group", "z": "", "name": "Water Temperature", "tab": "fb3422ea.1e1b6", "order": 2, "disp": true, "width": "6", "collapse": false }, { "id": "a85a0c1d.bc66f", "type": "ui_group", "z": "", "name": "Air Temperature", "tab": "fb3422ea.1e1b6", "order": 3, "disp": true, "width": "6", "collapse": false }, { "id": "fc434b8d.100268", "type": "ui_group", "z": "", "name": "On Off", "tab": "fb3422ea.1e1b6", "order": 1, "disp": true, "width": "6", "collapse": false }, { "id": "fb3422ea.1e1b6", "type": "ui_tab", "z": "", "name": "Pool Control", "icon": "dashboard" } ]