Stuck on an automation, detecting a state works one direction, but not the other

Hi all HA automation wizards!

I have 30 solar panels, and want to detect when they go offline, or come back online and send me an email. I had ChatGPT assist creating an automation that seems to work in testing (manually changing the state of the entity changing from ‘working’ to anything else) The automation is great because I don’t need to list all of my panels, it dynamically build a list and detects from that, will come in handy should I ever get new panels, more panels, swap panels.

Now we tried to create one that detects returning back to ‘working’ it doesn’t seem to work, no matter what we’ve tried, I mostly ended up going in circles with ChatGPT for an hour, Google Gemini just flat out gave up after 3 or so attempts.

So here is the code that works for testing if the entity state changes from ‘working’ to anything else:
Scroll down a bit for what should work, well ChatGPT seems to think so.
And yes there’s some code in there that ChatGPT has been trying to fix some funky formatting in the email.

alias: Solar Panel Offline Alert
description: >-
  Notify when one or more solar panels are NOT in "working" state for more than
  5 seconds.
triggers:
  - value_template: |-
      {{ states.binary_sensor
          | selectattr('entity_id', 'search', '^binary_sensor\.inverter_') 
          | selectattr('state', 'ne', 'working') 
          | list | count > 0 }}
    for: "00:00:05"
    trigger: template
actions:
  - variables:
      offline_panels: |-
        {% set panels = states.binary_sensor
          | selectattr('entity_id', 'search', '^binary_sensor\.inverter_')
          | selectattr('state', 'ne', 'working')
          | list %}
        {% set panel_names = panels
          | map(attribute='attributes.friendly_name')
          | map('regex_replace', find=' ', replace='') %}
        {% for panel in panel_names %}
          - {{ panel }} ({{ panels[loop.index0].state }})
        {% endfor %}
  - data:
      target: [email protected]
      title: ⚠️ Solar Panel Alert
      message: >-
        The following solar panel(s) are NOT in "working" state for over 5
        seconds:

        {{ offline_panels | join('\n') }}
    action: notify.me-at_gmail_com
mode: parallel
max: 5

Okay, now for the code that doesn’t work testing when that sensor changes back to ‘working’

alias: Solar Panel Online Alert
description: Notify when one or more solar panels come back online.
triggers:
  - value_template: |-
      {{ states.binary_sensor
          | selectattr('entity_id', 'search', '^binary_sensor\.inverter_')
          | selectattr('state', 'eq', 'working')
          | list | count > 0 }}
    for: "00:00:05"
    trigger: template
actions:
  - variables:
      online_panels: |-
        {% set panels = states.binary_sensor
          | selectattr('entity_id', 'search', '^binary_sensor\.inverter_')
          | selectattr('state', 'eq', 'working')
          | list %}
        {% set panel_names = panels
          | map(attribute='attributes.friendly_name')
          | map('regex_replace', find='[^a-zA-Z0-9]', replace='_') %}
        {% for panel in panel_names %}
          - {{ panel }} ({{ panels[loop.index0].state }})
        {% endfor %}
  - data:
      level: debug
      message: ✅ Online Trigger Fired!
    action: system_log.write
  - data:
      target: [email protected]
      title: ✅ Solar Panel Online Alert
      message: >-
        The following solar panel(s) are back online: {{ online_panels |
        join('\n') }}
    action: notify.lol_gmail_com
mode: parallel
max: 5

I can manually run the “online” automation, and it does fire off an email, with all 30 panels listed. The formatting is funky, but first I want to fix functionality then the formatting of the email.

Thanks in advance for any assistance.

I don’t think either of those templates are actually “working”…

The state of a binary sensor can only ever be one of the following: “on”, “off”, “unavailable”, “unknown”… it will never be “working”, so the selection selectattr('state', 'ne', 'working') will always pass all the previously selected entities’ state objects and the second one will never pass any state objects.

Second, I don’t know exactly what you were going for, but the following portion:

{% for panel in panel_names %}
  - {{ panel }} ({{ panels[loop.index0].state }})
{% endfor %}

is not creating an actual list, it’s creating a list-shaped string. If you actually want to extract a list as the result of a for loop you need to use a namespace. In the given examples it may not really matter, but it’s an important point to understand for many other use cases.

Finally, addressing the second automation. A template trigger fires when it’s evaluation changes from false to true. Assuming you fix the state selection mentioned previously, the template will only render false when none of the sensor’s are “on”, so it will only ever trigger when they have all been “off” and then the first one turns “on”.

1 Like

First off thank you for taking the time to reply!

I do understand the basics of a binary condition, ChatGPT asked me what values were listed in the actual device state when viewing it in Dev Tools → States, to which I replied ‘working’ is what I see now, so that’s how it got the testing for ‘working’ and it seemed to work if we changed the value of that state in Dev Tools to anything other than ‘working’. And I was under the assumption that somewhere in HomeAssistant this integration defined the values to more human friendly terms versus 0 or 1, on/off, etc.

Currently I believe because the sun is down it lists an ‘error’ in Dev Tools - States: earlier it was ‘working’

As for the loop that was ChatGPT assisting in trying to remove some funky formatting of the email, i gave up on that and was more concentrated on getting both automations working, then going back and making the email correct.

so going forward sounds like I need to test for “on” and changing from “on” to any value and any value back to “on”.

That assumption is not unfounded… there are special “frontend representation” values that are based on the entity’s device class. This is a value that is displayed in dashboard cards or that you may see if you use a Device trigger or condition in the automation editor, but it is not the actual state… that will always be “on” or “off” for binary sensors.

You can see a list of these frontend representations for binary sensors in the docs under the Device Class heading. However, neither “working” nor “error” appear anywhere on that list.

Nope, the only feasible way those values could appear as the state would be if someone manually entered them using the Set State function of the State tool. It will change back to “off” or “on” whenever the integration updates the entity.

Nope, the only feasible way those values could appear as the state would be if someone manually entered them using the Set State function of the State tool. It will change back to “off” or “on” whenever the integration updates the entity.

Well no one is manually entering the state of “error” or “working”. It has to be when the integration is polling the inverter every 300 seconds it changes the value, and the two values I have seen in that state are ‘working’, or ‘error’, unless I manually put something in there for testing purposes, in which case every 300 seconds my changes get replaced with “working” when the sun is up, and now is reporting “error”, because the inverter only actually works when the sun is up to power it. That’s what google says about solar inverters. I am also learning about solar systems as this journey goes on.