Repository navigation
Releases: lukab-dev/ha-layers
Release list
0.4.0b1: thermostats (beta)
Beta. HACS shows it only if you turn on beta versions for Layers.
Thermostats
Layers now manages climate entities as well as lights and switches. A layer on a thermostat holds an hvac_mode, a temperature and/or a preset_mode; mode: adjust takes an offset in °C, and offsets add up.
action: layers.set
target: {entity_id: climate.example}
data: {layer: away, priority: 40, temperature: 16}- A change made at the thermostat or in its app becomes a
manuallayer (priority 80, 3 h by default, both in the options). It never overwrites the base, so the schedule comes back when it expires. - An expiring layer never switches heating on. A setpoint can move either way on expiry; a mode never goes from
offto anything else by itself. - Slow devices: a report inside the report-back window (30 s by default) counts as the thermostat answering, not as a person.
- Delivery is checked: mode and preset exactly, the setpoint within half the device's step. Three attempts, then the thermostat shows as failed on
sensor.layers_status. - Watch-only for thermostats: a new switch,
switch.layers_apply_climate, is off after install and whenever a new thermostat is enrolled. While it is off, nothing is sent to any thermostat;layers.getshowswould_sendand the decision trace records it. Lights keep followingswitch.layers_apply, and turning that off stops thermostats too.
Not supported yet: two-setpoint thermostats (heat/cool range), fan, swing and humidity. Open questions are in the ROADMAP.
Light and switch behaviour is unchanged.
0.3.0b1: layer strength (beta)
Beta. HACS shows it only if you turn on beta versions for Layers.
Layer strength: signals that survive a scene
A layer used as a notification (a light that turns orange when the bins go out) used to vanish the moment someone pressed a scene on the wall, before anyone had seen it. A layer now has a strength:
strength |
A scene, a wall button, "all off", another automation | Someone changing this light itself |
|---|---|---|
soft (default) |
the light's option decides, as before | the light's option decides, as before |
sticky |
goes underneath: the layer stays, and the light shows it again | removes the layer: they've seen it |
locked |
goes underneath | goes underneath too |
action: layers.set
target: {entity_id: light.sofa}
data: {layer: bins, priority: 70, xy_color: [0.6, 0.38], brightness: 255,
strength: sticky, until: "23:00:00"}What decides is what the change was aimed at, not who made it. A wall button reaches Home Assistant as an automation running a scene, so it can't be told apart from any other automation; a scene, a call to several lights or any automation is aimed at the room, while the light's own switch or dimmer, or tapping that one light in the app, is aimed at the light.
- Whatever went underneath becomes the base: clearing the layer shows the room as it is now. A scene that turns the room off leaves a sticky layer lit until it's cleared or expires.
- A sticky layer removed at the light stays off that light until its owner clears it, like any layer taken back.
layers_externalreports it (droppedwithscope: lamp). - A locked layer (for alarms) comes back about 2 s after any change. A light that keeps changing back is left alone after 5 re-shows a minute and shows as failed on
sensor.layers_status. The Apply switch still stops everything. layer: allandlayer: activenever remove a sticky or locked layer; only its own id does.
Also changed
layers_externalalways carriesscope(room/lamp) andheld, and also fires when a change only went under a strong layer.layers.getshows each layer'sstrength.
Upgrading
From 0.2.0: no change to stored data; every existing layer is soft and behaves exactly as before. Going back to 0.2.0 is safe (it ignores the new fields). Requires Home Assistant 2026.7.0 or newer; tested on 2026.7.0 and 2026.9.3.
Feedback and issues are welcome.
0.2.0: follow layers, scenes that skip a light
Stable release of what was in 0.2.0b1: follow layers and the fix for scenes that skip a light. No code changes since the beta, only documentation.
Follow layers
layers.set mode: follow, source: <entity> puts a layer on lights whose brightness and colour come from another entity's attributes, such as an Adaptive Lighting switch or a template sensor, and change when it does. Layers does no circadian maths itself.
action: layers.set
target: {entity_id: [light.sofa, light.reading]}
data: {layer: circadian, priority: 10, mode: follow,
source: switch.adaptive_lighting_living_room}- It stacks like any layer: give it a low priority and a TV dim or a nightlight sits above it.
- It never turns a light on or off. Lights that are off get nothing.
- Someone's change never removes it. Only what they changed stops following: dim a light by hand and its brightness stays while its colour keeps adapting. It follows again once the light is off, or after
manual_timeout. - A light switched on without a brightness or colour (a wall switch, voice, a button) gets the follow values straight away.
- If the source becomes unavailable (an integration reloading), lights keep the last values. If the source is switched off, they fall back to what is below.
- New in the docs since the beta: a light is only sent new values once they differ from what it shows by more than Layers' usual tolerances (100 K colour temperature, 5/255 brightness, 0.03 xy). With Adaptive Lighting's default 90 s interval, a light changes colour about every 10 minutes, in steps of about 100 K. That is intended: steps that size are hard to see, and it keeps commands down.
Scenes that skip a light
Home Assistant sends nothing to a scene member that already looks the way the scene wants, so Layers never heard about it. A layer that made the light match outlived the scene, and clearing it later undid the scene. Layers now treats such a member as set by the scene, if the light really shows what the scene wanted.
Upgrading
From 0.1.0 or 0.2.0b1: no change to stored data, upgrades in place. layers.get shows five new fields on each layer (source, manual, manual_until, manual_timeout, transition). Requires Home Assistant 2026.7.0 or newer; tested on 2026.7.0 and 2026.9.3.
Feedback and issues are welcome.
v0.2.0b1
Beta. Two changes, one install. HACS shows it only if you turn on beta versions for Layers.
Follow layers
layers.set mode: follow, source: <entity> puts a layer on lights whose brightness and colour come from another entity's attributes, such as an Adaptive Lighting switch or a template sensor, and change when it does. Layers does no circadian maths itself.
action: layers.set
target: {entity_id: [light.sofa, light.reading]}
data: {layer: circadian, priority: 10, mode: follow,
source: switch.adaptive_lighting_living_room}- It stacks like any layer: give it a low priority and a TV dim or a nightlight sits above it.
- It never turns a light on or off. Lights that are off get nothing.
- Someone's change never removes it. Only what they changed stops following: dim a light by hand and its brightness stays while its colour keeps adapting. It follows again once the light is off, or after
manual_timeout. - A light switched on without a brightness or colour (a wall switch, voice, a button) gets the follow values straight away.
- If the source becomes unavailable (an integration reloading), lights keep the last values. If the source is switched off, they fall back to what is below.
Scenes that skip a light
Home Assistant sends nothing to a scene member that already looks the way the scene wants, so Layers never heard about it. A layer that made the light match outlived the scene, and clearing it later undid the scene. Layers now treats such a member as set by the scene, if the light really shows what the scene wanted.
Upgrading
No change to stored data: a 0.1.0 install upgrades in place, and layers.get shows five new fields on each layer (source, manual, manual_until, manual_timeout, transition). Requires Home Assistant 2026.7.0 or newer.
Feedback and issues are welcome.
v0.1.0
First public release.
Priority layers for Home Assistant lights: an automation borrows a lamp by putting a layer on it and gives it back by clearing the layer. The lamp then shows whatever is below that layer now, not a snapshot. See the README.
layers.set,layers.clear,layers.sync,layers.get- Per-lamp policies for changes made by people and other automations:
take_back(default),edit_active,base_keep_layers,reassert - Layers survive restarts; leases (
ttl/until) may only turn lamps off or dim them when they lapse - Commands are read back, retried, and owed to lamps that are offline
- Switches (
switch.*) can be enrolled as on/off lamps - A blueprint that dims a room while a media player plays
Requires Home Assistant 2026.7.0 or newer. It starts in observe-only mode (Apply off): watch the diagnostics for a few days, then turn it on.
This is an early release, running daily in one house. Feedback and issues are welcome.