TV Ambient Lighting, with Node-RED

I have a Hue LED strip mounted to the back of my 65″ TV, and I like to have it change color, according to input and activity on screen. It’s a pretty straight forward and easy setup, but one that people really enjoy.

Listed below is my setup and config, but I will try to show how to do this in the simplest way possible, in the hopes that it will work with whatever your setup is.

Hardware, and related integrations and addons:

(Amazon links are affiliate links, where I get a small commission of purchased item)


  • Home Assistant
    • Node-RED addon
      • Built in nodes – (Nodes that are included with Node-RED)
        1. function node
        2. event: state (server-state-changed) node
        3. switch node
        4. call service (api-call-service) node

Don’t worry if you do not have this exact configuration, since we’ll be using all generic nodes, this should work with virtually all configurations.

To start, we’re going to need to get the status of the TV. To do that, we’re going to use the Activities from the Harmony Hub and remote. The Harmony Hub integration will automatically pull all the activities you created when you first setup your Harmony Hub. The names of those activities are located in the harmony config file located at the root of the Home Assistant config directory. Using the file manager of your choice (I use the Visual Studio Code addon) navigate to this directory and take note of the activity names. Case is important, so make sure to note them exactly as they are.

Now that we know the activity names, we need to figure out how to filter them and use them to kick off flows. To do that, we’re going to grab an “events: state” node, and configure it like so:

Then we’re going to grab a debug node, and configure like so:

And then we are going to connect the two, open the debug window and then start an activity on your TV remote. You’ll see the debug output on the right. This shows all of the information passed on by the state node

If you drill down to “data.new_state.attributes.current_activity”, you’ll see the name of the current Activity, in this example it is “Google TV”. We now need to take this path, plug it into a switch node, and filter the activities. Start by copying the path by clicking the little > emblem.

This will copy the path to your clipboard.

Next, grab a switch node, and paste the path that you copied into the Property field. Then, in the fields below make sure == is selected and then enter the Activity names. This will filter everything that comes in through “data.new_state.attributes.current_activity” to the corresponding output. Nothing else will get passed through. Now, connect the event state node you created earlier to the switch node, and connect properly labeled debug nodes to each output on the switch node. Don’t forget the PowerOff activity!

Switch node configuration

With them all connected, when you start an activity from your remote, you can hover over the debug output and it will highlight the debug node that it came from. Doing this, you can verify that the switch node is routing the payload correctly.

Now that we know when we press Google TV on the remote, it will route through the Google TV output of the switch (along with all the other activities routing through the correct output), we can start programming the lighting per output.

Grab a “call service” node node, and we’re going to program it to turn on the light when PS5 is selected. I like to Google the RGB code of whatever service it is that I’m working with. For example, I would Google “Netflix logo RGB color” and it will give me the RGB code for Netflix Red. Same with Playstation Blue, etc. With that info, the call service node to turn the light Playstation Blue, would look like this:

Domain is light, service is “turn_on. Click the three dots to open the JSON editor to program the settings for the light. “brightness_pct”: 55 will set the light to 55% brightness. “transition”:1.5 means that the light will reach 55% brightness when turned on in one and a half seconds. “rgb_color”:102, 92, 190 is the RGB color for PlayStation Blue. “entity_id” is the name of the light you want to control. You will need to repeat this until you have all the outputs done. One for TV, one for Nintendo Switch, etc.

Lastly, don’t forget about the PowerOff activity, to turn the lights off when you turn off the TV. It’s the same setup, different service. Grab another “call service node”, and program similar to before, except the only thing you need to worry about is the service, which is now “turn_off, and the entity_id of course. It will look like this:

The completed flow will look like this:

Here is a video showing how it can look. Keep in mind, in the video, I’m using a more advanced version of the flow to change colors based on the currently selected app in my Google TV, but the effect is the same. I may do a part two later to show how to do that. Also, don’t mind the creepy whispering at the end of the video, I was lightly bullying my buddy cause his TV isn’t this awesome.

Finally, here is the code.

Time based automations, with Node-RED

Time based flows are probably the easiest to do. In this example, you can see that I’m using an inject node set to trigger at 8pm to set my Ecobee thermostat to 73*. The same with setting the alarm, turning lights on and off, etc.

Setting up something to trigger at a specific time is easy. Grab an inject node, and configure it similarly to this:

The payload can stay as a timestamp if you want, I just always change it to what I want it to do, just ’cause. You can see that it is set to repeat at a specific time (10:30pm), everyday of the week. In the first screenshot you can see that the 10:30pm node arms the house if the house isn’t armed, starts the subflow to close the garage if open, the subflow to turn off the front porch light if on, and the subflow to turn off the backyard flood light if on.

For the “Every 30 minutes” inject node, it connects to a time range node that only allows the inject node to work between 11 pm and 4:30am. This will check to be sure all the things I want to happen over night, happen, even if they are somehow missed by the 10:30 trigger. There is a better way to do this, but this is how to do it in it’s most basic form.

Here’s what the every 30 minute inject node looks like:

Here’s how the time frame node looks:

The big green node at the top of the flow is the bigtimer node. It operates sort of like a time range node and an inject node. I have it configured in it’s most basic way. It sends a message at sunset, and another at sunrise, which toggles my exterior light automations. Here’s how that node looks:

These are very basic ways to setup time based automations. In the future I will show how to set everything up in one fluid flow, but this will get you headed in the right direction.

Here’s the code.

Using the “stoptimer” node, in Node-RED

The stoptimer node has two functions. It refreshes the timer whenever it receives a new message, which is useful for motion automations; and it can start a timer when something happens, and stop the timer if something else happens.

They are very useful in motion lighting automations.

In the flow screenshot above, when the kitchen motion sensor is triggered between sunset and sunrise, and if none of the living area lights are on, the kitchen can bulbs 1 and 3 are turned on at 10% for 25 seconds, and then they are turned off. We’ll get to the turn off loop I’m using later in the post.

In this flow, every time the motion sensor is triggered, a new message is sent down the line. If that message reaches the stoptimer before the 25 second timer has ended, it restarts. This will keep the lights on until 25 seconds after the last triggered motion event. Make sure that the stoptimer duration is not shorter than the refresh duration of your motion sensor. My sensors refresh every 15 seconds, so any timer above 16 seconds will keep the lights on as long as motion is detected.

So, what if you want to stop the timer?

I have automations setup to monitor my outside refrigerator, because my knucklehead kids will leave the door cracked and it will defrost. So I thought I’d put something together to help stop that.

Here’s what that looks like:

In this flow, the top two flows monitors the refrigerator and freezer doors, the bottom two monitors the temps.

For the doors, an “event:state” node is monitoring the door state. When the door is opened, it sends from the top output which starts a stoptimer for 3 minutes. If the door remains open past that three minutes, a notification is sent to Telegram, which alerts my wife and I. If during that 3 minutes, the door is closed, it sends from the bottom output which triggers a “change” node that changes the msg.payload to “STOP”, which then is sent to the stoptimer node, and the timer is stopped and a notification is not sent.

For the temperatures, an “event:state” node is monitoring the temps of the freezer/fridge, which is then sent to a switch node. The switch node determines if the temps are equal-to-or-higher than a certain value (20 degrees for the freezer, 50 for the fridge), and if they are, to pass it on to the stoptimer which starts a 10 minute timer. I’m using 10 minutes, because the temps can temporarily rise past those values when the door is opened, and the timer gives it enough time to stabilize. If it wasn’t there, a notification would get sent almost every time the door was opened. So if the temps rise over the set value for more than 10 minutes, it’s safe to assume something is wrong.

Once the temp drops back down below the set value, the message is sent from the bottom output which triggers another change node, that will stop the timer, which again, cancels any notifications that were going to be sent.

When to use a stoptimer, instead of a delay node?

A delay node is very simple, it literally delays any messages for the duration of time that you set. There’s a few more things it can do, but as far as stopping it like a stoptimer, there is no function for this. So, when should you use a delay node instead of a stoptimer? Well, technically, you can use a stoptimer as a standard delay node if you wanted to, but I like to try to use them for their specific purpose, as it makes looking at a flow easier for me.

Lets look at another of my lighting automations.

Above is an automation used with our dining room light. In our house, the dining room light is one of those lights that just gets left on all the time, for no particular reason. I put this flow together to turn it off if there is no motion in the dining room room for 20 minutes. I have an “events:state” node checking for motion, and passing it on to a “current:state” node when motion is detected. The current state node checks to see if the Dining room light is on, and if it is, it passes the message on to the stoptimer node, which triggers the 20 minute timer. Whenever motion is detected, it sends another message, which restarts the timer, keeping the light on. When no motion is detected for 20 minutes, the light turns off. If a delay node was used here, the light would come on for 20 minutes, turn off, and then immediately come back on if motion is constantly being detected. This means the light will flash every 20 minutes, as long as someone is triggering the motion detector. So it makes sense to use a stoptimer here in the flow.

When you look further down the flow, after the stoptimer node, you see a call service node which turns off the dining room light. This then starts a 1 second delay node, which then sends to a current state node that checks the state of the dining room light. If the light is off, everything stops here. If the light is on, it loops back to the call service node to turn the light off. I started using these turn off loops when I noticed on rare occasions lights wouldn’t turn off or on correctly. Since there is no reason to stop the timer, a delay node can be used here. The delay node is stopped whenever the current state node says the light is off, and it doesn’t loop the message back around to the call service node to turn off the light. I stoptimer node could be used here, and it would work correctly and the flow would operate correctly, but it’s not “needed”. It’s sort of a “best practices” thing; its best practice to use the correct node in a specific situation.

Below are the codes for the flows if you want to mess around with them.

The code for the Kitchen motion lighting flow

The code for the outside refrigerator example. – Please note that I removed the Telegram notification node as it has all of the info to send to my bot, so you’ll need to connect this to your own notification nodes.

The code for the dining room motion automation.

Working with motion flows in Node-RED

Motion automations are some of my favorites. I’ve noticed a lot of questions across the internet about how to set them up, so I’ll do a few simple ones to help others get started.

Motion activated light.
Super simple. Grab an “events: state” node undefined, and a “call service” node undefined. Configure the events state node with your motion sensor. Here’s an example of mine:

If you put a value in the “If State” field, you will have two outputs. Top is “true”, bottom is “false”. In this node, the If State is “on”, so if motion is “on” (true), output from the top, when motion is “off”(false) output from the bottom. Think of it like “If state is true – top”, and “if state is false – bottom”. Doing it this way, the flow will start when motion is detected, or true, if connected to the top. If connected to the bottom, the flow will start once there is no motion. If you leave this field blank, there will only be a single output node that will trigger every time the state goes from on to off, and off to on.

The “Output only on state change” setting is important to how your flow will behave. Lets say that the motion sensor you are using is in the living room and you’re having a party. There’s a ton of people in your house and there’s constant movement. The motion sensor will trigger when it first senses motion, and it will stay triggered until it no longer senses motion. With “Output only on state change” checked, it will only send out a message from the output once, when it was initially triggered by motion. This is because the state has not changed from “on”. If you uncheck “Output only on state change“, it will send a new message every time the motion sensor is triggered. different motion sensors check for motion at different intervals. All of the motion sensors that I use (I highly recommend the Zooz ZSE40) trigger about every 15 seconds. So a new trigger message would be sent every 15 seconds with non stop motion.

If you’re brand new to this, I realize that’s a lot of info, but it will make sense soon enough.

On to the call service node. It will need to be configured like this:

Domain” is the first part of an entity in Home Assistant. “climate.xxxx” would be the domain of a thermostat, “lock.xxxx” would be the domain for a smart lock, etc. In this case, we’re using the “light” domain.

service” is the action you want to perform, in this case, “turn_on” which will turn on the light that we specify when triggered. After you’ve selected your domain, you can use the drop down menu to see what services are available. Below you’ll see that the options are “toggle”, “turn_off” and “turn_on”.

“Entity Id” is where you specify what device to control. if you type in “light”, it will auto complete every entity that is in the light domain, and you can just select the entity you want.

With both of these done, the most basic configurations are done. You now need to just connect the nodes. Now what we have is a complete working flow. When the Entryway Motion node state is “on”, it will turn on the Entryway Lights, and that’s it.

Easy flow, but essentially useless in the automation sense of things. Lets have the light turn off after a set period of time.

Motion activated light with timer.
We want the light to turn off at some point, so we’re going to work off the flow that we just created and make that happen. First grab a “stoptimer” node, undefined and wire it after the other two nodes.

The way the stoptimer node works; Once it receives a message, in this example from the Entryway Lights node, which was passed on from the Entryway Motion node, it starts a 5 second timer. Once the 5 seconds are over, it sends the message. If the stoptimer node receives another message within the five second timer, it restarts the timer.

Grab another call service node and attach it to the top output of the stoptimer node. Configure it exactly as you did the first call service node, except use the “turn_off” service. So this is what you’ll have:

So now, motion in the entryway, turns on the entryway lights, waits 5 seconds and turns off the entryway lights. Are you still with me? Don’t worry about it if you’re not, it’ll all work out in the end.

So at this point we have a complete but inefficient flow. We can fix this solely with configuring the nodes in a different way.

How do we make this a usable flow?
It’s easy. As we’ve said a few times already, our example motion sensor refreshes every 15 seconds and sends a new message depending on the state of the node. If there is constant motion, it will send a message of “on” every fifteen seconds. No motion will send “off” every fifteen seconds. If there was was motion and it sent “on, and then no motion, the next message will be “off”, etc etc, you probably get the point by now. Also remember, that the stoptimer resets if it receives another message before the timer is over. So if it’s a 5 second timer, and it receives another message at 4 seconds, it starts back over at 5 seconds.
So, knowing this, we can set the stoptimer to anytime longer than the refresh time of it’s input. The example motion sensor sends an update every 15 seconds, so we can set the stoptimer to 16 seconds. The motion sensor sends a message the first time it detects motion, which turns on the lights and then starts the stoptimer. If there is no more motion, the light will turn off in 16 seconds. If there is still motion, within the 16 seconds, it restarts the timer. The timer will be restarted as long as there is motion, which will leave the light on while the room is occupied.

Or will it? Remember that check box, “Output only on state change” ? With this checked, even though the motion sensor sends an update every 15 seconds, the Entryway Motion node would not send an update because the state stays “on” with constant motion. State doesn’t change, it doesn’t send a new message. With it checked, it would only send a new update to the top output when the motion went from on, to off and then back to on.

So, we uncheck it. This will allow the Entryway Motion node to send a new update every time it receives one from the motion sensor, even if the state never changes. Even if the state stays to on for an hour because there’s constant motion, it still sends an update every 15 seconds from the motion sensor, and since the timer is set to 16 seconds, the light always stays on with motion.

If your motion sensor sends a new update every 8 seconds, you’d want to set the stoptimer to 9 seconds to keep the light on with motion. Twenty second motion sensor, 21 seconds stop timer, etc etc.

Here’s the code of the above flow for import.

Here’s another motion flow as an example. If the dining room light is left on, and there is motion, the light will stay on. If there is no motion for 20 minutes, the light turns off. Le’ Code.

Using smart switches and smart bulbs together, with Home Assistant and Node-RED.

(Amazon links are affiliate links, where I get a small commission of purchased item)

I have 6 Hue A19 Color bulbs in the ceiling of my kitchen. We were using them with standard dummy switches, which was a pain as I had to constantly remind people to leave the switches on. Not to mention that it is bad for smart bulbs to be constantly powered on and off. I was about to pull out the smart bulbs and install standard LED lights and go with smart switches, but I really did not want to do this, as the individual bulbs are used for certain automations. For example, a nightlight where bulbs 1 and 3 are motion controlled to come on at 5% if everything else is turned off, and it’s dark outside.

How to get around this to keep my smart bulbs AND keep them powered at all times? At first, I tried using a Sylvania Dimming switch and control the lights with a scene. This switch is placed over the existing dummy switch, which you leave flipped on. Since this was a 3-way setup, I put a switch cover over the second switch (you could also get a second Sylvania switch). This worked….I now had always powered and physically controllable smart bulbs, and although it was a practical solution, it was kind of ugly. The wife definitely didn’t like the look in her new home, so I was back to trying to figure this out.

All of the smart switches in my house are of the Go Control / Linear / Nu Tone variety. These are all made by the same manufacturer, but sold under different names. They are not Z-Wave Plus, but I got the first one years ago and have been matching them together ever since. I haven’t noticed any downfalls of them not being Z-Wave Plus, but they’ll eventually be upgraded. For a three way setup, there is the NuTone NWT00Z which are not standard add-on switches. These are “virtual 3-way” switches. The low ratings on Amazon are somewhat understandable as the documentation (PDF of the manual here and here) is cryptic at best, and does not say explicitly how to use these. I will say that we’ve had these installed for a few months now with zero issues.

The way these are intended to work, are as “remotes” to other switches. In my entryway, I have one installed in a 3-way setup with a NWD500Z dimmer switch. You wire it up and and it controls the master switch in a zwave group association, but we’re going to do something different with them.

I used two of these in my kitchen. The way to wire them and have the lights always on is an odd way. Take the load, line and traveler wires from the wall, as well as the load line from the first switch and connect them all together. The ground and neutral are wired up as normal. The second switch needs to be wired a little differently as well. Take the line and load wires from the wall, cap them together and stuff them into the wall. Take the traveler wire, which is now a constant 120v line, and connect it to the load line of the NWT00Z. Wire the ground and neutral up as normal.

Now what we have are two smart switches that are wired up and connected to the mains, but they do not control the power to the lights. The power is now constant to the smart bulbs. At this point, the lights will stay powered on, unless you control them from Lovelace or using voice if you have Google Home/Alexa setup, but theres no way to mechanically control them yet. The hard part is done and we now have to head over to Node-RED and start working on the automation to turn these on or off.

We can’t add the switches to a Zwave group association, as the Hue lights are zigbee. So we need to grab the zwave event type commands coming from the switch. To do this, use a “events: all” node and filter “zwave.node_event” commands. Example below.

“events: all” node

So now we’re grabbing all node_events from the “zwave.” domain, now we need to filter them. To do this, we need a switch node to filter the “payload.entity_id” from the specific switches we setup. You’ll need to use the name that you gave these switches when including them in your network. One thing to remember, you need to use the “zwave” domain name, NOT the “switch” domain name.

At this point, we’re filtering the two switches with “payload.entity_id”. Now we need to filter it down again to get the actual commands from the switches. With these switches, “0” is off and “255” is on. We need another switch node and filter “payload.event.basic_level“. This will grab all “.basic_level” events that come over the two switches. You’ll want to connect both output nodes from the previous switch node to the input on this switch node. This will filter all commands from both switches to this node. In this node, the top output will be “on” and the bottom output will be “off”.

We’re almost done at this point. Now we need to use a call service node to turn on, and off the lights. I forgot to mention earlier that the easiest way to control multiple lights, is with a light group. This will create a “group.kitchen_lights” entity in Home Assistant. You’ll need to do this in your config.yaml or groups.yaml in Home Assistant.

Now we take a call service node, and configure it to control the kitchen_lights group. We need one for on, and one for off. The “on” node will be connected to the top output, and the “off” node will be connected to the bottom output.

Call service node to turn on the kitchen_light group.
Call service node to turn off the kitchen_light group.

Here is how the entire flow looks:

With this setup, we have Hue smart bulbs that are always powered and can be manually controlled by a switch. This allows individual bulbs to be used in automations and you don’t have to worry about the switches, like in me previous example of using lights 1 and 3 for a nightlight.

One more thing to keep in mind; When smart bulbs lose power, they will come on at full brightness when power is restored. The Hue bridge however has a setting for “power on behavior” where you can tell the bulbs what to do when power is restored.

Here is the formatted code if you’d like to import it and work off of it.