Trouble with two 3-way smart switches in Home Assistant

I have 2 Treat-Life 3-way switches that have been tasmotized. I installed one at the top of the stairwell and the other at the bottom in the same fashion that my “dumb” switches were installed. They have been configured with the correct template from the tasmota repository and I have my MQTT set up. Just like all the other tasmota devices, everything went fine, but when I brought them into home assistant, it’s not working correctly. The manual controls work fine and the states change in home assistant, but when I trigger the device from home assistant, nothing happens. I did find an automation so the states would mirror each other, but it has not made any change to the current issue. This is my first 3-way setup and I am probably missing something simple, but does anyone have any advice or a reference I can use? Here is the automation yaml in case something needs to be added or removed to solve the problem.

Copy to clipboard

- alias: Stairwell Light
  trigger:
    - platform: state
      entity_id: switch.stair_light_bottom, switch.stair_light_top
      from: 'on'
      to: 'off'
    - platform: state
      entity_id: switch.stair_light_bottom, switch.stair_light_top
      from: 'off'
      to: 'on'
  action:
    service_template: >
      {% if trigger.to_state.state == "on" %}
      switch.turn_on
      {% elif trigger.to_state.state == "off" %}
      switch.turn_off
      {% endif %}
    data_template: 
      entity_id: >
        {% if trigger.from_state.entity_id == "switch.stair_light_bottom" %}
        switch.stair_light_top
        {% elif trigger.from_state.entity_id == "switch.stair_light_top" %}
        switch.stair_light_bottom
        {% endif %}

I wouldn’t worry about getting the “mirroring” to work until the switches work correctly.

What is the template you used for the switches in HA?

The switches are Treat-Life 3-way SS01 switches and I used this template from the tasmota repository:

{"NAME":"Treatlife SS01 3-Way","GPIO":[0,0,0,0,21,158,0,0,22,18,9,0,0],"FLAG":0,"BASE":18}

Yeah, I wasn’t talking about the tasmota template. I was talking about the template in HA you used to get them to show up in HA. Or did you use discovery to get them into HA?

Sorry, just read that wrong. Saw template and immediately thought tasmota. I used discovery to bring them into HA.

I think the easiest way to troubleshoot is to start up a MQTT sniffer and watch for the messages that are generated by the tasmota console when you operate the switches and then compare them to what HA is sending & receiving when you operate them from HA.

I use MQTTFx for this or you can go to the mqtt section of HA and subscribe to # (all topics).

Sorry for not responding sooner. It has been a hectic week. I used MQTT Explorer and watch the messages being generated. When I configured the switches in tasmota, I saw that they had 2 relays per switch. I was assuming that relay 1 was the main relay and relay two was for the status LED. WRONG. It is actually the other way around. So now I can toggle the light in Home Assistant. If both switches are in the same state then the light comes on just like manual 3-way switches.

Ex.
Switch1 R2=OFF, Switch2 R2=OFF, Light=ON
Switch1 R2=ON, Switch2 R2=OFF, Light=OFF
Switch1 R2=OFF, Switch2 R2=ON, Light=OFF
Switch1 R2=ON, Switch2 R2=ON, Light=ON

So now that I know this, I want to be able to show that in Home Assistant. With my regular lights, I know that if the switch is on then the light is on and I can show that on an Entities Card. Is there anyway to use the two switches but only have one entity on the card that follows the state of the light. Since there isn’t an entity for the light, I am getting stuck. I have tried using Light Switch, but there are 2 switches. Is there a way to compare the 2 switches and have when the states are equal, then the light is on? I have been reading the forums and docs, but I can’t find exactly what I am trying to do. I know there is a good chance that it can’t be done but any suggestions?

I know this isn’t the same device as yours but maybe you can use the rules.

My device shows 2 toggles but I only use the 1 in HA.

Have you looked at using a template light?

With that you can do almost anything you want.

I looked into template light and it seems that will do what I want it to do as long as I get the syntax correct. This is what I have so far, but it is coming up as invalid

light:
  - platform: template
    lights:
      stair_lights:
        friendly_name: "Stairwell Light"
        value_template: >-
          {% if is_state('switch.bottom_stairwell == switch.top_stairwell', 'on') %} or
          {% if is_state('switch.bottom_stairwell == switch.top_stairwell', 'off') %}
            on
          {% else %}
            off
          {% endif %}
        turn_on:
          service: light.turn_on
          entity_id: light.stair_lights
        turn_off:
          service: light.turn_off
          entity_id: light.stair_lights

I started with the example from the Template Light documentation and added my entities. I went to the jinja2 documentation and saw the comparison and the logic syntax. So the way I am interpreting it is "If the states of the Bottom Switch and Top Switch are equal (on), or if the states of the Bottom Switch and Top Switch are equal (off), set Stairwell Light on. If not then set Stairwell Light off. When I check the configuration, I get this message:

 Invalid config for [light.template]: invalid template (TemplateSyntaxError: Unexpected end of template. Jinja was looking for the following tags: 'elif' or 'else' or 'endif'. The innermost block that needs to be closed is 'if'.) for dictionary value @ data['lights']['stair_lights']['value_template']. Got "{% if is_state('switch.bottom_stairwell == switch.top_stairwell', 'on') %} or {% if is_state('switch.bottom_stairwell == switch.top_stairwell', 'off') %}\n  on\n{% else %}\n  off\n{% endif %}". (See ?, line ?). 

I’m not understanding what it means by the innermost block. Any ideas?

try this:

{% if (is_state('switch.bottom_stairwell', 'on') and is_state('switch.top_stairwell', 'on')) or (is_state('switch.bottom_stairwell', 'off') and is_state('switch.top_stairwell', 'off')) %}
  on
{% else %}
   off
{% endif %}

Awesome. That allows me to add light.stair_lights to an entities card and see the stair light state, but the slider/toggle does not allow me to turn the light on or off That was my original intention to have both switches combined into one and that new entity to be able to show the state and control the light. The first part is good but is the second part even possible?

Yes.

Change the turn_on & turn_off actions to control the switches, not the light you just created

turn_on:
  service: switch.turn_on
  entity_id: 
    - switch.bottom_stairwell
    - switch.top_stairwell
turn_off:
  service: switch.turn_off
  entity_id: 
    - switch.bottom_stairwell
    - switch.top_stairwell

I think that should work.

Made the change and now i can see the state of the light on the entities card, and if the light is OFF toggling will turn the light on, but if it is ON toggling will not work. I can hear the relay click but the light remains on. I checked with MQTT Explorer and that configuration is essentially turning the light back on because both switches are in the same state of OFF. I deleted one of the switches from the turn_off action and now it works perfectly regardless of switch position or state. THANK YOU!!!

Here is the final yaml:

light:
  - platform: template
    lights:
      stairs:
        friendly_name: "Stairwell Light"
        value_template: >-
          {% if (is_state('switch.bottom_stairwell', 'on') and is_state('switch.top_stairwell', 'on')) or (is_state('switch.bottom_stairwell', 'off') and is_state('switch.top_stairwell', 'off')) %}
            on
          {% else %}
            off
          {% endif %}
        turn_on:
          service: switch.turn_on
          entity_id:
            - switch.bottom_stairwell
            - switch.top_stairwell
        turn_off:
          service: switch.turn_off
          entity_id:
            - switch.bottom_stairwell

Thanks again

1 Like

Hello, anyway to get this working with 4-way switch?
I made the same thing but with 3 switches instead of 2 and sometimes it’s working and sometimes not.
Here’s how mine look like:

- platform: template
  lights:
    front_staircase_3_way:
      friendly_name: Front Staircase 3 Way
      value_template: >-
        {% if (is_state('switch.2nd_livingroom_2_right', 'on')
          and is_state('switch.1st_livingroom1_2_right', 'on')
          and is_state('switch.front_door_2_left', 'on'))
        or (is_state('switch.2nd_livingroom_2_right', 'off')
          and is_state('switch.1st_livingroom1_2_right', 'off')
          and is_state('switch.front_door_2_left', 'off')) %}
            on
        {% else %}
          off
        {% endif %}
      turn_on:
        service: switch.turn_on
        entity_id:
        - switch.2nd_livingroom_2_right
        - switch.1st_livingroom1_2_right
        - switch.front_door_2_left
      turn_off:
        service: switch.turn_off
        entity_id:
        - switch.2nd_livingroom_2_right

Tough one. I personally do not have any applications for a 4-way setup, but it could be a couple of things.
First, could be the wiring. Are you using existing wiring that was already used in a 4-way setup? Did you wire the new switches in the correct way? Can you provide a diagram? What switches are you using?
If that is all good, then it could be the yaml. If I am not mistaken, a 4-way setup with 3 switches works like this: ( switches 1 & 3 are 3-way, switch 2 is 4-way)

1,2,3
down, down, down, = off
up, down, down, = on
up, up, down, = off
up, up, up, = on
down, up, up, = off
down, down, up, = on

Your yaml configuration would depend on which switch is the 4-way and which two are the 3-ways.

Thanks for answering. I don’t use the existing switches wiring. I only have one switch wired directly to the light and the other 2 switches are not wired to anything, just connected to live and neutral wire for power.
Here’s the wiring diagram:

  • switch.2nd_livingroom_2_right = xiaomi aqara 2 gang connected to actual light
  • switch.1st_livingroom1_2_right = xiaomi aqara 3 gang not connected to light
  • switch.front_door_2_left = xiaomi aqara 2 gang not connected to light

I don’t actually know how to describe the 4 way switch state, so it’s really hard to template it :sweat_smile:

If this is what I need to aim, so I need to get the turn on action to turn 2 switches to off/on state? My brain is hurting from thinking now :sweat_smile:

Ok now I get what you are trying to do. You want the main switch connected to the light, to control the light, and the other two switches to control the main switch.

I’m not sure if this would work, but could you possibly create a template switch using the two secondary switches.

switch:
  - platform: template
    switches:
        value_template: "{{ is_state('switch.1st_livingroom1_2_right', 'on') or is_state('switch.front_door_2_left', 'on') }}"
        turn_on:
          service: switch.turn_on
          target:
            entity_id: switch.2nd_livingroom_2_right
        turn_off:
          service: switch.turn_off
          target:
            entity_id: switch.2nd_livingroom_2_right