MQTT Payload_template Help

I am wanting to send two numbers to an MQTT topic to start my EV charging.
The values come from two helpers, and need to be delivered in tthe form ‘x, y’ with no brackets etc.
I have tried a few different things using mqtt.publish using the payload_template option, but I haven’t been able to get the data delivered in the right format.
The below code sends the numbers like this chargeNow = ('20.0', '3600')
It should be like this instead chargeNow = 20, 3600

Any suggestions?

service: mqtt.publish
data:
  qos: "0"
  retain: false
  topic: TWC/control/chargeNow
  payload_template: >-
    {{states('input_number.twc_charge_now_current'),states('sensor.twc_charge_now_time_seconds')}}

Try this:

payload_template: >-
    {{states('input_number.twc_charge_now_current')}}, {{states('sensor.twc_charge_now_time_seconds')}}
1 Like

that’s a very specific output. Unfortunately the template resolver will always add (). So your only option is to template the entire data section. Luckily that’s possible.

service: mqtt.publish
data: >
  {{ 
    {
      'qos': 0,
      'retain': False,
      'topic': 'TWC/control/chargeNow',
      'payload': states('input_number.twc_charge_now_current') ~ ',' ~ states('sensor.twc_charge_now_time_seconds'),
    }
  }}
1 Like

Really?

I’ve never noticed that before. WTH does it do that?

Templates always return a string. Some time in the past, we added typing to the result. this means that any comma separated value will resolve a list or tuple. Just like we resolve numbers or dictionaries in variables. It’s all the same code.

So state values are always strings unless they are a template result?

:unamused:

That’s not confusing at all. /s

It’s the template resolver. The output of the template is always a string. You can see the result of the resolver in the template editor.

When the template resolver can figure out how to assign a type to it, it will.

e.g. "X,Y" is the string that is output from the template {{ }}. The resolver will look at that, see the comma and change it to the python tuple (or list) ('X', 'Y') or ['X', 'Y']. This was specifically done because people weren’t actually returning true python lists for entity_id. They’d return just sensor.a, sensor.b and expect it to work even though a true python list would be ['sensor.a','sensor.b']. So while it may be confusing, it’s definitely the lesser of 2 evils.

And as one of the ‘few’ people who know about this, I usually only have to help ~2 people a year get around this list thing. Usually it’s for the xiaomi vacuums because they only accept a string that looks identical to a list.

see → How do I convert a string into a "number"? - #39 by petro

So, a trick to figure out EXACTLY what your template ({{ }}) is outputting while forcing the resolver to stop typing the result…

Output of your template, which is then passed through the resolver


put an x in front of it so it confuses the resolver…

So this (old) confusion that I did have to help a number of people with has now spread outside the template editor as the solution to the problem?

That’s quite bizarre.

I’m not sure I follow you. But the result you circle is a result of the ‘resolver’, not a result of the template. It’s been like this since the inception of template typing. The result type you see in the corner is the result type that will be stored if you used it as a variable. So even though it’s a string, the resolver says “hey, that’s a number” and then you get a number.

e.g.

{% set x = 4 %}
{{ x }}

is your whole template.

the x variable is 4. if you output
{{ x }}{{ x }}, you’re going to get a value of 44 because the resolver types the entire output. it’s not looking at x and x separately.

So in your issue, you’re using the ‘output of the entire template’ as proof that it’s incorrect when comparing to the output of a single variable, which happens to be your attribute.

Awesome, thanks guys.

Both methods seem to work for me. Not sure why it isn’t adding brackets around @tom_l 's method. Perhaps one of my values is stored as a string rather than an int?

Anyway. I also had to add | round to one of my values to get rid of an unneccesary .0.

For future reference, my use case was for TWCManager which normally controls my EV chargers to track solar production, but it can also be controlled via MQTT to manually charge at a given current for a given amount of time. I.e during off-peak times.