How to configure the expected values of the MQTT state of a switch?

Hello everyone

I would like to configure a simple MQTT switch which maintains its state (namely a Sonoff Basic).

To do so, I configured is as

light "ch1-lampe-bureau":
  platform: mqtt
  state_topic: "ch1-lampe-bureau/status"
  command_topic: "ch1-lampe-bureau/relay/0/set"

It appears in my Home Assistant web interface, with a slider to switch it on and off

When moving the slider, it goes to the “on” (blue) position and then goes back to “off”. At the same time, the lamp switches on.

This switch listens to the topic ch1-lampe-bureau/relay/0/set in order to change its state (this is successfully sent by HA), and subsequently sends a state value (0 or 1) to ch1-lampe-bureau/status.

I guess that Home Assistant does not recognize this 0 or 1 as being a proper state and I should be able to tell him what to expect.

What is the configuration entry I should use?

I saw something which may be a match:

state_value_template

(string)(Optional)Defines a template to extract the state value. The template should match the payload on and off values, so if your light uses power on to turn on, your state_value_template string should return power on when the switch is on. For example if the message is just on , your state_value_template should be power .

I just do not understand what this sentence mean (despite having an example - I just cannot place my 0 or 1 in this)

Can you paste exactly the messages (topic and payload) being sent. That way somebody can match the configuration for you.

The feedback message (the one the device sends after a change of state, or every few minutes) is

ch1-lampe-bureau/status 1
ch1-lampe-bureau/status 0

(depending on the state)

In the meantime I tried to interpret the state_value_template configuration item (which seems to be the only one which matches my use case) but they do not work

state_value_template: "{% if value == 0 %} 'OFF' {% else %} 'ON' {% endif %}"

or

state_value_template: "{% if value == '0' %} 'OFF' {% else %} 'ON' {% endif %}"

(I tried both in case the 0 is transmitted as a string or an int - which is not obvious from mosquitto output). I am not sure I understand the idea of the parameter at all, though.

I think you just need to remove the quote marks from the result, otherwise they get included.

state_value_template: "{% if value == '0' %}OFF{% else %}ON{% endif %}"

Edit:
Sorry, I think I copied the wrong one. value is always a string, so needs to be compared against that, unless you convert it to a float

That was a good idea but unfortunately it did not work (I tried both 0 and '0' just in case).

All my MQTT lights use 0 for OFF and 1 for ON for both command and state topics.

I use payload_on and payload_off to translate the message format. It handles both command and state topics.

light:
  - platform: mqtt
    name: "ch1-lampe-bureau"
    state_topic: "ch1-lampe-bureau/status"
    command_topic: "ch1-lampe-bureau/relay/0/set"
    payload_on: "1" 
    payload_off: "0"
    retain: false

I suggest you configure your MQTT light (are you using Tasmota?) to publish its state with retain=true. This ensures that when you restart Home Assistant, it will receive the light’s current state.

You need an MQTT tool like MQTTbox or MQTT.fx to see what MQTT messages and topics are going through your hub. If you are using Tasmota, I recommend you only change the topic variable in the setup. This makes the command and state topics more predictable.

You say the light is going on but the switch turns off a second later. This means that Home Assistant did not get a status from the switch.

Using your MQTT tool, subscribe to # and watch what MQTT messages are published when you turn the switch from Home Assistant on. You can also see what messages the Sonoff Basic publishes when you press the button.

Or if course use mosquitto_sub, which is included with the mosquito broker anyway.

@stevemann @nickrout I am not sure what was not clear in my question regarding this? (I would be glad to clarify)

I know which messages are sent and can read on the MQTT bus (either with mosquitto_sub but it is not practical as it does not show the topics, or I have a monitoring system which grabs every message (and its topic) anyway). I also mentioned them (and the whole timeline of what happens where) in the question.

@123 When HA sends an ON message to my switch (running Espurna) it gest correctly switched on (and, similarly, an OFF messages switches it off). I will try to change this to 1 and 0 (= force HA to send 1instead of ON etc.) and see if this works.

If it does it solves this exact problem (which is good already), but not the overall one of having different command and status messages for the state (hopefully solved via state_value_template)

If I had a switch that was controlled with on/off and reported its status with 1/0 then I would:

Re-program it!

Make it use on/off or 1/0, not both. It’s neater and will prevent having to create a state_template in Home Assistant. If you can’t re-program it then maybe this template will work for you:

    state_value_template: >-
      {% set values = { '0':'off', '1':'on'} %}
      {{ values[value] if value in values.keys() else 'off' }}

MQQTbox does show the topic. MQTT.fx does also, but it takes a bit more effort. (Click on the topic to see the message data).

I think the problem is that this should be value_template

  value_template: "{% if value == '0' %}OFF{% else %}ON{% endif %}"

mosquitto_sub does show topic, use the -v switch.

1 Like