From 5f3bec5a1d794d7af413fe5737c8aaa572901d81 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Thu, 14 Mar 2024 11:18:35 +0100 Subject: [PATCH] Add climate entity --- homeassistant/components/zha/climate.py | 68 ++++++++++++++++++++++- homeassistant/components/zha/icons.json | 18 ++++++ homeassistant/components/zha/strings.json | 24 ++++++-- 3 files changed, 105 insertions(+), 5 deletions(-) create mode 100644 homeassistant/components/zha/icons.json diff --git a/homeassistant/components/zha/climate.py b/homeassistant/components/zha/climate.py index 61c5f28ca8f41..f4d8bde486911 100644 --- a/homeassistant/components/zha/climate.py +++ b/homeassistant/components/zha/climate.py @@ -3,7 +3,6 @@ For more details on this platform, please refer to the documentation at https://home-assistant.io/components/zha.climate/ """ - from __future__ import annotations from datetime import datetime, timedelta @@ -823,3 +822,70 @@ async def async_preset_handler(self, preset: str, enable: bool = False) -> None: return await self._thrm.write_attributes_safe( {"operation_preset": 4}, manufacturer=mfg_code ) + + +@MULTI_MATCH( + cluster_handler_names={CLUSTER_HANDLER_THERMOSTAT, "cable_outlet_cluster"}, + stop_on_match_group=CLUSTER_HANDLER_THERMOSTAT, +) +class LegrandCableOutletThermostat(Thermostat): + """Legrand Cable outlet Thermostat implementation.""" + + _attr_translation_key = "legrand_thermostat" + + PRESET_COMFORT_MINUS_1 = "comfort_minus_1" + PRESET_COMFORT_MINUS_2 = "comfort_minus_2" + PRESET_FROST_PROTECTION = "frost_protection" + PRESET_OFF = "off" + + OPERATION_PRESET_TO_PRESET = { + 0: PRESET_COMFORT, + 1: PRESET_COMFORT_MINUS_1, + 2: PRESET_COMFORT_MINUS_2, + 3: PRESET_ECO, + 4: PRESET_FROST_PROTECTION, + 5: PRESET_OFF, + } + + PRESET_TO_OPERATION_PRESET = { + PRESET_COMFORT: 0, + PRESET_COMFORT_MINUS_1: 1, + PRESET_COMFORT_MINUS_2: 2, + PRESET_ECO: 3, + PRESET_FROST_PROTECTION: 4, + PRESET_OFF: 5, + } + + def __init__(self, unique_id, zha_device, cluster_handlers, **kwargs): + """Initialize ZHA Thermostat instance.""" + super().__init__(unique_id, zha_device, cluster_handlers, **kwargs) + self._presets = [ + PRESET_COMFORT, + self.PRESET_COMFORT_MINUS_1, + self.PRESET_COMFORT_MINUS_2, + PRESET_ECO, + self.PRESET_FROST_PROTECTION, + self.PRESET_OFF, + ] + self._supported_flags |= ClimateEntityFeature.PRESET_MODE + + @property + def current_temperature(self): + """Return the current temperature.""" + + return None + + async def async_attribute_updated(self, attr_id, attr_name, value): + """Handle attribute update from device.""" + if attr_name == "operation_preset": + self._preset = self.OPERATION_PRESET_TO_PRESET.get(value, self.PRESET_OFF) + await super().async_attribute_updated(attr_id, attr_name, value) + + async def async_preset_handler(self, preset: str, enable: bool = False) -> None: + """Set the preset mode.""" + mfg_code = self._zha_device.manufacturer_code + operation_preset = self.PRESET_TO_OPERATION_PRESET.get(preset) + if operation_preset is not None: + return await self._thrm.write_attributes_safe( + {"operation_preset": operation_preset}, manufacturer=mfg_code + ) diff --git a/homeassistant/components/zha/icons.json b/homeassistant/components/zha/icons.json new file mode 100644 index 0000000000000..6be95068e7821 --- /dev/null +++ b/homeassistant/components/zha/icons.json @@ -0,0 +1,18 @@ +{ + "entity": { + "climate": { + "legrand_thermostat": { + "state_attributes": { + "preset_mode": { + "state": { + "comfort_minus_1": "mdi:numeric-1-circle", + "comfort_minus_2": "mdi:numeric-2-circle", + "frost_protection": "mdi:snowflake-thermometer", + "off": "mdi:power" + } + } + } + } + } + } +} diff --git a/homeassistant/components/zha/strings.json b/homeassistant/components/zha/strings.json index e5c52dc4d9b1c..c56615d2a7dc8 100644 --- a/homeassistant/components/zha/strings.json +++ b/homeassistant/components/zha/strings.json @@ -588,6 +588,19 @@ "climate": { "thermostat": { "name": "[%key:component::climate::entity_component::_::name%]" + }, + "legrand_thermostat": { + "name": "[%key:component::climate::entity_component::_::name%]", + "state_attributes": { + "preset_mode": { + "state": { + "comfort_minus_1": "Comfort -1 °C", + "comfort_minus_2": "Comfort -2 °C", + "frost_protection": "Frost protection", + "off": "[%key:common::state::off%]" + } + } + } } }, "cover": { @@ -997,11 +1010,14 @@ "linkage_alarm": { "name": "Linkage alarm" }, - "buzzer_manual_mute": { - "name": "Buzzer manual mute" + "led_dark": { + "name": "Led dark" + }, + "led_on": { + "name": "Led on" }, - "buzzer_manual_alarm": { - "name": "Buzzer manual alarm" + "wire_pilot_enabled": { + "name": "Wire pilot mode" } } }