Script service data_template array based on input_boolean

I’m trying to create an array of elements to be set by input_boolean and used in script service call.

vacuum_zones:
  alias: 'Vacuum zones'
  sequence:
    - service: vacuum.send_command
      data_template:
        entity_id: vacuum.vacuum
        command: zoned_cleanup
        params:
          zone_ids: >-
            {% if is_state('input_boolean.vacuum_zone_corridor', 'on') %}'Corridor'{% endif %}
            {% if is_state('input_boolean.vacuum_zone_kitchen', 'on') %}'Kitchen'{% endif %}
            {% if is_state('input_boolean.vacuum_zone_saloon', 'on') %}'Saloon'{% endif %}
            {% if is_state('input_boolean.vacuum_zone_bathroom', 'on') %}'Bathroom'{% endif %}
            {% if is_state('input_boolean.vacuum_zone_office', 'on') %}'Office'{% endif %}
            {% if is_state('input_boolean.vacuum_zone_bedroom', 'on') %}'Bedroom'{% endif %}

I hope example above is self-explanatory. I’ve found similar data_template and tried to adjust it, but it gives no error in logs and also doesn’t start zoned cleanup.

When i.e. input_boolean.vacuum_zone_kitchen and input_boolean.vacuum_zone_bathroom are on I’d like to send such a service call:

    - service: vacuum.send_command
      data:
        entity_id: vacuum.vacuum
        command: zoned_cleanup
        params:
          zone_ids: ['Kitchen', 'Bathroom']

I believe YAML’s - element work same as [], because I tested example via Dev tools in UI.

vacuum_zones:
  alias: 'Vacuum zones'
  sequence:
    - service: vacuum.send_command
      data_template:
        entity_id: vacuum.vacuum
        command: zoned_cleanup
        params:
          zone_ids: >-
            [ {% if is_state('input_boolean.vacuum_zone_corridor', 'on') %}'Corridor',{% endif %}
              {% if is_state('input_boolean.vacuum_zone_kitchen', 'on') %}'Kitchen',{% endif %}
              {% if is_state('input_boolean.vacuum_zone_saloon', 'on') %}'Saloon',{% endif %}
              {% if is_state('input_boolean.vacuum_zone_bathroom', 'on') %}'Bathroom',{% endif %}
              {% if is_state('input_boolean.vacuum_zone_office', 'on') %}'Office',{% endif %}
              {% if is_state('input_boolean.vacuum_zone_bedroom', 'on') %}'Bedroom'{% endif %} ]
1 Like

Also tried this way – same result. Mind the difference between >- and >.

Someone recently had the same question and the solution that worked for them has not, unfortunately, worked for you. The difference is that their template was returning a list directly to params as opposed to zone_ids. I don’t understand why that would make difference but apparently it does because the same technique isn’t working for you.

I’m using home assistant 0.103 in a venv and I have a similar problem with templating zones.

Simplified example:
I have two zones (kitchen and living room). Everything works perfect, if I use a separate script for every zone like this:

vacuum_room:
  alias: "zoned cleaning"
  sequence:
    - service: vacuum.send_command
      data_template:
        entity_id: vacuum.rockrobo
        command: 'zoned_cleanup'
        params:
          'zone_ids': ['kitchen']

But I don’t want to have a seperate script for every zone. I would like to use one script like this:

vacuum_room:
  alias: "zoned cleaning"
  sequence:
    - service: vacuum.send_command
      data_template:
        entity_id: vacuum.rockrobo
        command: 'zoned_cleanup'
        params:
          'zone_ids': >
            {%- if is_state("input_select.vacuum_room", "Kitchen") %}['kitchen']{% endif %}
            {%- if is_state("input_select.vacuum_room", "Living Room") %}['living room']{% endif %}

The script seems to be executed without an error, but the vacuum does not start.

Here is an extraction of the log from the working script:

2019-12-20 06:52:43 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection.1528187664] Received {'type': 'call_service', 'domain': 'script', 'service': 'turn_on', 'service_data': {'entity_id': 'script.vacuum_room'}, 'id': 62}
2019-12-20 06:52:43 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=vacuum, service=send_command, service_data=entity_id=vacuum.rockrobo, command=zoned_cleanup, params=zone_ids=['kitchen']>
2019-12-20 06:52:43 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=mqtt, service=publish, service_data=topic=valetudo/rockrobo/custom_command, qos=0, retain=False, payload={"command": "zoned_cleanup", "zone_ids": ["kitchen"]}>
2019-12-20 06:52:43 DEBUG (MainThread) [homeassistant.components.mqtt] Transmitting message on valetudo/rockrobo/custom_command: {"command": "zoned_cleanup", "zone_ids": ["kitchen"]}

Here is an extraction of the log from the not working script:

2019-12-20 06:51:24 DEBUG (MainThread) [homeassistant.components.websocket_api.http.connection.1528187664] Received {'type': 'call_service', 'domain': 'script', 'service': 'turn_on', 'service_data': {'entity_id': 'script.vacuum_room'}, 'id': 57}
2019-12-20 06:51:24 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=vacuum, service=send_command, service_data=entity_id=vacuum.rockrobo, command=zoned_cleanup, params=zone_ids=['kitchen']>
2019-12-20 06:51:24 DEBUG (MainThread) [homeassistant.core] Bus:Handling <Event call_service[L]: domain=mqtt, service=publish, service_data=topic=valetudo/rockrobo/custom_command, qos=0, retain=False, payload={"command": "zoned_cleanup", "zone_ids": "['kitchen']"}>
2019-12-20 06:51:24 DEBUG (MainThread) [homeassistant.components.mqtt] Transmitting message on valetudo/rockrobo/custom_command: {"command": "zoned_cleanup", "zone_ids": "['kitchen']"}

Comparing the two logs it seems a problem of the double quotes. I already tried different notations in the template, but I always have problems with the double quotes.
Strangely the second line of the log is equal and in the third line of the log there is a difference with the double quotes, which is probably the reason of my problem.

Any hints what’s going wrong?

Thanks in advance!

There’s no need to put single quotes around zone_ids but that’s not the main issue. The primary problem is that you can’t use a template to generate a list. The Jinja2 interpreter always outputs a string. That means this template:

          'zone_ids': >
            {%- if is_state("input_select.vacuum_room", "Kitchen") %}['kitchen']{% endif %}
            {%- if is_state("input_select.vacuum_room", "Living Room") %}['living room']{% endif %}

will produce either ['kitchen'] or `[‘living room’] which have the appearance of a list but are actually strings because they were generated by the template.

The template should be limited to producing the list’s items and not the list itself.

         zone_ids: [ {{template_goes_here}} ]
1 Like

Thank you for the explanation. Now everything works. :grinning:

vacuum_room:
  alias: "zoned cleaning"
  sequence:
    - service: vacuum.send_command
      data_template:
        entity_id: vacuum.rockrobo
        command: 'zoned_cleanup'
        params:
          zone_ids: [ "{% if is_state('input_select.vacuum_room', 'Kitchen') %}kitchen{% elif is_state('input_select.vacuum_room', 'Living Room') %}living room{% endif %}" ]
1 Like

Hi,

Sorry for the necro, but I spent a lot of time finding a solution and I finally did it:

I am using Xiaomi Cloud Map Extractor to get the room numbers, then I created a boolean input for each room and a script to trigger the clean-up. Since it’s not possible to use append, I was able to use pop. ‘gg’ is not used, but it seems like pop is not working unless I return the result to a variable.

start_cleanup:
  alias: Start cleanup
  sequence:
  - data_template:
      entity_id: vacuum.xiaomi_vacuum_cleaner
      service: xiaomi_miio.vacuum_clean_segment
      segments: >-
          {% set myList = [4,3,1,16,2,5,17] %}
          {% if states.input_boolean.aspira_dormitor_mare.state != "on" %}
            {% set gg = myList.pop(myList.index(4)) %}
          {% endif %}
          {% if states.input_boolean.aspira_dormitor_mic.state != "on" %}
            {% set gg = myList.pop(myList.index(3)) %}
          {% endif %}
          {% if states.input_boolean.aspira_hol.state != "on" %}
            {% set gg = myList.pop(myList.index(1)) %}
          {% endif %}
          {% if states.input_boolean.aspira_bucatarie.state != "on" %}
            {% set gg = myList.pop(myList.index(16)) %}
          {% endif %}
          {% if states.input_boolean.aspira_baia_mica.state != "on" %}
            {% set gg = myList.pop(myList.index(2)) %}
          {% endif %}
          {% if states.input_boolean.aspira_baia_mare.state != "on" %}
            {% set gg = myList.pop(myList.index(5)) %}
          {% endif %}
          {% if states.input_boolean.aspira_living.state != "on" %}
            {% set gg = myList.pop(myList.index(17)) %}
          {% endif %}
          {{myList}}

Here’s another way to achieve the same thing. Instead of using pop to remove items from a list, it starts with an empty list and adds items to it.

start_cleanup:
  alias: Start cleanup
  sequence:
  - data:
      entity_id: vacuum.xiaomi_vacuum_cleaner
      service: xiaomi_miio.vacuum_clean_segment
      segments: >-
        {% set s = [] %}
        {% set ib = 'input__boolean.aspira_' %}
        {% set s = s + [4]  if is_state(ib ~ 'dormitor_mare', 'on') else s %}
        {% set s = s + [3]  if is_state(ib ~ 'dormitor_mic', 'on') else s %}
        {% set s = s + [1]  if is_state(ib ~ 'hol', 'on') else s %}
        {% set s = s + [16] if is_state(ib ~ 'bucatarie', 'on') else s %}
        {% set s = s + [2]  if is_state(ib ~ 'baia_mica', 'on') else s %}
        {% set s = s + [5]  if is_state(ib ~ 'baia_mare', 'on') else s %}
        {% set s = s + [17] if is_state(ib ~ 'living', 'on') else s %}
        {{s}}

oh, so append doesn’t work but it’s that easy to concatenate lists. Great! Thank you

This Topic helped me quite a bit, saved me much time. Thanks for that in advance…
One problem I run into is that my payload require a “,” between the items but if there is a “,” at the end the vacuum doenst start.

service: mqtt.publish
data:
  topic: valetudo/rockrobo-staubsauger/ZoneCleaningCapability/start/set
  retain: false
  payload: >-
    [{% if is_state('input_boolean.saugen_bad', 'on')
    %}"042104cc-c4bf-4805-9c81-585528e5d48d",{% endif %}{% if
    is_state('input_boolean.saugen_buero', 'on')
    %}"a4985750-6cb7-460a-9160-97672b7107b7",{% endif %}{% if
    is_state('input_boolean.saugen_couchbereich', 'on')
    %}"eba581c9-71ce-45a6-8050-a6f2e5744d6f",{% endif %}{% if
    is_state('input_boolean.saugen_flur', 'on')
    %}"d1d52d1d-2720-4782-8346-c1fdc9d36e80",{% endif %}{% if
    is_state('input_boolean.saugen_kueche', 'on')
    %}"314d183c-60f5-43fd-9dc1-de0361689779",{% endif %}{% if
    is_state('input_boolean.saugen_schlafzimmer', 'on')
    %}"9fbd998a-9afd-4913-a353-9dcea33a334b",{% endif %}{% if
    is_state('input_boolean.saugen_wohnzimmer', 'on')
    %}"d9b13f15-d427-40da-98d7-22ed250f6e10",{% endif %}{% if
    is_state('input_boolean.saugen_zimmer', 'on')
    %}"ff00afa6-1040-4d66-aa5a-1c9f3ea5088a"{% endif %}]

If I then only choose Wohnzimmer the string in mqtt looks like this…and the nothing more happens.

set = ["d9b13f15-d427-40da-98d7-22ed250f6e10",]

Any Idea how to cut off the last “,” every time ?

I suggest using a different approach. It requires organizing the data so that it becomes much easier to use in a template.

It involves assigning each one of the input_booleans a custom attribute called vacuum_area (the name can be whatever you want). It also requires creating a group (in this example I named it group.vacuum_areas) containing the 8 input_booleans.

The first step is to ensure configuration.yaml contains this important line concerning the location of the customize.yaml data:

homeassistant:
  customize: !include customize.yaml

In the customize.yaml file, add the following 8 input_booleans:

input_boolean.saugen_bad:
  vacuum_area: "042104cc-c4bf-4805-9c81-585528e5d48d"
input_boolean.saugen_buero:
  vacuum_area: "a4985750-6cb7-460a-9160-97672b7107b7"
input_boolean.saugen_couchbereich:
  vacuum_area: "eba581c9-71ce-45a6-8050-a6f2e5744d6f"
input_boolean.saugen_flur:
  vacuum_area: "d1d52d1d-2720-4782-8346-c1fdc9d36e80"
input_boolean.saugen_kueche:
  vacuum_area: "314d183c-60f5-43fd-9dc1-de0361689779"
input_boolean.saugen_schlafzimmer:
  vacuum_area: "9fbd998a-9afd-4913-a353-9dcea33a334b"
input_boolean.saugen_wohnzimmer:
  vacuum_area: "d9b13f15-d427-40da-98d7-22ed250f6e10"
input_boolean.saugen_zimmer:
  vacuum_area: "ff00afa6-1040-4d66-aa5a-1c9f3ea5088a"

Now restart Home Assistant.

After it has restarted, go to Developer Tools > States and confirm input_boolean.saugen_bad has a custom attribute called vacuum_area and its value is:
042104cc-c4bf-4805-9c81-585528e5d48d

Add the following new group to wherever you currently define your groups (typically groups.yaml or in configuration.yaml).

vacuum_areas:
  name: Vacuum Areas
  entities:
    - input_boolean.saugen_bad
    - input_boolean.saugen_buero
    - input_boolean.saugen_couchbereich
    - input_boolean.saugen_flur
    - input_boolean.saugen_kueche
    - input_boolean.saugen_schlafzimmer
    - input_boolean.saugen_wohnzimmer
    - input_boolean.saugen_zimmer

Execute Configuration > Server Controls > Reload Groups.

When it’s done, go to Developer Tools > States and confirm group.vacuum_areas exists and its members are the 8 input_booleans (displayed in its entities attribute).

Now the template can be simplified because the data is easily processed. Test the template by pasting it into the Template Editor and viewing the result.

    {{ expand('group.vacuum_areas') | selectattr('state', 'eq', 'on')
        | map(attribute='attributes.vacuum_area') | list }}

If it produces the output you want, you can add the template to your MQTT Publish command:

service: mqtt.publish
data:
  topic: valetudo/rockrobo-staubsauger/ZoneCleaningCapability/start/set
  retain: false
  payload: >
    {{ expand('group.vacuum_areas') | selectattr('state', 'eq', 'on')
        | map(attribute='attributes.vacuum_area') | list }}
1 Like

Thanks for very quick answer. Your approch looks good and organizied but I dont really want to use “manual” yaml files witch need restart of HA and so.

I think I have come up with solution just some minutes ago inside the webui with out any needed changes beside the template.
I can pretty easily add and remove zones without much hassle.

    {% set s = 0 %}
    {% set ib = 'input_boolean.saugen_' %}
    {% set s = s + 1 if is_state(ib ~ 'bad', 'on') else s %}
    {% set s = s + 1 if is_state(ib ~ 'buero', 'on') else s %}
    {% set s = s + 1 if is_state(ib ~ 'couchbereich', 'on') else s %}
    {% set s = s + 1 if is_state(ib ~ 'flur', 'on') else s %}
    {% set s = s + 1 if is_state(ib ~ 'kueche', 'on') else s %}
    {% set s = s + 1 if is_state(ib ~ 'schlafzimmer', 'on') else s %}
    {% set s = s + 1 if is_state(ib ~ 'wohnzimmer', 'on') else s %}
    {% set s = s + 1 if is_state(ib ~ 'zimmer', 'on') else s %}

    [{% if is_state('input_boolean.saugen_bad', 'on')%}{% set s = s - 1 %}"042104cc-c4bf-4805-9c81-585528e5d48d"{% if s != 0 %},{% endif %}{% endif %}
	{% if is_state('input_boolean.saugen_buero', 'on')%}{% set s = s - 1 %}"a4985750-6cb7-460a-9160-97672b7107b7"{% if s != 0 %},{% endif %}{% endif %}
	{% if is_state('input_boolean.saugen_couchbereich', 'on')%}{% set s = s - 1 %}"eba581c9-71ce-45a6-8050-a6f2e5744d6f"{% if s != 0 %},{% endif %}{% endif %}
	{% if is_state('input_boolean.saugen_flur', 'on')%}{% set s = s - 1 %}"d1d52d1d-2720-4782-8346-c1fdc9d36e80"{% if s != 0 %},{% endif %}{% endif %}
	{% if is_state('input_boolean.saugen_kueche', 'on')%}{% set s = s - 1 %}"314d183c-60f5-43fd-9dc1-de0361689779"{% if s != 0 %},{% endif %}{% endif %}
	{% if is_state('input_boolean.saugen_schlafzimmer', 'on')%}{% set s = s - 1 %}"9fbd998a-9afd-4913-a353-9dcea33a334b"{% if s != 0 %},{% endif %}{% endif %}
	{% if is_state('input_boolean.saugen_wohnzimmer', 'on')%}{% set s = s - 1 %}"d9b13f15-d427-40da-98d7-22ed250f6e10"{% if s != 0 %},{% endif %}{% endif %}
	{% if is_state('input_boolean.saugen_zimmer', 'on')%}{% set s = s - 1 %}"ff00afa6-1040-4d66-aa5a-1c9f3ea5088a"{% if s != 0 %},{% endif %}{% endif %}]
    
    {## only needed for debug ##}
    {{s}}

They only need a restart once and you may not even need to do it if you already have customize: !include customize.yaml in your config file. Afterwards, manual customizations can be reloaded via the UI.

If you don’t want to create custom attributes via customize.yaml, you can create them via Configuration > Customization. However, that takes more time (you customize each entity individually) than simply copy-pasting what I prepared above.

I don’t know how you are creating your groups, but they can only be created via YAML and they can be reloaded via the UI.

If you foresee the need to constantly add/subtract input_booleans then don’t create a group. Simply include them within the template itself. It’s still neater and simpler than long chains of if-else statements that splice phrases together.

  payload: >
    {{ expand('input_boolean.saugen_bad', 'input_boolean.saugen_buero',
              'input_boolean.saugen_couchbereich', 'input_boolean.saugen_flur',
              'input_boolean.saugen_kueche', 'input_boolean.saugen_schlafzimmer',
              'input_boolean.saugen_wohnzimmer', 'input_boolean.saugen_zimmer')
       | selectattr('state', 'eq', 'on')
       | map(attribute='attributes.vacuum_area') | list }}

The advantage of making the identifier (like 042104cc-c4bf-4805-9c81-585528e5d48d) a part of the input_boolean (as a custom attribute) is that it becomes accessible to other templates as well. It is centralized (one source of truth) and readily visible in Developer Tools > States. Those advantages are lost if the identifier is buried within one template.

Compare the effort of maintaining the template I posted to what you suggested. If I don’t want input_boolean.saugen_kueche to be included, I simply remove that one reference to it within the expand() function and done. There’s no extra effort of ensuring I haven’t corrupted an if-else chain or having to remove a second reference to it elsewhere in the template.

If I want to add an input_boolean, I simply append it within expand(). I don’t even have to remember its identifier because that’s already within its custom attribute that I have defined elsewhere.

1 Like

Happy to see some activities around the vaccum.
I just uprgrade my vaccum to valetudo 2021.06.0
With the new version there is a new mqtt sensor giving back all segments as an array.
Is there an easy way to select from there and send the mqtt statement accordingly?
The state attributes looks like this:

‘16’: Floor
‘17’: Kitchen
‘18’: Wardrobe
‘19’: Toilet
‘20’: Bedroom
‘21’: Balcony
‘22’: Livingroom
‘23’: Bathroom
‘24’: Couch
‘25’: Dining
friendly_name: Map segments
icon: mdi:vector-selection

Tell me, how do I use list encoding= “UTF-8” so that I can use the text in Russian, and not in English?

zone_ids": {{ expand(‘group.vacuum_zones’) | selectattr(‘state’, ‘eq’, ‘on’) | map(attribute=‘name’) |list encode(“utf-8”) |to_json }}

Below is an example of what the result looks like in the template

\u0413\u043e\u0441\u0442\u0438\u043d\u0430\u044f - this is an input_boolean with the name Living Room in Russian

“zone_ids”: [“\u0413\u043e\u0441\u0442\u0438\u043d\u0430\u044f”, “Hallway”]

  1. I don’t know the answer to your question.

  2. You directed your question specifically to me but I never discussed text encoding (I mentioned the use of custom attributes).

  3. Hopefully someone else can help you.

The issue is resolved. I express my gratitude to dext0r for the help. Link to its integration custom_filters

  1. Install the integration via HACS
  2. Add the custom_filters line to configuration.yaml
    image
  3. Restart the Home Assistant
  4. In the template, we use to_ascii_dcon and check whether it should encode characters into text in a language that we understand
"zone_ids": {{ expand('group.vacuum_zones') | selectattr('state', 'eq', 'on') | map(attribute ='name') |list| to_ascii_json }}

"zone_ids": {{ expand('group.vacuum_zones') | selectattr('state', 'eq', 'on') | map(attribute ='name') |list| to_json }}

image

Creating a group: Vacuum cleaner: Zonal cleaning в groups.yaml

vacuum_zones:
    name: "Vacuum cleaner: Zonal cleaning"
    all: false
    entities:
      - input_boolean.vacuum_cleaning_corridor
      - input_boolean.vacuum_cleaning_kitchen
      - input_boolean.vacuum_cleaning_living_room
      - input_boolean.vacuum_cleaning_bedroom_01
      - input_boolean.vacuum_cleaning_bedroom_02

Creating automation: Vacuum cleaner: Starting zonal cleaning

alias: 'Vacuum cleaner: Starting zonal cleaning'
description: ''
trigger:
  - platform: state
    entity_id: group.vacuum_zones
    from: 'off'
    to: 'on'
    id: vacuum zones on
  - platform: state
    entity_id: vacuum.rockrobo
    to: docked
    id: vacuum docked
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: vacuum zones on
        sequence:
          - delay:
              hours: 0
              minutes: 0
              seconds: 5
              milliseconds: 0
          - service: vacuum.send_command
            target:
              entity_id: vacuum.rockrobo
            data:
              command: zoned_cleanup
              params:
                zone_ids: >
                  {{ expand('group.vacuum_zones') | selectattr('state', 'eq',
                  'on') | map(attribute ='name') |list| to_ascii_json }}
      - conditions:
          - condition: trigger
            id: vacuum docked
        sequence:
          - service: homeassistant.turn_off
            target:
              entity_id: group.vacuum_zones
    default: []
mode: single
Текст на русском языке

Вопрос решен. Выражаю dext0r благодарность за помощь. Ссылка на его интеграцию custom_filters

  1. Устанавливаем интеграцию через HACS
  2. Добавляем в configuration.yaml строчку custom_filters:
    image
  3. Перезагружаем Home Assistant
  4. В шаблоне используем to_ascii_json и проверяем, должно кодировать символы в текст на понятном нам языке
"zone_ids": {{ expand('group.vacuum_zones') | selectattr('state', 'eq', 'on') | map(attribute ='name') |list| to_ascii_json }}

"zone_ids": {{ expand('group.vacuum_zones') | selectattr('state', 'eq', 'on') | map(attribute ='name') |list| to_json }}

image

Создаем группу: Пылесос: Зональная уборка в groups.yaml

vacuum_zones:
    name: "Пылесос: Зональная уборка"
    all: false
    entities:
      - input_boolean.vacuum_cleaning_corridor
      - input_boolean.vacuum_cleaning_kitchen
      - input_boolean.vacuum_cleaning_living_room
      - input_boolean.vacuum_cleaning_bedroom_01
      - input_boolean.vacuum_cleaning_bedroom_02

Создаем автоматизацию: Пылесос: Запуск зональной уборки

alias: 'Пылесос: Запуск зональной уборки'
description: ''
trigger:
  - platform: state
    entity_id: group.vacuum_zones
    from: 'off'
    to: 'on'
    id: vacuum zones on
  - platform: state
    entity_id: vacuum.rockrobo
    to: docked
    id: vacuum docked
condition: []
action:
  - choose:
      - conditions:
          - condition: trigger
            id: vacuum zones on
        sequence:
          - delay:
              hours: 0
              minutes: 0
              seconds: 5
              milliseconds: 0
          - service: vacuum.send_command
            target:
              entity_id: vacuum.rockrobo
            data:
              command: zoned_cleanup
              params:
                zone_ids: >
                  {{ expand('group.vacuum_zones') | selectattr('state', 'eq',
                  'on') | map(attribute ='name') |list| to_ascii_json }}
      - conditions:
          - condition: trigger
            id: vacuum docked
        sequence:
          - service: homeassistant.turn_off
            target:
              entity_id: group.vacuum_zones
    default: []
mode: single

There is another option, this is the use of cleaning in the order of the queue. For example, we chose the kitchen first, then the bedroom and the living room, then the vacuum cleaner will clean the kitchen, bedroom and living room. In the case of the alphabetic alphabet, the vacuum cleaner will clean first in the bedroom, then in the kitchen and then in the living room.

image

image

The order of cleaning
zone_ids: {{ expand(‘group.vacuum_zones’) | sort(attribute=‘last_changed’) | selectattr(‘state’, ‘eq’, ‘on’) | map(attribute =‘name’) | list | to_ascii_json }}

Alphabetically
zone_ids: {{ expand(‘group.vacuum_zones’) | selectattr(‘state’, ‘eq’,‘on’) | map(attribute =‘name’) |list| to_ascii_json }}

If you have a xiaomi vacuum cleaner with the original firmware, then you can use this integration
VacuumZones

Текст на русском языке

Есть еще один вариант, это использование уборки в порядке очереди. Например мы выбрали сначала кухню, потом спальню и гостиную, то пылесос сделает уборку на кухне, в спальне и в гостиной. В случае буквенного алфавита, пылесос будет убирать сначала в спальне, потом на кухне и потом в гостиной.

image

Очередность уборки
zone_ids: {{ expand(‘group.vacuum_zones’) | sort(attribute=‘last_changed’) | selectattr(‘state’, ‘eq’, ‘on’) | map(attribute =‘name’) | list | to_ascii_json }}

По алфавиту
zone_ids: {{ expand(‘group.vacuum_zones’) | selectattr(‘state’, ‘eq’,‘on’) | map(attribute =‘name’) |list| to_ascii_json }}
image

Если у вас пылесос xiaomi с оригинальной прошивкой, то можно использовать эту интеграцию
VacuumZones

1 Like

Reviving this old thread since I really like this way of abstracting the room data from the script and it’s so well documented by @123 I’ve tried to apply it to my xiaomi_miio.vacuum_clean_zone script but am running into some problems.

I have defined the following customization for the room input_booleans:

input_boolean.vacuum_can_clean_catarea:
  cleaning_zone: 24150,24707,25221,26479"

input_boolean.vacuum_can_clean_bedroom1:
  cleaning_zone: 23950,25336,26264,23121

But when I try to build the zone data using

{{ expand('group.vacuum_zones') | selectattr('state', 'eq', 'on')
 | map(attribute='attributes.cleaning_zone') | list }}

I get data looking like this in the Developer Tools Template Tester:

[
  "23950,25336,26264,23121",
  "24150,24707,25221,26479"
]

I guess it should look more like:

 [[23950,25336,26264,23121], [24150,24707,25221,26479]]

What’s the ‘right’ way to pull an array of arrays into a service call?