Repeat relative dimming steps

This commit is contained in:
2026-02-15 21:06:22 +01:00
parent c8d05acae9
commit a9fb58c87a
5 changed files with 38 additions and 10 deletions

View File

@@ -1,6 +1,7 @@
from __future__ import annotations
from dataclasses import dataclass
import asyncio
import logging
from typing import Any
@@ -181,6 +182,7 @@ class BridgeManager:
self._registered_addresses: list[tuple[str, str | None]] = []
self._address_options: dict[str, AddressOptions] = {}
self._light_components: dict[str, dict[str, int]] = {}
self._light_dimming_tasks: dict[str, asyncio.Task] = {}
async def async_setup(self) -> None:
if not self.hass.services.has_service(KNX_DOMAIN, "send"):
@@ -199,6 +201,10 @@ class BridgeManager:
self._knx_event_unsub()
self._knx_event_unsub = None
for task in self._light_dimming_tasks.values():
task.cancel()
self._light_dimming_tasks.clear()
await self._unregister_knx_events()
def _load_ports(
@@ -1155,6 +1161,7 @@ class BridgeManager:
if value is None:
return
if value in (0, 8):
self._stop_light_dimming(port.entity_id)
return
step = _relative_dimming_step(value)
if step is None:
@@ -1162,13 +1169,7 @@ class BridgeManager:
direction, percent = step
if percent <= 0:
return
if direction == "down":
percent = -percent
await self._call_light_service(
port.entity_id,
"turn_on",
{"brightness_step_pct": percent},
)
self._start_light_dimming(port.entity_id, direction, percent)
return
if action.startswith("red_"):
@@ -1399,6 +1400,28 @@ class BridgeManager:
},
)
def _start_light_dimming(
self, entity_id: str, direction: str, percent: int
) -> None:
self._stop_light_dimming(entity_id)
async def _runner() -> None:
while True:
step = percent if direction == "up" else -percent
await self._call_light_service(
entity_id, "turn_on", {"brightness_step_pct": step}
)
await asyncio.sleep(0.3)
self._light_dimming_tasks[entity_id] = self.hass.async_create_task(
_runner()
)
def _stop_light_dimming(self, entity_id: str) -> None:
task = self._light_dimming_tasks.pop(entity_id, None)
if task is not None:
task.cancel()
def _extract_event_value(event: Event) -> int | None:
if "value" in event.data: