Node-RED
Point 'n' Click workflow automation
Project started on November 01, 2021.Last updated on July 07, 2022.
...back to Smart Home overview
Node-RED is a great tool for visually creating workflows based on events. I use it in conjunction with my ESP-Env sensor and actor hardware and MQTT to automate my smart home.
I plan to extend these workflows as required when I add new hardware to my network.
Here is a simple setup that automatically switches lights in my bathroom according to the sun position, using node-red-contrib-sunevents. It allows forcing a temporary override via another MQTT topic, for a lightswitch. In the automatic, non-overridden mode it also includes presence detection using node-red-contrib-fritz. This is using the API of my Fritz!Box Router to check if specific MAC Addresses are connected to the WiFi network.
The fan in my window-less bathroom is kept on all the time for now. In the future I want to add movement sensors to the bathroom and integrate them into this logic, as well as the temperature / humidity sensors I already have in there. All these devices run my ESP-Env firmware.
And here are the flows for importing in Node-RED.
[
{
"id": "490116e54af5ff9a",
"type": "tab",
"label": "Bathroom Lights",
"disabled": false,
"info": "",
"env": []
},
{
"id": "74341bea93cc320d",
"type": "tab",
"label": "Bathroom Fan",
"disabled": false,
"info": "",
"env": []
},
{
"id": "8a6a748b145123cb",
"type": "tab",
"label": "Presence Detection",
"disabled": false,
"info": "",
"env": []
},
{
"id": "b9932c4c66b18537",
"type": "tab",
"label": "Functions",
"disabled": false,
"info": "",
"env": []
},
{
"id": "5be146a97e98891c",
"type": "mqtt-broker",
"name": "iot.fritz.box",
"broker": "iot.fritz.box",
"port": "1883",
"clientid": "",
"autoConnect": true,
"usetls": false,
"protocolVersion": "5",
"keepalive": "60",
"cleansession": true,
"birthTopic": "",
"birthQos": "0",
"birthPayload": "",
"birthMsg": {},
"closeTopic": "",
"closeQos": "0",
"closePayload": "",
"closeMsg": {},
"willTopic": "",
"willQos": "0",
"willPayload": "",
"willMsg": {},
"sessionExpiry": ""
},
{
"id": "bec40e042190e5b4",
"type": "fritzbox-config",
"name": "Fritz Box",
"host": "fritz.box",
"port": "49000",
"ssl": false,
"user": "YOUR_USERNAME_HERE"
},
{
"id": "4039bc1ca3cd6e11",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Check for new Sun Events",
"info": "",
"x": 150,
"y": 40,
"wires": []
},
{
"id": "ce5504b6991f8bf4",
"type": "inject",
"z": "490116e54af5ff9a",
"name": "Every 12h",
"props": [
{
"p": "topic",
"vt": "str"
}
],
"repeat": "43200",
"crontab": "",
"once": true,
"onceDelay": "1",
"topic": "",
"x": 110,
"y": 80,
"wires": [
[
"5151002c9539d2d6"
]
]
},
{
"id": "5151002c9539d2d6",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Set Location",
"rules": [
{
"t": "set",
"p": "payload.latitude",
"pt": "msg",
"to": "47.0",
"tot": "str"
},
{
"t": "set",
"p": "payload.longitude",
"pt": "msg",
"to": "9.0",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 270,
"y": 80,
"wires": [
[
"bc6e8bf098875279"
]
]
},
{
"id": "bc6e8bf098875279",
"type": "sun events",
"z": "490116e54af5ff9a",
"testmode": false,
"verbose": "N",
"topic": "",
"name": "Sun Events",
"x": 430,
"y": 80,
"wires": [
[
"4384fcd3b3567c6c",
"9c21e093193d54e4"
]
]
},
{
"id": "d8f1896d6ed5ca0d",
"type": "switch",
"z": "490116e54af5ff9a",
"name": "On Sunrise",
"property": "sunevent",
"propertyType": "global",
"rules": [
{
"t": "eq",
"v": "sunrise",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 1,
"x": 770,
"y": 220,
"wires": [
[
"98d848700eaa119d",
"76965df29f0c2651"
]
]
},
{
"id": "d17e0c1b295d531a",
"type": "switch",
"z": "490116e54af5ff9a",
"name": "On Sunset",
"property": "sunevent",
"propertyType": "global",
"rules": [
{
"t": "eq",
"v": "sunset",
"vt": "str"
}
],
"checkall": "false",
"repair": false,
"outputs": 1,
"x": 770,
"y": 260,
"wires": [
[
"3e4a16697db5b83d",
"6df166fb14211461"
]
]
},
{
"id": "895f005abb0c7a30",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Big Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_big",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1150,
"y": 200,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "c8246e3ed2f6ac51",
"type": "link call",
"z": "490116e54af5ff9a",
"name": "",
"links": [
"fd3c7a7a7a3b2e99"
],
"timeout": "30",
"x": 1340,
"y": 560,
"wires": [
[]
]
},
{
"id": "bbd4b1ede10ea09e",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Small Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_small",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1160,
"y": 320,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "0516f39aac309884",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Store Sun State",
"rules": [
{
"t": "set",
"p": "sunevent",
"pt": "global",
"to": "payload.sunevent",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 800,
"y": 80,
"wires": [
[
"23bd87871e2f0ecb"
]
]
},
{
"id": "86248602292b2932",
"type": "inject",
"z": "490116e54af5ff9a",
"name": "Every 15sec",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "15",
"crontab": "",
"once": true,
"onceDelay": "5",
"topic": "",
"payloadType": "date",
"x": 120,
"y": 540,
"wires": [
[
"ce6a5620f1e6af76"
]
]
},
{
"id": "98d848700eaa119d",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Turn On",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "on",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 980,
"y": 200,
"wires": [
[
"895f005abb0c7a30"
]
]
},
{
"id": "76965df29f0c2651",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Turn Off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "off",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 980,
"y": 240,
"wires": [
[
"b7ea8636c374cd25"
]
]
},
{
"id": "b7ea8636c374cd25",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Small Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_small",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1160,
"y": 240,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "3e4a16697db5b83d",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Turn On",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "on",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 980,
"y": 320,
"wires": [
[
"bbd4b1ede10ea09e"
]
]
},
{
"id": "6df166fb14211461",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Turn Off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "off",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 980,
"y": 360,
"wires": [
[
"8c16ac287cbf877c"
]
]
},
{
"id": "8c16ac287cbf877c",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Big Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_big",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 1150,
"y": 360,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "6af17a7135211b49",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Set Lights",
"info": "",
"x": 100,
"y": 500,
"wires": []
},
{
"id": "23bd87871e2f0ecb",
"type": "debug",
"z": "490116e54af5ff9a",
"name": "Sun Event Data",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "sunevent",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 980,
"y": 80,
"wires": []
},
{
"id": "9c21e093193d54e4",
"type": "switch",
"z": "490116e54af5ff9a",
"name": "Is Sunrise?",
"property": "payload.sunevent",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "sunrise",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 610,
"y": 120,
"wires": [
[
"0516f39aac309884"
]
]
},
{
"id": "4384fcd3b3567c6c",
"type": "switch",
"z": "490116e54af5ff9a",
"name": "Is Sunset?",
"property": "payload.sunevent",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "sunset",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 610,
"y": 80,
"wires": [
[
"0516f39aac309884"
]
]
},
{
"id": "669b4c826982a274",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Only store relevant states",
"info": "",
"x": 630,
"y": 40,
"wires": []
},
{
"id": "125e5ada06d3bb84",
"type": "mqtt in",
"z": "490116e54af5ff9a",
"name": "Forced Light",
"topic": "bathroom/force_light",
"qos": "2",
"datatype": "auto",
"broker": "5be146a97e98891c",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 110,
"y": 260,
"wires": [
[
"0e7e6ebfd46450f7",
"12082b0fb4909c57",
"42ee21fcc64e2f6b"
]
]
},
{
"id": "0e7e6ebfd46450f7",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Store Forced Light State",
"rules": [
{
"t": "set",
"p": "forced_light_bathroom",
"pt": "global",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 370,
"y": 260,
"wires": [
[
"ce6a5620f1e6af76"
]
]
},
{
"id": "3bcc8e43c0acccd5",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Allow overriding light schedule",
"info": "",
"x": 160,
"y": 220,
"wires": []
},
{
"id": "12082b0fb4909c57",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Store Time of forcing",
"rules": [
{
"t": "set",
"p": "forced_light_bathroom_time",
"pt": "global",
"to": "",
"tot": "date"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 360,
"y": 300,
"wires": [
[]
]
},
{
"id": "ce6a5620f1e6af76",
"type": "switch",
"z": "490116e54af5ff9a",
"name": "Lights Forced?",
"property": "forced_light_bathroom",
"propertyType": "global",
"rules": [
{
"t": "eq",
"v": "none",
"vt": "str"
},
{
"t": "eq",
"v": "off",
"vt": "str"
},
{
"t": "eq",
"v": "big",
"vt": "str"
},
{
"t": "eq",
"v": "small",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 4,
"x": 400,
"y": 540,
"wires": [
[
"d0b79744f8f9eacb",
"3c92f7e580f2d926"
],
[
"9241d0a69fa0e0ba"
],
[
"0106c313423b119b",
"c5b95b0a9268e6d6"
],
[
"72b9d0ad81123696",
"511135c0e9357ffe"
]
]
},
{
"id": "6ed0af4d2180e6c1",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Set Lights according to Sun Schedule",
"info": "",
"x": 850,
"y": 160,
"wires": []
},
{
"id": "9241d0a69fa0e0ba",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Turn Off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "off",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 660,
"y": 580,
"wires": [
[
"5118b6346eb963da",
"169b79020e5cc427"
]
]
},
{
"id": "169b79020e5cc427",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Small Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_small",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 860,
"y": 580,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "5118b6346eb963da",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Big Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_big",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 850,
"y": 620,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "a4d3930695a8574e",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Forced Off",
"info": "",
"x": 660,
"y": 540,
"wires": []
},
{
"id": "617d2b7904f23127",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Forced Big Light",
"info": "",
"x": 680,
"y": 700,
"wires": []
},
{
"id": "0106c313423b119b",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Turn Off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "off",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 660,
"y": 740,
"wires": [
[
"857e6aea1df251ba"
]
]
},
{
"id": "857e6aea1df251ba",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Small Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_small",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 840,
"y": 740,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "c5b95b0a9268e6d6",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Turn On",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "on",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 660,
"y": 780,
"wires": [
[
"10e0fc6e5014f1a8"
]
]
},
{
"id": "10e0fc6e5014f1a8",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Big Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_big",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 830,
"y": 780,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "be6439f19a674c49",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Forced Small Light",
"info": "",
"x": 690,
"y": 840,
"wires": []
},
{
"id": "511135c0e9357ffe",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Turn Off",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "off",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 660,
"y": 920,
"wires": [
[
"d6c93118a00de8be"
]
]
},
{
"id": "0e14dde521822fd9",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Small Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_small",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 840,
"y": 880,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "72b9d0ad81123696",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Turn On",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "on",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 660,
"y": 880,
"wires": [
[
"0e14dde521822fd9"
]
]
},
{
"id": "d6c93118a00de8be",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Bathroom Big Light",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/light_big",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 830,
"y": 920,
"wires": [
[
"c8246e3ed2f6ac51"
]
]
},
{
"id": "14e28adbe9d5ab9b",
"type": "inject",
"z": "490116e54af5ff9a",
"name": "Every 60sec",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "60",
"crontab": "",
"once": true,
"onceDelay": "5",
"topic": "",
"payloadType": "date",
"x": 120,
"y": 740,
"wires": [
[
"ca79c73ef3fd979b"
]
]
},
{
"id": "cfca4ed8e126b999",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Stop Override after time",
"info": "",
"x": 140,
"y": 700,
"wires": []
},
{
"id": "ca79c73ef3fd979b",
"type": "switch",
"z": "490116e54af5ff9a",
"name": "Lights Forced?",
"property": "forced_light_bathroom",
"propertyType": "global",
"rules": [
{
"t": "neq",
"v": "none",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 300,
"y": 740,
"wires": [
[
"3ec81549844232cc"
]
]
},
{
"id": "3ec81549844232cc",
"type": "function",
"z": "490116e54af5ff9a",
"name": "New Override State",
"func": "var trig_t = global.get(\"forced_light_bathroom_time\");\n//node.warn(\"trig_t = \" + trig_t);\n\ntrig_t += (1000 * 60 * 60 * 2); // 2 hours\n\n//trig_t += (1000 * 60); // 1 minute\n//node.warn(\"trig_t+1 = \" + trig_t);\n\nvar trig = new Date(trig_t);\n//node.warn(\"trig = \" + trig);\n\nvar now = new Date();\n//node.warn(\"now = \" + now);\n\nif (trig <= now) {\n msg.payload = \"none\";\n return msg;\n} else {\n return null;\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 150,
"y": 840,
"wires": [
[
"d9c6f73e0340a93e"
]
]
},
{
"id": "88d475840651d470",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Disable after 2 hours",
"info": "",
"x": 150,
"y": 800,
"wires": []
},
{
"id": "d9c6f73e0340a93e",
"type": "change",
"z": "490116e54af5ff9a",
"name": "Store Forced Light State",
"rules": [
{
"t": "set",
"p": "forced_light_bathroom",
"pt": "global",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 370,
"y": 840,
"wires": [
[
"100da1b7bffe4ab2",
"ce6a5620f1e6af76"
]
]
},
{
"id": "42ee21fcc64e2f6b",
"type": "debug",
"z": "490116e54af5ff9a",
"name": "Override",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 320,
"y": 340,
"wires": []
},
{
"id": "100da1b7bffe4ab2",
"type": "debug",
"z": "490116e54af5ff9a",
"name": "Override Refresh",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 390,
"y": 900,
"wires": []
},
{
"id": "d0b79744f8f9eacb",
"type": "function",
"z": "490116e54af5ff9a",
"name": "User or Spouse Present?",
"func": "var user = global.get(\"user_present\");\nvar work = global.get(\"user_present_work\");\nvar spouse = global.get(\"spouse_present\");\n\nif ((user == \"1\") || (work == \"1\") || (spouse == \"1\")) {\n msg.payload = \"none\";\n return msg;\n} else {\n return null;\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 610,
"y": 400,
"wires": [
[
"d8f1896d6ed5ca0d",
"d17e0c1b295d531a"
]
]
},
{
"id": "3c92f7e580f2d926",
"type": "function",
"z": "490116e54af5ff9a",
"name": "Nobody Present?",
"func": "var user = global.get(\"user_present\");\nvar work = global.get(\"user_present_work\");\nvar spouse = global.get(\"spouse_present\");\n\nif ((user == \"0\") && (work == \"0\") && (spouse == \"0\")) {\n msg.payload = \"none\";\n return msg;\n} else {\n return null;\n}",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 590,
"y": 440,
"wires": [
[
"9241d0a69fa0e0ba"
]
]
},
{
"id": "23201910ed265e74",
"type": "comment",
"z": "490116e54af5ff9a",
"name": "Presence Detection",
"info": "",
"x": 590,
"y": 360,
"wires": []
},
{
"id": "e70de37a1b248a25",
"type": "inject",
"z": "74341bea93cc320d",
"name": "Every 1min",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "60",
"crontab": "",
"once": true,
"onceDelay": "10",
"topic": "",
"payloadType": "date",
"x": 130,
"y": 100,
"wires": [
[
"4375482d5ce5df1c"
]
]
},
{
"id": "4375482d5ce5df1c",
"type": "change",
"z": "74341bea93cc320d",
"name": "Turn On",
"rules": [
{
"t": "set",
"p": "payload",
"pt": "msg",
"to": "on",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 300,
"y": 100,
"wires": [
[
"9f7db20cf89cff6d"
]
]
},
{
"id": "86f29e0ed5d23b51",
"type": "comment",
"z": "74341bea93cc320d",
"name": "Keep bathroom fan always on",
"info": "Make sure fan is always turned on.\nNo sensors available yet to do this better.",
"x": 160,
"y": 60,
"wires": []
},
{
"id": "9f7db20cf89cff6d",
"type": "change",
"z": "74341bea93cc320d",
"name": "Bathroom Fan",
"rules": [
{
"t": "set",
"p": "topic",
"pt": "msg",
"to": "bathroom/fan",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 480,
"y": 100,
"wires": [
[
"2e5626a57c7fdbe1"
]
]
},
{
"id": "2e5626a57c7fdbe1",
"type": "link call",
"z": "74341bea93cc320d",
"name": "",
"links": [
"fd3c7a7a7a3b2e99"
],
"timeout": "30",
"x": 660,
"y": 100,
"wires": [
[]
]
},
{
"id": "f80158f1.d27ab8",
"type": "inject",
"z": "8a6a748b145123cb",
"name": "MAC iPhone SE",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "30",
"crontab": "",
"once": true,
"onceDelay": "5",
"topic": "",
"payload": "{\"NewMACAddress\": \"XX:XX:XX:XX:XX:XX\" }",
"payloadType": "json",
"x": 130,
"y": 80,
"wires": [
[
"7b27936b.08bc8c"
]
]
},
{
"id": "7b27936b.08bc8c",
"type": "fritzbox-in",
"z": "8a6a748b145123cb",
"device": "bec40e042190e5b4",
"name": "",
"service": "urn:dslforum-org:service:Hosts:1",
"action": "GetSpecificHostEntry",
"arguments": "{\"NewMACAddress\":\"value\"}",
"x": 330,
"y": 80,
"wires": [
[
"12274598.0e46da",
"9c0d010be5886f15",
"b6d4657cbec9268d"
]
]
},
{
"id": "12274598.0e46da",
"type": "debug",
"z": "8a6a748b145123cb",
"name": "",
"active": true,
"console": "false",
"complete": "false",
"x": 570,
"y": 80,
"wires": []
},
{
"id": "9c0d010be5886f15",
"type": "switch",
"z": "8a6a748b145123cb",
"name": "Is Present?",
"property": "payload.NewActive",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "1",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 570,
"y": 120,
"wires": [
[
"8e9714f633561c05"
]
]
},
{
"id": "b6d4657cbec9268d",
"type": "switch",
"z": "8a6a748b145123cb",
"name": "Is Not Present?",
"property": "payload.NewActive",
"propertyType": "msg",
"rules": [
{
"t": "neq",
"v": "1",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 580,
"y": 160,
"wires": [
[
"3b561094f8825a29"
]
]
},
{
"id": "8e9714f633561c05",
"type": "change",
"z": "8a6a748b145123cb",
"name": "User present",
"rules": [
{
"t": "set",
"p": "user_present",
"pt": "global",
"to": "1",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 770,
"y": 120,
"wires": [
[]
]
},
{
"id": "3b561094f8825a29",
"type": "change",
"z": "8a6a748b145123cb",
"name": "User not present",
"rules": [
{
"t": "set",
"p": "user_present",
"pt": "global",
"to": "0",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 780,
"y": 160,
"wires": [
[]
]
},
{
"id": "f4ace639729b079b",
"type": "comment",
"z": "8a6a748b145123cb",
"name": "Main User Presence Detection",
"info": "",
"x": 160,
"y": 40,
"wires": []
},
{
"id": "2f609a2d2eb6c36a",
"type": "inject",
"z": "8a6a748b145123cb",
"name": "Samsung S20 FE",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "30",
"crontab": "",
"once": true,
"onceDelay": "10",
"topic": "",
"payload": "{\"NewMACAddress\": \"XX:XX:XX:XX:XX:XX\" }",
"payloadType": "json",
"x": 130,
"y": 460,
"wires": [
[
"1e09a8dddf0a36c2"
]
]
},
{
"id": "1e09a8dddf0a36c2",
"type": "fritzbox-in",
"z": "8a6a748b145123cb",
"device": "bec40e042190e5b4",
"name": "",
"service": "urn:dslforum-org:service:Hosts:1",
"action": "GetSpecificHostEntry",
"arguments": "{\"NewMACAddress\":\"value\"}",
"x": 330,
"y": 460,
"wires": [
[
"9b618d89591e4c32",
"6bae9ec64ae22aa4",
"ae2aacab4e21becd"
]
]
},
{
"id": "9b618d89591e4c32",
"type": "debug",
"z": "8a6a748b145123cb",
"name": "",
"active": true,
"console": "false",
"complete": "false",
"x": 570,
"y": 460,
"wires": []
},
{
"id": "6bae9ec64ae22aa4",
"type": "switch",
"z": "8a6a748b145123cb",
"name": "Is Present?",
"property": "payload.NewActive",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "1",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 570,
"y": 500,
"wires": [
[
"9d204199083405ac"
]
]
},
{
"id": "ae2aacab4e21becd",
"type": "switch",
"z": "8a6a748b145123cb",
"name": "Is Not Present?",
"property": "payload.NewActive",
"propertyType": "msg",
"rules": [
{
"t": "neq",
"v": "1",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 580,
"y": 540,
"wires": [
[
"7790892a62cafef9"
]
]
},
{
"id": "9d204199083405ac",
"type": "change",
"z": "8a6a748b145123cb",
"name": "Spouse present",
"rules": [
{
"t": "set",
"p": "spouse_present",
"pt": "global",
"to": "1",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 780,
"y": 500,
"wires": [
[]
]
},
{
"id": "7790892a62cafef9",
"type": "change",
"z": "8a6a748b145123cb",
"name": "Spouse not present",
"rules": [
{
"t": "set",
"p": "spouse_present",
"pt": "global",
"to": "0",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 790,
"y": 540,
"wires": [
[]
]
},
{
"id": "14272cd4a2102720",
"type": "comment",
"z": "8a6a748b145123cb",
"name": "Spouse Presence Detection",
"info": "",
"x": 160,
"y": 420,
"wires": []
},
{
"id": "f2c68c21a68054df",
"type": "inject",
"z": "8a6a748b145123cb",
"name": "MAC Samsung S22",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "30",
"crontab": "",
"once": true,
"onceDelay": "6",
"topic": "",
"payload": "{\"NewMACAddress\": \"XX:XX:XX:XX:XX:XX\" }",
"payloadType": "json",
"x": 140,
"y": 240,
"wires": [
[
"1b5d2574cd2e541f"
]
]
},
{
"id": "1b5d2574cd2e541f",
"type": "fritzbox-in",
"z": "8a6a748b145123cb",
"device": "bec40e042190e5b4",
"name": "",
"service": "urn:dslforum-org:service:Hosts:1",
"action": "GetSpecificHostEntry",
"arguments": "{\"NewMACAddress\":\"value\"}",
"x": 330,
"y": 240,
"wires": [
[
"2cbb2b7a8ebf4ac8",
"08dca32f4d3512b3",
"b2d30bc31b36a369"
]
]
},
{
"id": "2cbb2b7a8ebf4ac8",
"type": "debug",
"z": "8a6a748b145123cb",
"name": "",
"active": true,
"console": "false",
"complete": "false",
"x": 570,
"y": 240,
"wires": []
},
{
"id": "08dca32f4d3512b3",
"type": "switch",
"z": "8a6a748b145123cb",
"name": "Is Present?",
"property": "payload.NewActive",
"propertyType": "msg",
"rules": [
{
"t": "eq",
"v": "1",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 570,
"y": 280,
"wires": [
[
"09abca3d9ff5e44c"
]
]
},
{
"id": "b2d30bc31b36a369",
"type": "switch",
"z": "8a6a748b145123cb",
"name": "Is Not Present?",
"property": "payload.NewActive",
"propertyType": "msg",
"rules": [
{
"t": "neq",
"v": "1",
"vt": "str"
}
],
"checkall": "true",
"repair": false,
"outputs": 1,
"x": 580,
"y": 320,
"wires": [
[
"10582e300715e0b0"
]
]
},
{
"id": "09abca3d9ff5e44c",
"type": "change",
"z": "8a6a748b145123cb",
"name": "User (Work) present",
"rules": [
{
"t": "set",
"p": "user_present_work",
"pt": "global",
"to": "1",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 800,
"y": 280,
"wires": [
[]
]
},
{
"id": "10582e300715e0b0",
"type": "change",
"z": "8a6a748b145123cb",
"name": "User (Work) not present",
"rules": [
{
"t": "set",
"p": "user_present_work",
"pt": "global",
"to": "0",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 810,
"y": 320,
"wires": [
[]
]
},
{
"id": "e6010f1672bac815",
"type": "mqtt out",
"z": "b9932c4c66b18537",
"name": "IoT MQTT",
"topic": "",
"qos": "",
"retain": "",
"respTopic": "",
"contentType": "text/plain",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "5be146a97e98891c",
"x": 210,
"y": 160,
"wires": []
},
{
"id": "8a4031a3be97bf0a",
"type": "debug",
"z": "b9932c4c66b18537",
"name": "Debug Print",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 210,
"y": 120,
"wires": []
},
{
"id": "fd3c7a7a7a3b2e99",
"type": "link in",
"z": "b9932c4c66b18537",
"name": "set_mqtt",
"links": [],
"x": 55,
"y": 80,
"wires": [
[
"8a4031a3be97bf0a",
"e6010f1672bac815",
"d185ca7a7211b37e"
]
]
},
{
"id": "db9d2ccfce698ced",
"type": "comment",
"z": "b9932c4c66b18537",
"name": "set_mqtt",
"info": "",
"x": 100,
"y": 40,
"wires": []
},
{
"id": "d185ca7a7211b37e",
"type": "link out",
"z": "b9932c4c66b18537",
"name": "",
"mode": "return",
"links": [],
"x": 155,
"y": 80,
"wires": []
},
{
"id": "2f4447ab9df7cdc9",
"type": "comment",
"z": "b9932c4c66b18537",
"name": "Initialize States",
"info": "",
"x": 120,
"y": 280,
"wires": []
},
{
"id": "b8d60dba22486026",
"type": "inject",
"z": "b9932c4c66b18537",
"name": "Once",
"props": [
{
"p": "payload"
},
{
"p": "topic",
"vt": "str"
}
],
"repeat": "",
"crontab": "",
"once": true,
"onceDelay": 0.1,
"topic": "",
"payloadType": "date",
"x": 90,
"y": 320,
"wires": [
[
"0c523fcd13255b79",
"cdede78de7e379d1",
"31d1f2ec3504d186",
"7d3895abe57fe91b"
]
]
},
{
"id": "dd5d9dc12a9e14f0",
"type": "change",
"z": "b9932c4c66b18537",
"name": "Set Sun State",
"rules": [
{
"t": "set",
"p": "sunevent",
"pt": "global",
"to": "payload",
"tot": "msg"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 580,
"y": 360,
"wires": [
[]
]
},
{
"id": "0c523fcd13255b79",
"type": "change",
"z": "b9932c4c66b18537",
"name": "Bathroom Lights not forced",
"rules": [
{
"t": "set",
"p": "forced_light_bathroom",
"pt": "global",
"to": "none",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 340,
"y": 320,
"wires": [
[]
]
},
{
"id": "cdede78de7e379d1",
"type": "function",
"z": "b9932c4c66b18537",
"name": "Return current approx. sun state",
"func": "var now = new Date();\nvar h = now.getHours();\n\nif ((h >= 8) && (h <= 19)) {\n msg.payload = \"sunrise\";\n} else {\n msg.payload = \"sunset\";\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 350,
"y": 360,
"wires": [
[
"dd5d9dc12a9e14f0"
]
]
},
{
"id": "31d1f2ec3504d186",
"type": "change",
"z": "b9932c4c66b18537",
"name": "User present",
"rules": [
{
"t": "set",
"p": "user_present",
"pt": "global",
"to": "1",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 290,
"y": 400,
"wires": [
[]
]
},
{
"id": "7d3895abe57fe91b",
"type": "change",
"z": "b9932c4c66b18537",
"name": "Spouse present",
"rules": [
{
"t": "set",
"p": "spouse_present",
"pt": "global",
"to": "1",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 300,
"y": 480,
"wires": [
[]
]
},
{
"id": "0cd19755c3e94219",
"type": "change",
"z": "b9932c4c66b18537",
"name": "User (Work) present",
"rules": [
{
"t": "set",
"p": "user_present_work",
"pt": "global",
"to": "1",
"tot": "str"
}
],
"action": "",
"property": "",
"from": "",
"to": "",
"reg": false,
"x": 320,
"y": 440,
"wires": [
[]
]
}
]
The Node-RED installation is handled by an ansible script.



