Need Help: Concat Strings an sensor Values for mqtt payload

Hi there,

relatively new to ha and playing around with automations. Did get to work quite a lot of things but stuck on a simple Task for nearly 3 hours now…

Easy because I am only trying to concat Strings and a sensor value for the paload of an MQTT Message. Checked it in Template checker where that results in ‘{text: “Bezug 297 W”, “rainbow”: false, “duration”: 10, “color”:“#fc031c”, “icon”: 58276}’ what seem relatively good to me.

        - if:
          - condition: numeric_state
            entity_id: 'sensor.alpha_ess_total_power_grid '
            above: 100
          then:
          - service: mqtt.publish
            metadata: {}
            data:
              qos: '2'
              retain: false
              topic: awtrix_6d4498/custom/energystats
              payload: '{text: "{{"Bezug " ~  states('sensor.alpha_ess_total_power_grid')|int(0) ~ " W"}}", "rainbow": false, "duration": 10, "color":"#fc031c", "icon": 58276}'

The File Editor warns me of error

bad indentation of a mapping entry (389:55)

 386 |  ... 
 387 |  ... lse
 388 |  ... rix_6d4498/custom/energystats
 389 |  ... {text: "{{"Bezug " ~  states('sensor.alpha_ess_total_power_gr ...
------------------------------------------^
 390 |  ... 

I could imagine the problem being missing escaping of ’ but tbh am a bit lost at thins moment.

Any hints would be greatly appreciated.

              payload: >-
                {"text": "Bezug {{ states('sensor.alpha_ess_total_power_grid')|int(0) }} W", "rainbow": false, "duration": 10, "color":"#fc031c", "icon": 58276}

The alternative being something like this:

              payload: >-
                {% set j = {
                  "text": "Bezug " ~ states('sensor.alpha_ess_total_power_grid')|int(0) ~ " W",
                  "rainbow" : false,
                  "duration": 10,
                  "color": "#fc031c",
                  "icon": 58276
                  }
                %}
                {{ j|to_json }}
1 Like

fantastic, you just saved my day :smile: Works !

and thanks a lot for the alternative. Will help me a lot in the future as it is much more readable !

1 Like

For future reference, here’s how to use a script variable to define a complex value (i.e. a dictionary with five keys). I recently used this method for publishing MQTT payloads to control a fan.

        - if:
          - condition: numeric_state
            entity_id: 'sensor.alpha_ess_total_power_grid '
            above: 100
          then:
          - variables:
              msg:
                text: "Bezug {{ states('sensor.alpha_ess_total_power_grid')|int(0) }}W"
                rainbow: false
                duration: 10
                color: '#fc031c'
                icon: 58276
          - service: mqtt.publish
            metadata: {}
            data:
              qos: '2'
              retain: false
              topic: awtrix_6d4498/custom/energystats
              payload: '{{ msg | to_json }}'
1 Like

following those examples I started rewriting some of my automations because … errrm… it was / still is a big amount of ‘spaghetti-code’.

I wanted to get things to work an not knowing how to write it correctly I ended up generating really long automation blocks with a lot of nested if / else and conditions always repeating the same actions simply changing some values to send (in this whole block the action is always sending mqtt message, only payload changes).

Following your example I wanted to strip down the whole Block to building the dictionary based on some changing parameters without repeating code but was not able to get it working.

What I would want do do ist somethin like this (obviously not working like that nor the 12 other ways I tried)

- id: 'mqtt_tibber_price'
  alias: MQTT tibber price
  description: ''
  trigger:
  - platform: time_pattern
    minutes: '1'
  condition: []
  action:
  - variables:
      "{% set price_lvl = { state_attr('sensor.electricity_price_XXXXX', 'price_level') } %}"
      "{% if price_lvl == 'VERY_CHEAP' %}"
          "{% set color = '#33a000' %}"
          "{% set icon = 57917 %}"
      "{% elif price_lvl == 'NORMAL' ||  price_lvl == 'CHEAP' %}"
          "{% set color = '#f6ff00' %}"
          "{% set icon = 57585 %}"
      "{% elif price_lvl == 'EXPENSIVE' ||  price_lvl == 'VERY_EXPENSIVE' %}"
          "{% set color = '#fc031c' %}"
          "{% set icon = 57921 %}"
      "{% else %}" 
          "{% set color = '#fc031c' %}"
          "{% set icon = 9184 %}"
      "{% endif %}"
      msg:
        text: "{{ states('sensor.electricity_price_XXXXX')|float(0) }} €"
        rainbow: false
        duration: 10
        color: "{{ color }}"
        icon: "{{ icon }}"
  - service: mqtt.publish
    metadata: {}
    data:
      qos: '2'
      retain: false
      topic: awtrix_xxxxxx/custom/tibber
      payload: '{{ msg | to_json }}'

It doesn’t work because you put Jinja2 code where it doesn’t belong.

A Jinja2 template is used exclusively to compute a value for a YAML option.

  - variables:
       some_variable_name: "{{ Jinja2 template computing value for some_variable_name }}"

aye, ok understood, thank you!

Is there even a possibility to relatively easy dynamically generate a complex type (dictionary) based on external parameter (i.e. sensor Values) ?

Want to do somethin similar to this (it’s only pseudocode). Only posting the complete part to show that it’s a lot of ‘states’

          payload:              
              duration: 10
              text: "{{ states('sensor.ala001022030942_instantaneous_load')|float(0) }} €"
              if sensor.ala001022030942_instantaneous_load < 200
                icon: 52832
              elsif sensor.ala001022030942_instantaneous_load <= 300
                icon: 52833
              elsif sensor.ala001022030942_instantaneous_load <= 400 
                icon: 52834
              elsif sensor.ala001022030942_instantaneous_load  <= 500 
                icon: 52835
              elsif sensor.ala001022030942_instantaneous_load <= 600
                icon: 52837
              elsif sensor.ala001022030942_instantaneous_load <= 700
                icon: 52838
              elsif sensor.ala001022030942_instantaneous_load <= 800
                icon: 52839
              elsif sensor.ala001022030942_instantaneous_load <= 900
                icon: 52841
              elsif sensor.ala001022030942_instantaneous_load <= 1000
                icon: 52842
              elsif sensor.ala001022030942_instantaneous_load <= 1100
                icon: 52843
              elsif sensor.ala001022030942_instantaneous_load <= 1200
                icon: 52844
              elsif sensor.ala001022030942_instantaneous_load <= 1300
                icon: 52844
              elsif sensor.ala001022030942_instantaneous_load > 1200
                icon: 52846
              color: 
              if sensor.alpha_ess_total_power_grid > ala001022030942_instantaneous_load / 2
                if sensor.ala001022030942_instantaneous_generation > 100
                  gradient: [red, yellow]
                else
                  color: red
              elsif sensor.ala001022030942_instantaneous_generation > ala001022030942_instantaneous_load / 2
                if sensor.alpha_ess_total_power_grid > 100
                  gradient: [yellow, red]
                else
                  color: yellow
              elsif sensor.ala001022030942_instantaneous_battery_i_o > ala001022030942_instantaneous_load / 2
                if sensor.alpha_ess_total_power_grid > 100
                  gradient: [green, red]
                else
                  color: green

Just to send you down the right path:

icon: >-
  {% set load = states('sensor.ala001022030942_instantaneous_load')|float(0) %}
  {% if load < 200 %}
    52832
  {% elif load <= 300 %}
    52833
  {% elif load <= 400 %}
    52834
  {% elif load <= 500 %}
    52835
  {% elif load <= 600 %}
    52837
  {% elif load <= 700 %}
    52838
  ......
  {% endif %}

So as you can see the variable is like any other part of Home Assistant YAML.
icon is the variable name - but then you put the Jinja underneath it (indented) that outputs the actual value of the variable.

1 Like