MQTT Switch, payload, state, command

Hey all, Just got a question about the interaction of the payload_on, payload_off and value_template

I need to publish to control it:
publish (command) “{‘POWER’ : ‘ON’}”

I have a device that will publish something like:
publish (state) “{‘POWER’ : ‘ON’, ‘XXX’ : ‘42’, ‘YYY’ : ‘VAL’}”
So, the device might publish some other data in the response.

I was wondering how to specify this in the MQTT switch? Does the value_template apply to the command and the state or just the state? What about the payload on and off???

# Example configuration.yml entry
switch:
   - platform: mqtt
   name: "Device1"
   state_topic: "home/device1/"
   command_topic: "home/device1/set"
   payload_on: "{‘POWER’ : ‘ON’}"
   payload_off: "{‘POWER’ : ‘OFF’}”
   value_template: “{{ value_json.POWER }}”
   optimistic: false
   qos: 0
   retain: true

From what I can tell looking at the code, value_template is applied before checking payload_on/payload_off, so those would need to be

value_template: "{{ value_json.POWER }}"
payload_on: "ON"
payload_off: "OFF"

The issue then arises that when turning the switch on, it’ll send payload_on, which is just “ON” instead of “{‘POWER’ : ‘ON’}”.

So, to work around this you could essentially filter out all the extra data in the payload using value_template like so:

value_template: "{'POWER' : '{{ value_json.POWER }}'}"
payload_on: "{‘POWER’ : ‘ON’}"
payload_off: "{‘POWER’ : ‘OFF’}”

This is all untested, but that would be my best guess at how you could make this work.

1 Like

Thanks for the reply, I’ll give it a shot and see how it goes.

ended up getting it to work with this:

value_template: "{% raw %}{'power' : '{% endraw %}{{value_json.power}}{% raw %}' } {% endraw %}"

I’m not familiar with jinja so probably a better way to do it !

I know this is an old thread, but took me way to long to find the solution. this should be in the documents!

There have been a number of changes in the last two years. There is probably now a better way of doing anything that was written here.

Hi,

I’m trying to setup a mqtt switch like this:

switch:
  - platform: mqtt
    icon: mdi:mdi-power-socket-eu
    name: "Lavatrice"
    state_topic: "servicelocation/UUID/plug/1/state"
    command_topic: "servicelocation/UUID/plug/1/setstate"
    payload_on: '{"value":"ON","since":"{{ as_timestamp(now())|int }}"}'
    payload_off: '{"value":"OFF","since":"{{ as_timestamp(now())|int }}"}'
    state_on: "ON"
    state_off: "OFF"
    value_template: "{{ value_json.value }}"
    optimistic: false
    retain: true

I need to pass a timestamp in the payload value but it does not get interpreted and in the actual payload I have the Json {"value":"OFF","since":"{{ as_timestamp(now())|round|int }}"}

Any advice?

I believe payload_on and payload_off don’t accept templates.

MQTT switch provides value_template for processing the received payload. However, it doesn’t have an equivalent command_template for processing the transmitted payload. It ‘hard-codes’ the transmitted payload via payload_on and payload_off.

this means that there’s no solution viable? :frowning:

Oh, you wanted a solution. :wink:

Here’s one way to do it. Change the switch’s command_topic to something else like plug/1/setstate then create an automation that triggers on that topic and republishes its payload, with an added timestamp, to servicelocation/UUID/plug/1/setstate.

switch:
  - platform: mqtt
    icon: mdi:mdi-power-socket-eu
    name: "Lavatrice"
    state_topic: "servicelocation/UUID/plug/1/state"
    command_topic: "plug/1/setstate"
    state_on: "ON"
    state_off: "OFF"
    value_template: "{{ value_json.value }}"

Automation:

- alias: 'Plug 1 Publish'
  trigger:
    platform: mqtt
    topic: plug/1/setstate
  action:
    service: mqtt.publish
    data_template:
      topic: "servicelocation/UUID/plug/1/setstate"
      payload: '{"value":"{{trigger.payload}}","since":"{{ as_timestamp(now())|int }}"}'

In the automation, payload accepts templates.

The template is untested so you may need to adjust it for your needs.