Vacation Mode

Four steps to adding a vacation mode to your home and having lights turn on and off at random intervals. It also automatically prompts you with a notification about turning on vacation mode if you have been gone longer than 24 hours.

screenshot

Full Export

[{"id":"eb756b3f.d770f8","type":"subflow","name":"Create HA Helpers","info":"","category":"","in":[{"x":84,"y":96,"wires":[{"id":"7f1493fc.1300fc"}]}],"out":[],"env":[{"name":"serverName","type":"str","value":"Home Assistant","ui":{"label":{"en-US":"HA Server Name"},"type":"input","opts":{"types":["str"]}}},{"name":"helpers","type":"json","value":"[]","ui":{"label":{"en-US":"Helpers"},"type":"input","opts":{"types":["json"]}}}],"color":"#DDAA99","status":{"x":246,"y":48,"wires":[{"id":"a66d5d93.8a5f","port":0}]}},{"id":"7f1493fc.1300fc","type":"function","z":"eb756b3f.d770f8","name":"process helpers","func":"const serverName = toCamelCase(env.get('serverName'));\nconst haServer = global.get(\"homeassistant\")[serverName];\nif(!haServer) {\n    node.error(\"Invalid HA server name\");\n    return;\n}\nconst states = haServer.states;\nconst helpers = env.get(\"helpers\");\n\nhelpers.forEach(h => {\n    const entityId = `${h.type}.${h.id}`;\n    if(!states[entityId]) {\n        const {id, type, ...data} = h;\n        const apiData = {\n            entity: h,\n            payload: { \n                data \n            }\n        };\n        apiData.payload.data.type = `${type}/create`;\n    \n        node.send(apiData);\n        node.status({text: `Creating ${entityId}`});\n    }\n});\n\nnode.done();\n\nfunction toCamelCase(str) {\n    return str.replace(/(?:^\\w|[A-Z]|\\b\\w|\\s+)/g, (match, index) => {\n        if (+match === 0) return '';\n        return index === 0 ? match.toLowerCase() : match.toUpperCase();\n    });\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","x":224,"y":96,"wires":[["a4a0abd9.7576d8"]]},{"id":"a4a0abd9.7576d8","type":"ha-api","z":"eb756b3f.d770f8","name":"create helper","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"","dataType":"json","location":"payload","locationType":"msg","responseType":"json","x":390,"y":96,"wires":[["b76d0c56.d54b9"]]},{"id":"388bb5c7.47346a","type":"ha-api","z":"eb756b3f.d770f8","name":"rename helper entity id","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\t   \"type\":\"config/entity_registry/update\",\t   \"entity_id\": entity.type & \".\" & payload.id,\t   \"new_entity_id\": entity.type & \".\" & entity.id\t}","dataType":"jsonata","location":"payload","locationType":"msg","responseType":"json","x":788,"y":96,"wires":[[]]},{"id":"b76d0c56.d54b9","type":"switch","z":"eb756b3f.d770f8","name":"need to rename?","property":"payload.id","propertyType":"msg","rules":[{"t":"neq","v":"entity.id","vt":"msg"}],"checkall":"true","repair":false,"outputs":1,"x":570,"y":96,"wires":[["388bb5c7.47346a","3e47440a.eee2cc"]]},{"id":"a66d5d93.8a5f","type":"status","z":"eb756b3f.d770f8","name":"","scope":["7f1493fc.1300fc","3e47440a.eee2cc"],"x":124,"y":48,"wires":[[]]},{"id":"3e47440a.eee2cc","type":"function","z":"eb756b3f.d770f8","name":"rename status","func":"const oldEntityId = `${msg.entity.type}.${msg.payload.id}`;\nconst newEntityId = `${msg.entity.type}.${msg.entity.id}`;\n\nnode.status({text: `Renaming ${oldEntityId} to ${newEntityId}`});","outputs":1,"noerr":0,"initialize":"","finalize":"","x":768,"y":144,"wires":[[]]},{"id":"fda663f6.59a56","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"e9b697a.fc03268"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"57c0c58d.ffa1bc","port":0}]},{"x":1172,"y":176,"wires":[{"id":"57c0c58d.ffa1bc","port":1}]},{"x":1172,"y":224,"wires":[{"id":"57c0c58d.ffa1bc","port":2}]},{"x":964,"y":240,"wires":[{"id":"c3389099.bc489","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"d847d277.d448c","port":0}]}},{"id":"b4512e6b.640d9","type":"function","z":"fda663f6.59a56","name":"create service call","func":"const actions = [];\n[1,2,3].forEach(i => {\n    const name = `action${i}`\n    const id = flow.get(`${name}Id`);\n    const title = env.get(`${name}Title`);\n    const uri = env.get(`${name}Uri`);\n    const action = uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\n    \n    actions.push({\n        action,\n        title,\n        uri\n    });\n});\n\nmsg._originalPayload = msg.payload;\nflow.set('latestMessage', msg);\n\nconst services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            title: env.get('title'),\n            message: env.get('message'),\n            data: {\n                tag: flow.get('notificationTag'),\n                actions,\n                color: env.get(\"color\"),\n                group: env.get(\"group\"),\n                sticky: env.get(\"sticky\"),\n                timeout: env.get(\"timeout\"),\n                icon: env.get(\"icon\")\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\n\n[1,2,3].forEach(i => {\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\n})\n\n\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["7a427ca2.c030e4"]]},{"id":"57c0c58d.ffa1bc","type":"switch","z":"fda663f6.59a56","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"d847d277.d448c","type":"status","z":"fda663f6.59a56","name":"","scope":["b4512e6b.640d9","c3389099.bc489","7955d8e6.b10888","7a427ca2.c030e4"],"x":124,"y":272,"wires":[[]]},{"id":"c3389099.bc489","type":"function","z":"fda663f6.59a56","name":"build message","func":"const latestMessage = flow.get('latestMessage');\nconst event = msg.payload.event;\n\nlatestMessage.eventData = msg.payload;\nlatestMessage.payload = latestMessage._originalPayload;\ndelete latestMessage._originalPayload;\n\nif(env.get('userInfo')) {\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\n    latestMessage.userData = userData;\n}\n\nif(msg.event_type === 'mobile_app_notification_cleared') {\n    node.status({\n        text: `cleared at: ${getPrettyDate()}`,\n        shape: 'dot',\n        fill: 'blue'\n    });\n    \n    return [null, latestMessage];\n}\n\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\nnode.status({\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\n    shape: 'dot',\n    fill: 'green'\n});\n\nreturn latestMessage;\n\n\nfunction getPrettyDate() {\n    return new Date().toLocaleDateString('en-US', {\n        month: 'short',\n        day: 'numeric',\n        hour12: false,\n        hour: 'numeric',\n        minute: 'numeric',\n    });\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["57c0c58d.ffa1bc"],[]]},{"id":"f814cdc6.def07","type":"switch","z":"fda663f6.59a56","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["4db9b8d.0c14a48"]]},{"id":"7596669d.feb668","type":"ha-api","z":"fda663f6.59a56","name":"get user info","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/auth/list\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["c3389099.bc489"]]},{"id":"b745e475.d6cdf8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_cleared","server":"","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["f814cdc6.def07"]]},{"id":"4db9b8d.0c14a48","type":"switch","z":"fda663f6.59a56","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["7596669d.feb668"],["c3389099.bc489"]]},{"id":"e9b697a.fc03268","type":"switch","z":"fda663f6.59a56","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["b4512e6b.640d9"],["7955d8e6.b10888"]],"l":false},{"id":"7955d8e6.b10888","type":"function","z":"fda663f6.59a56","name":"create clear notification","func":"const services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            message: \"clear_notification\",\n            data: {\n                tag: flow.get('notificationTag'),\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["7a427ca2.c030e4"]]},{"id":"520a884c.35f9c8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_action","server":"","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["f814cdc6.def07"]]},{"id":"7a427ca2.c030e4","type":"api-call-service","z":"fda663f6.59a56","name":"","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"aa02fa4a.a35548","type":"inject","z":"9530fd91.600e2","name":"","repeat":"","crontab":"*/6 16-23 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":118,"y":336,"wires":[["7e966ac8.609524"]]},{"id":"cfa1b8e4.8d4a08","type":"time-range-switch","z":"9530fd91.600e2","name":"","startTime":"sunset","endTime":"23:59","startOffset":0,"endOffset":0,"x":496,"y":336,"wires":[["c7efc558.da1bc8"],[]]},{"id":"a41f4d83.d45c4","type":"ha-get-entities","z":"9530fd91.600e2","server":"","name":"","rules":[{"property":"entity_id","logic":"in_group","value":"group.vacation_lights","valueType":"str"},{"property":"state","logic":"is","value":"off","valueType":"str"}],"output_type":"random","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":806,"y":336,"wires":[["f3897d20.fffee"]]},{"id":"c7efc558.da1bc8","type":"function","z":"9530fd91.600e2","name":"25%","func":"const random = Math.round(Math.random() * 100);\n\nif(random < 75) {\n    node.status({fill: \"red\", text: random});\n    return;\n}\n\nnode.status({fill: \"green\", text: random});\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":658,"y":336,"wires":[["a41f4d83.d45c4"]]},{"id":"f3897d20.fffee","type":"api-call-service","z":"9530fd91.600e2","name":"turn on","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_on","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":956,"y":336,"wires":[["20fce293.98ce8e"]]},{"id":"20fce293.98ce8e","type":"delay","z":"9530fd91.600e2","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"5","randomLast":"36","randomUnits":"minutes","drop":false,"x":1100,"y":336,"wires":[["3d851328.fb1b8c"]]},{"id":"3d851328.fb1b8c","type":"api-call-service","z":"9530fd91.600e2","name":"turn off","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_off","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1234,"y":336,"wires":[[]]},{"id":"7e966ac8.609524","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is_not","override_topic":true,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":298,"y":336,"wires":[[],["cfa1b8e4.8d4a08"]]},{"id":"22f34ec4.9d3a22","type":"comment","z":"9530fd91.600e2","name":"Vacation Lights","info":"","x":112,"y":288,"wires":[]},{"id":"7003285c.a3a8c8","type":"api-call-service","z":"9530fd91.600e2","name":"turn on vacation mode","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":788,"y":192,"wires":[["4971bda0.0758f4"]]},{"id":"4971bda0.0758f4","type":"api-call-service","z":"9530fd91.600e2","name":"notify jason","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_jason","entityId":"","data":"{\"title\":\"Vacation Mode\",\"message\":\"Vacation Mode has been enabled.\"}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":982,"y":192,"wires":[[]]},{"id":"bf80cebf.58bcc","type":"server-state-changed","z":"9530fd91.600e2","name":"home/away","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person.jason","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"home","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"for":"1","forType":"num","forUnits":"days","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":102,"y":192,"wires":[["7d414deb.904f64"],["c81cbf7d.abe22"]]},{"id":"c81cbf7d.abe22","type":"api-call-service","z":"9530fd91.600e2","name":"vacation mode off","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":314,"y":240,"wires":[[]]},{"id":"7d414deb.904f64","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":314,"y":192,"wires":[["dca703ed.f3222"],[]]},{"id":"dca703ed.f3222","type":"subflow:fda663f6.59a56","z":"9530fd91.600e2","name":"turn on vacation mode?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Vacation Mode","type":"str"},{"name":"message","value":"You've been aways for 24 hours. Do you want to turn on vacation mode?","type":"str"},{"name":"action1Title","value":"Yes","type":"str"},{"name":"action2Title","value":"No","type":"str"},{"name":"group","value":"","type":"str"}],"x":542,"y":208,"wires":[["7003285c.a3a8c8"],[],[],[]]},{"id":"d4a03a04.6c78f8","type":"subflow:eb756b3f.d770f8","z":"9530fd91.600e2","name":"create input_boolean","env":[{"name":"helpers","value":"[{\"id\":\"vacation_mode\",\"type\":\"input_boolean\",\"name\":\"Vacation Mode\",\"icon\":\"mdi:beach\"}]","type":"json"}],"x":292,"y":96,"wires":[]},{"id":"f3d6f382.70bfe","type":"inject","z":"9530fd91.600e2","name":"Click me to","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":108,"y":96,"wires":[["d4a03a04.6c78f8"]]},{"id":"4a22094b.635368","type":"comment","z":"9530fd91.600e2","name":"Setup","info":"","x":82,"y":48,"wires":[]},{"id":"7ce57cf8.cad134","type":"comment","z":"9530fd91.600e2","name":"Actionable notification to turn on vacation mode","info":"","x":212,"y":144,"wires":[]}]

Step 1

Create an input boolean in Home Assistant that will control if the house is in vacation mode.

screenshot

or via the helpers menu in the Home Assistant UI or add it manually in YAML

input_boolean:
  vacation_mode:
    name: Vacation Mode
    icon: mdi:beach

Step 2

Create a flow that will automatically change the vacation mode to off if we come home. Secondly will send our phone an actionable notification for android asking if we want to turn on vacation mode if we have been gone longer than 24 hours.

screenshot

[{"id":"fda663f6.59a56","type":"subflow","name":"Actionable Notification","info":"[Documentation](https://zachowj.github.io/node-red-contrib-home-assistant-websocket/cookbook/actionable-notifications-subflow-for-android.html)\n","category":"","in":[{"x":84,"y":80,"wires":[{"id":"e9b697a.fc03268"}]}],"out":[{"x":1172,"y":128,"wires":[{"id":"57c0c58d.ffa1bc","port":0}]},{"x":1172,"y":176,"wires":[{"id":"57c0c58d.ffa1bc","port":1}]},{"x":1172,"y":224,"wires":[{"id":"57c0c58d.ffa1bc","port":2}]},{"x":964,"y":240,"wires":[{"id":"c3389099.bc489","port":1}]}],"env":[{"name":"service","type":"str","value":"","ui":{"label":{"en-US":"Notify Service"},"type":"input","opts":{"types":["str"]}}},{"name":"title","type":"str","value":"","ui":{"label":{"en-US":"Title"},"type":"input","opts":{"types":["str"]}}},{"name":"message","type":"str","value":"","ui":{"label":{"en-US":"Message"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Title","type":"str","value":"","ui":{"label":{"en-US":"Action 1 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action1Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 1 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Title","type":"str","value":"","ui":{"label":{"en-US":"Action 2 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action2Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 2 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Title","type":"str","value":"","ui":{"label":{"en-US":"Action 3 Title"},"type":"input","opts":{"types":["str"]}}},{"name":"action3Uri","type":"str","value":"","ui":{"label":{"en-US":"Action 3 URI (optional)"},"type":"input","opts":{"types":["str"]}}},{"name":"userInfo","type":"bool","value":"false","ui":{"label":{"en-US":"Populate User Information"},"type":"checkbox"}},{"name":"sticky","type":"bool","value":"false","ui":{"label":{"en-US":"Sticky"},"type":"checkbox"}},{"name":"group","type":"str","value":"None","ui":{"label":{"en-US":"Group"},"type":"select","opts":{"opts":[{"l":{"en-US":"None"},"v":""},{"l":{"en-US":"Cameras"},"v":"camera"},{"l":{"en-US":"Security"},"v":"security"},{"l":{"en-US":"Garage"},"v":"garage"},{"l":{"en-US":"Laundry Room"},"v":"laundry_room"}]}}},{"name":"color","type":"str","value":"","ui":{"label":{"en-US":"Color"},"type":"input","opts":{"types":["str"]}}},{"name":"timeout","type":"num","value":"","ui":{"label":{"en-US":"Timeout"},"type":"input","opts":{"types":["num"]}}},{"name":"icon","type":"str","value":"","ui":{"label":{"en-US":"Icon"},"type":"input","opts":{"types":["str"]}}}],"color":"#DDAA99","outputLabels":["Action 1","Action 2","Action 3","Cleared"],"status":{"x":244,"y":272,"wires":[{"id":"d847d277.d448c","port":0}]}},{"id":"b4512e6b.640d9","type":"function","z":"fda663f6.59a56","name":"create service call","func":"const actions = [];\n[1,2,3].forEach(i => {\n    const name = `action${i}`\n    const id = flow.get(`${name}Id`);\n    const title = env.get(`${name}Title`);\n    const uri = env.get(`${name}Uri`);\n    const action = uri.length ? 'URI' : title ? flow.get(`${name}Id`) : undefined;\n    \n    actions.push({\n        action,\n        title,\n        uri\n    });\n});\n\nmsg._originalPayload = msg.payload;\nflow.set('latestMessage', msg);\n\nconst services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            title: env.get('title'),\n            message: env.get('message'),\n            data: {\n                tag: flow.get('notificationTag'),\n                actions,\n                color: env.get(\"color\"),\n                group: env.get(\"group\"),\n                sticky: env.get(\"sticky\"),\n                timeout: env.get(\"timeout\"),\n                icon: env.get(\"icon\")\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"const randomId = () => Math.random().toString(36).replace(/[^a-z]+/g, '').substr(0, 5);\n\n[1,2,3].forEach(i => {\n    flow.set(`action${i}Id`, `action${i}_${randomId()}`);\n})\n\n\nflow.set('notificationTag', `${env.get('title')}_${randomId()}`);","finalize":"","x":298,"y":80,"wires":[["7a427ca2.c030e4"]]},{"id":"57c0c58d.ffa1bc","type":"switch","z":"fda663f6.59a56","name":"which action?","property":"eventData.event.action","propertyType":"msg","rules":[{"t":"eq","v":"action1Id","vt":"flow"},{"t":"eq","v":"action2Id","vt":"flow"},{"t":"eq","v":"action3Id","vt":"flow"}],"checkall":"true","repair":false,"outputs":3,"x":1024,"y":176,"wires":[[],[],[]]},{"id":"d847d277.d448c","type":"status","z":"fda663f6.59a56","name":"","scope":["b4512e6b.640d9","c3389099.bc489","7955d8e6.b10888","7a427ca2.c030e4"],"x":124,"y":272,"wires":[[]]},{"id":"c3389099.bc489","type":"function","z":"fda663f6.59a56","name":"build message","func":"const latestMessage = flow.get('latestMessage');\nconst event = msg.payload.event;\n\nlatestMessage.eventData = msg.payload;\nlatestMessage.payload = latestMessage._originalPayload;\ndelete latestMessage._originalPayload;\n\nif(env.get('userInfo')) {\n    const userData = msg.userData.find(u => u.id === msg.payload.context.user_id);\n    latestMessage.userData = userData;\n}\n\nif(msg.event_type === 'mobile_app_notification_cleared') {\n    node.status({\n        text: `cleared at: ${getPrettyDate()}`,\n        shape: 'dot',\n        fill: 'blue'\n    });\n    \n    return [null, latestMessage];\n}\n\nconst index = [1,2,3].find(i => event[`action_${i}_key`] === event.action);\nnode.status({\n    text: `${event[`action_${index}_title`]} at: ${getPrettyDate()}`,\n    shape: 'dot',\n    fill: 'green'\n});\n\nreturn latestMessage;\n\n\nfunction getPrettyDate() {\n    return new Date().toLocaleDateString('en-US', {\n        month: 'short',\n        day: 'numeric',\n        hour12: false,\n        hour: 'numeric',\n        minute: 'numeric',\n    });\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":832,"y":176,"wires":[["57c0c58d.ffa1bc"],[]]},{"id":"f814cdc6.def07","type":"switch","z":"fda663f6.59a56","name":"belongs here?","property":"payload.event.tag","propertyType":"msg","rules":[{"t":"eq","v":"notificationTag","vt":"flow"}],"checkall":"true","repair":false,"outputs":1,"x":432,"y":176,"wires":[["4db9b8d.0c14a48"]]},{"id":"7596669d.feb668","type":"ha-api","z":"fda663f6.59a56","name":"get user info","server":"","debugenabled":false,"protocol":"websocket","method":"get","path":"","data":"{\"type\": \"config/auth/list\"}","dataType":"json","location":"userData","locationType":"msg","responseType":"json","x":822,"y":128,"wires":[["c3389099.bc489"]]},{"id":"b745e475.d6cdf8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_cleared","server":"","event_type":"mobile_app_notification_cleared","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":224,"wires":[["f814cdc6.def07"]]},{"id":"4db9b8d.0c14a48","type":"switch","z":"fda663f6.59a56","name":"fetch user info?","property":"userInfo","propertyType":"env","rules":[{"t":"true"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":624,"y":176,"wires":[["7596669d.feb668"],["c3389099.bc489"]]},{"id":"e9b697a.fc03268","type":"switch","z":"fda663f6.59a56","name":"","property":"clear_notification","propertyType":"msg","rules":[{"t":"null"},{"t":"nnull"}],"checkall":"true","repair":false,"outputs":2,"x":143,"y":80,"wires":[["b4512e6b.640d9"],["7955d8e6.b10888"]],"l":false},{"id":"7955d8e6.b10888","type":"function","z":"fda663f6.59a56","name":"create clear notification","func":"const services = env.get('service');\nif(!services) {\n    node.status({\n        text: 'no services defined',\n        shape: 'ring',\n        fill: 'red'\n    });\n    return;    \n}\n\nservices.trim().split(/,\\s*/).forEach(service => {\n    if(!service) return;\n    \n    msg.payload = {\n        service,\n        data: {\n            message: \"clear_notification\",\n            data: {\n                tag: flow.get('notificationTag'),\n            }\n        }\n    };\n    node.send(msg);\n});\n\nnode.done();","outputs":1,"noerr":0,"initialize":"","finalize":"","x":318,"y":128,"wires":[["7a427ca2.c030e4"]]},{"id":"520a884c.35f9c8","type":"server-events","z":"fda663f6.59a56","name":"mobile_app_notification_action","server":"","event_type":"mobile_app_notification_action","exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"waitForRunning":false,"x":194,"y":176,"wires":[["f814cdc6.def07"]]},{"id":"7a427ca2.c030e4","type":"api-call-service","z":"fda663f6.59a56","name":"","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"","entityId":"","data":"","dataType":"json","mergecontext":"callServiceData","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":550,"y":80,"wires":[[]]},{"id":"7003285c.a3a8c8","type":"api-call-service","z":"9530fd91.600e2","name":"turn on vacation mode","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_on","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":788,"y":192,"wires":[["4971bda0.0758f4"]]},{"id":"4971bda0.0758f4","type":"api-call-service","z":"9530fd91.600e2","name":"notify jason","server":"","version":1,"debugenabled":false,"service_domain":"notify","service":"mobile_app_jason","entityId":"","data":"{\"title\":\"Vacation Mode\",\"message\":\"Vacation Mode has been enabled.\"}","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":982,"y":192,"wires":[[]]},{"id":"bf80cebf.58bcc","type":"server-state-changed","z":"9530fd91.600e2","name":"home/away","server":"","version":1,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityidfilter":"person.jason","entityidfiltertype":"exact","outputinitially":false,"state_type":"str","haltifstate":"home","halt_if_type":"str","halt_if_compare":"is_not","outputs":2,"output_only_on_state_change":true,"for":"1","forType":"num","forUnits":"days","ignorePrevStateNull":false,"ignorePrevStateUnknown":false,"ignorePrevStateUnavailable":false,"ignoreCurrentStateUnknown":false,"ignoreCurrentStateUnavailable":false,"x":102,"y":192,"wires":[["7d414deb.904f64"],["c81cbf7d.abe22"]]},{"id":"c81cbf7d.abe22","type":"api-call-service","z":"9530fd91.600e2","name":"vacation mode off","server":"","version":1,"debugenabled":false,"service_domain":"input_boolean","service":"turn_off","entityId":"input_boolean.vacation_mode","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":314,"y":240,"wires":[[]]},{"id":"7d414deb.904f64","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"off","halt_if_type":"str","halt_if_compare":"is","override_topic":false,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":314,"y":192,"wires":[["dca703ed.f3222"],[]]},{"id":"dca703ed.f3222","type":"subflow:fda663f6.59a56","z":"9530fd91.600e2","name":"turn on vacation mode?","env":[{"name":"service","value":"mobile_app_jason","type":"str"},{"name":"title","value":"Vacation Mode","type":"str"},{"name":"message","value":"You've been aways for 24 hours. Do you want to turn on vacation mode?","type":"str"},{"name":"action1Title","value":"Yes","type":"str"},{"name":"action2Title","value":"No","type":"str"},{"name":"group","value":"","type":"str"}],"x":542,"y":208,"wires":[["7003285c.a3a8c8"],[],[],[]]},{"id":"7ce57cf8.cad134","type":"comment","z":"9530fd91.600e2","name":"Actionable notification to turn on vacation mode","info":"","x":212,"y":144,"wires":[]}]

Also See

Step 3

Set up a group of lights and switches in Home Assistant that you want to turn on and off while vacation mode is active. This can be done without creating a group in Home Assistant by modifying the get-entities node in the below flow to entity_id in light.night_light,light.kitchen,switch.bedroom_light,switch.laundry_room.

group:
  vacation_lights:
    name: Vacation Lights
    entities:
      - light.night_light
      - light.kitchen
      - switch.bedroom_light
      - switch.laundry_room

Step 4

This flow will run between sunset and midnight turning lights on and off at random intervals if vacation mode is enabled.

screenshot

[{"id":"aa02fa4a.a35548","type":"inject","z":"9530fd91.600e2","name":"","repeat":"","crontab":"*/6 16-23 * * *","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":118,"y":336,"wires":[["7e966ac8.609524"]]},{"id":"cfa1b8e4.8d4a08","type":"time-range-switch","z":"9530fd91.600e2","name":"","startTime":"sunset","endTime":"23:59","startOffset":0,"endOffset":0,"x":496,"y":336,"wires":[["c7efc558.da1bc8"],[]]},{"id":"a41f4d83.d45c4","type":"ha-get-entities","z":"9530fd91.600e2","server":"","name":"","rules":[{"property":"entity_id","logic":"in_group","value":"group.vacation_lights","valueType":"str"},{"property":"state","logic":"is","value":"off","valueType":"str"}],"output_type":"random","output_empty_results":false,"output_location_type":"msg","output_location":"payload","output_results_count":1,"x":806,"y":336,"wires":[["f3897d20.fffee"]]},{"id":"c7efc558.da1bc8","type":"function","z":"9530fd91.600e2","name":"25%","func":"const random = Math.round(Math.random() * 100);\n\nif(random < 75) {\n    node.status({fill: \"red\", text: random});\n    return;\n}\n\nnode.status({fill: \"green\", text: random});\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":658,"y":336,"wires":[["a41f4d83.d45c4"]]},{"id":"f3897d20.fffee","type":"api-call-service","z":"9530fd91.600e2","name":"turn on","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_on","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"","output_location_type":"none","mustacheAltTags":false,"x":956,"y":336,"wires":[["20fce293.98ce8e"]]},{"id":"20fce293.98ce8e","type":"delay","z":"9530fd91.600e2","name":"","pauseType":"random","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"5","randomLast":"36","randomUnits":"minutes","drop":false,"x":1100,"y":336,"wires":[["3d851328.fb1b8c"]]},{"id":"3d851328.fb1b8c","type":"api-call-service","z":"9530fd91.600e2","name":"turn off","server":"","version":1,"debugenabled":false,"service_domain":"homeassistant","service":"turn_off","entityId":"{{payload.entity_id}}","data":"","dataType":"json","mergecontext":"","output_location":"payload","output_location_type":"msg","mustacheAltTags":false,"x":1234,"y":336,"wires":[[]]},{"id":"7e966ac8.609524","type":"api-current-state","z":"9530fd91.600e2","name":"vacation mode on?","server":"","version":1,"outputs":2,"halt_if":"on","halt_if_type":"str","halt_if_compare":"is_not","override_topic":true,"entity_id":"input_boolean.vacation_mode","state_type":"str","state_location":"payload","override_payload":"msg","entity_location":"data","override_data":"msg","blockInputOverrides":false,"x":298,"y":336,"wires":[[],["cfa1b8e4.8d4a08"]]},{"id":"22f34ec4.9d3a22","type":"comment","z":"9530fd91.600e2","name":"Vacation Lights","info":"","x":112,"y":288,"wires":[]}]