MQTT Switch - value_template

Hi,

digging into MQTT and a switch.

switch:
  - platform: mqtt
    name: "Venus GX Relay 0"
    state_topic: "N/xxx/system/0/Relay/0/State"
    value_template: "{{ value_json.value == 1 }}"
    command_topic: "W/xxx/system/0/Relay/0/State"
    payload_on: '{"value": 1}'
    payload_off: '{"value": 0}'

The MQTT state is a json object. See Payload on/off.

I cant get the state extracted with the value template. Any help appreatiated.

Regards
Ralf

I think you need to remove the “==1” from the value template and the just use “1” & "0’ in the payload.

I think…

switch:
  - platform: mqtt
    name: "Venus GX Relay 0"
    state_topic: "N/xxx/system/0/Relay/0/State"
    value_template: "{{ value_json.value }}"
    command_topic: "W/xxx/system/0/Relay/0/State"
    payload_on: 1
    payload_off: 0

Hello finity,

Thanks for chiming in. Unfortunately its not working as proposed.

with this payload the switch.turn_on/off services work, but switch.toggle does not.

    payload_on: '{"value": 1}'
    payload_off: '{"value": 0}'

For me this points into the direction that the payload definition is good, but the value extraction does not work.

I assume the value 1/0 need to be transfered to ON/OFF somehow?

Regards
Ralf

What do you have to send as the payload when you turn the switch off & on? do you send 0 & 1 or off & on or even OFF/ON (it make a difference)?

And then what does the switch send back for the status payload?

Turning it off is {"value": 0} and on is {"value": 1}.

The status topic is similar.

This works. I still find it unintuitive …

  - platform: mqtt
    name: "Venus GX Relay 0"
    state_topic: "N/0cae7d63f546/system/0/Relay/0/State"
    command_topic: "W/0cae7d63f546/system/0/Relay/0/State"
    payload_on: '{"value": 1}'
    payload_off: '{"value": 0}'

you mean removing value_template does the trick?

Absolutely yes.

I think it is intuitive, did you read the docs?
So if your payload_on represents what you need, there is no need to use[value_template](https://www.home-assistant.io/integrations/switch.mqtt/#value_template)
I believe that if you define it like

value_template: >
    {"value": {{ value_json.value }}}

your switch will work.

And if you define it like this
yaml</s> <s>value_template: ></s> <s> {{ 'ON' if value_json.value == 1 else 'OFF' }}</s> <s>
there will be no need to have payload_xxx if I remember it right

EDIT: well, it will work only for displaying state of your switch in HA but it won’t let you control your relay as ON/OFF (default values) won’t be recognised (see this post for more details).

It’s not intuitive only because you have instructed Home Assistant to match the literal JSON string in the payload. Normally, when the payload contains a JSON string, you would refer to it using value_json in the value_template.

You’re not doing that and have chosen to match the string verbatim. You may believe it’s a Solution but what you’ve done is work around the reason it originally failed.

The problem is that the JSON string’s key is called value. That word has special meaning for Home Assistant (just like value_json). If the value_template looks like this:

{{ value_json.value }}

it is using what is called “dot notation” to refer to value key in {value: 1} and will fail because the meaning of value is now ambiguous (i.e. do you want the value key or the special meaning of value?).

If you use “bracket notation” then the meaning of value becomes clear to Home Assistant. You don’t want the ‘special meaning’ you simply want it to refer to the value key in the payload.

{{ value_json['value'] }}

I’ve test the following and it works:

switch:
  - platform: mqtt
    name: "Venus GX Relay 0"
    state_topic: "N/xxx/system/0/Relay/0/State"
    value_template: "{{ value_json['value'] }}"
    command_topic: "W/xxx/system/0/Relay/0/State"
    payload_on: 1
    payload_off: 0

EDIT

Nice theory but not the cause of the problem. :man_shrugging:

1 Like

Dang!

I missed that but I was so close!

:laughing:

Hello Taras,

thanks for stepping in. I feel the need to appologize for using the phrase “unintuitive”. Better I would have used the phrase “I dont understand”.

  - platform: mqtt
    name: "Venus GX Relay 2"
    state_topic: "N/xxx/system/0/Relay/1/State"
    value_template: "{{ value_json['value'] }}"
    command_topic: "W/xxx/system/0/Relay/1/State"
    payload_on: 1
    payload_off: 0

I changed the code to what you proposed. Now the state changes work. I switch the Relay from outside of HA and HA recognizes the change.

However changing it in HA has no effect on the actual relay/hw anymore.

When subscribe to mosquito I see in MQTT.fx that HA sends they Payload not as JSON {"value": 1} but exactly as specified in the payload option as 1.

Any idea how to trouble shoot?

Regards
Ralf

that’s expectable as it’s used for both receiving and sending.
this one was the right one :wink:
and we all forgot about the sending bit :frowning:

Correct. Here’s how it works:

If you specify payload_on and payload_off, they define both the received and transmitted states. If you want the received state to be different from the transmitted state, you must also use state_on and state_off.

  - platform: mqtt
    name: "Venus GX Relay 2"
    state_topic: "N/xxx/system/0/Relay/1/State"
    value_template: "{{ value_json['value'] }}"
    command_topic: "W/xxx/system/0/Relay/1/State"
    state_on: 1
    state_off: 0
    payload_on: '{"value": 1}'
    payload_off: '{"value": 0}'

However, even though the example I’ve just presented is technically correct, it is needlessly complicated.

The fact is the switch you are using presents its data in JSON format but there’s no benefit to handling it in JSON format! The data is so simple that the best way to handle it is the way you did it. Just ignore the JSON format and interpret the received payload verbatim.

  - platform: mqtt
    name: "Venus GX Relay 0"
    state_topic: "N/0cae7d63f546/system/0/Relay/0/State"
    command_topic: "W/0cae7d63f546/system/0/Relay/0/State"
    payload_on: '{"value": 1}'
    payload_off: '{"value": 0}'

tl;dr
Your solution is the best choice for this particular situation.

hmm… Here’s what I created to test your hypothesis - 2 sensors

- platform: mqtt
  name: test_bracket
  state_topic: "test/State"
  value_template: >
    {{ value_json['value'] }}

- platform: mqtt
  name: test_dot
  state_topic: "test/State"
  value_template: >
    {{ value_json.value }}

and 2 switches

- platform: mqtt
  name: test_bracket
  state_topic: "test/State"
  command_topic: "test/Command"
  value_template: >
    {"value": {{ value_json['value'] }}}
  payload_on: '{"value": 1}'
  payload_off: '{"value": 0}'

- platform: mqtt
  name: test_dot
  state_topic: "test/State"
  command_topic: "test/Command"
  value_template: >
    {"value": {{ value_json.value }}}
  payload_on: '{"value": 1}'
  payload_off: '{"value": 0}'

I then published '{"value": 1}' and '{"value": 0}' messages to test/State topic and I saw no difference in my _dot and _ bracket versions’ states.
I expected sensor.test_dot to be different and even published '{"value": 1, "extra": 2}' but it’s still 1 for both sensors.

Therefore it seems to me that it’s ok to have value key in JSON and we can use it safely in both dot and bracket notations as any other key.

The reason TS’s original config didn’t work was the result of value_template (they most likely mixed MQTT switch with MQTT Binary Sensor) and to fix it they can either make it return a value that agrees with payload_on/payload_off or just delete it completely - as described in my previous reply.

And as it was pointed out, because we have a switch, payload_xxx is used to determine its new state (when HA receives a new message) and to control the device (as HA sends payload_xxx depending on the switch’s current state to toggle the device’s state) so we should not change it or fall back to the default values (ON/OFF).

You’re right but, in the final analysis, rak’s solution is the best one for this switch.

well, they broke it and they fixed it (by trial and error I presume) - I don’t mind, really :wink:
just wanted to make clear that ‘special meaning’ situation :wink:

In this case, I was wrong. However, there are situations where ‘special meaning’ (a.k.a. reserved word) did prove to be a source of ambiguity:

Looking at this topic and the MQTT Switch documentation (pretty sure other MQTT integrations are the same) I have to say that docs would do with improvements as there is a complex relationship between some of the configuration variables (payload_xxx, state_xxx and value_template in this case) but it’s not reflected there at all or well enough to understand how to use them.
Might make a PR when I have time.