Automating my TV

One of the lazy things that I've tried to do was have the Amazon Echo turn my TV on and off. When I had Home Assistant running on my Raspberry Pi, I used a component that controlled the TV and Apple TV via HDMI CEC. Unfortunately it wasn't quite reliable and I lost the ability to use it when I migrated to a VM for Home Assistant.

In a recent release of Home Assistant, support was added for Roku and since I have a TCL Roku TV, I decided to give it a try. The component itself works, but has a few major limitations for me. First off it initializes on Home Assistant startup. In order to conserve a little energy, I have my TV, Apple TV, and sound bar on a Z-Wave controlled outlet. The outlet doesn't turn on until the afternoon, so most of the time when Home Assistant restarts (I have it restart at 6 am so that my audio distribution units initialize as they also turn off at night), the TV isn't turned on. The second issue has to do with the TV going to sleep. It has a deep sleep and a fast start mode; fast start uses more energy, so I leave it off. The Roku component uses HTTP commands to control the device or TV; when the TV is in deep sleep, it doesn't respond to HTTP commands. This, of course, makes it impossible to turn on the TV with the component.

After thinking about this problem for awhile, I came up with some Node-RED flows to turn on the TV and handle status updates. The TV, it turns out, responds to a Wake-On-LAN packet as I have it connected via Ethernet and Home Assistant has a WOL component that lets me send the packet.

My flow to check on the TV state is a bit complicated.

  1. First it pings the TV. The ping is done every 10 seconds.
  2. If the TV responds, it sends an HTTP request to the TV.
  3. When the response comes back, it is parsed, the current application running is checked. This also lets me know what Roku channel is currently active. I have noticed that my TV reports that the Davinci Channel is active when I turn the TV off, so I special case that.
  4. If the channel is not null and not the Davinci Channel, I then send a command to check to see if the display is off.
  5. After I figure out the app and if the display is off, I craft a new payload with the current channel in it.
  6. The payload is then sent in an HTTP request back to Home Assistant's HTTP Sensor API
  7. If the TV doesn't respond to the ping, I set the payload to off and then send the state to the Home Assistant API.

Tv state flow

Turning on the TV is a bit less complicated.

  1. Send WOL packet to TV.
  2. Pause.
  3. Send HTTP command to turn on TV.
  4. Send HTTP command to set input to HDMI3 (my Apple TV).

Turning off the TV is even easier.

  1. Send HTTP command to turn off TV.

Tv on off flow
When I turn on the TV outlet, the state of the TV gets updated pretty quickly as the ping command from above is running every 10 seconds.

I've posted the Node-RED flows below that can be imported and modified for your situation.

Download Node-RED flow to turn Roku TV on/off

Download Node-RED flow to get current TV state