Is there a definitive way to manage lighting?

I’ve explored various cookbooks and blog posts, and I have lighting automation flows in various different formats.

Switch with Timer

In this example:

  • Motion is detected for more than 5 seconds
  • Between a time range (that Time Range Switch is very useful)
  • A Switch sets a payload of either On or Off
  • On is sent to a State node which is checked
    • The appropriate lights are turned on
  • A 5 minute timer is also started
    • After 5 minutes of no motion, the lights are turned off
Switch with Timer example
[
    {
        "id": "afe16b4b6239b5ff",
        "type": "server-state-changed",
        "z": "d3a07d369eada1b3",
        "name": "Kitchen Motion",
        "server": "c195525b96cc1e8a",
        "version": 4,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "binary_sensor.kitchen_motion_motion",
        "entityidfiltertype": "exact",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "on",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 2,
        "output_only_on_state_change": true,
        "for": "5",
        "forType": "num",
        "forUnits": "seconds",
        "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": 80,
        "wires": [
            [
                "a09192b2f6cbbe67"
            ],
            []
        ]
    },
    {
        "id": "a09192b2f6cbbe67",
        "type": "time-range-switch",
        "z": "d3a07d369eada1b3",
        "name": "Sunset Start and Sunrise End",
        "lat": "53.5695493",
        "lon": "-113.4513922",
        "startTime": "sunsetStart",
        "endTime": "sunriseEnd",
        "startOffset": 0,
        "endOffset": 0,
        "x": 270,
        "y": 140,
        "wires": [
            [
                "df56e5ea0a2306ba"
            ],
            []
        ]
    },
    {
        "id": "0f8033e8f5fc3442",
        "type": "stoptimer",
        "z": "d3a07d369eada1b3",
        "duration": "5",
        "units": "Minute",
        "payloadtype": "num",
        "payloadval": "0",
        "name": "",
        "x": 600,
        "y": 140,
        "wires": [
            [
                "4ea24d15f83eeb8f"
            ],
            []
        ]
    },
    {
        "id": "df56e5ea0a2306ba",
        "type": "switch",
        "z": "d3a07d369eada1b3",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "on",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "off",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 350,
        "y": 80,
        "wires": [
            [
                "0f8033e8f5fc3442",
                "647e7d5848a1c87d"
            ],
            [
                "0f8033e8f5fc3442"
            ]
        ]
    },
    {
        "id": "647e7d5848a1c87d",
        "type": "api-current-state",
        "z": "d3a07d369eada1b3",
        "name": "Kitchen Group On",
        "server": "c195525b96cc1e8a",
        "version": 3,
        "outputs": 2,
        "halt_if": "on",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "entity_id": "switch.kitchen_group",
        "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": 610,
        "y": 80,
        "wires": [
            [],
            [
                "1699b4d474b9253b"
            ]
        ]
    },
    {
        "id": "1699b4d474b9253b",
        "type": "api-call-service",
        "z": "d3a07d369eada1b3",
        "name": "Kitchen Group On",
        "server": "c195525b96cc1e8a",
        "version": 5,
        "debugenabled": false,
        "domain": "switch",
        "service": "turn_on",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "switch.kitchen_group"
        ],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 850,
        "y": 80,
        "wires": [
            []
        ]
    },
    {
        "id": "4ea24d15f83eeb8f",
        "type": "api-call-service",
        "z": "d3a07d369eada1b3",
        "name": "Kitchen Group Off",
        "server": "c195525b96cc1e8a",
        "version": 5,
        "debugenabled": false,
        "domain": "switch",
        "service": "turn_off",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "switch.kitchen_group"
        ],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 850,
        "y": 140,
        "wires": [
            []
        ]
    },
    {
        "id": "96d627ce2bbf2f4c",
        "type": "comment",
        "z": "d3a07d369eada1b3",
        "name": "Kitchen Motion detected for 5 seconds between sunset start and sunrise end",
        "info": "",
        "x": 290,
        "y": 40,
        "wires": []
    },
    {
        "id": "f85286f19134a142",
        "type": "comment",
        "z": "d3a07d369eada1b3",
        "name": "Switch Kitchen Group on for 5 minutes, switch Kitchen Group off after 5 minutes of no motion",
        "info": "",
        "x": 900,
        "y": 40,
        "wires": []
    },
    {
        "id": "c195525b96cc1e8a",
        "type": "server",
        "name": "homeassistant.instantdreams.org",
        "version": 5,
        "addon": false,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30",
        "areaSelector": "friendlyName",
        "deviceSelector": "friendlyName",
        "entitySelector": "friendlyName",
        "statusSeparator": ": ",
        "statusYear": "hidden",
        "statusMonth": "short",
        "statusDay": "numeric",
        "statusHourCycle": "default",
        "statusTimeFormat": "h:m",
        "enableGlobalContextStore": false
    }
]

Switch with Wait Until

In this example:

  • Motion is detected for more than 5 seconds
  • Between a time range
  • A Switch sets a payload of either On or Off
  • The light is switched on
  • A wait until entity is also called
  • After 2 minutes of no motion, the light is turned off
Switch with Wait Until example
[
    {
        "id": "9e2a08f5.4634b8",
        "type": "server-state-changed",
        "z": "d3a07d369eada1b3",
        "name": "Hall Motion",
        "server": "c195525b96cc1e8a",
        "version": 4,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "binary_sensor.hall_motion_motion",
        "entityidfiltertype": "exact",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "on",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 2,
        "output_only_on_state_change": true,
        "for": "5",
        "forType": "num",
        "forUnits": "seconds",
        "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": 120,
        "y": 260,
        "wires": [
            [
                "b47ee5de757edd5b"
            ],
            []
        ]
    },
    {
        "id": "6a54b527.806bec",
        "type": "api-call-service",
        "z": "d3a07d369eada1b3",
        "name": "Hall Light On",
        "server": "c195525b96cc1e8a",
        "version": 5,
        "debugenabled": false,
        "domain": "light",
        "service": "turn_on",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "light.hall_ceiling"
        ],
        "data": "{\"brightness_pct\":1}",
        "dataType": "json",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "output_location": "",
        "output_location_type": "none",
        "x": 830,
        "y": 260,
        "wires": [
            []
        ]
    },
    {
        "id": "c066de8f.8a0e2",
        "type": "ha-wait-until",
        "z": "d3a07d369eada1b3",
        "name": "",
        "server": "c195525b96cc1e8a",
        "version": 2,
        "outputs": 2,
        "entityId": "binary_sensor.kitchen_motion_motion",
        "entityIdFilterType": "exact",
        "property": "state",
        "comparator": "is",
        "value": "on",
        "valueType": "str",
        "timeout": "2",
        "timeoutType": "num",
        "timeoutUnits": "minutes",
        "checkCurrentState": true,
        "blockInputOverrides": true,
        "outputProperties": [],
        "x": 580,
        "y": 320,
        "wires": [
            [],
            [
                "28f00104.71e9de"
            ]
        ]
    },
    {
        "id": "28f00104.71e9de",
        "type": "api-call-service",
        "z": "d3a07d369eada1b3",
        "name": "Hall Light Off",
        "server": "c195525b96cc1e8a",
        "version": 5,
        "debugenabled": false,
        "domain": "light",
        "service": "turn_off",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "light.hall_ceiling"
        ],
        "data": "",
        "dataType": "json",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "output_location": "",
        "output_location_type": "none",
        "x": 830,
        "y": 320,
        "wires": [
            []
        ]
    },
    {
        "id": "b47ee5de757edd5b",
        "type": "time-range-switch",
        "z": "d3a07d369eada1b3",
        "name": "Sunset Start and 22:30",
        "lat": "53.5695493",
        "lon": "-113.4513922",
        "startTime": "sunsetStart",
        "endTime": "22:30",
        "startOffset": 0,
        "endOffset": 0,
        "x": 250,
        "y": 320,
        "wires": [
            [
                "b2adbd1cb06dd9d0"
            ],
            []
        ]
    },
    {
        "id": "b2adbd1cb06dd9d0",
        "type": "switch",
        "z": "d3a07d369eada1b3",
        "name": "",
        "property": "payload",
        "propertyType": "msg",
        "rules": [
            {
                "t": "eq",
                "v": "on",
                "vt": "str"
            },
            {
                "t": "eq",
                "v": "off",
                "vt": "str"
            }
        ],
        "checkall": "true",
        "repair": false,
        "outputs": 2,
        "x": 350,
        "y": 260,
        "wires": [
            [
                "6a54b527.806bec",
                "c066de8f.8a0e2"
            ],
            [
                "c066de8f.8a0e2"
            ]
        ]
    },
    {
        "id": "a50ac45220029805",
        "type": "comment",
        "z": "d3a07d369eada1b3",
        "name": "Hall Motion detected for 5 seconds between dusk and dawn",
        "info": "",
        "x": 230,
        "y": 220,
        "wires": []
    },
    {
        "id": "efa5251255230901",
        "type": "comment",
        "z": "d3a07d369eada1b3",
        "name": "Switch Hall Ceiling on for 2 minutes, switch Hall Ceiling off after 2 minutes of no motion",
        "info": "",
        "x": 820,
        "y": 220,
        "wires": []
    },
    {
        "id": "c195525b96cc1e8a",
        "type": "server",
        "name": "homeassistant.instantdreams.org",
        "version": 5,
        "addon": false,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30",
        "areaSelector": "friendlyName",
        "deviceSelector": "friendlyName",
        "entitySelector": "friendlyName",
        "statusSeparator": ": ",
        "statusYear": "hidden",
        "statusMonth": "short",
        "statusDay": "numeric",
        "statusHourCycle": "default",
        "statusTimeFormat": "h:m",
        "enableGlobalContextStore": false
    }
]

Trigger

In this example:

  • Motion is detected for more than 5 seconds
  • Between a time range
  • A Trigger sends a payload of “turn_on” plus additional information to a light entity or group
  • The Trigger then waits for a set number of minutes, extending the delay if additional messages arrive
  • After the delay the Trigger sends “turn_off” to the light entity or group
Trigger example
[
    {
        "id": "41396f468be568a3",
        "type": "server-state-changed",
        "z": "d3a07d369eada1b3",
        "name": "Front Motion",
        "server": "c195525b96cc1e8a",
        "version": 4,
        "exposeToHomeAssistant": false,
        "haConfig": [
            {
                "property": "name",
                "value": ""
            },
            {
                "property": "icon",
                "value": ""
            }
        ],
        "entityidfilter": "binary_sensor.front_motion_motion",
        "entityidfiltertype": "exact",
        "outputinitially": false,
        "state_type": "str",
        "haltifstate": "on",
        "halt_if_type": "str",
        "halt_if_compare": "is",
        "outputs": 2,
        "output_only_on_state_change": true,
        "for": "5",
        "forType": "num",
        "forUnits": "seconds",
        "ignorePrevStateNull": false,
        "ignorePrevStateUnknown": false,
        "ignorePrevStateUnavailable": false,
        "ignoreCurrentStateUnknown": false,
        "ignoreCurrentStateUnavailable": false,
        "outputProperties": [
            {
                "property": "payload",
                "propertyType": "msg",
                "value": "",
                "valueType": "entityState"
            },
            {
                "property": "topic",
                "propertyType": "msg",
                "value": "",
                "valueType": "triggerId"
            }
        ],
        "x": 110,
        "y": 1000,
        "wires": [
            [
                "ef9d53cccca844c0"
            ],
            []
        ]
    },
    {
        "id": "ef9d53cccca844c0",
        "type": "time-range-switch",
        "z": "d3a07d369eada1b3",
        "name": "Golden Hour Start and Golden Hour End",
        "lat": "53.5695493",
        "lon": "-113.4513922",
        "startTime": "goldenHour",
        "endTime": "goldenHourEnd",
        "startOffset": 0,
        "endOffset": 0,
        "x": 280,
        "y": 1060,
        "wires": [
            [
                "24f88e58e8e31bcd"
            ],
            []
        ]
    },
    {
        "id": "24f88e58e8e31bcd",
        "type": "trigger",
        "z": "d3a07d369eada1b3",
        "name": "",
        "op1": "{\"service\":\"turn_on\",\"data\":{\"transition\":4,\"brightness_pct\":60}}",
        "op2": "{\"service\":\"turn_off\",\"data\":{}}",
        "op1type": "json",
        "op2type": "json",
        "duration": "1",
        "extend": true,
        "overrideDelay": false,
        "units": "min",
        "reset": "",
        "bytopic": "all",
        "topic": "topic",
        "outputs": 1,
        "x": 450,
        "y": 1000,
        "wires": [
            [
                "e3fcc03bafc96ae2"
            ]
        ]
    },
    {
        "id": "e3fcc03bafc96ae2",
        "type": "api-call-service",
        "z": "d3a07d369eada1b3",
        "name": "Front Ceiling",
        "server": "c195525b96cc1e8a",
        "version": 5,
        "debugenabled": false,
        "domain": "light",
        "service": "{{payload.service}}",
        "areaId": [],
        "deviceId": [],
        "entityId": [
            "light.front_ceiling"
        ],
        "data": "",
        "dataType": "jsonata",
        "mergeContext": "",
        "mustacheAltTags": false,
        "outputProperties": [],
        "queue": "none",
        "x": 650,
        "y": 1000,
        "wires": [
            []
        ]
    },
    {
        "id": "d10ea8be3530a253",
        "type": "comment",
        "z": "d3a07d369eada1b3",
        "name": "Front Motion detected for 5 seconds between Golden Hour Start and Golden Hour End",
        "info": "",
        "x": 320,
        "y": 960,
        "wires": []
    },
    {
        "id": "c195525b96cc1e8a",
        "type": "server",
        "name": "homeassistant.instantdreams.org",
        "version": 5,
        "addon": false,
        "rejectUnauthorizedCerts": true,
        "ha_boolean": "y|yes|true|on|home|open",
        "connectionDelay": true,
        "cacheJson": true,
        "heartbeat": false,
        "heartbeatInterval": "30",
        "areaSelector": "friendlyName",
        "deviceSelector": "friendlyName",
        "entitySelector": "friendlyName",
        "statusSeparator": ": ",
        "statusYear": "hidden",
        "statusMonth": "short",
        "statusDay": "numeric",
        "statusHourCycle": "default",
        "statusTimeFormat": "h:m",
        "enableGlobalContextStore": false
    }
]

Summary

Which of these is generally considered the best way to manage lighting automation? I think the use of Trigger feels like the cleanest, but I’m not sure if it’s the best.

“Best” is subjective. Only you can define what is best for you.

I personally like to use a trigger node then a wait until (the dwell time expires on the motion sensor), then call service off.

Is that the same as my last example? Because that does seem like the best to me.

[{"id":"b3046bec28557348","type":"api-call-service","z":"fe1a8042.af255","name":"Mudroom Light On","server":"f3f422ce.9f2a6","version":5,"debugenabled":false,"domain":"switch","service":"turn_on","areaId":[],"deviceId":[],"entityId":["switch.mudroomlightswitch"],"data":"","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":310,"y":320,"wires":[["6d26bbe4a6308854"]]},{"id":"a9262cf82af02020","type":"api-call-service","z":"fe1a8042.af255","name":"Mudroom Light Off","server":"f3f422ce.9f2a6","version":5,"debugenabled":false,"domain":"switch","service":"turn_off","areaId":[],"deviceId":[],"entityId":["switch.mudroomlightswitch"],"data":"","dataType":"json","mergeContext":"","mustacheAltTags":false,"outputProperties":[],"queue":"none","x":529,"y":377,"wires":[[]]},{"id":"191915c8491e78e6","type":"trigger-state","z":"fe1a8042.af255","name":"Mudroom Motion","server":"f3f422ce.9f2a6","version":2,"exposeToHomeAssistant":false,"haConfig":[{"property":"name","value":""},{"property":"icon","value":""}],"entityid":"binary_sensor.mudroom_motion_motion","entityidfiltertype":"exact","debugenabled":false,"constraints":[{"targetType":"this_entity","targetValue":"","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"on"},{"targetType":"entity_id","targetValue":"switch.mudroomlightswitch","propertyType":"current_state","propertyValue":"new_state.state","comparatorType":"is","comparatorValueDatatype":"str","comparatorValue":"off"}],"inputs":0,"outputs":2,"customoutputs":[],"outputinitially":false,"state_type":"str","enableInput":false,"x":102,"y":320,"wires":[["b3046bec28557348"],[]]},{"id":"6d26bbe4a6308854","type":"ha-wait-until","z":"fe1a8042.af255","name":"No Motion","server":"f3f422ce.9f2a6","version":2,"outputs":1,"entityId":"binary_sensor.mudroom_motion_motion","entityIdFilterType":"exact","property":"state","comparator":"is","value":"off","valueType":"str","timeout":"0","timeoutType":"num","timeoutUnits":"minutes","checkCurrentState":true,"blockInputOverrides":true,"outputProperties":[],"x":290,"y":378,"wires":[["a9262cf82af02020"]]},{"id":"f3f422ce.9f2a6","type":"server","name":"Home Assistant","version":5,"addon":true,"rejectUnauthorizedCerts":true,"ha_boolean":"y|yes|true|on|home|open","connectionDelay":true,"cacheJson":true,"heartbeat":false,"heartbeatInterval":30,"areaSelector":"friendlyName","deviceSelector":"friendlyName","entitySelector":"friendlyName","statusSeparator":"at: ","statusYear":"hidden","statusMonth":"short","statusDay":"numeric","statusHourCycle":"h23","statusTimeFormat":"h:m","enableGlobalContextStore":true}]
1 Like