Перейти к содержанию

Освещение

LightEntity

Управление освещением: яркость, цвет (HSV), цветовая температура.

Sber Light entity — maps HA light to Sber light category.

Supports brightness, color temperature, RGB color (HSV), and light mode. Uses LinearConverter for value range mapping and ColorConverter for HSV.

LIGHT_ENTITY_CATEGORY module-attribute

LIGHT_ENTITY_CATEGORY = 'light'

Sber device category for light entities.

COLOR_MODES module-attribute

COLOR_MODES = {'hs', 'rgb', 'rgbw', 'rgbww', 'xy'}

HA color modes that map to Sber colour features.

NON_DIMMABLE_MODES module-attribute

NON_DIMMABLE_MODES = {'onoff', 'unknown'}

HA color modes that do NOT imply brightness support.

Per HA light architecture, every color mode except onoff and unknown supports brightness — including color_temp and white (issue #44: CCT-only lamps must expose light_brightness).

LightEntity

LightEntity(ha_entity_data)

Bases: BaseEntity

Sber light entity with brightness, color, and color temperature support.

Maps HA light entities to the Sber 'light' category with support for: - On/off control - Brightness (scaled 0-255 HA ↔ 100-900 Sber) - Color temperature (mireds ↔ 0-1000 Sber, reversed) - RGB color via HSV conversion - Light mode (white / colour)

Accepts battery / battery_low / signal_strength linked sensors via :attr:LINKABLE_ROLES (Zigbee lights commonly report these).

Command handlers address the entity in its own HA domain (:meth:get_entity_domain) rather than a hard-coded light, so an entity forced into light / led_strip by a user type override is driven through services that actually exist for it. For a light.* entity — the only domain these categories map to — the emitted calls are unchanged.

Initialize light entity from HA entity data.

Parameters:

Name Type Description Default
ha_entity_data dict

HA entity registry dict.

required
Source code in custom_components/sber_mqtt_bridge/devices/light.py
def __init__(self, ha_entity_data: dict) -> None:
    """Initialize light entity from HA entity data.

    Args:
        ha_entity_data: HA entity registry dict.
    """
    super().__init__(LIGHT_ENTITY_CATEGORY, ha_entity_data)
    self.supported_features: int = 0
    self.max_mireds: int = 500
    self.min_mireds: int = 153
    self.supported_color_modes: list[str] = []
    self.current_state: bool = False
    self._ha_brightness_raw: int = 0
    self.current_sber_brightness: int = 0
    self.current_sber_color_temp: int | None = 0
    self.current_color_mode: str | None = None
    self.hs_color: list[float] | None = None

    self.brightness_converter = LinearConverter()
    self.brightness_converter.set_ha_limits(0, 255)
    self.brightness_converter.set_sber_limits(100, 900)

    self.color_temp_converter = LinearConverter()
    self.color_temp_converter.set_reversed(True)
    self.color_temp_converter.set_ha_limits(153, 500)
    self.color_temp_converter.set_sber_limits(0, 1000)

fill_by_ha_state

fill_by_ha_state(ha_state)

Parse HA state and update all light attributes.

Simple attribute extraction is handled declaratively via :attr:ATTR_SPECS. Instance-specific LinearConverter transforms and state derivation remain here.

Parameters:

Name Type Description Default
ha_state dict

HA state dict with 'state' and 'attributes' keys.

required
Source code in custom_components/sber_mqtt_bridge/devices/light.py
def fill_by_ha_state(self, ha_state: dict) -> None:
    """Parse HA state and update all light attributes.

    Simple attribute extraction is handled declaratively via
    :attr:`ATTR_SPECS`.  Instance-specific LinearConverter transforms
    and state derivation remain here.

    Args:
        ha_state: HA state dict with 'state' and 'attributes' keys.
    """
    super().fill_by_ha_state(ha_state)
    attrs = ha_state.get("attributes", {})
    self._apply_attr_specs(attrs)

    # Update color_temp converter limits.  Modern HA (≥2026) publishes
    # only kelvin attributes; mireds are a legacy fallback (issue #44
    # audit — CCT state was silently unparsed on current HA).
    min_kelvin = _safe_int_parser(attrs.get("min_color_temp_kelvin"))
    max_kelvin = _safe_int_parser(attrs.get("max_color_temp_kelvin"))
    if min_kelvin and max_kelvin:
        # Kelvin and mireds are reciprocal: min_kelvin → max_mireds.
        self.min_mireds = round(1_000_000 / max_kelvin)
        self.max_mireds = round(1_000_000 / min_kelvin)
    else:
        self.max_mireds = attrs.get("max_mireds", 500)
        self.min_mireds = attrs.get("min_mireds", 153)
    if self.max_mireds is not None and self.min_mireds is not None:
        self.color_temp_converter.set_ha_limits(self.min_mireds, self.max_mireds)

    # Derive on/off state from HA state string
    self.current_state = ha_state.get("state", "off") == "on"

    # Apply LinearConverter to raw brightness → Sber scale
    self.current_sber_brightness = self.brightness_converter.ha_to_sber(self._ha_brightness_raw)

    # Apply LinearConverter to raw color_temp → Sber scale.  Prefer
    # kelvin (authoritative in modern HA) over legacy mireds.
    ha_kelvin = _safe_int_parser(attrs.get("color_temp_kelvin"))
    if ha_kelvin:
        self.current_sber_color_temp = self.color_temp_converter.ha_to_sber(round(1_000_000 / ha_kelvin))
    elif attrs.get("color_temp") is not None:
        self.current_sber_color_temp = self.color_temp_converter.ha_to_sber(attrs["color_temp"])
    else:
        self.current_sber_color_temp = None

create_allowed_values_list

create_allowed_values_list()

Build allowed values map for light features.

Built from the final features list (with user overrides applied) rather than from capability heuristics, so a feature added via extra_features always gets its limits — without them Sber renders a dead slider (issue #44).

Returns:

Type Description
dict[str, dict]

Dict mapping feature key to its allowed values descriptor.

Source code in custom_components/sber_mqtt_bridge/devices/light.py
def create_allowed_values_list(self) -> dict[str, dict]:
    """Build allowed values map for light features.

    Built from the **final** features list (with user overrides
    applied) rather than from capability heuristics, so a feature
    added via ``extra_features`` always gets its limits — without
    them Sber renders a dead slider (issue #44).

    Returns:
        Dict mapping feature key to its allowed values descriptor.
    """
    features = set(self.get_final_features_list())
    allowed_values: dict[str, dict] = {}

    if "light_brightness" in features:
        allowed_values["light_brightness"] = {
            "type": "INTEGER",
            "integer_values": {"min": "100", "max": "900", "step": "1"},
        }
    if "light_colour" in features:
        allowed_values["light_colour"] = {"type": "COLOUR"}
    if "light_mode" in features:
        allowed_values["light_mode"] = {"type": "ENUM", "enum_values": {"values": ["white", "colour"]}}
    if "light_colour_temp" in features:
        allowed_values["light_colour_temp"] = {
            "type": "INTEGER",
            "integer_values": {"min": "0", "max": "1000", "step": "1"},
        }

    return allowed_values

create_dependencies

create_dependencies()

Return light_colour → light_mode dependency when both features exist.

Returns:

Type Description
dict[str, dict]

Dependencies dict for Sber model descriptor.

Source code in custom_components/sber_mqtt_bridge/devices/light.py
def create_dependencies(self) -> dict[str, dict]:
    """Return light_colour → light_mode dependency when both features exist.

    Returns:
        Dependencies dict for Sber model descriptor.
    """
    features = self.get_final_features_list()
    if "light_colour" in features and "light_mode" in features:
        return {
            "light_colour": {
                "key": "light_mode",
                "values": [{"type": "ENUM", "enum_value": "colour"}],
            },
        }
    return {}

LedStripEntity

Светодиодная лента с поддержкой цвета и эффектов.

Sber LED Strip entity -- maps HA light entities to Sber led_strip category.

Identical to light in features and behavior, but uses the led_strip Sber category for LED strip devices.

LED_STRIP_CATEGORY module-attribute

LED_STRIP_CATEGORY = 'led_strip'

Sber device category for LED strip entities.

LedStripEntity

LedStripEntity(entity_data)

Bases: LightEntity

Sber LED strip entity.

Inherits all light behavior (on/off, brightness, color, color temperature) but registers under the Sber 'led_strip' category.

Initialize LED strip entity.

Parameters:

Name Type Description Default
entity_data dict

HA entity registry dict containing entity metadata.

required
Source code in custom_components/sber_mqtt_bridge/devices/led_strip.py
def __init__(self, entity_data: dict) -> None:
    """Initialize LED strip entity.

    Args:
        entity_data: HA entity registry dict containing entity metadata.
    """
    super().__init__(entity_data)
    self.category = LED_STRIP_CATEGORY