MQTT entity with multiple sensors in one topic

My MQTT entity is set up by putting the following line into configuration.yaml:
mqtt: !include mqtt.yaml
and creating the file mqtt.yaml with the contents:

sensor:
- name: SIP
  state_topic: SIP/zones
  availability:
    - topic: SIP
      payload_available: "\"UP\""
      payload_not_available: "\"DOWN\""
  value_template: "{{ value_json.zone_list }}"

My device populates the topic SIP/zones with
{"zone_list": [0, 0, 0, 0, 0, 0, 0, 0], "zone_dict": {"Front": 0, "South": 0, "North": 0, "T1south": 0, "S05": 0, "S06": 0, "S07": 0, "S08": 0}, "master_on": 0}
I create a card for the dashboard with:

type: entities
entities:
  - entity: sensor.sip
show_header_toggle: false

This displays:
[0, 0, 0, 0, 0, 0, 0, 0]

I have written a script that works, except for the condition:

alias: SetValvePerSIP
sequence:
  - service: notify.mysensors
    data:
      target: Zone
      message: "0"
  - repeat:
      count: "8"
      sequence:
        - if:
            - condition: state
              entity_id: "sensor.sip"
              state: "{{ sensor.sip[ {{ repeat.index - 1 }} ] }}"
          then:
            - service: notify.mysensors
              data:
                target: Zone
                message: "{{ repeat.index }}"
  - service: switch.turn_on
    data: {}
    target:
      entity_id: switch.start
mode: single

The conditional does not ever evaluate to true even when one of the values is 1. Why is that?

Thanks for your help

The state condition does not accept templates. Use a template condition.

Thanks @tom_l
I just tried this:

        - if:
            - condition: template
              value_template: "{{ sensor.sip[ repeat.index - 1] == 1 }}"

It didn’t work. I’m having a problem determining what should be in the place of sensor.sip (At least I can get the value template to evaluate true with 1==1) Any Suggestions?

OSD

Try:

        - if:
            - condition: template
              value_template: "{{ states('sensor.sip')[ repeat.index - 1] == 1 }}"

Or shorthand format:

        - if:
            - "{{ states('sensor.sip')[ repeat.index - 1] == 1 }}"

That didn’t work @tom_l :frowning:

If I remove from mqtt.yaml the line
value_template: "{{ value_json.zone_list }}"
the entire JSON is available
{"zone_list": [0, 0, 0, 0, 0, 0, 0, 0], "zone_dict": {"Front": 0, "South": 0, "North": 0, "T1south": 0, "S05": 0, "S06": 0, "S07": 0, "S08": 0}, "master_on": 0}
Would that be helpful?

Thanks for your help.

OSD

Sensor states are always strings. Your sensor isn’t a list, it’s a string, and needs to be “converted” to a list to work as you want. Example below, where a is like your sensor: a[0] is the first character of the string. Turn it into a list with from_json and then you can index elements.

So (with your original sensor definition) try:

        - if:
            - "{{ (states('sensor.sip')|from_json)[ repeat.index - 1] == 1 }}"
1 Like

Nice. Using from json is a lot easier than either of these I was coming up with while you replied:

For fixed lenght:

value_template: "{{ states('sensor.sip')[1:23]|split(', ')[ repeat.index - 1] == 1 }}"

For variable length:

value_template: "{{ states('sensor.sip')|replace('[','')|replace(']','')|split(', ')[ repeat.index - 1] == 1 }}"

Thanks @Troon ! That works! I would have never figured that out. Your one line of code links it all together for me.

This is for my irrigation control project. I am using the front end of Sustainable Irrigation Platform (SIP) to set my watering times. It publishes what valve to control to MQTT, which is picked up by HA. HA then notifies, again through MQTT, MySensors of the valve to turn on. An RPi, running the MySensors gateway (with local actuators) turns on a pair of relays which energize the valve.

I found on AliExpress (caveat emptor) an ESP8266 relay which I hope to tazmotize which would allow HA to control any number of valves directly.

I do have one more task and that is to turn my script into an automation which is triggered by a change in state of the status topic.

Thanks again! you, too, @tom_l !

OSD

2 Likes

Leave it as a script if it works already, and call the script from a simple automation.