Xiaomi Vacuum - error on vacuum_clean_segment: expected int for dictionary value @ data['segments']

I am trying to customize a Xiaomi vacuum card in order to have multi-zones selections. I added a “switch” button for every room (based on a input_select - see below) but I’m getting this error when executing xiaomi_miio.vacuum_clean_segment: “expected int for dictionary value @ data[‘segments’]”.
My configuration.yaml:

sensor:
  - platform: template
    sensors:
      vacuum_zones:
        friendly_name: "Zones"
        value_template: >
          {% if not is_state('input_select.vacuum_living', 'Off') %} {{ states('input_select.vacuum_living') + ',' }} {% endif %}
          {% if not is_state('input_select.vacuum_bedroom', 'Off') %} {{ states('input_select.vacuum_bedroom') + ',' }} {% endif %}
          {% if not is_state('input_select.vacuum_bathroom', 'Off') %} {{ states('input_select.vacuum_bathroom') + ',' }} {% endif %}
          {% if not is_state('input_select.vacuum_hallway', 'Off') %} {{ states('input_select.vacuum_hallway') + ',' }} {% endif %}
          {% if not is_state('input_select.vacuum_kitchen', 'Off') %} {{ states('input_select.vacuum_kitchen') + ',' }} {% endif %}

input_select:
  vacuum_living:
    name: Living
    initial: "Off"
    icon: mdi:sofa
    options:
      - 3
      - "Off"
  vacuum_bedroom:
    name: Bedroom
    initial: "Off"
    icon: mdi:bed
    options:
      - 1
      - "Off"
  vacuum_bathroom:
    name: Bathroom
    initial: "Off"
    icon: mdi:shower
    options:
      - 2
      - "Off"
  vacuum_hallway:
    name: Hallway
    initial: "Off"
    icon: mdi:road
    options:
      - 17
      - "Off"
  vacuum_kitchen:
    name: Kitchen
    initial: "Off"
    icon: mdi:silverware-fork-knife
    options:
      - 16
      - "Off"

My lovelace template:

  type: custom:button-card
  template: button_small
  aspect_ratio: 3/1.3
  name: Zones
  icon: mdi:play
  entity: vacuum.robo
  styles:
    icon:
      - color: >
          [[[ return entity.state == 'cleaning' ? 'var(--paper-item-icon-active-color)' : 'var(--paper-item-icon-color)' ]]]
  tap_action:
    action: call-service
    service: xiaomi_miio.vacuum_clean_segment
    service_data:
      entity_id: entity
      segments: >
        [[[ return ("[" + states["sensor.vacuum_zones"].state + "]").replace(",]", "]") ]]]

If I replace the value of segments with something like [1,3] is all ok and working.
Also, sensor.vacuum_zones works ok and returns its value in the exact format as above (eg: [1,3] ).
This is the card

image

Anyone? :thinking: I still don’t have a solution for that…

Your template is attempting to create a list by combining strings. The result may look like a list but it’s actually a string.

This doesn’t produce a true list:

"[" + "1, 2, 3" + "]"

I suggest you create a script that, when called, executes xiaomi_miio.vacuum_clean_segment and computes a proper list based on the input_selects. The button’s tap_action only needs to call this script (and doesn’t need to try to build a list).


As an experiment, copy-paste this into the Template Editor and let me know if it reports a list containing only the numbers of the rooms to be vacuumed. Are the room numbers listed in the order you expect (living, bedroom, bathroom, hallway, kitchen)?

{{ expand('input_select.vacuum_living',
          'input_select.vacuum_bedroom',
          'input_select.vacuum_bathroom',
          'input_select.vacuum_hallway',
          'input_select.vacuum_kitchen')
    | rejectattr('state', 'eq', 'Off')
    | map(attribute='state')
    | map('int') | list }}

If it produces a list with the room numbers in the desired order (I think it will) you can try using it in the script (for segments).

1 Like

Thanks a lot for your response! I wasn’t aware of the fact the list is actually a string…

I tried your code in Template Editor and is working as it should. So I changed the vacuum_zones sensor’s code with yours

  - sensor:
      - name: "Vacuum Zones"
        state: >
          {{ expand('input_select.vacuum_living',
          'input_select.vacuum_bedroom',
          'input_select.vacuum_bathroom',
          'input_select.vacuum_hallway',
          'input_select.vacuum_kitchen')
          | rejectattr('state', 'eq', 'Off')
          | map(attribute='state')
          | map('int') | list }}

and replaced the service_data from lovelace with

  tap_action:
    action: call-service
    service: xiaomi_miio.vacuum_clean_segment
    service_data:
      entity_id: entity
      segments: >
        [[[ states["sensor.vacuum_zones"].state ]]]

But it didn’t work, I get the same error as before :frowning:
Any idea why is not working?
As far as I can see, it should: the sensor has the proper list (int) and the service is using it directly, without building it.

Yes because you chose to do something other than what I suggested and the tap_action continues to create a string.

Do this:

I made the changes, as you suggested, and it works like a charm! :slight_smile:
Thanks a lot for your help!

1 Like