diff --git a/.coveragerc b/.coveragerc index 04c9182e0df..d6809f4301d 100644 --- a/.coveragerc +++ b/.coveragerc @@ -144,6 +144,7 @@ omit = homeassistant/components/braviatv/coordinator.py homeassistant/components/braviatv/media_player.py homeassistant/components/braviatv/remote.py + homeassistant/components/broadlink/climate.py homeassistant/components/broadlink/light.py homeassistant/components/broadlink/remote.py homeassistant/components/broadlink/switch.py diff --git a/CODEOWNERS b/CODEOWNERS index 6321847b41a..20f0e67f74e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -170,8 +170,8 @@ build.json @home-assistant/supervisor /tests/components/bosch_shc/ @tschamm /homeassistant/components/braviatv/ @bieniu @Drafteed /tests/components/braviatv/ @bieniu @Drafteed -/homeassistant/components/broadlink/ @danielhiversen @felipediel @L-I-Am -/tests/components/broadlink/ @danielhiversen @felipediel @L-I-Am +/homeassistant/components/broadlink/ @danielhiversen @felipediel @L-I-Am @eifinger +/tests/components/broadlink/ @danielhiversen @felipediel @L-I-Am @eifinger /homeassistant/components/brother/ @bieniu /tests/components/brother/ @bieniu /homeassistant/components/brottsplatskartan/ @gjohansson-ST diff --git a/homeassistant/components/broadlink/climate.py b/homeassistant/components/broadlink/climate.py new file mode 100644 index 00000000000..6937d6bb0da --- /dev/null +++ b/homeassistant/components/broadlink/climate.py @@ -0,0 +1,85 @@ +"""Support for Broadlink climate devices.""" +from typing import Any + +from homeassistant.components.climate import ( + ATTR_TEMPERATURE, + ClimateEntity, + ClimateEntityFeature, + HVACAction, + HVACMode, +) +from homeassistant.config_entries import ConfigEntry +from homeassistant.const import PRECISION_HALVES, Platform, UnitOfTemperature +from homeassistant.core import HomeAssistant, callback +from homeassistant.helpers.entity_platform import AddEntitiesCallback + +from .const import DOMAIN, DOMAINS_AND_TYPES +from .device import BroadlinkDevice +from .entity import BroadlinkEntity + + +async def async_setup_entry( + hass: HomeAssistant, + config_entry: ConfigEntry, + async_add_entities: AddEntitiesCallback, +) -> None: + """Set up the Broadlink climate entities.""" + device = hass.data[DOMAIN].devices[config_entry.entry_id] + + if device.api.type in DOMAINS_AND_TYPES[Platform.CLIMATE]: + async_add_entities([BroadlinkThermostat(device)]) + + +class BroadlinkThermostat(ClimateEntity, BroadlinkEntity): + """Representation of a Broadlink Hysen climate entity.""" + + _attr_has_entity_name = True + _attr_hvac_modes = [HVACMode.HEAT, HVACMode.OFF, HVACMode.AUTO] + _attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE + _attr_target_temperature_step = PRECISION_HALVES + _attr_temperature_unit = UnitOfTemperature.CELSIUS + + def __init__(self, device: BroadlinkDevice) -> None: + """Initialize the climate entity.""" + super().__init__(device) + self._attr_unique_id = device.unique_id + self._attr_hvac_mode = None + + async def async_set_temperature(self, **kwargs: Any) -> None: + """Set new target temperature.""" + temperature = kwargs[ATTR_TEMPERATURE] + await self._device.async_request(self._device.api.set_temp, temperature) + self._attr_target_temperature = temperature + self.async_write_ha_state() + + @callback + def _update_state(self, data: dict[str, Any]) -> None: + """Update data.""" + if data.get("power"): + if data.get("auto_mode"): + self._attr_hvac_mode = HVACMode.AUTO + else: + self._attr_hvac_mode = HVACMode.HEAT + + if data.get("active"): + self._attr_hvac_action = HVACAction.HEATING + else: + self._attr_hvac_action = HVACAction.IDLE + else: + self._attr_hvac_mode = HVACMode.OFF + self._attr_hvac_action = HVACAction.OFF + + self._attr_current_temperature = data.get("room_temp") + self._attr_target_temperature = data.get("thermostat_temp") + + async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None: + """Set new target hvac mode.""" + if hvac_mode == HVACMode.OFF: + await self._device.async_request(self._device.api.set_power, 0) + else: + await self._device.async_request(self._device.api.set_power, 1) + mode = 0 if hvac_mode == HVACMode.HEAT else 1 + await self._device.async_request(self._device.api.set_mode, mode, 0) + + self._attr_hvac_mode = hvac_mode + self.async_write_ha_state() diff --git a/homeassistant/components/broadlink/const.py b/homeassistant/components/broadlink/const.py index c1ccc5ec954..2b9e8787a43 100644 --- a/homeassistant/components/broadlink/const.py +++ b/homeassistant/components/broadlink/const.py @@ -4,6 +4,7 @@ from homeassistant.const import Platform DOMAIN = "broadlink" DOMAINS_AND_TYPES = { + Platform.CLIMATE: {"HYS"}, Platform.REMOTE: {"RM4MINI", "RM4PRO", "RMMINI", "RMMINIB", "RMPRO"}, Platform.SENSOR: { "A1", diff --git a/homeassistant/components/broadlink/manifest.json b/homeassistant/components/broadlink/manifest.json index 5778520e530..7fd925a2ff4 100644 --- a/homeassistant/components/broadlink/manifest.json +++ b/homeassistant/components/broadlink/manifest.json @@ -1,7 +1,7 @@ { "domain": "broadlink", "name": "Broadlink", - "codeowners": ["@danielhiversen", "@felipediel", "@L-I-Am"], + "codeowners": ["@danielhiversen", "@felipediel", "@L-I-Am", "@eifinger"], "config_flow": true, "dhcp": [ { @@ -30,6 +30,9 @@ }, { "macaddress": "EC0BAE*" + }, + { + "macaddress": "780F77*" } ], "documentation": "https://www.home-assistant.io/integrations/broadlink", diff --git a/homeassistant/components/broadlink/updater.py b/homeassistant/components/broadlink/updater.py index da8461bf90f..10ac4df4bb8 100644 --- a/homeassistant/components/broadlink/updater.py +++ b/homeassistant/components/broadlink/updater.py @@ -16,6 +16,7 @@ def get_update_manager(device): update_managers = { "A1": BroadlinkA1UpdateManager, "BG1": BroadlinkBG1UpdateManager, + "HYS": BroadlinkThermostatUpdateManager, "LB1": BroadlinkLB1UpdateManager, "LB2": BroadlinkLB1UpdateManager, "MP1": BroadlinkMP1UpdateManager, @@ -184,3 +185,11 @@ class BroadlinkLB1UpdateManager(BroadlinkUpdateManager): async def async_fetch_data(self): """Fetch data from the device.""" return await self.device.async_request(self.device.api.get_state) + + +class BroadlinkThermostatUpdateManager(BroadlinkUpdateManager): + """Manages updates for thermostats with Broadlink DNA.""" + + async def async_fetch_data(self): + """Fetch data from the device.""" + return await self.device.async_request(self.device.api.get_full_status) diff --git a/homeassistant/generated/dhcp.py b/homeassistant/generated/dhcp.py index 63c7cd84303..6d04d7602f2 100644 --- a/homeassistant/generated/dhcp.py +++ b/homeassistant/generated/dhcp.py @@ -109,6 +109,10 @@ DHCP: list[dict[str, str | bool]] = [ "domain": "broadlink", "macaddress": "EC0BAE*", }, + { + "domain": "broadlink", + "macaddress": "780F77*", + }, { "domain": "dlink", "hostname": "dsp-w215",