Automation trigger and templating with mqtt json payload

I am trying to set my HUE light bulbs from an mqtt automation trigger. I am sending the payload as JSON and trying to parse the json using the service_template and data_template to set the light entity state and brightness.

I am not using the light component because my purpose is a little more complicated, I have an Android application that is talking with HASS through MQTT and I want to control a dimmer light connected to HASS from the application.

This is the JSON I am sending as the payload:

{'topic':'room/dimmer/set', 'payload': '{"state":"on", "brightness":10}'}

Here is my automation:

- id: '1577995477209'
  alias: MQTT Dimmer
  description: ''
  trigger:
  - platform: mqtt
    topic: room/dimmer/set
  condition: []
  action:
  - data_template:
      brightness: '{{ trigger.payload_json.brightness }}'
      entity_id: light.living_room
    service_template: > 
      light.turn_{{ trigger.payload_json.state }}

Nothing is happening of course, but is there a way to test this with the dev tools or if anyone has something similar they would share.

1 Like

Payload needs to be an array [ ]

{"topic":"room/dimmer/set", "payload":  ["state":"on", "brightness":10]}

Then you use
value_json.payload[‘state’]
Or
value_json.payload[‘brightness’]
Use the templates in Dev Tools
To check your code

Just check it maybe
value_json.payload[0].state
Sorry replying from mobile phone

I could not get the array to evaluate, but I could evaluate the payload in using the template in the dev tools with an object not an array:

{% set my_test_json = {
  "topic":"room/dimmer/set", 
  "payload": {'state':'on', 'brightness':10}
  } %}

The state is {{ my_test_json.payload.state }} 

I think the issue is how to get the json values from the tigger of the automation when using mqtt platform. I have tried the following:

{{ trigger.payload.state }} 
{{ trigger.payload_json.payload.state }} 
{{ trigger.value_json.payload.state }} 
{{ trigger.payload_json.state }} 
{{ trigger.value_json.state }} 

There does not seem to be a way to evaluate the trigger using dev tools, so its a process of elimination by updating the automation and sending the mqtt message using the service, then checking the logs.

Did you try this?

{{ trigger.payload[state] }}
or
{{ trigger.payload_json[state] }}

as @Harry13 suggested

If you look at the documentation for automation templating for mqtt, it seems to indicate using trigger.payload_json, but using that throws an error that it cannot be found.

UndefinedError: ‘dict object’ has no attribute ‘payload_json’

1 Like

Maybe the problem is that your payload has the topic and the payload in it.

Try something like this:

{{ trigger.payload[payload][state] }}

or

{{ trigger.payload_json.payload.state }}

Where do you see this in the documentation?

trigger.payload gives the payload and trigger.payload_json gives a dictionary of the JSON parsed payload.

I spelled it wrong in my post, I tried payload_json not payload.json

1 Like

Yes, payload_json but not payload.json, small but important difference :wink:

Payload give you just the raw payload and payload_json gives you a JSON parsed dictionary of the payload.

Your payload has the keys “topic” and “payload”, that’s why you need two times payload. For your method to work the payload would need to look like this:

{"state":"on", "brightness":10}

Did you try these suggestions?

{{ trigger.payload[payload][state] }}

or

{{ trigger.payload_json.payload.state }}

This was my original mqtt post:

{
  "topic":"room/dimmer/set", 
  "payload": {"state":"on", "brightness":10}
  }

And this is my automation:

- id: '1577995477209'
  alias: MQTT Dimmer
  description: ''
  trigger:
  - platform: mqtt
    topic: room/dimmer/set
  condition: []
  action:
  - data_template:
      brightness: '{{ trigger.payload_json.brightness }}'
      entity_id: light.living_room
    service_template: > 
      light.turn_{{ trigger.payload_json.state }}

Referencing payload_json in the automation throws the error “UndefinedError: ‘dict object’ has no attribute ‘payload_json’”

I will try it using just “payload” instead of “payload_json”,but that error should not happen, payload_json is valid right?

Maybe this means it could not parse the payload as JSON.

Can you please change the action to

action:
  - service: persistent_notification.create
    data_template:
      message: '{{ trigger.payload }}'
  - service: persistent_notification.create
    data_template:
      message: '{{ trigger.payload_json }}'

and show the resulting notifications?

1 Like

Good idea for testing. Here are the results, the first message posted but the second one is empty or null.

Maybe this needs to be escaped or something. I am using the developer tools to post the MQTT message but not escaped. I will try it both ways to see if payload_json shows up.

Escaping the payload json made no difference, I cannot get the payload_json in the notification.

Then you need to use payload, can’t tell you why payload_json doesn’t work.

Do you get the correct result when you try this:

- service: persistent_notification.create
    data_template:
      message: '{{ trigger.payload[state] }}'

After a few restarts, the payload_json started working, this is what works now:

'{{ trigger.payload_json.state }}'

No idea why it was producing errors before. This is the payload using the dev tools service to send mqtt:

topic: room/dimmer/set
payload: '{"state":"on", "brightness":100}'
qos: 2
retain: true

Strange, at least it works now :slight_smile:

That seems to be the magic with HA, just keep restarting. This is my final automation format:

- id: '1577995477209'
  alias: MQTT Dimmer
  description: ''
  trigger:
  - platform: mqtt
    topic: room/dimmer/set
  condition: []
  action:
  - data_template:
      brightness: '{{ trigger.payload_json.brightness|int }}'
    entity_id: light.living_room
    service_template: > 
      light.turn_{{ trigger.payload_json.state }}

with this mqtt:

{
  "topic":"room/dimmer/set", 
  "payload": {"state":"on", "brightness":200}
}
1 Like

The problem with this solution is if you want to turn the light off, you cannot also set the brightness, it breaks the automation and throws an error in logs:

Error while executing automation automation.mqtt_dimmer_switch. Invalid data for call_service at pos 3: extra keys not allowed @ data['brightness']

So this needs to be broken into two automations, both reading the same MQTT message. One for turning on or off the lights, the other for setting the brightness but with a conditional. If the state is “on” then set the brightness, if the state is “off” do not attempt to set the brightness with the automation.