Motion-triggered automation doesn't reliably restart timer

Hi all,

I have a bedroom lighting automation that turns on lights when motion is detected and turns them off after a timer expires. The problem is that subsequent motion doesn’t reliably restart the timer - sometimes it works, sometimes it doesn’t, even though the automation trace shows the correct branch was executed.

The strange part: When I test this manually in Developer Tools (calling timer.start on a running timer), it always restarts correctly. But in real-world usage, the timer often doesn’t restart.

Setup

  • Home Assistant version: 2025.12.3
  • PIR sensors: 2x Philips Hue Motion Sensors connected via Zigbee2MQTT
  • PIR settings: Occupancy timeout = 5 seconds, Motion sensitivity = max
  • Binary sensor group: binary_sensor.bedroom_pirs (Group helper with “All entities” = OFF, so it triggers when ANY sensor detects motion)
  • Timer: timer.bedroom_light with 60 second duration (morning is 5 mins)

Automation Logic

The automation should:

  1. When motion detected + lights are off + media not playing → turn on lights + start 60s timer
  2. When motion detected again (while lights are on) → restart timer
  3. When timer finishes → turn off lights

Current Behavior

  1. :white_check_mark: First motion → lights turn on, timer starts (60s)
  2. :x: Subsequent motion → sometimes restarts timer, sometimes doesn’t
  3. Timer expires → lights turn off (even though I’m still in the room, andi can see sensor see me)

It worked before! after some upgrade it stopped and i am not able to find out why and what is the cause.

What I’ve Checked

  • Entity states: All conditions appear to be met (other lights off, media off, darkness on)
  • PIR behavior: Logbook shows the PIRs are detecting motion (off→on and on→off transitions)
  • Timer behavior: Works correctly when tested manually in Developer Tools using actions
  • Automation mode: single (also tried restart with same results)

Here is a part of automation code. (there are more lights at the room code is not complete. Important part is mentioned here (motion and timer finish)

alias: Bedroom Light
description: ''
triggers:
  - alias: Motion Detected
    trigger: state
    entity_id:
      - binary_sensor.bedroom_pirs
    from: 'off'
    to: 'on'
    id: motion
  - alias: Lamps
    trigger: state
    entity_id:
      - light.bedroom_lamps
    to:
    id: lamps
  - trigger: state
    entity_id:
      - light.bedroom_dimmer_ceiling
    to:
    id: ceiling
    alias: Ceiling Light
  - alias: Kodi-Bedroom
    trigger: state
    entity_id:
      - media_player.kodi_bedroom
    to:
    id: kodi
  - trigger: state
    entity_id:
      - media_player.lg_webos_tv_bedroom
    to:
    id: lgtv
    alias: LGTV
  - trigger: event
    event_type: timer.finished
    event_data:
      entity_id: timer.bedroom_light
    id: timer.finished
    alias: Timer
conditions:
  - condition: or
    conditions:
      - condition: state
        entity_id: binary_sensor.smart_darkness
        state: 'on'
      - condition: state
        entity_id: input_boolean.automatic_lights
        state: 'on'
      - condition: trigger
        id:
          - timer.finished
actions:
  - choose:
      - conditions:
          - condition: and
            conditions:
              - condition: trigger
                id:
                  - motion
              - condition: state
                entity_id: light.bedroom_dimmer_ceiling
                state: 'off'
              - condition: state
                entity_id: light.bedroom_lamps
                state: 'off'
              - condition: state
                entity_id: sensor.media_status_bedroom
                state:
                  - 'off'
        sequence:
          - action: timer.cancel
            target:
              entity_id: timer.bedroom_light
          - if:
              - condition: state
                entity_id: sensor.time_of_day
                state: morning
            then:
              - action: timer.start
                target:
                  entity_id: timer.bedroom_light
                data:
                  duration: '00:05:00'
            else:
              - action: timer.start
                target:
                  entity_id: timer.bedroom_light
                data:
                  duration: '00:00:60'
          - action: scene.turn_on
            target:
              entity_id: scene.bedroom_motion
        alias: Motion
      # ... other branches for lamps, ceiling, kodi, etc.
      - conditions:
          - condition: trigger
            id:
              - timer.finished
          - condition: or
            conditions:
              - condition: state
                entity_id: media_player.lg_webos_tv_bedroom
                state: 'off'
              - condition: state
                entity_id: media_player.lg_webos_tv_bedroom
                state:
                  - unavailable
        sequence:
          - type: turn_off
            device_id: 4748e927444d894569caf861b2e50b1e
            entity_id: ca5472cdc9d904cf1e05d527e5aeea3f
            domain: light
        alias: Time Finished
mode: single

Current work i am trying to make is reliable and more simple using sensor for media. LGTV, KODI sometimes return unexpected state (unavailable).

Helper Sensor for Media Status

- name: "Media Status Bedroom"
  unique_id: "media_status_bedroom"
  state: |
    {% if is_state('media_player.kodi_bedroom', 'playing') %}
      playing
    {% elif is_state('media_player.kodi_bedroom', 'paused') %}
      paused
    {% elif is_state('media_player.lg_webos_tv_bedroom', 'on') %}
      on
    {% else %}
      off
    {% endif %}

Binary Sensor Group

Created via UI Helper:

  • Type: Binary sensor group
  • Members: binary_sensor.bedroom_pir_bed_1_occupancy, binary_sensor.bedroom_pir_bed_2_occupancy
  • “All entities” option: OFF (triggers when ANY member is on)

Questions

  1. Could the Binary Sensor Group helper be causing timing issues with the state transitions?
  2. Is there a known issue with Philips Hue PIRs via Zigbee2MQTT and occupancy detection?
  3. Should I use a different approach for motion detection (e.g., template sensor instead of group)?
  4. Any ideas why timer.start would work in Developer Tools but not reliably in automation?

What I’ve Already Tried

  • Changed occupancy timeout from 0 to 5 seconds
  • Verified all condition entities have correct states
  • Checked automation traces
  • Tested timer.start manually (works fine)

Any help would be appreciated!

Correct. It doesn’t. I don’t see a restart command here anywhere.

Also I think your LLM messed up the formatting a bit on

Would you be so kind as to adjusting the format of your code so that we can read it properly & check the YAML spacing, etc. Editing your original is the preferred way. It is very hard for us to tell what is what when the text formatter jumbles everything like that.
You can use the </> button like this… How to format your code in forum posts
OR… Here is an example of how to fix formatting from the site FAQ Page.
How to help us help you - or How to ask a good question.

Hi @Sir_Goodenough,

thank you for reply. I dont understand you. There is no command restart.

I had in my configuration Timer.Cancel and Timer.Start it worked. Then i tryed to use only Timer.Start and it works as well. Tested in dev tools.

My problem is that it works “sometimes”.

  1. enter room → timer starts 60 → lights on
  2. motion in room → timer (re)starts 60s - lights still on
  3. motion in room → timer not restarted (still counting down)
  4. motion in room → timer timer finishes - lights off

How it should be then configured?

And when it goes to the else, it tries to start it when running and is probably confusing you.
Perhaps use the command to add time instead? Not sure, I don’t use the timer very often.

I think you might be better off using a while loop, something like this -

repeat:
  while:
    - condition: template
      value_template: >-
        {% set occupancy_seconds = (now() -
        states.binary_sensor.bedroom_pirs.last_changed | as_datetime).seconds %}

        {% if states('binary_sensor.bedroom_pirs') == 'off'  and
        occupancy_seconds > 60 %}
        true
        {% else %}
        false
        {% endif %}
  sequence:
    - delay:
        hours: 0
        minutes: 1
        seconds: 0
        milliseconds: 0

Then the following action could be to turn the lights off.

I’m not sure timers are really designed to be used in the way you’ve implemented them.

The way this works means that the automation will be running for as long as the while loop is satisfied, this means that if home assistant is restarted whilst the automation is running then it will stop working until it is re-triggered.

I have a similar automation that works to turn on/off my lights using various triggers and IDs, you might want to consider changing it to a similar set up?

A screenshot of the triggers I have, it then goes to a choose block in the actions.

I can share the YAML if it’s helpful!

Fundamental flaw in your logic. Typical PIR fires when the motion is detected, then stays on as long as something is still moving in sight of view, then goes off after cool down period.
So If you continue moving it will not restart timer, but let it count down. If you stop moving and start again after PIR cool down period and before timer it will restart timer.
Simpler option is to start timer after PIR goes off and eventually make it short (20s?) and stop it when PIR goes on. This way light will stay on as long as you move and up to 20s after cool down of PIR. If during this time another move is detected timer will be stopped and will start again after PIR goes down.

1 Like

Hi @mp583 Yes i was thinking about this as well. this will be probably solution to rework automation to get it work again.

@mirekmal - I tested it very well. sensors were configured with 0 - 5 seconds Occupancy timeout. I was able to see multiple on/off states switches during the tests. So it should cause the restart. It was working very well till some update.

I agree that this is a reliable way to control lights and it can even survive reboots.

Each light here has it own timer helper with a default time

When a automation is triggered by movement the timer is started. If the timer was already running it wil be restarted. Nothing else.
Turning the light off is don in a other automation that triggers on timer.finished

alias: Motion Keuken plankje
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.keuken_plankje_beweging
    to: "on"
conditions: []
actions:
  - action: light.turn_on
    metadata: {}
    data: {}
    target:
      entity_id: light.keuken_plankje_plankje_verlichting
  - action: timer.start
    metadata: {}
    data: {}
    target:
      entity_id: timer.licht_keuken_plankje_timer
mode: single

1 Like

What does the trace show?

ETA: .restart is not required. .start will start or restart the timer.

The timer starts when light.bedroom_lamps has the status ‘off’, and when is the timer restarted/reset while the light is on?

My proposed solution:

alias: Bedroom Light
description: ''
triggers:
  - alias: Motion Detected
    trigger: state
    entity_id:
      - binary_sensor.bedroom_pirs
    from: 'off'
    to: 'on'
    id: id_motion
  - alias: Lamps
    trigger: state
    entity_id:
      - light.bedroom_lamps
    to:
    id: id_lamps
  - trigger: state
    entity_id:
      - light.bedroom_dimmer_ceiling
    to:
    id: id_ceiling
    alias: Ceiling Light
  - alias: Kodi-Bedroom
    trigger: state
    entity_id:
      - media_player.kodi_bedroom
    to:
    id: id_kodi
  - trigger: state
    entity_id:
      - media_player.lg_webos_tv_bedroom
    to:
    id: id_lgtv
    alias: LGTV
  - trigger: event
    event_type: timer.finished
    event_data:
      entity_id: timer.bedroom_light
    id: id_timer.finished
    alias: Timer
  - trigger: event
    event_type: timer.cancelled
    event_data:
      entity_id: timer.bedroom_light
    id: id_timer.finished
conditions:
  - condition: or
    conditions:
      - condition: state
        entity_id: binary_sensor.smart_darkness
        state: 'on'
      - condition: state
        entity_id: input_boolean.automatic_lights
        state: 'on'
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - id_motion
        sequence:
          - if:
              - condition: state
                entity_id: sensor.time_of_day
                state: morning
            then:
              - action: timer.start
                target:
                  entity_id: timer.bedroom_light
                data:
                  duration: '00:05:00'
            else:
              - action: timer.start
                target:
                  entity_id: timer.bedroom_light
                data:
                  duration: '00:00:60'
          - if:
              - condition: and
                conditions:
                  - condition: state
                    entity_id: light.bedroom_dimmer_ceiling
                    state: "off"
                  - condition: state
                    entity_id: light.bedroom_lamps
                    state: "off"
                  - condition: state
                    entity_id: sensor.media_status_bedroom
                    state: "off"
            then:
              - action: scene.turn_on
                target:
                  entity_id: scene.bedroom_motion
        alias: Motion
        # ... other branches for lamps, ceiling, kodi, etc.

      - conditions:
          - condition: trigger
            id:
              - id_timer.finished
        sequence:
         - if:
              - condition: or
                conditions:
                  - condition: state
                    entity_id: media_player.lg_webos_tv_bedroom
                    state: 'off'
                  - condition: state
                    entity_id: media_player.lg_webos_tv_bedroom
                    state:
                      - unavailable
            then:
              - type: turn_off
                device_id: 4748e927444d894569caf861b2e50b1e
                entity_id: ca5472cdc9d904cf1e05d527e5aeea3f
                domain: light
        alias: Time Finished

mode: single