How to create a list of multiple rooms to clean within an automation

Currently i am using node-red to start my roborock vacuum to clean selected rooms.

Therefore i added a function node that evaluates which rooms are selected.

var myarray=[]

for (var i = 0; i < msg.payload.length; i++) {
    if (msg.payload[i].entity_id == "input_boolean.raumauswahl_flur_technik") {
        myarray.push(21);
    }
    else if (msg.payload[i].entity_id == "input_boolean.raumauswahl_kuche") {
        myarray.push(20);
    }
    else if (msg.payload[i].entity_id == "input_boolean.raumauswahl_wohnzimmer") {
        myarray.push(23);
    }
    else if (msg.payload[i].entity_id == "input_boolean.raumauswahl_waschkuche") {
        myarray.push(17);
    }
    else if (msg.payload[i].entity_id == "input_boolean.raumauswahl_alte_kuche") {
        myarray.push(22);
    }
    else if (msg.payload[i].entity_id == "input_boolean.raumauswahl_gaste_wc") {
        myarray.push(16);
    }
    else if (msg.payload[i].entity_id == "input_boolean.raumauswahl_flur_eingang") {
        myarray.push(19);
    }
    else if (msg.payload[i].entity_id == "input_boolean.raumauswahl_esstisch") {
        myarray.push(18);
    }
}
msg.payload = myarray
return msg;

Is there a similar way to achieve this in a home assistant automation?

In the end i need a automation that creates the following service call:

service: vacuum.send_command
data:
  command: app_segment_clean
  params:
    - segments:
        - 22
        - 23
      repeat: 2
target:
  entity_id: vacuum.s7_roborock

What i need to create dynamically is the list of the segments.

In your Node-Red flow, msg.payload contains a list of Input Booleans. The for-loop iterates through the list and checks if it contains the entity_id any of six specific Input Booleans. For each matching Input Boolean, it appends its associated integer value to a list.

What in Home Assistant contains this list of Input Booleans?

In other words, how do you plan to tell the automation which rooms you want to have vacuumed?

1 Like

What in Home Assistant contains this list of Input Booleans?

That is exactly my question, how can i achieve this.

I have those input_booleans and need the list → the values for the segment parameter.

Let me re-phrase my question.

How are you currently telling your Node-Red flow which rooms you want vacuumed?

You appear to have a Function node that receives msg.payload containing a list of Input Booleans. What is/are the previous node(s) in your flow that is producing the list of Input Booleans and passing it to your Function node via msg.payload?

1 Like

Ah got it. Its an „get entities„ node and „in group“ selection within that node

So a group entity contains the list of input_boolean entities?

What is the group entity’s entity_id?

1 Like

Its

group.raumauswahl_erdgeschoss_alle_raume

  - service: vacuum.send_command
    data:
      command: app_segment_clean
      params:
        - segments: >
            {% set rooms = {
              "input_boolean.raumauswahl_flur_technik": 21,
              "input_boolean.raumauswahl_kuche": 20,
              "input_boolean.raumauswahl_wohnzimmer": 23,
              "input_boolean.raumauswahl_waschkuche": 17,
              "input_boolean.raumauswahl_alte_kuche": 22,
              "input_boolean.raumauswahl_gaste_wc": 16,
              "input_boolean.raumauswahl_flur_eingang": 19 } %}
            {% set ns = namespace(room_numbers=[]) %}
            {% for room in state_attr('group.raumauswahl_erdgeschoss_alle_raume', 'entity_id') %}
            {% set ns.room_numbers = ns.room_numbers + [rooms.get(room)] %}
            {% endfor %}
            {{ ns.room_numbers }}
      repeat: 2
target:
  entity_id: vacuum.s7_roborock
2 Likes

Wow thank you!

The example from 123 is efficient!

I do the same thing, but with extra steps. I put all my “segments” code into a template sensor, then point to that for the params in the service call.

I add my room numbers as attributes on the input booleans using customize.yaml:
CONFIG > customize.yaml

input_boolean.raumauswahl_flur_technik:
  room_id: "21"
input_boolean.raumauswahl_kuche:
  room_id: "20"
input_boolean.raumauswahl_wohnzimmer:
  room_id: "23"
input_boolean.raumauswahl_waschkuche:
  room_id: "17"
input_boolean.raumauswahl_alte_kuche:
  room_id: "22"
input_boolean.raumauswahl_gaste_wc:
  room_id: "16"
input_boolean.raumauswahl_flur_eingang:
  room_id: "19"

Then make sure you tell home assistant about the customize.yaml file. Place the following in
CONFIG > configuration.yaml:

homeassistant:
  customize: !include customize.yaml

By doing this type of attribute customization, you might then create a template sensor helper with the following: (I named mine “sensor.active_vacuum_zones”)

{% set ns =namespace(COMMAND = "") -%}
{%- set ROOM_FLAGS = expand("group.raumauswahl_erdgeschoss_alle_raume") | selectattr("state", "eq", "on") | list-%}

{%- for flag in ROOM_FLAGS -%}
  {%- set ROOM_NUMBER = flag.attributes.room_id -%}
  {% if loop.last %}
    {%- set ROOM_NUMBER_STR = (ROOM_NUMBER|string) -%}
  {% else %}
    {%- set ROOM_NUMBER_STR = (ROOM_NUMBER|string +",") -%}
  {% endif %}
  {%- set ns.COMMAND = ns.COMMAND + ROOM_NUMBER_STR -%}
{%- endfor -%}

[{{ ns.COMMAND }}]

Now in your script code you call the list from the helper sensor:

service: vacuum.send_command
data:
  command: app_segment_clean
  params:
    - segments: "{{ states('sensor.active_vacuum_zones') }}"
      repeat: 2
target:
  entity_id: vacuum.s7_roborock

In my example, I used a dictionary to store the relationship between an Input Boolean and its associated room id.

In super60’s example, Manual Customization is used to store each Input Boolean’s room id in a custom attribute (named room_id).

If you store the room id in a custom attribute, it reduces the template to this:

- service: vacuum.send_command
    data:
      command: app_segment_clean
      params:
        - segments: >
            {{ expand(state_attr('group.raumauswahl_erdgeschoss_alle_raume', 'entity_id') )
              | map(attribute='attributes.room_id')
              | map('int', 16) | list }} 
      repeat: 2
target:
  entity_id: vacuum.s7_roborock
2 Likes

I love this script but I would like to have it only vacuum the rooms I select–the rooms were the input_boolean for that room is on. The group contains all the rooms and correctly pulls the corresponding seqment numbers, but for my use case, I want to only vacuum the segments where the corresponding input_boolean segment(s) for the rooms have been turned on.

EDIT:
I figured out what I needed: from @123’s first example just add an if around making the room list:

        {% if states(room) == 'on' %}
          {% set ns.room_numbers = ns.room_numbers + [rooms.get(room)] %}
        {% endif %}

I am trying to use this, but I am struggling creating a helper group (group.raumauswahl_erdgeschoss_alle_raume) containing all of my input_boolean helpers. The GUI doesn’t let me create a group containing those helpers, at least the entities can’t be found. Maybe I have to create the group via YAML? :slight_smile:

Or is there a better way to get @123 script working, without having to create a group that contains the boolean helpers?

Also, if all of my room helpers are set to OFF, I would like to clean all of the rooms. What’s a good way to achieve that? Add all room ids to “segments”?

Yes.

group entities cannot be created via the UI.

You could add a label to each Input Boolean and then, in the automation, select all Input Booleans having the same label.

1 Like

Thanks, in the meantime I created a group via YAML. Seems to be working.

Now I only need to check somehow if all of the helpers are “off” and if so, then all rooms are supposed to be cleaned.