Grouping sensors that report non-numeric data

Hello,
I have a number of Homematic three-state HM-Sec-RHS window handle devices, which in HA are identified as sensors. Each sensor reports text info as closed/open/tilted, which is working fine.

  • The Homematic devices used to be controlled by a separate FHEM system that sent individual status info for each window into my LCN bus system. Three LEDs on the switch panel were then used to display per floor info: off for everything closed, blinking for an open window and on for a tilted one.
    Gira 1013

  • I have now migrated all Homematic devices from FHEM to HA/Raspberrymatic. I plan to eventually put some tablets on the walls. Until then I would like to reestablish the window status display using the LEDs

One possibility would be to copy the old functionality by adding an automation for each individual window. However, I thought of using the Group functionality of HA instead to avoid having to set up that many automations, but run into difficulties: the RHS device is a sensor that reports its status as a non-numeric information. Grouping them leads to the group status being always ā€œunavailableā€. Is there a chance to have the group use the text info instead?

No, your best bet would be to use three template binary sensors / helpers.

everything closed

{{ is_state('sensor.window_1','open') and is_state('sensor.window_2','open') and is_state('sensor.window_3','open') }}

an open window

{{ 'open' in [states('sensor.window_1'),states('sensor.window_2'),states('sensor.window_3')] }}

a tilted window

{{ 'tilted' in [states('sensor.window_1'),states('sensor.window_2'),states('sensor.window_3')] }}

Then automate your LEDs based on the states of these sensors.

Thanks Tom,

So no other efficient way than having to look at the 17 windows (like in your example for 1-3) separately for each floor.

The reality is even more complicated because I also have some intelligent windows handles that report off/on/unknown. Hence the need to combine two sensor sets for each of the three states.

And all this for one little LED :smiley:

In FHEM I was calling a special URL that directly set the window status in LCN. Maybe running a separate RESTful command for each window is easier and more flexible.

You could use labels in the UI to label each window that you want to feed into the led status.

Then the template for a binary sensor could be:

{{ label_entities('second_floor_windows')| select('is_state', ['open','on']) | list | count > 0 }}
2 Likes

That looks good! I had already wondered what labels are for. If I understand this correctly, the code line returns the number of entities that are either open or on.

Iā€™ll check it out over the weekend and report back.

Dear @mekaneck ,

Iā€™ve seen that I can assign multiple labels to the same entity, which is great. As a newbie I now struggle with the automation section.

The automation should be triggered by any state change of the labelled entities:

triggers:
- trigger: template
  value_template: {{ label_entities('Fenster Bad/WC')| select('is_state', ['open','on']) | list | count > 0 }}

In the above example I would need to check for

  • open/on ā†’ action LED blink
  • tilted/unknown ā†’ action LED on
  • closed/off ā†’ action LED off

So the automation needs to run upon any state change, which I believe it does.

After reading through the trigger documentation page I am a bit lost. Could you kindly guide me a little bit?

  • Does the trigger value definition work it if I donā€™t use list | count in the trigger value_template?
  • ShouId I use Conditions: and evaluate three different template checks (if open >0 then LED blink, elseif tilted >0 then LED on, else LED off) or is there a better way?.

Each trigger will cause the automation to fire when any one changes from false to true; see the first paragraph of the template trigger docs.

Try it in the template editor (developer tools ā†’ template). The output of the select filter will be a Python generator object, so if you omit | list | count but leave > 0 youā€™ll get an error because you canā€™t conpare a generator object to an integer.

The way Tom suggested originally made sense to me, using 3 binary template sensors. However if you donā€™t want to create any entities and instead want to do it all in an automation, I think youā€™ll need 6 template triggers and then I would use a choose block in the actions, which is essentially a more flexible version of the if/then/else statement.

You will need 6 template triggers because youā€™ll need 3 for when each one goes > 0 and youā€™ll need 3 more for when each one goes < 1 (or == 0). Then in your choose block youā€™ll have 3 options, each with the appropriate template conditions.

Thanks,

Checking the template expressions in the developer tools section give the desired result. The template conditions in my vaml should be ok, but I donā€™t know how to set the trigger definition that it fires upon any change.Right now it does nothing.

  triggers:
  - trigger: template
    value_template: >-
      {{ label_entities('Fenster Bad/WC')| select('is_state', ['open','on', 'tilted']), | list | count > 0 }}
  actions:
  - choose:
    - conditions:
      value_template: >-
        {{ label_entities('Bad/WC')| select('is_state', ['open','on']) | list | count > 0}}
      sequence:
      - action: lcn.pck
        data:
          address: LinHK.0.g50
          pck: LA001B
    - conditions:
      value_template: >-
        {{ label_entities('Bad/WC')| select('is_state', ['tilted','unknown']) | list | count > 0}} 
      sequence:
      - action: lcn.pck
        data:
          address: LinHK.0.g50
          pck: LA001E
    - conditions:
      value_template: >-
        {{ label_entities('Bad/WC')| select('is_state', ['closed','off']) | list | count == 6}}
      sequence:
      - action: lcn.pck
        data:
          address: LinHK.0.g50
          pck: LA001A
  mode: single

What am I doing wrong?

You will need more triggers. You will need a template trigger for each condition that can cause a LED to change behavior:

  • 1 or more windows open
  • zero windows open
  • 1 or more windows tilted/unknown
  • zero windows tilted/unknown
  • 1 or more windows closed
  • 0 windows closed

I crossed out the last two because they are redundant with the first 4. For example you donā€™t need to trigger when you get to zero windows closed because that necessarily means a trigger would occur for either 1 or more windows open or 1 or more windows tilted/unknown. So I originally said you need 6 triggers, but actually 4 will suffice. Itā€™s worth mentioning that including the extra triggers would just make the automation run twice if itā€™s in queued or parallel mode, or once if itā€™s in single or restart mode. Either way, the extra triggers wouldnā€™t hurt anything, theyā€™re just unnecessary.

So a simple check for a state change is not possible or is it?

Anyway, I struggle with the syntax. Testing only one condition with the following code throws missed comma between flow collection entries

  triggers:
  - trigger: template
    value_template: {{ label_entities('Fenster Bad/WC')| select('is_state', ['open','on']), | list | count > 0 }}

Thank you for your patience with me!

Template triggers get evaluated as either true or false, and only fire when they change from false to true. So it is not possible to have a template trigger count a number and then fire when the number changes. But there are many (nearly unlimited) alternatives. Here are some decent ones:

  • have a state trigger, and you select each of your windows to include. You wonā€™t be able to use the label entities though, youā€™ll have to select each entity manually.
  • create a separate template sensor which has itā€™s state as the count of windows that are open, and then set up this automation with a state trigger that will fire whenever that template sensor changes. You will probably want one template sensor calculating the number of open windows, and another template sensor calculating the number of tilted windows. And you can trigger when either one changes.

You have an extra comma:


{{ label_entities('Fenster Bad/WC')| select('is_state', ['open','on']), | list | count > 0 }}
                                                                      ^
                                                                     here

Removed it, still error:

missed comma between flow collection entries (72:90)

69 | ā€¦
70 | ā€¦
71 | ā€¦
72 | ā€¦ lect(ā€˜is_stateā€™, [ā€˜openā€™,ā€˜onā€™]) | list | count > 0 }}

HAā€™s entry hurdle is pretty high.

That will of course work - and is easier to read for me. Maybe not as elegant as the concise syntax that I see here and thereā€¦
Yet if I check for a list of (in total) 27 windows, or maybe 10 per floor, I may as well treat each window individually by reporting its status directly into my LCN bus system where the display logic is already implemented.

That gets close to what I was doing in my FHEM/Homematic setup. However, it was easier there by nestingn simple structure commands, i.e.

structure room1 window1 window2 window3
structure floor1 room1 room2 room3

floor1 would then be used to define a notify to fire upon any window state change in floor1 (room1 to 3), running an action sequence. The underlying concept is the same and I believe one can achieve something similar in HA, but it appears more complicated at first glance.

I guess I need to study the docs a little bit more before I can fully grab HAā€™s capabilities.

I missed the fact that you have a single-line template but did not surround it with double quotes.

Here are some important tips for templating; rule #1 is your issue :wink:

I had read the instruction and tried that but it threw another error. With added quotes I get

bad indentation of a mapping entry (72:41)

 72 |  ... template: '{{ label_entities('Fenster Bad/WC')| select('is_st ...
-----------------------------------------^

I begin to see that indentation is important, so is the use of hyphens and colons. The documentation is not very comprehensive in this direction. The template section has a few examples, but none with the usage of template value. What is even more confusing is that on the other hand HA is not always strict on its semantics, maybe because of legacy and downward compatibility for older code. So searching the forum for solutions is kind of confusing when looking at the code sniplets.

I am extremely grateful that you sacrify your time for me. However, mastering these advanced concepts require a more thorough understanding of yaml programming and object creation that is probably above a newbieā€™s level.

I am not an IT Pro but just a chemist with basic programming skills. I mastered PERL for FHEM/Homematic and will certainly not give up on YAML. Nonetheless, at this moment I am a little bit frustrated because I am down to trial and error. :face_with_raised_eyebrow:

I can provide some more thorough help if you provide the complete YAML you are using. Itā€™s difficult to see what mistakes you might be making, especially with indentations, if I can only see a line or two because I donā€™t know what comes before it.

One thing I can comment on: the template must be surrounded by quotes that donā€™t match any quotes that are inside the template. In other words, use double quotes outside the template if single quotes are used inside the template. Or use multiline format.

  triggers:
  - trigger: template
    value_template: "{{ label_entities('Fenster Bad/WC')| select('is_state', ['open','on']) | list | count > 0 }}"

Or

  triggers:
  - trigger: template
    value_template: '{{ label_entities("Fenster Bad/WC")| select("is_state", ["open","on"]) | list | count > 0 }}'

Or

  triggers:
  - trigger: template
    value_template: >
      {{ label_entities('Fenster Bad/WC')| select('is_state', ['open','on']) | list | count > 0 }}

HA can be a real miracle bag! :laughing: How is one supposed to know that?

Pls see below

This should work: give me a moment to check this out before you reply. :slight_smile:

  actions:
  - choose:
    - conditions:
      - condition: 
        value_template: "{{ label_entities('Bad/WC') | select('is_state', ['open','on']) | list | count > 0}}"
        sequence:
      - action: lcn.pck
        data:
          address: LinHK.0.g50
          pck: LA001B

OK, I now have a code that is semantically correct. I can see with development tools that the template switches form false to true and back if I toggle the entity state between closed and open. But the condition part is not executed. I have the feeling that listing multiple entities in the trigger definition that way is not right.

# ------------------------------------------------------
- id: '1728493173157'
  alias: Signalisierung Fenster Bad/WC
  description: 'Blinken/Leuchten LED1 LCN-Gruppe 50'
  triggers:
  - trigger: state
    entity_id: 
    - binary_sensor.hm_sec_sc_jeq0068580  # WC OG
    - binary_sensor.hm_sec_sc_jeq0069959  # Bad Eltern 1
    - sensor.hm_sec_rhs_jeq0042056        # Bad Eltern 2
    - sensor.hm_sec_rhs_ieq0044522        # WC EG
    - sensor.hm_sec_rhs_jeq0042212        # Bad Kinder
    - sensor.hm_sec_rhs_jeq0152161        # Bad Gast
  actions:
  - choose:
    - conditions:
      - condition: 
        value_template: "{{ label_entities('Bad/WC') | select('is_state', ['open','on']) | list | count > 0}}"
        sequence:
        - action: lcn.pck
          data:
            address: LinHK.0.20
            pck: PIN001
    - conditions:
      - condition:
        value_template: "{{ label_entities('Bad/WC')| select('is_state', ['tilted','unknown']) | list | count > 0}}"
        sequence:
        - action: lcn.pck
          data:
            address: LinHK.0.g50
            pck: LA001E
    - conditions:
        condition:
        value_template: "{{ label_entities('Bad/WC')| select('is_state', ['closed','off']) | list | count == 6}}"
      sequence:
      - action: lcn.pck
        data:
          address: LinHK.0.g50
          pck: LA001A
  mode: single
# ------------------------------------------------------

The first action PIN001 will simply trigger an audible signal next to my desk as a sign that it is executed. It is not.

I would strongly recommend you build your automations using the UI interface until you get to the point where you are confident in your YAML coding skills. Or at least build them piecewise using the UI: Create just a single trigger (or condition or action) with the UI, test it to make sure it works, then switch over to YAML mode and copy the code out of the editor and place it into the automation that you are manually coding. You can do this step-by-step and you will end up with an automation that you have much more confidence in.

Also continue to go back to look for errors in your logs. If nothing is happening when you trigger the automation, there will certainly be errors there that will guide you to the problem.

For YAML, indentation is extremely important. In your choose block, the format should be:

actions:
  - choose:
    - conditions:
      - # conditions for the first option
      sequence: 
      - # actions for the first option
    - conditions:
      - # conditions for the second option
      sequence: 
      - # actions for the second option    
...

You had extra indentation in front of the sequence: lines. You were also missing the hyphen in front of the 3rd condition which makes it a dictionary (or ā€œmappingā€) instead of a list.

Iā€™m also not certain that comments are allowed on the same line as valid YAML, but I left them in the code below but I didnā€™t verify it worked.

You can also refer to this page for automation YAML information and examples.

Hereā€™s what I think you should have for your code:

# ------------------------------------------------------
- id: '1728493173157'
  alias: Signalisierung Fenster Bad/WC
  description: 'Blinken/Leuchten LED1 LCN-Gruppe 50'
  triggers:
    - trigger: state
      entity_id: 
        - binary_sensor.hm_sec_sc_jeq0068580  # WC OG
        - binary_sensor.hm_sec_sc_jeq0069959  # Bad Eltern 1
        - sensor.hm_sec_rhs_jeq0042056        # Bad Eltern 2
        - sensor.hm_sec_rhs_ieq0044522        # WC EG
        - sensor.hm_sec_rhs_jeq0042212        # Bad Kinder
        - sensor.hm_sec_rhs_jeq0152161        # Bad Gast
  actions:
    - choose:
        - conditions:
            - condition: 
              value_template: "{{ label_entities('Bad/WC') | select('is_state', ['open','on']) | list | count > 0}}"
          sequence:
            - action: lcn.pck
              data:
                address: LinHK.0.20
                pck: PIN001
        - conditions:
            - condition:
              value_template: "{{ label_entities('Bad/WC')| select('is_state', ['tilted','unknown']) | list | count > 0}}"
          sequence:
            - action: lcn.pck
              data:
                address: LinHK.0.g50
                pck: LA001E
        - conditions:
            - condition:
              value_template: "{{ label_entities('Bad/WC')| select('is_state', ['closed','off']) | list | count == 6}}"
          sequence:
            - action: lcn.pck
              data:
                address: LinHK.0.g50
                pck: LA001A
  mode: single
# ------------------------------------------------------

Comments on the same line are allowed, but are discouraged:
YAML style guide

Also see the section on indentation for block-style sequences. That is why my example has more indentation than yours.

If you donā€™t want to list out your entities manually in the triggers, here would be the 4 template triggers you can use:

triggers:
  - trigger: template
    value_template: "{{ label_entities('Bad/WC') | select('is_state', ['open', 'on']) | list | count > 0 }}"
  - trigger: template
    value_template: "{{ label_entities('Bad/WC') | select('is_state', ['open', 'on']) | list | count < 1 }}"
  - trigger: template
    value_template: "{{ label_entities('Bad/WC') | select('is_state', ['tilted', 'unknown']) | list | count > 0 }}"
  - trigger: template
    value_template: "{{ label_entities('Bad/WC') | select('is_state', ['tilted', 'unknown']) | list | count < 1 }}"
1 Like