mirror of
https://github.com/bahmcloud/HA-KNX-Bridge.git
synced 2026-04-06 12:11:14 +00:00
Fix HA 2026.03 light color temp compatibility and bump 0.0.34
This commit is contained in:
9
.idea/PROJECT_STATE.md
generated
9
.idea/PROJECT_STATE.md
generated
@@ -10,7 +10,7 @@ The integration should:
|
|||||||
- Auto-select appropriate KNX DPTs and request only the group addresses needed.
|
- Auto-select appropriate KNX DPTs and request only the group addresses needed.
|
||||||
- Ignore missing/empty group addresses without errors.
|
- Ignore missing/empty group addresses without errors.
|
||||||
|
|
||||||
Target compatibility: Home Assistant 2025.12 with forward compatibility to 2026.2.
|
Target compatibility: Home Assistant 2025.12 with forward compatibility to 2026.03.
|
||||||
|
|
||||||
Project rules:
|
Project rules:
|
||||||
- Keep `README.md` updated for user-relevant changes after each new version.
|
- Keep `README.md` updated for user-relevant changes after each new version.
|
||||||
@@ -18,7 +18,7 @@ Project rules:
|
|||||||
- Releases are created only when explicitly requested.
|
- Releases are created only when explicitly requested.
|
||||||
- Version number must match everywhere it is referenced (manifest, changelog, README, HACS if used).
|
- Version number must match everywhere it is referenced (manifest, changelog, README, HACS if used).
|
||||||
|
|
||||||
## Current State (as of 2026-02-15)
|
## Current State (as of 2026-03-09)
|
||||||
Completed:
|
Completed:
|
||||||
- Repo initialized with `main` branch and pushed to GitHub.
|
- Repo initialized with `main` branch and pushed to GitHub.
|
||||||
- HACS metadata (`hacs.json`) and base integration scaffold created.
|
- HACS metadata (`hacs.json`) and base integration scaffold created.
|
||||||
@@ -48,8 +48,9 @@ Completed:
|
|||||||
- Relative color temperature control wired into light schema, UI order adjusted, and KNX color temperature types aligned.
|
- Relative color temperature control wired into light schema, UI order adjusted, and KNX color temperature types aligned.
|
||||||
- Color temperature service calls now use mireds for better compatibility.
|
- Color temperature service calls now use mireds for better compatibility.
|
||||||
- Relative dimming/color temperature decoding improved for control/stepcode payloads.
|
- Relative dimming/color temperature decoding improved for control/stepcode payloads.
|
||||||
- Relative dimming/CT now treat step_code 0 as a start/stop toggle and rely on raw payload parsing.
|
- Relative dimming/CT now parse control strings from DPT 3.007 payloads and treat raw step values as percent steps (0/8 stop).
|
||||||
- Project version set to 0.0.32 and `CHANGELOG.md` maintained.
|
- Home Assistant 2026.03 compatibility fix: graceful fallback for removed `ATTR_COLOR_TEMP` import and color temperature service calls now use Kelvin.
|
||||||
|
- Project version set to 0.0.34 and `CHANGELOG.md` maintained.
|
||||||
|
|
||||||
Files created:
|
Files created:
|
||||||
- `custom_components/ha_knx_bridge/__init__.py`
|
- `custom_components/ha_knx_bridge/__init__.py`
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 0.0.34 - 2026-03-09
|
||||||
|
- Fix startup on Home Assistant 2026.03 by handling removed `ATTR_COLOR_TEMP` imports.
|
||||||
|
- Switch light color temperature service calls to `color_temp_kelvin`.
|
||||||
|
|
||||||
|
## 0.0.33 - 2026-02-15
|
||||||
|
- Parse control strings from DPT 3.007 payloads and use raw step values as percent steps (0/8 stop).
|
||||||
|
|
||||||
## 0.0.32 - 2026-02-15
|
## 0.0.32 - 2026-02-15
|
||||||
- Treat DPT 3.007 step_code 0 as a start/stop toggle for relative dimming/CT and rely on raw payload parsing.
|
- Treat DPT 3.007 step_code 0 as a start/stop toggle for relative dimming/CT and rely on raw payload parsing.
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Current minimal scope:
|
|||||||
- Light port (KNX -> HA commands, HA state -> KNX)
|
- Light port (KNX -> HA commands, HA state -> KNX)
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
- Home Assistant 2025.12 or newer (tested for compatibility with 2026.2).
|
- Home Assistant 2025.12 or newer (tested for compatibility with 2026.03).
|
||||||
- The built-in KNX integration must be set up and running.
|
- The built-in KNX integration must be set up and running.
|
||||||
|
|
||||||
## Install (HACS)
|
## Install (HACS)
|
||||||
@@ -77,8 +77,8 @@ Notes:
|
|||||||
- Relative dimming (DPT 3.007) maps KNX step values (control/stepcode) to small `brightness_step_pct` changes in Home Assistant.
|
- Relative dimming (DPT 3.007) maps KNX step values (control/stepcode) to small `brightness_step_pct` changes in Home Assistant.
|
||||||
- For relative dimming, the bridge repeats steps until a KNX stop telegram (0 or 8) is received.
|
- For relative dimming, the bridge repeats steps until a KNX stop telegram (0 or 8) is received.
|
||||||
- Relative color temperature (DPT 3.007) adjusts Kelvin in the same start/stop pattern.
|
- Relative color temperature (DPT 3.007) adjusts Kelvin in the same start/stop pattern.
|
||||||
- Some KNX keypads send `step_code 0` for a start/stop toggle; the bridge treats `step_code 0` as start when idle and stop when already dimming.
|
- Step values `1..7` dim down, `9..15` dim up, and `0/8` stop; the bridge uses the raw step value as the percent step size.
|
||||||
- Color temperature mode must match the KNX telegram DPT: `relative` for 5.001, `absolute` for 7.600 (2-byte unsigned), `absolute_float` for DPT 9 (2-byte float). The bridge sends HA color temperature using `color_temp` (mireds) for maximum compatibility.
|
- Color temperature mode must match the KNX telegram DPT: `relative` for 5.001, `absolute` for 7.600 (2-byte unsigned), `absolute_float` for DPT 9 (2-byte float). The bridge sends HA color temperature using `color_temp_kelvin`.
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
- For DPT 1.008 (Up/Down), the bridge treats `0 = Up/Open` and `1 = Down/Close`.
|
- For DPT 1.008 (Up/Down), the bridge treats `0 = Up/Open` and `1 = Down/Close`.
|
||||||
@@ -113,5 +113,5 @@ Notes:
|
|||||||
- Advanced DPT mapping options and inversion settings.
|
- Advanced DPT mapping options and inversion settings.
|
||||||
|
|
||||||
## Versioning and Releases
|
## Versioning and Releases
|
||||||
- Current version: 0.0.32
|
- Current version: 0.0.34
|
||||||
- `CHANGELOG.md` lists versions with the newest entries at the top.
|
- `CHANGELOG.md` lists versions with the newest entries at the top.
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ from typing import Any
|
|||||||
from homeassistant.components.light import (
|
from homeassistant.components.light import (
|
||||||
ATTR_BRIGHTNESS,
|
ATTR_BRIGHTNESS,
|
||||||
ATTR_COLOR_MODE,
|
ATTR_COLOR_MODE,
|
||||||
ATTR_COLOR_TEMP,
|
|
||||||
ATTR_HS_COLOR,
|
ATTR_HS_COLOR,
|
||||||
ATTR_RGB_COLOR,
|
ATTR_RGB_COLOR,
|
||||||
ATTR_RGBW_COLOR,
|
ATTR_RGBW_COLOR,
|
||||||
@@ -79,6 +78,11 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
KNX_DOMAIN = "knx"
|
KNX_DOMAIN = "knx"
|
||||||
|
|
||||||
|
try:
|
||||||
|
from homeassistant.components.light import ATTR_COLOR_TEMP
|
||||||
|
except ImportError: # pragma: no cover - fallback for newer HA
|
||||||
|
ATTR_COLOR_TEMP = "color_temp"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from homeassistant.components.light import ATTR_COLOR_TEMP_KELVIN
|
from homeassistant.components.light import ATTR_COLOR_TEMP_KELVIN
|
||||||
except ImportError: # pragma: no cover - fallback for older HA
|
except ImportError: # pragma: no cover - fallback for older HA
|
||||||
@@ -678,13 +682,13 @@ class BridgeManager:
|
|||||||
)
|
)
|
||||||
self._register_knx_light_command(
|
self._register_knx_light_command(
|
||||||
port.relative_color_temperature_address,
|
port.relative_color_temperature_address,
|
||||||
None,
|
"control_dimming",
|
||||||
port,
|
port,
|
||||||
"relative_color_temperature",
|
"relative_color_temperature",
|
||||||
)
|
)
|
||||||
self._register_knx_light_command(
|
self._register_knx_light_command(
|
||||||
port.relative_dimming_address,
|
port.relative_dimming_address,
|
||||||
None,
|
"control_dimming",
|
||||||
port,
|
port,
|
||||||
"relative_dimming",
|
"relative_dimming",
|
||||||
)
|
)
|
||||||
@@ -1167,7 +1171,7 @@ class BridgeManager:
|
|||||||
await self._call_light_service(
|
await self._call_light_service(
|
||||||
port.entity_id,
|
port.entity_id,
|
||||||
"turn_on",
|
"turn_on",
|
||||||
{"color_temp": _kelvin_to_mireds(kelvin)},
|
{ATTR_COLOR_TEMP_KELVIN: int(round(kelvin))},
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1176,13 +1180,7 @@ class BridgeManager:
|
|||||||
if dim_info is not None:
|
if dim_info is not None:
|
||||||
control, step_code = dim_info
|
control, step_code = dim_info
|
||||||
if step_code == 0:
|
if step_code == 0:
|
||||||
direction = "up" if control else "down"
|
self._stop_light_dimming(port.entity_id)
|
||||||
if port.entity_id in self._light_dimming_tasks:
|
|
||||||
self._stop_light_dimming(port.entity_id)
|
|
||||||
return
|
|
||||||
self._start_light_dimming(
|
|
||||||
port.entity_id, direction, 1
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
value = _extract_dimming_value(event)
|
value = _extract_dimming_value(event)
|
||||||
if value is None:
|
if value is None:
|
||||||
@@ -1204,13 +1202,7 @@ class BridgeManager:
|
|||||||
if dim_info is not None:
|
if dim_info is not None:
|
||||||
control, step_code = dim_info
|
control, step_code = dim_info
|
||||||
if step_code == 0:
|
if step_code == 0:
|
||||||
direction = "up" if control else "down"
|
self._stop_light_ct_adjust(port.entity_id)
|
||||||
if port.entity_id in self._light_ct_tasks:
|
|
||||||
self._stop_light_ct_adjust(port.entity_id)
|
|
||||||
return
|
|
||||||
self._start_light_ct_adjust(
|
|
||||||
port, direction, 1
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
value = _extract_dimming_value(event)
|
value = _extract_dimming_value(event)
|
||||||
if value is None:
|
if value is None:
|
||||||
@@ -1516,7 +1508,7 @@ class BridgeManager:
|
|||||||
await self._call_light_service(
|
await self._call_light_service(
|
||||||
port.entity_id,
|
port.entity_id,
|
||||||
"turn_on",
|
"turn_on",
|
||||||
{"color_temp": _kelvin_to_mireds(next_kelvin)},
|
{ATTR_COLOR_TEMP_KELVIN: int(round(next_kelvin))},
|
||||||
)
|
)
|
||||||
await asyncio.sleep(0.3)
|
await asyncio.sleep(0.3)
|
||||||
|
|
||||||
@@ -1549,7 +1541,7 @@ class BridgeManager:
|
|||||||
await self._call_light_service(
|
await self._call_light_service(
|
||||||
port.entity_id,
|
port.entity_id,
|
||||||
"turn_on",
|
"turn_on",
|
||||||
{"color_temp": _kelvin_to_mireds(next_kelvin)},
|
{ATTR_COLOR_TEMP_KELVIN: int(round(next_kelvin))},
|
||||||
)
|
)
|
||||||
|
|
||||||
self.hass.async_create_task(_runner())
|
self.hass.async_create_task(_runner())
|
||||||
@@ -1595,8 +1587,11 @@ def _extract_dimming_info(event: Event) -> tuple[bool, int] | None:
|
|||||||
control = value.get("control")
|
control = value.get("control")
|
||||||
step = value.get("stepcode", value.get("step_code"))
|
step = value.get("stepcode", value.get("step_code"))
|
||||||
if control is not None and step is not None:
|
if control is not None and step is not None:
|
||||||
|
control_bit = _parse_control_value(control)
|
||||||
|
if control_bit is None:
|
||||||
|
return None
|
||||||
try:
|
try:
|
||||||
return bool(int(control)), int(step) & 0x07
|
return control_bit, int(step) & 0x07
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
return None
|
return None
|
||||||
if isinstance(value, (int, float)):
|
if isinstance(value, (int, float)):
|
||||||
@@ -1616,6 +1611,20 @@ def _extract_dimming_info(event: Event) -> tuple[bool, int] | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_control_value(value: Any) -> bool | None:
|
||||||
|
if isinstance(value, bool):
|
||||||
|
return value
|
||||||
|
if isinstance(value, (int, float)):
|
||||||
|
return bool(int(value))
|
||||||
|
if isinstance(value, str):
|
||||||
|
text = value.strip().lower()
|
||||||
|
if text in ("increase", "up", "raise", "1", "true", "on"):
|
||||||
|
return True
|
||||||
|
if text in ("decrease", "down", "lower", "0", "false", "off"):
|
||||||
|
return False
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _clean_address(address: Any) -> str | None:
|
def _clean_address(address: Any) -> str | None:
|
||||||
if not address:
|
if not address:
|
||||||
return None
|
return None
|
||||||
@@ -1692,12 +1701,6 @@ def _percent_to_brightness(percent: int) -> int:
|
|||||||
return int(round(percent / 100 * 255))
|
return int(round(percent / 100 * 255))
|
||||||
|
|
||||||
|
|
||||||
def _kelvin_to_mireds(kelvin: float) -> int:
|
|
||||||
if kelvin <= 0:
|
|
||||||
return 0
|
|
||||||
return int(round(1000000 / kelvin))
|
|
||||||
|
|
||||||
|
|
||||||
def _mireds_to_kelvin(mireds: float) -> float:
|
def _mireds_to_kelvin(mireds: float) -> float:
|
||||||
if mireds <= 0:
|
if mireds <= 0:
|
||||||
return 0
|
return 0
|
||||||
@@ -1889,21 +1892,11 @@ def _relative_dimming_step(value: int) -> tuple[str, int] | None:
|
|||||||
return None
|
return None
|
||||||
if value <= 7:
|
if value <= 7:
|
||||||
direction = "down"
|
direction = "down"
|
||||||
step = value
|
percent = value
|
||||||
else:
|
else:
|
||||||
direction = "up"
|
direction = "up"
|
||||||
step = value - 8
|
percent = value
|
||||||
percent_map = {
|
if percent <= 0:
|
||||||
1: 10,
|
|
||||||
2: 8,
|
|
||||||
3: 6,
|
|
||||||
4: 4,
|
|
||||||
5: 3,
|
|
||||||
6: 2,
|
|
||||||
7: 1,
|
|
||||||
}
|
|
||||||
percent = percent_map.get(step)
|
|
||||||
if percent is None:
|
|
||||||
return None
|
return None
|
||||||
return direction, percent
|
return direction, percent
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"domain": "ha_knx_bridge",
|
"domain": "ha_knx_bridge",
|
||||||
"name": "HA KNX Bridge",
|
"name": "HA KNX Bridge",
|
||||||
"version": "0.0.32",
|
"version": "0.0.34",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://github.com/bahmcloud/HA-KNX-Bridge",
|
"documentation": "https://github.com/bahmcloud/HA-KNX-Bridge",
|
||||||
"issue_tracker": "https://github.com/bahmcloud/HA-KNX-Bridge/issues",
|
"issue_tracker": "https://github.com/bahmcloud/HA-KNX-Bridge/issues",
|
||||||
|
|||||||
Reference in New Issue
Block a user