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

Климат

ClimateEntity (HVAC AC)

Кондиционер: температура, режим, скорость вентилятора, свинг.

Sber Climate (AC) entity -- maps HA climate entities to Sber hvac_ac category.

CLIMATE_CATEGORY module-attribute

CLIMATE_CATEGORY = 'hvac_ac'

Sber device category for air conditioner / HVAC entities.

HA_TO_SBER_WORK_MODE module-attribute

HA_TO_SBER_WORK_MODE = {'cool': 'cooling', 'heat': 'heating', 'dry': 'dehumidification', 'fan_only': 'ventilation', 'heat_cool': 'auto', 'auto': 'auto', 'eco': 'eco'}

Map HA HVAC modes to Sber work mode enum values.

'off' is excluded — use on_off. Sber also supports 'turbo' and 'quiet' work modes; these are mapped from HA preset_modes (boost→turbo, sleep→quiet) in to_sber_current_state.

SBER_TO_HA_WORK_MODE module-attribute

SBER_TO_HA_WORK_MODE = {'cooling': 'cool', 'heating': 'heat', 'dehumidification': 'dry', 'ventilation': 'fan_only', 'auto': 'auto', 'eco': 'eco'}

Reverse mapping: Sber work mode → HA hvac_mode.

Note: kept as a separate literal (not auto-generated) because HA_TO_SBER_WORK_MODE has heat_cool and auto both mapping to auto — a naive reverse would lose heat_cool. The reverse here prefers the canonical HA mode for each Sber value.

HA_TO_SBER_SWING module-attribute

HA_TO_SBER_SWING = {'off': 'no', 'vertical': 'vertical', 'horizontal': 'horizontal', 'both': 'rotation', 'swing': 'swing', 'auto': 'auto'}

Map HA swing modes to Sber air flow direction values.

SBER_TO_HA_SWING module-attribute

SBER_TO_HA_SWING = {v: k for k, v in (items())}

Reverse mapping: Sber swing → HA swing_mode.

HA_TO_SBER_THERMOSTAT_MODE module-attribute

HA_TO_SBER_THERMOSTAT_MODE = {'heat': 'heating', 'auto': 'auto', 'heat_cool': 'auto'}

Map HA HVAC modes to Sber thermostat mode enum values (simpler devices).

SBER_TO_HA_THERMOSTAT_MODE module-attribute

SBER_TO_HA_THERMOSTAT_MODE = {'heating': 'heat', 'auto': 'auto'}

Reverse mapping: Sber thermostat mode → HA hvac_mode.

Kept as explicit literal for the same reason as SBER_TO_HA_WORK_MODE: heat_cool and auto both forward-map to auto.

HA_TO_SBER_FAN_MODE module-attribute

HA_TO_SBER_FAN_MODE = {'auto': 'auto', 'low': 'low', 'medium': 'medium', 'mid': 'medium', 'high': 'high', 'turbo': 'turbo', 'quiet': 'quiet', 'silent': 'quiet', 'sleep': 'quiet', 'strong': 'turbo', 'boost': 'turbo', 'max': 'turbo', 'min': 'low', '1': 'quiet', '2': 'low', '3': 'medium', '4': 'high', '5': 'turbo'}

Map HA fan modes to Sber air flow power enum values.

ClimateEntity

ClimateEntity(entity_data, category=CLIMATE_CATEGORY, min_temp=16.0, max_temp=32.0, temp_step=1)

Bases: BaseEntity

Sber climate entity for air conditioner control.

Maps HA climate entities to the Sber 'hvac_ac' category with support for: - On/off control - Temperature reading and target temperature setting - Fan mode, swing mode, and HVAC work mode selection - Allowed values for dynamic enum features

Subclasses override class-level flags to restrict features per Sber spec: - _supports_fan: include hvac_air_flow_power (default True for AC) - _supports_swing: include hvac_air_flow_direction (default True for AC) - _supports_work_mode: include hvac_work_mode (default True for AC) - _supports_thermostat_mode: include hvac_thermostat_mode (default False)

Initialize climate entity.

Parameters:

Name Type Description Default
entity_data dict

HA entity registry dict containing entity metadata.

required
category str

Sber device category (override in subclasses).

CLIMATE_CATEGORY
min_temp float

Minimum temperature default.

16.0
max_temp float

Maximum temperature default.

32.0
temp_step int

Temperature step for allowed_values (Sber spec varies by category).

1
Source code in custom_components/sber_mqtt_bridge/devices/climate.py
def __init__(
    self,
    entity_data: dict,
    category: str = CLIMATE_CATEGORY,
    min_temp: float = 16.0,
    max_temp: float = 32.0,
    temp_step: int = 1,
) -> None:
    """Initialize climate entity.

    Args:
        entity_data: HA entity registry dict containing entity metadata.
        category: Sber device category (override in subclasses).
        min_temp: Minimum temperature default.
        max_temp: Maximum temperature default.
        temp_step: Temperature step for allowed_values (Sber spec varies by category).
    """
    super().__init__(category, entity_data)
    self.temp_step = temp_step
    self.current_state = False
    self.temperature = None
    self.target_temperature = None
    self.fan_modes = []
    self.swing_modes = []
    self.hvac_modes = []
    self.fan_mode = None
    self.swing_mode = None
    self.hvac_mode = None
    self.min_temp = min_temp
    self.max_temp = max_temp
    self._target_humidity: int | None = None
    self._preset_mode: str | None = None
    self._preset_modes: list[str] = []
    self._child_lock: bool | None = None

fill_by_ha_state

fill_by_ha_state(ha_state)

Parse HA state and update all climate attributes.

Simple attribute extraction is handled declaratively via :attr:ATTR_SPECS. State-derived values (current_state, hvac_mode) remain here since they come from the top-level state field, not from attributes.

Parameters:

Name Type Description Default
ha_state dict

HA state dict with 'state' and 'attributes' keys. Attributes may include current_temperature, temperature, fan_modes, swing_modes, hvac_modes, target_humidity, preset_mode, preset_modes, etc.

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

    Simple attribute extraction is handled declaratively via
    :attr:`ATTR_SPECS`.  State-derived values (``current_state``,
    ``hvac_mode``) remain here since they come from the top-level
    ``state`` field, not from ``attributes``.

    Args:
        ha_state: HA state dict with 'state' and 'attributes' keys.
            Attributes may include current_temperature, temperature,
            fan_modes, swing_modes, hvac_modes, target_humidity,
            preset_mode, preset_modes, etc.
    """
    super().fill_by_ha_state(ha_state)
    attrs = ha_state.get("attributes", {})
    self._apply_attr_specs(attrs)

    # Derive on/off state and hvac_mode from top-level state string
    self.current_state = ha_state.get("state", "off") != "off"
    self.hvac_mode = ha_state.get("state")

create_allowed_values_list

create_allowed_values_list()

Build allowed values map for enum-based and integer-based features.

Returns:

Type Description
dict[str, dict]

Dict mapping feature key to its allowed values descriptor.

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

    Returns:
        Dict mapping feature key to its allowed values descriptor.
    """
    allowed: dict[str, dict] = {}
    if self._supports_fan and self.fan_modes:
        sber_fans = [HA_TO_SBER_FAN_MODE.get(m, m) for m in self.fan_modes]
        allowed["hvac_air_flow_power"] = {
            "type": "ENUM",
            "enum_values": {"values": list(dict.fromkeys(sber_fans))},
        }
    if self._supports_swing and self.swing_modes:
        sber_swings = [HA_TO_SBER_SWING.get(m, m) for m in self.swing_modes]
        allowed["hvac_air_flow_direction"] = {
            "type": "ENUM",
            "enum_values": {"values": list(dict.fromkeys(sber_swings))},
        }
    if self._supports_work_mode and self.hvac_modes:
        sber_modes = [HA_TO_SBER_WORK_MODE[m] for m in self.hvac_modes if m in HA_TO_SBER_WORK_MODE]
        if sber_modes:
            allowed["hvac_work_mode"] = {"type": "ENUM", "enum_values": {"values": list(dict.fromkeys(sber_modes))}}
    if self._supports_thermostat_mode and self.hvac_modes:
        sber_modes = [HA_TO_SBER_THERMOSTAT_MODE[m] for m in self.hvac_modes if m in HA_TO_SBER_THERMOSTAT_MODE]
        if sber_modes:
            allowed["hvac_thermostat_mode"] = {
                "type": "ENUM",
                "enum_values": {"values": list(dict.fromkeys(sber_modes))},
            }
    allowed["hvac_temp_set"] = {
        "type": "INTEGER",
        "integer_values": {
            "min": str(int(self.min_temp)),
            "max": str(int(self.max_temp)),
            "step": str(self.temp_step),
        },
    }
    return allowed

to_sber_current_state

to_sber_current_state()

Build Sber current state payload with all climate attributes.

Includes online, on_off, temperature, target temperature, fan mode, swing mode, HVAC work mode, target humidity, and night mode when values are available.

Per Sber specification: - temperature uses x10 encoding (e.g. 22.0C -> 220) - hvac_temp_set uses whole degrees (e.g. 22.0C -> 22) - All integer_value fields are serialized as strings.

Returns:

Type Description
dict[str, dict]

Dict mapping entity_id to its Sber state representation.

Source code in custom_components/sber_mqtt_bridge/devices/climate.py
def to_sber_current_state(self) -> dict[str, dict]:
    """Build Sber current state payload with all climate attributes.

    Includes online, on_off, temperature, target temperature, fan mode,
    swing mode, HVAC work mode, target humidity, and night mode
    when values are available.

    Per Sber specification:
    - ``temperature`` uses x10 encoding (e.g. 22.0C -> 220)
    - ``hvac_temp_set`` uses whole degrees (e.g. 22.0C -> 22)
    - All ``integer_value`` fields are serialized as strings.

    Returns:
        Dict mapping entity_id to its Sber state representation.
    """
    states = [
        make_state(SberFeature.ONLINE, make_bool_value(self._is_online)),
        make_state(SberFeature.ON_OFF, make_bool_value(self.current_state)),
    ]
    states.extend(self._state_temperature())
    states.extend(self._state_fan_with_presets())
    states.extend(self._state_swing())
    states.extend(self._state_work_mode_with_presets())
    states.extend(self._state_thermostat())
    states.extend(self._state_optional_flags())
    return {self.entity_id: {"states": states}}

HvacRadiatorEntity

Радиатор отопления.

Sber HVAC Radiator entity -- maps HA radiator climate entities to Sber hvac_radiator.

HVAC_RADIATOR_CATEGORY module-attribute

HVAC_RADIATOR_CATEGORY = 'hvac_radiator'

Sber device category for radiator/heater climate entities.

HvacRadiatorEntity

HvacRadiatorEntity(entity_data)

Bases: ClimateEntity

Sber HVAC radiator entity for heating devices.

Inherits climate behavior but registers under the Sber 'hvac_radiator' category with radiator-appropriate temperature defaults (25-40 C).

Per Sber spec, radiators only support: on_off, online, temperature, hvac_temp_set. Fan, swing, and work mode features are disabled.

Initialize HVAC radiator 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/hvac_radiator.py
def __init__(self, entity_data: dict) -> None:
    """Initialize HVAC radiator entity.

    Args:
        entity_data: HA entity registry dict containing entity metadata.
    """
    super().__init__(
        entity_data,
        category=HVAC_RADIATOR_CATEGORY,
        min_temp=25.0,
        max_temp=40.0,
        temp_step=5,
    )

HvacBoilerEntity

Бойлер/котёл.

Sber HVAC Boiler entity -- maps HA water heater climate entities to Sber hvac_boiler.

HVAC_BOILER_CATEGORY module-attribute

HVAC_BOILER_CATEGORY = 'hvac_boiler'

Sber device category for boiler/water heater entities.

HvacBoilerEntity

HvacBoilerEntity(entity_data)

Bases: ClimateEntity

Sber HVAC boiler entity for water heater devices.

Inherits climate behavior but registers under the Sber 'hvac_boiler' category with boiler-appropriate temperature defaults (25-80 C).

Per Sber spec, boilers use hvac_thermostat_mode (NOT hvac_work_mode). Fan and swing features are disabled.

Initialize HVAC boiler 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/hvac_boiler.py
def __init__(self, entity_data: dict) -> None:
    """Initialize HVAC boiler entity.

    Args:
        entity_data: HA entity registry dict containing entity metadata.
    """
    super().__init__(
        entity_data,
        category=HVAC_BOILER_CATEGORY,
        min_temp=25.0,
        max_temp=80.0,
        temp_step=5,
    )

HvacFanEntity

Вентилятор.

Sber HVAC Fan entity -- maps HA fan entities to Sber hvac_fan category.

Supports on/off control and fan speed via the hvac_air_flow_power feature.

SBER_SPEED_VALUES module-attribute

SBER_SPEED_VALUES = ['auto', 'high', 'low', 'medium', 'quiet', 'turbo']

Allowed Sber ENUM values for hvac_air_flow_power (per Sber C2C spec).

HVAC_FAN_CATEGORY module-attribute

HVAC_FAN_CATEGORY = 'hvac_fan'

Sber device category for fan entities.

HvacFanEntity

HvacFanEntity(entity_data)

Bases: FanSpeedMixin, BaseEntity

Sber fan entity for ventilator control.

Maps HA fan entities to the Sber 'hvac_fan' category with support for: - On/off control - Fan speed via preset_mode or percentage-based speed mapping

Initialize fan 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/hvac_fan.py
def __init__(self, entity_data: dict) -> None:
    """Initialize fan entity.

    Args:
        entity_data: HA entity registry dict containing entity metadata.
    """
    super().__init__(HVAC_FAN_CATEGORY, entity_data)
    self.current_state: bool = False
    self.preset_mode: str | None = None
    self.preset_modes: list[str] = []
    self.percentage: int | None = None

fill_by_ha_state

fill_by_ha_state(ha_state)

Parse HA state and update fan attributes.

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/hvac_fan.py
def fill_by_ha_state(self, ha_state: dict) -> None:
    """Parse HA state and update fan attributes.

    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)
    self.current_state = ha_state.get("state") != "off"

create_allowed_values_list

create_allowed_values_list()

Build allowed values map for fan speed feature.

Returns empty dict when the fan has no speed support.

Returns:

Type Description
dict[str, dict]

Dict mapping feature key to its allowed ENUM values descriptor.

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

    Returns empty dict when the fan has no speed support.

    Returns:
        Dict mapping feature key to its allowed ENUM values descriptor.
    """
    if not self._supports_speed:
        return {}
    return {
        "hvac_air_flow_power": {
            "type": "ENUM",
            "enum_values": {"values": SBER_SPEED_VALUES},
        }
    }

to_sber_current_state

to_sber_current_state()

Build Sber current state payload with fan attributes.

Returns:

Type Description
dict[str, dict]

Dict mapping entity_id to its Sber state representation.

Source code in custom_components/sber_mqtt_bridge/devices/hvac_fan.py
def to_sber_current_state(self) -> dict[str, dict]:
    """Build Sber current state payload with fan attributes.

    Returns:
        Dict mapping entity_id to its Sber state representation.
    """
    states = [
        make_state(SberFeature.ONLINE, make_bool_value(self._is_online)),
        make_state(SberFeature.ON_OFF, make_bool_value(self.current_state)),
    ]
    if self._supports_speed:
        speed = self._get_sber_speed() or "auto"
        states.append(make_state(SberFeature.HVAC_AIR_FLOW_POWER, make_enum_value(speed)))
    return {self.entity_id: {"states": states}}

HvacHeaterEntity

Обогреватель.

Sber HVAC Heater entity -- maps HA heater climate entities to Sber hvac_heater.

HVAC_HEATER_CATEGORY module-attribute

HVAC_HEATER_CATEGORY = 'hvac_heater'

Sber device category for heater climate entities.

HvacHeaterEntity

HvacHeaterEntity(entity_data)

Bases: ClimateEntity

Sber HVAC heater entity for space heater devices.

Inherits climate behavior but registers under the Sber 'hvac_heater' category with heater-appropriate temperature defaults (5-40 C).

Per Sber spec, heaters support: hvac_air_flow_power, hvac_temp_set, hvac_thermostat_mode, on_off, online, temperature. No swing, no work mode.

Initialize HVAC heater 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/hvac_heater.py
def __init__(self, entity_data: dict) -> None:
    """Initialize HVAC heater entity.

    Args:
        entity_data: HA entity registry dict containing entity metadata.
    """
    super().__init__(
        entity_data,
        category=HVAC_HEATER_CATEGORY,
        min_temp=5.0,
        max_temp=40.0,
    )

HvacUnderfloorHeatingEntity

Тёплый пол.

Sber HVAC Underfloor Heating entity -- maps HA underfloor heating climate entities.

HVAC_UNDERFLOOR_CATEGORY module-attribute

HVAC_UNDERFLOOR_CATEGORY = 'hvac_underfloor_heating'

Sber device category for underfloor heating entities.

HvacUnderfloorEntity

HvacUnderfloorEntity(entity_data)

Bases: ClimateEntity

Sber HVAC underfloor heating entity.

Inherits climate behavior but registers under the Sber 'hvac_underfloor_heating' category with underfloor-appropriate temperature defaults (25-50 C).

Per Sber spec, underfloor heating uses hvac_thermostat_mode (NOT hvac_work_mode). Fan and swing features are disabled.

Initialize HVAC underfloor heating 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/hvac_underfloor_heating.py
def __init__(self, entity_data: dict) -> None:
    """Initialize HVAC underfloor heating entity.

    Args:
        entity_data: HA entity registry dict containing entity metadata.
    """
    super().__init__(
        entity_data,
        category=HVAC_UNDERFLOOR_CATEGORY,
        min_temp=25.0,
        max_temp=50.0,
        temp_step=5,
    )

HvacAirPurifierEntity

Очиститель воздуха.

Sber HVAC Air Purifier entity -- maps HA fan entities to Sber hvac_air_purifier category.

Supports on/off control, fan speed via hvac_air_flow_power, and read-only features: ionization, night mode, aromatization, filter/ionizer replacement.

HVAC_AIR_PURIFIER_CATEGORY module-attribute

HVAC_AIR_PURIFIER_CATEGORY = 'hvac_air_purifier'

Sber device category for air purifier entities.

HvacAirPurifierEntity

HvacAirPurifierEntity(entity_data)

Bases: FanSpeedMixin, BaseEntity

Sber air purifier entity for purifier fan devices.

Maps HA fan entities (with device_class purifier/air_purifier) to the Sber 'hvac_air_purifier' category with support for: - On/off control - Fan speed via preset_mode or percentage - Read-only flags: ionization, night mode, aromatization, filter replacement, ionizer replacement, decontamination

Initialize air purifier 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/hvac_air_purifier.py
def __init__(self, entity_data: dict) -> None:
    """Initialize air purifier entity.

    Args:
        entity_data: HA entity registry dict containing entity metadata.
    """
    super().__init__(HVAC_AIR_PURIFIER_CATEGORY, entity_data)
    self.current_state: bool = False
    self.preset_mode: str | None = None
    self.preset_modes: list[str] = []
    self.percentage: int | None = None
    self._ionization: bool = False
    self._night_mode: bool = False
    self._aromatization: bool = False
    self._replace_filter: bool = False
    self._replace_ionizator: bool = False
    self._decontaminate: bool = False

fill_by_ha_state

fill_by_ha_state(ha_state)

Parse HA state and update air purifier attributes.

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/hvac_air_purifier.py
def fill_by_ha_state(self, ha_state: dict) -> None:
    """Parse HA state and update air purifier attributes.

    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)
    self.current_state = ha_state.get("state") != "off"

create_allowed_values_list

create_allowed_values_list()

Build allowed values map for air flow power feature.

Returns:

Type Description
dict[str, dict]

Dict mapping feature key to its allowed ENUM values descriptor.

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

    Returns:
        Dict mapping feature key to its allowed ENUM values descriptor.
    """
    return {
        "hvac_air_flow_power": {
            "type": "ENUM",
            "enum_values": {"values": SBER_SPEED_VALUES},
        }
    }

to_sber_current_state

to_sber_current_state()

Build Sber current state payload with air purifier attributes.

Returns:

Type Description
dict[str, dict]

Dict mapping entity_id to its Sber state representation.

Source code in custom_components/sber_mqtt_bridge/devices/hvac_air_purifier.py
def to_sber_current_state(self) -> dict[str, dict]:
    """Build Sber current state payload with air purifier attributes.

    Returns:
        Dict mapping entity_id to its Sber state representation.
    """
    states = [
        make_state(SberFeature.ONLINE, make_bool_value(self._is_online)),
        make_state(SberFeature.ON_OFF, make_bool_value(self.current_state)),
    ]
    speed = self._get_sber_speed()
    if speed:
        states.append(make_state(SberFeature.HVAC_AIR_FLOW_POWER, make_enum_value(speed)))
    states.extend(
        [
            make_state(SberFeature.HVAC_IONIZATION, make_bool_value(self._ionization)),
            make_state(SberFeature.HVAC_NIGHT_MODE, make_bool_value(self._night_mode)),
            make_state(SberFeature.HVAC_AROMATIZATION, make_bool_value(self._aromatization)),
            make_state(SberFeature.HVAC_REPLACE_FILTER, make_bool_value(self._replace_filter)),
            make_state(SberFeature.HVAC_REPLACE_IONIZATOR, make_bool_value(self._replace_ionizator)),
        ]
    )
    if self._decontaminate:
        states.append(make_state(SberFeature.HVAC_DECONTAMINATE, make_bool_value(self._decontaminate)))
    return {self.entity_id: {"states": states}}