fix(ha-integration): ausgeschaltete Lampe -> "unavailable" statt Fehlerzustand
War eine Lampe stromlos, wurde der Verbindungsfehler als UpdateFailed gemeldet; HA schob den Config-Entry in SETUP_RETRY und die Integration fiel in den Fehlerzustand. Jetzt wird Connection-Refused/Timeout als NinlightUnavailable gefuehrt: der Coordinator liefert den letzten bekannten State mit available=False, der Entry bleibt geladen und die Entity zeigt "unavailable". Protokollfehler (400, kaputtes JSON) und Auth (401 -> Reauth) verhalten sich unveraendert. Light-Faehigkeiten (RGB/CT, Kelvin-Bereich) sind deshalb dynamische Properties — ein Entry, der mit stromloser Lampe angelegt wurde, erkennt sie, sobald die Lampe antwortet.
This commit is contained in:
@@ -54,17 +54,33 @@ class NinlightLight(NinlightEntity, LightEntity):
|
||||
|
||||
def __init__(self, coordinator: NinlightCoordinator, entry: NinlightConfigEntry) -> None:
|
||||
super().__init__(coordinator, entry)
|
||||
state = coordinator.data
|
||||
self._attr_unique_id = f"{(entry.unique_id or '').lower()}-light"
|
||||
# Both modes are advertised for RGB bulbs: the firmware keeps the last color and
|
||||
# the last color temperature and picks between them with `mode`, which is exactly
|
||||
# how HA models a color_temp + rgb light.
|
||||
self._attr_supported_color_modes = {ColorMode.COLOR_TEMP, ColorMode.RGB} if state.has_rgb else {
|
||||
ColorMode.COLOR_TEMP
|
||||
}
|
||||
self._attr_supported_features = LightEntityFeature.TRANSITION
|
||||
self._attr_min_color_temp_kelvin = state.ct_min
|
||||
self._attr_max_color_temp_kelvin = state.ct_max
|
||||
|
||||
# Capabilities come from the polled state, not from a one-time __init__ snapshot: an
|
||||
# entry set up while the bulb was powered off starts from defaults and must pick up
|
||||
# the real RGB/CT range as soon as the bulb answers again.
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
# An unreachable (powered-off) bulb is an expected state: the entity goes
|
||||
# unavailable instead of the config entry erroring.
|
||||
return self.coordinator.last_update_success and self.coordinator.data.available
|
||||
|
||||
@property
|
||||
def supported_color_modes(self) -> set[ColorMode]:
|
||||
state = self.coordinator.data
|
||||
# Both modes for RGB bulbs: the firmware keeps the last color and the last color
|
||||
# temperature and picks between them with `mode`, exactly how HA models a
|
||||
# color_temp + rgb light.
|
||||
return {ColorMode.COLOR_TEMP, ColorMode.RGB} if state.has_rgb else {ColorMode.COLOR_TEMP}
|
||||
|
||||
@property
|
||||
def min_color_temp_kelvin(self) -> int:
|
||||
return self.coordinator.data.ct_min
|
||||
|
||||
@property
|
||||
def max_color_temp_kelvin(self) -> int:
|
||||
return self.coordinator.data.ct_max
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
|
||||
Reference in New Issue
Block a user