Address late Airzone PR comments and fix Fahrenheit temperatures (#67904)
* airzone: address late PR comments Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> * airzone: fix fahrenheit temperatures Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> * airzone: add changes suggested by @MartinHjelmare Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
This commit is contained in:
parent
cc11562fa2
commit
542c3cbf90
8 changed files with 52 additions and 32 deletions
|
@ -2,6 +2,7 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from aioairzone.common import ConnectionOptions
|
from aioairzone.common import ConnectionOptions
|
||||||
|
from aioairzone.const import AZD_ZONES
|
||||||
from aioairzone.localapi_device import AirzoneLocalApi
|
from aioairzone.localapi_device import AirzoneLocalApi
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
@ -37,6 +38,15 @@ class AirzoneEntity(CoordinatorEntity):
|
||||||
}
|
}
|
||||||
self.system_zone_id = system_zone_id
|
self.system_zone_id = system_zone_id
|
||||||
|
|
||||||
|
def get_zone_value(self, key):
|
||||||
|
"""Return zone value by key."""
|
||||||
|
value = None
|
||||||
|
if self.system_zone_id in self.coordinator.data[AZD_ZONES]:
|
||||||
|
zone = self.coordinator.data[AZD_ZONES][self.system_zone_id]
|
||||||
|
if key in zone:
|
||||||
|
value = zone[key]
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
"""Set up Airzone from a config entry."""
|
"""Set up Airzone from a config entry."""
|
||||||
|
|
|
@ -34,14 +34,15 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
airzone = AirzoneLocalApi(
|
||||||
|
aiohttp_client.async_get_clientsession(self.hass),
|
||||||
|
ConnectionOptions(
|
||||||
|
user_input[CONF_HOST],
|
||||||
|
user_input[CONF_PORT],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
airzone = AirzoneLocalApi(
|
|
||||||
aiohttp_client.async_get_clientsession(self.hass),
|
|
||||||
ConnectionOptions(
|
|
||||||
user_input[CONF_HOST],
|
|
||||||
user_input[CONF_PORT],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
await airzone.validate_airzone()
|
await airzone.validate_airzone()
|
||||||
except (ClientConnectorError, InvalidHost):
|
except (ClientConnectorError, InvalidHost):
|
||||||
errors["base"] = "cannot_connect"
|
errors["base"] = "cannot_connect"
|
||||||
|
|
|
@ -2,8 +2,17 @@
|
||||||
|
|
||||||
from typing import Final
|
from typing import Final
|
||||||
|
|
||||||
|
from aioairzone.common import TemperatureUnit
|
||||||
|
|
||||||
|
from homeassistant.const import TEMP_CELSIUS, TEMP_FAHRENHEIT
|
||||||
|
|
||||||
DOMAIN: Final = "airzone"
|
DOMAIN: Final = "airzone"
|
||||||
MANUFACTURER: Final = "Airzone"
|
MANUFACTURER: Final = "Airzone"
|
||||||
|
|
||||||
AIOAIRZONE_DEVICE_TIMEOUT_SEC: Final = 10
|
AIOAIRZONE_DEVICE_TIMEOUT_SEC: Final = 10
|
||||||
DEFAULT_LOCAL_API_PORT: Final = 3000
|
DEFAULT_LOCAL_API_PORT: Final = 3000
|
||||||
|
|
||||||
|
TEMP_UNIT_LIB_TO_HASS: Final[dict[TemperatureUnit, str]] = {
|
||||||
|
TemperatureUnit.CELSIUS: TEMP_CELSIUS,
|
||||||
|
TemperatureUnit.FAHRENHEIT: TEMP_FAHRENHEIT,
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,6 @@ class AirzoneUpdateCoordinator(DataUpdateCoordinator):
|
||||||
async with async_timeout.timeout(AIOAIRZONE_DEVICE_TIMEOUT_SEC):
|
async with async_timeout.timeout(AIOAIRZONE_DEVICE_TIMEOUT_SEC):
|
||||||
try:
|
try:
|
||||||
await self.airzone.update_airzone()
|
await self.airzone.update_airzone()
|
||||||
return self.airzone.data()
|
|
||||||
except ClientConnectorError as error:
|
except ClientConnectorError as error:
|
||||||
raise UpdateFailed(error) from error
|
raise UpdateFailed(error) from error
|
||||||
|
return self.airzone.data()
|
||||||
|
|
|
@ -3,7 +3,7 @@ from __future__ import annotations
|
||||||
|
|
||||||
from typing import Final
|
from typing import Final
|
||||||
|
|
||||||
from aioairzone.const import AZD_HUMIDITY, AZD_NAME, AZD_TEMP, AZD_ZONES
|
from aioairzone.const import AZD_HUMIDITY, AZD_NAME, AZD_TEMP, AZD_TEMP_UNIT, AZD_ZONES
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
STATE_CLASS_MEASUREMENT,
|
STATE_CLASS_MEASUREMENT,
|
||||||
|
@ -21,7 +21,7 @@ from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
|
||||||
from . import AirzoneEntity
|
from . import AirzoneEntity
|
||||||
from .const import DOMAIN
|
from .const import DOMAIN, TEMP_UNIT_LIB_TO_HASS
|
||||||
from .coordinator import AirzoneUpdateCoordinator
|
from .coordinator import AirzoneUpdateCoordinator
|
||||||
|
|
||||||
SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = (
|
SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = (
|
||||||
|
@ -84,12 +84,12 @@ class AirzoneSensor(AirzoneEntity, SensorEntity):
|
||||||
self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}_{description.key}"
|
self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}_{description.key}"
|
||||||
self.entity_description = description
|
self.entity_description = description
|
||||||
|
|
||||||
|
if description.key == AZD_TEMP:
|
||||||
|
self._attr_native_unit_of_measurement = TEMP_UNIT_LIB_TO_HASS.get(
|
||||||
|
self.get_zone_value(AZD_TEMP_UNIT)
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def native_value(self):
|
def native_value(self):
|
||||||
"""Return the state."""
|
"""Return the state."""
|
||||||
value = None
|
return self.get_zone_value(self.entity_description.key)
|
||||||
if self.system_zone_id in self.coordinator.data[AZD_ZONES]:
|
|
||||||
zone = self.coordinator.data[AZD_ZONES][self.system_zone_id]
|
|
||||||
if self.entity_description.key in zone:
|
|
||||||
value = zone[self.entity_description.key]
|
|
||||||
return value
|
|
||||||
|
|
|
@ -53,13 +53,13 @@ async def test_form(hass):
|
||||||
async def test_form_duplicated_id(hass):
|
async def test_form_duplicated_id(hass):
|
||||||
"""Test setting up duplicated entry."""
|
"""Test setting up duplicated entry."""
|
||||||
|
|
||||||
|
entry = MockConfigEntry(domain=DOMAIN, data=CONFIG)
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"aioairzone.localapi_device.AirzoneLocalApi.get_hvac",
|
"aioairzone.localapi_device.AirzoneLocalApi.get_hvac",
|
||||||
return_value=HVAC_MOCK,
|
return_value=HVAC_MOCK,
|
||||||
):
|
):
|
||||||
entry = MockConfigEntry(domain=DOMAIN, data=CONFIG)
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
result = await hass.config_entries.flow.async_init(
|
||||||
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
|
DOMAIN, context={"source": SOURCE_USER}, data=CONFIG
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,15 +13,15 @@ from tests.common import MockConfigEntry
|
||||||
async def test_unload_entry(hass):
|
async def test_unload_entry(hass):
|
||||||
"""Test unload."""
|
"""Test unload."""
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(
|
||||||
|
domain=DOMAIN, unique_id="airzone_unique_id", data=CONFIG
|
||||||
|
)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"aioairzone.localapi_device.AirzoneLocalApi.get_hvac",
|
"aioairzone.localapi_device.AirzoneLocalApi.get_hvac",
|
||||||
return_value=HVAC_MOCK,
|
return_value=HVAC_MOCK,
|
||||||
):
|
):
|
||||||
config_entry = MockConfigEntry(
|
|
||||||
domain=DOMAIN, unique_id="airzone_unique_id", data=CONFIG
|
|
||||||
)
|
|
||||||
config_entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
assert config_entry.state is ConfigEntryState.LOADED
|
assert config_entry.state is ConfigEntryState.LOADED
|
||||||
|
|
|
@ -107,17 +107,17 @@ HVAC_MOCK = {
|
||||||
API_ZONE_ID: 4,
|
API_ZONE_ID: 4,
|
||||||
API_NAME: "Despacho",
|
API_NAME: "Despacho",
|
||||||
API_ON: 0,
|
API_ON: 0,
|
||||||
API_MAX_TEMP: 30,
|
API_MAX_TEMP: 86,
|
||||||
API_MIN_TEMP: 15,
|
API_MIN_TEMP: 59,
|
||||||
API_SET_POINT: 19.5,
|
API_SET_POINT: 67.1,
|
||||||
API_ROOM_TEMP: 21.2,
|
API_ROOM_TEMP: 70.16,
|
||||||
API_MODE: 3,
|
API_MODE: 3,
|
||||||
API_COLD_STAGES: 1,
|
API_COLD_STAGES: 1,
|
||||||
API_COLD_STAGE: 1,
|
API_COLD_STAGE: 1,
|
||||||
API_HEAT_STAGES: 1,
|
API_HEAT_STAGES: 1,
|
||||||
API_HEAT_STAGE: 1,
|
API_HEAT_STAGE: 1,
|
||||||
API_HUMIDITY: 36,
|
API_HUMIDITY: 36,
|
||||||
API_UNITS: 0,
|
API_UNITS: 1,
|
||||||
API_ERRORS: [],
|
API_ERRORS: [],
|
||||||
API_AIR_DEMAND: 0,
|
API_AIR_DEMAND: 0,
|
||||||
API_FLOOR_DEMAND: 0,
|
API_FLOOR_DEMAND: 0,
|
||||||
|
@ -153,12 +153,12 @@ async def async_init_integration(
|
||||||
):
|
):
|
||||||
"""Set up the Airzone integration in Home Assistant."""
|
"""Set up the Airzone integration in Home Assistant."""
|
||||||
|
|
||||||
|
entry = MockConfigEntry(domain=DOMAIN, data=CONFIG)
|
||||||
|
entry.add_to_hass(hass)
|
||||||
|
|
||||||
with patch(
|
with patch(
|
||||||
"aioairzone.localapi_device.AirzoneLocalApi.get_hvac",
|
"aioairzone.localapi_device.AirzoneLocalApi.get_hvac",
|
||||||
return_value=HVAC_MOCK,
|
return_value=HVAC_MOCK,
|
||||||
):
|
):
|
||||||
entry = MockConfigEntry(domain=DOMAIN, data=CONFIG)
|
|
||||||
entry.add_to_hass(hass)
|
|
||||||
|
|
||||||
await hass.config_entries.async_setup(entry.entry_id)
|
await hass.config_entries.async_setup(entry.entry_id)
|
||||||
await hass.async_block_till_done()
|
await hass.async_block_till_done()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue