MQTT payload template in HA 117 doesn't work, need help

posted in a GitHub issue before before, but that now is closed, so please bear with me here in this dedicated topic for an mqtt publish service, I simply can’t get workin in Ha 117.0b5

@BrianHanifin hope you don’t mind the tag, but since we we’re both in the issue tracker, supposed you would still be struggling with the same…

here’s the original mqtt service I used successfully up to 117:

    action:
      service: mqtt.publish
      data:
        topic: location/marijn
        retain: true
        payload: >-
          {
            "latitude": "{{state_attr('zone.home','latitude')}}",
            "longitude": "{{state_attr('zone.home','longitude')}}",
            "battery_level": {{states('sensor.calltheboss_battery_level')|int}},
            "gps_accuracy": 0
          }

and

    action:
      service: mqtt.publish
      data:
        topic: location/marijn
        retain: true
        payload: >-
          {
            "latitude": "{{trigger.to_state.attributes.latitude}}",
            "longitude": "{{trigger.to_state.attributes.longitude}}",
            "battery_level": {{states('sensor.calltheboss_battery_level')|int}},
            "gps_accuracy": {{trigger.to_state.attributes.gps_accuracy|int}}
          }

note this is a carefully built payload, and the quotings are correct. See here for explanation

error:

Marijn Presence Update from Router or Bluetooth: Error executing script. Unexpected error for call_service at pos 1: payload must be a string, bytearray, int, float or None.
While executing automation automation.marijn_presence_update_from_router_or_bluetooth

.....
TypeError: payload must be a string, bytearray, int, float or None.

I’d need this exact payload, so something like this doesn’t work (I’ve tried)

    action:
      service: mqtt.publish
      data:
        topic: location/marijn
        retain: true
        payload:
          latitude: "{{state_attr('zone.home','latitude')}}",
          longitude: "{{state_attr('zone.home','longitude')}}",
          battery_level: {{states('sensor.calltheboss_battery_level')|int}},
          gps_accuracy: 0

hope anyone can get this to work, it seems a rather basic mqtt payload, so hope this helps the community too…

must add this is for the device_tracker mqtt_json:

device_tracker:
  - platform: mqtt_json
    devices:
      marijn_presence: location/marijn

so maybe that’s causing the issue? A json tracker not getting json anymore …?

I can’t reproduce your issue. I’m on 0.117.0b5 and have the following in the automation:

automation:
- id: test_mqtt
  alias: "Test MQTT."
  mode: single
  trigger:
    - platform: state
      entity_id: input_boolean.sleep_mode
  action:
    service: mqtt.publish
    data:
      topic: test/test
      retain: true
      payload: >-
        {
          "latitude": "{{state_attr('zone.home','latitude')}}",
          "longitude": "{{state_attr('zone.home','longitude')}}",
          "battery_level": {{states('sensor.calltheboss_battery_level')|int}},
          "gps_accuracy": 0
        }

When the input_boolean is changed I get:

As far as I understand, this will not work, because it results in a dict:

payload:
   latitude: "{{state_attr('zone.home','latitude')}}",
   longitude: "{{state_attr('zone.home','longitude')}}",
   battery_level: {{states('sensor.calltheboss_battery_level')|int}},
   gps_accuracy: 0

I apologize in advance for not reading your full posts, but a birthday dinner is starting now. I saw Franck make a suggestion on the hass-variable repo issue. So I just gave it a try and it worked:

variables:
  name: "mqtt_dict_test"

  # attributes: >
  #   { 
  #     "name": "{{ name }}"
  #   }
  #attributes: '{"name":"{{ name }}"}'
  attributes:
    name: "{{ name }}"

sequence:
  - service: mqtt.publish
    data:
      topic: "custom/sensor/{{ name }}/attributes"
      payload: "{{ attributes }}"
      retain: true

thanks, and HB!

seems the mqtt service is working as expected since 117.0b5 after all, see Paulus intervention here

so that’s 1 issue less to tackle.

I’ll mark this as solved, by the same link to the issue, thanks to the dev team
cheers!

1 Like

@Mariusthvdb OK, after some more testing I discovered the following:

This fails saying “value should be a string for dictionary value @ data[‘payload’]”.

  - service: mqtt.publish
    data:
      retain: true
      topic: "custom/sensor/{{ name }}/attributes"
      payload:
        name: "{{ name }}"

I feel like Han Solo… if I hide the contraband “list” data inside of variable I can smuggle the data in safely. I think these may be the data packets you are looking for. :wink:

    variables:
      location:
        latitude: "{{state_attr('zone.home','latitude')}}",
        longitude: "{{state_attr('zone.home','longitude')}}",
        battery_level: "{{states('sensor.calltheboss_battery_level')|int}}",
        gps_accuracy: 0

    action:
      service: mqtt.publish
      data:
        topic: location/marijn
        retain: true
        payload: "{{ location }}"

OK, while I can write JSON data like that to mqtt.publish on 117.0b5, my MQTT sensor will not pull the data back out as an attribute. This sensor below pulls retrieves the state correctly, but no longer adds the attribute(s) like it used to.

So rather than continuing to make my life more difficult, I flexed and created a second sensor, rather than continue to fight with adding an attribute to an MQTT sensor.

sensor:
  platform: mqtt
  name: Last Message
  state_topic: "custom/sensor/last_message/state"
  json_attributes_topic: "custom/sensor/last_message/attributes"

script:
  sequence:
    - service: mqtt.publish
      data:
        topic: "custom/sensor/last_message/state"
        payload: "Testing, 1, 2, 3."

    - service: mqtt.publish
      data:
        topic: "custom/sensor/last_message/attributes"
        payload: >-
          {
            target: "media_player.google_family_room"
          }

well, I had tried that before without succes. if you have a look 1 post up, you’ll see my original template is now accepted by the fix Paulus made in the backend. Which is even better because we wont have to fiddle with our configs :+1: