Automation - Repeat until + condition AND

I have made the following repeat actions in my automation, where I wanted to do a repeat loop until two conditions are met:

- alias: AUTO - light1
  description: ''
  mode: restart
  trigger:
  - platform: state
    to: 'on'
    entity_id:
    - binary_sensor.door
    - binary_sensor.pir
  condition: []
  action:
  - alias: repeat until 2 conditions
    repeat:
      sequence:
        - service: switch.turn_on
          entity_id: switch.light1
        - delay: 00:00:15
      until:
        - condition: 
            condition: and
            conditions:
              - condition: state
                entity_id: binary_sensor.pir
                state: 'off'
              - condition: state
                entity_id: binary_sensor.door
                state: 'off'
  - service: switch.turn_off
    entity_id: switch.light1

When I reload Automations all is OK and I get message that Automations reloaded
Unfortunately when I do Restart HASS I get the following errors:
Error2:

Logger: homeassistant.components.hassio
Source: components/hassio/__init__.py:420
Integration: Home Assistant Supervisor (documentation, issues)
First occurred: 22:41:36 (1 occurrences)
Last logged: 22:41:36

Unexpected error calling config validator: unhashable type: 'collections.OrderedDict'

Error1:

Logger: homeassistant.helpers.check_config
Source: helpers/config_validation.py:790
First occurred: 22:41:36 (1 occurrences)
Last logged: 22:41:36

Unexpected error validating config
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/check_config.py", line 145, in async_check_ha_config_file
    await config_validator.async_validate_config(  # type: ignore
  File "/usr/src/homeassistant/homeassistant/components/automation/config.py", line 102, in async_validate_config
    await asyncio.gather(
  File "/usr/src/homeassistant/homeassistant/components/automation/config.py", line 84, in _try_async_validate_config_item
    config = await async_validate_config_item(hass, config, full_config)
  File "/usr/src/homeassistant/homeassistant/components/automation/config.py", line 60, in async_validate_config_item
    config = PLATFORM_SCHEMA(config)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 218, in __call__
    return self._exec((Schema(val) for val in self.validators), v)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 337, in _exec
    v = func(v)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 272, in __call__
    return self._compiled([], data)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 817, in validate_callable
    return schema(data)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 272, in __call__
    return self._compiled([], data)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 594, in validate_dict
    return base_validate(path, iteritems(data), out)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 386, in validate_mapping
    cval = cvalue(key_path, value)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 215, in _run
    return self._exec(self._compiled, value, path)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 339, in _exec
    v = func(path, v)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 635, in validate_sequence
    cval = validate(index_path, value)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 817, in validate_callable
    return schema(data)
  File "/usr/src/homeassistant/homeassistant/helpers/config_validation.py", line 888, in script_action
    return ACTION_TYPE_SCHEMAS[determine_script_action(value)](value)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 272, in __call__
    return self._compiled([], data)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 594, in validate_dict
    return base_validate(path, iteritems(data), out)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 386, in validate_mapping
    cval = cvalue(key_path, value)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 215, in _run
    return self._exec(self._compiled, value, path)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 339, in _exec
    v = func(path, v)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 594, in validate_dict
    return base_validate(path, iteritems(data), out)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 386, in validate_mapping
    cval = cvalue(key_path, value)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 215, in _run
    return self._exec(self._compiled, value, path)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 339, in _exec
    v = func(path, v)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 635, in validate_sequence
    cval = validate(index_path, value)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 817, in validate_callable
    return schema(data)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 272, in __call__
    return self._compiled([], data)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 215, in _run
    return self._exec(self._compiled, value, path)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/validators.py", line 260, in _exec
    return func(path, v)
  File "/usr/local/lib/python3.8/site-packages/voluptuous/schema_builder.py", line 817, in validate_callable
    return schema(data)
  File "/usr/src/homeassistant/homeassistant/helpers/config_validation.py", line 790, in key_value_validator
    if key_value not in value_schemas:
TypeError: unhashable type: 'collections.OrderedDict'

When I remove AND condition and my automation look like this:

- alias: AUTO - light1
  description: ''
  mode: restart
  trigger:
  - platform: state
    to: 'on'
    entity_id:
    - binary_sensor.door
    - binary_sensor.pir
  condition: []
  action:
  - alias: repeat until 2 conditions
    repeat:
      sequence:
        - service: switch.turn_on
          entity_id: switch.light1
        - delay: 00:00:15
      until:
        - condition: state
          entity_id: binary_sensor.pir
          state: 'off'
  - service: switch.turn_off
    entity_id: switch.light1

there is no issue during restarting HASS (also during reloading Automation).

Either I am doing something wrong in automation or there is a bug compiling AND condition in “Repeat until” section in automation.
Any comment, help, insight - will be appreciated.

Try it like this (the logical AND of the two conditions is implicit):

- alias: AUTO - light1
  description: ''
  mode: restart
  trigger:
  - platform: state
    to: 'on'
    entity_id:
    - binary_sensor.door
    - binary_sensor.pir
  condition: []
  action:
  - alias: repeat until 2 conditions
    repeat:
      sequence:
        - service: switch.turn_on
          entity_id: switch.light1
        - delay: 00:00:15
      until:
        - condition: state
          entity_id: binary_sensor.pir
          state: 'off'
        - condition: state
          entity_id: binary_sensor.door
          state: 'off'
  - service: switch.turn_off
    entity_id: switch.light1

BTW, are you sure you want mode: restart?

1 Like

Or just uncomplicate your life…

- alias: AUTO - light1
  trigger:
    - platform: state
      entity_id: &sensors
        - binary_sensor.door
        - binary_sensor.pir
      to: 'on' 
    - platform: state
      entity_id: *sensors
      to: 'off'
      for:
        seconds: 15
  action:
    service: "switch.turn_{{ trigger.to_state.state }}"
    entity_id: switch.light1

Thanks! This works! No errors during reloading automation and HASS.
I did not know that in “repeat - until” loop all conditions must be met to stop the loop. Was thinking that it is similar to trigger… :frowning:

I used mode: restart in order to prevent several triggers of this automation (there are warnings in the logs) while I am in the room (PIR sensor).

Wow! This is pro level… I like simple solutions!
So let me understand this better. &sensors is kind o variable defined on the fly which contains all the sensors below and the *sensors is the usage of this variable ?
Or this is kind of format to be used (exactly must be “&sensors”) ?
I like this simple line: service: "switch.turn_{{ trigger.to_state.state }}" !

I did test it and it works, however it also switch the light off while I am in the room and the door is closed for 15 seconds even if in the meantime PIR has sensed my presence. I think I have similar logic “conflict” in previous versions and that is why I worked on it.
The unwanted case is that I open the door (the light goes ON), go in and PIR sensor sense my presence (again automation turns the light ON - no change as they are ON already). I close the door and since that moment 15 seconds count starts and regardless my presence in the room and subsequent PIR sensor activation after those 15 seconds the lights will be turned off. And the previous automation with added condition like this:

until:
        - condition: state
          entity_id: binary_sensor.pir
          state: 'off'
          for: 00:00:15
        - condition: state
          entity_id: binary_sensor.door
          state: 'off'

prevents this.
Thank you !

1 Like
  • For multiple conditions, they are understood to be logical AND by default.
  • For multiple triggers, they are understood to be logical OR by default.

For reference, here is an excerpt from the documentation:

Unlike a trigger, which is always or, conditions are and by default - all conditions have to be true.

1 Like