diff --git a/tests/data/devices/tze200-cpmgn2cf-ts0601.json b/tests/data/devices/tze200-cpmgn2cf-ts0601.json index 2d75064d0..15351299e 100644 --- a/tests/data/devices/tze200-cpmgn2cf-ts0601.json +++ b/tests/data/devices/tze200-cpmgn2cf-ts0601.json @@ -955,7 +955,7 @@ "unique_id": "ab:cd:ef:12:e8:32:c6:e4-1", "migrate_unique_ids": [], "platform": "climate", - "class_name": "MoesThermostat", + "class_name": "Thermostat", "translation_key": "thermostat", "translation_placeholders": null, "device_class": null, @@ -980,18 +980,11 @@ "fan_mode": "auto", "max_temp": 30.0, "min_temp": 7.0, - "supported_features": 401, + "supported_features": 385, "fan_modes": null, - "preset_modes": [ - "none", - "away", - "Schedule", - "comfort", - "eco", - "boost", - "Complex" - ], + "preset_modes": [], "hvac_modes": [ + "off", "heat" ], "sys_mode": "[4]/heat", diff --git a/tests/data/devices/tze200-mudxchsu-ts0601-0x00000045.json b/tests/data/devices/tze200-mudxchsu-ts0601-0x00000045.json index 3aafb048d..2c91cddaf 100644 --- a/tests/data/devices/tze200-mudxchsu-ts0601-0x00000045.json +++ b/tests/data/devices/tze200-mudxchsu-ts0601-0x00000045.json @@ -8,7 +8,7 @@ "friendly_model": "TS0601", "name": "_TZE200_mudxchsu TS0601", "quirk_applied": true, - "quirk_class": "zhaquirks.tuya.ts0601_trv:ZonnsmartTV01_ZG", + "quirk_class": "zhaquirks.tuya.ts0601_trv:(_TZE200_7yoranx2 / TS0601)", "exposes_features": [], "manufacturer_code": 4098, "power_source": "Battery or Unknown", @@ -669,7 +669,7 @@ "unique_id": "ab:cd:ef:12:65:80:74:f3-1", "migrate_unique_ids": [], "platform": "climate", - "class_name": "ZONNSMARTThermostat", + "class_name": "ZonnsmartTV01Climate", "translation_key": "thermostat", "translation_placeholders": null, "device_class": null, diff --git a/tests/data/devices/tze200-sur6q7ko-ts0601-0x00000045.json b/tests/data/devices/tze200-sur6q7ko-ts0601-0x00000045.json index b97f7c835..9030c037b 100644 --- a/tests/data/devices/tze200-sur6q7ko-ts0601-0x00000045.json +++ b/tests/data/devices/tze200-sur6q7ko-ts0601-0x00000045.json @@ -8,7 +8,7 @@ "friendly_model": "TS0601", "name": "_TZE200_sur6q7ko TS0601", "quirk_applied": true, - "quirk_class": "zhaquirks.tuya.ts0601_trv:ZonnsmartTV01_ZG", + "quirk_class": "zhaquirks.tuya.ts0601_trv:(_TZE200_7yoranx2 / TS0601)", "exposes_features": [], "manufacturer_code": 4098, "power_source": "Battery or Unknown", @@ -561,7 +561,7 @@ "unique_id": "ab:cd:ef:12:a2:68:cb:79-1", "migrate_unique_ids": [], "platform": "climate", - "class_name": "Thermostat", + "class_name": "ZonnsmartTV01Climate", "translation_key": "thermostat", "translation_placeholders": null, "device_class": null, @@ -586,9 +586,14 @@ "fan_mode": "auto", "max_temp": 30.0, "min_temp": 5.0, - "supported_features": 385, + "supported_features": 401, "fan_modes": null, - "preset_modes": [], + "preset_modes": [ + "none", + "holiday", + "Schedule", + "frost protect" + ], "hvac_modes": [ "off", "heat" diff --git a/tests/data/devices/zehnder-group-vaux-andigny-alcantara2-d1-00p1-02z1-00.json b/tests/data/devices/zehnder-group-vaux-andigny-alcantara2-d1-00p1-02z1-00.json index d789aee98..9655d5536 100644 --- a/tests/data/devices/zehnder-group-vaux-andigny-alcantara2-d1-00p1-02z1-00.json +++ b/tests/data/devices/zehnder-group-vaux-andigny-alcantara2-d1-00p1-02z1-00.json @@ -7,8 +7,8 @@ "friendly_manufacturer": "ZEHNDER GROUP VAUX ANDIGNY ", "friendly_model": "ALCANTARA2 D1.00P1.02Z1.00", "name": "ZEHNDER GROUP VAUX ANDIGNY ALCANTARA2 D1.00P1.02Z1.00", - "quirk_applied": false, - "quirk_class": "zigpy.device.ZigbeeDevice", + "quirk_applied": true, + "quirk_class": "zhaquirks.zehnder.thermostat:(ZEHNDER GROUP VAUX ANDIGNY / None)", "exposes_features": [], "manufacturer_code": 4098, "power_source": "Mains", diff --git a/tests/data/devices/zen-within-zen-01-0x0000021f.json b/tests/data/devices/zen-within-zen-01-0x0000021f.json index 019a0df88..882574277 100644 --- a/tests/data/devices/zen-within-zen-01-0x0000021f.json +++ b/tests/data/devices/zen-within-zen-01-0x0000021f.json @@ -392,7 +392,7 @@ "unique_id": "ab:cd:ef:12:e9:5a:2c:fd-1", "migrate_unique_ids": [], "platform": "climate", - "class_name": "ZenWithinThermostat", + "class_name": "Thermostat", "translation_key": "thermostat", "translation_placeholders": null, "device_class": null, diff --git a/tests/test_climate.py b/tests/test_climate.py index 12df5b02a..780331ef8 100644 --- a/tests/test_climate.py +++ b/tests/test_climate.py @@ -35,7 +35,6 @@ from zha.application.const import ( PRESET_AWAY, PRESET_BOOST, - PRESET_NONE, PRESET_SCHEDULE, PRESET_TEMP_MANUAL, ) @@ -45,7 +44,6 @@ HVAC_MODE_2_SYSTEM, SEQ_OF_OPERATION, Thermostat as ThermostatEntity, - ZehnderThermostat, ) from zha.application.platforms.climate.const import SEQ_FAN_MODES, FanState, HVACMode from zha.application.platforms.number import NumberConfigurationEntity @@ -139,21 +137,6 @@ } } -CLIMATE_MOES = { - 1: { - SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID, - SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.THERMOSTAT, - SIG_EP_INPUT: [ - zigpy.zcl.clusters.general.Basic.cluster_id, - zigpy.zcl.clusters.general.Identify.cluster_id, - zigpy.zcl.clusters.hvac.Thermostat.cluster_id, - zigpy.zcl.clusters.hvac.UserInterface.cluster_id, - 61148, - ], - SIG_EP_OUTPUT: [zigpy.zcl.clusters.general.Ota.cluster_id], - } -} - CLIMATE_BECA = { 1: { SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID, @@ -171,26 +154,10 @@ } } -CLIMATE_ZONNSMART = { - 1: { - SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID, - SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.THERMOSTAT, - SIG_EP_INPUT: [ - zigpy.zcl.clusters.general.Basic.cluster_id, - zigpy.zcl.clusters.hvac.Thermostat.cluster_id, - zigpy.zcl.clusters.hvac.UserInterface.cluster_id, - 61148, - ], - SIG_EP_OUTPUT: [zigpy.zcl.clusters.general.Ota.cluster_id], - } -} - MANUF_SINOPE = "Sinope Technologies" MANUF_ZEN = "Zen Within" MANUF_ZEHNDER = "ZEHNDER GROUP VAUX ANDIGNY " -MANUF_MOES = "_TZE200_ckud7u2l" MANUF_BECA = "_TZE200_b6wax7g0" -MANUF_ZONNSMART = "_TZE200_hue3yfsn" ZCL_ATTR_PLUG = { "abs_min_heat_setpoint_limit": 800, @@ -573,56 +540,6 @@ async def test_climate_hvac_action_running_state_zehnder( assert entity.state.hvac_action == "idle" -@pytest.mark.parametrize( - "hvac_mode, sys_mode", - ( - ("heat", Thermostat.SystemMode.Auto), - ("off", Thermostat.SystemMode.Off), - ("heat_cool", None), - ), -) -async def test_set_hvac_mode_zehnder( - zha_gateway: Gateway, - hvac_mode, - sys_mode, -): - """Test setting hvac mode.""" - device_climate_zehnder = await device_climate_mock( - zha_gateway, CLIMATE_ZEHNDER, manuf=MANUF_ZEHNDER - ) - - thrm_cluster = device_climate_zehnder.device.endpoints[1].thermostat - entity: ThermostatEntity = get_entity( - device_climate_zehnder, platform=Platform.CLIMATE, entity_type=ZehnderThermostat - ) - - assert entity.state.hvac_mode == "off" - - await entity.async_set_hvac_mode(hvac_mode) - await zha_gateway.async_block_till_done() - - if sys_mode is not None: - assert entity.state.hvac_mode == hvac_mode - assert thrm_cluster.write_attributes.call_count == 1 - assert thrm_cluster.write_attributes.call_args[0][0] == { - "system_mode": sys_mode - } - else: - assert thrm_cluster.write_attributes.call_count == 0 - assert entity.state.hvac_mode == "off" - - # turn off - thrm_cluster.write_attributes.reset_mock() - await entity.async_set_hvac_mode("off") - await zha_gateway.async_block_till_done() - - assert entity.state.hvac_mode == "off" - assert thrm_cluster.write_attributes.call_count == 1 - assert thrm_cluster.write_attributes.call_args[0][0] == { - "system_mode": Thermostat.SystemMode.Off - } - - async def test_climate_hvac_action_pi_demand( zha_gateway: Gateway, ): @@ -1614,142 +1531,6 @@ async def test_fan_mode_smart_returns_none( assert entity.state.fan_mode is None -async def test_set_moes_preset(zha_gateway: Gateway): - """Test setting preset for moes trv.""" - - device_climate_moes = await device_climate_mock( - zha_gateway, - CLIMATE_MOES, - manuf=MANUF_MOES, - quirk=zhaquirks.tuya.ts0601_trv.MoesHY368_Type1, - ) - thrm_cluster = device_climate_moes.device.endpoints[1].thermostat - entity: ThermostatEntity = get_entity( - device_climate_moes, platform=Platform.CLIMATE, entity_type=ThermostatEntity - ) - - assert entity.state.preset_mode == "none" - - await entity.async_set_preset_mode("away") - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 1 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 0 - } - - thrm_cluster.write_attributes.reset_mock() - await entity.async_set_preset_mode("Schedule") - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 2 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 2 - } - assert thrm_cluster.write_attributes.call_args_list[1][0][0] == { - "operation_preset": 1 - } - - thrm_cluster.write_attributes.reset_mock() - await entity.async_set_preset_mode("comfort") - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 2 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 2 - } - assert thrm_cluster.write_attributes.call_args_list[1][0][0] == { - "operation_preset": 3 - } - - thrm_cluster.write_attributes.reset_mock() - await entity.async_set_preset_mode("eco") - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 2 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 2 - } - assert thrm_cluster.write_attributes.call_args_list[1][0][0] == { - "operation_preset": 4 - } - - thrm_cluster.write_attributes.reset_mock() - await entity.async_set_preset_mode("boost") - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 2 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 2 - } - assert thrm_cluster.write_attributes.call_args_list[1][0][0] == { - "operation_preset": 5 - } - - thrm_cluster.write_attributes.reset_mock() - await entity.async_set_preset_mode("Complex") - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 2 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 2 - } - assert thrm_cluster.write_attributes.call_args_list[1][0][0] == { - "operation_preset": 6 - } - - thrm_cluster.write_attributes.reset_mock() - await entity.async_set_preset_mode("none") - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 1 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 2 - } - - -async def test_set_moes_operation_mode(zha_gateway: Gateway): - """Test setting preset for moes trv.""" - device_climate_moes = await device_climate_mock( - zha_gateway, - CLIMATE_MOES, - manuf=MANUF_MOES, - quirk=zhaquirks.tuya.ts0601_trv.MoesHY368_Type1, - ) - thrm_cluster = device_climate_moes.device.endpoints[1].thermostat - entity: ThermostatEntity = get_entity( - device_climate_moes, platform=Platform.CLIMATE, entity_type=ThermostatEntity - ) - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 0}) - - assert entity.state.preset_mode == "away" - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 1}) - - assert entity.state.preset_mode == "Schedule" - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 2}) - - assert entity.state.preset_mode == "none" - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 3}) - - assert entity.state.preset_mode == "comfort" - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 4}) - - assert entity.state.preset_mode == "eco" - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 5}) - - assert entity.state.preset_mode == "boost" - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 6}) - - assert entity.state.preset_mode == "Complex" - - # Device is running an energy-saving mode PRESET_ECO = "eco" @@ -1800,102 +1581,6 @@ async def test_beca_operation_mode_update( ] -async def test_set_zonnsmart_preset(zha_gateway: Gateway) -> None: - """Test setting preset from homeassistant for zonnsmart trv.""" - device_climate_zonnsmart = await device_climate_mock( - zha_gateway, - CLIMATE_ZONNSMART, - manuf=MANUF_ZONNSMART, - quirk=zhaquirks.tuya.ts0601_trv.ZonnsmartTV01_ZG, - ) - thrm_cluster = device_climate_zonnsmart.device.endpoints[1].thermostat - entity: ThermostatEntity = get_entity( - device_climate_zonnsmart, - platform=Platform.CLIMATE, - entity_type=ThermostatEntity, - ) - - assert entity.state.preset_mode == PRESET_NONE - - await entity.async_set_preset_mode(PRESET_SCHEDULE) - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 1 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 0 - } - - thrm_cluster.write_attributes.reset_mock() - - await entity.async_set_preset_mode("holiday") - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 2 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 1 - } - assert thrm_cluster.write_attributes.call_args_list[1][0][0] == { - "operation_preset": 3 - } - - thrm_cluster.write_attributes.reset_mock() - await entity.async_set_preset_mode("frost protect") - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 2 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 1 - } - assert thrm_cluster.write_attributes.call_args_list[1][0][0] == { - "operation_preset": 4 - } - - thrm_cluster.write_attributes.reset_mock() - await entity.async_set_preset_mode(PRESET_NONE) - await zha_gateway.async_block_till_done() - - assert thrm_cluster.write_attributes.await_count == 1 - assert thrm_cluster.write_attributes.call_args_list[0][0][0] == { - "operation_preset": 1 - } - - -async def test_set_zonnsmart_operation_mode(zha_gateway: Gateway) -> None: - """Test setting preset from trv for zonnsmart trv.""" - device_climate_zonnsmart = await device_climate_mock( - zha_gateway, - CLIMATE_ZONNSMART, - manuf=MANUF_ZONNSMART, - quirk=zhaquirks.tuya.ts0601_trv.ZonnsmartTV01_ZG, - ) - thrm_cluster = device_climate_zonnsmart.device.endpoints[1].thermostat - entity: ThermostatEntity = get_entity( - device_climate_zonnsmart, - platform=Platform.CLIMATE, - entity_type=ThermostatEntity, - ) - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 0}) - - assert entity.state.preset_mode == PRESET_SCHEDULE - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 1}) - - assert entity.state.preset_mode == PRESET_NONE - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 2}) - - assert entity.state.preset_mode == "holiday" - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 3}) - - assert entity.state.preset_mode == "holiday" - - await send_attributes_report(zha_gateway, thrm_cluster, {"operation_preset": 4}) - - assert entity.state.preset_mode == "frost protect" - - async def test_thermostat_default_local_temperature_calibration_config( zha_gateway: Gateway, ) -> None: diff --git a/zha/application/platforms/climate/__init__.py b/zha/application/platforms/climate/__init__.py index a1cd7fda7..77b115c9a 100644 --- a/zha/application/platforms/climate/__init__.py +++ b/zha/application/platforms/climate/__init__.py @@ -1081,202 +1081,6 @@ async def async_preset_handler_away(self, is_away: bool = False) -> None: ) -@register_entity(ThermostatCluster.cluster_id) -class ZenWithinThermostat(Thermostat): - """Zen Within Thermostat implementation.""" - - _cluster_match = ClusterMatch( - server_clusters=frozenset({ThermostatCluster.cluster_id}), - optional_server_clusters=frozenset({FanCluster.cluster_id}), - manufacturers=frozenset({"Zen Within", "LUX"}), - feature_priority=(PlatformFeatureGroup.THERMOSTAT_FAN, 2), - ) - - -@register_entity(ThermostatCluster.cluster_id) -class ZehnderThermostat(Thermostat): - """Zehnder thermostat to adapt AUTO mode behavior.""" - - _cluster_match = ClusterMatch( - server_clusters=frozenset({ThermostatCluster.cluster_id}), - manufacturers=frozenset( - {"ZEHNDER GROUP VAUX ANDIGNY ", "ZEHNDER GROUP VAUX ANDIGNY"} - ), - feature_priority=(PlatformFeatureGroup.THERMOSTAT_FAN, 2), - ) - - ZEHNDER_HVAC_MODE_2_SYSTEM = { - HVACMode.OFF: SystemMode.Off, - HVACMode.HEAT: SystemMode.Auto, - } - - ZEHNDER_SYSTEM_MODE_2_HVAC = { - SystemMode.Off: HVACMode.OFF, - SystemMode.Auto: HVACMode.HEAT, - } - - hvac_modes = [HVACMode.OFF, HVACMode.HEAT] - - async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: - """Set new target operation mode.""" - if hvac_mode not in self.hvac_modes: - self.warning( - "can't set '%s' mode. Supported modes are: %s", - hvac_mode, - self.hvac_modes, - ) - return - - await write_attributes_safe( - self._cluster, - { - ThermostatCluster.AttributeDefs.system_mode.name: ZehnderThermostat.ZEHNDER_HVAC_MODE_2_SYSTEM[ - hvac_mode - ] - }, - ) - self.maybe_emit_state_changed_event() - - @property - def current_temperature(self): - """Force no current temperature.""" - return None - - @property - def system_mode_string(self) -> str | None: - """Return a formatted system mode string.""" - if self.hvac_mode is None: - return None - system_mode = ZehnderThermostat.ZEHNDER_SYSTEM_MODE_2_HVAC.get( - self._system_mode, "unknown" - ) - return f"[{self._system_mode}]/{system_mode}" - - @property - def hvac_mode(self) -> HVACMode | None: - """Return HVAC operation mode.""" - return ZehnderThermostat.ZEHNDER_SYSTEM_MODE_2_HVAC.get(self._system_mode) - - -@register_entity(ThermostatCluster.cluster_id) -class CentralitePearl(Thermostat): - """Centralite Pearl Thermostat implementation.""" - - _cluster_match = ClusterMatch( - server_clusters=frozenset({ThermostatCluster.cluster_id}), - optional_server_clusters=frozenset({FanCluster.cluster_id}), - manufacturers=frozenset({"Centralite"}), - models=frozenset({"3157100", "3157100-E"}), - feature_priority=(PlatformFeatureGroup.THERMOSTAT_FAN, 2), - ) - - -MOES_MANUFACTURERS = frozenset( - { - "_TZE200_ckud7u2l", - "_TZE200_ywdxldoj", - "_TZE200_cwnjrr72", - "_TZE200_2atgpdho", - "_TZE200_pvvbommb", - "_TZE200_4eeyebrt", - "_TZE200_cpmgn2cf", - "_TZE200_9sfg7gm0", - "_TZE200_8whxpsiw", - "_TYST11_ckud7u2l", - "_TYST11_ywdxldoj", - "_TYST11_cwnjrr72", - "_TYST11_2atgpdho", - } -) - - -@register_entity(ThermostatCluster.cluster_id) -class MoesThermostat(Thermostat): - """Moes Thermostat implementation.""" - - _cluster_match = ClusterMatch( - server_clusters=frozenset({ThermostatCluster.cluster_id}), - manufacturers=MOES_MANUFACTURERS, - feature_priority=(PlatformFeatureGroup.THERMOSTAT_FAN, 2), - ) - - def recompute_capabilities(self) -> None: - """Recompute capabilities and feature flags.""" - super().recompute_capabilities() - self._presets = [ - Preset.NONE, - Preset.AWAY, - Preset.SCHEDULE, - Preset.COMFORT, - Preset.ECO, - Preset.BOOST, - Preset.COMPLEX, - ] - self._supported_features |= ClimateEntityFeature.PRESET_MODE - - @functools.cached_property - def hvac_modes(self) -> list[HVACMode]: - """Return only the heat mode, because the device can't be turned off.""" - return [HVACMode.HEAT] - - def handle_attribute_updated( - self, - event: AttributeReadEvent - | AttributeReportedEvent - | AttributeUpdatedEvent - | AttributeWrittenEvent, - ) -> None: - """Handle attribute update from device.""" - if event.attribute_name == "operation_preset": - if event.value == 0: - self._preset = Preset.AWAY - if event.value == 1: - self._preset = Preset.SCHEDULE - if event.value == 2: - self._preset = Preset.NONE - if event.value == 3: - self._preset = Preset.COMFORT - if event.value == 4: - self._preset = Preset.ECO - if event.value == 5: - self._preset = Preset.BOOST - if event.value == 6: - self._preset = Preset.COMPLEX - super().handle_attribute_updated(event) - - async def async_preset_handler(self, preset: str, enable: bool = False) -> None: - """Set the preset mode.""" - mfg_code = self._device.manufacturer_code - if not enable: - return await write_attributes_safe( - self._cluster, {"operation_preset": 2}, manufacturer=mfg_code - ) - if preset == Preset.AWAY: - return await write_attributes_safe( - self._cluster, {"operation_preset": 0}, manufacturer=mfg_code - ) - if preset == Preset.SCHEDULE: - return await write_attributes_safe( - self._cluster, {"operation_preset": 1}, manufacturer=mfg_code - ) - if preset == Preset.COMFORT: - return await write_attributes_safe( - self._cluster, {"operation_preset": 3}, manufacturer=mfg_code - ) - if preset == Preset.ECO: - return await write_attributes_safe( - self._cluster, {"operation_preset": 4}, manufacturer=mfg_code - ) - if preset == Preset.BOOST: - return await write_attributes_safe( - self._cluster, {"operation_preset": 5}, manufacturer=mfg_code - ) - if preset == Preset.COMPLEX: - return await write_attributes_safe( - self._cluster, {"operation_preset": 6}, manufacturer=mfg_code - ) - - @register_entity(ThermostatCluster.cluster_id) class BecaThermostat(Thermostat): """Beca Thermostat implementation.""" @@ -1355,102 +1159,3 @@ async def async_preset_handler(self, preset: str, enable: bool = False) -> None: return await write_attributes_safe( self._cluster, {"operation_preset": 7}, manufacturer=mfg_code ) - - -@register_entity(ThermostatCluster.cluster_id) -class StelproFanHeater(Thermostat): - """Stelpro Fan Heater implementation.""" - - _cluster_match = ClusterMatch( - server_clusters=frozenset({ThermostatCluster.cluster_id}), - manufacturers=frozenset({"Stelpro"}), - models=frozenset({"SORB"}), - feature_priority=(PlatformFeatureGroup.THERMOSTAT_FAN, 2), - ) - - @functools.cached_property - def hvac_modes(self) -> list[HVACMode]: - """Return only the heat mode, because the device can't be turned off.""" - return [HVACMode.HEAT] - - -ZONNSMART_MANUFACTURERS = frozenset( - { - "_TZE200_7yoranx2", - "_TZE200_e9ba97vf", # TV01-ZG - "_TZE200_hue3yfsn", # TV02-ZG - "_TZE200_husqqvux", # TSL-TRV-TV01ZG - "_TZE200_kds0pmmv", # MOES TRV TV02 - "_TZE200_kly8gjlz", # TV05-ZG - "_TZE200_lnbfnyxd", - "_TZE200_mudxchsu", - } -) - - -@register_entity(ThermostatCluster.cluster_id) -class ZONNSMARTThermostat(Thermostat): - """ZONNSMART Thermostat implementation. - - Notice that this device uses two holiday presets (2: HolidayMode, - 3: HolidayModeTemp), but only one of them can be set. - """ - - PRESET_HOLIDAY = "holiday" - PRESET_FROST = "frost protect" - - _cluster_match = ClusterMatch( - server_clusters=frozenset({ThermostatCluster.cluster_id}), - manufacturers=ZONNSMART_MANUFACTURERS, - feature_priority=(PlatformFeatureGroup.THERMOSTAT_FAN, 2), - ) - - def recompute_capabilities(self) -> None: - """Recompute capabilities.""" - super().recompute_capabilities() - self._presets = [ - Preset.NONE, - self.PRESET_HOLIDAY, - Preset.SCHEDULE, - self.PRESET_FROST, - ] - self._supported_features |= ClimateEntityFeature.PRESET_MODE - - def handle_attribute_updated( - self, - event: AttributeReadEvent - | AttributeReportedEvent - | AttributeUpdatedEvent - | AttributeWrittenEvent, - ) -> None: - """Handle attribute update from device.""" - if event.attribute_name == "operation_preset": - if event.value == 0: - self._preset = Preset.SCHEDULE - if event.value == 1: - self._preset = Preset.NONE - if event.value in (2, 3): - self._preset = self.PRESET_HOLIDAY - if event.value == 4: - self._preset = self.PRESET_FROST - super().handle_attribute_updated(event) - - async def async_preset_handler(self, preset: str, enable: bool = False) -> None: - """Set the preset mode.""" - mfg_code = self._device.manufacturer_code - if not enable: - return await write_attributes_safe( - self._cluster, {"operation_preset": 1}, manufacturer=mfg_code - ) - if preset == Preset.SCHEDULE: - return await write_attributes_safe( - self._cluster, {"operation_preset": 0}, manufacturer=mfg_code - ) - if preset == self.PRESET_HOLIDAY: - return await write_attributes_safe( - self._cluster, {"operation_preset": 3}, manufacturer=mfg_code - ) - if preset == self.PRESET_FROST: - return await write_attributes_safe( - self._cluster, {"operation_preset": 4}, manufacturer=mfg_code - )