Switch state always return to off

Hi, I’m need help on how to correctly read switch states (on/off) from mqtt message.
I can control the switches but the state always return to off state.

Installation details

OS: RaspbianOS 64 bit on Raspberry Pi 4 4GB
Home assistant docker image: ghcr.io/linuxserver/homeassistant
Home assistant version: core-2021.5.5
Mqtt docker image: eclipse-mosquitto: 1.6.13

Zigbee hub: Sonoff ZbBridge flashed with Zigbee2Tasmota
Switch: Xiaomi Aqara (QBKG03LM). Double key wired wall switch without neutral wire. 

Below are the on & off mqtt messages from Tasmota console:

Button 1 on: 
tele/zbBridge/1A90/SENSOR = {"ZbReceived":{"0x1A90":{"Device":"0x1A90","Name":" br3WallSwitch","Power":1,"0006/F000":52072473,"Endpoint":2,"LinkQuality":97}}} (retained)
tele/zbBridge/1A90/SENSOR = {"ZbReceived":{"0x1A90":{"Device":"0x1A90","Name":" br3WallSwitch","Power":0,"Power2":1,"Endpoint":4,"LinkQuality":107}}} (retained)

Button 1 off: 
tele/zbBridge/1A90/SENSOR = {"ZbReceived":{"0x1A90":{"Device":"0x1A90","Name":" br3WallSwitch","Power":0,"0006/F000":52072473,"Endpoint":2,"LinkQuality":102}}} (retained)
tele/zbBridge/1A90/SENSOR = {"ZbReceived":{"0x1A90":{"Device":"0x1A90","Name":" br3WallSwitch","Power":0,"Power2":1,"Endpoint":4,"LinkQuality":105}}} (retained)
Button 2 on: 
tele/zbBridge/1A90/SENSOR = {"ZbReceived":{"0x1A90":{"Device":"0x1A90","Name":" br3WallSwitch","Power":1,"0006/F000":52072471,"Endpoint":3,"LinkQuality":100}}} (retained)
tele/zbBridge/1A90/SENSOR = {"ZbReceived":{"0x1A90":{"Device":"0x1A90","Name":" br3WallSwitch","Power":0,"Power2":1,"Endpoint":5,"LinkQuality":94}}} (retained)

Button 2 off: 
tele/zbBridge/1A90/SENSOR = {"ZbReceived":{"0x1A90":{"Device":"0x1A90","Name":" br3WallSwitch","Power":0,"0006/F000":52072471,"Endpoint":3,"LinkQuality":105}}} (retained)
tele/zbBridge/1A90/SENSOR = {"ZbReceived":{"0x1A90":{"Device":"0x1A90","Name":" br3WallSwitch","Power":0,"Power2":1,"Endpoint":5,"LinkQuality":102}}} (retained)

Home assistant configuration.yaml:
Since this switch have 2 button and I have to check 2 state: Power & Endpoint, below are my configuration

# Button 1 conf:
- platform: mqtt
  unique_id: "br3WallFan"
  name: "br3WallFan"
  state_topic: "tele/zbBridge/1A90/SENSOR"
  value_template: >
  {%- if value_json['ZbReceived']['0x1A90']['Power'] == 1 and value_json['ZbReceived']['0x1A90']['Endpoint'] == 2 -%}
  on
  {%- elif value_json['ZbReceived']['0x1A90']['Power'] == 0 and value_json['ZbReceived']['0x1A90']['Endpoint'] == 2 -%}
  off
  {%- else -%}
  {{ states('switch.br3wallfan') }}
  {%- endif -%}
  command_topic: "cmnd/zbBridge/ZbSend"
  payload_on: '{"device": "0x1A90","send":{"Power":1},"endpoint":2}'
  payload_off: '{"device": "0x1A90","send":{"Power":0},"endpoint":2}'
  availability_topic: "tele/zbBridge/LWT"
  payload_available: "Online"
  payload_not_available: "Offline"
  retain: true
# Button 2 conf:
- platform: mqtt
  unique_id: "br3WallLight"
  name: "br3WallLight"
  state_topic: "tele/zbBridge/1A90/SENSOR"
  value_template: >
  {% if value_json.ZbReceived is defined and value_json.ZbReceived['0x1A90'] is defined and value_json.ZbReceived['0x1A90'].Power is defined and value_json.ZbReceived['0x1A90'].Endpoint is defined %}
  {% if value_json.ZbReceived['0x1A90'].Power == 1 and value_json.ZbReceived['0x1A90'].Endpoint == 3 %}
  on
  {% else %}
  off
  {% endif %}
  {% else %}
  {{ states('switch.br3walllight') }}
  {% endif %}
  command_topic: "cmnd/zbBridge/ZbSend"
  payload_on: '{"device": "0x1A90","send":{"Power":1},"endpoint":3}'
  payload_off: '{"device": "0x1A90","send":{"Power":0},"endpoint":3}'
  availability_topic: "tele/zbBridge/LWT"
  payload_available: "Online"
  payload_not_available: "Offline"

I tried 2 different setting for each button, but both does not read the correct switch state and always return to off in lovelace UI.

Any idea how to fix it? And thank you in advance.

Here is a thread where I (partially) helped someone in a similar situation. It may help you:

Thanks @finity for that link, changing on/off in the value_template to be the same as on/off payload fixed the issue.

Here my fixed configuration for other reference:

  - platform: mqtt
    unique_id: "br3WallFan"
    name: "br3WallFan"
    state_topic: "tele/zbBridge/1A90/SENSOR"
    value_template: >
      {% if value_json['ZbReceived']['0x1A90']['Endpoint'] == 2 %}
      {%- if value_json['ZbReceived']['0x1A90']['Power'] == 1 -%}
        {"device": "0x1A90","send":{"Power":1},"endpoint":2}
      {%- else -%}
        {"device": "0x1A90","send":{"Power":0},"endpoint":2}
      {% endif %}
      {% else %}
      {{ states('switch.br3wallfan') }}
      {% endif %}
    command_topic: "cmnd/zbBridge/ZbSend"
    payload_on: '{"device": "0x1A90","send":{"Power":1},"endpoint":2}' 
    payload_off: '{"device": "0x1A90","send":{"Power":0},"endpoint":2}'
    availability_topic: "tele/zbBridge/LWT"
    payload_available: "Online"
    payload_not_available: "Offline"
    retain: true

  - platform: mqtt
    unique_id: "br3WallLight"
    name: "br3WallLight"
    state_topic: "tele/zbBridge/1A90/SENSOR"
    value_template: >
      {% if value_json['ZbReceived']['0x1A90']['Endpoint'] == 3 %}
      {%- if value_json['ZbReceived']['0x1A90']['Power'] == 1 -%}
        {"device": "0x1A90","send":{"Power":1},"endpoint":3}
      {%- else -%}
        {"device": "0x1A90","send":{"Power":0},"endpoint":3}
      {% endif %}
      {% else %}
      {{ states('switch.br3walllight') }}
      {% endif %}
    command_topic: "cmnd/zbBridge/ZbSend"
    payload_on: '{"device": "0x1A90","send":{"Power":1},"endpoint":3}' 
    payload_off: '{"device": "0x1A90","send":{"Power":0},"endpoint":3}'
    availability_topic: "tele/zbBridge/LWT"
    payload_available: "Online"
    payload_not_available: "Offline"
    retain: true
2 Likes