How to bind two states / build a toggle switch

Hello,

I’ve been banging my head against the wall for days so it’s time to ask for help. I have searched in forums and HA documentation yet I cannot find a solution. I don’t know how much detail is needed so I’ll describe my goal and my problem in the next paragraph, and will then follow with more details which may or may not be relevant - feel free to skip if it’s too much information.

Goal

I have a TV with audio output connected to a stereo system. I want to set up the stereo to come on when the TV is powered on, and to power off when the TV is powered off. I have two binary sensors in HA that indicate whether a TV and stereo system are on/off. I also have a momentary switch which toggles the power button on the stereo system (It’s an old stereo - I have literally soldered two wires to the PCB and have an ESP8266 running ESPHome with a relay physically short the wires mimicking the physical power button). I have a simple automation to toggle the stereo when TV power changes.

Problem

Now this works most of the time however the problem is that those power sensors are not instant, and neither is the stereo power toggle. As a result if I turn the TV on and off quickly the stereo powers on but does not power off and vice versa - if I turn the TV off and then on again the stereo will power down but will not power on again.

What I would like to do is to come up with a toggle switch for the stereo - after all I have a sensor which reflects it’s power state and a momentary switch to power it on/off. I have tried to build a template switch but no matter what I try it doesn’t work like a toggle switch but acts like a momentary switch.

Why this matters to me

One solution would be to set up another automation on a timer loop to check the states every 5s or so and, if they do not match, to toggle the stereo. While it would work I feel this is not a very elegant solution. Moreover, I have some other similar but more complex scenarios where that approach wouldn’t work. Finally, while this may be trivial, part of me thinks that constant timer loops with delays can be resource intensive although I might be making this up - if anyone knows more about how this stuff works under the hood let me know.

Details on my sensors / switch setup

Both my TV and stereo system have smart Wi-Fi power switches from Sonoff which measure power consumption. They are ESP8266 based so I have flashed them with ESPHome and they report almost instant power consumption of my devices (there’s maybe 500ms lag). In HA I have two binary template sensors which turn on when the power consumption goes above a certain threshold:

template:
  - binary_sensor:
      name: TV power state
      state: '{% if states(''sensor.tv_power'') | float > 10 %} on {% endif %}'
      delay_on: '00:00:03'
  - binary_sensor:
      name: Stereo power state
      state: '{% if states(''sensor.stereo_power'') | float > 10 %} on {% endif %}'

(There’s a 3s delay_on for the TV because the power consumption occasionally spikes momentarily which then triggers the stereo to switch on. I could potentially reduce this but I cannot eliminate it. The stereo sensor is actually instant however there is a delay in the actual stereo when being power on and off - even using the physical switch it takes about 3 seconds to power on/off - it shows greetings and goodbyes on the screen, and other stupid animations…)

The stereo switch is actually a relay soldered directly to the PCB of the stereo which mimics the press of a physical power button. It is controlled by an ESP8266 flashed with ESPHome and the following code - this is how ESPHome documentation advises to build a momentary switch:

switch:
  - platform: gpio
    pin: 5
    id: relay
    name: "Stereo switch"
    icon: "mdi:power"
    on_turn_on:
    - delay: 500ms
    - switch.turn_off: relay

The problem I have here is that this actually creates a toggle switch in HA. The toggle is normally off, it goes on when clicked and goes back off after 500ms.

You can see all above entities in the screenshot below where the stereo switch is this momentary power switch from ESPHome.
Screenshot 2024-04-06 235853

Questions

  1. How can I create a toggle switch to power my stereo system using the binary power sensor and the momentary switch? I’m obviously open to changing the code for the sensors and even the ESP switch on the stereo.
  2. How can I tie the states of my TV power and stereo power together? I.e. How can I make sure that the stereo will always power on when the TV is switched on, and then back off when the TV is switched off?
  3. Also, is there a way to basically tie the two states (like, for example, what you do in HVAC systems in USA where you want the fan to physically bound to the heater so it ALWAYS comes on when the heating is on) so that they would work both ways i.e. the TV would also come on if I power the stereo instead (this would be the opposite of what I’m trying to achieve here but I need this for other setups). It’s not exactly a smart TV but I have an Nvidia Shield player which can power it on/off via HDMI so I do have a way to power it on/off from HA).

Thanks for bearing and me and I welcome any suggestions.

I am digesting what you posted. This type of thing would be very nice to know.

Have you explored setting the default for float?

If you have anything unavailable it’s my understanding that the float filter cannot convert unavailable to a number especially in template sensors. Don’t quote me on that though…

float(0)

Thanks for your reply.

I’m afraid I can’t see how that would help me tie the two sensors or build a toggle switch? The sensor always reports on/off correctly as the power meter is always reporting a numeric value so that’s never been an issue.

you said you have 2 sensors. reporting the power of the tv and the stereo. it sounds like you have a smart tv with a direct integration connection to it. is that right?

if so, that integration is reliable in turning on/off the tv and also reporting whether the tv is on or off. is that right?

if that’s right, is the power sensor on the tv necessary and useful?

i definitely would not have a 5 second timer always checking.

if i understand your problem right, here’s what i would do:

  1. create a helper switch (this ends up creating an input_boolean. let’s call it input_boolean.stereo) - this will represent the power state that we want the stereo to have.

  2. how long does it take for the stereo to power on such that it’s ok to hit the toggle again? it sounds like if you hit the momentary toggle button too quickly, the second press fails. so how long of a wait is ok? for the below, let’s assume that’s 4 seconds… you can replace all the 4’s with whatever is right.

my first approach just to make sure things work is to put a damper on input_boolean.stereo. meaning that if it changes state, it needs to change states and stay in that changed state for 4 seconds. (trigger becomes state change for 4 seconds). that will prevent the issue you said about fast switching back and forth.

if it does trigger (new state for 4 seconds), then you synchronize the stereo to the input_boolean.stereo desired state. you do this by checking if sensor.stereo_power == input_boolean.stereo. ie if they are both on, or if they are both off. if they are the same (which may happen if you hit on/off quickly then wait) then do nothing. if they are not the same, then press you momentary button… which, presuming it works will then make the states the same.

i think that takes care of the fast bounce issue.

you said you wanted the tv and stereo to stay in sync. if you turn on the tv or stereo, the other turns on. you may be able to use this blueprint:

i would use this to sync your tv entity and the input_boolean.stereo entity. you didn’t say much about the tv entity so i don’t know what you’re using and if this blueprint will work for you. if it’s a media_player entity, it might not work since this is presuming the entities have “on” and “off” as its states, whereas the “on” state for a media_player is not always “on”. however if this blueprint doesn’t work, you can do it by hand easily enough.

caveats:
this approach would require that turning on/off the stereo is done via this input_boolean (which you can easily wrap a template switch around or just use it as an input_boolean). what i described above would not work to detect a manual ‘on’ of the stereo that then pumps the power sensor up then turns the input_boolean on. this can be addressed, but requires a bit more work.

this approach also introduces a bit of a delay (4 seconds) between when you ask the stereo to turn on / off before it actually turns on/off. this can be addressed with more work, but i haven’t gone into that. first wanted to run this approach by you and see if i understand the problem right and get your perspective on this solution…

1 Like

Hi armedad,

I really want to thank you for your response. It’s late on a Sunday and I’ll need a day or two to actually put something together. But I’ve ready through everything and I think that’s exactly what I was after just didn’t know how to word it. I’ll probably be able to stitch it together using an input_boolean. I always thought that Home Assistant is missing some sort of easy temp variable which could be set / read by different entities - I didn’t think to use input_booleans for that.

The sensor situation is actually a bit different.

The TV is not really smart, it doesn’t provide anything. For the purposes of this discussion let’s say it’s completely dumb. Just like the stereo it normally needs to be powered on/off manually.

For both TV and stereo I have two identical smart switches with power meters. I use the same approach for both TV and stereo. As described in my binary sensor code, once the power meter hits 10W or more the sensor reports on - otherwise it’s off.

For the stereo I have wired a relay to the PCB to mimic the press of a physical power button - this then provides a momentary switch in HA to toggle it between on/off. You are absolutely right when you talk about the debounce issue - it takes approximately 4-5 seconds for the stereo state to change (it goes through some stupid animations on the screen…) and if another toggle command is sent in that time it simply doesn’t register (an input_boolean would allow me to capture it and then correct it 4-5 seconds later just as you described).

The TV itself does not have any way to power it remotely. However, it does support HDMI CEC and my main player (used 98% of the time) is Nvidia Shield. Now Nvidia Shield is “smart” and through an integration it does provide a power toggle switch in HA. So effectively by turning the Shield player on/off (manually or through HA) I can turn the TV on/off. Effectively it’s a similar situation to my stereo - I have an on/off sensor which cannot control the power state and then I have a separate toggle (through the Shield player) so the two combined could become a TV power switch.

I’ll do some tinkering in the next 1-2 days and will report back :wink: Thank you!

ok, so if I understand the nvidia shield situation, for all intents and purposes, we can think of it as the smart TV switch that does indeed have reliability in turning on/off and accurately reporting state… is that right? of so what is the role for the power sensor for the tv? In what scenario would you think you would need it?

one thing I thought of … for that second automation that triggers after 4 seconds, key that off of input_boolean.stereo != sensor.stereo_power for 4 seconds… ie trigger not on a state change, but of discrepancy of state between the desired and the observed state. this would allow the bouncing of the switch all you’d like and only trigger if the last state is diff than actual.

noodle on all of this. If this mental model is right, I’m happy to help code it if you need … I don’t know your coding skills level and whether you just needed to figure out the approach or need help with the implementation as well

I thought you were going to ask that :smiley: the power sensor actually came first, before I even had the Shield player. However, the ongoing benefit is that it reports the state of TV no matter which input I use - while most of the time (probably 98% of the time) it’s Shield player, I do have a gaming console and a PC input that are used occasionally. I need the stereo to come on when those other inputs are being used, not just when the Shield player is active.

I’m somewhat YAML challenged but I can usually piece things together following examples on HA documentation or here. I just need to set aside an hour or two and actually give it a go - hopefully today :wink:

Thanks and I’ll report back soon.

ah, well that is new news about the TV being turned on via other devices. that would require more code than I outlined above. however I would still start with what I have and build up from there. ie write it first so that it requires the shield to turn on/off the tv

Hi Armedad,

So, I think I can call this a success. At first I did everything as you suggested using an input_boolean. It worked but it required several automations in addition to this input_boolean so it wasn’t very elegant. However, I used your idea of using != as a trigger, cut out the middle man and just did a very basic automation - works like a charm.

trigger:
  - platform: template
    value_template: >-
      {{ states('binary_sensor.stereo_power_state') !=
      states('binary_sensor.tv_power_state') }}
    for:
      hours: 0
      minutes: 0
      seconds: 5
action:
  - service: switch.turn_on
    target:
      entity_id: switch.stereo_switch

Using the != discrepancy as a trigger is much more reliable than using the change of state as a trigger. Now, I don’t have the toggle switch for the stereo like I would with an input_boolean but, since this is working so reliably, I don’t actually need it. Fewer automations, less clutter :slight_smile:

Bottom line is thank you - problem solved.

1 Like

awesome! glad to hear it!

1 Like

btw… I can see some limitations on this certainly. but if you’re happy with it then golden! if you later decide to get adventuresome with it, don’t hesitate to holler. I do think it would take 2 automations to make it work… But it can/should still be elegant…

still most important is that it works for what you want it to do!

Could you elaborate on those limitations you anticipate?

As an example if I understand it right, you are keying everything on the TV power. and focused on the ‘on’ state. unless there are other automations not posted here.

so it means you must turn things on via the tv. can’t initiate via stereo.

so I’m guessing you either have other automations at play or you are ok w these limitations

Sorry for the delay - been busy busy busy.

You are quite right, at the moment the stereo is passive and simply follows the TV power state. At the moment I’m actually okay with this and I don’t really need it to work the other way round at this time.

I am, however, grateful that you’ve helped me figure it out because I do have a few other entities where I do need to sync their states - or make them mutually exclusive (for example, switching heating off when the window is open and then back on when it is closed and few others like that).

I still find it all rather inelegant - for each such scenario I need at least a single input_boolean and several automations. These are then under different tabs (automations and helpers) and I cannot see them all at once on one screen. That’s a lot more fiddly than say a actual programmed while loop or an if/then/elseif sort of loop. But that’s more of a HA limitation. I guess with new labels that’s solved somewhat.

Either way, thanks, it helped me understand how to utilize input_booleans and input_selects a bit better :wink: