Skip to main content
Selora Homes Selora Homes
Recipe · v1.0.0 · Released Aug 28, 2026

Presence Room Lighting

Installs a Home Assistant automation that keeps a room's lights on for as long as an mmWave presence sensor sees someone in it, and switches them off shortly after the room empties. Add a light sensor to run only after dark, and dimmable lights that come up softly.

A motion sensor sees movement and then forgets you the moment you sit still, which is why motion lighting drops the lights on someone reading on the sofa. This recipe uses an mmWave presence sensor instead. It reports the room occupied for as long as anyone is in it, so the lights stay on through a still evening and go off shortly after the last person leaves.

The clear delay is a short grace period after the room reads empty, set in seconds. A few seconds smooths over the brief gaps a sensor can report as someone crosses the room, without leaving the lights on for long once the room is genuinely empty. Everything runs on your own sensor and lights, with no cloud in the loop.

Only after dark

A well-lit room in the afternoon does not need the lights. Pick a light sensor as the optional illuminance role and the lights only come on while the room is below the darkness level you set. Leave the sensor out and the lights follow presence at any hour.

A softer light at night

Add dimmable lights as the optional dimmer role and they come up at the accent brightness you set rather than at full, so walking into a room late does not mean the lights at their brightest.

Files Selora AI's pipeline reads to install this recipe. The manifest declares roles, inputs, and integrations; the package files are Jinja-templated YAML applied to Home Assistant.

# Presence Room Lighting — hold a room's lights on while an mmWave presence
# sensor sees anyone, and switch them off shortly after the room empties.
#
# One required presence role (multi-select, several sensors can cover a room)
# and one required light role. Optional illuminance gates the lights to
# darkness; optional dimmable lights come up at a softer accent brightness.
slug: presence-room-lighting
version: 1.0.0
title: Presence Room Lighting
tagline: The lights stay on while anyone is in the room and go off shortly after it empties.
description: >-
  Keeps the lights on for as long as an mmWave presence sensor sees someone in
  the room, including someone sitting still, and switches them off after a
  short grace period once the room is empty. Add a light sensor to run only
  after dark and dimmable lights that come up softly.
author: Selora AI
released: "2026-08-28"
min_integration_version: "0.12.0"
tags: [lighting, presence, mmwave, occupancy]
roles:
  # Presence sensors — multi-select so several mmWave sensors can cover one
  # room. binary_sensor + device_class occupancy is how they register.
  # min_count 1: with no sensor there is nothing to follow.
  - id: presence_sensors
    title: Presence sensors
    kind: binary_sensor
    device_class: occupancy
    min_count: 1
    selection: required
    description: >-
      The mmWave presence sensors covering the room. Any one seeing presence
      keeps the lights on.
  # Lights — multi-select. min_count 1: the recipe needs a light to control.
  - id: lights
    title: Room lights
    kind: light
    min_count: 1
    selection: required
    description: >-
      The light or lights the recipe switches with presence.
  # Optional illuminance sensor to gate the lights to darkness. max_count 1.
  - id: illuminance
    title: Light level sensor
    kind: sensor
    device_class: illuminance
    min_count: 0
    max_count: 1
    selection: required
    description: >-
      Optional. A light sensor so the lights only come on while the room is
      dark. Leave empty to follow presence at any hour.
  # Optional dimmable accent lights brought up at a softer brightness.
  - id: dimmers
    title: Dimmable accent lights
    kind: light
    min_count: 0
    selection: required
    description: >-
      Optional. Dimmable lights the recipe brings up at the accent brightness
      instead of full. Leave empty to skip.
inputs:
  # Grace period, in seconds, after the room reads empty before the lights go
  # off. A few seconds smooths over brief detection gaps without leaving the
  # lights on once the room is genuinely empty.
  - id: clear_seconds
    type: number
    label: Clear delay (seconds)
    description: >-
      How long the room must read empty before the lights turn off.
    default: 30
    min: 0
    max: 3600
  # Darkness threshold in lux, used only when an illuminance sensor is picked.
  - id: dark_lux
    type: number
    label: Darkness threshold (lux)
    description: >-
      With a light sensor picked, the lights only come on below this reading.
    default: 40
    min: 1
    max: 1000
  # Brightness percent for the optional dimmable accent lights.
  - id: dim_brightness
    type: number
    label: Accent brightness (percent)
    description: >-
      Brightness the optional dimmable lights come up at.
    default: 40
    min: 1
    max: 100
package_files:
  - package/automations/presence.yaml.j2
{# Presence Room Lighting: one automation to switch the lights on when the
   room becomes occupied, one to switch them off after it has been empty for
   the clear delay.

   The on automation fires on any presence sensor going on, optionally gated to
   a dark illuminance reading. The off automation waits for every presence
   sensor to have read empty for the clear delay, then confirms all are clear
   before switching off, so one sensor still seeing someone keeps the lights
   on. Optional dimmable lights come up at the accent brightness. #}
automation:
  - id: selora_recipe_{{ slug | replace('-', '_') }}_on
    alias: "Presence Room Lighting: on"
    description: >-
      When any presence sensor reports the room occupied, switch the lights on,
      optionally only while the room is dark.
    mode: restart
    trigger:
{% for sensor in roles.presence_sensors %}
      - platform: state
        entity_id: {{ sensor }}
        to: "on"
{% endfor %}
{% if roles.illuminance %}
    condition:
      - condition: numeric_state
        entity_id: {{ roles.illuminance[0] }}
        below: {{ inputs.dark_lux }}
{% endif %}
    action:
      - service: light.turn_on
        target:
          entity_id:
{% for light in roles.lights %}
            - {{ light }}
{% endfor %}
{% if roles.dimmers %}
      - service: light.turn_on
        target:
          entity_id:
{% for dimmer in roles.dimmers %}
            - {{ dimmer }}
{% endfor %}
        data:
          brightness_pct: {{ inputs.dim_brightness }}
{% endif %}
  - id: selora_recipe_{{ slug | replace('-', '_') }}_off
    alias: "Presence Room Lighting: off"
    description: >-
      Once every presence sensor has read the room empty for the clear delay,
      switch the lights off.
    mode: restart
    trigger:
{% for sensor in roles.presence_sensors %}
      - platform: state
        entity_id: {{ sensor }}
        to: "off"
        for:
          seconds: {{ inputs.clear_seconds }}
{% endfor %}
    condition:
      # for: applies to every entity in the list, so all of them must have read
      # empty for the full clear delay. Without it the trigger firing for one
      # sensor was enough and the rest only had to be off at that moment, which
      # cut the delay short whenever a room had more than one sensor.
      - condition: state
        state: "off"
        for:
          seconds: {{ inputs.clear_seconds }}
        entity_id:
{% for sensor in roles.presence_sensors %}
          - {{ sensor }}
{% endfor %}
    action:
      - service: light.turn_off
        target:
          entity_id:
{% for light in roles.lights %}
            - {{ light }}
{% endfor %}
{% for dimmer in roles.dimmers %}
            - {{ dimmer }}
{% endfor %}

Type to search across

↑↓ navigate ↵ open
⌘K search