MQTT Script fails with "Error rendering data template: UndefinedError: 'value_json' is undefined"

This script used to work. Unfortunately I made some changes that required running this old script to restore the previous settings. I suspect one of the core updates ( maybe 0.115/0.116 ? ) changed something and I am unsure where to start looking.

service: mqtt.publish
data:
  payload: >-
    '{ 
      "name": "bedroomfan",
      "availability_topic": "tele/tuyas5/LWT",
      "payload_available": "Online",
      "state_topic": "stat/tuyas5/RESULT",
      "command_topic": "cmnd/tuyas5/FanSpeed",
      "payload_high_speed": "3",
      "payload_low_speed":"1",
      "payload_medium_speed": "2",
      "payload_not_available":"Offline",
      "payload_off": "0",
      "payload_on": "4",
      "unique_id":"bedroomfan",
      "speed_command_topic": "tuyas5/cmnd/FanSpeed",
      "speed_state_topic":"stat/tuyas5/RESULT", 
      "speed_value_template": "{{ value_json.FanSpeed }}",
      "speeds": ["off", "low", "medium","high"],
      "state_topic": "stat/tuyas5/RESULT",
      "state_value_template": "{% if value_json.FanSpeed is defined %}{% if value_json.FanSpeed == 0 -%}0{%- elif value_json.FanSpeed > 0 -%}4{%- endif %}{% else %}{% if states.fan.bedroomfan.state == 'off' -%}0{%- elif states.fan.bedroomfan.state == 'on' -%}4{%- endif %}{% endif %}",
      "dev": {
        "ids": ["8D9C6C"] }
    }'
  retain: true
  topic: homeassistant/fan/bedroomfan/config

As the error says, value_json is not defined, you use it multiple times in your payload. Can you please show the full automation?

Here it is

  create_mqtt_fan:
    alias: MQTT create fan with manual discovery
    mode: single
    sequence:
      service: mqtt.publish
      data:
        payload: |
          '{ 
            "name": "bedroomfan",
            "availability_topic": "tele/tuyas5/LWT",
            "payload_available": "Online",
            "state_topic": "stat/tuyas5/RESULT",
            "command_topic": "cmnd/tuyas5/FanSpeed",
            "payload_high_speed": "3",
            "payload_low_speed":"1",
            "payload_medium_speed": "2",
            "payload_not_available":"Offline",
            "payload_off": "0",
            "payload_on": "4",
            "unique_id":"bedroomfan",
            "speed_command_topic": "tuyas5/cmnd/FanSpeed",
            "speed_state_topic":"stat/tuyas5/RESULT", 
            "speed_value_template": "{{ value_json.FanSpeed }}",
            "speeds": ["off", "low", "medium","high"],
            "state_topic": "stat/tuyas5/RESULT",
            "state_value_template": "{% if value_json.FanSpeed is defined %}{% if value_json.FanSpeed == 0 -%}0{%- elif value_json.FanSpeed > 0 -%}4{%- endif %}{% else %}{% if states.fan.bedroomfan.state == 'off' -%}0{%- elif states.fan.bedroomfan.state == 'on' -%}4{%- endif %}{% endif %}",
            "dev": {
              "ids": ["8D9C6C"] }
          }'
        retain: true
        topic: homeassistant/fan/bedroomfan/config

Iā€™m still experimenting with just the publshing one line to figure out what Iā€™m doing wrong
the result I want is ā€œspeed_value_templateā€: ā€œ{{ value_json.FanSpeed }}ā€

and Iā€™m trying ā€˜ā€œspeed_value_templateā€: ā€œ{{ā€œvalue_json.FanSpeedā€}}ā€ā€™
which gives me ā€œspeed_value_templateā€: ā€œvalue_json.FanSpeedā€ when I look at the published info using MQTT explorer

Just missing the {{ }} around ā€œvalue_json.FanSpeedā€

Ah ok,now I understand what youā€™re trying to do.
The problem is that since 0.115, data and data_template are equivalent, therefore it interprets your payload as a template and and gives you the error.

Try like this:

"{{ '{{ value_json.FanSpeed }}' }}"

Or without any brackets

{{ value_json.FanSpeed }}

2 Likes

Thanks very much this has been big help pointing me in the right direction. Your ā€œtry likeā€ suggestions unfortunately did not work. So I spun up a basic VM with 0.114.4, and by pointing to my main HA instance I was able to update MQTT and see the ā€œdeviceā€. Updating the VM to 0.115 gave the same failures as you predicted.

I would still like to resolve in the event I need to run the script in the future. Any suggestions ? Here is my parred down script. Once it runs the final test is to verify the output in MQTT

It should be ā€œspeed_value_templateā€: ā€œ{{ value_json.FanSpeed }}ā€

'1603813354661':
  alias: MQTT value_json test
  sequence:
  - data:
      payload: '"speed_value_template": "{{ value_json.FanSpeed }}"'
      retain: true
      topic: homeassistant/fan/bedroomfantest/config
    service: mqtt.publish

Getting closer have one more portion working needed double quotes in both places

"speed_value_template": "{{ "{{ value_json.FanSpeed }}" }}"

now working on

ā€œstate_value_templateā€: "{% if value_json.FanSpeed is defined %} ā€¦

I have several scripts designed to create entities via MQTT Discovery ā€¦ just like what brucel1642 is doing. The payloads contain templates. Youā€™ve made me realize that if I ever need to run them again, I will face the same problem.

This is one of those ā€˜edge casesā€™ where you donā€™t want the template to be evaluated. I have a feeling it was never envisioned when data was promoted to work just like data_template.

Iā€™m not looking forward to modifying all those scripts to prevent their templates from being evaluated. :persevere: Some of the templates were difficult enough to quote correctly without this additional layer of quoting complexity. This one comes to mind:

              "command_template": "{\"action\":\"{{action}}\", \"code\":\"{{code}}\"}",

Burningstone, Thanks I now have it working. Wrapping with ā€œ{{ ā€¦ }}ā€ fixed it

123 Taras, Modifying the scripts wasnā€™t so bad for me. I kept a copy of the script in my packages folder in a ā€œreadableā€ format ie no escape \ characters. Then I pasted the payload into the script editor. When you go and look at the code in scripts.yaml with an file editor it shows all the escape characters it automatically added for you.

Heresā€™ the end result

  create_mqtt_fan:
    alias: MQTT create fan with manual discovery
    mode: single
    sequence:
      service: mqtt.publish
      data:
        payload: |
          '{ 
            "name": "bedroomfan",
            "availability_topic": "tele/tuyas5/LWT",
            "payload_available": "Online",
            "state_topic": "stat/tuyas5/RESULT",
            "command_topic": "cmnd/tuyas5/FanSpeed",
            "payload_high_speed": "3",
            "payload_low_speed":"1",
            "payload_medium_speed": "2",
            "payload_not_available":"Offline",
            "payload_off": "0",
            "payload_on": "4",
            "unique_id":"bedroomfan",
            "speed_command_topic": "tuyas5/cmnd/FanSpeed",
            "speed_state_topic":"stat/tuyas5/RESULT", 
            "speed_value_template": "{{ "{{ value_json.FanSpeed }}" }}",
            "speeds": ["off", "low", "medium","high"],
            "state_topic": "stat/tuyas5/RESULT",
            "state_value_template": "{{ "{% if value_json.FanSpeed is defined %}{% if value_json.FanSpeed == 0 -%}0{%- elif value_json.FanSpeed > 0 -%}4{%- endif %}{% else %}{% if states('fan.bedroomfan') == 'off' -%}0{%- elif states('fan.bedroomfan') == 'on' -%}4{%- endif %}{% endif %}" }}",
            "dev": {
              "ids": ["8D9C6C"] }
          }'
        retain: true
        topic: homeassistant/fan/bedroomfan/config

Can you post that version here so we can compare it? Or is that the one you just posted??

agreed, and we shouldnā€™t, This should really be fixed in the backend, and as a matter of fact, a fix for a related issue is coming (see my posts on the rest_command issues in another thread, and this GitHub issue)

hoping this will fix our issues at hand , yah

123 Taras

The One I posted is my working version

OK. My point was this fails to produce the desired result (in versions prior to the deprecation of data_template):

              "command_template": "{"action":"{{action}}", "code":"{{code}}"}",

whereas this works:

              "command_template": "{\"action\":\"{{action}}\", \"code\":\"{{code}}\"}",

That was the situation when data: did not attempt to render templates. Now that it does render them, I can only imagine what contortions will be needed to pass the payload without rendering.