From 48a1e23be930646a301dc7b7a20d484c2343b77c Mon Sep 17 00:00:00 2001 From: m038 Date: Sat, 13 Jun 2026 13:33:10 +0200 Subject: [PATCH] Update flow files --- flows.json | 22662 +++++++++++++++++++++++++-------------------------- 1 file changed, 11155 insertions(+), 11507 deletions(-) diff --git a/flows.json b/flows.json index d322f0b..ecff6e9 100644 --- a/flows.json +++ b/flows.json @@ -1,8 +1,50 @@ [ + { + "id": "600f7a12.5ee66c", + "type": "tab", + "label": "[Global] Security", + "disabled": false, + "info": "" + }, + { + "id": "a320f821a7cb3f55", + "type": "tab", + "label": "[Global] Maintenance", + "disabled": false + }, + { + "id": "f02b32ef07b4b378", + "type": "tab", + "label": "[Global] Home Audio", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "1f4d4622.7490ca", + "type": "tab", + "label": "[Global] Temperature & Climate" + }, + { + "id": "75c53969.aa5438", + "type": "tab", + "label": "[Global] Wake Up Routine", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "6dfa989bb120e6c6", + "type": "tab", + "label": "[Global] Home Presence", + "disabled": false, + "info": "", + "env": [] + }, { "id": "bbf25964.5edb38", "type": "tab", - "label": "Coffee-mations", + "label": "[Global] Coffee Circle", "disabled": false, "info": "", "env": [ @@ -13,70 +55,415 @@ } ] }, - { - "id": "600f7a12.5ee66c", - "type": "tab", - "label": "Security" - }, - { - "id": "75c53969.aa5438", - "type": "tab", - "label": "Wake up & mosquito" - }, - { - "id": "f02b32ef07b4b378", - "type": "tab", - "label": "Home Audio" - }, - { - "id": "da896085.24c698", - "type": "tab", - "label": "Home Media" - }, - { - "id": "a9edb9da.ccb6d", - "type": "tab", - "label": "Motion detection" - }, - { - "id": "97e0f1338e182d76", - "type": "tab", - "label": "Bedroom" - }, - { - "id": "5af82cd4c44df066", - "type": "tab", - "label": "Kitchen" - }, { "id": "10cbea6aaac127cd", "type": "tab", - "label": "Balcony" - }, - { - "id": "1f4d4622.7490ca", - "type": "tab", - "label": "Temperature & climate" - }, - { - "id": "b70ee13eafa73823", - "type": "tab", - "label": "Living room" + "label": "[Balcony] Lights", + "disabled": false, + "info": "", + "env": [] }, { "id": "c7f876875da48b87", "type": "tab", - "label": "Bathroom" + "label": "[Bathroom] Lights", + "disabled": false, + "info": "", + "env": [] }, { - "id": "6dfa989bb120e6c6", + "id": "97e0f1338e182d76", "type": "tab", - "label": "Home Presence" + "label": "[Bedroom] Lights" }, { - "id": "a320f821a7cb3f55", + "id": "550f84daf129f66b", "type": "tab", - "label": "Maintenance" + "label": "[Bedroom] Mosquito Repellent", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "c19dee9f.e72838", + "type": "tab", + "label": "[Hallway] Lights" + }, + { + "id": "b73eb220c60f9f8b", + "type": "tab", + "label": "[Kitchen] Espresso Machine", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "5af82cd4c44df066", + "type": "tab", + "label": "[Kitchen] Lights" + }, + { + "id": "b70ee13eafa73823", + "type": "tab", + "label": "[Living Room] Lights", + "disabled": false, + "info": "", + "env": [] + }, + { + "id": "e52c44dc.71cb5", + "type": "subflow", + "name": "Is it Night?", + "info": "Determines if the current time is between the _Night Time_ and the _Morning Time_ settings in Home Assistant.", + "category": "", + "in": [ + { + "x": 140, + "y": 140, + "wires": [ + { + "id": "dc7ddc2d53abc038" + } + ] + } + ], + "out": [ + { + "x": 780, + "y": 160, + "wires": [ + { + "id": "dc7ddc2d53abc038", + "port": 5 + } + ] + }, + { + "x": 800, + "y": 100, + "wires": [ + { + "id": "dc7ddc2d53abc038", + "port": 0 + }, + { + "id": "dc7ddc2d53abc038", + "port": 1 + }, + { + "id": "dc7ddc2d53abc038", + "port": 2 + }, + { + "id": "dc7ddc2d53abc038", + "port": 3 + }, + { + "id": "dc7ddc2d53abc038", + "port": 4 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DDAA99", + "outputLabels": [ + "After night time", + "Before morning time " + ] + }, + { + "id": "091c97d9c8d81499", + "type": "subflow", + "name": "JSON Escape", + "info": "", + "category": "", + "in": [ + { + "x": 120, + "y": 140, + "wires": [ + { + "id": "9e4fac23fd2c73ed" + } + ] + } + ], + "out": [ + { + "x": 520, + "y": 140, + "wires": [ + { + "id": "9e4fac23fd2c73ed", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DDAA99" + }, + { + "id": "52430f5e9f9ee267", + "type": "subflow", + "name": "Which timeslot are we in?", + "info": "", + "category": "", + "in": [ + { + "x": 100, + "y": 160, + "wires": [ + { + "id": "f4da808dc4c218b6" + }, + { + "id": "25fe3f965108a4f8" + }, + { + "id": "910e431ab636c701" + }, + { + "id": "1029462b97e1cc7c" + }, + { + "id": "c263329e3207423d" + }, + { + "id": "6a5d6248d66d5303" + } + ] + } + ], + "out": [ + { + "x": 1760, + "y": 440, + "wires": [ + { + "id": "b884e557f9524784", + "port": 0 + } + ] + }, + { + "x": 1760, + "y": 480, + "wires": [ + { + "id": "06f7380c6f28bdd1", + "port": 0 + } + ] + }, + { + "x": 1780, + "y": 520, + "wires": [ + { + "id": "41de38d16e68d1d9", + "port": 0 + } + ] + }, + { + "x": 1760, + "y": 560, + "wires": [ + { + "id": "4d992d3713228542", + "port": 0 + } + ] + }, + { + "x": 1770, + "y": 600, + "wires": [ + { + "id": "25b5aff2dea58057", + "port": 0 + } + ] + }, + { + "x": 1750, + "y": 640, + "wires": [ + { + "id": "5f0e5f63552a97f2", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DDAA99", + "inputLabels": [ + "anything" + ], + "outputLabels": [ + "morning", + "midday", + "late afternoon", + "evening", + "late evening", + "night" + ] + }, + { + "id": "c0a0e0.ae6cbf2", + "type": "subflow", + "name": "Zigbee2MQTT dim & toggle", + "info": "", + "category": "", + "in": [ + { + "x": 480, + "y": 340, + "wires": [ + { + "id": "821795d7.433b58" + } + ] + } + ], + "out": [], + "env": [ + { + "name": "topic", + "type": "str", + "value": "" + } + ], + "color": "#DDAA99" + }, + { + "id": "be8264a322721305", + "type": "subflow", + "name": "Timer based on hour config", + "info": "", + "category": "", + "in": [ + { + "x": 120, + "y": 100, + "wires": [ + { + "id": "a93b68e3e83b1d25" + } + ] + } + ], + "out": [ + { + "x": 860, + "y": 100, + "wires": [ + { + "id": "7a1e6b58aaf9559f", + "port": 0 + } + ] + } + ], + "env": [], + "meta": {}, + "color": "#DDAA99" + }, + { + "id": "657c7463.48e1e4", + "type": "server", + "name": "Home Assistant Latest", + "addon": false, + "rejectUnauthorizedCerts": true, + "ha_boolean": [ + "y", + "|", + "e", + "s", + "t", + "r", + "u", + "o", + "n", + "h", + "m", + "p" + ], + "connectionDelay": true, + "cacheJson": false, + "heartbeat": false, + "heartbeatInterval": "", + "statusSeparator": "", + "enableGlobalContextStore": false + }, + { + "id": "62ed34c9191cebca", + "type": "ha-entity-config", + "server": "657c7463.48e1e4", + "deviceConfig": "", + "name": "Kitchen Motion Sensor Flow", + "version": "6", + "entityType": "switch", + "haConfig": [ + { + "property": "name", + "value": "kitchen_motion_sensor_flow" + }, + { + "property": "icon", + "value": "" + }, + { + "property": "entity_picture", + "value": "" + }, + { + "property": "entity_category", + "value": "" + }, + { + "property": "device_class", + "value": "" + } + ], + "resend": false, + "debugEnabled": false + }, + { + "id": "d51b5899.a2d5d8", + "type": "mqtt-broker", + "d": true, + "name": "Mosquto Broker", + "broker": "192.168.1.6", + "port": "1883", + "clientid": "", + "autoConnect": true, + "usetls": false, + "compatmode": false, + "protocolVersion": "4", + "keepalive": "60", + "cleansession": true, + "autoUnsubscribe": true, + "birthTopic": "", + "birthQos": "0", + "birthPayload": "", + "birthMsg": {}, + "closeTopic": "", + "closeQos": "0", + "closePayload": "", + "closeMsg": {}, + "willTopic": "", + "willQos": "0", + "willPayload": "", + "willMsg": {}, + "userProps": "", + "sessionExpiry": "" }, { "id": "cc000023", @@ -112,6 +499,40 @@ "resend": false, "debugEnabled": false }, + { + "id": "cc000024", + "type": "ha-entity-config", + "z": "bbf25964.5edb38", + "server": "657c7463.48e1e4", + "deviceConfig": "", + "name": "CC Delivery Product", + "version": "6", + "entityType": "sensor", + "haConfig": [ + { + "property": "name", + "value": "cc_next_delivery_product" + }, + { + "property": "icon", + "value": "mdi:coffee" + }, + { + "property": "entity_picture", + "value": "" + }, + { + "property": "entity_category", + "value": "" + }, + { + "property": "device_class", + "value": "" + } + ], + "resend": false, + "debugEnabled": false + }, { "id": "cc000025", "type": "ha-entity-config", @@ -215,625 +636,52 @@ "debugEnabled": false }, { - "id": "cc000024", - "type": "ha-entity-config", - "z": "bbf25964.5edb38", - "server": "657c7463.48e1e4", - "deviceConfig": "", - "name": "CC Delivery Product", - "version": "6", - "entityType": "sensor", - "haConfig": [ - { - "property": "name", - "value": "cc_next_delivery_product" - }, - { - "property": "icon", - "value": "mdi:coffee" - }, - { - "property": "entity_picture", - "value": "" - }, - { - "property": "entity_category", - "value": "" - }, - { - "property": "device_class", - "value": "" - } - ], - "resend": false, - "debugEnabled": false - }, - { - "id": "6240870c.31fd5", - "type": "server-state-changed", - "z": "bbf25964.5edb38", - "name": "Coffee warump time", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_datetime.coffee_warmup_time" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 150, - "y": 200, - "wires": [ - [ - "2192f59f.22ce22" - ] - ] - }, - { - "id": "2192f59f.22ce22", - "type": "function", - "z": "bbf25964.5edb38", - "name": "actual start time", - "outputs": 1, - "x": 400, - "y": 200, - "wires": [ - [ - "beb09931.b70f28", - "a8e14f78.138b18" - ] - ] - }, - { - "id": "beb09931.b70f28", - "type": "schedex", - "z": "bbf25964.5edb38", - "name": "Wake up timer", - "x": 660, - "y": 200, - "wires": [ - [ - "1c291b99.49c854" - ] - ] - }, - { - "id": "1c291b99.49c854", - "type": "api-current-state", - "z": "bbf25964.5edb38", - "name": "Warmup enabled?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "on", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_boolean.coffee_warmup_enable", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 230, - "y": 280, - "wires": [ - [ - "d05c6bb6.89189", - "96ec81ec.b8b198" - ], - [] - ] - }, - { - "id": "6cb3a102.ddf1", - "type": "api-call-service", - "z": "bbf25964.5edb38", - "name": "Turn on espresso", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "areaId": [], - "deviceId": [], - "entityId": [ - "switch.espresso_machine" - ], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "domain": "switch", - "service": "turn_on", - "x": 890, - "y": 280, - "wires": [ - [] - ] - }, - { - "id": "d05c6bb6.89189", - "type": "api-call-service", - "z": "bbf25964.5edb38", - "name": "Turn off warmup", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "areaId": [], - "deviceId": [], - "entityId": [ - "input_boolean.coffee_warmup_enable" - ], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "domain": "input_boolean", - "service": "turn_off", - "x": 560, - "y": 360, - "wires": [ - [] - ] - }, - { - "id": "81386d51.ea72e8", - "type": "api-call-service", - "z": "bbf25964.5edb38", - "name": "Notify via HA", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "areaId": [], - "deviceId": [], - "entityId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "domain": "notify", - "service": "gotify_ha", - "x": 1190, - "y": 160, - "wires": [ - [] - ] - }, - { - "id": "96ec81ec.b8b198", - "type": "api-current-state", - "z": "bbf25964.5edb38", - "name": "Espresso machine already on?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "off", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "switch.espresso_machine", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 610, - "y": 280, - "wires": [ - [ - "6cb3a102.ddf1" - ], - [] - ] - }, - { - "id": "2d4463ba.d359dc", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Espresso ready at...", - "outputs": 1, - "x": 1180, - "y": 80, - "wires": [ - [ - "81386d51.ea72e8" - ] - ] - }, - { - "id": "a8e14f78.138b18", - "type": "api-current-state", - "z": "bbf25964.5edb38", - "name": "Warmup enabled?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "on", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_boolean.coffee_warmup_enable", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", + "id": "dc7ddc2d53abc038", + "type": "subflow:52430f5e9f9ee267", + "z": "e52c44dc.71cb5", + "name": "", "x": 390, - "y": 120, + "y": 140, "wires": [ - [ - "b837b0d4.49bfe" - ], - [] - ] - }, - { - "id": "b837b0d4.49bfe", - "type": "api-current-state", - "z": "bbf25964.5edb38", - "name": "Espresso machine already on?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "off", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "switch.espresso_machine", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 870, - "y": 120, - "wires": [ - [ - "2d4463ba.d359dc" - ], - [] - ] - }, - { - "id": "9baaac50.5dc4d8", - "type": "server-state-changed", - "z": "bbf25964.5edb38", - "name": "Coffee one time switch is on", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_boolean.coffee_one_time_warmup" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 40, - "wires": [ - [ - "cc2ab74b.72878" - ], - [] - ] - }, - { - "id": "cc2ab74b.72878", - "type": "api-current-state", - "z": "bbf25964.5edb38", - "name": "Get warm up time", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 1, - "halt_if": "", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_datetime.coffee_warmup_time", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 410, - "y": 40, - "wires": [ - [ - "4cf72b61.3d5e4c" - ] - ] - }, - { - "id": "4cf72b61.3d5e4c", - "type": "function", - "z": "bbf25964.5edb38", - "name": "actual start time", - "outputs": 1, - "x": 600, - "y": 40, - "wires": [ - [ - "b837b0d4.49bfe" - ] - ] - }, - { - "id": "5009c878.847b08", - "type": "api-current-state", - "z": "bbf25964.5edb38", - "name": "Get auto standby time", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 1, - "halt_if": "", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_number.espresso_auto_standby", - "state_type": "num", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 480, - "y": 500, - "wires": [ - [ - "d76881ab.11ea4" - ] - ] - }, - { - "id": "c1260337.f1478", - "type": "server-state-changed", - "z": "bbf25964.5edb38", - "name": "Espresso machine is on", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "switch.espresso_machine" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 500, - "wires": [ - [ - "5009c878.847b08" - ], - [] - ] - }, - { - "id": "e3a24a7e.c7952", - "type": "api-call-service", - "z": "bbf25964.5edb38", - "name": "Turn off espresso", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "areaId": [], - "deviceId": [], - "entityId": [ - "switch.espresso_machine" - ], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "domain": "switch", - "service": "turn_off", - "x": 1070, - "y": 560, - "wires": [ - [] - ] - }, - { - "id": "d76881ab.11ea4", - "type": "stoptimer-varidelay", - "z": "bbf25964.5edb38", - "name": "Off timer (default 60 mins)", - "x": 790, - "y": 560, - "wires": [ - [ - "e3a24a7e.c7952" - ], + [], + [], + [], + [], [], [] ] }, { - "id": "3bdeab05.91997c", - "type": "server-state-changed", - "z": "bbf25964.5edb38", - "name": "Espresso machine is off", + "id": "9e4fac23fd2c73ed", + "type": "function", + "z": "091c97d9c8d81499", + "name": "Escape JSON string", + "func": "msg.payload = JSON.stringify(msg.payload).replace(/\"/g, '\\\"');\n\nreturn msg;", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 320, + "y": 140, + "wires": [ + [] + ] + }, + { + "id": "910e431ab636c701", + "type": "api-current-state", + "z": "52430f5e9f9ee267", + "name": "Night Time", "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "switch.espresso_machine" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "off", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_datetime.night_starts_ha", + "state_type": "str", + "blockInputOverrides": false, "outputProperties": [ { "property": "payload", @@ -842,936 +690,1077 @@ "valueType": "entityState" }, { - "property": "data", + "property": "topic", + "propertyType": "msg", + "value": "night", + "valueType": "str" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 330, + "y": 260, + "wires": [ + [ + "b1106a1c85cc30f3" + ] + ] + }, + { + "id": "f4da808dc4c218b6", + "type": "api-current-state", + "z": "52430f5e9f9ee267", + "name": "Morning Time", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_datetime.morning_starts_ha", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", "propertyType": "msg", "value": "", - "valueType": "eventData" + "valueType": "entityState" }, { "property": "topic", "propertyType": "msg", - "value": "", - "valueType": "triggerId" + "value": "morning", + "valueType": "str" } ], - "x": 180, - "y": 580, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 340, + "y": 60, "wires": [ [ - "d96cad4e.4fd068" - ], - [] - ] - }, - { - "id": "d96cad4e.4fd068", - "type": "change", - "z": "bbf25964.5edb38", - "name": "Send STOP", - "x": 450, - "y": 580, - "wires": [ - [ - "d76881ab.11ea4" + "b1106a1c85cc30f3" ] ] }, { - "id": "cc000001", - "type": "comment", - "z": "bbf25964.5edb38", - "name": "Coffee Circle Subscription — fetches next delivery data every 6h", - "info": "", - "x": 310, - "y": 660, - "wires": [] - }, - { - "id": "cc000002", - "type": "inject", - "z": "bbf25964.5edb38", - "name": "Every 6h + on deploy", - "props": [ + "id": "25fe3f965108a4f8", + "type": "api-current-state", + "z": "52430f5e9f9ee267", + "name": "Evening Time", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_datetime.evening_starts_ha", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ { - "p": "payload" + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" }, { - "p": "topic", - "vt": "str" + "property": "topic", + "propertyType": "msg", + "value": "evening", + "valueType": "str" } ], - "repeat": "21600", - "crontab": "", - "once": true, - "onceDelay": "5", + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 340, + "y": 180, + "wires": [ + [ + "b1106a1c85cc30f3" + ] + ] + }, + { + "id": "b1106a1c85cc30f3", + "type": "join", + "z": "52430f5e9f9ee267", + "name": "Collect all times", + "mode": "custom", + "build": "object", + "property": "payload", + "propertyType": "msg", + "key": "topic", + "joiner": "\\n", + "joinerType": "str", + "accumulate": false, + "timeout": "", + "count": "6", + "reduceRight": false, + "reduceExp": "", + "reduceInit": "", + "reduceInitType": "", + "reduceFixup": "", + "x": 750, + "y": 160, + "wires": [ + [ + "4e491e57f35c4458", + "ca40f18fea0361e5" + ] + ] + }, + { + "id": "1029462b97e1cc7c", + "type": "api-current-state", + "z": "52430f5e9f9ee267", + "name": "Midday Time", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_datetime.midday_starts_ha", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "midday", + "valueType": "str" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 330, + "y": 100, + "wires": [ + [ + "b1106a1c85cc30f3" + ] + ] + }, + { + "id": "6a5d6248d66d5303", + "type": "api-current-state", + "z": "52430f5e9f9ee267", + "name": "Late Evening Time", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_datetime.late_evening_starts_ha", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "late_evening", + "valueType": "str" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 350, + "y": 220, + "wires": [ + [ + "b1106a1c85cc30f3" + ] + ] + }, + { + "id": "c263329e3207423d", + "type": "api-current-state", + "z": "52430f5e9f9ee267", + "name": "Late Afternoon Time", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_datetime.late_afternoon_starts_ha", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "late_afternoon", + "valueType": "str" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 360, + "y": 140, + "wires": [ + [ + "b1106a1c85cc30f3" + ] + ] + }, + { + "id": "4e491e57f35c4458", + "type": "split", + "z": "52430f5e9f9ee267", + "name": "For each configured time", + "splt": "\\n", + "spltType": "str", + "arraySplt": 1, + "arraySpltType": "len", + "stream": false, + "addname": "topic", + "x": 1070, + "y": 160, + "wires": [ + [ + "3cc1cd83a914fbed" + ] + ] + }, + { + "id": "d88527a4c0207c0c", + "type": "join", + "z": "52430f5e9f9ee267", + "name": "Merge elements into single array", + "mode": "custom", + "build": "object", + "property": "payload", + "propertyType": "msg", + "key": "topic", + "joiner": "\\n", + "joinerType": "str", + "accumulate": false, + "timeout": "", + "count": "8", + "reduceRight": false, + "reduceExp": "", + "reduceInit": "", + "reduceInitType": "", + "reduceFixup": "", + "x": 1100, + "y": 360, + "wires": [ + [ + "00fdb1bc99d82683" + ] + ] + }, + { + "id": "3cc1cd83a914fbed", + "type": "moment", + "z": "52430f5e9f9ee267", + "name": "Convert time to date time", "topic": "", - "payload": "", - "payloadType": "date", - "x": 200, - "y": 720, + "input": "payload", + "inputType": "msg", + "inTz": "Europe/Berlin", + "adjAmount": 0, + "adjType": "days", + "adjDir": "add", + "format": "", + "locale": "en-US", + "output": "payload", + "outputType": "msg", + "outTz": "Europe/Berlin", + "x": 1070, + "y": 220, "wires": [ [ - "cc000004" + "558cbc9bafd7fda2" ] ] }, { - "id": "cc000003", - "type": "link in", - "z": "bbf25964.5edb38", - "name": "CC Fetch Trigger", - "links": [], - "x": 195, - "y": 780, - "wires": [ - [ - "cc000004" - ] - ] - }, - { - "id": "cc000004", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Read session cookie", - "func": "msg.payload = env.get(\"CC_SESSION\");\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 420, - "y": 720, - "wires": [ - [ - "cc000005" - ] - ] - }, - { - "id": "cc000005", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Build auth request", - "func": "const sessionCookie = msg.payload;\nif (!sessionCookie || sessionCookie === '') {\n node.error('CC_SESSION env var is empty — set it in Node-RED Coffee-mations tab settings');\n return null;\n}\nmsg.url = 'https://account.coffeecircle.com/oauth/token';\nmsg.method = 'GET';\nmsg.headers = { 'Cookie': '_shopify_essential=' + sessionCookie };\nmsg.payload = '';\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 640, - "y": 720, - "wires": [ - [ - "cc000006" - ] - ] - }, - { - "id": "cc000006", - "type": "http request", - "z": "bbf25964.5edb38", - "name": "GET /oauth/token", - "method": "use", - "ret": "obj", - "paytoqs": "ignore", - "url": "", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "", - "senderr": false, - "headers": [], - "x": 880, - "y": 720, - "wires": [ - [ - "cc000007", - "cc00000f" - ] - ] - }, - { - "id": "cc000007", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Extract token + charges URL", - "func": "const resp = msg.payload;\nconst token = resp?.access_token || resp?.token || resp?.bearer_token || resp?.accessToken || resp?.id_token;\nif (!token) {\n node.error('/oauth/token response: ' + JSON.stringify(resp));\n return null;\n}\nflow.set('cc_token', token);\nconst today = new Date().toISOString().split('T')[0];\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges?status=queued,error,skipped&scheduledAtMin=' + today;\nmsg.method = 'GET';\nmsg.headers = { 'Authorization': 'Bearer ' + token };\nmsg.payload = '';\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1140, - "y": 720, - "wires": [ - [ - "cc000008" - ] - ] - }, - { - "id": "cc000008", - "type": "http request", - "z": "bbf25964.5edb38", - "name": "GET /charges", - "method": "use", - "ret": "obj", - "paytoqs": "ignore", - "url": "", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "", - "senderr": false, - "headers": [], - "x": 1360, - "y": 720, - "wires": [ - [ - "cc000009", - "cc000010" - ] - ] - }, - { - "id": "cc000009", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Parse charges → charge_id", - "func": "const resp = msg.payload;\nconst charges = resp?.charges || resp?.data || resp?.items || resp?.results || (Array.isArray(resp) ? resp : null);\nif (!charges || charges.length === 0) {\n node.error('No queued charges. Response: ' + JSON.stringify(resp).substring(0, 300));\n return null;\n}\nconst charge = charges[0];\nconst chargeId = charge?.id || charge?.charge_id;\nconst deliveryDate = charge?.scheduledAt || charge?.scheduled_at || charge?.next_billing_date || charge?.billing_date || charge?.ship_date;\nif (!chargeId) {\n node.error('Cannot extract charge ID. Keys: ' + Object.keys(charge || {}).join(', '));\n return null;\n}\nflow.set('cc_charge_id', String(chargeId));\nflow.set('cc_delivery_date', deliveryDate || 'unknown');\nconst token = flow.get('cc_token');\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges/' + chargeId;\nmsg.method = 'GET';\nmsg.headers = { 'Authorization': 'Bearer ' + token };\nmsg.payload = '';\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1600, - "y": 720, - "wires": [ - [ - "cc00000a" - ] - ] - }, - { - "id": "cc00000a", - "type": "http request", - "z": "bbf25964.5edb38", - "name": "GET /charges/", - "method": "use", - "ret": "obj", - "paytoqs": "ignore", - "url": "", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "", - "senderr": false, - "headers": [], - "x": 1840, - "y": 720, - "wires": [ - [ - "cc00000b", - "cc000011" - ] - ] - }, - { - "id": "cc00000b", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Parse detail → 3 sensors", - "func": "const resp = msg.payload;\nconst charge = resp?.charge || resp?.data || resp;\nconst lineItems = charge?.lineItems || charge?.line_items || charge?.items || [];\nconst firstItem = lineItems[0] || {};\nconst product = firstItem.title || firstItem.product_title || firstItem.name || charge?.product_title || 'Coffee subscription';\nconst totalObj = charge?.totalAmount || {};\nconst totalVal = totalObj?.amount || charge?.total_price || charge?.total || '?';\nconst currency = totalObj?.currencyCode || 'EUR';\nconst currencySymbol = { EUR: '€', USD: '$', GBP: '£' }[currency] || currency + ' ';\nconst total = currencySymbol + totalVal;\nconst deliveryDate = flow.get('cc_delivery_date') || charge?.scheduledAt || charge?.scheduled_at || 'unknown';\nconst mkMsg = p => ({ _msgid: msg._msgid, payload: p });\nreturn [mkMsg(deliveryDate), mkMsg(product), mkMsg(total)];", - "outputs": 3, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 2080, - "y": 720, - "wires": [ - [ - "cc00000c" - ], - [ - "cc00000d" - ], - [ - "cc00000e" - ] - ] - }, - { - "id": "cc00000c", - "type": "ha-sensor", - "z": "bbf25964.5edb38", - "name": "cc_next_delivery_date", - "entityConfig": "cc000023", - "version": 1, - "state": "payload", - "stateType": "msg", - "attributes": [], - "inputOverride": "allow", - "outputProperties": [], - "x": 2340, - "y": 680, - "wires": [ - [] - ] - }, - { - "id": "cc00000e", - "type": "ha-sensor", - "z": "bbf25964.5edb38", - "name": "cc_next_delivery_total", - "entityConfig": "cc000025", - "version": 1, - "state": "payload", - "stateType": "msg", - "attributes": [], - "inputOverride": "allow", - "outputProperties": [], - "x": 2340, - "y": 760, - "wires": [ - [] - ] - }, - { - "id": "cc00000f", - "type": "debug", - "z": "bbf25964.5edb38", - "name": "Token response", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "payload", - "targetType": "msg", - "statusVal": "", - "statusType": "auto", - "x": 880, - "y": 800, - "wires": [] - }, - { - "id": "cc000010", - "type": "debug", - "z": "bbf25964.5edb38", - "name": "Charges response", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "payload", - "targetType": "msg", - "statusVal": "", - "statusType": "auto", - "x": 1360, - "y": 800, - "wires": [] - }, - { - "id": "cc000011", - "type": "debug", - "z": "bbf25964.5edb38", - "name": "Detail response", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "payload", - "targetType": "msg", - "statusVal": "", - "statusType": "auto", - "x": 1840, - "y": 800, - "wires": [] - }, - { - "id": "cc000012", - "type": "catch", - "z": "bbf25964.5edb38", - "name": "CC Errors", - "scope": [ - "cc000004", - "cc000005", - "cc000006", - "cc000007", - "cc000008", - "cc000009", - "cc00000a", - "cc00000b", - "cc000017", - "cc000018", - "cc000019", - "cc00001a", - "cc00001b", - "cc00001c", - "cc00001d" + "id": "558cbc9bafd7fda2", + "type": "switch", + "z": "52430f5e9f9ee267", + "name": "Check additional date for night ", + "property": "topic", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "night", + "vt": "str" + }, + { + "t": "else" + } ], - "uncaught": false, - "x": 160, - "y": 880, - "wires": [ - [ - "cc000013" - ] - ] - }, - { - "id": "cc000013", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Format error", - "func": "const errMsg = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nmsg.payload = JSON.stringify({\n title: 'Coffee Circle Error',\n message: errMsg + '\\n\\nIf auth error: update CC_SESSION env var in Node-RED tab settings.',\n notification_id: 'cc_integration_error'\n});\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 380, - "y": 880, - "wires": [ - [ - "cc000014" - ] - ] - }, - { - "id": "cc000014", - "type": "api-call-service", - "z": "bbf25964.5edb38", - "name": "Notify error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "areaId": [], - "deviceId": [], - "entityId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "domain": "persistent_notification", - "service": "create", - "x": 600, - "y": 880, - "wires": [ - [] - ] - }, - { - "id": "cc000015", - "type": "comment", - "z": "bbf25964.5edb38", - "name": "CC Send Now — triggers immediate delivery on button press", - "info": "", - "x": 290, - "y": 960, - "wires": [] - }, - { - "id": "cc000016", - "type": "ha-button", - "z": "bbf25964.5edb38", - "name": "CC Send Now button", - "version": 1, - "outputs": 1, - "entityConfig": "cc000026", - "outputProperties": [], - "x": 180, - "y": 1020, - "wires": [ - [ - "cc000017" - ] - ] - }, - { - "id": "cc000017", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Read session cookie", - "func": "msg.payload = env.get(\"CC_SESSION\");\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 400, - "y": 1020, - "wires": [ - [ - "cc000018" - ] - ] - }, - { - "id": "cc000018", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Build auth request", - "func": "const sessionCookie = msg.payload;\nif (!sessionCookie || sessionCookie === '') {\n node.error('CC_SESSION env var is empty — set it in Node-RED Coffee-mations tab settings');\n return null;\n}\nmsg.url = 'https://account.coffeecircle.com/oauth/token';\nmsg.method = 'GET';\nmsg.headers = { 'Cookie': '_shopify_essential=' + sessionCookie };\nmsg.payload = '';\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 640, - "y": 1020, - "wires": [ - [ - "cc000019" - ] - ] - }, - { - "id": "cc000019", - "type": "http request", - "z": "bbf25964.5edb38", - "name": "GET /oauth/token", - "method": "use", - "ret": "obj", - "paytoqs": "ignore", - "url": "", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "", - "senderr": false, - "headers": [], - "x": 880, - "y": 1020, - "wires": [ - [ - "cc00001a" - ] - ] - }, - { - "id": "cc00001a", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Extract token + charges URL", - "func": "const resp = msg.payload;\nconst token = resp?.access_token || resp?.token || resp?.bearer_token || resp?.accessToken || resp?.id_token;\nif (!token) {\n node.error('/oauth/token response: ' + JSON.stringify(resp));\n return null;\n}\nflow.set('cc_token', token);\nconst today = new Date().toISOString().split('T')[0];\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges?status=queued,error,skipped&scheduledAtMin=' + today;\nmsg.method = 'GET';\nmsg.headers = { 'Authorization': 'Bearer ' + token };\nmsg.payload = '';\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1140, - "y": 1020, - "wires": [ - [ - "cc00001b" - ] - ] - }, - { - "id": "cc00001b", - "type": "http request", - "z": "bbf25964.5edb38", - "name": "GET /charges", - "method": "use", - "ret": "obj", - "paytoqs": "ignore", - "url": "", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "", - "senderr": false, - "headers": [], - "x": 1360, - "y": 1020, - "wires": [ - [ - "cc00001c" - ] - ] - }, - { - "id": "cc00001c", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Extract charge_id + build process URL", - "func": "const resp = msg.payload;\nconst charges = resp?.charges || resp?.data || resp?.items || resp?.results || (Array.isArray(resp) ? resp : null);\nif (!charges || charges.length === 0) {\n node.error('No queued charges for Send Now');\n return null;\n}\nconst charge = charges[0];\nconst chargeId = charge?.id || charge?.charge_id;\nif (!chargeId) {\n node.error('Cannot extract charge ID. Keys: ' + Object.keys(charge || {}).join(', '));\n return null;\n}\nconst token = flow.get('cc_token');\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges/' + chargeId + '/process';\nmsg.method = 'POST';\nmsg.headers = { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' };\nmsg.payload = {};\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1620, - "y": 1020, - "wires": [ - [ - "cc00001d" - ] - ] - }, - { - "id": "cc00001d", - "type": "http request", - "z": "bbf25964.5edb38", - "name": "POST /charges//process", - "method": "use", - "ret": "obj", - "paytoqs": "ignore", - "url": "", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "", - "senderr": false, - "headers": [], - "x": 1880, - "y": 1020, - "wires": [ - [ - "cc00001e" - ] - ] - }, - { - "id": "cc00001e", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Check result", - "func": "const statusCode = msg.statusCode;\nif (statusCode >= 200 && statusCode < 300) {\n return [msg, null];\n}\nconst detail = JSON.stringify(msg.payload).substring(0, 200);\nmsg.payload = JSON.stringify({\n title: 'Coffee Circle Send Now Failed',\n message: 'HTTP ' + statusCode + ': ' + detail,\n notification_id: 'cc_send_now_error'\n});\nreturn [null, msg];", + "checkall": "true", + "repair": false, "outputs": 2, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 2100, - "y": 1020, + "x": 1090, + "y": 280, "wires": [ [ - "cc00001f" + "72abde726eb791b7", + "d88527a4c0207c0c" ], [ - "cc000020" + "d88527a4c0207c0c" ] ] }, { - "id": "cc00001f", - "type": "link out", - "z": "bbf25964.5edb38", - "name": "Trigger CC Fetch", - "mode": "link", - "links": [ - "cc000003" - ], - "x": 2320, - "y": 1000, - "wires": [] + "id": "72abde726eb791b7", + "type": "moment", + "z": "52430f5e9f9ee267", + "name": "Create date time for night tomorrow", + "topic": "night_tomorrow", + "input": "payload", + "inputType": "msg", + "inTz": "Europe/Berlin", + "adjAmount": "1", + "adjType": "days", + "adjDir": "add", + "format": "", + "locale": "en-US", + "output": "payload", + "outputType": "msg", + "outTz": "Europe/Berlin", + "x": 1460, + "y": 280, + "wires": [ + [ + "d88527a4c0207c0c" + ] + ] }, { - "id": "cc000020", - "type": "api-call-service", - "z": "bbf25964.5edb38", - "name": "Notify Send Now error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "areaId": [], - "deviceId": [], - "entityId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "domain": "persistent_notification", - "service": "create", - "x": 2340, - "y": 1060, + "id": "035b7bb98d69b0a0", + "type": "switch", + "z": "52430f5e9f9ee267", + "name": "Compare times", + "property": "payload.now", + "propertyType": "msg", + "rules": [ + { + "t": "lt", + "v": "payload.night", + "vt": "msg" + }, + { + "t": "btwn", + "v": "payload.night", + "vt": "msg", + "v2": "payload.morning", + "v2t": "msg" + }, + { + "t": "btwn", + "v": "payload.morning", + "vt": "msg", + "v2": "payload.midday", + "v2t": "msg" + }, + { + "t": "btwn", + "v": "payload.midday", + "vt": "msg", + "v2": "payload.late_afternoon", + "v2t": "msg" + }, + { + "t": "btwn", + "v": "payload.late_afternoon", + "vt": "msg", + "v2": "payload.evening", + "v2t": "msg" + }, + { + "t": "btwn", + "v": "payload.evening", + "vt": "msg", + "v2": "payload.late_evening", + "v2t": "msg" + }, + { + "t": "btwn", + "v": "payload.late_evening", + "vt": "msg", + "v2": "payload.night_tomorrow", + "v2t": "msg" + }, + { + "t": "else" + } + ], + "checkall": "false", + "repair": false, + "outputs": 8, + "x": 1080, + "y": 520, + "wires": [ + [ + "25b5aff2dea58057" + ], + [ + "5f0e5f63552a97f2" + ], + [ + "b884e557f9524784" + ], + [ + "06f7380c6f28bdd1" + ], + [ + "41de38d16e68d1d9" + ], + [ + "4d992d3713228542" + ], + [ + "25b5aff2dea58057" + ], + [ + "5f0e5f63552a97f2" + ] + ] + }, + { + "id": "b884e557f9524784", + "type": "change", + "z": "52430f5e9f9ee267", + "name": "It's morning", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "morning", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1490, + "y": 440, "wires": [ [] ] }, { - "id": "cc000028", - "type": "comment", - "z": "bbf25964.5edb38", - "name": "CC Postpone by 1 Week — postpones delivery by 7 days on button press", - "info": "", - "x": 280, - "y": 1260, + "id": "06f7380c6f28bdd1", + "type": "change", + "z": "52430f5e9f9ee267", + "name": "It's midday", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "midday", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1490, + "y": 480, + "wires": [ + [] + ] + }, + { + "id": "41de38d16e68d1d9", + "type": "change", + "z": "52430f5e9f9ee267", + "name": "It's late afternoon", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "late_afternoon", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1510, + "y": 520, + "wires": [ + [] + ] + }, + { + "id": "4d992d3713228542", + "type": "change", + "z": "52430f5e9f9ee267", + "name": "It's evening", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "evening", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1490, + "y": 560, + "wires": [ + [] + ] + }, + { + "id": "25b5aff2dea58057", + "type": "change", + "z": "52430f5e9f9ee267", + "name": "It's late evening", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "late_evening", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1500, + "y": 600, + "wires": [ + [] + ] + }, + { + "id": "5f0e5f63552a97f2", + "type": "change", + "z": "52430f5e9f9ee267", + "name": "It's night", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "night", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1480, + "y": 640, + "wires": [ + [] + ] + }, + { + "id": "ca40f18fea0361e5", + "type": "moment", + "z": "52430f5e9f9ee267", + "name": "Add current date time", + "topic": "now", + "input": "", + "inputType": "date", + "inTz": "Europe/Berlin", + "adjAmount": "0", + "adjType": "days", + "adjDir": "add", + "format": "", + "locale": "en-US", + "output": "payload", + "outputType": "msg", + "outTz": "Europe/Berlin", + "x": 760, + "y": 220, + "wires": [ + [ + "d88527a4c0207c0c" + ] + ] + }, + { + "id": "00fdb1bc99d82683", + "type": "change", + "z": "52430f5e9f9ee267", + "name": "Clean up msg object", + "rules": [ + { + "t": "delete", + "p": "settings", + "pt": "msg" + }, + { + "t": "delete", + "p": "topic", + "pt": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1060, + "y": 420, + "wires": [ + [ + "035b7bb98d69b0a0" + ] + ] + }, + { + "id": "94df66c8.23c748", + "type": "switch", + "z": "c0a0e0.ae6cbf2", + "name": "Direction", + "property": "direction", + "propertyType": "flow", + "rules": [ + { + "t": "eq", + "v": "up", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 820, + "y": 220, + "wires": [ + [ + "488569b9.ed45a8" + ], + [ + "be09eac4.e90d18" + ] + ] + }, + { + "id": "488569b9.ed45a8", + "type": "change", + "z": "c0a0e0.ae6cbf2", + "name": "Set direction down", + "rules": [ + { + "t": "set", + "p": "direction", + "pt": "flow", + "to": "down", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1040, + "y": 180, + "wires": [ + [ + "de7aef74.e638b" + ] + ] + }, + { + "id": "be09eac4.e90d18", + "type": "change", + "z": "c0a0e0.ae6cbf2", + "name": "Set direction up", + "rules": [ + { + "t": "set", + "p": "direction", + "pt": "flow", + "to": "up", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1030, + "y": 260, + "wires": [ + [ + "32ce8567.49120a" + ] + ] + }, + { + "id": "da116e59.611b2", + "type": "mqtt out", + "z": "c0a0e0.ae6cbf2", + "name": "", + "topic": "", + "qos": "", + "retain": "", + "respTopic": "", + "contentType": "", + "userProps": "", + "correl": "", + "expiry": "", + "broker": "d51b5899.a2d5d8", + "x": 1520, + "y": 180, "wires": [] }, { - "id": "cc000029", - "type": "ha-button", - "z": "bbf25964.5edb38", - "name": "CC Postpone 1 week", - "version": 1, - "outputs": 1, - "entityConfig": "cc000027", - "outputProperties": [], - "x": 180, - "y": 1320, + "id": "de7aef74.e638b", + "type": "change", + "z": "c0a0e0.ae6cbf2", + "name": "MQTT message UP", + "rules": [ + { + "t": "set", + "p": "topic", + "pt": "msg", + "to": "topic", + "tot": "env" + }, + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_move\": 70}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1280, + "y": 180, "wires": [ [ - "cc00002a" + "da116e59.611b2" ] ] }, { - "id": "cc00002a", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Read session cookie", - "func": "msg.payload = env.get('CC_SESSION');\nflow.set('cc_session_cookie', msg.payload);\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 400, - "y": 1320, + "id": "5f89dab8.652954", + "type": "mqtt out", + "z": "c0a0e0.ae6cbf2", + "name": "", + "topic": "", + "qos": "", + "retain": "", + "broker": "d51b5899.a2d5d8", + "x": 1520, + "y": 260, + "wires": [] + }, + { + "id": "32ce8567.49120a", + "type": "change", + "z": "c0a0e0.ae6cbf2", + "name": "MQTT message DOWN", + "rules": [ + { + "t": "set", + "p": "topic", + "pt": "msg", + "to": "topic", + "tot": "env" + }, + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_move\": -70}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1300, + "y": 260, "wires": [ [ - "cc00002b" + "5f89dab8.652954" ] ] }, { - "id": "cc00002b", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Build auth request", - "func": "const sessionCookie = msg.payload;\nif (!sessionCookie || sessionCookie === '') {\n node.error('CC_SESSION env var is empty — set it in Node-RED Coffee-mations tab settings');\n return null;\n}\nmsg.url = 'https://account.coffeecircle.com/oauth/token';\nmsg.method = 'GET';\nmsg.headers = { 'Cookie': '_shopify_essential=' + sessionCookie };\nmsg.payload = '';\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 640, - "y": 1320, + "id": "bad6cfaf.6876d", + "type": "mqtt out", + "z": "c0a0e0.ae6cbf2", + "name": "", + "topic": "", + "qos": "", + "retain": "", + "respTopic": "", + "contentType": "", + "userProps": "", + "correl": "", + "expiry": "", + "broker": "d51b5899.a2d5d8", + "x": 1090, + "y": 340, + "wires": [] + }, + { + "id": "370e7b7e.f5dca4", + "type": "change", + "z": "c0a0e0.ae6cbf2", + "name": "MQTT message STOP", + "rules": [ + { + "t": "set", + "p": "topic", + "pt": "msg", + "to": "topic", + "tot": "env" + }, + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_move\": 0}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 860, + "y": 340, "wires": [ [ - "cc00002c" + "bad6cfaf.6876d" ] ] }, { - "id": "cc00002c", - "type": "http request", - "z": "bbf25964.5edb38", - "name": "GET /oauth/token", - "method": "use", - "ret": "obj", - "paytoqs": "ignore", - "url": "", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "", - "senderr": false, - "headers": [], - "x": 880, - "y": 1320, + "id": "96ea6236.ce35a", + "type": "mqtt out", + "z": "c0a0e0.ae6cbf2", + "name": "", + "topic": "", + "qos": "", + "retain": "", + "broker": "d51b5899.a2d5d8", + "x": 1090, + "y": 460, + "wires": [] + }, + { + "id": "7e1107c0.6c8b38", + "type": "change", + "z": "c0a0e0.ae6cbf2", + "name": "MQTT message TOGGLE", + "rules": [ + { + "t": "set", + "p": "topic", + "pt": "msg", + "to": "topic", + "tot": "env" + }, + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"state\": \"TOGGLE\"}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 870, + "y": 460, "wires": [ [ - "cc00002d" + "96ea6236.ce35a" ] ] }, { - "id": "cc00002d", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Extract token + charges URL", - "func": "const resp = msg.payload;\nconst token = resp?.access_token || resp?.token || resp?.bearer_token || resp?.accessToken || resp?.id_token;\nif (!token) {\n node.error('/oauth/token response: ' + JSON.stringify(resp));\n return null;\n}\nflow.set('cc_token', token);\nconst today = new Date().toISOString().split('T')[0];\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges?status=queued,error,skipped&scheduledAtMin=' + today;\nmsg.method = 'GET';\nmsg.headers = { 'Authorization': 'Bearer ' + token };\nmsg.payload = '';\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1140, - "y": 1320, - "wires": [ - [ - "cc00002e" - ] - ] - }, - { - "id": "cc00002e", - "type": "http request", - "z": "bbf25964.5edb38", - "name": "GET /charges", - "method": "use", - "ret": "obj", - "paytoqs": "ignore", - "url": "", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "", - "senderr": false, - "headers": [], - "x": 1360, - "y": 1320, - "wires": [ - [ - "cc00002f" - ] - ] - }, - { - "id": "cc00002f", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Extract charge_id + build reschedule", - "func": "const resp = msg.payload;\nconst charges = resp?.charges || resp?.data || resp?.items || resp?.results || (Array.isArray(resp) ? resp : null);\nif (!charges || charges.length === 0) {\n node.error('No queued charges for Postpone');\n return null;\n}\nconst charge = charges[0];\nconst chargeId = charge?.id || charge?.charge_id;\nif (!chargeId) {\n node.error('Cannot extract charge ID. Keys: ' + Object.keys(charge || {}).join(', '));\n return null;\n}\nflow.set('cc_charge_id', String(chargeId));\n// Read delivery date from HA state cache\nconst states = global.get('homeassistant')?.homeAssistantLatest?.states;\nconst dateStr = states?.['sensor.cc_next_delivery_date']?.state || flow.get('cc_delivery_date');\nif (!dateStr || dateStr === 'unknown' || dateStr === 'unavailable') {\n node.error('Cannot read current delivery date from HA state: ' + dateStr);\n return null;\n}\nconst d = new Date(dateStr);\nd.setDate(d.getDate() + 7);\nconst newDate = d.toISOString().split('T')[0];\nconst token = flow.get('cc_token');\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges/' + chargeId + '/reschedule';\nmsg.method = 'PUT';\nmsg.headers = { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' };\nmsg.payload = { scheduledAt: newDate };\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1620, - "y": 1320, - "wires": [ - [ - "cc000030" - ] - ] - }, - { - "id": "cc000030", - "type": "http request", - "z": "bbf25964.5edb38", - "name": "PUT /reschedule", - "method": "use", - "ret": "obj", - "paytoqs": "ignore", - "url": "", - "tls": "", - "persist": false, - "proxy": "", - "insecureHTTPParser": false, - "authType": "", - "senderr": false, - "headers": [], - "x": 1880, - "y": 1320, - "wires": [ - [ - "cc000031" - ] - ] - }, - { - "id": "cc000031", - "type": "function", - "z": "bbf25964.5edb38", - "name": "Check reschedule result", - "func": "const statusCode = msg.statusCode;\nif (statusCode >= 200 && statusCode < 300) {\n return [msg, null, null];\n}\nif (statusCode === 401 && !msg._retried) {\n msg._retried = true;\n msg.payload = flow.get('cc_session_cookie');\n return [null, msg, null];\n}\nconst detail = JSON.stringify(msg.payload).substring(0, 200);\nmsg.payload = JSON.stringify({\n title: 'Coffee Circle Postpone Failed',\n message: 'HTTP ' + statusCode + ': ' + detail,\n notification_id: 'cc_postpone_error'\n});\nreturn [null, null, msg];", + "id": "821795d7.433b58", + "type": "switch", + "z": "c0a0e0.ae6cbf2", + "name": "Action", + "property": "payload", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "dim", + "vt": "str" + }, + { + "t": "eq", + "v": "stop", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "true", + "repair": false, "outputs": 3, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 2100, - "y": 1320, + "x": 630, + "y": 340, "wires": [ [ - "cc000032" + "94df66c8.23c748" ], [ - "cc00002b" + "370e7b7e.f5dca4" ], [ - "cc000033" + "7e1107c0.6c8b38" ] ] }, { - "id": "cc000032", - "type": "link out", - "z": "bbf25964.5edb38", - "name": "Trigger CC Fetch", - "mode": "link", - "links": [ - "cc000003" - ], - "x": 2320, - "y": 1300, - "wires": [] + "id": "a93b68e3e83b1d25", + "type": "moment", + "z": "be8264a322721305", + "name": "Format to HH:mm", + "topic": "", + "input": "payload", + "inputType": "msg", + "inTz": "Europe/Berlin", + "adjAmount": "5", + "adjType": "minutes", + "adjDir": "add", + "format": "HH:mm", + "locale": "en-GB", + "output": "payload", + "outputType": "msg", + "outTz": "Europe/Berlin", + "x": 290, + "y": 100, + "wires": [ + [ + "0dc0142b97a1bdc7" + ] + ] }, { - "id": "cc000033", - "type": "api-call-service", - "z": "bbf25964.5edb38", - "name": "Notify postpone error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "areaId": [], - "deviceId": [], - "entityId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "domain": "persistent_notification", - "service": "create", - "x": 2340, - "y": 1360, + "id": "7a1e6b58aaf9559f", + "type": "schedex", + "z": "be8264a322721305", + "name": "Timer", + "passthroughunhandled": true, + "suspended": false, + "lat": "", + "lon": "", + "ontime": "", + "ontopic": "", + "onpayload": "", + "onoffset": 0, + "onrandomoffset": 0, + "offtime": "", + "offtopic": "", + "offpayload": "", + "offoffset": 0, + "offrandomoffset": 0, + "mon": true, + "tue": true, + "wed": true, + "thu": true, + "fri": true, + "sat": true, + "sun": true, + "x": 710, + "y": 100, "wires": [ [] ] }, { - "id": "cc00000d", - "type": "ha-sensor", - "z": "bbf25964.5edb38", - "name": "cc_next_delivery_product", - "entityConfig": "cc000024", - "version": 1, - "state": "payload", - "stateType": "msg", - "attributes": [], - "inputOverride": "allow", - "outputProperties": [], - "x": 2340, - "y": 720, + "id": "0dc0142b97a1bdc7", + "type": "string", + "z": "be8264a322721305", + "name": "Prepend ontime", + "methods": [ + { + "name": "prepend", + "params": [ + { + "type": "str", + "value": "ontime " + } + ] + } + ], + "prop": "payload", + "propout": "payload", + "object": "msg", + "objectout": "msg", + "x": 520, + "y": 100, "wires": [ - [] + [ + "7a1e6b58aaf9559f" + ] ] }, { @@ -2161,49 +2150,49 @@ "wires": [] }, { - "id": "p2catch_sec", + "id": "err600f7a12_c", "type": "catch", "z": "600f7a12.5ee66c", - "name": "Catch all errors", + "name": "Tab errors", "scope": null, "uncaught": false, - "x": 160, - "y": 460, + "x": 100, + "y": 440, "wires": [ [ - "p2fmt_sec" + "err600f7a12_f" ] ] }, { - "id": "p2fmt_sec", + "id": "err600f7a12_f", "type": "function", "z": "600f7a12.5ee66c", "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Security',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Security\", data: { priority: 1 } });\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 400, - "y": 460, + "x": 340, + "y": 440, "wires": [ [ - "p2ntfy_sec" + "err600f7a12_s" ] ] }, { - "id": "p2ntfy_sec", + "id": "err600f7a12_s", "type": "api-call-service", "z": "600f7a12.5ee66c", - "name": "Notify error", + "name": "gotify_nodered", "server": "657c7463.48e1e4", "version": 7, "debugenabled": false, - "action": "notify.gotify_ha", + "action": "notify.gotify_nodered", "floorId": [], "areaId": [], "deviceId": [], @@ -2217,11 +2206,3745 @@ "queue": "none", "blockInputOverrides": false, "domain": "notify", + "service": "gotify_nodered", + "x": 580, + "y": 440, + "wires": [ + [] + ] + }, + { + "id": "ecee1bee9953f98a", + "type": "ha-get-entities", + "z": "a320f821a7cb3f55", + "name": "Low Bat Sensors", + "server": "657c7463.48e1e4", + "version": 1, + "rules": [ + { + "property": "entity_id", + "logic": "is", + "value": ".*low_bat.*", + "valueType": "re" + }, + { + "property": "attributes.battery", + "logic": "is_not", + "value": "High", + "valueType": "str" + } + ], + "outputType": "array", + "outputEmptyResults": false, + "outputLocationType": "msg", + "outputLocation": "payload", + "outputResultsCount": 1, + "x": 550, + "y": 180, + "wires": [ + [ + "5f8552a4635072aa" + ] + ] + }, + { + "id": "1b30535ba22c4655", + "type": "inject", + "z": "a320f821a7cb3f55", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 100, + "y": 320, + "wires": [ + [ + "293113adda48f9d0" + ] + ] + }, + { + "id": "b9891a936c8fb9d0", + "type": "debug", + "z": "a320f821a7cb3f55", + "name": "debug 3", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 1040, + "y": 540, + "wires": [] + }, + { + "id": "556cc66d606c190e", + "type": "ha-get-entities", + "z": "a320f821a7cb3f55", + "name": "Battery Sensors - Low", + "server": "657c7463.48e1e4", + "version": 1, + "rules": [ + { + "property": "entity_id", + "logic": "is", + "value": ".*battery.*", + "valueType": "re" + }, + { + "property": "attributes.state_class", + "logic": "is", + "value": "measurement", + "valueType": "str" + }, + { + "property": "state", + "logic": "lt", + "value": "10", + "valueType": "num" + } + ], + "outputType": "array", + "outputEmptyResults": false, + "outputLocationType": "msg", + "outputLocation": "payload", + "outputResultsCount": 1, + "x": 560, + "y": 300, + "wires": [ + [ + "5f8552a4635072aa" + ] + ] + }, + { + "id": "1e34ff50a693e724", + "type": "ha-get-entities", + "z": "a320f821a7cb3f55", + "name": "Battery Sensors", + "server": "657c7463.48e1e4", + "version": 1, + "rules": [ + { + "property": "entity_id", + "logic": "is", + "value": ".*battery.*", + "valueType": "re" + } + ], + "outputType": "array", + "outputEmptyResults": false, + "outputLocationType": "msg", + "outputLocation": "payload", + "outputResultsCount": 1, + "x": 540, + "y": 540, + "wires": [ + [ + "b9891a936c8fb9d0" + ] + ] + }, + { + "id": "89a7c77a676b858b", + "type": "ha-get-entities", + "z": "a320f821a7cb3f55", + "name": "Battery Sensors - Unavailable", + "server": "657c7463.48e1e4", + "version": 1, + "rules": [ + { + "property": "entity_id", + "logic": "is", + "value": ".*battery.*", + "valueType": "re" + }, + { + "property": "attributes.state_class", + "logic": "is", + "value": "measurement", + "valueType": "str" + }, + { + "property": "state", + "logic": "is", + "value": "unavailable", + "valueType": "str" + } + ], + "outputType": "array", + "outputEmptyResults": false, + "outputLocationType": "msg", + "outputLocation": "payload", + "outputResultsCount": 1, + "x": 590, + "y": 420, + "wires": [ + [] + ] + }, + { + "id": "91f002d04003ce84", + "type": "comment", + "z": "a320f821a7cb3f55", + "name": "Filter for all *battery* entities", + "info": "", + "x": 580, + "y": 500, + "wires": [] + }, + { + "id": "ac0b28356c7eb45a", + "type": "comment", + "z": "a320f821a7cb3f55", + "name": "HomeMatic Devices", + "info": "", + "x": 550, + "y": 140, + "wires": [] + }, + { + "id": "a8192e1fcbdc41aa", + "type": "comment", + "z": "a320f821a7cb3f55", + "name": "Hue devices", + "info": "", + "x": 530, + "y": 260, + "wires": [] + }, + { + "id": "6beef06f4f0b788d", + "type": "comment", + "z": "a320f821a7cb3f55", + "name": "Any unavailable device", + "info": "", + "x": 560, + "y": 380, + "wires": [] + }, + { + "id": "5f8552a4635072aa", + "type": "split", + "z": "a320f821a7cb3f55", + "name": "", + "splt": "\\n", + "spltType": "str", + "arraySplt": 1, + "arraySpltType": "len", + "stream": false, + "addname": "", + "x": 850, + "y": 300, + "wires": [ + [ + "9dcd82782246d4e9" + ] + ] + }, + { + "id": "cc33a58286775199", + "type": "api-call-service", + "z": "a320f821a7cb3f55", + "name": "Notify via HA", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "notify.gotify_ha", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "{\"title\":\"warning\",\"message\":\"{{{payload}}}\"}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "notify", "service": "gotify_ha", "output_location": "", "output_location_type": "none", + "x": 1270, + "y": 300, + "wires": [ + [] + ] + }, + { + "id": "9dcd82782246d4e9", + "type": "template", + "z": "a320f821a7cb3f55", + "name": "", + "field": "payload", + "fieldType": "msg", + "format": "handlebars", + "syntax": "mustache", + "template": "Battery level low for {{payload.attributes.friendly_name}} ({{payload.state}}%)", + "output": "str", + "x": 1060, + "y": 300, + "wires": [ + [ + "cc33a58286775199" + ] + ] + }, + { + "id": "293113adda48f9d0", + "type": "schedex", + "z": "a320f821a7cb3f55", + "name": "Saturday at 11:00", + "passthroughunhandled": true, + "suspended": false, + "lat": "", + "lon": "", + "ontime": "11:00", + "ontopic": "", + "onpayload": "", + "onoffset": 0, + "onrandomoffset": 0, + "offtime": "", + "offtopic": "", + "offpayload": "", + "offoffset": 0, + "offrandomoffset": 0, + "mon": false, + "tue": false, + "wed": false, + "thu": false, + "fri": true, + "sat": true, + "sun": false, + "x": 150, + "y": 200, + "wires": [ + [ + "ecee1bee9953f98a", + "556cc66d606c190e", + "89a7c77a676b858b" + ] + ] + }, + { + "id": "edaf40fcc105703a", + "type": "comment", + "z": "a320f821a7cb3f55", + "name": "Battery state alerts for all devices", + "info": "", + "x": 190, + "y": 160, + "wires": [] + }, + { + "id": "e4eda627074a2cf3", + "type": "comment", + "z": "a320f821a7cb3f55", + "name": "Unavailable devices alert", + "info": "Any devices that becomes unavailable in Home Assistant will be reported. This might indicate zigbee connecticity issues.", + "x": 150, + "y": 620, + "wires": [] + }, + { + "id": "a2a4917908eed983", + "type": "trigger-state", + "z": "a320f821a7cb3f55", + "d": true, + "name": "", + "server": "657c7463.48e1e4", + "version": 5, + "inputs": 0, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [], + "substring": [], + "regex": [ + ".*" + ] + }, + "debugEnabled": false, + "constraints": [ + { + "targetType": "this_entity", + "targetValue": "", + "propertyType": "current_state", + "propertyValue": "new_state.state", + "comparatorType": "is", + "comparatorValueDatatype": "str", + "comparatorValue": "unavailable" + } + ], + "customOutputs": [], + "outputInitially": false, + "stateType": "str", + "enableInput": false, + "x": 120, + "y": 660, + "wires": [ + [ + "deb32f94b6f9aad7" + ], + [] + ] + }, + { + "id": "deb32f94b6f9aad7", + "type": "debug", + "z": "a320f821a7cb3f55", + "name": "State changed debug", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 540, + "y": 660, + "wires": [] + }, + { + "id": "comment-heos-individual", + "type": "comment", + "z": "a320f821a7cb3f55", + "name": "HEOS individual speaker reset via TCP", + "info": "", + "x": 190, + "y": 760, + "wires": [] + }, + { + "id": "comment-heos-all", + "type": "comment", + "z": "a320f821a7cb3f55", + "name": "HEOS reset all speakers sequentially", + "info": "", + "x": 190, + "y": 1060, + "wires": [] + }, + { + "id": "heos-trigger-bedroom", + "type": "server-state-changed", + "z": "a320f821a7cb3f55", + "name": "Reset Speaker Bedroom", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.reset_speaker_bedroom" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + }, + { + "property": "speaker", + "propertyType": "msg", + "value": "Bedroom", + "valueType": "str" + }, + { + "property": "ip", + "propertyType": "msg", + "value": "192.168.1.XXX", + "valueType": "str" + } + ], + "x": 150, + "y": 800, + "wires": [ + [ + "heos-change-target" + ] + ] + }, + { + "id": "heos-trigger-kitchen", + "type": "server-state-changed", + "z": "a320f821a7cb3f55", + "name": "Reset Speaker Kitchen", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.reset_speaker_kitchen" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + }, + { + "property": "speaker", + "propertyType": "msg", + "value": "Kitchen", + "valueType": "str" + }, + { + "property": "ip", + "propertyType": "msg", + "value": "192.168.1.XXX", + "valueType": "str" + } + ], + "x": 140, + "y": 860, + "wires": [ + [ + "heos-change-target" + ] + ] + }, + { + "id": "heos-trigger-bathroom", + "type": "server-state-changed", + "z": "a320f821a7cb3f55", + "name": "Reset Speaker Bathroom", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.reset_speaker_bathroom" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + }, + { + "property": "speaker", + "propertyType": "msg", + "value": "Bathroom", + "valueType": "str" + }, + { + "property": "ip", + "propertyType": "msg", + "value": "192.168.1.XXX", + "valueType": "str" + } + ], + "x": 150, + "y": 920, + "wires": [ + [ + "heos-change-target" + ] + ] + }, + { + "id": "heos-trigger-hometheater", + "type": "server-state-changed", + "z": "a320f821a7cb3f55", + "name": "Reset Speaker Home Theater", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.reset_speaker_home_theater" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + }, + { + "property": "speaker", + "propertyType": "msg", + "value": "Home Theater", + "valueType": "str" + }, + { + "property": "ip", + "propertyType": "msg", + "value": "192.168.1.XXX", + "valueType": "str" + } + ], + "x": 160, + "y": 980, + "wires": [ + [ + "heos-change-target" + ] + ] + }, + { + "id": "heos-change-target", + "type": "change", + "z": "a320f821a7cb3f55", + "name": "Set speaker target", + "rules": [ + { + "t": "set", + "p": "host", + "pt": "msg", + "to": "ip", + "tot": "msg" + }, + { + "t": "set", + "p": "port", + "pt": "msg", + "to": "1255", + "tot": "num" + }, + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "heos://system/reboot\r\n", + "tot": "str" + }, + { + "t": "set", + "p": "topic", + "pt": "msg", + "to": "\"Reboot \" & msg.speaker & \" @ \" & msg.ip & \":1255\"", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 450, + "y": 880, + "wires": [ + [ + "heos-tcp", + "heos-debug" + ] + ] + }, + { + "id": "heos-tcp", + "type": "tcp request", + "z": "a320f821a7cb3f55", + "name": "Telnet HEOS", + "server": "", + "port": "", + "out": "immed", + "ret": "string", + "splitc": "0", + "newline": "", + "trim": false, + "tls": "", + "x": 670, + "y": 880, + "wires": [ + [] + ] + }, + { + "id": "heos-debug", + "type": "debug", + "z": "a320f821a7cb3f55", + "name": "HEOS command (debug)", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "true", + "targetType": "full", + "statusVal": "", + "statusType": "auto", + "x": 710, + "y": 960, + "wires": [] + }, + { + "id": "heos-trigger-all", + "type": "server-state-changed", + "z": "a320f821a7cb3f55", + "name": "Reset All Speakers", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.reset_all_speakers" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 130, + "y": 1100, + "wires": [ + [ + "heos-emit-all" + ] + ] + }, + { + "id": "heos-emit-all", + "type": "function", + "z": "a320f821a7cb3f55", + "name": "Emit 4 button presses", + "func": "const buttons = [\n \"input_button.reset_speaker_bedroom\",\n \"input_button.reset_speaker_kitchen\",\n \"input_button.reset_speaker_bathroom\",\n \"input_button.reset_speaker_home_theater\"\n];\nreturn [buttons.map(b => ({ ...msg, payload: b }))];", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 440, + "y": 1100, + "wires": [ + [ + "heos-delay-all" + ] + ] + }, + { + "id": "heos-delay-all", + "type": "delay", + "z": "a320f821a7cb3f55", + "name": "5s between resets", + "pauseType": "rate", + "timeout": "5", + "timeoutUnits": "seconds", + "rate": "1", + "nbRateUnits": "5", + "rateUnits": "second", + "randomFirst": "1", + "randomLast": "5", + "randomUnits": "seconds", + "drop": false, + "allowrate": false, + "outputs": 1, + "x": 690, + "y": 1100, + "wires": [ + [ + "heos-service-press" + ] + ] + }, + { + "id": "heos-service-press", + "type": "api-call-service", + "z": "a320f821a7cb3f55", + "name": "Press speaker reset button", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "input_button.press", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "{\"entity_id\": payload}", + "dataType": "jsonata", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "input_button", + "service": "press", + "x": 1000, + "y": 1100, + "wires": [ + [] + ] + }, + { + "id": "erra320f821_c", + "type": "catch", + "z": "a320f821a7cb3f55", + "name": "Tab errors", + "scope": null, + "uncaught": false, + "x": 100, + "y": 1200, + "wires": [ + [ + "erra320f821_f" + ] + ] + }, + { + "id": "erra320f821_f", + "type": "function", + "z": "a320f821a7cb3f55", + "name": "Format error", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Maintenance\", data: { priority: 1 } });\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 340, + "y": 1200, + "wires": [ + [ + "erra320f821_s" + ] + ] + }, + { + "id": "erra320f821_s", + "type": "api-call-service", + "z": "a320f821a7cb3f55", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "notify", + "service": "gotify_nodered", + "x": 580, + "y": 1200, + "wires": [ + [] + ] + }, + { + "id": "bc24bd25f183a7ac", + "type": "inject", + "z": "f02b32ef07b4b378", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 140, + "y": 1760, + "wires": [ + [ + "3b572aa5a025838b" + ] + ] + }, + { + "id": "3b572aa5a025838b", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Join media players", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.join", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "media_player.bathroom" + ], + "labelId": [], + "data": "{\"group_members\":[\"media_player.kitchen\",\"media_player.bedroom\"]}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "join", + "x": 370, + "y": 1760, + "wires": [ + [ + "ed251e315e4c2c9f" + ] + ] + }, + { + "id": "ed251e315e4c2c9f", + "type": "debug", + "z": "f02b32ef07b4b378", + "name": "debug 8", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", "x": 660, - "y": 460, + "y": 1760, + "wires": [] + }, + { + "id": "7ad8e1f3e2e0968a", + "type": "inject", + "z": "f02b32ef07b4b378", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "", + "payloadType": "date", + "x": 140, + "y": 1840, + "wires": [ + [ + "b298882274d1cdf3" + ] + ] + }, + { + "id": "b298882274d1cdf3", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Unjoin media players", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.unjoin", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "media_player.bathroom", + "media_player.bedroom", + "media_player.kitchen" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "unjoin", + "x": 380, + "y": 1840, + "wires": [ + [ + "bdd2b9572315b352" + ] + ] + }, + { + "id": "bdd2b9572315b352", + "type": "debug", + "z": "f02b32ef07b4b378", + "name": "debug 9", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 660, + "y": 1840, + "wires": [] + }, + { + "id": "a17410f072874366", + "type": "inject", + "z": "f02b32ef07b4b378", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "true", + "payloadType": "bool", + "x": 130, + "y": 1960, + "wires": [ + [ + "d94c32c408534cea" + ] + ] + }, + { + "id": "d94c32c408534cea", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Unmute/Mute media players", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.volume_mute", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "media_player.bathroom", + "media_player.bedroom", + "media_player.kitchen" + ], + "labelId": [], + "data": "{\"is_volume_muted\": {{{payload}}} }", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "volume_mute", + "x": 400, + "y": 1960, + "wires": [ + [ + "c262b732d4b31093" + ] + ] + }, + { + "id": "c262b732d4b31093", + "type": "debug", + "z": "f02b32ef07b4b378", + "name": "debug 10", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 660, + "y": 1960, + "wires": [] + }, + { + "id": "023b11d63a8f319c", + "type": "inject", + "z": "f02b32ef07b4b378", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "false", + "payloadType": "bool", + "x": 130, + "y": 2020, + "wires": [ + [ + "d94c32c408534cea" + ] + ] + }, + { + "id": "947aef7d0b37c64e", + "type": "inject", + "z": "f02b32ef07b4b378", + "name": "", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "true", + "payloadType": "bool", + "x": 130, + "y": 2100, + "wires": [ + [ + "b14ca76bd3f6d739" + ] + ] + }, + { + "id": "b14ca76bd3f6d739", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Set volume to 20", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.volume_set", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "media_player.bathroom", + "media_player.bedroom", + "media_player.kitchen", + "media_player.heos_multiroom" + ], + "labelId": [], + "data": "{\"volume_level\": 0.2 }", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "volume_set", + "x": 370, + "y": 2100, + "wires": [ + [ + "7ff52464dc77aa88" + ] + ] + }, + { + "id": "7ff52464dc77aa88", + "type": "debug", + "z": "f02b32ef07b4b378", + "name": "debug 12", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 660, + "y": 2100, + "wires": [] + }, + { + "id": "b35f9365319a9bd4", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Kitchen motion sensor", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "62ed34c9191cebca", + "entities": { + "entity": [ + "binary_sensor.kitchen_motion_sensor_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "on", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 140, + "y": 560, + "wires": [ + [], + [] + ] + }, + { + "id": "643f64eeb88d0dc2", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Bedroom motion sensor", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "62ed34c9191cebca", + "entities": { + "entity": [ + "binary_sensor.bedroom_motion_sensor_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "on", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 140, + "y": 620, + "wires": [ + [], + [] + ] + }, + { + "id": "b613959939f3fdb7", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Kitchen motion sensor", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "62ed34c9191cebca", + "entities": { + "entity": [ + "binary_sensor.kitchen_motion_sensor_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "on", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 140, + "y": 680, + "wires": [ + [], + [] + ] + }, + { + "id": "b57cf93b3481bb17", + "type": "comment", + "z": "f02b32ef07b4b378", + "name": "Speaker config buttons", + "info": "", + "x": 140, + "y": 80, + "wires": [] + }, + { + "id": "73bf252f2983ae0c", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Mute Speakers", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": true, + "action": "media_player.volume_mute", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "{{ mute }}" + ], + "labelId": [], + "data": "{\"is_volume_muted\":true}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "volume_mute", + "x": 800, + "y": 200, + "wires": [ + [] + ] + }, + { + "id": "e8d4582f1a35b5fe", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Umute Speakers", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.volume_mute", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "{{ unmute }}" + ], + "labelId": [], + "data": "{\"is_volume_muted\": false }", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "volume_mute", + "x": 810, + "y": 240, + "wires": [ + [] + ] + }, + { + "id": "9c40d4014ed62a08", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Kitchen audio config", + "rules": [ + { + "t": "set", + "p": "unmute", + "pt": "msg", + "to": "media_player.kitchen", + "tot": "str" + }, + { + "t": "set", + "p": "mute", + "pt": "msg", + "to": "media_player.bedroom, media_player.bathroom, media_player.home_theater_universal", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 420, + "y": 120, + "wires": [ + [ + "73bf252f2983ae0c", + "e8d4582f1a35b5fe" + ] + ] + }, + { + "id": "4a3201a1c23eb1bd", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Bedroom audio config", + "rules": [ + { + "t": "set", + "p": "unmute", + "pt": "msg", + "to": "media_player.bedroom", + "tot": "str" + }, + { + "t": "set", + "p": "mute", + "pt": "msg", + "to": "media_player.bathroom, media_player.kitchen, media_player.home_theater_universal", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 420, + "y": 180, + "wires": [ + [ + "73bf252f2983ae0c", + "e8d4582f1a35b5fe" + ] + ] + }, + { + "id": "ab34bd65550a49eb", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Bathroom audio config", + "rules": [ + { + "t": "set", + "p": "unmute", + "pt": "msg", + "to": "media_player.bathroom", + "tot": "str" + }, + { + "t": "set", + "p": "mute", + "pt": "msg", + "to": "media_player.bedroom, media_player.kitchen, media_player.home_theater_universal", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 420, + "y": 240, + "wires": [ + [ + "73bf252f2983ae0c", + "e8d4582f1a35b5fe" + ] + ] + }, + { + "id": "1ce85c93fddec1ed", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "All speaker unmute config", + "rules": [ + { + "t": "set", + "p": "unmute", + "pt": "msg", + "to": "media_player.bathroom, media_player.bedroom, media_player.kitchen, media_player.home_theater_universal", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 430, + "y": 380, + "wires": [ + [ + "e8d4582f1a35b5fe" + ] + ] + }, + { + "id": "ed546967f38f4321", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "All speaker mute config", + "rules": [ + { + "t": "set", + "p": "mute", + "pt": "msg", + "to": "media_player.bathroom, media_player.bedroom, media_player.kitchen, media_player.home_theater_universal", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 430, + "y": 440, + "wires": [ + [ + "73bf252f2983ae0c" + ] + ] + }, + { + "id": "4e372d2ae02e476f", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Kitchen audio button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.kitchen_only_audio" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 130, + "y": 120, + "wires": [ + [ + "9c40d4014ed62a08" + ] + ] + }, + { + "id": "7e30cae17b6f1147", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Bedroom audio button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.bedroom_only_audio" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 140, + "y": 180, + "wires": [ + [ + "4a3201a1c23eb1bd" + ] + ] + }, + { + "id": "7087100e45352fd6", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Bathroom audio button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.bathroom_only_audio" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 140, + "y": 240, + "wires": [ + [ + "ab34bd65550a49eb" + ] + ] + }, + { + "id": "1e1bbdf54bcc0e71", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "All speakers unmute button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.unmute_all_speakers" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 150, + "y": 380, + "wires": [ + [ + "1ce85c93fddec1ed" + ] + ] + }, + { + "id": "0dada2e07914212e", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "All speakers mute button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.mute_all_speakers" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 150, + "y": 440, + "wires": [ + [ + "ed546967f38f4321" + ] + ] + }, + { + "id": "83cfde5f5f29bfee", + "type": "comment", + "z": "f02b32ef07b4b378", + "name": "Audio Follow system", + "info": "", + "x": 130, + "y": 520, + "wires": [] + }, + { + "id": "d6a335eabf0309af", + "type": "comment", + "z": "f02b32ef07b4b378", + "name": "Speaker time out", + "info": "", + "x": 120, + "y": 820, + "wires": [] + }, + { + "id": "8d0c16fdcaa044c5", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Music fade out button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.music_fade_out" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 140, + "y": 860, + "wires": [ + [ + "5a53dda5700dcbd4" + ] + ] + }, + { + "id": "487f7f9cb870301d", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Set bedroom volume", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.volume_set", + "floorId": [], + "areaId": [ + "7047cdd7d50e49f980eba16f832acb57" + ], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "{ \"volume_level\" : {{ payload }} }", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "volume_set", + "x": 1700, + "y": 1020, + "wires": [ + [ + "470f04a1f67ed2c5" + ] + ] + }, + { + "id": "099e68b4526af252", + "type": "easing", + "z": "f02b32ef07b4b378", + "name": "Calculate fade in volume", + "easingType": "linear", + "outputType": "overTime", + "duration": "30000", + "interval": "2000", + "numberOfValues": 10, + "x": 1710, + "y": 880, + "wires": [ + [ + "148bfd7bfd19a3f2" + ] + ] + }, + { + "id": "465266c8ebc87190", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Set volume parameters", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"from\": $number(payload), \"to\": 0, \"size\": 0.01}", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1710, + "y": 820, + "wires": [ + [ + "099e68b4526af252" + ] + ] + }, + { + "id": "148bfd7bfd19a3f2", + "type": "calculator", + "z": "f02b32ef07b4b378", + "name": "Round to max 2 decimals", + "inputMsgField": "payload", + "outputMsgField": "payload", + "operation": "rdec", + "constant": "2", + "round": false, + "truncate": false, + "decimals": "0", + "decimals2": 0, + "x": 1710, + "y": 940, + "wires": [ + [ + "487f7f9cb870301d" + ] + ] + }, + { + "id": "5a53dda5700dcbd4", + "type": "trigger", + "z": "f02b32ef07b4b378", + "name": "20min trigger to start fade out", + "op1": "", + "op2": "off", + "op1type": "nul", + "op2type": "str", + "duration": "20", + "extend": false, + "overrideDelay": false, + "units": "min", + "reset": "on", + "bytopic": "all", + "topic": "topic", + "outputs": 1, + "x": 480, + "y": 860, + "wires": [ + [ + "64d51f4ce06f71bb" + ] + ] + }, + { + "id": "243eaae96c3615b7", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Music cancel fade out button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.music_cancel_fade_out" + ], + "substring": [], + "regex": [] + }, + "outputInitially": true, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "reset", + "propertyType": "msg", + "value": "true", + "valueType": "bool" + } + ], + "x": 160, + "y": 920, + "wires": [ + [ + "5a53dda5700dcbd4" + ] + ] + }, + { + "id": "658612bb048cebd0", + "type": "api-current-state", + "z": "f02b32ef07b4b378", + "name": "Get bedroom volume", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 2, + "halt_if": "playing", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "media_player.bedroom", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entity" + } + ], + "for": "0", + "forType": "num", + "forUnits": "minutes", + "override_topic": false, + "state_location": "payload", + "override_payload": "msg", + "entity_location": "data", + "override_data": "msg", + "x": 740, + "y": 860, + "wires": [ + [ + "9df152f9e9ea7a00" + ], + [ + "2c391596726d163a" + ] + ] + }, + { + "id": "eee9cae5a34371af", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Set default volume", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "0.2", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1350, + "y": 860, + "wires": [ + [ + "465266c8ebc87190" + ] + ] + }, + { + "id": "2c391596726d163a", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Stop media players", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.media_stop", + "floorId": [], + "areaId": [ + "f7affcd2d1854f58b829a3d1f67684e9", + "7047cdd7d50e49f980eba16f832acb57", + "58b6232129db4aa396355dcff5edc036", + "9fb80339d4ee49f098decfafad38ab78" + ], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "", + "dataType": "jsonata", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "media_stop", + "x": 1690, + "y": 1180, + "wires": [ + [] + ] + }, + { + "id": "470f04a1f67ed2c5", + "type": "switch", + "z": "f02b32ef07b4b378", + "name": "Volume all the way down?", + "property": "payload", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "0", + "vt": "num" + } + ], + "checkall": "true", + "repair": false, + "outputs": 1, + "x": 1710, + "y": 1100, + "wires": [ + [ + "2c391596726d163a" + ] + ] + }, + { + "id": "32128a2d9466c2a5", + "type": "switch", + "z": "f02b32ef07b4b378", + "name": "Volume is numeric?", + "property": "payload", + "propertyType": "msg", + "rules": [ + { + "t": "istype", + "v": "number", + "vt": "number" + }, + { + "t": "else" + } + ], + "checkall": "false", + "repair": false, + "outputs": 2, + "x": 1350, + "y": 800, + "wires": [ + [ + "465266c8ebc87190" + ], + [ + "eee9cae5a34371af" + ] + ] + }, + { + "id": "9df152f9e9ea7a00", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Set volume from speaker", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "data.attributes.volume_level", + "tot": "msg" + }, + { + "t": "delete", + "p": "data", + "pt": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1030, + "y": 860, + "wires": [ + [ + "32128a2d9466c2a5" + ] + ] + }, + { + "id": "64d51f4ce06f71bb", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Stop media players", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.media_stop", + "floorId": [], + "areaId": [ + "f7affcd2d1854f58b829a3d1f67684e9", + "7047cdd7d50e49f980eba16f832acb57", + "58b6232129db4aa396355dcff5edc036", + "9fb80339d4ee49f098decfafad38ab78" + ], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "", + "dataType": "jsonata", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "media_stop", + "x": 730, + "y": 920, + "wires": [ + [] + ] + }, + { + "id": "7537b14f401fe338", + "type": "comment", + "z": "f02b32ef07b4b378", + "name": "Disabled fade out flow (breaks HEOS + spotify)", + "info": "", + "x": 820, + "y": 820, + "wires": [] + }, + { + "id": "691572bc73058f7b", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Livingroom audio config", + "rules": [ + { + "t": "set", + "p": "unmute", + "pt": "msg", + "to": "media_player.home_theater_universal", + "tot": "str" + }, + { + "t": "set", + "p": "mute", + "pt": "msg", + "to": "media_player.bedroom, media_player.kitchen, media_player.bathroom", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 430, + "y": 300, + "wires": [ + [ + "73bf252f2983ae0c", + "e8d4582f1a35b5fe" + ] + ] + }, + { + "id": "483ec65e18051a31", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Livingroom audio button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.livingroom_only_audio" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 140, + "y": 300, + "wires": [ + [ + "691572bc73058f7b" + ] + ] + }, + { + "id": "aa6cfabebf9a872f", + "type": "comment", + "z": "f02b32ef07b4b378", + "name": "Grouping and ungrouping", + "info": "", + "x": 150, + "y": 1040, + "wires": [] + }, + { + "id": "0a5de0c3e1526c14", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Group all", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.heos_group_all" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 100, + "y": 1080, + "wires": [ + [ + "608262f04a2a221d" + ] + ] + }, + { + "id": "756d563e795b953a", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Group all, excl. livingroom", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.heos_group_all_but_livingroom" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 150, + "y": 1140, + "wires": [ + [ + "80be5093f48e88fc" + ] + ] + }, + { + "id": "a83c93f336d93f56", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Group all, excl bathroom", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.heos_group_all_but_bathroom" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 150, + "y": 1200, + "wires": [ + [ + "aaafe15411371f43" + ] + ] + }, + { + "id": "0fe637de86520e51", + "type": "server-state-changed", + "z": "f02b32ef07b4b378", + "name": "Group all, excl bedroom", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.heos_group_all_but_bedroom" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 140, + "y": 1260, + "wires": [ + [ + "980d8e52b0eceaff" + ] + ] + }, + { + "id": "ccc51eb8edf2e33d", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Join all speakers", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.join", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "{\t \"entity_id\": leader, \t \"group_members\": followers\t}", + "dataType": "jsonata", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": true, + "domain": "media_player", + "service": "join", + "x": 1130, + "y": 1180, + "wires": [ + [] + ] + }, + { + "id": "608262f04a2a221d", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Set leader and followers", + "rules": [ + { + "t": "set", + "p": "leader", + "pt": "msg", + "to": "media_player.bedroom", + "tot": "str" + }, + { + "t": "set", + "p": "followers", + "pt": "msg", + "to": "[\"media_player.denon_avr_x3600h\",\"media_player.kitchen\",\"media_player.bathroom\"]", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 450, + "y": 1080, + "wires": [ + [ + "ccc51eb8edf2e33d" + ] + ] + }, + { + "id": "80be5093f48e88fc", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Set leader and followers", + "rules": [ + { + "t": "set", + "p": "leader", + "pt": "msg", + "to": "media_player.bedroom", + "tot": "str" + }, + { + "t": "set", + "p": "followers", + "pt": "msg", + "to": "[\"media_player.kitchen\",\"media_player.bathroom\"]", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 450, + "y": 1140, + "wires": [ + [ + "ccc51eb8edf2e33d" + ] + ] + }, + { + "id": "aaafe15411371f43", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Set leader and followers", + "rules": [ + { + "t": "set", + "p": "leader", + "pt": "msg", + "to": "media_player.bedroom", + "tot": "str" + }, + { + "t": "set", + "p": "followers", + "pt": "msg", + "to": "[\"media_player.denon_avr_x3600h\",\"media_player.kitchen\"]", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 450, + "y": 1200, + "wires": [ + [ + "ccc51eb8edf2e33d" + ] + ] + }, + { + "id": "980d8e52b0eceaff", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Set leader and followers", + "rules": [ + { + "t": "set", + "p": "leader", + "pt": "msg", + "to": "media_player.kitchen", + "tot": "str" + }, + { + "t": "set", + "p": "followers", + "pt": "msg", + "to": "[\"media_player.denon_avr_x3600h\",\"media_player.bathroom\"]", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 450, + "y": 1260, + "wires": [ + [ + "ccc51eb8edf2e33d" + ] + ] + }, + { + "id": "1278b99a481e6dd1", + "type": "comment", + "z": "f02b32ef07b4b378", + "name": "Home Theather volume control on heos start", + "info": "", + "x": 210, + "y": 1360, + "wires": [] + }, + { + "id": "5f677939f2c09f28", + "type": "trigger-state", + "z": "f02b32ef07b4b378", + "name": "Switching home theather to heos", + "server": "657c7463.48e1e4", + "version": 5, + "inputs": 0, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "media_player.home_theater_universal" + ], + "substring": [], + "regex": [] + }, + "debugEnabled": false, + "constraints": [ + { + "targetType": "this_entity", + "targetValue": "", + "propertyType": "property", + "propertyValue": "new_state.attributes.source", + "comparatorType": "is", + "comparatorValueDatatype": "str", + "comparatorValue": "HEOS Music" + }, + { + "targetType": "this_entity", + "targetValue": "", + "propertyType": "property", + "propertyValue": "old_state.attributes.source", + "comparatorType": "is_not", + "comparatorValueDatatype": "str", + "comparatorValue": "HEOS Music" + } + ], + "customOutputs": [], + "outputInitially": false, + "stateType": "str", + "enableInput": false, + "x": 170, + "y": 1400, + "wires": [ + [ + "8c788d92123228cb" + ], + [] + ] + }, + { + "id": "8c788d92123228cb", + "type": "delay", + "z": "f02b32ef07b4b378", + "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": 430, + "y": 1400, + "wires": [ + [ + "f1ddda7676ab9bbc" + ] + ] + }, + { + "id": "f1ddda7676ab9bbc", + "type": "api-current-state", + "z": "f02b32ef07b4b378", + "name": "Fetch bedroom volume", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "media_player.bedroom", + "state_type": "str", + "blockInputOverrides": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entity" + } + ], + "for": "0", + "forType": "num", + "forUnits": "minutes", + "override_topic": false, + "state_location": "payload", + "override_payload": "msg", + "entity_location": "data", + "override_data": "msg", + "x": 630, + "y": 1400, + "wires": [ + [ + "087e6e0c92150113" + ] + ] + }, + { + "id": "087e6e0c92150113", + "type": "change", + "z": "f02b32ef07b4b378", + "name": "Calculate volume", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "(\t $leader_volume := data.attributes.is_volume_muted ? 0 : $number(data.attributes.volume_level ? data.attributes.volume_level : 0);\t $base_volume := $leader_volume = 0 ? 0.15 : $leader_volume;\t $added_volume := $base_volume + 0.18;\t $clamped_volume := $added_volume > 0.5 ? 0.5 : $added_volume;\t $target_volume := $round($clamped_volume, 2);\t { \"entity_id\": \"media_player.home_theater_universal\", \"volume_level\": $target_volume }\t)", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 880, + "y": 1400, + "wires": [ + [ + "8a59f44f4fc0c8d0" + ] + ] + }, + { + "id": "8a59f44f4fc0c8d0", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "Set home theather volume", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.volume_set", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "payload", + "dataType": "jsonata", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": true, + "domain": "media_player", + "service": "volume_set", + "x": 1160, + "y": 1400, + "wires": [ + [] + ] + }, + { + "id": "errf02b32ef_c", + "type": "catch", + "z": "f02b32ef07b4b378", + "name": "Tab errors", + "scope": null, + "uncaught": false, + "x": 120, + "y": 2220, + "wires": [ + [ + "errf02b32ef_f" + ] + ] + }, + { + "id": "errf02b32ef_f", + "type": "function", + "z": "f02b32ef07b4b378", + "name": "Format error", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Home Audio\", data: { priority: 1 } });\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 360, + "y": 2220, + "wires": [ + [ + "errf02b32ef_s" + ] + ] + }, + { + "id": "errf02b32ef_s", + "type": "api-call-service", + "z": "f02b32ef07b4b378", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "notify", + "service": "gotify_nodered", + "x": 600, + "y": 2220, + "wires": [ + [] + ] + }, + { + "id": "eb217ba8.833d48", + "type": "server-state-changed", + "z": "1f4d4622.7490ca", + "d": true, + "name": "Outside temperature", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "sensor.openweathermap_temperature" + ], + "substring": [], + "regex": [] + }, + "outputInitially": true, + "stateType": "num", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 110, + "y": 120, + "wires": [ + [ + "c8bf7086.b32ab8", + "be230668.4e6718", + "1de4cd6b31838517" + ] + ] + }, + { + "id": "c8bf7086.b32ab8", + "type": "api-current-state", + "z": "1f4d4622.7490ca", + "name": "Inside temperature", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "sensor.livingroom_temperature_avg", + "state_type": "", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entity" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 470, + "y": 120, + "wires": [ + [ + "13a9b38f.3ab9d4", + "1de4cd6b31838517" + ] + ] + }, + { + "id": "68aa8fe5.4cd4f", + "type": "function", + "z": "1f4d4622.7490ca", + "name": "Determine cooler or warmer", + "func": "var outsideTemp = parseFloat(msg.payload.outside);\nvar insideTemp = parseFloat(msg.payload.inside);\nvar notification = '';\n\nif (outsideTemp < insideTemp) {\n notification = 'Outside is cooler than inside';\n} else {\n notification = 'Outside is warmer than inside';\n}\n\nmsg.payload = notification;\n\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 880, + "y": 180, + "wires": [ + [ + "e27e4896.4eefa", + "1de4cd6b31838517" + ] + ] + }, + { + "id": "e27e4896.4eefa", + "type": "api-call-service", + "z": "1f4d4622.7490ca", + "name": "Notify via HA", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "notify.gotify_ha", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "{\"title\":\"Info\",\"message\":\"{{{payload}}}\"}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "notify", + "service": "gotify_ha", + "output_location": "", + "output_location_type": "none", + "x": 1130, + "y": 180, + "wires": [ + [] + ] + }, + { + "id": "be230668.4e6718", + "type": "change", + "z": "1f4d4622.7490ca", + "name": "Clear data", + "rules": [ + { + "t": "delete", + "p": "data", + "pt": "msg" + }, + { + "t": "set", + "p": "topic", + "pt": "msg", + "to": "outside", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 470, + "y": 260, + "wires": [ + [ + "2119da07.2ad496" + ] + ] + }, + { + "id": "13a9b38f.3ab9d4", + "type": "change", + "z": "1f4d4622.7490ca", + "name": "Clear data", + "rules": [ + { + "t": "delete", + "p": "data", + "pt": "msg" + }, + { + "t": "set", + "p": "topic", + "pt": "msg", + "to": "inside", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 470, + "y": 200, + "wires": [ + [ + "2119da07.2ad496" + ] + ] + }, + { + "id": "2119da07.2ad496", + "type": "join", + "z": "1f4d4622.7490ca", + "name": "", + "mode": "custom", + "build": "object", + "property": "payload", + "propertyType": "msg", + "key": "topic", + "joiner": "\\n", + "joinerType": "str", + "accumulate": false, + "timeout": "", + "count": "2", + "reduceRight": false, + "reduceExp": "", + "reduceInit": "", + "reduceInitType": "", + "reduceFixup": "", + "x": 670, + "y": 180, + "wires": [ + [ + "68aa8fe5.4cd4f" + ] + ] + }, + { + "id": "1de4cd6b31838517", + "type": "debug", + "z": "1f4d4622.7490ca", + "name": "Temperature alert", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 830, + "y": 60, + "wires": [] + }, + { + "id": "9a99a3d8e416b026", + "type": "comment", + "z": "1f4d4622.7490ca", + "name": "Temperature alert", + "info": "", + "x": 100, + "y": 80, + "wires": [] + }, + { + "id": "a676209fc00d4d6c", + "type": "comment", + "z": "1f4d4622.7490ca", + "name": "Climate control", + "info": "", + "x": 100, + "y": 360, + "wires": [] + }, + { + "id": "6156c5585680e99e", + "type": "server-state-changed", + "z": "1f4d4622.7490ca", + "d": true, + "name": "Livingroom window open", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "sensor.window_handle_bedroom_state" + ], + "substring": [], + "regex": [] + }, + "outputInitially": true, + "stateType": "str", + "ifState": "closed", + "ifStateType": "str", + "ifStateOperator": "is_not", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 130, + "y": 420, + "wires": [ + [ + "ea05134bce8525ef" + ], + [ + "e2f354b6c7b22e8d" + ] + ] + }, + { + "id": "ea05134bce8525ef", + "type": "api-call-service", + "z": "1f4d4622.7490ca", + "d": true, + "name": "Activate window open mode", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "scene.turn_on", + "floorId": [], + "areaId": [ + "7047cdd7d50e49f980eba16f832acb57" + ], + "deviceId": [], + "entityId": [ + "scene.bedroom_climate_window_open" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "scene", + "service": "turn_on", + "output_location": "", + "output_location_type": "none", + "x": 520, + "y": 420, + "wires": [ + [] + ] + }, + { + "id": "e2f354b6c7b22e8d", + "type": "api-call-service", + "z": "1f4d4622.7490ca", + "d": true, + "name": "Activate window open mode", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "scene.apply", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "scene", + "service": "apply", + "output_location": "", + "output_location_type": "none", + "x": 520, + "y": 500, + "wires": [ + [] + ] + }, + { + "id": "err1f4d4622_c", + "type": "catch", + "z": "1f4d4622.7490ca", + "name": "Tab errors", + "scope": null, + "uncaught": false, + "x": 120, + "y": 2000, + "wires": [ + [ + "err1f4d4622_f" + ] + ] + }, + { + "id": "err1f4d4622_f", + "type": "function", + "z": "1f4d4622.7490ca", + "name": "Format error", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Temperature & climate\", data: { priority: 1 } });\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 360, + "y": 2000, + "wires": [ + [ + "err1f4d4622_s" + ] + ] + }, + { + "id": "err1f4d4622_s", + "type": "api-call-service", + "z": "1f4d4622.7490ca", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "notify", + "service": "gotify_nodered", + "x": 600, + "y": 2000, "wires": [ [] ] @@ -3664,648 +7387,6 @@ "y": 700, "wires": [] }, - { - "id": "64e25c08b51a1c62", - "type": "comment", - "z": "75c53969.aa5438", - "name": "Mosquito repellent", - "info": "", - "x": 170, - "y": 1360, - "wires": [] - }, - { - "id": "22546de14d49ffe0", - "type": "server-state-changed", - "z": "75c53969.aa5438", - "name": "Mosquito repellent start", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_datetime.mosquito_repellent_start" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 1480, - "wires": [ - [ - "5ba4538297e14338" - ] - ] - }, - { - "id": "9046160e1b2dcae8", - "type": "api-current-state", - "z": "75c53969.aa5438", - "name": "Enable Mosquito repellent?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "on", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_boolean.mosquito_device", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 680, - "y": 1480, - "wires": [ - [ - "fbabed1ad7a24ba0" - ], - [] - ] - }, - { - "id": "fbabed1ad7a24ba0", - "type": "function", - "z": "75c53969.aa5438", - "name": "Mosquito repellent notification", - "func": "var newMsg = {};\nnewMsg.payload = \n \"Mosquito repellent will turn on at \"+\n flow.get('mosquito_start_time').substr(0,5)\n ;\n\nreturn newMsg;", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 990, - "y": 1480, - "wires": [ - [ - "e9a1ce2e4ff7ec96" - ] - ] - }, - { - "id": "e9a1ce2e4ff7ec96", - "type": "api-call-service", - "z": "75c53969.aa5438", - "name": "Notify via HA", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{\"title\":\"Info\",\"message\":\"{{{payload}}}\"}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 1410, - "y": 1440, - "wires": [ - [] - ] - }, - { - "id": "5ba4538297e14338", - "type": "change", - "z": "75c53969.aa5438", - "name": "", - "rules": [ - { - "t": "set", - "p": "mosquito_start_time", - "pt": "flow", - "to": "payload", - "tot": "msg" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 200, - "y": 1540, - "wires": [ - [ - "9046160e1b2dcae8", - "a2a01fc407a0436d" - ] - ] - }, - { - "id": "59b8f49a70e4cd99", - "type": "server-state-changed", - "z": "75c53969.aa5438", - "name": "Mosquito repellent start", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_boolean.mosquito_device" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 1400, - "wires": [ - [ - "597bdcb50e6cb418" - ] - ] - }, - { - "id": "597bdcb50e6cb418", - "type": "function", - "z": "75c53969.aa5438", - "name": "Mosquito repellent notification", - "func": "var newMsg = {};\nnewMsg.payload = \n \"Mosquito repellent turned \" + \n msg.payload + \n \".\"\n ;\n\nreturn newMsg;", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 690, - "y": 1400, - "wires": [ - [ - "e9a1ce2e4ff7ec96" - ] - ] - }, - { - "id": "a2a01fc407a0436d", - "type": "function", - "z": "75c53969.aa5438", - "name": "actual start time", - "func": "var newMsg = {};\nnewMsg.payload = {}\nnewMsg.payload.ontime = flow.get('mosquito_start_time').substr(0, 5);\n\nreturn newMsg;", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 640, - "y": 1540, - "wires": [ - [ - "ced1a60d7a156f31", - "03a4a0b9263bb6a5" - ] - ] - }, - { - "id": "ced1a60d7a156f31", - "type": "schedex", - "z": "75c53969.aa5438", - "name": "Mosquito repellent start timer", - "passthroughunhandled": false, - "suspended": false, - "lat": "", - "lon": "", - "ontime": "", - "ontopic": "", - "onpayload": "", - "onoffset": 0, - "onrandomoffset": 0, - "offtime": "", - "offtopic": "", - "offpayload": "", - "offoffset": 0, - "offrandomoffset": 0, - "mon": true, - "tue": true, - "wed": true, - "thu": true, - "fri": true, - "sat": true, - "sun": true, - "x": 680, - "y": 1600, - "wires": [ - [ - "681c8277c5546141", - "03a4a0b9263bb6a5" - ] - ] - }, - { - "id": "6f4031ab571aeae0", - "type": "api-call-service", - "z": "75c53969.aa5438", - "name": "Turn on mosquito repellent", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "switch.turn_on", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "switch.bedroom_mosquito_switch" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "switch", - "service": "turn_on", - "output_location": "", - "output_location_type": "none", - "x": 1460, - "y": 1560, - "wires": [ - [] - ] - }, - { - "id": "681c8277c5546141", - "type": "api-current-state", - "z": "75c53969.aa5438", - "name": "Enable Mosquito repellent?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "on", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_boolean.mosquito_device", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 980, - "y": 1540, - "wires": [ - [ - "6f4031ab571aeae0", - "03a4a0b9263bb6a5" - ], - [] - ] - }, - { - "id": "8c2dd2f5682080ac", - "type": "server-state-changed", - "z": "75c53969.aa5438", - "name": "Mosquito repellent stop", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_datetime.mosquito_repellent_stop" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 1620, - "wires": [ - [ - "392706767c38e18e" - ] - ] - }, - { - "id": "392706767c38e18e", - "type": "change", - "z": "75c53969.aa5438", - "name": "", - "rules": [ - { - "t": "set", - "p": "mosquito_stop_time", - "pt": "flow", - "to": "payload", - "tot": "msg" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 200, - "y": 1680, - "wires": [ - [ - "b79251d5e98f3863", - "280a9497b4700592" - ] - ] - }, - { - "id": "b79251d5e98f3863", - "type": "api-current-state", - "z": "75c53969.aa5438", - "name": "Enable Mosquito repellent?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "on", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_boolean.mosquito_device", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 680, - "y": 1680, - "wires": [ - [ - "4b8aaa94a2eb49c4" - ], - [] - ] - }, - { - "id": "4b8aaa94a2eb49c4", - "type": "function", - "z": "75c53969.aa5438", - "name": "Mosquito repellent notification", - "func": "var newMsg = {};\nnewMsg.payload = \n \"Mosquito repellent will turn off at \"+\n flow.get('mosquito_stop_time').substr(0,5)\n ;\n\nreturn newMsg;", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 990, - "y": 1680, - "wires": [ - [ - "e9a1ce2e4ff7ec96" - ] - ] - }, - { - "id": "280a9497b4700592", - "type": "function", - "z": "75c53969.aa5438", - "name": "actual stop time", - "func": "var newMsg = {};\nnewMsg.payload = {}\nnewMsg.payload.ontime = flow.get('mosquito_stop_time').substr(0, 5);\n\nreturn newMsg;", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 640, - "y": 1740, - "wires": [ - [ - "8d3c194ede95021a", - "03a4a0b9263bb6a5" - ] - ] - }, - { - "id": "8d3c194ede95021a", - "type": "schedex", - "z": "75c53969.aa5438", - "name": "Mosquito repellent stop timer", - "passthroughunhandled": false, - "suspended": false, - "lat": "", - "lon": "", - "ontime": "", - "ontopic": "", - "onpayload": "", - "onoffset": 0, - "onrandomoffset": 0, - "offtime": "", - "offtopic": "", - "offpayload": "", - "offoffset": 0, - "offrandomoffset": 0, - "mon": true, - "tue": true, - "wed": true, - "thu": true, - "fri": true, - "sat": true, - "sun": true, - "x": 680, - "y": 1800, - "wires": [ - [ - "9ba1f8f1e3d43149", - "03a4a0b9263bb6a5" - ] - ] - }, - { - "id": "9ba1f8f1e3d43149", - "type": "api-call-service", - "z": "75c53969.aa5438", - "name": "Turn off mosquito repellent", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "switch.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "switch.bedroom_mosquito_switch" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "switch", - "service": "turn_off", - "output_location": "", - "output_location_type": "none", - "x": 1460, - "y": 1700, - "wires": [ - [] - ] - }, - { - "id": "03a4a0b9263bb6a5", - "type": "debug", - "z": "75c53969.aa5438", - "name": "debug mosquito", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "payload", - "targetType": "msg", - "statusVal": "", - "statusType": "auto", - "x": 1320, - "y": 1800, - "wires": [] - }, { "id": "18eb0644ca136b1c", "type": "function", @@ -4802,2397 +7883,105 @@ "wires": [] }, { - "id": "p2catch_wku", + "id": "err75c53969_c", "type": "catch", "z": "75c53969.aa5438", - "name": "Catch all errors", + "name": "Tab errors", "scope": null, "uncaught": false, - "x": 160, - "y": 2000, - "wires": [ - [ - "p2fmt_wku" - ] - ] - }, - { - "id": "p2fmt_wku", - "type": "function", - "z": "75c53969.aa5438", - "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Wake up & mosquito',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 400, - "y": 2000, - "wires": [ - [ - "p2ntfy_wku" - ] - ] - }, - { - "id": "p2ntfy_wku", - "type": "api-call-service", - "z": "75c53969.aa5438", - "name": "Notify error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 2000, - "wires": [ - [] - ] - }, - { - "id": "bc24bd25f183a7ac", - "type": "inject", - "z": "f02b32ef07b4b378", - "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 140, - "y": 1480, - "wires": [ - [ - "3b572aa5a025838b" - ] - ] - }, - { - "id": "3b572aa5a025838b", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Join media players", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.join", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "media_player.bathroom" - ], - "labelId": [], - "data": "{\"group_members\":[\"media_player.kitchen\",\"media_player.bedroom\"]}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "join", - "x": 370, - "y": 1480, - "wires": [ - [ - "ed251e315e4c2c9f" - ] - ] - }, - { - "id": "ed251e315e4c2c9f", - "type": "debug", - "z": "f02b32ef07b4b378", - "name": "debug 8", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "false", - "statusVal": "", - "statusType": "auto", - "x": 660, - "y": 1480, - "wires": [] - }, - { - "id": "7ad8e1f3e2e0968a", - "type": "inject", - "z": "f02b32ef07b4b378", - "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 140, - "y": 1560, - "wires": [ - [ - "b298882274d1cdf3" - ] - ] - }, - { - "id": "b298882274d1cdf3", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Unjoin media players", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.unjoin", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "media_player.bathroom", - "media_player.bedroom", - "media_player.kitchen" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "unjoin", - "x": 380, - "y": 1560, - "wires": [ - [ - "bdd2b9572315b352" - ] - ] - }, - { - "id": "bdd2b9572315b352", - "type": "debug", - "z": "f02b32ef07b4b378", - "name": "debug 9", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "false", - "statusVal": "", - "statusType": "auto", - "x": 660, - "y": 1560, - "wires": [] - }, - { - "id": "a17410f072874366", - "type": "inject", - "z": "f02b32ef07b4b378", - "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "true", - "payloadType": "bool", - "x": 130, - "y": 1680, - "wires": [ - [ - "d94c32c408534cea" - ] - ] - }, - { - "id": "d94c32c408534cea", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Unmute/Mute media players", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.volume_mute", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "media_player.bathroom", - "media_player.bedroom", - "media_player.kitchen" - ], - "labelId": [], - "data": "{\"is_volume_muted\": {{{payload}}} }", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "volume_mute", - "x": 400, - "y": 1680, - "wires": [ - [ - "c262b732d4b31093" - ] - ] - }, - { - "id": "c262b732d4b31093", - "type": "debug", - "z": "f02b32ef07b4b378", - "name": "debug 10", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "false", - "statusVal": "", - "statusType": "auto", - "x": 660, - "y": 1680, - "wires": [] - }, - { - "id": "023b11d63a8f319c", - "type": "inject", - "z": "f02b32ef07b4b378", - "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "false", - "payloadType": "bool", - "x": 130, - "y": 1740, - "wires": [ - [ - "d94c32c408534cea" - ] - ] - }, - { - "id": "947aef7d0b37c64e", - "type": "inject", - "z": "f02b32ef07b4b378", - "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "true", - "payloadType": "bool", - "x": 130, - "y": 1820, - "wires": [ - [ - "b14ca76bd3f6d739" - ] - ] - }, - { - "id": "b14ca76bd3f6d739", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Set volume to 20", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.volume_set", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "media_player.bathroom", - "media_player.bedroom", - "media_player.kitchen" - ], - "labelId": [], - "data": "{\"volume_level\": 0.2 }", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "volume_set", - "x": 370, - "y": 1820, - "wires": [ - [ - "7ff52464dc77aa88" - ] - ] - }, - { - "id": "7ff52464dc77aa88", - "type": "debug", - "z": "f02b32ef07b4b378", - "name": "debug 12", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "false", - "statusVal": "", - "statusType": "auto", - "x": 660, - "y": 1820, - "wires": [] - }, - { - "id": "b57cf93b3481bb17", - "type": "comment", - "z": "f02b32ef07b4b378", - "name": "Speaker config buttons", - "info": "", - "x": 140, - "y": 80, - "wires": [] - }, - { - "id": "73bf252f2983ae0c", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Mute Speakers", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": true, - "action": "media_player.volume_mute", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "{{ mute }}" - ], - "labelId": [], - "data": "{\"is_volume_muted\":true}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "volume_mute", - "x": 800, - "y": 200, - "wires": [ - [] - ] - }, - { - "id": "e8d4582f1a35b5fe", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Umute Speakers", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.volume_mute", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "{{ unmute }}" - ], - "labelId": [], - "data": "{\"is_volume_muted\": false }", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "volume_mute", - "x": 810, - "y": 240, - "wires": [ - [] - ] - }, - { - "id": "9c40d4014ed62a08", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Kitchen audio config", - "rules": [ - { - "t": "set", - "p": "unmute", - "pt": "msg", - "to": "media_player.kitchen", - "tot": "str" - }, - { - "t": "set", - "p": "mute", - "pt": "msg", - "to": "media_player.bedroom, media_player.bathroom, media_player.home_theater_universal", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 420, - "y": 120, - "wires": [ - [ - "73bf252f2983ae0c", - "e8d4582f1a35b5fe" - ] - ] - }, - { - "id": "4a3201a1c23eb1bd", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Bedroom audio config", - "rules": [ - { - "t": "set", - "p": "unmute", - "pt": "msg", - "to": "media_player.bedroom", - "tot": "str" - }, - { - "t": "set", - "p": "mute", - "pt": "msg", - "to": "media_player.bathroom, media_player.kitchen, media_player.home_theater_universal", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 420, - "y": 180, - "wires": [ - [ - "73bf252f2983ae0c", - "e8d4582f1a35b5fe" - ] - ] - }, - { - "id": "ab34bd65550a49eb", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Bathroom audio config", - "rules": [ - { - "t": "set", - "p": "unmute", - "pt": "msg", - "to": "media_player.bathroom", - "tot": "str" - }, - { - "t": "set", - "p": "mute", - "pt": "msg", - "to": "media_player.bedroom, media_player.kitchen, media_player.home_theater_universal", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 420, - "y": 240, - "wires": [ - [ - "73bf252f2983ae0c", - "e8d4582f1a35b5fe" - ] - ] - }, - { - "id": "1ce85c93fddec1ed", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "All speaker unmute config", - "rules": [ - { - "t": "set", - "p": "unmute", - "pt": "msg", - "to": "media_player.bathroom, media_player.bedroom, media_player.kitchen, media_player.home_theater_universal", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 430, - "y": 380, - "wires": [ - [ - "e8d4582f1a35b5fe" - ] - ] - }, - { - "id": "ed546967f38f4321", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "All speaker mute config", - "rules": [ - { - "t": "set", - "p": "mute", - "pt": "msg", - "to": "media_player.bathroom, media_player.bedroom, media_player.kitchen, media_player.home_theater_universal", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 430, - "y": 440, - "wires": [ - [ - "73bf252f2983ae0c" - ] - ] - }, - { - "id": "4e372d2ae02e476f", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Kitchen audio button", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.kitchen_only_audio" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 130, - "y": 120, - "wires": [ - [ - "9c40d4014ed62a08" - ] - ] - }, - { - "id": "7e30cae17b6f1147", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Bedroom audio button", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.bedroom_only_audio" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 140, - "y": 180, - "wires": [ - [ - "4a3201a1c23eb1bd" - ] - ] - }, - { - "id": "7087100e45352fd6", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Bathroom audio button", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.bathroom_only_audio" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 140, - "y": 240, - "wires": [ - [ - "ab34bd65550a49eb" - ] - ] - }, - { - "id": "1e1bbdf54bcc0e71", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "All speakers unmute button", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.unmute_all_speakers" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 150, - "y": 380, - "wires": [ - [ - "1ce85c93fddec1ed" - ] - ] - }, - { - "id": "0dada2e07914212e", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "All speakers mute button", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.mute_all_speakers" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 150, - "y": 440, - "wires": [ - [ - "ed546967f38f4321" - ] - ] - }, - { - "id": "d6a335eabf0309af", - "type": "comment", - "z": "f02b32ef07b4b378", - "name": "Speaker time out", - "info": "", "x": 120, - "y": 540, - "wires": [] - }, - { - "id": "8d0c16fdcaa044c5", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Music fade out button", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.music_fade_out" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 140, - "y": 580, + "y": 2000, "wires": [ [ - "5a53dda5700dcbd4" + "err75c53969_f" ] ] }, { - "id": "487f7f9cb870301d", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Set bedroom volume", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.volume_set", - "floorId": [], - "areaId": [ - "7047cdd7d50e49f980eba16f832acb57" - ], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{ \"volume_level\" : {{ payload }} }", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "volume_set", - "x": 1700, - "y": 740, - "wires": [ - [ - "470f04a1f67ed2c5" - ] - ] - }, - { - "id": "099e68b4526af252", - "type": "easing", - "z": "f02b32ef07b4b378", - "name": "Calculate fade in volume", - "easingType": "linear", - "outputType": "overTime", - "duration": "30000", - "interval": "2000", - "numberOfValues": 10, - "x": 1710, - "y": 600, - "wires": [ - [ - "148bfd7bfd19a3f2" - ] - ] - }, - { - "id": "465266c8ebc87190", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Set volume parameters", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"from\": $number(payload), \"to\": 0, \"size\": 0.01}", - "tot": "jsonata" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1710, - "y": 540, - "wires": [ - [ - "099e68b4526af252" - ] - ] - }, - { - "id": "148bfd7bfd19a3f2", - "type": "calculator", - "z": "f02b32ef07b4b378", - "name": "Round to max 2 decimals", - "inputMsgField": "payload", - "outputMsgField": "payload", - "operation": "rdec", - "constant": "2", - "round": false, - "truncate": false, - "decimals": "0", - "decimals2": 0, - "x": 1710, - "y": 660, - "wires": [ - [ - "487f7f9cb870301d" - ] - ] - }, - { - "id": "5a53dda5700dcbd4", - "type": "trigger", - "z": "f02b32ef07b4b378", - "name": "20min trigger to start fade out", - "op1": "", - "op2": "off", - "op1type": "nul", - "op2type": "str", - "duration": "20", - "extend": false, - "overrideDelay": false, - "units": "min", - "reset": "on", - "bytopic": "all", - "topic": "topic", - "outputs": 1, - "x": 480, - "y": 580, - "wires": [ - [ - "64d51f4ce06f71bb" - ] - ] - }, - { - "id": "243eaae96c3615b7", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Music cancel fade out button", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.music_cancel_fade_out" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "reset", - "propertyType": "msg", - "value": "true", - "valueType": "bool" - } - ], - "x": 160, - "y": 640, - "wires": [ - [ - "5a53dda5700dcbd4" - ] - ] - }, - { - "id": "658612bb048cebd0", - "type": "api-current-state", - "z": "f02b32ef07b4b378", - "name": "Get bedroom volume", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "playing", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "media_player.bedroom", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], - "for": "0", - "forType": "num", - "forUnits": "minutes", - "override_topic": false, - "state_location": "payload", - "override_payload": "msg", - "entity_location": "data", - "override_data": "msg", - "x": 740, - "y": 580, - "wires": [ - [ - "9df152f9e9ea7a00" - ], - [ - "2c391596726d163a" - ] - ] - }, - { - "id": "eee9cae5a34371af", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Set default volume", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "0.2", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1350, - "y": 580, - "wires": [ - [ - "465266c8ebc87190" - ] - ] - }, - { - "id": "2c391596726d163a", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Stop media players", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.media_stop", - "floorId": [], - "areaId": [ - "f7affcd2d1854f58b829a3d1f67684e9", - "7047cdd7d50e49f980eba16f832acb57", - "58b6232129db4aa396355dcff5edc036", - "9fb80339d4ee49f098decfafad38ab78" - ], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "", - "dataType": "jsonata", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "media_stop", - "x": 1690, - "y": 900, - "wires": [ - [] - ] - }, - { - "id": "470f04a1f67ed2c5", - "type": "switch", - "z": "f02b32ef07b4b378", - "name": "Volume all the way down?", - "property": "payload", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "0", - "vt": "num" - } - ], - "checkall": "true", - "repair": false, - "outputs": 1, - "x": 1710, - "y": 820, - "wires": [ - [ - "2c391596726d163a" - ] - ] - }, - { - "id": "32128a2d9466c2a5", - "type": "switch", - "z": "f02b32ef07b4b378", - "name": "Volume is numeric?", - "property": "payload", - "propertyType": "msg", - "rules": [ - { - "t": "istype", - "v": "number", - "vt": "number" - }, - { - "t": "else" - } - ], - "checkall": "false", - "repair": false, - "outputs": 2, - "x": 1350, - "y": 520, - "wires": [ - [ - "465266c8ebc87190" - ], - [ - "eee9cae5a34371af" - ] - ] - }, - { - "id": "9df152f9e9ea7a00", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Set volume from speaker", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "data.attributes.volume_level", - "tot": "msg" - }, - { - "t": "delete", - "p": "data", - "pt": "msg" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1030, - "y": 580, - "wires": [ - [ - "32128a2d9466c2a5" - ] - ] - }, - { - "id": "64d51f4ce06f71bb", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Stop media players", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.media_stop", - "floorId": [], - "areaId": [ - "f7affcd2d1854f58b829a3d1f67684e9", - "7047cdd7d50e49f980eba16f832acb57", - "58b6232129db4aa396355dcff5edc036", - "9fb80339d4ee49f098decfafad38ab78" - ], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "", - "dataType": "jsonata", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "media_stop", - "x": 730, - "y": 640, - "wires": [ - [] - ] - }, - { - "id": "7537b14f401fe338", - "type": "comment", - "z": "f02b32ef07b4b378", - "name": "Disabled fade out flow (breaks HEOS + spotify)", - "info": "", - "x": 820, - "y": 540, - "wires": [] - }, - { - "id": "691572bc73058f7b", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Livingroom audio config", - "rules": [ - { - "t": "set", - "p": "unmute", - "pt": "msg", - "to": "media_player.home_theater_universal", - "tot": "str" - }, - { - "t": "set", - "p": "mute", - "pt": "msg", - "to": "media_player.bedroom, media_player.kitchen, media_player.bathroom", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 430, - "y": 300, - "wires": [ - [ - "73bf252f2983ae0c", - "e8d4582f1a35b5fe" - ] - ] - }, - { - "id": "483ec65e18051a31", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Livingroom audio button", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.livingroom_only_audio" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 140, - "y": 300, - "wires": [ - [ - "691572bc73058f7b" - ] - ] - }, - { - "id": "aa6cfabebf9a872f", - "type": "comment", - "z": "f02b32ef07b4b378", - "name": "Grouping and ungrouping", - "info": "", - "x": 150, - "y": 760, - "wires": [] - }, - { - "id": "0a5de0c3e1526c14", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Group all", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.heos_group_all" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 100, - "y": 800, - "wires": [ - [ - "608262f04a2a221d" - ] - ] - }, - { - "id": "756d563e795b953a", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Group all, excl. livingroom", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.heos_group_all_but_livingroom" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 150, - "y": 860, - "wires": [ - [ - "80be5093f48e88fc" - ] - ] - }, - { - "id": "a83c93f336d93f56", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Group all, excl bathroom", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.heos_group_all_but_bathroom" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 150, - "y": 920, - "wires": [ - [ - "aaafe15411371f43" - ] - ] - }, - { - "id": "0fe637de86520e51", - "type": "server-state-changed", - "z": "f02b32ef07b4b378", - "name": "Group all, excl bedroom", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.heos_group_all_but_bedroom" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 140, - "y": 980, - "wires": [ - [ - "980d8e52b0eceaff" - ] - ] - }, - { - "id": "ccc51eb8edf2e33d", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Join all speakers", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.join", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{\t \"entity_id\": leader, \t \"group_members\": followers\t}", - "dataType": "jsonata", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": true, - "domain": "media_player", - "service": "join", - "x": 1130, - "y": 900, - "wires": [ - [] - ] - }, - { - "id": "608262f04a2a221d", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Set leader and followers", - "rules": [ - { - "t": "set", - "p": "leader", - "pt": "msg", - "to": "media_player.bedroom", - "tot": "str" - }, - { - "t": "set", - "p": "followers", - "pt": "msg", - "to": "[\"media_player.denon_avr_x3600h\",\"media_player.kitchen\",\"media_player.bathroom\"]", - "tot": "jsonata" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 450, - "y": 800, - "wires": [ - [ - "ccc51eb8edf2e33d" - ] - ] - }, - { - "id": "80be5093f48e88fc", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Set leader and followers", - "rules": [ - { - "t": "set", - "p": "leader", - "pt": "msg", - "to": "media_player.bedroom", - "tot": "str" - }, - { - "t": "set", - "p": "followers", - "pt": "msg", - "to": "[\"media_player.kitchen\",\"media_player.bathroom\"]", - "tot": "jsonata" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 450, - "y": 860, - "wires": [ - [ - "ccc51eb8edf2e33d" - ] - ] - }, - { - "id": "aaafe15411371f43", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Set leader and followers", - "rules": [ - { - "t": "set", - "p": "leader", - "pt": "msg", - "to": "media_player.bedroom", - "tot": "str" - }, - { - "t": "set", - "p": "followers", - "pt": "msg", - "to": "[\"media_player.denon_avr_x3600h\",\"media_player.kitchen\"]", - "tot": "jsonata" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 450, - "y": 920, - "wires": [ - [ - "ccc51eb8edf2e33d" - ] - ] - }, - { - "id": "980d8e52b0eceaff", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Set leader and followers", - "rules": [ - { - "t": "set", - "p": "leader", - "pt": "msg", - "to": "media_player.kitchen", - "tot": "str" - }, - { - "t": "set", - "p": "followers", - "pt": "msg", - "to": "[\"media_player.denon_avr_x3600h\",\"media_player.bathroom\"]", - "tot": "jsonata" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 450, - "y": 980, - "wires": [ - [ - "ccc51eb8edf2e33d" - ] - ] - }, - { - "id": "1278b99a481e6dd1", - "type": "comment", - "z": "f02b32ef07b4b378", - "name": "Home Theather volume control on heos start", - "info": "", - "x": 210, - "y": 1080, - "wires": [] - }, - { - "id": "5f677939f2c09f28", - "type": "trigger-state", - "z": "f02b32ef07b4b378", - "name": "Switching home theather to heos", - "server": "657c7463.48e1e4", - "version": 5, - "inputs": 0, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "media_player.home_theater_universal" - ], - "substring": [], - "regex": [] - }, - "debugEnabled": false, - "constraints": [ - { - "targetType": "this_entity", - "targetValue": "", - "propertyType": "property", - "propertyValue": "new_state.attributes.source", - "comparatorType": "is", - "comparatorValueDatatype": "str", - "comparatorValue": "HEOS Music" - }, - { - "targetType": "this_entity", - "targetValue": "", - "propertyType": "property", - "propertyValue": "old_state.attributes.source", - "comparatorType": "is_not", - "comparatorValueDatatype": "str", - "comparatorValue": "HEOS Music" - } - ], - "customOutputs": [], - "outputInitially": false, - "stateType": "str", - "enableInput": false, - "x": 170, - "y": 1120, - "wires": [ - [ - "8c788d92123228cb" - ], - [] - ] - }, - { - "id": "8c788d92123228cb", - "type": "delay", - "z": "f02b32ef07b4b378", - "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": 430, - "y": 1120, - "wires": [ - [ - "f1ddda7676ab9bbc" - ] - ] - }, - { - "id": "f1ddda7676ab9bbc", - "type": "api-current-state", - "z": "f02b32ef07b4b378", - "name": "Fetch bedroom volume", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 1, - "halt_if": "", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "media_player.bedroom", - "state_type": "str", - "blockInputOverrides": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], - "for": "0", - "forType": "num", - "forUnits": "minutes", - "override_topic": false, - "state_location": "payload", - "override_payload": "msg", - "entity_location": "data", - "override_data": "msg", - "x": 630, - "y": 1120, - "wires": [ - [ - "087e6e0c92150113" - ] - ] - }, - { - "id": "087e6e0c92150113", - "type": "change", - "z": "f02b32ef07b4b378", - "name": "Calculate volume", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "(\t $leader_volume := data.attributes.is_volume_muted ? 0 : $number(data.attributes.volume_level ? data.attributes.volume_level : 0);\t $base_volume := $leader_volume = 0 ? 0.15 : $leader_volume;\t $added_volume := $base_volume + 0.18;\t $clamped_volume := $added_volume > 0.5 ? 0.5 : $added_volume;\t $target_volume := $round($clamped_volume, 2);\t { \"entity_id\": \"media_player.home_theater_universal\", \"volume_level\": $target_volume }\t)", - "tot": "jsonata" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 880, - "y": 1120, - "wires": [ - [ - "8a59f44f4fc0c8d0" - ] - ] - }, - { - "id": "8a59f44f4fc0c8d0", - "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Set home theather volume", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.volume_set", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "payload", - "dataType": "jsonata", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": true, - "domain": "media_player", - "service": "volume_set", - "x": 1160, - "y": 1120, - "wires": [ - [] - ] - }, - { - "id": "p2catch_aud", - "type": "catch", - "z": "f02b32ef07b4b378", - "name": "Catch all errors", - "scope": null, - "uncaught": false, - "x": 160, - "y": 2020, - "wires": [ - [ - "p2fmt_aud" - ] - ] - }, - { - "id": "p2fmt_aud", + "id": "err75c53969_f", "type": "function", - "z": "f02b32ef07b4b378", + "z": "75c53969.aa5438", "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Home Audio',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Wake up & mosquito\", data: { priority: 1 } });\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 400, - "y": 2020, + "x": 360, + "y": 2000, "wires": [ [ - "p2ntfy_aud" + "err75c53969_s" ] ] }, { - "id": "p2ntfy_aud", + "id": "err75c53969_s", "type": "api-call-service", - "z": "f02b32ef07b4b378", - "name": "Notify error", + "z": "75c53969.aa5438", + "name": "gotify_nodered", "server": "657c7463.48e1e4", "version": 7, "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], "areaId": [], "deviceId": [], "entityId": [], - "labelId": [], "data": "{{{payload}}}", "dataType": "json", "mergeContext": "", "mustacheAltTags": false, "outputProperties": [], "queue": "none", - "blockInputOverrides": false, "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 2020, + "service": "gotify_nodered", + "x": 600, + "y": 2000, "wires": [ [] ] }, { - "id": "c8d37a58.56051", - "type": "server-state-changed", - "z": "da896085.24c698", - "name": "Remote is on", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "remote.living_room" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], + "id": "pres_c_homemode", + "type": "comment", + "z": "6dfa989bb120e6c6", + "name": "── Home Mode ──", + "info": "", "x": 130, - "y": 80, - "wires": [ - [ - "73d6c796.13d8f8" - ], - [] - ] - }, - { - "id": "275763d9.2d137c", - "type": "debug", - "z": "da896085.24c698", - "name": "", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "x": 590, - "y": 260, + "y": 60, "wires": [] }, { - "id": "73d6c796.13d8f8", - "type": "switch", - "z": "da896085.24c698", - "name": "", - "property": "data.new_state.attributes.current_activity", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "Entertainment", - "vt": "str" - }, - { - "t": "eq", - "v": "Playstation", - "vt": "str" - }, - { - "t": "eq", - "v": "Play Record", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 3, - "x": 390, - "y": 80, - "wires": [ - [ - "275763d9.2d137c" - ], - [], - [] - ] - }, - { - "id": "f337ae51.b639e", - "type": "api-call-service", - "z": "da896085.24c698", - "name": "Switch to TV Scene", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "script.scene_watch_tv", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "script", - "service": "scene_watch_tv", - "output_location": "", - "output_location_type": "none", - "x": 890, - "y": 60, - "wires": [ - [] - ] - }, - { - "id": "p2catch_med", - "type": "catch", - "z": "da896085.24c698", - "name": "Catch all errors", - "scope": null, - "uncaught": false, - "x": 160, - "y": 460, - "wires": [ - [ - "p2fmt_med" - ] - ] - }, - { - "id": "p2fmt_med", - "type": "function", - "z": "da896085.24c698", - "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Home Media',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 400, - "y": 460, - "wires": [ - [ - "p2ntfy_med" - ] - ] - }, - { - "id": "p2ntfy_med", - "type": "api-call-service", - "z": "da896085.24c698", - "name": "Notify error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 460, - "wires": [ - [] - ] - }, - { - "id": "f3a37054.39c5e", + "id": "pres001a2b3c4d5e", "type": "server-state-changed", - "z": "a9edb9da.ccb6d", - "name": "Bathroom Motion", + "z": "6dfa989bb120e6c6", + "name": "Mischa presence", "server": "657c7463.48e1e4", "version": 6, "outputs": 1, "exposeAsEntityConfig": "", "entities": { "entity": [ - "binary_sensor.bathroom_motion" + "person.mischa_gorinskat" ], "substring": [], "regex": [] }, - "outputInitially": true, + "outputInitially": false, "stateType": "str", "ifState": "", "ifStateType": "str", "ifStateOperator": "is", "outputOnlyOnStateChange": true, - "for": "0", + "for": 0, "forType": "num", "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, "outputProperties": [ { "property": "payload", @@ -7213,804 +8002,64 @@ "valueType": "triggerId" } ], - "x": 160, - "y": 180, + "x": 120, + "y": 100, "wires": [ [ - "a621255c.9f3f68" + "pres002a2b3c4d5e" ] ] }, { - "id": "a621255c.9f3f68", + "id": "pres002a2b3c4d5e", "type": "switch", - "z": "a9edb9da.ccb6d", - "name": "On or Off", + "z": "6dfa989bb120e6c6", + "name": "Home or Away?", "property": "payload", "propertyType": "msg", "rules": [ { "t": "eq", - "v": "on", + "v": "home", "vt": "str" }, { "t": "eq", - "v": "off", + "v": "not_home", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 2, - "x": 340, - "y": 180, - "wires": [ - [ - "3d6da756.4dd7d8", - "2a6b709d.d09008" - ], - [ - "2a6b709d.d09008" - ] - ] - }, - { - "id": "a4c3349e.8a322", - "type": "api-call-service", - "z": "a9edb9da.ccb6d", - "name": "Turn on", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "script.{{payload}}", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "script", - "service": "{{payload}}", - "output_location": "", - "output_location_type": "none", - "x": 1140, - "y": 160, - "wires": [ - [] - ] - }, - { - "id": "53fec2fd.96730c", - "type": "api-call-service", - "z": "a9edb9da.ccb6d", - "name": "Turn off", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "light.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "light.bathroom" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_off", - "output_location": "", - "output_location_type": "none", - "x": 1020, - "y": 300, - "wires": [ - [] - ] - }, - { - "id": "3d6da756.4dd7d8", - "type": "api-current-state", - "z": "a9edb9da.ccb6d", - "name": "Bathroom light status", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "off", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "light.bathroom", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 620, - "y": 60, - "wires": [ - [ - "251c7437.a18554" - ], - [] - ] - }, - { - "id": "2a6b709d.d09008", - "type": "stoptimer-varidelay", - "z": "a9edb9da.ccb6d", - "duration": "120", - "durationType": "num", - "units": "Second", - "payloadtype": "num", - "payloadval": "0", - "name": "", - "x": 710, - "y": 240, - "wires": [ - [ - "d550e021.fe23a" - ], - [], - [] - ] - }, - { - "id": "b2bc4296.7de718", - "type": "server-state-changed", - "z": "a9edb9da.ccb6d", - "name": "Hallway Motion", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.hallway_motion" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 460, - "wires": [ - [ - "a15cb282.9b59a8" - ] - ] - }, - { - "id": "a15cb282.9b59a8", - "type": "switch", - "z": "a9edb9da.ccb6d", - "name": "On or Off", - "property": "payload", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "on", - "vt": "str" - }, - { - "t": "eq", - "v": "off", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 380, - "y": 460, - "wires": [ - [ - "e13f2dd9.12937", - "8d847d6b.3e76c8" - ], - [ - "8d847d6b.3e76c8" - ] - ] - }, - { - "id": "8a2e7e1b.11471", - "type": "api-call-service", - "z": "a9edb9da.ccb6d", - "name": "Turn off", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "light.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "light.hallway" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_off", - "output_location": "", - "output_location_type": "none", - "x": 1160, - "y": 600, - "wires": [ - [] - ] - }, - { - "id": "e13f2dd9.12937", - "type": "api-current-state", - "z": "a9edb9da.ccb6d", - "name": "Hallway light status", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "off", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "light.hallway", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 610, - "y": 420, - "wires": [ - [ - "74e4cae8.021cc4" - ], - [] - ] - }, - { - "id": "8d847d6b.3e76c8", - "type": "stoptimer-varidelay", - "z": "a9edb9da.ccb6d", - "duration": "120", - "durationType": "num", - "units": "Second", - "payloadtype": "num", - "payloadval": "0", - "name": "", - "persist": false, - "x": 670, - "y": 560, - "wires": [ - [ - "84dd47fc.401908" - ], - [], - [] - ] - }, - { - "id": "2a492dfb.c1d1aa", - "type": "subflow:e52c44dc.71cb5", - "z": "a9edb9da.ccb6d", - "name": "", - "env": [], - "x": 630, - "y": 160, - "wires": [ - [ - "2046a794.95dbf8" - ], - [ - "2046a794.95dbf8" - ] - ] - }, - { - "id": "251c7437.a18554", - "type": "change", - "z": "a9edb9da.ccb6d", - "name": "Day Mode", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "lights_bathroom_default", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 870, - "y": 180, - "wires": [ - [ - "a4c3349e.8a322" - ] - ] - }, - { - "id": "2046a794.95dbf8", - "type": "change", - "z": "a9edb9da.ccb6d", - "name": "NIght Mode", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "lights_bathroom_night", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 870, - "y": 140, - "wires": [ - [ - "a4c3349e.8a322" - ] - ] - }, - { - "id": "f75b8e7d.5a41", - "type": "api-call-service", - "z": "a9edb9da.ccb6d", - "name": "Turn on", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "script.{{payload}}", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "script", - "service": "{{payload}}", - "output_location": "", - "output_location_type": "none", - "x": 1160, - "y": 500, - "wires": [ - [] - ] - }, - { - "id": "2ec0419c.2b47de", - "type": "subflow:e52c44dc.71cb5", - "z": "a9edb9da.ccb6d", - "name": "", - "env": [], - "x": 650, - "y": 500, - "wires": [ - [ - "75d95034.3eedb8" - ], - [ - "75d95034.3eedb8" - ] - ] - }, - { - "id": "74e4cae8.021cc4", - "type": "change", - "z": "a9edb9da.ccb6d", - "name": "Day Mode", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "lights_hallway_default", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 890, - "y": 520, - "wires": [ - [ - "f75b8e7d.5a41" - ] - ] - }, - { - "id": "75d95034.3eedb8", - "type": "change", - "z": "a9edb9da.ccb6d", - "name": "NIght Mode", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "lights_hallway_night", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 890, - "y": 480, - "wires": [ - [ - "f75b8e7d.5a41" - ] - ] - }, - { - "id": "d81ec1ce.a79708", - "type": "server-state-changed", - "z": "a9edb9da.ccb6d", - "name": "Bathroom Motion", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.bathroom_motion" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 740, - "wires": [ - [ - "871cbf67.15da1" - ], - [] - ] - }, - { - "id": "4f7b5988.be4f98", - "type": "server-state-changed", - "z": "a9edb9da.ccb6d", - "name": "Hallway Motion", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.hallway_motion" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 800, - "wires": [ - [ - "968bedf.e30a31" - ], - [] - ] - }, - { - "id": "b0a84917.d9a89", - "type": "server-state-changed", - "z": "a9edb9da.ccb6d", - "name": "Livingroom Motion", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.livingroom_motion" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 190, - "y": 860, - "wires": [ - [ - "d614641a.552438" - ], - [] - ] - }, - { - "id": "871cbf67.15da1", - "type": "change", - "z": "a9edb9da.ccb6d", - "name": "Set Bathroom", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "bathroom", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, "x": 400, - "y": 740, + "y": 100, "wires": [ [ - "7d3df8ac.4610c", - "bce32dc1.85221" + "pres003a2b3c4d5e" + ], + [ + "pres004a2b3c4d5e" ] ] }, { - "id": "968bedf.e30a31", - "type": "change", - "z": "a9edb9da.ccb6d", - "name": "Set Hallway", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "hallway", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 390, - "y": 800, - "wires": [ - [ - "7d3df8ac.4610c", - "bce32dc1.85221" - ] - ] - }, - { - "id": "d614641a.552438", - "type": "change", - "z": "a9edb9da.ccb6d", - "name": "Set Livingroom", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "livingroom", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 400, - "y": 860, - "wires": [ - [ - "7d3df8ac.4610c", - "bce32dc1.85221" - ] - ] - }, - { - "id": "7d3df8ac.4610c", + "id": "pres003a2b3c4d5e", "type": "api-call-service", - "z": "a9edb9da.ccb6d", - "name": "Update last motion to value", + "z": "6dfa989bb120e6c6", + "name": "Set Home", "server": "657c7463.48e1e4", "version": 7, - "debugenabled": true, + "debugenabled": false, "action": "input_select.select_option", "floorId": [], "areaId": [], "deviceId": [], "entityId": [ - "input_select.last_motion" + "input_select.home_mode" ], "labelId": [], - "data": "{\"option\":\"{{payload}}\"}", + "data": "{\"option\": \"Home\"}", "dataType": "json", "mergeContext": "", "mustacheAltTags": false, @@ -8019,94 +8068,1857 @@ "blockInputOverrides": false, "domain": "input_select", "service": "select_option", - "output_location": "", - "output_location_type": "none", - "x": 770, - "y": 820, + "x": 660, + "y": 60, "wires": [ [] ] }, { - "id": "c59f167c.f20e", + "id": "pres004a2b3c4d5e", "type": "api-call-service", - "z": "a9edb9da.ccb6d", - "name": "Notify via HA", + "z": "6dfa989bb120e6c6", + "name": "Set Away", "server": "657c7463.48e1e4", "version": 7, "debugenabled": false, - "action": "notify.gotify_ha", + "action": "input_select.select_option", "floorId": [], "areaId": [], "deviceId": [], - "entityId": [], + "entityId": [ + "input_select.home_mode" + ], "labelId": [], - "data": "{\"title\":\"Info\",\"message\":\"{{{payload}}}\"}", + "data": "{\"option\": \"Away\"}", "dataType": "json", "mergeContext": "", "mustacheAltTags": false, "outputProperties": [], "queue": "none", "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 1010, - "y": 940, + "domain": "input_select", + "service": "select_option", + "x": 660, + "y": 140, "wires": [ [] ] }, { - "id": "bce32dc1.85221", - "type": "template", - "z": "a9edb9da.ccb6d", - "name": "Motion detected in...", - "field": "payload", - "fieldType": "msg", - "format": "handlebars", - "syntax": "mustache", - "template": "Motion detected in {{payload}}.", - "output": "str", - "x": 720, - "y": 940, - "wires": [ - [] - ] - }, - { - "id": "7529dee.0a6322", + "id": "pres_sm_c_header", "type": "comment", - "z": "a9edb9da.ccb6d", - "name": "Enable notifications when we have out of home detection", - "info": "", - "x": 830, - "y": 900, - "wires": [] - }, - { - "id": "7b42fe61.f5b758", - "type": "comment", - "z": "a9edb9da.ccb6d", - "name": "Set last motion entity", + "z": "6dfa989bb120e6c6", + "name": "── Room Presence State Machine ──", "info": "", "x": 190, - "y": 700, + "y": 300, "wires": [] }, { - "id": "d550e021.fe23a", + "id": "pres_sm_c_person", + "type": "comment", + "z": "6dfa989bb120e6c6", + "name": "Person", + "info": "", + "x": 90, + "y": 360, + "wires": [] + }, + { + "id": "pres_sm_c_hall", + "type": "comment", + "z": "6dfa989bb120e6c6", + "name": "Hallway (direction + state)", + "info": "", + "x": 150, + "y": 480, + "wires": [] + }, + { + "id": "pres_sm_c_rooms", + "type": "comment", + "z": "6dfa989bb120e6c6", + "name": "Room Motion Sensors", + "info": "", + "x": 140, + "y": 780, + "wires": [] + }, + { + "id": "pres_sm_c_sm", + "type": "comment", + "z": "6dfa989bb120e6c6", + "name": "State Machine", + "info": "", + "x": 450, + "y": 580, + "wires": [] + }, + { + "id": "pres_sm_c_out", + "type": "comment", + "z": "6dfa989bb120e6c6", + "name": "Outputs", + "info": "", + "x": 730, + "y": 580, + "wires": [] + }, + { + "id": "pres_sm_person", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Person (room SM)", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "person.mischa_gorinskat" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 130, + "y": 400, + "wires": [ + [ + "pres_sm_func" + ] + ] + }, + { + "id": "pres_sm_hall1", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Hallway S1 (corner/front door)", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.hallway_motion_sensor_1_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 160, + "y": 520, + "wires": [ + [ + "pres_sm_func" + ] + ] + }, + { + "id": "pres_sm_hall2", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Hallway S2 (near living room)", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.hallway_motion_sensor_2_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 160, + "y": 580, + "wires": [ + [ + "pres_sm_func" + ] + ] + }, + { + "id": "pres_sm_hall3", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Hallway S3 (near kitchen)", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.hallway_motion_sensor_3_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 150, + "y": 640, + "wires": [ + [ + "pres_sm_func" + ] + ] + }, + { + "id": "pres_sm_hallg", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Hallway (group)", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.hallway_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 120, + "y": 700, + "wires": [ + [ + "pres_sm_func" + ] + ] + }, + { + "id": "pres_sm_lr", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Living Room Motion", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.livingroom_motion_sensor_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 130, + "y": 820, + "wires": [ + [ + "pres_sm_func", + "220b2cc030918c97" + ] + ] + }, + { + "id": "pres_sm_bed", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Bedroom Motion", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.bedroom_motion_sensor_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 120, + "y": 880, + "wires": [ + [ + "pres_sm_func", + "220b2cc030918c97" + ] + ] + }, + { + "id": "pres_sm_bath", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Bathroom Motion", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.bathroom_motion_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 120, + "y": 940, + "wires": [ + [ + "pres_sm_func", + "220b2cc030918c97" + ] + ] + }, + { + "id": "pres_sm_kit", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Kitchen Motion", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.kitchen_motion_sensor_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 120, + "y": 1000, + "wires": [ + [ + "pres_sm_func", + "220b2cc030918c97" + ] + ] + }, + { + "id": "pres_sm_func", + "type": "function", + "z": "6dfa989bb120e6c6", + "name": "Room Presence SM", + "func": "// === ROOM PRESENCE STATE MACHINE ===\n// msg.topic = triggering entity_id (from triggerId output property)\n// msg.payload = entity state string\n// msg.data = full HASC event data\n\nconst entityId = (msg.data && msg.data.entity_id) ? msg.data.entity_id : (msg.topic || '');\nconst newState = (msg.data && msg.data.new_state) ? msg.data.new_state.state : msg.payload;\n\n// Guest mode guard — multi-person breaks single-occupant assumptions\nconst haStates = (global.get('homeassistant') || {}).homeAssistantLatest\n ? global.get('homeassistant').homeAssistantLatest.states : {};\nconst guestMode = (haStates['input_boolean.guest_mode'] || {}).state;\nif (guestMode === 'on') return null;\n\n// Current state from flow context\nlet currentRoom = flow.get('currentRoom') || 'unknown';\n\n// ── Helpers ────────────────────────────────────────────────────────────────\n\nfunction capitalize(s) {\n const map = {\n unknown: 'Unknown', away: 'Away', hallway: 'Hallway',\n living_room: 'Livingroom', bedroom: 'Bedroom',\n bathroom: 'Bathroom', kitchen: 'Kitchen', balcony: 'Balcony'\n };\n return map[s] || (s.charAt(0).toUpperCase() + s.slice(1));\n}\n\nfunction cancelDestTimer() {\n const h = flow.get('destTimerHandle');\n if (h) { clearTimeout(h); flow.set('destTimerHandle', null); }\n}\n\nfunction setDestTimer() {\n cancelDestTimer();\n const h = setTimeout(function () {\n const lr = flow.get('lastRoom') || 'unknown';\n flow.set('currentRoom', lr);\n flow.set('destTimerHandle', null);\n node.send([\n { payload: capitalize(lr) },\n { payload: '[presence] dest-timer expired → reverted to ' + lr }\n ]);\n }, 90000);\n flow.set('destTimerHandle', h);\n}\n\nfunction setState(newRoom) {\n const prev = flow.get('currentRoom') || 'unknown';\n if (newRoom === prev) return null; // no change needed\n flow.set('lastRoom', prev);\n flow.set('currentRoom', newRoom);\n return [\n { payload: capitalize(newRoom) },\n { payload: '[presence] ' + prev + ' → ' + newRoom + ' (via ' + entityId + ')' }\n ];\n}\n\nfunction updateHallwaySequence(sensorNum) {\n let seq = flow.get('hallwaySequence') || [];\n const now = Date.now();\n seq = seq.filter(function (e) { return now - e.time < 15000; });\n seq.push({ sensor: sensorNum, time: now });\n flow.set('hallwaySequence', seq);\n flow.set('lastHallwayTime', now);\n}\n\n// ── Transitions ────────────────────────────────────────────────────────────\n\n// 1. Person home / away\nif (entityId === 'person.mischa_gorinskat') {\n if (newState === 'not_home') {\n cancelDestTimer();\n return setState('away');\n }\n if (newState === 'home') {\n return setState('unknown');\n }\n return null;\n}\n\n// Ignore all motion when person is away\nif (currentRoom === 'away') return null;\n\n// 2. Individual hallway sensors — direction tracking only, no state change\nif (entityId === 'binary_sensor.hallway_motion_sensor_1_occupancy') {\n if (newState === 'on') updateHallwaySequence(1);\n return null;\n}\nif (entityId === 'binary_sensor.hallway_motion_sensor_2_occupancy') {\n if (newState === 'on') updateHallwaySequence(2);\n return null;\n}\nif (entityId === 'binary_sensor.hallway_motion_sensor_3_occupancy') {\n if (newState === 'on') updateHallwaySequence(3);\n return null;\n}\n\n// 3. Hallway group — primary state change trigger\nif (entityId === 'binary_sensor.hallway_occupancy') {\n if (newState === 'on') {\n flow.set('lastRoom', currentRoom); // save room before entering hallway\n setDestTimer(); // 90s: if no room fires → revert\n return setState('hallway');\n }\n return null; // hallway turning off doesn't trigger a state change\n}\n\n// 4. Room sensors\nconst roomMap = {\n 'binary_sensor.livingroom_motion_sensor_occupancy': 'living_room',\n 'binary_sensor.bedroom_motion_sensor_occupancy': 'bedroom',\n 'binary_sensor.bathroom_motion_occupancy': 'bathroom',\n 'binary_sensor.kitchen_motion_sensor_occupancy': 'kitchen',\n 'binary_sensor.balcony_motion_occupancy': 'balcony'\n};\n\nconst targetRoom = roomMap[entityId];\nif (targetRoom) {\n if (newState === 'on') {\n cancelDestTimer(); // confirmed destination\n\n // Balcony is accessed directly from living room, not via hallway\n if (targetRoom === 'balcony' && currentRoom === 'living_room') {\n return setState('balcony');\n }\n\n // Return from balcony via living room motion\n if (targetRoom === 'living_room' && currentRoom === 'balcony') {\n return setState('living_room');\n }\n\n // Accept if we came through hallway, are re-confirming same room, or state is unknown\n if (currentRoom === 'hallway' || currentRoom === targetRoom || currentRoom === 'unknown') {\n return setState(targetRoom);\n }\n return null;\n }\n return null;\n}\n\nnode.error('Unrecognised entity in Room Presence SM: ' + entityId + ' (state: ' + newState + ')', msg);\nreturn null;", + "outputs": 2, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 480, + "y": 620, + "wires": [ + [ + "pres_sm_api", + "ee5e4c61fe053644" + ], + [ + "pres_sm_dbg" + ] + ] + }, + { + "id": "pres_sm_api", + "type": "api-call-service", + "z": "6dfa989bb120e6c6", + "name": "Set Room Presence", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "input_select.select_option", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "input_select.room_presence" + ], + "labelId": [], + "data": "{\"option\": \"{{{payload}}}\"}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "input_select", + "service": "select_option", + "x": 780, + "y": 620, + "wires": [ + [] + ] + }, + { + "id": "pres_sm_dbg", + "type": "debug", + "z": "6dfa989bb120e6c6", + "name": "Presence log", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 750, + "y": 680, + "wires": [] + }, + { + "id": "pres_sm_bal", + "type": "server-state-changed", + "z": "6dfa989bb120e6c6", + "name": "Balcony Motion", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.balcony_motion_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 120, + "y": 1060, + "wires": [ + [ + "pres_sm_func", + "220b2cc030918c97" + ] + ] + }, + { + "id": "err6dfa989b_c", + "type": "catch", + "z": "6dfa989bb120e6c6", + "name": "Tab errors", + "scope": null, + "uncaught": false, + "x": 120, + "y": 2000, + "wires": [ + [ + "err6dfa989b_f" + ] + ] + }, + { + "id": "err6dfa989b_f", + "type": "function", + "z": "6dfa989bb120e6c6", + "name": "Format error", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || \"Unknown error\");\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Home Presence\", data: { priority: 1 } });\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 360, + "y": 2000, + "wires": [ + [ + "err6dfa989b_s" + ] + ] + }, + { + "id": "err6dfa989b_s", + "type": "api-call-service", + "z": "6dfa989bb120e6c6", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "notify", + "service": "gotify_nodered", + "x": 600, + "y": 2000, + "wires": [ + [] + ] + }, + { + "id": "220b2cc030918c97", + "type": "debug", + "z": "6dfa989bb120e6c6", + "name": "debug 2", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 560, + "y": 800, + "wires": [] + }, + { + "id": "ee5e4c61fe053644", + "type": "debug", + "z": "6dfa989bb120e6c6", + "name": "debug 5", + "active": true, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "false", + "statusVal": "", + "statusType": "auto", + "x": 760, + "y": 520, + "wires": [] + }, + { + "id": "cc000001", + "type": "comment", + "z": "bbf25964.5edb38", + "name": "Coffee Circle Subscription — fetches next delivery data every 6h", + "info": "", + "x": 270, + "y": 380, + "wires": [] + }, + { + "id": "cc000002", + "type": "inject", + "z": "bbf25964.5edb38", + "name": "Every 6h + on deploy", + "props": [ + { + "p": "payload" + }, + { + "p": "topic", + "vt": "str" + } + ], + "repeat": "21600", + "crontab": "", + "once": true, + "onceDelay": "5", + "topic": "", + "payload": "", + "payloadType": "date", + "x": 150, + "y": 440, + "wires": [ + [ + "cc000004" + ] + ] + }, + { + "id": "cc000003", + "type": "link in", + "z": "bbf25964.5edb38", + "name": "CC Fetch Trigger", + "links": [], + "x": 165, + "y": 500, + "wires": [ + [ + "cc000004" + ] + ] + }, + { + "id": "cc000004", + "type": "change", + "z": "bbf25964.5edb38", + "name": "Read session cookie", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "CC_SESSION", + "tot": "env" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 390, + "y": 440, + "wires": [ + [ + "cc000005" + ] + ] + }, + { + "id": "cc000005", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Build auth request", + "func": "const sessionCookie = msg.payload;\nif (!sessionCookie || sessionCookie === '') {\n node.error('CC_SESSION env var is empty — set it in Node-RED Coffee-mations tab settings');\n return null;\n}\nmsg.url = 'https://account.coffeecircle.com/oauth/token';\nmsg.method = 'GET';\nmsg.headers = { 'Cookie': '_shopify_essential=' + sessionCookie };\nmsg.payload = '';\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 650, + "y": 440, + "wires": [ + [ + "cc000006" + ] + ] + }, + { + "id": "cc000006", + "type": "http request", + "z": "bbf25964.5edb38", + "name": "GET /oauth/token", + "method": "use", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 850, + "y": 440, + "wires": [ + [ + "cc000007", + "cc00000f" + ] + ] + }, + { + "id": "cc000007", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Extract token + charges URL", + "func": "const resp = msg.payload;\nconst token = resp?.access_token || resp?.token || resp?.bearer_token || resp?.accessToken || resp?.id_token;\nif (!token) {\n node.error('/oauth/token response: ' + JSON.stringify(resp));\n return null;\n}\nflow.set('cc_token', token);\nconst today = new Date().toISOString().split('T')[0];\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges?status=queued,error,skipped&scheduledAtMin=' + today;\nmsg.method = 'GET';\nmsg.headers = { 'Authorization': 'Bearer ' + token };\nmsg.payload = '';\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1110, + "y": 440, + "wires": [ + [ + "cc000008" + ] + ] + }, + { + "id": "cc000008", + "type": "http request", + "z": "bbf25964.5edb38", + "name": "GET /charges", + "method": "use", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 1330, + "y": 440, + "wires": [ + [ + "cc000009", + "cc000010" + ] + ] + }, + { + "id": "cc000009", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Parse charges → charge_id", + "func": "const resp = msg.payload;\nconst charges = resp?.charges || resp?.data || resp?.items || resp?.results || (Array.isArray(resp) ? resp : null);\nif (!charges || charges.length === 0) {\n node.error('No queued charges. Response: ' + JSON.stringify(resp).substring(0, 300));\n return null;\n}\nconst charge = charges[0];\nconst chargeId = charge?.id || charge?.charge_id;\nconst deliveryDate = charge?.scheduledAt || charge?.scheduled_at || charge?.next_billing_date || charge?.billing_date || charge?.ship_date;\nif (!chargeId) {\n node.error('Cannot extract charge ID. Keys: ' + Object.keys(charge || {}).join(', '));\n return null;\n}\nflow.set('cc_charge_id', String(chargeId));\nflow.set('cc_delivery_date', deliveryDate || 'unknown');\nconst token = flow.get('cc_token');\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges/' + chargeId;\nmsg.method = 'GET';\nmsg.headers = { 'Authorization': 'Bearer ' + token };\nmsg.payload = '';\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1570, + "y": 440, + "wires": [ + [ + "cc00000a" + ] + ] + }, + { + "id": "cc00000a", + "type": "http request", + "z": "bbf25964.5edb38", + "name": "GET /charges/", + "method": "use", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 1810, + "y": 440, + "wires": [ + [ + "cc00000b", + "cc000011" + ] + ] + }, + { + "id": "cc00000b", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Parse detail → 3 sensors", + "func": "const resp = msg.payload;\nconst charge = resp?.charge || resp?.data || resp;\nconst lineItems = charge?.lineItems || charge?.line_items || charge?.items || [];\nconst firstItem = lineItems[0] || {};\nconst product = firstItem.title || firstItem.product_title || firstItem.name || charge?.product_title || 'Coffee subscription';\nconst totalObj = charge?.totalAmount || {};\nconst totalVal = totalObj?.amount || charge?.total_price || charge?.total || '?';\nconst currency = totalObj?.currencyCode || 'EUR';\nconst currencySymbol = { EUR: '€', USD: '$', GBP: '£' }[currency] || currency + ' ';\nconst total = currencySymbol + totalVal;\nconst deliveryDate = flow.get('cc_delivery_date') || charge?.scheduledAt || charge?.scheduled_at || 'unknown';\nconst mkMsg = p => ({ _msgid: msg._msgid, payload: p });\nreturn [mkMsg(deliveryDate), mkMsg(product), mkMsg(total)];", + "outputs": 3, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 2050, + "y": 440, + "wires": [ + [ + "cc00000c" + ], + [ + "cc00000d" + ], + [ + "cc00000e" + ] + ] + }, + { + "id": "cc00000c", + "type": "ha-sensor", + "z": "bbf25964.5edb38", + "name": "cc_next_delivery_date", + "entityConfig": "cc000023", + "version": 1, + "state": "payload", + "stateType": "msg", + "attributes": [], + "inputOverride": "allow", + "outputProperties": [], + "x": 2310, + "y": 400, + "wires": [ + [] + ] + }, + { + "id": "cc00000d", + "type": "ha-sensor", + "z": "bbf25964.5edb38", + "name": "cc_next_delivery_product", + "entityConfig": "cc000024", + "version": 1, + "state": "payload", + "stateType": "msg", + "attributes": [], + "inputOverride": "allow", + "outputProperties": [], + "x": 2310, + "y": 440, + "wires": [ + [] + ] + }, + { + "id": "cc00000e", + "type": "ha-sensor", + "z": "bbf25964.5edb38", + "name": "cc_next_delivery_total", + "entityConfig": "cc000025", + "version": 1, + "state": "payload", + "stateType": "msg", + "attributes": [], + "inputOverride": "allow", + "outputProperties": [], + "x": 2310, + "y": 480, + "wires": [ + [] + ] + }, + { + "id": "cc00000f", + "type": "debug", + "z": "bbf25964.5edb38", + "name": "Token response", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 850, + "y": 520, + "wires": [] + }, + { + "id": "cc000010", + "type": "debug", + "z": "bbf25964.5edb38", + "name": "Charges response", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 1330, + "y": 520, + "wires": [] + }, + { + "id": "cc000011", + "type": "debug", + "z": "bbf25964.5edb38", + "name": "Detail response", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 1810, + "y": 520, + "wires": [] + }, + { + "id": "cc000012", + "type": "catch", + "z": "bbf25964.5edb38", + "name": "CC Errors", + "scope": [ + "cc000005", + "cc000006", + "cc000007", + "cc000008", + "cc000009", + "cc00000a", + "cc00000b", + "cc000018", + "cc000019", + "cc00001a", + "cc00001b", + "cc00001c", + "cc00001d" + ], + "uncaught": false, + "x": 120, + "y": 220, + "wires": [ + [ + "cc000013" + ] + ] + }, + { + "id": "cc000013", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Format error", + "func": "const errMsg = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({\n message: errMsg + '\n\nIf auth error: update CC_SESSION env var in Node-RED tab settings.',\n title: 'NR Error: Coffee-mations',\n data: { priority: 1 }\n});\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 350, + "y": 220, + "wires": [ + [ + "cc000014" + ] + ] + }, + { + "id": "cc000014", + "type": "api-call-service", + "z": "bbf25964.5edb38", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "notify", + "service": "gotify_nodered", + "x": 570, + "y": 220, + "wires": [ + [] + ] + }, + { + "id": "cc000015", + "type": "comment", + "z": "bbf25964.5edb38", + "name": "CC Send Now — triggers immediate delivery on button press", + "info": "", + "x": 260, + "y": 580, + "wires": [] + }, + { + "id": "cc000016", + "type": "ha-button", + "z": "bbf25964.5edb38", + "name": "CC Send Now button", + "version": 1, + "outputs": 1, + "entityConfig": "cc000026", + "outputProperties": [], + "x": 140, + "y": 620, + "wires": [ + [ + "cc000017" + ] + ] + }, + { + "id": "cc000017", + "type": "change", + "z": "bbf25964.5edb38", + "name": "Read session cookie", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "CC_SESSION", + "tot": "env" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 380, + "y": 620, + "wires": [ + [ + "cc000018" + ] + ] + }, + { + "id": "cc000018", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Build auth request", + "func": "const sessionCookie = msg.payload;\nif (!sessionCookie || sessionCookie === '') {\n node.error('CC_SESSION env var is empty');\n return null;\n}\nmsg.url = 'https://account.coffeecircle.com/oauth/token';\nmsg.method = 'GET';\nmsg.headers = { 'Cookie': '_shopify_essential=' + sessionCookie };\nmsg.payload = '';\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 610, + "y": 620, + "wires": [ + [ + "cc000019" + ] + ] + }, + { + "id": "cc000019", + "type": "http request", + "z": "bbf25964.5edb38", + "name": "GET /oauth/token", + "method": "use", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 610, + "y": 680, + "wires": [ + [ + "cc00001a" + ] + ] + }, + { + "id": "cc00001a", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Extract token + charges URL", + "func": "const resp = msg.payload;\nconst token = resp?.access_token || resp?.token || resp?.bearer_token || resp?.accessToken || resp?.id_token;\nif (!token) {\n node.error('/oauth/token response: ' + JSON.stringify(resp));\n return null;\n}\nflow.set('cc_token', token);\nconst today = new Date().toISOString().split('T')[0];\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges?status=queued,error,skipped&scheduledAtMin=' + today;\nmsg.method = 'GET';\nmsg.headers = { 'Authorization': 'Bearer ' + token };\nmsg.payload = '';\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1000, + "y": 620, + "wires": [ + [ + "cc00001b" + ] + ] + }, + { + "id": "cc00001b", + "type": "http request", + "z": "bbf25964.5edb38", + "name": "GET /charges", + "method": "use", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 960, + "y": 680, + "wires": [ + [ + "cc00001c" + ] + ] + }, + { + "id": "cc00001c", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Extract charge_id + build process URL", + "func": "const resp = msg.payload;\nconst charges = resp?.charges || resp?.data || resp?.items || resp?.results || (Array.isArray(resp) ? resp : null);\nif (!charges || charges.length === 0) {\n node.error('No queued charges for Send Now');\n return null;\n}\nconst charge = charges[0];\nconst chargeId = charge?.id || charge?.charge_id;\nif (!chargeId) {\n node.error('Cannot extract charge ID. Keys: ' + Object.keys(charge || {}).join(', '));\n return null;\n}\nconst token = flow.get('cc_token');\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges/' + chargeId + '/process';\nmsg.method = 'POST';\nmsg.headers = { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' };\nmsg.payload = {};\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1370, + "y": 620, + "wires": [ + [ + "cc00001d" + ] + ] + }, + { + "id": "cc00001d", + "type": "http request", + "z": "bbf25964.5edb38", + "name": "POST /charges//process", + "method": "use", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 1340, + "y": 680, + "wires": [ + [ + "cc00001e" + ] + ] + }, + { + "id": "cc00001e", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Check result", + "func": "const statusCode = msg.statusCode;\nif (statusCode >= 200 && statusCode < 300) {\n return [msg, null];\n}\nconst detail = JSON.stringify(msg.payload).substring(0, 200);\nmsg.payload = JSON.stringify({\n title: 'Coffee Circle Send Now Failed',\n message: 'HTTP ' + statusCode + ': ' + detail,\n notification_id: 'cc_send_now_error'\n});\nreturn [null, msg];", + "outputs": 2, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1650, + "y": 660, + "wires": [ + [ + "cc00001f" + ], + [ + "cc000020" + ] + ] + }, + { + "id": "cc00001f", + "type": "link out", + "z": "bbf25964.5edb38", + "name": "Trigger CC Fetch", + "mode": "link", + "links": [ + "cc000003" + ], + "x": 1785, + "y": 640, + "wires": [] + }, + { + "id": "cc000020", + "type": "api-call-service", + "z": "bbf25964.5edb38", + "name": "Notify Send Now error", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "persistent_notification", + "service": "create", + "x": 1880, + "y": 700, + "wires": [ + [] + ] + }, + { + "id": "cc000028", + "type": "comment", + "z": "bbf25964.5edb38", + "name": "CC Postpone by 1 Week — postpones delivery by 7 days on button press", + "info": "", + "x": 320, + "y": 820, + "wires": [] + }, + { + "id": "cc000029", + "type": "ha-button", + "z": "bbf25964.5edb38", + "name": "CC Postpone 1 week", + "version": 1, + "outputs": 1, + "entityConfig": "cc000027", + "outputProperties": [], + "x": 160, + "y": 880, + "wires": [ + [ + "cc00002a" + ] + ] + }, + { + "id": "cc00002a", + "type": "change", + "z": "bbf25964.5edb38", + "name": "Read session cookie", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "CC_SESSION", + "tot": "env" + }, + { + "t": "set", + "p": "cc_session_cookie", + "pt": "flow", + "to": "payload", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 380, + "y": 880, + "wires": [ + [ + "cc00002b" + ] + ] + }, + { + "id": "cc00002b", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Build auth request", + "func": "const sessionCookie = msg.payload;\nif (!sessionCookie || sessionCookie === '') {\n node.error('CC_SESSION env var is empty');\n return null;\n}\nmsg.url = 'https://account.coffeecircle.com/oauth/token';\nmsg.method = 'GET';\nmsg.headers = { 'Cookie': '_shopify_essential=' + sessionCookie };\nmsg.payload = '';\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 620, + "y": 880, + "wires": [ + [ + "cc00002c" + ] + ] + }, + { + "id": "cc00002c", + "type": "http request", + "z": "bbf25964.5edb38", + "name": "GET /oauth/token", + "method": "use", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 860, + "y": 880, + "wires": [ + [ + "cc00002d" + ] + ] + }, + { + "id": "cc00002d", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Extract token + charges URL", + "func": "const resp = msg.payload;\nconst token = resp?.access_token || resp?.token || resp?.bearer_token || resp?.accessToken || resp?.id_token;\nif (!token) {\n node.error('/oauth/token response: ' + JSON.stringify(resp));\n return null;\n}\nflow.set('cc_token', token);\nconst today = new Date().toISOString().split('T')[0];\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges?status=queued,error,skipped&scheduledAtMin=' + today;\nmsg.method = 'GET';\nmsg.headers = { 'Authorization': 'Bearer ' + token };\nmsg.payload = '';\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1120, + "y": 880, + "wires": [ + [ + "cc00002e" + ] + ] + }, + { + "id": "cc00002e", + "type": "http request", + "z": "bbf25964.5edb38", + "name": "GET /charges", + "method": "use", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 1340, + "y": 880, + "wires": [ + [ + "cc00002f" + ] + ] + }, + { + "id": "cc00002f", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Extract charge_id + build reschedule", + "func": "const resp = msg.payload;\nconst charges = resp?.charges || resp?.data || resp?.items || resp?.results || (Array.isArray(resp) ? resp : null);\nif (!charges || charges.length === 0) {\n node.error('No queued charges for Postpone');\n return null;\n}\nconst charge = charges[0];\nconst chargeId = charge?.id || charge?.charge_id;\nif (!chargeId) {\n node.error('Cannot extract charge ID. Keys: ' + Object.keys(charge || {}).join(', '));\n return null;\n}\nflow.set('cc_charge_id', String(chargeId));\nconst states = global.get('homeassistant')?.homeAssistantLatest?.states;\nconst dateStr = states?.['sensor.cc_next_delivery_date']?.state || flow.get('cc_delivery_date');\nif (!dateStr || dateStr === 'unknown' || dateStr === 'unavailable') {\n node.error('Cannot read current delivery date: ' + dateStr);\n return null;\n}\nconst d = new Date(dateStr);\nd.setDate(d.getDate() + 7);\nconst newDate = d.toISOString().split('T')[0];\nconst token = flow.get('cc_token');\nmsg.url = 'https://api.coffeecircle.com/api/subscription/charges/' + chargeId + '/reschedule';\nmsg.method = 'PUT';\nmsg.headers = { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' };\nmsg.payload = { scheduledAt: newDate };\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1600, + "y": 880, + "wires": [ + [ + "cc000030" + ] + ] + }, + { + "id": "cc000030", + "type": "http request", + "z": "bbf25964.5edb38", + "name": "PUT /reschedule", + "method": "use", + "ret": "obj", + "paytoqs": "ignore", + "url": "", + "tls": "", + "persist": false, + "proxy": "", + "insecureHTTPParser": false, + "authType": "", + "senderr": false, + "headers": [], + "x": 1860, + "y": 880, + "wires": [ + [ + "cc000031" + ] + ] + }, + { + "id": "cc000031", + "type": "function", + "z": "bbf25964.5edb38", + "name": "Check reschedule result", + "func": "const statusCode = msg.statusCode;\nif (statusCode >= 200 && statusCode < 300) {\n return [msg, null, null];\n}\nif (statusCode === 401 && !msg._retried) {\n msg._retried = true;\n msg.payload = flow.get('cc_session_cookie');\n return [null, msg, null];\n}\nconst detail = JSON.stringify(msg.payload).substring(0, 200);\nmsg.payload = JSON.stringify({\n title: 'Coffee Circle Postpone Failed',\n message: 'HTTP ' + statusCode + ': ' + detail,\n notification_id: 'cc_postpone_error'\n});\nreturn [null, null, msg];", + "outputs": 3, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 2080, + "y": 880, + "wires": [ + [ + "cc000032" + ], + [ + "cc00002b" + ], + [ + "cc000033" + ] + ] + }, + { + "id": "cc000032", + "type": "link out", + "z": "bbf25964.5edb38", + "name": "Trigger CC Fetch", + "mode": "link", + "links": [ + "cc000003" + ], + "x": 2300, + "y": 860, + "wires": [] + }, + { + "id": "cc000033", + "type": "api-call-service", + "z": "bbf25964.5edb38", + "name": "Notify postpone error", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "persistent_notification", + "service": "create", + "x": 2320, + "y": 920, + "wires": [ + [] + ] + }, + { + "id": "f3d66e8924f18806", + "type": "server-state-changed", + "z": "10cbea6aaac127cd", + "name": "Balcony Tradfri button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "sensor.balcony_light_switch_action" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "on", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 180, + "y": 140, + "wires": [ + [ + "f1e907e6ede24945" + ], + [] + ] + }, + { + "id": "9412a727b1cbef12", + "type": "comment", + "z": "10cbea6aaac127cd", + "name": "Balcony light control", + "info": "", + "x": 170, + "y": 100, + "wires": [] + }, + { + "id": "f1e907e6ede24945", "type": "api-current-state", - "z": "a9edb9da.ccb6d", - "name": "Still in bathroom?", + "z": "10cbea6aaac127cd", + "name": "Balcony Lights On?", "server": "657c7463.48e1e4", "version": 3, "outputs": 2, - "halt_if": "bathroom", + "halt_if": "on", "halt_if_type": "str", "halt_if_compare": "is", - "entity_id": "input_select.last_motion", + "entity_id": "light.outdoor_light_string", "state_type": "str", "blockInputOverrides": false, "outputProperties": [ @@ -8123,90 +9935,467 @@ "valueType": "entity" } ], - "for": 0, + "for": "0", "forType": "num", "forUnits": "minutes", - "x": 710, - "y": 320, + "override_topic": false, + "state_location": "payload", + "override_payload": "msg", + "entity_location": "data", + "override_data": "msg", + "x": 510, + "y": 140, "wires": [ [ - "2a6b709d.d09008" + "199c4827dec86225" ], [ - "53fec2fd.96730c" + "a29b4c78a44241b6" ] ] }, { - "id": "3efd032.0055a7c", - "type": "subflow:e52c44dc.71cb5", - "z": "a9edb9da.ccb6d", - "name": "", - "env": [], - "x": 550, - "y": 1100, - "wires": [ - [ - "7c0d40bf.1ee4c" - ], - [ - "7c0d40bf.1ee4c" - ] - ] - }, - { - "id": "a3eba9b6.df5ca8", - "type": "inject", - "z": "a9edb9da.ccb6d", - "name": "", - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 320, - "y": 1080, - "wires": [ - [ - "3efd032.0055a7c" - ] - ] - }, - { - "id": "7c0d40bf.1ee4c", - "type": "debug", - "z": "a9edb9da.ccb6d", - "name": "", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "false", + "id": "a29b4c78a44241b6", + "type": "api-call-service", + "z": "10cbea6aaac127cd", + "name": "Turn on balcony lights", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": true, + "action": "light.turn_on", + "floorId": [], + "areaId": [ + "balcony" + ], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "light", + "service": "turn_on", "x": 860, - "y": 1100, - "wires": [] + "y": 160, + "wires": [ + [] + ] }, { - "id": "fc251c5a.cc6918", + "id": "199c4827dec86225", + "type": "api-call-service", + "z": "10cbea6aaac127cd", + "name": "Turn of balcony lights", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": true, + "action": "light.turn_off", + "floorId": [], + "areaId": [ + "balcony" + ], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "light", + "service": "turn_off", + "x": 860, + "y": 100, + "wires": [ + [] + ] + }, + { + "id": "err10cbea6a_c", + "type": "catch", + "z": "10cbea6aaac127cd", + "name": "Tab errors", + "scope": null, + "uncaught": false, + "x": 120, + "y": 2000, + "wires": [ + [ + "err10cbea6a_f" + ] + ] + }, + { + "id": "err10cbea6a_f", + "type": "function", + "z": "10cbea6aaac127cd", + "name": "Format error", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Balcony\", data: { priority: 1 } });\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 360, + "y": 2000, + "wires": [ + [ + "err10cbea6a_s" + ] + ] + }, + { + "id": "err10cbea6a_s", + "type": "api-call-service", + "z": "10cbea6aaac127cd", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "notify", + "service": "gotify_nodered", + "x": 600, + "y": 2000, + "wires": [ + [] + ] + }, + { + "id": "13c933aa7d791e63", + "type": "subflow:52430f5e9f9ee267", + "z": "c7f876875da48b87", + "name": "", + "x": 670, + "y": 160, + "wires": [ + [ + "cc46642a3ea04954" + ], + [ + "cc46642a3ea04954" + ], + [ + "cc46642a3ea04954" + ], + [ + "1ae97faec6bec4ae" + ], + [ + "1ae97faec6bec4ae" + ], + [ + "bath_br_state_01" + ] + ] + }, + { + "id": "812f8294add5575c", "type": "server-state-changed", - "z": "a9edb9da.ccb6d", - "name": "Last motion room updated", + "z": "c7f876875da48b87", + "name": "Bathroom lights on", "server": "657c7463.48e1e4", "version": 6, - "outputs": 1, + "outputs": 2, "exposeAsEntityConfig": "", "entities": { "entity": [ - "input_select.last_motion" + "light.bathroom_switch_left" ], "substring": [], "regex": [] }, "outputInitially": true, "stateType": "str", - "ifState": "", + "ifState": "on", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 150, + "y": 240, + "wires": [ + [ + "eab005bf8b682c46" + ], + [] + ] + }, + { + "id": "23f3fd10ac242022", + "type": "server-state-changed", + "z": "c7f876875da48b87", + "name": "Bathroom Humidity Changed", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "sensor.bathroom_temperature_humidity" + ], + "substring": [], + "regex": [] + }, + "outputInitially": true, + "stateType": "", + "ifState": "0", + "ifStateType": "num", + "ifStateOperator": "gte", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 180, + "y": 1140, + "wires": [ + [ + "f1a2b3c4d5e60001" + ], + [] + ] + }, + { + "id": "b2a9a137a909e257", + "type": "api-call-service", + "z": "c7f876875da48b87", + "name": "Turn on fan", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "switch.turn_on", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "switch.bathroom_switch_right" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [ + { + "property": "fan_state", + "propertyType": "msg", + "value": "on", + "valueType": "str" + } + ], + "queue": "all", + "blockInputOverrides": false, + "domain": "switch", + "service": "turn_on", + "output_location": "", + "output_location_type": "none", + "x": 830, + "y": 1140, + "wires": [ + [ + "bthrm_audio_acs_01" + ] + ] + }, + { + "id": "7e4f4bb9c0c9ef2b", + "type": "trigger", + "z": "c7f876875da48b87", + "name": "Wait for 5:00", + "op1": "", + "op2": "5 minutes past", + "op1type": "nul", + "op2type": "str", + "duration": "300", + "extend": false, + "overrideDelay": false, + "units": "s", + "reset": "off", + "bytopic": "all", + "topic": "topic", + "outputs": 1, + "x": 490, + "y": 1040, + "wires": [ + [ + "82599133dd2b9883" + ] + ] + }, + { + "id": "82599133dd2b9883", + "type": "api-current-state", + "z": "c7f876875da48b87", + "name": "Get Bathroom Humidity", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 2, + "halt_if": "0", + "halt_if_type": "num", + "halt_if_compare": "gte", + "entity_id": "sensor.bathroom_temperature_humidity", + "state_type": "", + "blockInputOverrides": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entity" + } + ], + "for": "0", + "forType": "num", + "forUnits": "minutes", + "override_topic": false, + "state_location": "payload", + "override_payload": "msg", + "entity_location": "data", + "override_data": "msg", + "x": 750, + "y": 1040, + "wires": [ + [ + "d6e7f8a9b0c10002" + ], + [] + ] + }, + { + "id": "27d9e5846a679b8b", + "type": "api-call-service", + "z": "c7f876875da48b87", + "name": "Turn off fan", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "switch.turn_off", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "switch.bathroom_switch_right" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "switch", + "service": "turn_off", + "output_location": "", + "output_location_type": "none", + "x": 1310, + "y": 1040, + "wires": [ + [] + ] + }, + { + "id": "4548a32796918fd8", + "type": "comment", + "z": "c7f876875da48b87", + "name": "Bathroom ventilator automation shower", + "info": "", + "x": 210, + "y": 1000, + "wires": [] + }, + { + "id": "3d44cb85e182a197", + "type": "server-state-changed", + "z": "c7f876875da48b87", + "name": "Bathroom fan turned on", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "switch.bathroom_switch_right" + ], + "substring": [], + "regex": [] + }, + "outputInitially": true, + "stateType": "str", + "ifState": "on", "ifStateType": "str", "ifStateOperator": "is", "outputOnlyOnStateChange": true, @@ -8238,52 +10427,784 @@ "valueType": "triggerId" } ], - "x": 210, - "y": 1000, + "x": 160, + "y": 1040, "wires": [ [ - "e3ecc53a.1c89e8" + "7e4f4bb9c0c9ef2b" + ], + [] + ] + }, + { + "id": "ebb5b8c2c3eb6ff5", + "type": "server-state-changed", + "z": "c7f876875da48b87", + "name": "Bathroom motion sensor on", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.bathroom_motion_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "on", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 180, + "y": 320, + "wires": [ + [ + "eab005bf8b682c46", + "580c3afd65deefed", + "cbba47369f1e6479" + ], + [ + "52af4ffdf85f60e4" ] ] }, { - "id": "e3ecc53a.1c89e8", - "type": "template", - "z": "a9edb9da.ccb6d", - "name": "Last motion variable set to...", - "field": "payload", - "fieldType": "msg", - "format": "handlebars", - "syntax": "mustache", - "template": "Last motion variable set to: {{payload}}.", - "output": "str", - "x": 520, - "y": 1000, + "id": "cc46642a3ea04954", + "type": "change", + "z": "c7f876875da48b87", + "name": "Scene Bathroom Bright", + "rules": [ + { + "t": "set", + "p": "entity_id", + "pt": "msg", + "to": "scene.bathroom_bright", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1290, + "y": 120, "wires": [ [ - "c59f167c.f20e" + "ed2d549e91e1399d" ] ] }, { - "id": "84dd47fc.401908", + "id": "ed2d549e91e1399d", + "type": "api-call-service", + "z": "c7f876875da48b87", + "name": "Turn on Scene", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "scene.turn_on", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "{{ entity_id }}" + ], + "labelId": [], + "data": "{\"transition\":0}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "all", + "blockInputOverrides": false, + "domain": "scene", + "service": "turn_on", + "output_location": "", + "output_location_type": "none", + "x": 1600, + "y": 140, + "wires": [ + [] + ] + }, + { + "id": "1ae97faec6bec4ae", + "type": "change", + "z": "c7f876875da48b87", + "name": "Scene Bathroom Evening", + "rules": [ + { + "t": "set", + "p": "entity_id", + "pt": "msg", + "to": "scene.bathroom_evening", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1290, + "y": 160, + "wires": [ + [ + "ed2d549e91e1399d" + ] + ] + }, + { + "id": "ddf62bacca5574f6", + "type": "change", + "z": "c7f876875da48b87", + "name": "Scene Bathroom Night", + "rules": [ + { + "t": "set", + "p": "entity_id", + "pt": "msg", + "to": "scene.bathroom_night", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1280, + "y": 200, + "wires": [ + [ + "ed2d549e91e1399d" + ] + ] + }, + { + "id": "bdccd31c131b65fb", + "type": "comment", + "z": "c7f876875da48b87", + "name": "Bathroom automated lights", + "info": "", + "x": 170, + "y": 200, + "wires": [] + }, + { + "id": "38ff5b8ecfcbfdd0", + "type": "server-state-changed", + "z": "c7f876875da48b87", + "name": "Bathmode turned on", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_boolean.bath_mode" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "on", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 150, + "y": 100, + "wires": [ + [ + "20da8eedd69886b0", + "f4a8732084a282d7" + ], + [ + "13c933aa7d791e63" + ] + ] + }, + { + "id": "20da8eedd69886b0", + "type": "change", + "z": "c7f876875da48b87", + "name": "Scene Bathroom Bath", + "rules": [ + { + "t": "set", + "p": "entity_id", + "pt": "msg", + "to": "scene.bathroom_bath", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1280, + "y": 80, + "wires": [ + [ + "ed2d549e91e1399d" + ] + ] + }, + { + "id": "b8f30c8224cf9d74", + "type": "comment", + "z": "c7f876875da48b87", + "name": "Bathmode ", + "info": "", + "x": 120, + "y": 60, + "wires": [] + }, + { + "id": "eab005bf8b682c46", "type": "api-current-state", - "z": "a9edb9da.ccb6d", - "name": "Still in Hallway?", + "z": "c7f876875da48b87", + "name": "Noone bathing?", "server": "657c7463.48e1e4", "version": 3, "outputs": 2, - "halt_if": "hallway", + "halt_if": "off", "halt_if_type": "str", "halt_if_compare": "is", - "entity_id": "input_select.last_motion", + "entity_id": "input_boolean.bath_mode", + "state_type": "str", + "blockInputOverrides": true, + "outputProperties": [], + "for": "0", + "forType": "num", + "forUnits": "minutes", + "override_topic": false, + "state_location": "payload", + "override_payload": "msg", + "entity_location": "data", + "override_data": "msg", + "x": 440, + "y": 220, + "wires": [ + [ + "13c933aa7d791e63" + ], + [] + ] + }, + { + "id": "cbba47369f1e6479", + "type": "trigger", + "z": "c7f876875da48b87", + "name": "Wait 1:30 min", + "op1": "", + "op2": "90", + "op1type": "nul", + "op2type": "num", + "duration": "90", + "extend": false, + "overrideDelay": false, + "units": "s", + "reset": "on", + "bytopic": "all", + "topic": "topic", + "outputs": 1, + "x": 640, + "y": 660, + "wires": [ + [ + "e12d8801b6c6f320" + ] + ] + }, + { + "id": "580c3afd65deefed", + "type": "trigger", + "z": "c7f876875da48b87", + "name": "Wait for 2:00 min", + "op1": "", + "op2": "120", + "op1type": "nul", + "op2type": "num", + "duration": "120", + "extend": false, + "overrideDelay": false, + "units": "s", + "reset": "on", + "bytopic": "all", + "topic": "topic", + "outputs": 1, + "x": 650, + "y": 620, + "wires": [ + [ + "e12d8801b6c6f320" + ] + ] + }, + { + "id": "26f9395831aa077c", + "type": "change", + "z": "c7f876875da48b87", + "name": "Flash at brightness 100%", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_pct\":100,\"flash\":\"short\"}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1250, + "y": 800, + "wires": [ + [ + "b1e7dd85582b7d3e" + ] + ] + }, + { + "id": "b1e7dd85582b7d3e", + "type": "api-call-service", + "z": "c7f876875da48b87", + "name": "Execute effect on lights bathroom", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "light.turn_on", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "light.bathroom_lights" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "light", + "service": "turn_on", + "output_location": "", + "output_location_type": "none", + "x": 1580, + "y": 800, + "wires": [ + [] + ] + }, + { + "id": "07d4571f236fd04b", + "type": "api-current-state", + "z": "c7f876875da48b87", + "name": "Noone bathing?", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 2, + "halt_if": "off", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_boolean.bath_mode", + "state_type": "str", + "blockInputOverrides": true, + "outputProperties": [], + "for": "0", + "forType": "num", + "forUnits": "minutes", + "override_topic": false, + "state_location": "payload", + "override_payload": "msg", + "entity_location": "data", + "override_data": "msg", + "x": 1100, + "y": 640, + "wires": [ + [ + "bthrm_presence_acs_01" + ], + [] + ] + }, + { + "id": "a8ad8572dc926e44", + "type": "api-call-service", + "z": "c7f876875da48b87", + "name": "Turn off lights bathroom", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "light.turn_off", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "light.bathroom_lights" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "light", + "service": "turn_off", + "output_location": "", + "output_location_type": "none", + "x": 1550, + "y": 740, + "wires": [ + [] + ] + }, + { + "id": "52af4ffdf85f60e4", + "type": "change", + "z": "c7f876875da48b87", + "name": "Store motion off time", + "rules": [ + { + "t": "set", + "p": "motion_off_at", + "pt": "msg", + "to": "data.last_changed", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 320, + "y": 600, + "wires": [ + [ + "580c3afd65deefed", + "cbba47369f1e6479" + ] + ] + }, + { + "id": "e12d8801b6c6f320", + "type": "change", + "z": "c7f876875da48b87", + "name": "Store which delay", + "rules": [ + { + "t": "set", + "p": "delay", + "pt": "msg", + "to": "payload", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 890, + "y": 640, + "wires": [ + [ + "07d4571f236fd04b" + ] + ] + }, + { + "id": "bbd7dc3adff7b866", + "type": "switch", + "z": "c7f876875da48b87", + "name": "2:00 or 1:30 min delay", + "property": "delay", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "120", + "vt": "num" + }, + { + "t": "eq", + "v": "90", + "vt": "num" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 900, + "y": 740, + "wires": [ + [ + "a8ad8572dc926e44" + ], + [ + "26f9395831aa077c" + ] + ] + }, + { + "id": "f4a8732084a282d7", + "type": "trigger", + "z": "c7f876875da48b87", + "name": "Wait for 5 hours", + "op1": "", + "op2": "", + "op1type": "nul", + "op2type": "num", + "duration": "5", + "extend": false, + "overrideDelay": false, + "units": "hr", + "reset": "off", + "bytopic": "all", + "topic": "topic", + "outputs": 1, + "x": 640, + "y": 520, + "wires": [ + [ + "4b98e17771cc3851" + ] + ] + }, + { + "id": "4b98e17771cc3851", + "type": "api-call-service", + "z": "c7f876875da48b87", + "name": "Turn off bath mode", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "input_boolean.turn_off", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "input_boolean.bath_mode" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "input_boolean", + "service": "turn_off", + "output_location": "", + "output_location_type": "none", + "x": 890, + "y": 520, + "wires": [ + [] + ] + }, + { + "id": "bb74897476a1a5e6", + "type": "comment", + "z": "c7f876875da48b87", + "name": "Automatic turn off bath mode after X hours", + "info": "", + "x": 720, + "y": 480, + "wires": [] + }, + { + "id": "f1a2b3c4d5e60001", + "type": "function", + "z": "c7f876875da48b87", + "name": "Rise >= 3% in 2 min?", + "func": "const readings = context.get('readings') || [];\nconst lastTriggered = context.get('lastTriggered') || 0;\nconst now = Date.now();\nconst current = parseFloat(msg.payload);\n\nif (isNaN(current)) {\n node.error('Humidity sensor non-numeric value: ' + msg.payload, msg);\n return null;\n}\n\n// 15-minute cooldown after triggering\nif (now - lastTriggered < 15 * 60 * 1000) return null;\n\nreadings.push({ time: now, value: current });\nconst windowMs = 2 * 60 * 1000;\nconst filtered = readings.filter(r => r.time >= now - windowMs);\ncontext.set('readings', filtered);\n\nif (filtered.length < 2) return null;\n\nconst minInWindow = Math.min(...filtered.map(r => r.value));\nconst rise = current - minInWindow;\n\nif (rise >= 3) {\n context.set('lastTriggered', now);\n context.set('readings', []);\n flow.set('humidityBaseline', minInWindow);\n return msg;\n}\nreturn null;", + "outputs": 1, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 520, + "y": 1140, + "wires": [ + [ + "b2a9a137a909e257" + ] + ] + }, + { + "id": "d6e7f8a9b0c10002", + "type": "function", + "z": "c7f876875da48b87", + "name": "Below baseline + 5%?", + "func": "const current = parseFloat(msg.payload);\nconst baseline = flow.get(\"humidityBaseline\") || 60;\nconst threshold = baseline + 5;\n\nif (current <= threshold) {\n return [msg, null];\n}\nreturn [null, msg];", + "outputs": 2, + "timeout": 0, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 1020, + "y": 1040, + "wires": [ + [ + "27d9e5846a679b8b" + ], + [ + "7e4f4bb9c0c9ef2b" + ] + ] + }, + { + "id": "bthrm_timebased_01", + "type": "server-state-changed", + "z": "c7f876875da48b87", + "name": "Bathroom time-based turn on", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.bathroom_time_based_turn_on" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "", + "forType": "num", + "forUnits": "milliseconds", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 180, + "y": 140, + "wires": [ + [ + "13c933aa7d791e63" + ] + ] + }, + { + "id": "bath_br_state_01", + "type": "api-current-state", + "z": "c7f876875da48b87", + "name": "Bedroom ceiling brightness", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "light.bedroom_main", "state_type": "str", "blockInputOverrides": false, "outputProperties": [ { "property": "payload", "propertyType": "msg", - "value": "", + "value": "string", "valueType": "entityState" }, { @@ -8296,83 +11217,473 @@ "for": 0, "forType": "num", "forUnits": "minutes", - "x": 660, - "y": 640, + "x": 940, + "y": 220, "wires": [ [ - "8d847d6b.3e76c8" + "bath_br_switch_01" + ] + ] + }, + { + "id": "bath_br_switch_01", + "type": "switch", + "z": "c7f876875da48b87", + "name": "Bedroom brightness > 50%?", + "property": "data.attributes.brightness", + "propertyType": "msg", + "rules": [ + { + "t": "gt", + "v": "128", + "vt": "num" + }, + { + "t": "else" + } + ], + "checkall": "false", + "repair": false, + "outputs": 2, + "x": 940, + "y": 280, + "wires": [ + [ + "1ae97faec6bec4ae" ], [ - "8a2e7e1b.11471" + "ddf62bacca5574f6" ] ] }, { - "id": "p2catch_mot", + "id": "errc7f87687_c", "type": "catch", - "z": "a9edb9da.ccb6d", - "name": "Catch all errors", + "z": "c7f876875da48b87", + "name": "Tab errors", "scope": null, "uncaught": false, - "x": 160, - "y": 1300, + "x": 120, + "y": 940, "wires": [ [ - "p2fmt_mot" + "errc7f87687_f" ] ] }, { - "id": "p2fmt_mot", + "id": "errc7f87687_f", "type": "function", - "z": "a9edb9da.ccb6d", + "z": "c7f876875da48b87", "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Motion detection',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || \"Unknown error\");\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Bathroom\", data: { priority: 1 } });\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 400, - "y": 1300, + "x": 360, + "y": 940, "wires": [ [ - "p2ntfy_mot" + "errc7f87687_s" ] ] }, { - "id": "p2ntfy_mot", + "id": "errc7f87687_s", "type": "api-call-service", - "z": "a9edb9da.ccb6d", - "name": "Notify error", + "z": "c7f876875da48b87", + "name": "gotify_nodered", "server": "657c7463.48e1e4", "version": 7, "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], "areaId": [], "deviceId": [], "entityId": [], - "labelId": [], "data": "{{{payload}}}", "dataType": "json", "mergeContext": "", "mustacheAltTags": false, "outputProperties": [], "queue": "none", - "blockInputOverrides": false, "domain": "notify", - "service": "gotify_ha", + "service": "gotify_nodered", + "x": 600, + "y": 940, + "wires": [ + [] + ] + }, + { + "id": "bthrm_audio_cmt_01", + "type": "comment", + "z": "c7f876875da48b87", + "name": "Shower → Audio Volume Sync", + "info": "", + "x": 190, + "y": 1220, + "wires": [] + }, + { + "id": "bthrm_audio_ssc_01", + "type": "server-state-changed", + "z": "c7f876875da48b87", + "name": "Bathroom fan turned off", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "switch.bathroom_switch_right" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "off", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "fan_state", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + } + ], + "x": 160, + "y": 1260, + "wires": [ + [ + "bthrm_audio_acs_01" + ], + [] + ] + }, + { + "id": "bthrm_audio_acs_01", + "type": "api-current-state", + "z": "c7f876875da48b87", + "name": "Get bathroom speaker state", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 2, + "halt_if": "playing", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "media_player.bathroom", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entity" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "override_topic": false, + "state_location": "payload", + "override_payload": "msg", + "entity_location": "data", + "override_data": "msg", + "x": 620, + "y": 1260, + "wires": [ + [ + "bthrm_audio_swt_vol_01" + ], + [] + ] + }, + { + "id": "bthrm_audio_swt_vol_01", + "type": "switch", + "z": "c7f876875da48b87", + "name": "Volume > 0?", + "property": "data.attributes.volume_level", + "propertyType": "msg", + "rules": [ + { + "t": "gt", + "v": "0", + "vt": "num" + }, + { + "t": "else" + } + ], + "checkall": "false", + "repair": false, + "outputs": 2, + "x": 930, + "y": 1300, + "wires": [ + [ + "bthrm_audio_swt_fan_01" + ], + [] + ] + }, + { + "id": "bthrm_audio_swt_fan_01", + "type": "switch", + "z": "c7f876875da48b87", + "name": "Fan on or off?", + "property": "fan_state", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "on", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "false", + "repair": false, + "outputs": 2, + "x": 1140, + "y": 1300, + "wires": [ + [ + "bthrm_audio_chg_up_01" + ], + [ + "bthrm_audio_chg_dn_01" + ] + ] + }, + { + "id": "bthrm_audio_chg_up_01", + "type": "change", + "z": "c7f876875da48b87", + "name": "Volume +0.05", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "$min(0.28, $round((data.attributes.volume_level + 0.05) * 100) / 100)", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1380, + "y": 1260, + "wires": [ + [ + "bthrm_audio_svc_01" + ] + ] + }, + { + "id": "bthrm_audio_chg_dn_01", + "type": "change", + "z": "c7f876875da48b87", + "name": "Volume -0.05", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "$max(0, $round((data.attributes.volume_level - 0.05) * 100) / 100)", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1370, + "y": 1340, + "wires": [ + [ + "bthrm_audio_svc_01" + ] + ] + }, + { + "id": "bthrm_audio_svc_01", + "type": "api-call-service", + "z": "c7f876875da48b87", + "name": "Set bathroom speaker volume", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.volume_set", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "media_player.bathroom" + ], + "labelId": [], + "data": "{\"volume_level\": {{{payload}}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "volume_set", "output_location": "", "output_location_type": "none", - "x": 660, + "x": 1670, "y": 1300, "wires": [ [] ] }, + { + "id": "bthrm_audio_ssc_02", + "type": "server-state-changed", + "z": "c7f876875da48b87", + "name": "Bathroom music playing", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "media_player.bathroom" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "playing", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 160, + "y": 1340, + "wires": [ + [ + "bthrm_audio_acs_fan_01" + ], + [] + ] + }, + { + "id": "bthrm_audio_acs_fan_01", + "type": "api-current-state", + "z": "c7f876875da48b87", + "name": "Get fan state", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "switch.bathroom_switch_right", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "fan_state", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 570, + "y": 1340, + "wires": [ + [ + "bthrm_audio_swt_vol_01" + ] + ] + }, + { + "id": "bthrm_presence_acs_01", + "type": "api-current-state", + "z": "c7f876875da48b87", + "name": "Still in bathroom?", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 2, + "halt_if": "Bathroom", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_select.room_presence", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 1370, + "y": 640, + "wires": [ + [], + [ + "bbd7dc3adff7b866" + ] + ] + }, { "id": "d46b0ef0ec904159", "type": "server-state-changed", @@ -10244,45 +13555,197 @@ "wires": [] }, { - "id": "p2catch_bed", + "id": "err97e0f133_c", "type": "catch", "z": "97e0f1338e182d76", - "name": "Catch all errors", + "name": "Tab errors", "scope": null, "uncaught": false, - "x": 160, - "y": 2280, + "x": 120, + "y": 2200, "wires": [ [ - "p2fmt_bed" + "err97e0f133_f" ] ] }, { - "id": "p2fmt_bed", + "id": "err97e0f133_f", "type": "function", "z": "97e0f1338e182d76", "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Bedroom',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Bedroom\", data: { priority: 1 } });\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 400, - "y": 2280, + "x": 360, + "y": 2200, "wires": [ [ - "p2ntfy_bed" + "err97e0f133_s" ] ] }, { - "id": "p2ntfy_bed", + "id": "err97e0f133_s", "type": "api-call-service", "z": "97e0f1338e182d76", - "name": "Notify error", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "notify", + "service": "gotify_nodered", + "x": 600, + "y": 2200, + "wires": [ + [] + ] + }, + { + "id": "72ec1bae1134aa", + "type": "comment", + "z": "550f84daf129f66b", + "name": "Mosquito repellent", + "info": "", + "x": 170, + "y": 60, + "wires": [] + }, + { + "id": "bcabc32f102b8e", + "type": "server-state-changed", + "z": "550f84daf129f66b", + "name": "Mosquito repellent start", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_datetime.mosquito_repellent_start" + ], + "substring": [], + "regex": [] + }, + "outputInitially": true, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 180, + "y": 180, + "wires": [ + [ + "d46c98a17c8a15" + ] + ] + }, + { + "id": "727a10305e0a16", + "type": "api-current-state", + "z": "550f84daf129f66b", + "name": "Enable Mosquito repellent?", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 2, + "halt_if": "on", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_boolean.mosquito_device", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entity" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 680, + "y": 180, + "wires": [ + [ + "9300f29ece6381" + ], + [] + ] + }, + { + "id": "9300f29ece6381", + "type": "template", + "z": "550f84daf129f66b", + "name": "Mosquito repellent notification", + "field": "payload", + "fieldType": "msg", + "format": "handlebars", + "syntax": "mustache", + "template": "Mosquito repellent will turn on at {{flow.mosquito_start_time}}.", + "output": "str", + "x": 990, + "y": 180, + "wires": [ + [ + "936fccc20bee4c" + ] + ] + }, + { + "id": "936fccc20bee4c", + "type": "api-call-service", + "z": "550f84daf129f66b", + "name": "Notify via HA", "server": "657c7463.48e1e4", "version": 7, "debugenabled": false, @@ -10292,6 +13755,1923 @@ "deviceId": [], "entityId": [], "labelId": [], + "data": "{\"title\":\"Info\",\"message\":\"{{{payload}}}\"}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "notify", + "service": "gotify_ha", + "output_location": "", + "output_location_type": "none", + "x": 1410, + "y": 140, + "wires": [ + [] + ] + }, + { + "id": "d46c98a17c8a15", + "type": "change", + "z": "550f84daf129f66b", + "name": "Store start time (HH:MM)", + "rules": [ + { + "t": "set", + "p": "mosquito_start_time", + "pt": "flow", + "to": "$substring(payload,0,5)", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 200, + "y": 240, + "wires": [ + [ + "727a10305e0a16", + "e4f8a0fb9f6178" + ] + ] + }, + { + "id": "1bca75a94f78af", + "type": "server-state-changed", + "z": "550f84daf129f66b", + "name": "Mosquito repellent start", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_boolean.mosquito_device" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 180, + "y": 100, + "wires": [ + [ + "4266c71ab7c3a0" + ] + ] + }, + { + "id": "4266c71ab7c3a0", + "type": "template", + "z": "550f84daf129f66b", + "name": "Mosquito repellent notification", + "field": "payload", + "fieldType": "msg", + "format": "handlebars", + "syntax": "mustache", + "template": "Mosquito repellent turned {{payload}}.", + "output": "str", + "x": 690, + "y": 100, + "wires": [ + [ + "936fccc20bee4c" + ] + ] + }, + { + "id": "e4f8a0fb9f6178", + "type": "function", + "z": "550f84daf129f66b", + "name": "actual start time", + "func": "var newMsg = {};\nnewMsg.payload = {}\nnewMsg.payload.ontime = flow.get('mosquito_start_time').substr(0, 5);\n\nreturn newMsg;", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 640, + "y": 240, + "wires": [ + [ + "81df5e19836373", + "63f356fcccdebe" + ] + ] + }, + { + "id": "81df5e19836373", + "type": "schedex", + "z": "550f84daf129f66b", + "name": "Mosquito repellent start timer", + "passthroughunhandled": false, + "suspended": false, + "lat": "", + "lon": "", + "ontime": "", + "ontopic": "", + "onpayload": "", + "onoffset": 0, + "onrandomoffset": 0, + "offtime": "", + "offtopic": "", + "offpayload": "", + "offoffset": 0, + "offrandomoffset": 0, + "mon": true, + "tue": true, + "wed": true, + "thu": true, + "fri": true, + "sat": true, + "sun": true, + "x": 680, + "y": 300, + "wires": [ + [ + "5aa163dddb83a6", + "63f356fcccdebe" + ] + ] + }, + { + "id": "54300959dd3ad8", + "type": "api-call-service", + "z": "550f84daf129f66b", + "name": "Turn on mosquito repellent", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "switch.turn_on", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "switch.bedroom_mosquito_switch" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "switch", + "service": "turn_on", + "output_location": "", + "output_location_type": "none", + "x": 1460, + "y": 260, + "wires": [ + [] + ] + }, + { + "id": "5aa163dddb83a6", + "type": "api-current-state", + "z": "550f84daf129f66b", + "name": "Enable Mosquito repellent?", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 2, + "halt_if": "on", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_boolean.mosquito_device", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entity" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 980, + "y": 240, + "wires": [ + [ + "54300959dd3ad8", + "63f356fcccdebe" + ], + [] + ] + }, + { + "id": "c68c535a4a9118", + "type": "server-state-changed", + "z": "550f84daf129f66b", + "name": "Mosquito repellent stop", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_datetime.mosquito_repellent_stop" + ], + "substring": [], + "regex": [] + }, + "outputInitially": true, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": "0", + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 180, + "y": 320, + "wires": [ + [ + "bcbf46feac9f81" + ] + ] + }, + { + "id": "bcbf46feac9f81", + "type": "change", + "z": "550f84daf129f66b", + "name": "Store stop time (HH:MM)", + "rules": [ + { + "t": "set", + "p": "mosquito_stop_time", + "pt": "flow", + "to": "$substring(payload,0,5)", + "tot": "jsonata" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 200, + "y": 380, + "wires": [ + [ + "c931341fc25f2c", + "cff3a9e80fb25d" + ] + ] + }, + { + "id": "c931341fc25f2c", + "type": "api-current-state", + "z": "550f84daf129f66b", + "name": "Enable Mosquito repellent?", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 2, + "halt_if": "on", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_boolean.mosquito_device", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entity" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 680, + "y": 380, + "wires": [ + [ + "d51e6e8bb45611" + ], + [] + ] + }, + { + "id": "d51e6e8bb45611", + "type": "template", + "z": "550f84daf129f66b", + "name": "Mosquito repellent notification", + "field": "payload", + "fieldType": "msg", + "format": "handlebars", + "syntax": "mustache", + "template": "Mosquito repellent will turn off at {{flow.mosquito_stop_time}}.", + "output": "str", + "x": 990, + "y": 380, + "wires": [ + [ + "936fccc20bee4c" + ] + ] + }, + { + "id": "cff3a9e80fb25d", + "type": "function", + "z": "550f84daf129f66b", + "name": "actual stop time", + "func": "var newMsg = {};\nnewMsg.payload = {}\nnewMsg.payload.ontime = flow.get('mosquito_stop_time').substr(0, 5);\n\nreturn newMsg;", + "outputs": 1, + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 640, + "y": 440, + "wires": [ + [ + "979317245239d4", + "63f356fcccdebe" + ] + ] + }, + { + "id": "979317245239d4", + "type": "schedex", + "z": "550f84daf129f66b", + "name": "Mosquito repellent stop timer", + "passthroughunhandled": false, + "suspended": false, + "lat": "", + "lon": "", + "ontime": "", + "ontopic": "", + "onpayload": "", + "onoffset": 0, + "onrandomoffset": 0, + "offtime": "", + "offtopic": "", + "offpayload": "", + "offoffset": 0, + "offrandomoffset": 0, + "mon": true, + "tue": true, + "wed": true, + "thu": true, + "fri": true, + "sat": true, + "sun": true, + "x": 680, + "y": 500, + "wires": [ + [ + "c1bb76fea749ec", + "63f356fcccdebe" + ] + ] + }, + { + "id": "c1bb76fea749ec", + "type": "api-call-service", + "z": "550f84daf129f66b", + "name": "Turn off mosquito repellent", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "switch.turn_off", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "switch.bedroom_mosquito_switch" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "switch", + "service": "turn_off", + "output_location": "", + "output_location_type": "none", + "x": 1460, + "y": 400, + "wires": [ + [] + ] + }, + { + "id": "63f356fcccdebe", + "type": "debug", + "z": "550f84daf129f66b", + "name": "debug mosquito", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 1320, + "y": 500, + "wires": [] + }, + { + "id": "f3539c39863479", + "type": "catch", + "z": "550f84daf129f66b", + "name": "Tab errors", + "scope": null, + "uncaught": false, + "x": 120, + "y": 700, + "wires": [ + [ + "c9e87254c5eb5e" + ] + ] + }, + { + "id": "c9e87254c5eb5e", + "type": "function", + "z": "550f84daf129f66b", + "name": "Format error", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || \"Unknown error\");\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Wake up & mosquito\", data: { priority: 1 } });\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 360, + "y": 700, + "wires": [ + [ + "9039bd588229a2" + ] + ] + }, + { + "id": "9039bd588229a2", + "type": "api-call-service", + "z": "550f84daf129f66b", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "notify", + "service": "gotify_nodered", + "x": 600, + "y": 700, + "wires": [ + [] + ] + }, + { + "id": "1be4d360986fd1f1", + "type": "server-state-changed", + "z": "c19dee9f.e72838", + "name": "Hallway smart switch", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "sensor.hallway_switch_action" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 160, + "y": 120, + "wires": [ + [ + "9bea73aa40198378", + "hllw_sw_onhold_01", + "hllw_sw_brup_01", + "hllw_sw_brdn_01", + "hllw_sw_dbg_01" + ] + ] + }, + { + "id": "9bea73aa40198378", + "type": "switch", + "z": "c19dee9f.e72838", + "name": "On/Off check", + "property": "payload", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "on_press_release", + "vt": "str" + }, + { + "t": "eq", + "v": "off_press_release", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 470, + "y": 220, + "wires": [ + [ + "3369429b11ec6c87" + ], + [ + "492a8c0fafdb95c0" + ] + ] + }, + { + "id": "93521b5966f6fca9", + "type": "comment", + "z": "c19dee9f.e72838", + "name": "Hallway Lights on/off switch", + "info": "", + "x": 180, + "y": 80, + "wires": [] + }, + { + "id": "28b5f90c956f8589", + "type": "api-call-service", + "z": "c19dee9f.e72838", + "name": "Turn on/off lights hallway", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "light.turn_on", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "light.hallway" + ], + "labelId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "light", + "service": "turn_on", + "x": 1790, + "y": 260, + "wires": [ + [] + ] + }, + { + "id": "3369429b11ec6c87", + "type": "subflow:52430f5e9f9ee267", + "z": "c19dee9f.e72838", + "name": "", + "x": 890, + "y": 280, + "wires": [ + [ + "9e21108d47dd29fe" + ], + [ + "9e21108d47dd29fe" + ], + [ + "da8f36cbc0df2e8c" + ], + [ + "da8f36cbc0df2e8c" + ], + [ + "hllw_br_state_01" + ], + [ + "hllw_br_state_01" + ] + ] + }, + { + "id": "c2c1acbc73dc80f4", + "type": "comment", + "z": "c19dee9f.e72838", + "name": "Hallway Motion sensor", + "info": "", + "x": 160, + "y": 480, + "wires": [] + }, + { + "id": "c4a4ba3c5f68d440", + "type": "server-state-changed", + "z": "c19dee9f.e72838", + "name": "Hallway motion sensor", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "binary_sensor.hallway_motion_sensor_1_occupancy", + "binary_sensor.hallway_motion_sensor_2_occupancy", + "binary_sensor.hallway_motion_sensor_3_occupancy" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "on", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 160, + "y": 520, + "wires": [ + [ + "3369429b11ec6c87", + "4b6861fef07dcf9c", + "cb510a92532ea7f5" + ], + [] + ] + }, + { + "id": "hllw_timebased_01", + "type": "server-state-changed", + "z": "c19dee9f.e72838", + "name": "Hallway Time Based Turn On", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "input_button.hallway_time_based_turn_on" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 180, + "y": 580, + "wires": [ + [ + "3369429b11ec6c87", + "4b6861fef07dcf9c", + "cb510a92532ea7f5" + ] + ] + }, + { + "id": "492a8c0fafdb95c0", + "type": "change", + "z": "c19dee9f.e72838", + "name": "Brightness to 0 (turn off)", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness\":0}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1350, + "y": 560, + "wires": [ + [ + "28b5f90c956f8589" + ] + ] + }, + { + "id": "dcd933bc4929181e", + "type": "change", + "z": "c19dee9f.e72838", + "name": "Brightness to 20%", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_pct\":20}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1310, + "y": 280, + "wires": [ + [ + "28b5f90c956f8589" + ] + ] + }, + { + "id": "9e21108d47dd29fe", + "type": "change", + "z": "c19dee9f.e72838", + "name": "Brightness to 100%", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_pct\":100}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1310, + "y": 200, + "wires": [ + [ + "28b5f90c956f8589" + ] + ] + }, + { + "id": "da8f36cbc0df2e8c", + "type": "change", + "z": "c19dee9f.e72838", + "name": "Brightness to 65%", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_pct\":65}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1310, + "y": 240, + "wires": [ + [ + "28b5f90c956f8589" + ] + ] + }, + { + "id": "1e4d5008dcd7fb69", + "type": "change", + "z": "c19dee9f.e72838", + "name": "Flash at brightness 100%", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_pct\":100,\"flash\":\"short\"}", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1350, + "y": 600, + "wires": [ + [ + "28b5f90c956f8589" + ] + ] + }, + { + "id": "4b6861fef07dcf9c", + "type": "trigger", + "z": "c19dee9f.e72838", + "name": "Trigger 4:30min for flash", + "op1": "", + "op2": "offf", + "op1type": "nul", + "op2type": "str", + "duration": "270", + "extend": true, + "overrideDelay": false, + "units": "s", + "reset": "", + "bytopic": "all", + "topic": "topic", + "outputs": 1, + "x": 710, + "y": 560, + "wires": [ + [ + "1e4d5008dcd7fb69" + ] + ] + }, + { + "id": "cb510a92532ea7f5", + "type": "trigger", + "z": "c19dee9f.e72838", + "name": "Trigger 5:00 min for off", + "op1": "", + "op2": "offf", + "op1type": "nul", + "op2type": "str", + "duration": "300", + "extend": true, + "overrideDelay": false, + "units": "s", + "reset": "", + "bytopic": "all", + "topic": "topic", + "outputs": 1, + "x": 700, + "y": 520, + "wires": [ + [ + "492a8c0fafdb95c0" + ] + ] + }, + { + "id": "hllw_sw_onhold_01", + "type": "switch", + "z": "c19dee9f.e72838", + "name": "On hold", + "property": "payload", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "on_hold", + "vt": "str" + }, + { + "t": "eq", + "v": "off_hold", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 460, + "y": 140, + "wires": [ + [ + "9e21108d47dd29fe" + ], + [ + "dcd933bc4929181e" + ] + ] + }, + { + "id": "hllw_sw_brup_01", + "type": "switch", + "z": "c19dee9f.e72838", + "name": "Brightness check - Up press/hold", + "property": "payload", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "up_press", + "vt": "str" + }, + { + "t": "eq", + "v": "up_hold", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 540, + "y": 60, + "wires": [ + [ + "hllw_sw_inc_01" + ], + [ + "hllw_sw_inc_01" + ] + ] + }, + { + "id": "hllw_sw_brdn_01", + "type": "switch", + "z": "c19dee9f.e72838", + "name": "Brightness check - Down press/hold", + "property": "payload", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "down_press", + "vt": "str" + }, + { + "t": "eq", + "v": "down_hold", + "vt": "str" + } + ], + "checkall": "true", + "repair": false, + "outputs": 2, + "x": 540, + "y": 100, + "wires": [ + [ + "hllw_sw_dec_01" + ], + [ + "hllw_sw_dec_01" + ] + ] + }, + { + "id": "hllw_sw_inc_01", + "type": "change", + "z": "c19dee9f.e72838", + "name": "Brightness increase (smooth)", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_step\":15,\"transition\":0.8}", + "tot": "json" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1320, + "y": 60, + "wires": [ + [ + "28b5f90c956f8589" + ] + ] + }, + { + "id": "hllw_sw_dec_01", + "type": "change", + "z": "c19dee9f.e72838", + "name": "Brightness decrease (smooth)", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "{\"brightness_step\":-15,\"transition\":0.8}", + "tot": "json" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 1330, + "y": 100, + "wires": [ + [ + "28b5f90c956f8589" + ] + ] + }, + { + "id": "hllw_sw_dbg_01", + "type": "debug", + "z": "c19dee9f.e72838", + "name": "Hallway Switch Debug", + "active": false, + "tosidebar": true, + "console": false, + "tostatus": false, + "complete": "payload", + "targetType": "msg", + "statusVal": "", + "statusType": "auto", + "x": 180, + "y": 200, + "wires": [] + }, + { + "id": "hllw_goodbye_comment_01", + "type": "comment", + "z": "c19dee9f.e72838", + "name": "Goodbye button", + "info": "", + "x": 140, + "y": 660, + "wires": [] + }, + { + "id": "hllw_goodbye_trigger_01", + "type": "server-state-changed", + "z": "c19dee9f.e72838", + "name": "Goodbye button", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 1, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "sensor.goodbye_button_action" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": false, + "ignoreCurrentStateUnavailable": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 140, + "y": 700, + "wires": [ + [ + "hllw_goodbye_espresso_01", + "hllw_goodbye_harmony_01", + "hllw_goodbye_heos_01", + "hllw_goodbye_lights_01" + ] + ] + }, + { + "id": "hllw_goodbye_espresso_01", + "type": "api-call-service", + "z": "c19dee9f.e72838", + "name": "Espresso off", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "switch.turn_off", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "switch.espresso_kitchen" + ], + "labelId": [], + "data": "", + "dataType": "jsonata", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "switch", + "service": "turn_off", + "x": 510, + "y": 700, + "wires": [ + [] + ] + }, + { + "id": "hllw_goodbye_harmony_01", + "type": "api-call-service", + "z": "c19dee9f.e72838", + "name": "Harmony off", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "remote.turn_off", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "remote.living_room" + ], + "labelId": [], + "data": "", + "dataType": "jsonata", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "remote", + "service": "turn_off", + "x": 510, + "y": 760, + "wires": [ + [] + ] + }, + { + "id": "hllw_goodbye_heos_01", + "type": "api-call-service", + "z": "c19dee9f.e72838", + "name": "HEOS pause", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "media_player.media_pause", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "media_player.bathroom", + "media_player.bedroom", + "media_player.kitchen" + ], + "labelId": [], + "data": "", + "dataType": "jsonata", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "media_player", + "service": "media_pause", + "x": 510, + "y": 820, + "wires": [ + [] + ] + }, + { + "id": "hllw_goodbye_lights_01", + "type": "api-call-service", + "z": "c19dee9f.e72838", + "name": "Lights off", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "light.turn_off", + "floorId": [], + "areaId": [ + "7047cdd7d50e49f980eba16f832acb57", + "58b6232129db4aa396355dcff5edc036", + "9fb80339d4ee49f098decfafad38ab78", + "balcony" + ], + "deviceId": [], + "entityId": [], + "labelId": [], + "data": "", + "dataType": "jsonata", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "light", + "service": "turn_off", + "x": 500, + "y": 880, + "wires": [ + [] + ] + }, + { + "id": "hllw_br_state_01", + "type": "api-current-state", + "z": "c19dee9f.e72838", + "name": "Bedroom ceiling brightness", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "light.bedroom_main", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entity" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 1340, + "y": 400, + "wires": [ + [ + "hllw_br_switch_01" + ] + ] + }, + { + "id": "hllw_br_switch_01", + "type": "switch", + "z": "c19dee9f.e72838", + "name": "Bedroom brightness > 50%?", + "property": "data.attributes.brightness", + "propertyType": "msg", + "rules": [ + { + "t": "gt", + "v": "128", + "vt": "num" + }, + { + "t": "else" + } + ], + "checkall": "false", + "repair": false, + "outputs": 2, + "x": 1340, + "y": 440, + "wires": [ + [ + "da8f36cbc0df2e8c" + ], + [ + "dcd933bc4929181e" + ] + ] + }, + { + "id": "d62ce1b52df12205", + "type": "comment", + "z": "c19dee9f.e72838", + "name": "When bedroom is lit - use more brightness", + "info": "", + "x": 1380, + "y": 360, + "wires": [] + }, + { + "id": "errc19dee9f_c", + "type": "catch", + "z": "c19dee9f.e72838", + "name": "Tab errors", + "scope": null, + "uncaught": false, + "x": 120, + "y": 2000, + "wires": [ + [ + "errc19dee9f_f" + ] + ] + }, + { + "id": "errc19dee9f_f", + "type": "function", + "z": "c19dee9f.e72838", + "name": "Format error", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Hallway\", data: { priority: 1 } });\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 360, + "y": 2000, + "wires": [ + [ + "errc19dee9f_s" + ] + ] + }, + { + "id": "errc19dee9f_s", + "type": "api-call-service", + "z": "c19dee9f.e72838", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "notify", + "service": "gotify_nodered", + "x": 600, + "y": 2000, + "wires": [ + [] + ] + }, + { + "id": "b1b0a80b.d1f6cf", + "type": "api-current-state", + "z": "b73eb220c60f9f8b", + "name": "Get auto standby time", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_number.coffee_max_standby", + "state_type": "", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "number", + "valueType": "entityState" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 440, + "y": 120, + "wires": [ + [ + "espresso_fn_001" + ] + ] + }, + { + "id": "espresso_fn_001", + "type": "change", + "z": "b73eb220c60f9f8b", + "name": "Store standby time", + "rules": [ + { + "t": "set", + "p": "espresso_standby", + "pt": "flow", + "to": "payload", + "tot": "msg" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 750, + "y": 120, + "wires": [ + [ + "c0926692.581f73" + ] + ] + }, + { + "id": "304a933a.0c94bb", + "type": "server-state-changed", + "z": "b73eb220c60f9f8b", + "name": "Espresso machine is on", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "switch.espresso_kitchen" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "on", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 160, + "y": 120, + "wires": [ + [ + "b1b0a80b.d1f6cf" + ], + [] + ] + }, + { + "id": "8b67baba.6bec7f", + "type": "api-call-service", + "z": "b73eb220c60f9f8b", + "name": "Turn off espresso", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [ + "switch.espresso_kitchen" + ], + "labelId": [], + "data": "", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "blockInputOverrides": false, + "domain": "switch", + "service": "turn_off", + "x": 1090, + "y": 200, + "wires": [ + [] + ] + }, + { + "id": "c0926692.581f73", + "type": "stoptimer-varidelay", + "z": "b73eb220c60f9f8b", + "duration": "espresso_standby", + "durationType": "flow", + "units": "Minute", + "payloadtype": "num", + "payloadval": "", + "name": "Off timer ", + "reporting": "none", + "reportingformat": "human", + "persist": true, + "ignoretimerpass": false, + "x": 800, + "y": 200, + "wires": [ + [ + "8b67baba.6bec7f" + ], + [], + [] + ] + }, + { + "id": "fa64478a.97f1a8", + "type": "server-state-changed", + "z": "b73eb220c60f9f8b", + "name": "Espresso machine is off", + "server": "657c7463.48e1e4", + "version": 6, + "outputs": 2, + "exposeAsEntityConfig": "", + "entities": { + "entity": [ + "switch.espresso_kitchen" + ], + "substring": [], + "regex": [] + }, + "outputInitially": false, + "stateType": "str", + "ifState": "off", + "ifStateType": "str", + "ifStateOperator": "is", + "outputOnlyOnStateChange": true, + "for": 0, + "forType": "num", + "forUnits": "minutes", + "ignorePrevStateNull": false, + "ignorePrevStateUnknown": false, + "ignorePrevStateUnavailable": false, + "ignoreCurrentStateUnknown": true, + "ignoreCurrentStateUnavailable": true, + "outputProperties": [ + { + "property": "payload", + "propertyType": "msg", + "value": "string", + "valueType": "entityState" + }, + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "eventData" + }, + { + "property": "topic", + "propertyType": "msg", + "value": "", + "valueType": "triggerId" + } + ], + "x": 160, + "y": 200, + "wires": [ + [ + "f4b1069c.ad2569" + ], + [] + ] + }, + { + "id": "f4b1069c.ad2569", + "type": "change", + "z": "b73eb220c60f9f8b", + "name": "Send STOP", + "rules": [ + { + "t": "set", + "p": "payload", + "pt": "msg", + "to": "stop", + "tot": "str" + } + ], + "x": 410, + "y": 200, + "wires": [ + [ + "c0926692.581f73" + ] + ] + }, + { + "id": "errb73eb220_c", + "type": "catch", + "z": "b73eb220c60f9f8b", + "name": "Tab errors", + "scope": null, + "uncaught": false, + "x": 120, + "y": 2000, + "wires": [ + [ + "errb73eb220_f" + ] + ] + }, + { + "id": "errb73eb220_f", + "type": "function", + "z": "b73eb220c60f9f8b", + "name": "Format error", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Espresso Machine\", data: { priority: 1 } });\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 360, + "y": 2000, + "wires": [ + [ + "errb73eb220_s" + ] + ] + }, + { + "id": "errb73eb220_s", + "type": "api-call-service", + "z": "b73eb220c60f9f8b", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "areaId": [], + "deviceId": [], + "entityId": [], + "data": "{{{payload}}}", + "dataType": "json", + "mergeContext": "", + "mustacheAltTags": false, + "outputProperties": [], + "queue": "none", + "domain": "notify", + "service": "gotify_nodered", + "x": 600, + "y": 2000, + "wires": [ + [] + ] + }, + { + "id": "3dbc0aef753068b6", + "type": "catch", + "z": "b73eb220c60f9f8b", + "name": "Tab errors", + "scope": null, + "uncaught": false, + "x": 120, + "y": 320, + "wires": [ + [ + "f12242c7d3a27af5" + ] + ] + }, + { + "id": "f12242c7d3a27af5", + "type": "function", + "z": "b73eb220c60f9f8b", + "name": "Format error", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Living room\", data: { priority: 1 } });\nreturn msg;", + "outputs": 1, + "timeout": "", + "noerr": 0, + "initialize": "", + "finalize": "", + "libs": [], + "x": 390, + "y": 320, + "wires": [ + [ + "4abcaba467c1d59d" + ] + ] + }, + { + "id": "4abcaba467c1d59d", + "type": "api-call-service", + "z": "b73eb220c60f9f8b", + "name": "gotify_nodered", + "server": "657c7463.48e1e4", + "version": 7, + "debugenabled": false, + "action": "notify.gotify_nodered", + "floorId": [], + "areaId": [], + "deviceId": [], + "entityId": [], + "labelId": [], "data": "{{{payload}}}", "dataType": "json", "mergeContext": "", @@ -10300,15 +15680,38 @@ "queue": "none", "blockInputOverrides": false, "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 2280, + "service": "gotify_nodered", + "x": 640, + "y": 320, "wires": [ [] ] }, + { + "id": "bcbc032dc0da76b5", + "type": "inject", + "z": "b73eb220c60f9f8b", + "name": "", + "props": [ + { + "p": "payload" + } + ], + "repeat": "", + "crontab": "", + "once": false, + "onceDelay": 0.1, + "topic": "", + "payload": "5", + "payloadType": "num", + "x": 410, + "y": 260, + "wires": [ + [ + "espresso_fn_001" + ] + ] + }, { "id": "970f66c027cf1bda", "type": "server-state-changed", @@ -10954,370 +16357,6 @@ ] ] }, - { - "id": "fb51416832400a90", - "type": "server-state-changed", - "z": "5af82cd4c44df066", - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.test_button_kitchen" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 310, - "y": 860, - "wires": [ - [ - "a83bddfc2380a7fc" - ] - ] - }, - { - "id": "a83bddfc2380a7fc", - "type": "debug", - "z": "5af82cd4c44df066", - "name": "debug 5", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "false", - "statusVal": "", - "statusType": "auto", - "x": 740, - "y": 860, - "wires": [] - }, - { - "id": "d8bfcf399f7df488", - "type": "server-state-changed", - "z": "5af82cd4c44df066", - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_select.kitchen_scene_selector" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 280, - "y": 920, - "wires": [ - [ - "a83bddfc2380a7fc" - ] - ] - }, - { - "id": "0f50cf7e0d776d55", - "type": "server-state-changed", - "z": "5af82cd4c44df066", - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_select.kitchen_scene_shifter" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 280, - "y": 980, - "wires": [ - [ - "a83bddfc2380a7fc" - ] - ] - }, - { - "id": "ee1d6a217dd0e238", - "type": "server-state-changed", - "z": "5af82cd4c44df066", - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_boolean.kitchen_lights_on" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 280, - "y": 1040, - "wires": [ - [ - "a83bddfc2380a7fc" - ] - ] - }, - { - "id": "bbae72e59241d2c0", - "type": "server-state-changed", - "z": "5af82cd4c44df066", - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_boolean.kitchen_occupied" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 280, - "y": 1160, - "wires": [ - [ - "a83bddfc2380a7fc" - ] - ] - }, - { - "id": "c223cdc7301b7103", - "type": "server-state-changed", - "z": "5af82cd4c44df066", - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "light.kitchen_2" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 280, - "y": 1100, - "wires": [ - [ - "a83bddfc2380a7fc" - ] - ] - }, { "id": "28725aa2f0bc83ef", "type": "subflow:52430f5e9f9ee267", @@ -11457,789 +16496,61 @@ ] }, { - "id": "p2catch_kit", + "id": "err5af82cd4_c", "type": "catch", "z": "5af82cd4c44df066", - "name": "Catch all errors", + "name": "Tab errors", "scope": null, "uncaught": false, - "x": 160, - "y": 1360, + "x": 120, + "y": 2000, "wires": [ [ - "p2fmt_kit" + "err5af82cd4_f" ] ] }, { - "id": "p2fmt_kit", + "id": "err5af82cd4_f", "type": "function", "z": "5af82cd4c44df066", "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Kitchen',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Kitchen\", data: { priority: 1 } });\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 400, - "y": 1360, + "x": 360, + "y": 2000, "wires": [ [ - "p2ntfy_kit" + "err5af82cd4_s" ] ] }, { - "id": "p2ntfy_kit", + "id": "err5af82cd4_s", "type": "api-call-service", "z": "5af82cd4c44df066", - "name": "Notify error", + "name": "gotify_nodered", "server": "657c7463.48e1e4", "version": 7, "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], "areaId": [], "deviceId": [], "entityId": [], - "labelId": [], "data": "{{{payload}}}", "dataType": "json", "mergeContext": "", "mustacheAltTags": false, "outputProperties": [], "queue": "none", - "blockInputOverrides": false, "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 1360, - "wires": [ - [] - ] - }, - { - "id": "f3d66e8924f18806", - "type": "server-state-changed", - "z": "10cbea6aaac127cd", - "name": "Balcony Tradfri button", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.balcony_light_switch_action" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 140, - "wires": [ - [ - "f1e907e6ede24945" - ], - [] - ] - }, - { - "id": "9412a727b1cbef12", - "type": "comment", - "z": "10cbea6aaac127cd", - "name": "Balcony light control", - "info": "", - "x": 170, - "y": 100, - "wires": [] - }, - { - "id": "f1e907e6ede24945", - "type": "api-current-state", - "z": "10cbea6aaac127cd", - "name": "Balcony Lights On?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "on", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "light.outdoor_light_string", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], - "for": "0", - "forType": "num", - "forUnits": "minutes", - "override_topic": false, - "state_location": "payload", - "override_payload": "msg", - "entity_location": "data", - "override_data": "msg", - "x": 510, - "y": 140, - "wires": [ - [ - "199c4827dec86225" - ], - [ - "a29b4c78a44241b6" - ] - ] - }, - { - "id": "a29b4c78a44241b6", - "type": "api-call-service", - "z": "10cbea6aaac127cd", - "name": "Turn on balcony lights", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": true, - "action": "light.turn_on", - "floorId": [], - "areaId": [ - "balcony" - ], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_on", - "x": 860, - "y": 160, - "wires": [ - [] - ] - }, - { - "id": "199c4827dec86225", - "type": "api-call-service", - "z": "10cbea6aaac127cd", - "name": "Turn of balcony lights", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": true, - "action": "light.turn_off", - "floorId": [], - "areaId": [ - "balcony" - ], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_off", - "x": 860, - "y": 100, - "wires": [ - [] - ] - }, - { - "id": "p2catch_bal", - "type": "catch", - "z": "10cbea6aaac127cd", - "name": "Catch all errors", - "scope": null, - "uncaught": false, - "x": 160, - "y": 360, - "wires": [ - [ - "p2fmt_bal" - ] - ] - }, - { - "id": "p2fmt_bal", - "type": "function", - "z": "10cbea6aaac127cd", - "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Balcony',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 400, - "y": 360, - "wires": [ - [ - "p2ntfy_bal" - ] - ] - }, - { - "id": "p2ntfy_bal", - "type": "api-call-service", - "z": "10cbea6aaac127cd", - "name": "Notify error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 360, - "wires": [ - [] - ] - }, - { - "id": "eb217ba8.833d48", - "type": "server-state-changed", - "z": "1f4d4622.7490ca", - "d": true, - "name": "Outside temperature", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.openweathermap_temperature" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "num", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 110, - "y": 120, - "wires": [ - [ - "c8bf7086.b32ab8", - "be230668.4e6718", - "1de4cd6b31838517" - ] - ] - }, - { - "id": "c8bf7086.b32ab8", - "type": "api-current-state", - "z": "1f4d4622.7490ca", - "name": "Inside temperature", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 1, - "halt_if": "", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "sensor.livingroom_temperature_avg", - "state_type": "num", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "string", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], - "for": 0, - "forType": "num", - "forUnits": "minutes", - "x": 470, - "y": 120, - "wires": [ - [ - "13a9b38f.3ab9d4", - "1de4cd6b31838517" - ] - ] - }, - { - "id": "68aa8fe5.4cd4f", - "type": "function", - "z": "1f4d4622.7490ca", - "name": "Determine cooler or warmer", - "func": "var outsideTemp = parseFloat(msg.payload.outside);\nvar insideTemp = parseFloat(msg.payload.inside);\nvar notification = '';\n\nif (outsideTemp < insideTemp) {\n notification = 'Outside is cooler than inside';\n} else {\n notification = 'Outside is warmer than inside';\n}\n\nmsg.payload = notification;\n\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 880, - "y": 180, - "wires": [ - [ - "e27e4896.4eefa", - "1de4cd6b31838517" - ] - ] - }, - { - "id": "e27e4896.4eefa", - "type": "api-call-service", - "z": "1f4d4622.7490ca", - "name": "Notify via HA", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{\"title\":\"Info\",\"message\":\"{{{payload}}}\"}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 1130, - "y": 180, - "wires": [ - [] - ] - }, - { - "id": "be230668.4e6718", - "type": "change", - "z": "1f4d4622.7490ca", - "name": "Clear data", - "rules": [ - { - "t": "delete", - "p": "data", - "pt": "msg" - }, - { - "t": "set", - "p": "topic", - "pt": "msg", - "to": "outside", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 470, - "y": 260, - "wires": [ - [ - "2119da07.2ad496" - ] - ] - }, - { - "id": "13a9b38f.3ab9d4", - "type": "change", - "z": "1f4d4622.7490ca", - "name": "Clear data", - "rules": [ - { - "t": "delete", - "p": "data", - "pt": "msg" - }, - { - "t": "set", - "p": "topic", - "pt": "msg", - "to": "inside", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 470, - "y": 200, - "wires": [ - [ - "2119da07.2ad496" - ] - ] - }, - { - "id": "2119da07.2ad496", - "type": "join", - "z": "1f4d4622.7490ca", - "name": "", - "mode": "custom", - "build": "object", - "property": "payload", - "propertyType": "msg", - "key": "topic", - "joiner": "\\n", - "joinerType": "str", - "accumulate": false, - "timeout": "", - "count": "2", - "reduceRight": false, - "reduceExp": "", - "reduceInit": "", - "reduceInitType": "", - "reduceFixup": "", - "x": 670, - "y": 180, - "wires": [ - [ - "68aa8fe5.4cd4f" - ] - ] - }, - { - "id": "1de4cd6b31838517", - "type": "debug", - "z": "1f4d4622.7490ca", - "name": "Temperature alert", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "payload", - "targetType": "msg", - "statusVal": "", - "statusType": "auto", - "x": 830, - "y": 60, - "wires": [] - }, - { - "id": "9a99a3d8e416b026", - "type": "comment", - "z": "1f4d4622.7490ca", - "name": "Temperature alert", - "info": "", - "x": 100, - "y": 80, - "wires": [] - }, - { - "id": "a676209fc00d4d6c", - "type": "comment", - "z": "1f4d4622.7490ca", - "name": "Climate control", - "info": "", - "x": 100, - "y": 360, - "wires": [] - }, - { - "id": "6156c5585680e99e", - "type": "server-state-changed", - "z": "1f4d4622.7490ca", - "d": true, - "name": "Livingroom window open", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.window_handle_bedroom_state" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "closed", - "ifStateType": "str", - "ifStateOperator": "is_not", - "outputOnlyOnStateChange": true, - "for": "0", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 130, - "y": 420, - "wires": [ - [ - "ea05134bce8525ef" - ], - [ - "e2f354b6c7b22e8d" - ] - ] - }, - { - "id": "ea05134bce8525ef", - "type": "api-call-service", - "z": "1f4d4622.7490ca", - "d": true, - "name": "Activate window open mode", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "scene.turn_on", - "floorId": [], - "areaId": [ - "7047cdd7d50e49f980eba16f832acb57" - ], - "deviceId": [], - "entityId": [ - "scene.bedroom_climate_window_open" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "scene", - "service": "turn_on", - "output_location": "", - "output_location_type": "none", - "x": 520, - "y": 420, - "wires": [ - [] - ] - }, - { - "id": "e2f354b6c7b22e8d", - "type": "api-call-service", - "z": "1f4d4622.7490ca", - "d": true, - "name": "Activate window open mode", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "scene.apply", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "scene", - "service": "apply", - "output_location": "", - "output_location_type": "none", - "x": 520, - "y": 500, - "wires": [ - [] - ] - }, - { - "id": "p2catch_tmp", - "type": "catch", - "z": "1f4d4622.7490ca", - "name": "Catch all errors", - "scope": null, - "uncaught": false, - "x": 160, - "y": 700, - "wires": [ - [ - "p2fmt_tmp" - ] - ] - }, - { - "id": "p2fmt_tmp", - "type": "function", - "z": "1f4d4622.7490ca", - "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Temperature & climate',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 400, - "y": 700, - "wires": [ - [ - "p2ntfy_tmp" - ] - ] - }, - { - "id": "p2ntfy_tmp", - "type": "api-call-service", - "z": "1f4d4622.7490ca", - "name": "Notify error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 700, + "service": "gotify_nodered", + "x": 600, + "y": 2000, "wires": [ [] ] @@ -12919,7 +17230,7 @@ "z": "b70ee13eafa73823", "name": "", "x": 850, - "y": 600, + "y": 700, "wires": [ [ "ecf9fefeac6dc853" @@ -13179,7 +17490,7 @@ { "property": "payload", "propertyType": "msg", - "value": "", + "value": "string", "valueType": "entityState" } ], @@ -13191,12 +17502,12 @@ "override_payload": "msg", "entity_location": "data", "override_data": "msg", - "x": 500, - "y": 480, + "x": 540, + "y": 420, "wires": [ [ - "ce7a6033db2e3ffa", - "0836295ca0bc0df3" + "0836295ca0bc0df3", + "ce7a6033db2e3ffa" ], [ "ec6ae14bf7d95e92" @@ -13266,7 +17577,7 @@ "blockInputOverrides": false, "domain": "input_select", "service": "select_next", - "x": 1680, + "x": 1760, "y": 420, "wires": [ [] @@ -13308,7 +17619,7 @@ "override_payload": "msg", "entity_location": "data", "override_data": "msg", - "x": 800, + "x": 840, "y": 400, "wires": [ [ @@ -13352,7 +17663,7 @@ "override_payload": "msg", "entity_location": "data", "override_data": "msg", - "x": 780, + "x": 820, "y": 440, "wires": [ [ @@ -13408,7 +17719,7 @@ "checkall": "false", "repair": false, "outputs": 2, - "x": 1250, + "x": 1270, "y": 460, "wires": [ [ @@ -13438,7 +17749,7 @@ "from": "", "to": "", "reg": false, - "x": 1630, + "x": 1710, "y": 480, "wires": [ [ @@ -13534,7 +17845,7 @@ "z": "b70ee13eafa73823", "name": "Only shift if value is identical between selects", "info": "In case the UI elements are already the same, then i want to trigger the next scene.\nIn case the UI elements are not the same, they should be synchonized.", - "x": 1170, + "x": 1190, "y": 500, "wires": [] }, @@ -13588,8 +17899,7 @@ "y": 100, "wires": [ [ - "dining_route_001", - "13bf72e70e9bbd73" + "dining_cs_001" ] ] }, @@ -13639,7 +17949,7 @@ "domain": "light", "service": "{{ service }}", "x": 1340, - "y": 1240, + "y": 1220, "wires": [ [] ] @@ -14016,258 +18326,6 @@ ] ] }, - { - "id": "7de469ae61567be2", - "type": "server-state-changed", - "z": "b70ee13eafa73823", - "d": true, - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.livingroom_tapdial_action" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 240, - "y": 1820, - "wires": [ - [ - "4b1badad7ce89076" - ] - ] - }, - { - "id": "4b1badad7ce89076", - "type": "debug", - "z": "b70ee13eafa73823", - "name": "debug 6", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "false", - "statusVal": "", - "statusType": "auto", - "x": 660, - "y": 1880, - "wires": [] - }, - { - "id": "66756ac444fc22da", - "type": "server-state-changed", - "z": "b70ee13eafa73823", - "d": true, - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.livingroom_tapdial_action_time" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 260, - "y": 1940, - "wires": [ - [ - "4b1badad7ce89076" - ] - ] - }, - { - "id": "7d4e2bdc0bcf256d", - "type": "server-state-changed", - "z": "b70ee13eafa73823", - "d": true, - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.livingroom_tapdial_action_type" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 260, - "y": 1900, - "wires": [ - [ - "4b1badad7ce89076" - ] - ] - }, - { - "id": "ec9d9a53e6083bcb", - "type": "server-state-changed", - "z": "b70ee13eafa73823", - "d": true, - "name": "", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.livingroom_tapdial_action_direction" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 270, - "y": 1860, - "wires": [ - [ - "4b1badad7ce89076" - ] - ] - }, { "id": "13bf72e70e9bbd73", "type": "debug", @@ -14307,15 +18365,13 @@ "checkall": "true", "repair": false, "outputs": 2, - "x": 550, + "x": 510, "y": 1360, "wires": [ [ - "dining_scene_toggle_001" + "dining_cs_002" ], - [ - "dc98aceee1133a56" - ] + [] ] }, { @@ -14354,8 +18410,8 @@ "override_payload": "msg", "entity_location": "data", "override_data": "msg", - "x": 810, - "y": 1340, + "x": 750, + "y": 1320, "wires": [ [ "0d22e917d1b9469d" @@ -14422,8 +18478,8 @@ "from": "", "to": "", "reg": false, - "x": 1100, - "y": 1360, + "x": 1140, + "y": 1380, "wires": [ [ "28f2c687c20d4265" @@ -14456,8 +18512,8 @@ "from": "", "to": "", "reg": false, - "x": 1100, - "y": 1400, + "x": 1140, + "y": 1420, "wires": [ [ "28f2c687c20d4265" @@ -14500,7 +18556,7 @@ "override_payload": "msg", "entity_location": "data", "override_data": "msg", - "x": 820, + "x": 760, "y": 1400, "wires": [ [ @@ -14549,17 +18605,7 @@ "name": "Livingroom tap-dial", "info": "", "x": 150, - "y": 2020, - "wires": [] - }, - { - "id": "10325d851d92b3db", - "type": "comment", - "z": "b70ee13eafa73823", - "name": "Dimmer functionality testing - HUE", - "info": "", - "x": 400, - "y": 2020, + "y": 2000, "wires": [] }, { @@ -15026,7 +19072,7 @@ } ], "x": 190, - "y": 1360, + "y": 1180, "wires": [ [ "691f50e528c73024" @@ -15139,8 +19185,8 @@ "valueType": "triggerId" } ], - "x": 140, - "y": 1660, + "x": 160, + "y": 1780, "wires": [ [ "f71263e2817da390" @@ -15176,8 +19222,8 @@ "blockInputOverrides": false, "domain": "light", "service": "turn_on", - "x": 630, - "y": 1720, + "x": 650, + "y": 1840, "wires": [ [ "203f27c455479e23" @@ -15203,8 +19249,8 @@ "from": "", "to": "", "reg": false, - "x": 410, - "y": 1640, + "x": 430, + "y": 1760, "wires": [ [ "222353ea1c063036" @@ -15230,8 +19276,8 @@ "from": "", "to": "", "reg": false, - "x": 410, - "y": 1680, + "x": 430, + "y": 1800, "wires": [ [ "222353ea1c063036" @@ -15261,8 +19307,8 @@ "blockInputOverrides": false, "domain": "scene", "service": "create", - "x": 630, - "y": 1660, + "x": 650, + "y": 1780, "wires": [ [ "317a78818934e225" @@ -15292,8 +19338,8 @@ "blockInputOverrides": false, "domain": "scene", "service": "delete", - "x": 1190, - "y": 1720, + "x": 1210, + "y": 1840, "wires": [ [ "22a05465f41aea40" @@ -15323,8 +19369,8 @@ "blockInputOverrides": false, "domain": "scene", "service": "turn_on", - "x": 940, - "y": 1720, + "x": 960, + "y": 1840, "wires": [ [ "a890dae37cb6e247" @@ -15348,8 +19394,8 @@ "drop": false, "allowrate": false, "outputs": 1, - "x": 640, - "y": 1780, + "x": 660, + "y": 1900, "wires": [ [ "8be5c8df48382bc5" @@ -15382,8 +19428,8 @@ "blockInputOverrides": false, "domain": "light", "service": "turn_on", - "x": 900, - "y": 1800, + "x": 1460, + "y": 1840, "wires": [ [] ] @@ -15411,7 +19457,7 @@ "override_payload": "msg", "entity_location": "data", "override_data": "msg", - "x": 190, + "x": 150, "y": 2120, "wires": [ [ @@ -16459,7 +20505,7 @@ { "property": "payload", "propertyType": "msg", - "value": "", + "value": "string", "valueType": "entityState" }, { @@ -16475,8 +20521,8 @@ "valueType": "triggerId" } ], - "x": 130, - "y": 680, + "x": 110, + "y": 660, "wires": [ [ "6073e4e66bb6e228" @@ -16492,7 +20538,7 @@ "y": 740, "wires": [ [ - "f833288986e00ae0" + "2db649c0455c7a49" ] ] }, @@ -16547,7 +20593,7 @@ "valueType": "triggerId" } ], - "x": 150, + "x": 130, "y": 780, "wires": [ [ @@ -16564,7 +20610,7 @@ "y": 840, "wires": [ [ - "f833288986e00ae0" + "2db649c0455c7a49" ] ] }, @@ -16619,7 +20665,7 @@ "valueType": "triggerId" } ], - "x": 130, + "x": 110, "y": 880, "wires": [ [ @@ -16636,7 +20682,7 @@ "y": 940, "wires": [ [ - "f833288986e00ae0" + "2db649c0455c7a49" ] ] }, @@ -16691,7 +20737,7 @@ "valueType": "triggerId" } ], - "x": 150, + "x": 130, "y": 980, "wires": [ [ @@ -16708,50 +20754,10 @@ "y": 1040, "wires": [ [ - "f833288986e00ae0" + "2db649c0455c7a49" ] ] }, - { - "id": "f833288986e00ae0", - "type": "api-current-state", - "z": "b70ee13eafa73823", - "name": "Livingroom lights on?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "on", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "light.living_room", - "state_type": "str", - "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - } - ], - "for": "0", - "forType": "num", - "forUnits": "minutes", - "override_topic": false, - "state_location": "payload", - "override_payload": "msg", - "entity_location": "data", - "override_data": "msg", - "x": 500, - "y": 520, - "wires": [ - [ - "0836295ca0bc0df3", - "ce7a6033db2e3ffa" - ], - [] - ] - }, { "id": "613a9be150591ee7", "type": "comment", @@ -17009,9 +21015,11 @@ "y": 580, "wires": [ [ - "ca7ee0d8f3f6d02e" + "guest_lr_check_01" ], - [] + [ + "lr_timeout_01" + ] ] }, { @@ -17044,8 +21052,8 @@ "override_payload": "msg", "entity_location": "data", "override_data": "msg", - "x": 520, - "y": 580, + "x": 560, + "y": 560, "wires": [ [], [ @@ -17058,7 +21066,7 @@ "type": "function", "z": "b70ee13eafa73823", "name": "Swap to no-dining scene if dining table off", - "func": "const states = global.get('homeassistant')?.homeAssistantLatest?.states || {};\nconst diningOn = states['light.living_room_dining_table']?.state === 'on';\nif (!diningOn) {\n msg.entity_id = msg.entity_id.replace(/_ha$/, '') + '_no_dining';\n}\nreturn msg;", + "func": "const diningOn = msg.data === 'on';\nif (!diningOn) {\n msg.entity_id = msg.entity_id.replace(/_ha$/, '') + '_no_dining';\n}\nreturn msg;", "outputs": 1, "timeout": 0, "noerr": 0, @@ -17078,14 +21086,14 @@ "type": "function", "z": "b70ee13eafa73823", "name": "Dining toggle: apply scene variant", - "func": "const states = global.get('homeassistant')?.homeAssistantLatest?.states || {};\nconst diningOn = states['light.living_room_dining_table']?.state === 'on';\n\nconst mainLights = [\n 'light.living_room_ceiling_1',\n 'light.living_room_ceiling_2',\n 'light.living_room_ceiling_3',\n 'light.living_room_bookshelf',\n 'light.living_room_top_of_bar'\n];\nconst sceneActive = mainLights.some(id => states[id]?.state === 'on');\n\nif (!sceneActive) {\n return diningOn ? [null, { ...msg }, null] : [null, null, { ...msg }];\n}\n\nconst selectorName = states['input_select.livingroom_scene_selector']?.state || '';\nconst slug = selectorName.toLowerCase()\n .replace(/[^a-z0-9 ]/g, '')\n .trim()\n .replace(/ +/g, '_');\n\nconst sceneId = diningOn\n ? 'scene.livingroom_' + slug + '_no_dining'\n : 'scene.livingroom_' + slug + '_ha';\n\nreturn [{ ...msg, entity_id: sceneId }, diningOn ? { ...msg } : null, null];", + "func": "const diningOn = msg.data === 'on';\nconst states = global.get('homeassistant')?.homeAssistantLatest?.states || {};\n\nconst mainLights = [\n 'light.living_room_ceiling_1',\n 'light.living_room_ceiling_2',\n 'light.living_room_ceiling_3',\n 'light.living_room_bookshelf',\n 'light.living_room_top_of_bar'\n];\nconst sceneActive = mainLights.some(id => states[id]?.state === 'on');\n\nif (!sceneActive) {\n return diningOn ? [null, { ...msg }, null] : [null, null, { ...msg }];\n}\n\nconst selectorName = states['input_select.livingroom_scene_selector']?.state || '';\nconst slug = selectorName.toLowerCase()\n .replace(/[^a-z0-9 ]/g, '')\n .trim()\n .replace(/ +/g, '_');\n\nconst sceneId = diningOn\n ? 'scene.livingroom_' + slug + '_no_dining'\n : 'scene.livingroom_' + slug + '_ha';\n\nreturn [{ ...msg, entity_id: sceneId }, diningOn ? { ...msg } : null, null];", "outputs": 3, "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 1060, - "y": 1340, + "x": 1200, + "y": 1320, "wires": [ [ "dining_scene_apply_001" @@ -17123,8 +21131,8 @@ "blockInputOverrides": false, "domain": "scene", "service": "turn_on", - "x": 1300, - "y": 1300, + "x": 1630, + "y": 1280, "wires": [ [] ] @@ -17154,8 +21162,8 @@ "blockInputOverrides": false, "domain": "light", "service": "turn_off", - "x": 1300, - "y": 1380, + "x": 1630, + "y": 1320, "wires": [ [] ] @@ -17185,376 +21193,191 @@ "blockInputOverrides": false, "domain": "light", "service": "turn_on", - "x": 1300, - "y": 1460, + "x": 1630, + "y": 1360, "wires": [ [] ] }, { - "id": "p2catch_lr", + "id": "errb70ee13e_c", "type": "catch", "z": "b70ee13eafa73823", - "name": "Catch all errors", + "name": "Tab errors", "scope": null, "uncaught": false, - "x": 160, - "y": 3860, + "x": 120, + "y": 3780, "wires": [ [ - "p2fmt_lr" + "errb70ee13e_f" ] ] }, { - "id": "p2fmt_lr", + "id": "errb70ee13e_f", "type": "function", "z": "b70ee13eafa73823", "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Living room',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", + "func": "const e = msg.error && msg.error.message ? msg.error.message : String(msg.error || 'Unknown error');\nmsg.payload = JSON.stringify({ message: e, title: \"NR Error: Living room\", data: { priority: 1 } });\nreturn msg;", "outputs": 1, "timeout": "", "noerr": 0, "initialize": "", "finalize": "", "libs": [], - "x": 400, - "y": 3860, + "x": 360, + "y": 3780, "wires": [ [ - "p2ntfy_lr" + "errb70ee13e_s" ] ] }, { - "id": "p2ntfy_lr", + "id": "errb70ee13e_s", "type": "api-call-service", "z": "b70ee13eafa73823", - "name": "Notify error", + "name": "gotify_nodered", "server": "657c7463.48e1e4", "version": 7, "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], "areaId": [], "deviceId": [], "entityId": [], - "labelId": [], "data": "{{{payload}}}", "dataType": "json", "mergeContext": "", "mustacheAltTags": false, "outputProperties": [], "queue": "none", - "blockInputOverrides": false, "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 3860, - "wires": [ - [] - ] - }, - { - "id": "13c933aa7d791e63", - "type": "subflow:52430f5e9f9ee267", - "z": "c7f876875da48b87", - "name": "", - "x": 670, - "y": 160, - "wires": [ - [ - "cc46642a3ea04954" - ], - [ - "cc46642a3ea04954" - ], - [ - "cc46642a3ea04954" - ], - [ - "1ae97faec6bec4ae" - ], - [ - "1ae97faec6bec4ae" - ], - [ - "bath_br_state_01" - ] - ] - }, - { - "id": "8ff99e0276ad242f", - "type": "trigger", - "z": "c7f876875da48b87", - "name": "Wait 4:30 min", - "op1": "", - "op2": "270", - "op1type": "nul", - "op2type": "num", - "duration": "270", - "extend": true, - "overrideDelay": false, - "units": "s", - "reset": "on", - "bytopic": "all", - "topic": "topic", - "outputs": 1, + "service": "gotify_nodered", "x": 600, - "y": 360, - "wires": [ - [ - "ce6d7cb10437a4ac" - ] - ] - }, - { - "id": "a2887d07baac63d5", - "type": "trigger", - "z": "c7f876875da48b87", - "name": "Wait for 5:00 min", - "op1": "", - "op2": "300", - "op1type": "nul", - "op2type": "num", - "duration": "300", - "extend": true, - "overrideDelay": false, - "units": "s", - "reset": "on", - "bytopic": "all", - "topic": "topic", - "outputs": 1, - "x": 610, - "y": 320, - "wires": [ - [ - "ce6d7cb10437a4ac" - ] - ] - }, - { - "id": "173369324c7a842c", - "type": "change", - "z": "c7f876875da48b87", - "name": "Flash at brightness 100%", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"brightness_pct\":100,\"flash\":\"short\"}", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1150, - "y": 440, - "wires": [ - [ - "3013e31f0b3d9303" - ] - ] - }, - { - "id": "812f8294add5575c", - "type": "server-state-changed", - "z": "c7f876875da48b87", - "name": "Bathroom lights on", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "light.bathroom_switch_left" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "string", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 150, - "y": 240, - "wires": [ - [ - "eab005bf8b682c46" - ], - [] - ] - }, - { - "id": "23f3fd10ac242022", - "type": "server-state-changed", - "z": "c7f876875da48b87", - "name": "Bathroom Humidity Changed", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.bathroom_temperature_humidity" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "num", - "ifState": "0", - "ifStateType": "num", - "ifStateOperator": "gte", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "string", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 1040, - "wires": [ - [ - "f1a2b3c4d5e60001" - ], - [] - ] - }, - { - "id": "b2a9a137a909e257", - "type": "api-call-service", - "z": "c7f876875da48b87", - "name": "Turn on fan", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "switch.turn_on", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "switch.bathroom_switch_right" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "all", - "blockInputOverrides": false, - "domain": "switch", - "service": "turn_on", - "x": 670, - "y": 1040, + "y": 3780, "wires": [ [] ] }, { - "id": "7e4f4bb9c0c9ef2b", - "type": "trigger", - "z": "c7f876875da48b87", - "name": "Wait for 5:00", - "op1": "", - "op2": "5 minutes past", - "op1type": "nul", - "op2type": "str", - "duration": "300", - "extend": false, - "overrideDelay": false, - "units": "s", - "reset": "off", - "bytopic": "all", - "topic": "topic", - "outputs": 1, - "x": 670, - "y": 1120, - "wires": [ - [ - "82599133dd2b9883" - ] - ] - }, - { - "id": "82599133dd2b9883", + "id": "dining_cs_001", "type": "api-current-state", - "z": "c7f876875da48b87", - "name": "Get Bathroom Humidity", + "z": "b70ee13eafa73823", + "name": "Dining table on?", "server": "657c7463.48e1e4", "version": 3, - "outputs": 2, - "halt_if": "0", - "halt_if_type": "num", - "halt_if_compare": "gte", - "entity_id": "sensor.bathroom_temperature_humidity", - "state_type": "num", - "blockInputOverrides": true, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "light.living_room_dining_table", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 1760, + "y": 100, + "wires": [ + [ + "dining_route_001" + ] + ] + }, + { + "id": "dining_cs_002", + "type": "api-current-state", + "z": "b70ee13eafa73823", + "name": "Dining table on?", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "light.living_room_dining_table", + "state_type": "str", + "blockInputOverrides": false, + "outputProperties": [ + { + "property": "data", + "propertyType": "msg", + "value": "", + "valueType": "entityState" + } + ], + "for": 0, + "forType": "num", + "forUnits": "minutes", + "x": 740, + "y": 1360, + "wires": [ + [ + "dining_scene_toggle_001" + ] + ] + }, + { + "id": "lr_off_cmt_01", + "type": "comment", + "z": "b70ee13eafa73823", + "name": "Auto turn-off: motion timeout + presence/media check", + "x": 260, + "y": 1320, + "wires": [] + }, + { + "id": "lr_timeout_01", + "type": "trigger", + "z": "b70ee13eafa73823", + "name": "Wait 5 min", + "op1": "", + "op2": "payload", + "op1type": "nul", + "op2type": "pay", + "duration": 300, + "extend": true, + "overrideDelay": false, + "units": "s", + "reset": "", + "bytopic": "all", + "topic": "topic", + "outputs": 1, + "x": 470, + "y": 1420, + "wires": [ + [ + "guest_lr_check_03" + ] + ] + }, + { + "id": "lr_media_acs_01", + "type": "api-current-state", + "z": "b70ee13eafa73823", + "name": "Get media box state", + "server": "657c7463.48e1e4", + "version": 3, + "outputs": 1, + "halt_if": "", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "media_player.media_box", + "state_type": "str", + "blockInputOverrides": false, "outputProperties": [ { "property": "payload", "propertyType": "msg", - "value": "string", + "value": "", "valueType": "entityState" }, { @@ -17564,811 +21387,72 @@ "valueType": "entity" } ], - "for": "0", - "forType": "num", - "forUnits": "minutes", - "override_topic": false, - "state_location": "payload", - "override_payload": "msg", - "entity_location": "data", - "override_data": "msg", - "x": 950, - "y": 1120, - "wires": [ - [ - "d6e7f8a9b0c10002" - ], - [] - ] - }, - { - "id": "27d9e5846a679b8b", - "type": "api-call-service", - "z": "c7f876875da48b87", - "name": "Turn off fan", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "switch.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "switch.bathroom_switch_right" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "switch", - "service": "turn_off", - "x": 1510, - "y": 1120, - "wires": [ - [] - ] - }, - { - "id": "4548a32796918fd8", - "type": "comment", - "z": "c7f876875da48b87", - "name": "Bathroom ventilator automation shower", - "info": "", - "x": 210, - "y": 1000, - "wires": [] - }, - { - "id": "3d44cb85e182a197", - "type": "server-state-changed", - "z": "c7f876875da48b87", - "name": "Bathroom fan turned on", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "switch.bathroom_switch_right" - ], - "substring": [], - "regex": [] - }, - "outputInitially": true, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "", - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 160, - "y": 1120, - "wires": [ - [ - "7e4f4bb9c0c9ef2b" - ], - [] - ] - }, - { - "id": "ebb5b8c2c3eb6ff5", - "type": "server-state-changed", - "z": "c7f876875da48b87", - "name": "Bathroom motion sensor on", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.bathroom_motion_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, "for": 0, "forType": "num", "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 320, + "x": 680, + "y": 1500, "wires": [ [ - "eab005bf8b682c46", - "a2887d07baac63d5", - "8ff99e0276ad242f", - "580c3afd65deefed", - "cbba47369f1e6479" - ], - [ - "a2887d07baac63d5", - "8ff99e0276ad242f", - "52af4ffdf85f60e4" + "lr_media_swt_01" ] ] }, { - "id": "cc46642a3ea04954", - "type": "change", - "z": "c7f876875da48b87", - "name": "Scene Bathroom Bright", - "rules": [ - { - "t": "set", - "p": "entity_id", - "pt": "msg", - "to": "scene.bathroom_bright", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1010, - "y": 120, - "wires": [ - [ - "ed2d549e91e1399d" - ] - ] - }, - { - "id": "ed2d549e91e1399d", - "type": "api-call-service", - "z": "c7f876875da48b87", - "name": "Turn on Scene", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "scene.turn_on", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "{{ entity_id }}" - ], - "labelId": [], - "data": "{\"transition\":0}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "all", - "blockInputOverrides": false, - "domain": "scene", - "service": "turn_on", - "x": 1560, - "y": 100, - "wires": [ - [] - ] - }, - { - "id": "1ae97faec6bec4ae", - "type": "change", - "z": "c7f876875da48b87", - "name": "Scene Bathroom Evening", - "rules": [ - { - "t": "set", - "p": "entity_id", - "pt": "msg", - "to": "scene.bathroom_evening", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1010, - "y": 160, - "wires": [ - [ - "ed2d549e91e1399d" - ] - ] - }, - { - "id": "ddf62bacca5574f6", - "type": "change", - "z": "c7f876875da48b87", - "name": "Scene Bathroom Night", - "rules": [ - { - "t": "set", - "p": "entity_id", - "pt": "msg", - "to": "scene.bathroom_night", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1000, - "y": 200, - "wires": [ - [ - "ed2d549e91e1399d" - ] - ] - }, - { - "id": "3013e31f0b3d9303", - "type": "api-call-service", - "z": "c7f876875da48b87", - "name": "Execute effect on lights bathroom", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "light.turn_on", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "light.bathroom_lights" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_on", - "x": 1540, - "y": 440, - "wires": [ - [] - ] - }, - { - "id": "bdccd31c131b65fb", - "type": "comment", - "z": "c7f876875da48b87", - "name": "Bathroom automated lights", - "info": "", - "x": 170, - "y": 200, - "wires": [] - }, - { - "id": "a9f5122a5704e0e2", - "type": "api-current-state", - "z": "c7f876875da48b87", - "name": "Noone bathing?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "off", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_boolean.bath_mode", - "state_type": "str", - "blockInputOverrides": true, - "outputProperties": [], - "for": "0", - "forType": "num", - "forUnits": "minutes", - "override_topic": false, - "state_location": "payload", - "override_payload": "msg", - "entity_location": "data", - "override_data": "msg", - "x": 1040, - "y": 340, - "wires": [ - [ - "ff97c96955f8d423" - ], - [] - ] - }, - { - "id": "38ff5b8ecfcbfdd0", - "type": "server-state-changed", - "z": "c7f876875da48b87", - "name": "Bathmode turned on", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_boolean.bath_mode" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "string", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 150, - "y": 100, - "wires": [ - [ - "20da8eedd69886b0", - "f4a8732084a282d7" - ], - [ - "13c933aa7d791e63" - ] - ] - }, - { - "id": "20da8eedd69886b0", - "type": "change", - "z": "c7f876875da48b87", - "name": "Scene Bathroom Bath", - "rules": [ - { - "t": "set", - "p": "entity_id", - "pt": "msg", - "to": "scene.bathroom_bath", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1000, - "y": 80, - "wires": [ - [ - "ed2d549e91e1399d" - ] - ] - }, - { - "id": "b8f30c8224cf9d74", - "type": "comment", - "z": "c7f876875da48b87", - "name": "Bathmode ", - "info": "", - "x": 120, - "y": 60, - "wires": [] - }, - { - "id": "eab005bf8b682c46", - "type": "api-current-state", - "z": "c7f876875da48b87", - "name": "Noone bathing?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "off", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_boolean.bath_mode", - "state_type": "str", - "blockInputOverrides": true, - "outputProperties": [], - "for": "0", - "forType": "num", - "forUnits": "minutes", - "override_topic": false, - "state_location": "payload", - "override_payload": "msg", - "entity_location": "data", - "override_data": "msg", - "x": 440, - "y": 220, - "wires": [ - [ - "13c933aa7d791e63" - ], - [] - ] - }, - { - "id": "97b500f5140c1dc1", - "type": "api-call-service", - "z": "c7f876875da48b87", - "name": "Turn off lights bathroom", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "light.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "light.bathroom_lights" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_off", - "x": 1510, - "y": 380, - "wires": [ - [] - ] - }, - { - "id": "ce6d7cb10437a4ac", - "type": "change", - "z": "c7f876875da48b87", - "name": "Store which delay", - "rules": [ - { - "t": "set", - "p": "delay", - "pt": "msg", - "to": "payload", - "tot": "msg" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 830, - "y": 340, - "wires": [ - [ - "a9f5122a5704e0e2" - ] - ] - }, - { - "id": "ff97c96955f8d423", + "id": "lr_media_swt_01", "type": "switch", - "z": "c7f876875da48b87", - "name": "5:00 or 4:30 min delay", - "property": "delay", + "z": "b70ee13eafa73823", + "name": "Media active?", + "property": "payload", "propertyType": "msg", "rules": [ { "t": "eq", - "v": "300", - "vt": "num" + "v": "playing", + "vt": "str" }, { "t": "eq", - "v": "270", - "vt": "num" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 840, - "y": 420, - "wires": [ - [ - "97b500f5140c1dc1" - ], - [ - "173369324c7a842c" - ] - ] - }, - { - "id": "cbba47369f1e6479", - "type": "trigger", - "z": "c7f876875da48b87", - "name": "Wait 1:30 min", - "op1": "", - "op2": "90", - "op1type": "nul", - "op2type": "num", - "duration": "90", - "extend": false, - "overrideDelay": false, - "units": "s", - "reset": "on", - "bytopic": "all", - "topic": "topic", - "outputs": 1, - "x": 640, - "y": 660, - "wires": [ - [ - "e12d8801b6c6f320" - ] - ] - }, - { - "id": "580c3afd65deefed", - "type": "trigger", - "z": "c7f876875da48b87", - "name": "Wait for 2:00 min", - "op1": "", - "op2": "120", - "op1type": "nul", - "op2type": "num", - "duration": "120", - "extend": false, - "overrideDelay": false, - "units": "s", - "reset": "on", - "bytopic": "all", - "topic": "topic", - "outputs": 1, - "x": 650, - "y": 620, - "wires": [ - [ - "e12d8801b6c6f320" - ] - ] - }, - { - "id": "26f9395831aa077c", - "type": "change", - "z": "c7f876875da48b87", - "name": "Flash at brightness 100%", - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"brightness_pct\":100,\"flash\":\"short\"}", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1270, - "y": 820, - "wires": [ - [ - "b1e7dd85582b7d3e" - ] - ] - }, - { - "id": "b1e7dd85582b7d3e", - "type": "api-call-service", - "z": "c7f876875da48b87", - "name": "Execute effect on lights bathroom", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "light.turn_on", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "light.bathroom_lights" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_on", - "x": 1580, - "y": 820, - "wires": [ - [] - ] - }, - { - "id": "07d4571f236fd04b", - "type": "api-current-state", - "z": "c7f876875da48b87", - "name": "Noone bathing?", - "server": "657c7463.48e1e4", - "version": 3, - "outputs": 2, - "halt_if": "off", - "halt_if_type": "str", - "halt_if_compare": "is", - "entity_id": "input_boolean.bath_mode", - "state_type": "str", - "blockInputOverrides": true, - "outputProperties": [], - "for": "0", - "forType": "num", - "forUnits": "minutes", - "override_topic": false, - "state_location": "payload", - "override_payload": "msg", - "entity_location": "data", - "override_data": "msg", - "x": 1100, - "y": 640, - "wires": [ - [ - "32e3e60ad0e0d9a1" - ], - [] - ] - }, - { - "id": "a8ad8572dc926e44", - "type": "api-call-service", - "z": "c7f876875da48b87", - "name": "Turn off lights bathroom", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "light.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "light.bathroom_lights" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_off", - "x": 1550, - "y": 760, - "wires": [ - [] - ] - }, - { - "id": "ade1222fab2ea469", - "type": "inject", - "z": "c7f876875da48b87", - "name": "", - "props": [ - { - "p": "payload" + "v": "paused", + "vt": "str" }, { - "p": "topic", + "t": "eq", + "v": "on", "vt": "str" + }, + { + "t": "else" } ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 140, - "y": 740, + "checkall": "false", + "repair": false, + "outputs": 4, + "x": 940, + "y": 1480, "wires": [ + [], + [], + [], [ - "32e3e60ad0e0d9a1" + "lr_hifi_acs_01" ] ] }, { - "id": "32e3e60ad0e0d9a1", + "id": "lr_hifi_acs_01", "type": "api-current-state", - "z": "c7f876875da48b87", - "name": "Bathroom door closed?", + "z": "b70ee13eafa73823", + "name": "Get home theater state", "server": "657c7463.48e1e4", "version": 3, - "outputs": 2, - "halt_if": "off", + "outputs": 1, + "halt_if": "", "halt_if_type": "str", "halt_if_compare": "is", - "entity_id": "binary_sensor.bathroom_door_contact", + "entity_id": "media_player.home_theater_universal", "state_type": "str", - "blockInputOverrides": true, + "blockInputOverrides": false, "outputProperties": [ { "property": "payload", @@ -18383,3581 +21467,145 @@ "valueType": "entity" } ], - "for": "0", + "for": 0, "forType": "num", "forUnits": "minutes", - "override_topic": false, - "state_location": "payload", - "override_payload": "msg", - "entity_location": "data", - "override_data": "msg", - "x": 1350, - "y": 640, + "x": 1180, + "y": 1500, + "wires": [ + [ + "lr_hifi_swt_01" + ] + ] + }, + { + "id": "lr_hifi_swt_01", + "type": "switch", + "z": "b70ee13eafa73823", + "name": "Vinyl active?", + "property": "data.attributes.source", + "propertyType": "msg", + "rules": [ + { + "t": "eq", + "v": "VINYL", + "vt": "str" + }, + { + "t": "else" + } + ], + "checkall": "false", + "repair": false, + "outputs": 2, + "x": 1430, + "y": 1500, "wires": [ [], [ - "bbd7dc3adff7b866" + "lr_presence_acs_01" ] ] }, { - "id": "52af4ffdf85f60e4", - "type": "change", - "z": "c7f876875da48b87", - "name": "Store motion off time", - "rules": [ - { - "t": "set", - "p": "motion_off_at", - "pt": "msg", - "to": "data.last_changed", - "tot": "msg" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 400, - "y": 680, - "wires": [ - [ - "580c3afd65deefed", - "cbba47369f1e6479" - ] - ] - }, - { - "id": "e12d8801b6c6f320", - "type": "change", - "z": "c7f876875da48b87", - "name": "Store which delay", - "rules": [ - { - "t": "set", - "p": "delay", - "pt": "msg", - "to": "payload", - "tot": "msg" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 890, - "y": 640, - "wires": [ - [ - "07d4571f236fd04b" - ] - ] - }, - { - "id": "bbd7dc3adff7b866", - "type": "switch", - "z": "c7f876875da48b87", - "name": "2:00 or 1:30 min delay", - "property": "delay", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "120", - "vt": "num" - }, - { - "t": "eq", - "v": "90", - "vt": "num" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 940, - "y": 780, - "wires": [ - [ - "a8ad8572dc926e44" - ], - [ - "26f9395831aa077c" - ] - ] - }, - { - "id": "f4a8732084a282d7", - "type": "trigger", - "z": "c7f876875da48b87", - "name": "Wait for 5 hours", - "op1": "", - "op2": "", - "op1type": "nul", - "op2type": "num", - "duration": "5", - "extend": false, - "overrideDelay": false, - "units": "hr", - "reset": "off", - "bytopic": "all", - "topic": "topic", - "outputs": 1, - "x": 600, - "y": 520, - "wires": [ - [ - "4b98e17771cc3851" - ] - ] - }, - { - "id": "4b98e17771cc3851", - "type": "api-call-service", - "z": "c7f876875da48b87", - "name": "Turn off bath mode", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "input_boolean.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "input_boolean.bath_mode" - ], - "labelId": [], - "data": "", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "input_boolean", - "service": "turn_off", - "x": 850, - "y": 520, - "wires": [ - [] - ] - }, - { - "id": "bb74897476a1a5e6", - "type": "comment", - "z": "c7f876875da48b87", - "name": "Automatic turn off bath mode after X hours", - "info": "", - "x": 220, - "y": 480, - "wires": [] - }, - { - "id": "f1a2b3c4d5e60001", - "type": "function", - "z": "c7f876875da48b87", - "name": "Rise >= 3% in 2 min?", - "func": "const readings = context.get(\"readings\") || [];\nconst lastTriggered = context.get(\"lastTriggered\") || 0;\nconst now = Date.now();\nconst current = parseFloat(msg.payload);\n\nif (isNaN(current)) return null;\n\n// 15-minute cooldown after triggering\nif (now - lastTriggered < 15 * 60 * 1000) return null;\n\nreadings.push({ time: now, value: current });\nconst windowMs = 2 * 60 * 1000;\nconst filtered = readings.filter(r => r.time >= now - windowMs);\ncontext.set(\"readings\", filtered);\n\nif (filtered.length < 2) return null;\n\nconst minInWindow = Math.min(...filtered.map(r => r.value));\nconst rise = current - minInWindow;\n\nif (rise >= 3) {\n context.set(\"lastTriggered\", now);\n context.set(\"readings\", []);\n flow.set(\"humidityBaseline\", minInWindow);\n return msg;\n}\nreturn null;", - "outputs": 1, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 460, - "y": 1040, - "wires": [ - [ - "b2a9a137a909e257" - ] - ] - }, - { - "id": "d6e7f8a9b0c10002", - "type": "function", - "z": "c7f876875da48b87", - "name": "Below baseline + 5%?", - "func": "const current = parseFloat(msg.payload);\nconst baseline = flow.get(\"humidityBaseline\") || 60;\nconst threshold = baseline + 5;\n\nif (current <= threshold) {\n return [msg, null];\n}\nreturn [null, msg];", - "outputs": 2, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 1240, - "y": 1120, - "wires": [ - [ - "27d9e5846a679b8b" - ], - [ - "7e4f4bb9c0c9ef2b" - ] - ] - }, - { - "id": "bthrm_timebased_01", - "type": "server-state-changed", - "z": "c7f876875da48b87", - "name": "Bathroom time-based turn on", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.bathroom_time_based_turn_on" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": "", - "forType": "num", - "forUnits": "milliseconds", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 140, - "wires": [ - [ - "13c933aa7d791e63", - "a2887d07baac63d5", - "8ff99e0276ad242f" - ] - ] - }, - { - "id": "bath_br_state_01", + "id": "lr_presence_acs_01", "type": "api-current-state", - "z": "c7f876875da48b87", - "name": "Bedroom ceiling brightness", + "z": "b70ee13eafa73823", + "name": "Still in living room?", "server": "657c7463.48e1e4", "version": 3, - "outputs": 1, - "halt_if": "", + "outputs": 2, + "halt_if": "Livingroom", "halt_if_type": "str", "halt_if_compare": "is", - "entity_id": "light.bedroom_main", + "entity_id": "input_select.room_presence", "state_type": "str", "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], + "outputProperties": [], "for": 0, "forType": "num", "forUnits": "minutes", - "x": 830, - "y": 240, + "x": 1650, + "y": 1500, "wires": [ + [], [ - "bath_br_switch_01" + "e64edc58615d79d4" ] ] }, { - "id": "bath_br_switch_01", - "type": "switch", - "z": "c7f876875da48b87", - "name": "Bedroom brightness > 50%?", - "property": "data.attributes.brightness", - "propertyType": "msg", - "rules": [ - { - "t": "gt", - "v": "128", - "vt": "num" - }, - { - "t": "else" - } - ], - "checkall": "false", - "repair": false, + "id": "guest_lr_check_01", + "type": "api-current-state", + "z": "b70ee13eafa73823", + "name": "Guest in living room on?", + "server": "657c7463.48e1e4", + "version": 3, "outputs": 2, - "x": 1080, - "y": 240, - "wires": [ - [ - "1ae97faec6bec4ae" - ], - [ - "ddf62bacca5574f6" - ] - ] - }, - { - "id": "p2catch_bth", - "type": "catch", - "z": "c7f876875da48b87", - "name": "Catch all errors", - "scope": null, - "uncaught": false, - "x": 160, - "y": 1320, - "wires": [ - [ - "p2fmt_bth" - ] - ] - }, - { - "id": "p2fmt_bth", - "type": "function", - "z": "c7f876875da48b87", - "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Bathroom',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 400, - "y": 1320, - "wires": [ - [ - "p2ntfy_bth" - ] - ] - }, - { - "id": "p2ntfy_bth", - "type": "api-call-service", - "z": "c7f876875da48b87", - "name": "Notify error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", + "halt_if": "on", + "halt_if_type": "str", + "halt_if_compare": "is", + "entity_id": "input_boolean.guest_bedroom", + "state_type": "str", "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 1320, - "wires": [ - [] - ] - }, - { - "id": "pres_c_homemode", - "type": "comment", - "z": "6dfa989bb120e6c6", - "name": "── Home Mode ──", - "info": "", - "x": 130, - "y": 60, - "wires": [] - }, - { - "id": "pres001a2b3c4d5e", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Mischa presence", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "person.mischa_gorinskat" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 120, - "y": 100, - "wires": [ - [ - "pres002a2b3c4d5e" - ] - ] - }, - { - "id": "pres002a2b3c4d5e", - "type": "switch", - "z": "6dfa989bb120e6c6", - "name": "Home or Away?", - "property": "payload", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "home", - "vt": "str" - }, - { - "t": "eq", - "v": "not_home", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 400, - "y": 100, - "wires": [ - [ - "pres003a2b3c4d5e" - ], - [ - "pres004a2b3c4d5e" - ] - ] - }, - { - "id": "pres003a2b3c4d5e", - "type": "api-call-service", - "z": "6dfa989bb120e6c6", - "name": "Set Home", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "input_select.select_option", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "input_select.home_mode" - ], - "labelId": [], - "data": "{\"option\": \"Home\"}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "input_select", - "service": "select_option", - "x": 660, - "y": 60, - "wires": [ - [] - ] - }, - { - "id": "pres004a2b3c4d5e", - "type": "api-call-service", - "z": "6dfa989bb120e6c6", - "name": "Set Away", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "input_select.select_option", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "input_select.home_mode" - ], - "labelId": [], - "data": "{\"option\": \"Away\"}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "input_select", - "service": "select_option", - "x": 660, - "y": 140, - "wires": [ - [] - ] - }, - { - "id": "pres_sm_c_header", - "type": "comment", - "z": "6dfa989bb120e6c6", - "name": "── Room Presence State Machine ──", - "info": "", - "x": 190, - "y": 300, - "wires": [] - }, - { - "id": "pres_sm_c_person", - "type": "comment", - "z": "6dfa989bb120e6c6", - "name": "Person", - "info": "", - "x": 90, - "y": 360, - "wires": [] - }, - { - "id": "pres_sm_c_hall", - "type": "comment", - "z": "6dfa989bb120e6c6", - "name": "Hallway (direction + state)", - "info": "", - "x": 150, - "y": 480, - "wires": [] - }, - { - "id": "pres_sm_c_rooms", - "type": "comment", - "z": "6dfa989bb120e6c6", - "name": "Room Motion Sensors", - "info": "", - "x": 140, - "y": 780, - "wires": [] - }, - { - "id": "pres_sm_c_sm", - "type": "comment", - "z": "6dfa989bb120e6c6", - "name": "State Machine", - "info": "", - "x": 450, - "y": 580, - "wires": [] - }, - { - "id": "pres_sm_c_out", - "type": "comment", - "z": "6dfa989bb120e6c6", - "name": "Outputs", - "info": "", - "x": 730, - "y": 580, - "wires": [] - }, - { - "id": "pres_sm_person", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Person (room SM)", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "person.mischa_gorinskat" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, "for": 0, "forType": "num", "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "string", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 130, - "y": 400, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "pres_sm_hall1", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Hallway S1 (corner/front door)", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.hallway_motion_sensor_1_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 160, - "y": 520, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "pres_sm_hall2", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Hallway S2 (near living room)", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.hallway_motion_sensor_2_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 160, - "y": 580, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "pres_sm_hall3", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Hallway S3 (near kitchen)", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.hallway_motion_sensor_3_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 150, - "y": 640, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "pres_sm_hallg", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Hallway (group)", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.hallway_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 120, - "y": 700, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "pres_sm_lr", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Living Room Motion", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.livingroom_motion_sensor_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 130, - "y": 820, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "pres_sm_bed", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Bedroom Motion", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.bedroom_motion_sensor_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 120, - "y": 880, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "pres_sm_bath", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Bathroom Motion", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.bathroom_motion_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 120, - "y": 940, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "pres_sm_kit", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Kitchen Motion", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.kitchen_motion_sensor_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 120, - "y": 1000, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "pres_sm_func", - "type": "function", - "z": "6dfa989bb120e6c6", - "name": "Room Presence SM", - "func": "// === ROOM PRESENCE STATE MACHINE ===\n// msg.topic = triggering entity_id (from triggerId output property)\n// msg.payload = entity state string\n// msg.data = full HASC event data\n\nconst entityId = (msg.data && msg.data.entity_id) ? msg.data.entity_id : (msg.topic || '');\nconst newState = (msg.data && msg.data.new_state) ? msg.data.new_state.state : msg.payload;\n\n// Guest mode guard — multi-person breaks single-occupant assumptions\nconst ha = global.get('homeassistant') || {};\nconst haStates = (ha.homeAssistantLatest || {}).states || {};\nconst guestMode = (haStates['input_boolean.guest_mode'] || {}).state;\nif (guestMode === 'on') return null;\n\n// Current state from flow context\nconst currentRoom = flow.get('currentRoom') || 'unknown';\n\n// ── Helpers ────────────────────────────────────────────────────────────────\n\nfunction capitalize(s) {\n const map = {\n unknown: 'Unknown', away: 'Away', hallway: 'Hallway',\n living_room: 'Livingroom', bedroom: 'Bedroom',\n bathroom: 'Bathroom', kitchen: 'Kitchen', balcony: 'Balcony'\n };\n return map[s] || (s.charAt(0).toUpperCase() + s.slice(1));\n}\n\nfunction cancelDestTimer() {\n const h = flow.get('destTimerHandle');\n if (h) { clearTimeout(h); flow.set('destTimerHandle', null); }\n}\n\n\nfunction setDestTimer() {\n cancelDestTimer();\n const h = setTimeout(function () {\n const lr = flow.get('lastRoom') || 'unknown';\n flow.set('currentRoom', lr);\n flow.set('destTimerHandle', null);\n node.send([\n { payload: capitalize(lr) },\n { payload: '[presence] dest-timer expired → reverted to ' + lr }\n ]);\n }, 90000);\n flow.set('destTimerHandle', h);\n}\n\n\nfunction setState(newRoom) {\n const prev = flow.get('currentRoom') || 'unknown';\n if (newRoom === prev) return null; // no change needed\n flow.set('lastRoom', prev);\n flow.set('currentRoom', newRoom);\n return [\n { payload: capitalize(newRoom) },\n { payload: '[presence] ' + prev + ' → ' + newRoom + ' (via ' + entityId + ')' }\n ];\n}\n\nfunction updateHallwaySequence(sensorNum) {\n // TODO: direction detection not yet implemented — sequence data is stored but not consumed.\n // Intended to detect hallway direction (e.g. S1→S2 = heading toward living room,\n // S2→S1 = heading toward front door).\n let seq = flow.get('hallwaySequence') || [];\n const now = Date.now();\n seq = seq.filter(function (e) { return now - e.time < 15000; });\n seq.push({ sensor: sensorNum, time: now });\n flow.set('hallwaySequence', seq);\n flow.set('lastHallwayTime', now);\n}\n\n// ── Transitions ────────────────────────────────────────────────────────────\n\n// 1. Person home / away\nif (entityId === 'person.mischa_gorinskat') {\n if (newState === 'not_home') {\n cancelDestTimer();\n return setState('away');\n }\n if (newState === 'home') {\n return setState('unknown');\n }\n return null;\n}\n\n// Ignore all motion when person is away\nif (currentRoom === 'away') return null;\n\n// 2. Individual hallway sensors — direction tracking only, no state change\nif (entityId === 'binary_sensor.hallway_motion_sensor_1_occupancy') {\n if (newState === 'on') updateHallwaySequence(1);\n return null;\n}\nif (entityId === 'binary_sensor.hallway_motion_sensor_2_occupancy') {\n if (newState === 'on') updateHallwaySequence(2);\n return null;\n}\nif (entityId === 'binary_sensor.hallway_motion_sensor_3_occupancy') {\n if (newState === 'on') updateHallwaySequence(3);\n return null;\n}\n\n// 3. Hallway group — primary state change trigger\nif (entityId === 'binary_sensor.hallway_occupancy') {\n if (newState === 'on') {\n flow.set('lastRoom', currentRoom); // save room before entering hallway\n setDestTimer(); // 90s: if no room fires → revert\n return setState('hallway');\n }\n return null; // hallway turning off doesn't trigger a state change\n}\n\n// 4. Room sensors\nconst roomMap = {\n 'binary_sensor.livingroom_motion_sensor_occupancy': 'living_room',\n 'binary_sensor.bedroom_motion_sensor_occupancy': 'bedroom',\n 'binary_sensor.bathroom_motion_occupancy': 'bathroom',\n 'binary_sensor.kitchen_motion_sensor_occupancy': 'kitchen',\n 'binary_sensor.balcony_motion_occupancy': 'balcony'\n};\n\nconst targetRoom = roomMap[entityId];\nif (targetRoom && newState === 'on') {\n cancelDestTimer(); // confirmed destination\n\n const canTransition =\n currentRoom === 'hallway' ||\n currentRoom === targetRoom ||\n currentRoom === 'unknown' ||\n (targetRoom === 'living_room' && currentRoom === 'balcony') || // return from balcony\n (targetRoom === 'balcony' && currentRoom === 'living_room'); // step onto balcony\n\n if (canTransition) return setState(targetRoom);\n return null;\n}\n\nreturn null;", - "outputs": 2, - "timeout": 0, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 480, - "y": 620, - "wires": [ - [ - "pres_sm_api" - ], - [ - "pres_sm_dbg" - ] - ] - }, - { - "id": "pres_sm_api", - "type": "api-call-service", - "z": "6dfa989bb120e6c6", - "name": "Set Room Presence", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "input_select.select_option", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "input_select.room_presence" - ], - "labelId": [], - "data": "{\"option\": \"{{{payload}}}\"}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "input_select", - "service": "select_option", - "x": 780, - "y": 620, - "wires": [ - [] - ] - }, - { - "id": "pres_sm_dbg", - "type": "debug", - "z": "6dfa989bb120e6c6", - "name": "Presence log", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "payload", - "targetType": "msg", - "statusVal": "", - "statusType": "auto", - "x": 750, - "y": 680, - "wires": [] - }, - { - "id": "pres_sm_balcony", - "type": "server-state-changed", - "z": "6dfa989bb120e6c6", - "name": "Balcony Motion", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.balcony_motion_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 120, - "y": 1060, - "wires": [ - [ - "pres_sm_func" - ] - ] - }, - { - "id": "p2catch_prs", - "type": "catch", - "z": "6dfa989bb120e6c6", - "name": "Catch all errors", - "scope": null, - "uncaught": false, - "x": 160, - "y": 1260, - "wires": [ - [ - "p2fmt_prs" - ] - ] - }, - { - "id": "p2fmt_prs", - "type": "function", - "z": "6dfa989bb120e6c6", - "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Home Presence',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 400, - "y": 1260, - "wires": [ - [ - "p2ntfy_prs" - ] - ] - }, - { - "id": "p2ntfy_prs", - "type": "api-call-service", - "z": "6dfa989bb120e6c6", - "name": "Notify error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 1260, - "wires": [ - [] - ] - }, - { - "id": "ecee1bee9953f98a", - "type": "ha-get-entities", - "z": "a320f821a7cb3f55", - "name": "Low Bat Sensors", - "server": "657c7463.48e1e4", - "version": 1, - "rules": [ - { - "property": "entity_id", - "logic": "is", - "value": ".*low_bat.*", - "valueType": "re" - }, - { - "property": "attributes.battery", - "logic": "is_not", - "value": "High", - "valueType": "str" - } - ], - "outputType": "array", - "outputEmptyResults": false, - "outputLocationType": "msg", - "outputLocation": "payload", - "outputResultsCount": 1, - "x": 530, - "y": 100, - "wires": [ - [ - "5f8552a4635072aa" - ] - ] - }, - { - "id": "1b30535ba22c4655", - "type": "inject", - "z": "a320f821a7cb3f55", - "name": "", - "props": [ - { - "p": "payload" - }, - { - "p": "topic", - "vt": "str" - } - ], - "repeat": "", - "crontab": "", - "once": false, - "onceDelay": 0.1, - "topic": "", - "payload": "", - "payloadType": "date", - "x": 160, - "y": 260, - "wires": [ - [ - "293113adda48f9d0" - ] - ] - }, - { - "id": "b9891a936c8fb9d0", - "type": "debug", - "z": "a320f821a7cb3f55", - "name": "debug 3", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "false", - "statusVal": "", - "statusType": "auto", - "x": 460, - "y": 500, - "wires": [] - }, - { - "id": "556cc66d606c190e", - "type": "ha-get-entities", - "z": "a320f821a7cb3f55", - "name": "Battery Sensors - Low", - "server": "657c7463.48e1e4", - "version": 1, - "rules": [ - { - "property": "entity_id", - "logic": "is", - "value": ".*battery.*", - "valueType": "re" - }, - { - "property": "attributes.state_class", - "logic": "is", - "value": "measurement", - "valueType": "str" - }, - { - "property": "state", - "logic": "lt", - "value": "10", - "valueType": "num" - } - ], - "outputType": "array", - "outputEmptyResults": false, - "outputLocationType": "msg", - "outputLocation": "payload", - "outputResultsCount": 1, - "x": 540, - "y": 220, - "wires": [ - [ - "5f8552a4635072aa" - ] - ] - }, - { - "id": "1e34ff50a693e724", - "type": "ha-get-entities", - "z": "a320f821a7cb3f55", - "name": "Battery Sensors", - "server": "657c7463.48e1e4", - "version": 1, - "rules": [ - { - "property": "entity_id", - "logic": "is", - "value": ".*battery.*", - "valueType": "re" - } - ], - "outputType": "array", - "outputEmptyResults": false, - "outputLocationType": "msg", - "outputLocation": "payload", - "outputResultsCount": 1, - "x": 140, - "y": 500, - "wires": [ - [ - "b9891a936c8fb9d0" - ] - ] - }, - { - "id": "89a7c77a676b858b", - "type": "ha-get-entities", - "z": "a320f821a7cb3f55", - "name": "Battery Sensors - Unavailable", - "server": "657c7463.48e1e4", - "version": 1, - "rules": [ - { - "property": "entity_id", - "logic": "is", - "value": ".*battery.*", - "valueType": "re" - }, - { - "property": "attributes.state_class", - "logic": "is", - "value": "measurement", - "valueType": "str" - }, - { - "property": "state", - "logic": "is", - "value": "unavailable", - "valueType": "str" - } - ], - "outputType": "array", - "outputEmptyResults": false, - "outputLocationType": "msg", - "outputLocation": "payload", - "outputResultsCount": 1, - "x": 570, - "y": 340, - "wires": [ - [] - ] - }, - { - "id": "91f002d04003ce84", - "type": "comment", - "z": "a320f821a7cb3f55", - "name": "Filter for all *battery* entities", - "info": "", - "x": 180, - "y": 460, - "wires": [] - }, - { - "id": "ac0b28356c7eb45a", - "type": "comment", - "z": "a320f821a7cb3f55", - "name": "HomeMatic Devices", - "info": "", - "x": 530, - "y": 60, - "wires": [] - }, - { - "id": "a8192e1fcbdc41aa", - "type": "comment", - "z": "a320f821a7cb3f55", - "name": "Hue devices", - "info": "", - "x": 510, - "y": 180, - "wires": [] - }, - { - "id": "6beef06f4f0b788d", - "type": "comment", - "z": "a320f821a7cb3f55", - "name": "Any unavailable device", - "info": "", - "x": 540, - "y": 300, - "wires": [] - }, - { - "id": "5f8552a4635072aa", - "type": "split", - "z": "a320f821a7cb3f55", - "name": "", - "splt": "\\n", - "spltType": "str", - "arraySplt": 1, - "arraySpltType": "len", - "stream": false, - "addname": "", - "x": 830, - "y": 160, - "wires": [ - [ - "9dcd82782246d4e9" - ] - ] - }, - { - "id": "cc33a58286775199", - "type": "api-call-service", - "z": "a320f821a7cb3f55", - "name": "Notify via HA", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{\"title\":\"warning\",\"message\":\"{{{payload}}}\"}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 1260, - "y": 200, - "wires": [ - [] - ] - }, - { - "id": "9dcd82782246d4e9", - "type": "template", - "z": "a320f821a7cb3f55", - "name": "", - "field": "payload", - "fieldType": "msg", - "format": "handlebars", - "syntax": "mustache", - "template": "Battery level low for {{payload.attributes.friendly_name}} ({{payload.state}}%)", - "output": "str", - "x": 1000, - "y": 160, - "wires": [ - [ - "cc33a58286775199" - ] - ] - }, - { - "id": "293113adda48f9d0", - "type": "schedex", - "z": "a320f821a7cb3f55", - "name": "Saturday at 11:00", - "passthroughunhandled": true, - "suspended": false, - "lat": "", - "lon": "", - "ontime": "11:00", - "ontopic": "", - "onpayload": "", - "onoffset": 0, - "onrandomoffset": 0, - "offtime": "", - "offtopic": "", - "offpayload": "", - "offoffset": 0, - "offrandomoffset": 0, - "mon": false, - "tue": false, - "wed": false, - "thu": false, - "fri": true, - "sat": true, - "sun": false, - "x": 170, - "y": 180, - "wires": [ - [ - "ecee1bee9953f98a", - "556cc66d606c190e", - "89a7c77a676b858b" - ] - ] - }, - { - "id": "edaf40fcc105703a", - "type": "comment", - "z": "a320f821a7cb3f55", - "name": "Battery state alerts for all devices", - "info": "", - "x": 210, - "y": 140, - "wires": [] - }, - { - "id": "e4eda627074a2cf3", - "type": "comment", - "z": "a320f821a7cb3f55", - "name": "Unavailable devices alert", - "info": "Any devices that becomes unavailable in Home Assistant will be reported. This might indicate zigbee connecticity issues.", - "x": 170, - "y": 560, - "wires": [] - }, - { - "id": "a2a4917908eed983", - "type": "trigger-state", - "z": "a320f821a7cb3f55", - "d": true, - "name": "", - "server": "657c7463.48e1e4", - "version": 5, - "inputs": 0, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [], - "substring": [], - "regex": [ - ".*" - ] - }, - "debugEnabled": false, - "constraints": [ - { - "targetType": "this_entity", - "targetValue": "", - "propertyType": "current_state", - "propertyValue": "new_state.state", - "comparatorType": "is", - "comparatorValueDatatype": "str", - "comparatorValue": "unavailable" - } - ], - "customOutputs": [], - "outputInitially": false, - "stateType": "str", - "enableInput": false, - "x": 140, - "y": 600, - "wires": [ - [ - "deb32f94b6f9aad7" - ], - [] - ] - }, - { - "id": "deb32f94b6f9aad7", - "type": "debug", - "z": "a320f821a7cb3f55", - "name": "State changed debug", - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "payload", - "targetType": "msg", - "statusVal": "", - "statusType": "auto", - "x": 500, - "y": 600, - "wires": [] - }, - { - "id": "comment-heos-individual", - "type": "comment", - "z": "a320f821a7cb3f55", - "name": "HEOS individual speaker reset via TCP", - "info": "", - "x": 210, - "y": 720, - "wires": [] - }, - { - "id": "comment-heos-all", - "type": "comment", - "z": "a320f821a7cb3f55", - "name": "HEOS reset all speakers sequentially", - "info": "", - "x": 210, - "y": 960, - "wires": [] - }, - { - "id": "heos-trigger-bedroom", - "type": "server-state-changed", - "z": "a320f821a7cb3f55", - "name": "Reset Speaker Bedroom", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.reset_speaker_bedroom" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "string", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - }, - { - "property": "speaker", - "propertyType": "msg", - "value": "Bedroom", - "valueType": "str" - }, - { - "property": "ip", - "propertyType": "msg", - "value": "192.168.1.60", - "valueType": "str" - } - ], - "x": 170, - "y": 760, - "wires": [ - [ - "heos-change-target" - ] - ] - }, - { - "id": "heos-trigger-kitchen", - "type": "server-state-changed", - "z": "a320f821a7cb3f55", - "name": "Reset Speaker Kitchen", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.reset_speaker_kitchen" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - }, - { - "property": "speaker", - "propertyType": "msg", - "value": "Kitchen", - "valueType": "str" - }, - { - "property": "ip", - "propertyType": "msg", - "value": "192.168.1.62", - "valueType": "str" - } - ], - "x": 160, - "y": 800, - "wires": [ - [ - "heos-change-target" - ] - ] - }, - { - "id": "heos-trigger-bathroom", - "type": "server-state-changed", - "z": "a320f821a7cb3f55", - "name": "Reset Speaker Bathroom", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.reset_speaker_bathroom" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - }, - { - "property": "speaker", - "propertyType": "msg", - "value": "Bathroom", - "valueType": "str" - }, - { - "property": "ip", - "propertyType": "msg", - "value": "192.168.1.61", - "valueType": "str" - } - ], - "x": 170, - "y": 840, - "wires": [ - [ - "heos-change-target" - ] - ] - }, - { - "id": "heos-trigger-hometheater", - "type": "server-state-changed", - "z": "a320f821a7cb3f55", - "name": "Reset Speaker Home Theater", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.reset_speaker_home_theater" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - }, - { - "property": "speaker", - "propertyType": "msg", - "value": "Home Theater", - "valueType": "str" - }, - { - "property": "ip", - "propertyType": "msg", - "value": "192.168.1.204", - "valueType": "str" - } - ], - "x": 180, - "y": 880, - "wires": [ - [ - "heos-change-target" - ] - ] - }, - { - "id": "heos-change-target", - "type": "change", - "z": "a320f821a7cb3f55", - "name": "Set speaker target", - "rules": [ - { - "t": "set", - "p": "host", - "pt": "msg", - "to": "ip", - "tot": "msg" - }, - { - "t": "set", - "p": "port", - "pt": "msg", - "to": "1255", - "tot": "num" - }, - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "heos://system/reboot", - "tot": "str" - }, - { - "t": "set", - "p": "topic", - "pt": "msg", - "to": "\"Reboot \" & msg.speaker & \" @ \" & msg.ip & \":1255\"", - "tot": "jsonata" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 470, - "y": 820, - "wires": [ - [ - "heos-tcp", - "heos-debug" - ] - ] - }, - { - "id": "heos-tcp", - "type": "tcp request", - "z": "a320f821a7cb3f55", - "name": "Telnet HEOS", - "server": "", - "port": "", - "out": "immed", - "ret": "string", - "splitc": "0", - "newline": "", - "trim": false, - "tls": "", - "x": 730, - "y": 780, - "wires": [ - [] - ] - }, - { - "id": "heos-debug", - "type": "debug", - "z": "a320f821a7cb3f55", - "name": "HEOS command (debug)", - "active": true, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "true", - "targetType": "full", - "statusVal": "", - "statusType": "auto", - "x": 770, - "y": 840, - "wires": [] - }, - { - "id": "heos-trigger-all", - "type": "server-state-changed", - "z": "a320f821a7cb3f55", - "name": "Reset All Speakers", - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.reset_all_speakers" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": true, - "ignoreCurrentStateUnavailable": true, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 150, - "y": 1000, - "wires": [ - [ - "heos-emit-all" - ] - ] - }, - { - "id": "heos-emit-all", - "type": "function", - "z": "a320f821a7cb3f55", - "name": "Emit 4 button presses", - "func": "const buttons = [\n \"input_button.reset_speaker_bedroom\",\n \"input_button.reset_speaker_kitchen\",\n \"input_button.reset_speaker_bathroom\",\n \"input_button.reset_speaker_home_theater\"\n];\nreturn [buttons.map(b => ({ ...msg, payload: b }))];", - "outputs": 1, - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 410, - "y": 1000, - "wires": [ - [ - "heos-delay-all" - ] - ] - }, - { - "id": "heos-delay-all", - "type": "delay", - "z": "a320f821a7cb3f55", - "name": "5s between resets", - "pauseType": "rate", - "timeout": "5", - "timeoutUnits": "seconds", - "rate": "1", - "nbRateUnits": "5", - "rateUnits": "second", - "randomFirst": "1", - "randomLast": "5", - "randomUnits": "seconds", - "drop": false, - "allowrate": false, - "outputs": 1, - "x": 650, - "y": 1000, - "wires": [ - [ - "heos-service-press" - ] - ] - }, - { - "id": "heos-service-press", - "type": "api-call-service", - "z": "a320f821a7cb3f55", - "name": "Press speaker reset button", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "input_button.press", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{\"entity_id\": payload}", - "dataType": "jsonata", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "input_button", - "service": "press", - "x": 910, - "y": 1000, - "wires": [ - [] - ] - }, - { - "id": "p2catch_mnt", - "type": "catch", - "z": "a320f821a7cb3f55", - "name": "Catch all errors", - "scope": null, - "uncaught": false, - "x": 140, - "y": 1080, - "wires": [ - [ - "p2fmt_mnt" - ] - ] - }, - { - "id": "p2fmt_mnt", - "type": "function", - "z": "a320f821a7cb3f55", - "name": "Format error", - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Maintenance',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 370, - "y": 1080, - "wires": [ - [ - "p2ntfy_mnt" - ] - ] - }, - { - "id": "p2ntfy_mnt", - "type": "api-call-service", - "z": "a320f821a7cb3f55", - "name": "Notify error", - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 650, - "y": 1080, - "wires": [ - [] - ] - }, - { - "type": "tab", - "label": "Hallway", - "id": "c19dee9f.e72838" - }, - { - "id": "1be4d360986fd1f1", - "type": "server-state-changed", - "z": "c19dee9f.e72838", - "name": "Hallway smart switch", - "wires": [ - [ - "9bea73aa40198378", - "hllw_sw_onhold_01", - "hllw_sw_brup_01", - "hllw_sw_brdn_01", - "hllw_sw_dbg_01" - ] - ], - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.hallway_switch_action" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "string", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 160, - "y": 120 - }, - { - "id": "9bea73aa40198378", - "type": "switch", - "z": "c19dee9f.e72838", - "name": "On/Off check", - "wires": [ - [ - "3369429b11ec6c87" - ], - [ - "492a8c0fafdb95c0" - ] - ], - "property": "payload", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "on_press_release", - "vt": "str" - }, - { - "t": "eq", - "v": "off_press_release", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 470, - "y": 220 - }, - { - "id": "93521b5966f6fca9", - "type": "comment", - "z": "c19dee9f.e72838", - "name": "Hallway Lights on/off switch", - "wires": [], - "info": "", - "x": 180, - "y": 80 - }, - { - "id": "28b5f90c956f8589", - "type": "api-call-service", - "z": "c19dee9f.e72838", - "name": "Turn on/off lights hallway", - "wires": [ - [] - ], - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "light.turn_on", - "floorId": [], - "areaId": [ - "b156eada202a4a3381ef6ffa674f5ebc" - ], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_on", - "x": 1790, - "y": 260 - }, - { - "id": "3369429b11ec6c87", - "type": "subflow:52430f5e9f9ee267", - "z": "c19dee9f.e72838", - "name": "", - "wires": [ - [ - "9e21108d47dd29fe" - ], - [ - "9e21108d47dd29fe" - ], - [ - "da8f36cbc0df2e8c" - ], - [ - "da8f36cbc0df2e8c" - ], - [ - "hllw_br_state_01" - ], - [ - "hllw_br_state_01" - ] - ], - "x": 890, - "y": 280 - }, - { - "id": "c2c1acbc73dc80f4", - "type": "comment", - "z": "c19dee9f.e72838", - "name": "Hallway Motion sensor", - "wires": [], - "info": "", - "x": 160, - "y": 480 - }, - { - "id": "c4a4ba3c5f68d440", - "type": "server-state-changed", - "z": "c19dee9f.e72838", - "name": "Hallway motion sensor", - "wires": [ - [ - "3369429b11ec6c87", - "4b6861fef07dcf9c", - "cb510a92532ea7f5" - ], - [] - ], - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 2, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "binary_sensor.hallway_motion_sensor_1_occupancy", - "binary_sensor.hallway_motion_sensor_2_occupancy", - "binary_sensor.hallway_motion_sensor_3_occupancy" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "on", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "string", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 160, - "y": 520 - }, - { - "id": "hllw_timebased_01", - "type": "server-state-changed", - "z": "c19dee9f.e72838", - "name": "Hallway Time Based Turn On", - "wires": [ - [ - "3369429b11ec6c87", - "4b6861fef07dcf9c", - "cb510a92532ea7f5" - ] - ], - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "input_button.hallway_time_based_turn_on" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "string", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 180, - "y": 580 - }, - { - "id": "492a8c0fafdb95c0", - "type": "change", - "z": "c19dee9f.e72838", - "name": "Brightness to 0 (turn off)", - "wires": [ - [ - "28b5f90c956f8589" - ] - ], - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"brightness\":0}", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1350, - "y": 560 - }, - { - "id": "dcd933bc4929181e", - "type": "change", - "z": "c19dee9f.e72838", - "name": "Brightness to 20%", - "wires": [ - [ - "28b5f90c956f8589" - ] - ], - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"brightness_pct\":20}", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1310, - "y": 280 - }, - { - "id": "9e21108d47dd29fe", - "type": "change", - "z": "c19dee9f.e72838", - "name": "Brightness to 100%", - "wires": [ - [ - "28b5f90c956f8589" - ] - ], - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"brightness_pct\":100}", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1310, - "y": 200 - }, - { - "id": "da8f36cbc0df2e8c", - "type": "change", - "z": "c19dee9f.e72838", - "name": "Brightness to 65%", - "wires": [ - [ - "28b5f90c956f8589" - ] - ], - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"brightness_pct\":65}", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1310, - "y": 240 - }, - { - "id": "1e4d5008dcd7fb69", - "type": "change", - "z": "c19dee9f.e72838", - "name": "Flash at brightness 100%", - "wires": [ - [ - "28b5f90c956f8589" - ] - ], - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"brightness_pct\":100,\"flash\":\"short\"}", - "tot": "str" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1350, - "y": 600 - }, - { - "id": "4b6861fef07dcf9c", - "type": "trigger", - "z": "c19dee9f.e72838", - "name": "Trigger 4:30min for flash", - "wires": [ - [ - "1e4d5008dcd7fb69" - ] - ], - "op1": "", - "op2": "offf", - "op1type": "nul", - "op2type": "str", - "duration": "270", - "extend": true, - "overrideDelay": false, - "units": "s", - "reset": "", - "bytopic": "all", - "topic": "topic", - "outputs": 1, - "x": 710, - "y": 560 - }, - { - "id": "cb510a92532ea7f5", - "type": "trigger", - "z": "c19dee9f.e72838", - "name": "Trigger 5:00 min for off", - "wires": [ - [ - "492a8c0fafdb95c0" - ] - ], - "op1": "", - "op2": "offf", - "op1type": "nul", - "op2type": "str", - "duration": "300", - "extend": true, - "overrideDelay": false, - "units": "s", - "reset": "", - "bytopic": "all", - "topic": "topic", - "outputs": 1, - "x": 700, - "y": 520 - }, - { - "id": "hllw_sw_onhold_01", - "type": "switch", - "z": "c19dee9f.e72838", - "name": "On hold", - "wires": [ - [ - "9e21108d47dd29fe" - ], - [ - "dcd933bc4929181e" - ] - ], - "property": "payload", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "on_hold", - "vt": "str" - }, - { - "t": "eq", - "v": "off_hold", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 460, - "y": 140 - }, - { - "id": "hllw_sw_brup_01", - "type": "switch", - "z": "c19dee9f.e72838", - "name": "Brightness check - Up press/hold", - "wires": [ - [ - "hllw_sw_inc_01" - ], - [ - "hllw_sw_inc_01" - ] - ], - "property": "payload", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "up_press", - "vt": "str" - }, - { - "t": "eq", - "v": "up_hold", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 540, - "y": 60 - }, - { - "id": "hllw_sw_brdn_01", - "type": "switch", - "z": "c19dee9f.e72838", - "name": "Brightness check - Down press/hold", - "wires": [ - [ - "hllw_sw_dec_01" - ], - [ - "hllw_sw_dec_01" - ] - ], - "property": "payload", - "propertyType": "msg", - "rules": [ - { - "t": "eq", - "v": "down_press", - "vt": "str" - }, - { - "t": "eq", - "v": "down_hold", - "vt": "str" - } - ], - "checkall": "true", - "repair": false, - "outputs": 2, - "x": 540, - "y": 100 - }, - { - "id": "hllw_sw_inc_01", - "type": "change", - "z": "c19dee9f.e72838", - "name": "Brightness increase (smooth)", - "wires": [ - [ - "28b5f90c956f8589" - ] - ], - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"brightness_step\":15,\"transition\":0.8}", - "tot": "json" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1320, - "y": 60 - }, - { - "id": "hllw_sw_dec_01", - "type": "change", - "z": "c19dee9f.e72838", - "name": "Brightness decrease (smooth)", - "wires": [ - [ - "28b5f90c956f8589" - ] - ], - "rules": [ - { - "t": "set", - "p": "payload", - "pt": "msg", - "to": "{\"brightness_step\":-15,\"transition\":0.8}", - "tot": "json" - } - ], - "action": "", - "property": "", - "from": "", - "to": "", - "reg": false, - "x": 1330, - "y": 100 - }, - { - "id": "hllw_sw_dbg_01", - "type": "debug", - "z": "c19dee9f.e72838", - "name": "Hallway Switch Debug", - "wires": [], - "active": false, - "tosidebar": true, - "console": false, - "tostatus": false, - "complete": "payload", - "targetType": "msg", - "statusVal": "", - "statusType": "auto", - "x": 180, - "y": 200 - }, - { - "id": "hllw_goodbye_comment_01", - "type": "comment", - "z": "c19dee9f.e72838", - "name": "Goodbye button", - "wires": [], - "info": "", - "x": 140, - "y": 660 - }, - { - "id": "hllw_goodbye_trigger_01", - "type": "server-state-changed", - "z": "c19dee9f.e72838", - "name": "Goodbye button", - "wires": [ - [ - "hllw_goodbye_espresso_01", - "hllw_goodbye_harmony_01", - "hllw_goodbye_heos_01", - "hllw_goodbye_lights_01" - ] - ], - "server": "657c7463.48e1e4", - "version": 6, - "outputs": 1, - "exposeAsEntityConfig": "", - "entities": { - "entity": [ - "sensor.goodbye_button_action" - ], - "substring": [], - "regex": [] - }, - "outputInitially": false, - "stateType": "str", - "ifState": "", - "ifStateType": "str", - "ifStateOperator": "is", - "outputOnlyOnStateChange": true, - "for": 0, - "forType": "num", - "forUnits": "minutes", - "ignorePrevStateNull": false, - "ignorePrevStateUnknown": false, - "ignorePrevStateUnavailable": false, - "ignoreCurrentStateUnknown": false, - "ignoreCurrentStateUnavailable": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "eventData" - }, - { - "property": "topic", - "propertyType": "msg", - "value": "", - "valueType": "triggerId" - } - ], - "x": 140, - "y": 700 - }, - { - "id": "hllw_goodbye_espresso_01", - "type": "api-call-service", - "z": "c19dee9f.e72838", - "name": "Espresso off", - "wires": [ - [] - ], - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "switch.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "switch.espresso_kitchen" - ], - "labelId": [], - "data": "", - "dataType": "jsonata", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "switch", - "service": "turn_off", - "x": 510, - "y": 700 - }, - { - "id": "hllw_goodbye_harmony_01", - "type": "api-call-service", - "z": "c19dee9f.e72838", - "name": "Harmony off", - "wires": [ - [] - ], - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "remote.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "remote.living_room" - ], - "labelId": [], - "data": "", - "dataType": "jsonata", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "remote", - "service": "turn_off", - "x": 510, - "y": 740 - }, - { - "id": "hllw_goodbye_heos_01", - "type": "api-call-service", - "z": "c19dee9f.e72838", - "name": "HEOS pause", - "wires": [ - [] - ], - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "media_player.media_pause", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "media_player.bathroom", - "media_player.bedroom", - "media_player.kitchen" - ], - "labelId": [], - "data": "", - "dataType": "jsonata", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "media_player", - "service": "media_pause", - "x": 510, - "y": 780 - }, - { - "id": "hllw_goodbye_lights_01", - "type": "api-call-service", - "z": "c19dee9f.e72838", - "name": "Lights off (LR/BR/Bath)", - "wires": [ - [] - ], - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "light.turn_off", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [ - "light.living_room", - "light.bedroom", - "light.bathroom" - ], - "labelId": [], - "data": "", - "dataType": "jsonata", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "light", - "service": "turn_off", + "override_topic": false, + "state_location": "payload", + "override_payload": "msg", + "entity_location": "data", + "override_data": "msg", "x": 550, - "y": 820 + "y": 500, + "wires": [ + [], + [ + "ca7ee0d8f3f6d02e" + ] + ] }, { - "id": "hllw_br_state_01", + "id": "guest_lr_check_03", "type": "api-current-state", - "z": "c19dee9f.e72838", - "name": "Bedroom ceiling brightness", - "wires": [ - [ - "hllw_br_switch_01" - ] - ], + "z": "b70ee13eafa73823", + "name": "Guest in living room?", "server": "657c7463.48e1e4", "version": 3, - "outputs": 1, - "halt_if": "", + "outputs": 2, + "halt_if": "on", "halt_if_type": "str", "halt_if_compare": "is", - "entity_id": "light.bedroom_main", + "entity_id": "input_boolean.guest_bedroom", "state_type": "str", "blockInputOverrides": false, - "outputProperties": [ - { - "property": "payload", - "propertyType": "msg", - "value": "", - "valueType": "entityState" - }, - { - "property": "data", - "propertyType": "msg", - "value": "", - "valueType": "entity" - } - ], + "outputProperties": [], "for": 0, "forType": "num", "forUnits": "minutes", - "x": 1340, - "y": 400 - }, - { - "id": "hllw_br_switch_01", - "type": "switch", - "z": "c19dee9f.e72838", - "name": "Bedroom brightness > 50%?", + "override_topic": false, + "state_location": "payload", + "override_payload": "msg", + "entity_location": "data", + "override_data": "msg", + "x": 680, + "y": 1440, "wires": [ [ - "da8f36cbc0df2e8c" + "lr_media_acs_01" ], - [ - "dcd933bc4929181e" - ] - ], - "property": "data.attributes.brightness", - "propertyType": "msg", - "rules": [ - { - "t": "gt", - "v": "128", - "vt": "num" - }, - { - "t": "else" - } - ], - "checkall": "false", - "repair": false, - "outputs": 2, - "x": 1340, - "y": 440 - }, - { - "id": "d62ce1b52df12205", - "type": "comment", - "z": "c19dee9f.e72838", - "name": "When bedroom is lit - use more brightness", - "wires": [], - "info": "", - "x": 1380, - "y": 360 - }, - { - "id": "p2catch_hal", - "type": "catch", - "z": "c19dee9f.e72838", - "name": "Catch all errors", - "wires": [ - [ - "p2fmt_hal" - ] - ], - "scope": null, - "uncaught": false, - "x": 160, - "y": 1020 - }, - { - "id": "p2fmt_hal", - "type": "function", - "z": "c19dee9f.e72838", - "name": "Format error", - "wires": [ - [ - "p2ntfy_hal" - ] - ], - "func": "const err = (msg.error && msg.error.message) ? msg.error.message : String(msg.payload || 'Unknown error');\nconst src = (msg.error && msg.error.source) ? (msg.error.source.name || msg.error.source.id || '') : '';\nmsg.payload = JSON.stringify({\n title: 'Node-RED Error: Hallway',\n message: err + (src ? '\\n\\nNode: ' + src : '')\n});\nreturn msg;", - "outputs": 1, - "timeout": "", - "noerr": 0, - "initialize": "", - "finalize": "", - "libs": [], - "x": 400, - "y": 1020 - }, - { - "id": "p2ntfy_hal", - "type": "api-call-service", - "z": "c19dee9f.e72838", - "name": "Notify error", - "wires": [ [] - ], - "server": "657c7463.48e1e4", - "version": 7, - "debugenabled": false, - "action": "notify.gotify_ha", - "floorId": [], - "areaId": [], - "deviceId": [], - "entityId": [], - "labelId": [], - "data": "{{{payload}}}", - "dataType": "json", - "mergeContext": "", - "mustacheAltTags": false, - "outputProperties": [], - "queue": "none", - "blockInputOverrides": false, - "domain": "notify", - "service": "gotify_ha", - "output_location": "", - "output_location_type": "none", - "x": 660, - "y": 1020 + ] }, { - "id": "62ed34c9191cebca", - "type": "ha-entity-config", - "name": "Kitchen Motion Sensor Flow", - "server": "657c7463.48e1e4", - "deviceConfig": "", - "version": "6", - "entityType": "switch", - "haConfig": [ - { - "property": "name", - "value": "kitchen_motion_sensor_flow" - }, - { - "property": "icon", - "value": "" - }, - { - "property": "entity_picture", - "value": "" - }, - { - "property": "entity_category", - "value": "" - }, - { - "property": "device_class", - "value": "" - } - ], - "resend": false, - "debugEnabled": false - }, - { - "id": "d51b5899.a2d5d8", - "type": "mqtt-broker", - "name": "Mosquto Broker", - "d": true, - "broker": "192.168.1.6", - "port": "1883", - "clientid": "", - "autoConnect": true, - "usetls": false, - "compatmode": false, - "protocolVersion": "4", - "keepalive": "60", - "cleansession": true, - "autoUnsubscribe": true, - "birthTopic": "", - "birthQos": "0", - "birthPayload": "", - "birthMsg": {}, - "closeTopic": "", - "closeQos": "0", - "closePayload": "", - "closeMsg": {}, - "willTopic": "", - "willQos": "0", - "willPayload": "", - "willMsg": {}, - "userProps": "", - "sessionExpiry": "" - }, - { - "id": "cc000023", - "type": "ha-entity-config", - "z": "bbf25964.5edb38", - "name": "CC Delivery Date", - "server": "657c7463.48e1e4", - "deviceConfig": "", - "version": "6", - "entityType": "sensor", - "haConfig": [ - { - "property": "name", - "value": "cc_next_delivery_date" - }, - { - "property": "icon", - "value": "mdi:calendar" - }, - { - "property": "entity_picture", - "value": "" - }, - { - "property": "entity_category", - "value": "" - }, - { - "property": "device_class", - "value": "" - } - ], - "resend": false, - "debugEnabled": false - }, - { - "id": "cc000025", - "type": "ha-entity-config", - "z": "bbf25964.5edb38", - "name": "CC Delivery Total", - "server": "657c7463.48e1e4", - "deviceConfig": "", - "version": "6", - "entityType": "sensor", - "haConfig": [ - { - "property": "name", - "value": "cc_next_delivery_total" - }, - { - "property": "icon", - "value": "mdi:currency-eur" - }, - { - "property": "entity_picture", - "value": "" - }, - { - "property": "entity_category", - "value": "" - }, - { - "property": "device_class", - "value": "" - } - ], - "resend": false, - "debugEnabled": false - }, - { - "id": "cc000026", - "type": "ha-entity-config", - "z": "bbf25964.5edb38", - "name": "CC Send Now Button", - "server": "657c7463.48e1e4", - "deviceConfig": "", - "version": "6", - "entityType": "button", - "haConfig": [ - { - "property": "name", - "value": "cc_send_now" - }, - { - "property": "icon", - "value": "mdi:send" - }, - { - "property": "entity_picture", - "value": "" - }, - { - "property": "entity_category", - "value": "" - }, - { - "property": "device_class", - "value": "" - } - ], - "resend": false, - "debugEnabled": false - }, - { - "id": "cc000027", - "type": "ha-entity-config", - "z": "bbf25964.5edb38", - "name": "CC Postpone 1 Week", - "server": "657c7463.48e1e4", - "deviceConfig": "", - "version": "6", - "entityType": "button", - "haConfig": [ - { - "property": "name", - "value": "cc_postpone_one_week" - }, - { - "property": "icon", - "value": "mdi:calendar-plus" - }, - { - "property": "entity_picture", - "value": "" - }, - { - "property": "entity_category", - "value": "" - }, - { - "property": "device_class", - "value": "" - } - ], - "resend": false, - "debugEnabled": false - }, - { - "id": "cc000024", - "type": "ha-entity-config", - "z": "bbf25964.5edb38", - "name": "CC Delivery Product", - "server": "657c7463.48e1e4", - "deviceConfig": "", - "version": "6", - "entityType": "sensor", - "haConfig": [ - { - "property": "name", - "value": "cc_next_delivery_product" - }, - { - "property": "icon", - "value": "mdi:coffee" - }, - { - "property": "entity_picture", - "value": "" - }, - { - "property": "entity_category", - "value": "" - }, - { - "property": "device_class", - "value": "" - } - ], - "resend": false, - "debugEnabled": false + "id": "ca67d1c08c39caec", + "type": "comment", + "z": "b70ee13eafa73823", + "name": "Livingroom tap-dial music control", + "info": "", + "x": 210, + "y": 1740, + "wires": [] } ] \ No newline at end of file