How to insert a variable in a value_template MQTT discovery script?

Because I almost pulled out all of my hair after a few weeks of trying, I hope someone can help to point me in the right direction on how to insert a variable in a value_template that is used in a MQTT publish script.

TL/DR;

The line below:

"value_template": "{{ "{{ value_json.outlets[0].current }}" }}",

returns a correct value of 0.043 (measured current of the first outlet of the PDU).

When I add that line and adapt it so I can use it in a repeat loop, the line below:

"value_template": "{{ "{{ value_json.outlets[repeat.index - 1 ].current }}" }}",

returns nothing.

In the trace log, I see

value_template: '{{ value_json.outlets[repeat.index - 1].current }}'

The pointer variable repeat.index is shown instead of it numerical value! How can make it happen that the numerical value is shown instead of the pointer variable repeat.index (minus 1)?

Thank you.
Johan


A bit more context

I have a PDU (Power Distribution Unit) with MQTT support. The idea is to write a MQTT discovery script bundle so I can monitor and manage the PDU from HA. Writing that MQTT discovery script bundle worked, but I wanted to ā€œbeautify itā€. Instead of writing a script for each outlet, I hoped to write a repeat script. So far that did not work.

On MQTT topic de/gudesystems/epc/00:19:32/device/telemetry, the PDU publishes each 60 seconds telemetry data in JSON format such as below:

{"type": "telemetry", "portstates": [{"port": "1", "name": "Switch", "state": 1},{"port": "2", "name": "zbridge", "state": 1},{"port": "3", "name": "Fiber, Router", "state": 1},{"port": "4", "name": "Nestor", "state": 1},{"port": "5", "name": "WiFi", "state": 1},{"port": "6", "name": "UNIX box 1", "state": 1},{"port": "7", "name": "UNIX box 2", "state": 1},{"port": "8", "name": "Power Port", "state": 1}], "ovp_state": [1], "line_in": [{"voltage": 232.070,"current": 0.043,"freq": 49.99,"phase": 53.60,"act_pow": 6.0,"react_pow": 7.0,"app_pow": 9.0,"pow_fact": 0.631,"tot_energy": 1.521,"res_energy": 1.516,"res_time": 1424021,"res_current": 0.0003}], "outlets": [{"voltage": 232.060,"current": 0.000,"freq": 49.99,"phase": -7.20,"act_pow": 0.0,"react_pow": 0.0,"app_pow": 0.0,"pow_fact": 1.000,"tot_energy": 1.010,"res_energy": 0.995,"res_time": 1424021},{"voltage": 232.060,"current": 0.043,"freq": 49.99,"phase": 53.40,"act_pow": 6.0,"react_pow": 7.0,"app_pow": 9.0,"pow_fact": 0.635,"tot_energy": 0.813,"res_energy": 0.789,"res_time": 1424021},{"voltage": 232.030,"current": 0.000,"freq": 49.99,"phase": 7.20,"act_pow": 0.0,"react_pow": 0.0,"app_pow": 0.0,"pow_fact": 1.000,"tot_energy": 0.293,"res_energy": 0.260,"res_time": 1424021},{"voltage": 232.070,"current": 0.000,"freq": 49.99,"phase": 101.60,"act_pow": 0.0,"react_pow": 0.0,"app_pow": 0.0,"pow_fact": 1.000,"tot_energy": 0.258,"res_energy": 0.216,"res_time": 1423721},{"voltage": 232.080,"current": 0.000,"freq": 49.99,"phase": -49.30,"act_pow": 0.0,"react_pow": 0.0,"app_pow": 0.0,"pow_fact": 1.000,"tot_energy": 0.268,"res_energy": 0.217,"res_time": 1423721},{"voltage": 232.070,"current": 0.000,"freq": 49.99,"phase": -63.60,"act_pow": 0.0,"react_pow": 0.0,"app_pow": 0.0,"pow_fact": 1.000,"tot_energy": 0.278,"res_energy": 0.218,"res_time": 1423721},{"voltage": 232.110,"current": 0.000,"freq": 49.99,"phase": -58.10,"act_pow": 0.0,"react_pow": 0.0,"app_pow": 0.0,"pow_fact": 1.000,"tot_energy": 0.287,"res_energy": 0.218,"res_time": 1423721},{"voltage": 232.100,"current": 0.000,"freq": 50.00,"phase": -23.30,"act_pow": 0.0,"react_pow": 0.0,"app_pow": 0.0,"pow_fact": 1.000,"tot_energy": 0.295,"res_energy": 0.216,"res_time": 1423721}], "ts": 1767305309}

For now, everything runs in a test environment, so I am free to experiment.

The per outlet script

The script below works:

alias: Outlet 1 Current
action: mqtt.publish
metadata: {}
data:
  qos: "0"
  retain: false
  topic: homeassistant/sensor/pdu_001932/outlet_1_current/config
  payload: |-
    {
              "name": "PDU Outlet 1 Current",
              "unique_id": "pdu_001932_outlet_1_current",
              "state_topic": "de/gudesystems/epc/00:19:32/device/telemetry",
              "value_template": "{{ {{ value_json.outlets[0].current }}" }}",
              "state_class": "measurement",
              "device_class": "current",
              "unit_of_measurement": "A",
              "device": {
                "identifiers": ["pdu_001932"]
              }
            }
enabled: true

The script with a repeat loop

This PDU has 8 outlets. I hoped I could create a script such as:

alias: Define Current measurement of outlets 1 through 8
repeat:
  count: 8
  sequence:
    - action: mqtt.publish
      metadata: {}
      data:
        qos: "0"
        retain: true
        topic: >-
          homeassistant/sensor/pdu_001932/outlet_{{ repeat.index
          }}_current/config
        payload: |-
          {
                      "name": "PDU Outlet {{ repeat.index }} Current",
                      "unique_id": "pdu_001932_outlet_{{ repeat.index }}_current",
                      "state_topic": "de/gudesystems/epc/00:19:32/device/telemetry",
                      "value_template": "{{ "{{ value_json.outlets[repeat.index - 1 ].current }}" }}",
                      "state_class": "measurement",
                      "device_class": "current",
                      "unit_of_measurement": "A",
                      "device": {
                      "identifiers": ["pdu_001932"]
                      }
                    }
    - delay:
        hours: 0
        minutes: 0
        seconds: 1
        milliseconds: 0

The repeat.index pointer starts at 1, but the array pointer starts at 0, so I need to subtract 1 (I tried repeat.index0, but that did not work).
For some reason, when I use in HA for value_template "{{, I get an UndefinedError: ā€˜value_json’ is undefined. When I do it like I did in my scripts "{{ "{{, I don’t get the error and I get results back that I expect.

If I look at the trace result for the latter script, I see (for the first iteration):

MQTT 'Publish'
Iteration 1
Executed: January 1, 2026 at 10:30:51 PM
Result:

params:
  domain: mqtt
  service: publish
  service_data:
    qos: '0'
    retain: true
    topic: homeassistant/sensor/pdu_001932/outlet_1_current/config
    payload:
      name: PDU Outlet 1 Current
      unique_id: pdu_001932_outlet_1_current
      state_topic: de/gudesystems/epc/00:19:32/device/telemetry
      value_template: '{{ value_json.outlets[repeat.index - 1].current }}'
      state_class: measurement
      device_class: current
      unit_of_measurement: A
      device:
        identifiers:
          - pdu_001932
  target: {}
running_script: false

To my surprise, the pointer variable name repeat.index is shown, instead of its expected numerical value 1 - 1 = 0.

How can make it happen that the numerical value is shown instead of the pointer variable repeat.index (minus 1)?

Thank you for pointing me in the right direction.

Johan

You have quote in quote.
change one of the pairs to single quote.

Try using Repeat for each to get the right range, and raw blocks. The following is untested:

repeat:
  for_each: "{{ range(0,8) | list}}" 
  sequence:
    - action: mqtt.publish
      metadata: {}
      data:
        qos: "0"
        retain: true
        topic: >-
          homeassistant/sensor/pdu_001932/outlet_{{ repeat.item }}_current/config
        payload: |
          {%raw%}{
            "name": "PDU Outlet {%endraw%}{{ repeat.item }}{%raw%} Current",
            "unique_id": "pdu_001932_outlet_{%endraw%}{{ repeat.item }}{%raw%}_current",
            "state_topic": "de/gudesystems/epc/00:19:32/device/telemetry",
            "value_template": "{{ value_json.outlets[{%endraw%}{{repeat.item}}{%raw%}].current }}",
            "state_class": "measurement",
            "device_class": "current",
            "unit_of_measurement": "A",
            "device": {
            "identifiers": ["pdu_001932"]
            }
          }{%endraw%}

Hi,
I tried what you suggest here, but that did not work. Didgeridrew, suggested something else that pointed me out in the right direction.

Hi,
It did not completely work, but you pointed me in the right direction. Thank you for that.
Johan

1 Like

Please post what worked for you so other users with similar issues have an example to work from.

1 Like