Smart light bulbs are probably the first thing everyone getting into home automation buys. It is easy to see the applications for them – have the lights come on at night, turn off when you’re home, etc. It’s very satisfying to have the lights react to the day and your activities, and my goal with automating lighting has always been to not have to think about it, for it to work in the background.

In my initial post about Home Assistant and Node-Red, I explained the initial hoops you have to jump through to get both pieces of software up and running and talking to each other. Now we will start using them together in some very simple flows to control lighting, to get a better understanding of how Node-Red works, and to start to delve into this powerful tool.





SPLIT PERSONALITY

The way I approach making automations is to think of Home Assistant as a state machine. It’s job is to track all the states of the devices, and to call services to change those states. All the hardware interfacing – the communication between the hub and the device and interpreting that information – is all Home Assistant. Home Assistant is a giant catalog of data (states) and actions (services) that Node-Red can draw from.

Node-Red, on the other hand, is our brain. Node-Red performs the logic. Node-Red doesn’t have to keep track of states or know how to talk to a Philips Hue bulb and a Wemo smart switch, Node-Red just asks Home Assistant when it needs to know the state of something. When Node-Red makes a decision, it sends the command (service) back to Home Assistant to handle. Node-Red is all about the big picture.

This simple separation of duties in our automations will make integrating much easier.





LIGHTING ONE: SIMPLE BINARY

I have a light bulb in an awkward crawl space that is really hard to reach. Every once in a while I need to reach a breaker in there and can never find the switch. So I replaced the bulb with a cheap smart bulb and added a door sensor. When the door opens, the light comes on, when it’s closed, the light is off.

[{"id":"70a001ee.bfd2e","type":"server-state-changed","z":"18835ede.3f82d1","name":"Crawl Space Door","server":"8ac3cd7f.58d3e","entityidfilter":"binary_sensor.crawl_space_door","haltifstate":"","x":131.4206886291504,"y":544.5259022712708,"wires":[["d0ccbd28.cb728"]]},{"id":"d0ccbd28.cb728","type":"switch","z":"18835ede.3f82d1","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","outputs":2,"x":299.98705673217773,"y":544.2827610969543,"wires":[["5e9a8806.36d148"],["6123b169.361c9"]]},{"id":"5e9a8806.36d148","type":"api-call-service","z":"18835ede.3f82d1","name":"ON","server":"8ac3cd7f.58d3e","service_domain":"light","service":"turn_on","data":"{\"entity_id\":\"light.crawl_space\"}","x":444.8025550842285,"y":516.2688345909119,"wires":[]},{"id":"6123b169.361c9","type":"api-call-service","z":"18835ede.3f82d1","name":"OFF","server":"8ac3cd7f.58d3e","service_domain":"homeassistant","service":"turn_off","data":"{\"entity_id\":\"light.crawl_space\"}","x":445.87427139282227,"y":567.6973919868469,"wires":[]},{"id":"8ac3cd7f.58d3e","type":"server","z":"","name":"Home Assistant","url":"http://localhost:8123","pass":"XXXXX"}]

Our input is a Home Assistant state node that monitors the door sensor. When a state change is detected, it’s sent as a message to the next node, a switch.

If the message (msg.payload in Node-Red terms) is on, route to output 1, if it’s off, route to output 2. These outputs end in Home Assistant service calls that turn the light on or off.

You must hit the “DEPLOY” to save and activate your flow.

Congrats, this is the entire process of creating an automation with Node-Red.

LIGHTING TWO: MOTION TIMER

Let’s do something more interesting. For this example we will need an extra node called stoptimer, which can be installed through “Manage palette” in the Node-Red menu. When stoptimer receives a message, the timer starts. If it receives another message the timer is reset. If it gets a message that says “STOP” then it cancels the timer. Pretty useful.

I have a motion sensor under my office desk, when I sit down the lights come on. If I walk away I want the lights to turn off – say after 20 minutes of no activity.

[{"id":"6b710453.81dbac","type":"server-state-changed","z":"4056fc4f.0baa64","name":"Office Motion","server":"8ac3cd7f.58d3e","entityidfilter":"binary_sensor.office_motion","haltifstate":"","x":190,"y":380,"wires":[["994dd149.e4555"]]},{"id":"19caec7f.e0b4d4","type":"stoptimer","z":"4056fc4f.0baa64","duration":"20","units":"Minute","payloadtype":"num","payloadval":"0","name":"20min","x":550,"y":420,"wires":[["a9408fec.408e1"],[]]},{"id":"a9408fec.408e1","type":"api-call-service","z":"4056fc4f.0baa64","name":"OFF","server":"8ac3cd7f.58d3e","service_domain":"homeassistant","service":"turn_off","data":"{\"entity_id\":\"group.Office\"}","x":1010,"y":414,"wires":[]},{"id":"fa446f4f.1df58","type":"api-call-service","z":"4056fc4f.0baa64","name":"ON","server":"8ac3cd7f.58d3e","service_domain":"homeassistant","service":"turn_on","data":"{\"entity_id\":\"group.Office\"}","x":1010.1666526794434,"y":373.95236015319824,"wires":[]},{"id":"994dd149.e4555","type":"switch","z":"4056fc4f.0baa64","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","outputs":2,"x":350,"y":380,"wires":[["19caec7f.e0b4d4","da14546c.577218"],["19caec7f.e0b4d4"]]},{"id":"da14546c.577218","type":"api-current-state","z":"4056fc4f.0baa64","name":"Already On?","server":"8ac3cd7f.58d3e","halt_if":"on","entity_id":"switch.office","x":748,"y":373,"wires":[["fa446f4f.1df58"]]},{"id":"8ac3cd7f.58d3e","type":"server","z":"","name":"Home Assistant","url":"http://localhost:8123","pass":"XXXXX"}]

We’ve added a few nodes to our first example, let’s follow the flow.

If Office Motion is on, the switch sends it down two paths simultaneously:

A state node that looks up the state of group.office . If it’s already on , the flow halts, otherwise the lights are turned on

. If it’s already , the flow halts, otherwise the lights are turned on Starts or resets the 20 minute stoptimer if it’s already running. If no other state changes come from the Office Motion sensor, the msg.payload terminates in an off service command.

If Office Motion is off, it starts or resets the timer.

This keeps the lights on as long as something is happening with the motion sensor. When there’s been no activity for 20 minutes, the timer reaches it’s conclusion and the msg.payload is sent to the output to turn the light off.

Note in the “Already On?” node we can halt the flow according to the state it returns:

The alternative would be to use a switch node, but this saves us the trouble. In Home Assistant terminology, this is equivalent to a condition.

LIGHTING THREE: MOTION, TIME RANGE, & OCCUPANCY

Now that’s we’ve done two simple examples, let’s start to show off the real power of Node-Red. For this one we’re going to need another additional node, the time range switch. I’m also using a meta-motion sensor that shows where Home Assistant last saw motion.

[{"id":"4876c05d.90497","type":"server-state-changed","z":"4056fc4f.0baa64","name":"Bathroom Motion","server":"8ac3cd7f.58d3e","entityidfilter":"binary_sensor.bathroom_motion","haltifstate":"off","x":220,"y":420,"wires":[["e25bff84.3451d"]]},{"id":"e25bff84.3451d","type":"time-range-switch","z":"4056fc4f.0baa64","name":"After 6AM","lat":"","lon":"","startTime":"06:00","endTime":"23:59","x":403.333309173584,"y":419.9999780654907,"wires":[["e6559f89.5c606","ec4009c3.5b4c48"],[]]},{"id":"e6559f89.5c606","type":"api-current-state","z":"4056fc4f.0baa64","name":"Light Off?","server":"8ac3cd7f.58d3e","halt_if":"on","entity_id":"switch.bathroom_light","x":573.3334007263184,"y":381.33339405059814,"wires":[["13aee75f.de9699"]]},{"id":"13aee75f.de9699","type":"api-call-service","z":"4056fc4f.0baa64","name":"ON","server":"8ac3cd7f.58d3e","service_domain":"switch","service":"turn_on","data":"{\"entity_id\":\"switch.bathroom_light\"}","x":1034.9999504089355,"y":382.99997901916504,"wires":[]},{"id":"1c5dbbe7.4de5e4","type":"api-render-template","z":"4056fc4f.0baa64","name":"Still in Bathroom?","server":"8ac3cd7f.58d3e","template":"{{ states.variable.last_motion.state != 'Bathroom Motion' }}","x":743.3333396911621,"y":440.0000238418579,"wires":[["67242a38.922154"]]},{"id":"ec4009c3.5b4c48","type":"stoptimer","z":"4056fc4f.0baa64","duration":"12","units":"Minute","payloadtype":"num","payloadval":"0","name":"12min","x":560.0000190734863,"y":446.6667079925537,"wires":[["1c5dbbe7.4de5e4"],[]]},{"id":"67242a38.922154","type":"switch","z":"4056fc4f.0baa64","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"True","vt":"str"}],"checkall":"true","outputs":1,"x":908.3333015441895,"y":440.00000286102295,"wires":[["e1e6dad7.9a0dc8"]]},{"id":"e1e6dad7.9a0dc8","type":"api-call-service","z":"4056fc4f.0baa64","name":"OFF","server":"8ac3cd7f.58d3e","service_domain":"homeassistant","service":"turn_off","data":"{\"entity_id\":\"group.bathroom\"}","x":1037.5001754760742,"y":440.00003147125244,"wires":[]},{"id":"ed231cde.fc99","type":"server-state-changed","z":"4056fc4f.0baa64","name":"Bathroom Switch Flipped On","server":"8ac3cd7f.58d3e","entityidfilter":"switch.bathroom_light","haltifstate":"off","x":353.33336639404297,"y":495.0001130104065,"wires":[["ec4009c3.5b4c48"]]},{"id":"8ac3cd7f.58d3e","type":"server","z":"","name":"Home Assistant","url":"http://localhost:8123","pass":"XXXXX"}]

In my bathroom I’ve got a motion sensor and a Z-Wave wall switch that controls the light. I want the light to turn off after 12 minutes of no motion, but not if I’m still… taking care of business. The switch should trigger the same timer if someone uses it. And also – I don’t want to get blinded if I get up in the middle of the night.

Following the flow, the state of the Bathroom Motion sensor is sent to the time-range switch, which will only continue if it’s after 6AM. After that we essentially do the same thing as the last example, checking to see if the light is already on before calling the light.turn_on service. The stop timer accepts another input from the wall switch if guests use it.

After the timer concludes, it gets the state of the meta-motion sensor and the switch evaluates if I’m still in the Bathroom before turning the light off.

LIGHTING FOUR: SOLAR EVENT TRIGGER

What about having the lights turn on at sunset? There’s more than one node for that. Here I am using bigtimer because it allows offsetting solar events. You can read the documentation for bigtimer, it’s kind of more complicated than it needs to be IMO, but it’s useful here for turning my aquarium on at sunset and off at 10pm.

[{"id":"c49b6101.4865","type":"bigtimer","z":"59230ccd.4625e4","outtopic":"","outpayload1":"","outpayload2":"","name":"Sunset","lat":"37.799564008","lon":"-122.268797","starttime":"5004","endtime":"5003","startoff":"-60","endoff":"240","offs":0,"outtext1":"on","outtext2":"off","timeout":1440,"sun":true,"mon":true,"tue":true,"wed":true,"thu":true,"fri":true,"sat":true,"jan":true,"feb":true,"mar":true,"apr":true,"may":true,"jun":true,"jul":true,"aug":true,"sep":true,"oct":true,"nov":true,"dec":true,"day1":0,"month1":0,"day2":0,"month2":0,"day3":0,"month3":0,"day4":0,"month4":0,"day5":0,"month5":0,"d1":0,"w1":0,"d2":0,"w2":0,"d3":0,"w3":0,"d4":0,"w4":0,"d5":0,"w5":0,"suspend":false,"random":false,"repeat":true,"atstart":true,"odd":false,"even":false,"x":353.75000381469727,"y":428.7500057220459,"wires":[[],[],["c6e50538.2732a8"]]},{"id":"c6e50538.2732a8","type":"switch","z":"59230ccd.4625e4","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"on","vt":"str"},{"t":"eq","v":"off","vt":"str"}],"checkall":"true","outputs":2,"x":593.1337394714355,"y":406.8185729980469,"wires":[["4c8b4d1b.32ece4"],["db50b01e.eea8e"]]},{"id":"893ff0c6.accba","type":"api-call-service","z":"59230ccd.4625e4","name":"Turn off Aquarium","server":"8ac3cd7f.58d3e","service_domain":"switch","service":"turn_off","data":"{\"entity_id\":\"switch.aquarium\"}","x":990.0001640319824,"y":446.24994373321533,"wires":[]},{"id":"4c8b4d1b.32ece4","type":"api-call-service","z":"59230ccd.4625e4","name":"Turn on Aquarium","server":"8ac3cd7f.58d3e","service_domain":"switch","service":"turn_on","data":"{\"entity_id\":\"switch.aquarium\"}","x":989.3838424682617,"y":382.6952495574951,"wires":[]},{"id":"bc733e16.0eb51","type":"inject","z":"59230ccd.4625e4","name":"10pm","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"00 22 * * *","once":false,"x":600.6250152587891,"y":444.9523983001709,"wires":[["893ff0c6.accba"]]},{"id":"db50b01e.eea8e","type":"api-current-state","z":"59230ccd.4625e4","name":"Off Already?","server":"8ac3cd7f.58d3e","halt_if":"off","entity_id":"switch.aquarium","x":762.4783706665039,"y":422.348180770874,"wires":[["893ff0c6.accba"]]},{"id":"8ac3cd7f.58d3e","type":"server","z":"","name":"Home Assistant","url":"http://localhost:8123","pass":"XXXXXX"}]

MORE LINKS

Hopefully now you’ve got a better idea of some of the things that are possible using just a handful of nodes with Home Assistant. I’ve got a big list of nodes I’ve used in home automation linked below if you want to explore some more.

One of the great things about Node-Red is how easy it is to share flows. Copy from the pastebin link below to get all the flows here and start automating your lights immediately!