diff --git a/homeassistant/components/myneomitis/climate.py b/homeassistant/components/myneomitis/climate.py index 01c6771aa7f822..016e3c4732482e 100644 --- a/homeassistant/components/myneomitis/climate.py +++ b/homeassistant/components/myneomitis/climate.py @@ -93,7 +93,7 @@ def __init__(self, api: PyAxencoAPI, device: dict[str, Any]) -> None: state = device.get("state", {}) self._is_sub_device = model in SUPPORTED_SUB_MODELS - self._parents = device.get("parents") or {} + self._parents = device.get("parents") if model in PRESET_MODE_MODELS: self._attr_preset_modes = PRESET_MODE_MODELS[model] else: @@ -122,7 +122,7 @@ def __init__(self, api: PyAxencoAPI, device: dict[str, Any]) -> None: if self._attr_preset_mode and self._attr_preset_mode != "standby" else None ) - if model == "NTD" and state.get("changeOverUser") == 1: + if model == "NTD" and state.get("comfTemp") < state.get("ecoTemp"): self._attr_hvac_modes = [HVACMode.COOL, HVACMode.OFF] self._attr_hvac_mode = ( HVACMode.OFF @@ -315,7 +315,11 @@ async def _set_device_mode(self, mode: str) -> bool: return False if self._is_sub_device: - gateway = self._parents.get("gateway") + gateway = ( + self._parents.split(",")[1] + if isinstance(self._parents, str) + else None + ) rfid = self._device.get("rfid") if not gateway or not rfid: _LOGGER.error( @@ -336,7 +340,11 @@ async def _set_device_temperature(self, temperature: float) -> bool: """Set the device temperature via API.""" try: if self._is_sub_device: - gateway = self._parents.get("gateway") + gateway = ( + self._parents.split(",")[1] + if isinstance(self._parents, str) + else None + ) rfid = self._device.get("rfid") if not gateway or not rfid: _LOGGER.error( diff --git a/homeassistant/components/myneomitis/select.py b/homeassistant/components/myneomitis/select.py index 6ae7b6a0c79d45..78df9b5e10a08b 100644 --- a/homeassistant/components/myneomitis/select.py +++ b/homeassistant/components/myneomitis/select.py @@ -9,10 +9,12 @@ import logging from typing import Any +import aiohttp from pyaxencoapi import PyAxencoAPI from homeassistant.components.select import SelectEntity, SelectEntityDescription from homeassistant.core import HomeAssistant, callback +from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import device_registry as dr from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback @@ -141,6 +143,7 @@ def __init__( self.entity_description = description self._api = api self._device = device + self._parents = device.get("parents") self._attr_unique_id = device["_id"] self._attr_available = device["connected"] self._attr_device_info = dr.DeviceInfo( @@ -199,6 +202,29 @@ async def async_select_option(self, option: str) -> None: _LOGGER.warning("Unknown mode selected: %s", option) return - await self._api.set_device_mode(self._device["_id"], mode_code) + try: + if self._device["model"] in SUPPORTED_MODELS: + await self._api.set_device_mode(self._device["_id"], mode_code) + else: # UFH + gateway = ( + self._parents.split(",")[1] + if isinstance(self._parents, str) + else None + ) + rfid = self._device.get("rfid") + if not gateway or not rfid: + _LOGGER.error( + "Missing gateway or rfid for sub-device %s, cannot set mode", + self._attr_unique_id, + ) + raise HomeAssistantError(f"Failed to set mode for {self.entity_id}") + + await self._api.set_sub_device_mode_ufh(gateway, str(rfid), mode_code) + except (aiohttp.ClientError, TimeoutError, ConnectionError) as err: + _LOGGER.error("Error setting mode for %s: %s", self._device["_id"], err) + raise HomeAssistantError( + f"Failed to set mode for {self.entity_id}" + ) from err + self._attr_current_option = option self.async_write_ha_state() diff --git a/tests/components/myneomitis/test_climate.py b/tests/components/myneomitis/test_climate.py index 5c2cf0f054a1fa..c132430f615e32 100644 --- a/tests/components/myneomitis/test_climate.py +++ b/tests/components/myneomitis/test_climate.py @@ -37,12 +37,14 @@ "currentTemp": 19.0, "targetTemp": 20.0, "targetMode": 1, + "comfTemp": 20.0, + "ecoTemp": 16.5, "comfLimitMin": 7, "comfLimitMax": 30, "connected": True, }, "connected": True, - "parents": {"gateway": "gw-1"}, + "parents": ",gw-1,", "rfid": "rfid-1", "program": {"data": {}}, } @@ -55,13 +57,15 @@ "currentTemp": 20.0, "targetTemp": 21.0, "targetMode": 1, + "comfTemp": 26.0, + "ecoTemp": 28.0, "comfLimitMin": 7, "comfLimitMax": 30, "changeOverUser": 1, "connected": True, }, "connected": True, - "parents": {"gateway": "gw-ntd"}, + "parents": ",gw-ntd,", "rfid": "rfid-ntd", "program": {"data": {}}, } @@ -218,7 +222,7 @@ async def test_set_temperature_sub_device_missing_parents( mock_pyaxenco_client: AsyncMock, ) -> None: """Missing parents/rfid for sub-device should fail temperature set without API call.""" - bad_sub = {**CLIMATE_SUB_DEVICE, "parents": {}, "rfid": None} + bad_sub = {**CLIMATE_SUB_DEVICE, "parents": None, "rfid": None} mock_pyaxenco_client.get_devices.return_value = [bad_sub] mock_config_entry.add_to_hass(hass) @@ -403,7 +407,7 @@ async def test_ntd_changeover_sets_cool( mock_config_entry: MockConfigEntry, mock_pyaxenco_client: AsyncMock, ) -> None: - """NTD devices with changeOverUser==1 should expose COOL and OFF modes and start in COOL.""" + """NTD devices with comfTemp