Rewrite Atag (#35496)

* rewrite library

* Update strings.json

* fix updated with empty reply

* dont use entity_id

* atag_id

* use super init instead

* original ids to prevent breaking change
This commit is contained in:
MatsNl 2020-05-12 11:47:33 +02:00 committed by GitHub
parent 86b984b0bd
commit 4099815a08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 112 additions and 173 deletions

View File

@ -3,24 +3,12 @@ from datetime import timedelta
import logging import logging
import async_timeout import async_timeout
from pyatag import AtagDataStore, AtagException from pyatag import AtagException, AtagOne
from homeassistant.components.climate import DOMAIN as CLIMATE from homeassistant.components.climate import DOMAIN as CLIMATE
from homeassistant.components.sensor import DOMAIN as SENSOR from homeassistant.components.sensor import DOMAIN as SENSOR
from homeassistant.components.water_heater import DOMAIN as WATER_HEATER from homeassistant.components.water_heater import DOMAIN as WATER_HEATER
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_ICON,
ATTR_ID,
ATTR_MODE,
ATTR_NAME,
ATTR_UNIT_OF_MEASUREMENT,
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_TEMPERATURE,
PRESSURE_BAR,
TEMP_CELSIUS,
)
from homeassistant.core import HomeAssistant, asyncio from homeassistant.core import HomeAssistant, asyncio
from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.exceptions import ConfigEntryNotReady
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
@ -30,94 +18,7 @@ from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, Upda
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DOMAIN = "atag" DOMAIN = "atag"
DATA_LISTENER = f"{DOMAIN}_listener"
SIGNAL_UPDATE_ATAG = f"{DOMAIN}_update"
PLATFORMS = [CLIMATE, WATER_HEATER, SENSOR] PLATFORMS = [CLIMATE, WATER_HEATER, SENSOR]
HOUR = "h"
FIRE = "fire"
PERCENTAGE = "%"
ICONS = {
TEMP_CELSIUS: "mdi:thermometer",
PRESSURE_BAR: "mdi:gauge",
FIRE: "mdi:fire",
ATTR_MODE: "mdi:settings",
}
ENTITY_TYPES = {
SENSOR: [
{
ATTR_NAME: "Outside Temperature",
ATTR_ID: "outside_temp",
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: ICONS[TEMP_CELSIUS],
},
{
ATTR_NAME: "Average Outside Temperature",
ATTR_ID: "tout_avg",
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: ICONS[TEMP_CELSIUS],
},
{
ATTR_NAME: "Weather Status",
ATTR_ID: "weather_status",
ATTR_UNIT_OF_MEASUREMENT: None,
ATTR_DEVICE_CLASS: None,
ATTR_ICON: None,
},
{
ATTR_NAME: "CH Water Pressure",
ATTR_ID: "ch_water_pres",
ATTR_UNIT_OF_MEASUREMENT: PRESSURE_BAR,
ATTR_DEVICE_CLASS: DEVICE_CLASS_PRESSURE,
ATTR_ICON: ICONS[PRESSURE_BAR],
},
{
ATTR_NAME: "CH Water Temperature",
ATTR_ID: "ch_water_temp",
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: ICONS[TEMP_CELSIUS],
},
{
ATTR_NAME: "CH Return Temperature",
ATTR_ID: "ch_return_temp",
ATTR_UNIT_OF_MEASUREMENT: TEMP_CELSIUS,
ATTR_DEVICE_CLASS: DEVICE_CLASS_TEMPERATURE,
ATTR_ICON: ICONS[TEMP_CELSIUS],
},
{
ATTR_NAME: "Burning Hours",
ATTR_ID: "burning_hours",
ATTR_UNIT_OF_MEASUREMENT: HOUR,
ATTR_DEVICE_CLASS: None,
ATTR_ICON: ICONS[FIRE],
},
{
ATTR_NAME: "Flame",
ATTR_ID: "rel_mod_level",
ATTR_UNIT_OF_MEASUREMENT: PERCENTAGE,
ATTR_DEVICE_CLASS: None,
ATTR_ICON: ICONS[FIRE],
},
],
CLIMATE: {
ATTR_NAME: DOMAIN.title(),
ATTR_ID: CLIMATE,
ATTR_UNIT_OF_MEASUREMENT: None,
ATTR_DEVICE_CLASS: None,
ATTR_ICON: None,
},
WATER_HEATER: {
ATTR_NAME: DOMAIN.title(),
ATTR_ID: WATER_HEATER,
ATTR_UNIT_OF_MEASUREMENT: None,
ATTR_DEVICE_CLASS: None,
ATTR_ICON: None,
},
}
async def async_setup(hass: HomeAssistant, config): async def async_setup(hass: HomeAssistant, config):
@ -130,8 +31,10 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
session = async_get_clientsession(hass) session = async_get_clientsession(hass)
coordinator = AtagDataUpdateCoordinator(hass, session, entry) coordinator = AtagDataUpdateCoordinator(hass, session, entry)
try:
await coordinator.async_refresh() await coordinator.async_refresh()
except AtagException:
raise ConfigEntryNotReady
if not coordinator.last_update_success: if not coordinator.last_update_success:
raise ConfigEntryNotReady raise ConfigEntryNotReady
@ -152,7 +55,7 @@ class AtagDataUpdateCoordinator(DataUpdateCoordinator):
def __init__(self, hass, session, entry): def __init__(self, hass, session, entry):
"""Initialize.""" """Initialize."""
self.atag = AtagDataStore(session, paired=True, **entry.data) self.atag = AtagOne(session=session, **entry.data)
super().__init__( super().__init__(
hass, _LOGGER, name=DOMAIN, update_interval=timedelta(seconds=30) hass, _LOGGER, name=DOMAIN, update_interval=timedelta(seconds=30)
@ -162,12 +65,12 @@ class AtagDataUpdateCoordinator(DataUpdateCoordinator):
"""Update data via library.""" """Update data via library."""
with async_timeout.timeout(20): with async_timeout.timeout(20):
try: try:
await self.atag.async_update() await self.atag.update()
if not self.atag.sensordata: if not self.atag.report:
raise UpdateFailed("No data") raise UpdateFailed("No data")
except (AtagException) as error: except AtagException as error:
raise UpdateFailed(error) raise UpdateFailed(error)
return self.atag.sensordata return self.atag.report
async def async_unload_entry(hass, entry): async def async_unload_entry(hass, entry):
@ -188,24 +91,21 @@ async def async_unload_entry(hass, entry):
class AtagEntity(Entity): class AtagEntity(Entity):
"""Defines a base Atag entity.""" """Defines a base Atag entity."""
def __init__(self, coordinator: AtagDataUpdateCoordinator, atag_type: dict) -> None: def __init__(self, coordinator: AtagDataUpdateCoordinator, atag_id: str) -> None:
"""Initialize the Atag entity.""" """Initialize the Atag entity."""
self.coordinator = coordinator self.coordinator = coordinator
self._id = atag_type[ATTR_ID] self._id = atag_id
self._name = atag_type[ATTR_NAME] self._name = DOMAIN.title()
self._icon = atag_type[ATTR_ICON]
self._unit = atag_type[ATTR_UNIT_OF_MEASUREMENT]
self._class = atag_type[ATTR_DEVICE_CLASS]
@property @property
def device_info(self) -> dict: def device_info(self) -> dict:
"""Return info for device registry.""" """Return info for device registry."""
device = self.coordinator.atag.device device = self.coordinator.atag.id
version = self.coordinator.atag.apiversion version = self.coordinator.atag.apiversion
return { return {
"identifiers": {(DOMAIN, device)}, "identifiers": {(DOMAIN, device)},
ATTR_NAME: "Atag Thermostat", "name": "Atag Thermostat",
"model": "Atag One", "model": "Atag One",
"sw_version": version, "sw_version": version,
"manufacturer": "Atag", "manufacturer": "Atag",
@ -216,14 +116,6 @@ class AtagEntity(Entity):
"""Return the name of the entity.""" """Return the name of the entity."""
return self._name return self._name
@property
def icon(self) -> str:
"""Return the mdi icon of the entity."""
self._icon = (
self.coordinator.data.get(self._id, {}).get(ATTR_ICON) or self._icon
)
return self._icon
@property @property
def should_poll(self) -> bool: def should_poll(self) -> bool:
"""Return the polling requirement of the entity.""" """Return the polling requirement of the entity."""
@ -232,12 +124,7 @@ class AtagEntity(Entity):
@property @property
def unit_of_measurement(self): def unit_of_measurement(self):
"""Return the unit of measurement of this entity, if any.""" """Return the unit of measurement of this entity, if any."""
return self._unit return self.coordinator.atag.climate.temp_unit
@property
def device_class(self):
"""Return the device class."""
return self._class
@property @property
def available(self): def available(self):
@ -247,7 +134,7 @@ class AtagEntity(Entity):
@property @property
def unique_id(self): def unique_id(self):
"""Return a unique ID to use for this entity.""" """Return a unique ID to use for this entity."""
return f"{self.coordinator.atag.device}-{self._id}" return f"{self.coordinator.atag.id}-{self._id}"
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Connect to dispatcher listening for entity data notifications.""" """Connect to dispatcher listening for entity data notifications."""

View File

@ -1,7 +1,7 @@
"""Initialization of ATAG One climate platform.""" """Initialization of ATAG One climate platform."""
from typing import List, Optional from typing import List, Optional
from homeassistant.components.climate import ClimateDevice from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
CURRENT_HVAC_HEAT, CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE, CURRENT_HVAC_IDLE,
@ -14,7 +14,7 @@ from homeassistant.components.climate.const import (
) )
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS, TEMP_FAHRENHEIT
from . import CLIMATE, DOMAIN, ENTITY_TYPES, AtagEntity from . import CLIMATE, DOMAIN, AtagEntity
PRESET_SCHEDULE = "Auto" PRESET_SCHEDULE = "Auto"
PRESET_MANUAL = "Manual" PRESET_MANUAL = "Manual"
@ -33,10 +33,10 @@ HVAC_MODES = [HVAC_MODE_AUTO, HVAC_MODE_HEAT]
async def async_setup_entry(hass, entry, async_add_entities): async def async_setup_entry(hass, entry, async_add_entities):
"""Load a config entry.""" """Load a config entry."""
coordinator = hass.data[DOMAIN][entry.entry_id] coordinator = hass.data[DOMAIN][entry.entry_id]
async_add_entities([AtagThermostat(coordinator, ENTITY_TYPES[CLIMATE])]) async_add_entities([AtagThermostat(coordinator, CLIMATE)])
class AtagThermostat(AtagEntity, ClimateDevice): class AtagThermostat(AtagEntity, ClimateEntity):
"""Atag climate device.""" """Atag climate device."""
@property @property
@ -47,8 +47,8 @@ class AtagThermostat(AtagEntity, ClimateDevice):
@property @property
def hvac_mode(self) -> Optional[str]: def hvac_mode(self) -> Optional[str]:
"""Return hvac operation ie. heat, cool mode.""" """Return hvac operation ie. heat, cool mode."""
if self.coordinator.atag.hvac_mode in HVAC_MODES: if self.coordinator.atag.climate.hvac_mode in HVAC_MODES:
return self.coordinator.atag.hvac_mode return self.coordinator.atag.climate.hvac_mode
return None return None
@property @property
@ -59,31 +59,31 @@ class AtagThermostat(AtagEntity, ClimateDevice):
@property @property
def hvac_action(self) -> Optional[str]: def hvac_action(self) -> Optional[str]:
"""Return the current running hvac operation.""" """Return the current running hvac operation."""
if self.coordinator.atag.cv_status: if self.coordinator.atag.climate.status:
return CURRENT_HVAC_HEAT return CURRENT_HVAC_HEAT
return CURRENT_HVAC_IDLE return CURRENT_HVAC_IDLE
@property @property
def temperature_unit(self): def temperature_unit(self):
"""Return the unit of measurement.""" """Return the unit of measurement."""
if self.coordinator.atag.temp_unit in [TEMP_CELSIUS, TEMP_FAHRENHEIT]: if self.coordinator.atag.climate.temp_unit in [TEMP_CELSIUS, TEMP_FAHRENHEIT]:
return self.coordinator.atag.temp_unit return self.coordinator.atag.climate.temp_unit
return None return None
@property @property
def current_temperature(self) -> Optional[float]: def current_temperature(self) -> Optional[float]:
"""Return the current temperature.""" """Return the current temperature."""
return self.coordinator.atag.temperature return self.coordinator.atag.climate.temperature
@property @property
def target_temperature(self) -> Optional[float]: def target_temperature(self) -> Optional[float]:
"""Return the temperature we try to reach.""" """Return the temperature we try to reach."""
return self.coordinator.atag.target_temperature return self.coordinator.atag.climate.target_temperature
@property @property
def preset_mode(self) -> Optional[str]: def preset_mode(self) -> Optional[str]:
"""Return the current preset mode, e.g., auto, manual, fireplace, extend, etc.""" """Return the current preset mode, e.g., auto, manual, fireplace, extend, etc."""
return self.coordinator.atag.hold_mode return self.coordinator.atag.climate.preset_mode
@property @property
def preset_modes(self) -> Optional[List[str]]: def preset_modes(self) -> Optional[List[str]]:
@ -92,15 +92,15 @@ class AtagThermostat(AtagEntity, ClimateDevice):
async def async_set_temperature(self, **kwargs) -> None: async def async_set_temperature(self, **kwargs) -> None:
"""Set new target temperature.""" """Set new target temperature."""
await self.coordinator.atag.set_temp(kwargs.get(ATTR_TEMPERATURE)) await self.coordinator.atag.climate.set_temp(kwargs.get(ATTR_TEMPERATURE))
self.async_write_ha_state() self.async_write_ha_state()
async def async_set_hvac_mode(self, hvac_mode: str) -> None: async def async_set_hvac_mode(self, hvac_mode: str) -> None:
"""Set new target hvac mode.""" """Set new target hvac mode."""
await self.coordinator.atag.set_hvac_mode(hvac_mode) await self.coordinator.atag.climate.set_hvac_mode(hvac_mode)
self.async_write_ha_state() self.async_write_ha_state()
async def async_set_preset_mode(self, preset_mode: str) -> None: async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set new preset mode.""" """Set new preset mode."""
await self.coordinator.atag.set_hold_mode(preset_mode) await self.coordinator.atag.climate.set_preset_mode(preset_mode)
self.async_write_ha_state() self.async_write_ha_state()

View File

@ -1,9 +1,9 @@
"""Config flow for the Atag component.""" """Config flow for the Atag component."""
from pyatag import DEFAULT_PORT, AtagDataStore, AtagException from pyatag import DEFAULT_PORT, AtagException, AtagOne
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.const import CONF_DEVICE, CONF_HOST, CONF_PORT from homeassistant.const import CONF_DEVICE, CONF_EMAIL, CONF_HOST, CONF_PORT
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.aiohttp_client import async_get_clientsession
@ -11,6 +11,7 @@ from . import DOMAIN # pylint: disable=unused-import
DATA_SCHEMA = { DATA_SCHEMA = {
vol.Required(CONF_HOST): str, vol.Required(CONF_HOST): str,
vol.Optional(CONF_EMAIL): str,
vol.Required(CONF_PORT, default=DEFAULT_PORT): vol.Coerce(int), vol.Required(CONF_PORT, default=DEFAULT_PORT): vol.Coerce(int),
} }
@ -31,14 +32,15 @@ class AtagConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return await self._show_form() return await self._show_form()
session = async_get_clientsession(self.hass) session = async_get_clientsession(self.hass)
try: try:
atag = AtagDataStore(session, **user_input) atag = AtagOne(session=session, **user_input)
await atag.async_check_pair_status() await atag.authorize()
await atag.update(force=True)
except AtagException: except AtagException:
return await self._show_form({"base": "connection_error"}) return await self._show_form({"base": "connection_error"})
user_input.update({CONF_DEVICE: atag.device}) user_input.update({CONF_DEVICE: atag.id})
return self.async_create_entry(title=atag.device, data=user_input) return self.async_create_entry(title=atag.id, data=user_input)
@callback @callback
async def _show_form(self, errors=None): async def _show_form(self, errors=None):

View File

@ -3,6 +3,6 @@
"name": "Atag", "name": "Atag",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/atag/", "documentation": "https://www.home-assistant.io/integrations/atag/",
"requirements": ["pyatag==0.2.19"], "requirements": ["pyatag==0.3.1.1"],
"codeowners": ["@MatsNL"] "codeowners": ["@MatsNL"]
} }

View File

@ -1,14 +1,31 @@
"""Initialization of ATAG One sensor platform.""" """Initialization of ATAG One sensor platform."""
from homeassistant.const import ATTR_STATE from homeassistant.const import (
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_TEMPERATURE,
PRESSURE_BAR,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
)
from . import DOMAIN, ENTITY_TYPES, SENSOR, AtagEntity from . import DOMAIN, AtagEntity
SENSORS = {
"Outside Temperature": "outside_temp",
"Average Outside Temperature": "tout_avg",
"Weather Status": "weather_status",
"CH Water Pressure": "ch_water_pres",
"CH Water Temperature": "ch_water_temp",
"CH Return Temperature": "ch_return_temp",
"Burning Hours": "burning_hours",
"Flame": "rel_mod_level",
}
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Initialize sensor platform from config entry.""" """Initialize sensor platform from config entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id] coordinator = hass.data[DOMAIN][config_entry.entry_id]
entities = [] entities = []
for sensor in ENTITY_TYPES[SENSOR]: for sensor in SENSORS:
entities.append(AtagSensor(coordinator, sensor)) entities.append(AtagSensor(coordinator, sensor))
async_add_entities(entities) async_add_entities(entities)
@ -16,7 +33,38 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
class AtagSensor(AtagEntity): class AtagSensor(AtagEntity):
"""Representation of a AtagOne Sensor.""" """Representation of a AtagOne Sensor."""
def __init__(self, coordinator, sensor):
"""Initialize Atag sensor."""
super().__init__(coordinator, SENSORS[sensor])
self._name = sensor
@property @property
def state(self): def state(self):
"""Return the state of the sensor.""" """Return the state of the sensor."""
return self.coordinator.data[self._id][ATTR_STATE] return self.coordinator.data[self._id].state
@property
def icon(self):
"""Return icon."""
return self.coordinator.data[self._id].icon
@property
def device_class(self):
"""Return deviceclass."""
if self.coordinator.data[self._id].sensorclass in [
DEVICE_CLASS_PRESSURE,
DEVICE_CLASS_TEMPERATURE,
]:
return self.coordinator.data[self._id].sensorclass
return None
@property
def unit_of_measurement(self):
"""Return measure."""
if self.coordinator.data[self._id].measure in [
PRESSURE_BAR,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
]:
return self.coordinator.data[self._id].measure
return None

View File

@ -6,6 +6,7 @@
"title": "Connect to the device", "title": "Connect to the device",
"data": { "data": {
"host": "Host", "host": "Host",
"email": "Email (Optional)",
"port": "Port (10000)" "port": "Port (10000)"
} }
} }

View File

@ -3,11 +3,11 @@ from homeassistant.components.water_heater import (
ATTR_TEMPERATURE, ATTR_TEMPERATURE,
STATE_ECO, STATE_ECO,
STATE_PERFORMANCE, STATE_PERFORMANCE,
WaterHeaterDevice, WaterHeaterEntity,
) )
from homeassistant.const import STATE_OFF, TEMP_CELSIUS from homeassistant.const import STATE_OFF, TEMP_CELSIUS
from . import DOMAIN, ENTITY_TYPES, WATER_HEATER, AtagEntity from . import DOMAIN, WATER_HEATER, AtagEntity
SUPPORT_FLAGS_HEATER = 0 SUPPORT_FLAGS_HEATER = 0
OPERATION_LIST = [STATE_OFF, STATE_ECO, STATE_PERFORMANCE] OPERATION_LIST = [STATE_OFF, STATE_ECO, STATE_PERFORMANCE]
@ -16,10 +16,10 @@ OPERATION_LIST = [STATE_OFF, STATE_ECO, STATE_PERFORMANCE]
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Initialize DHW device from config entry.""" """Initialize DHW device from config entry."""
coordinator = hass.data[DOMAIN][config_entry.entry_id] coordinator = hass.data[DOMAIN][config_entry.entry_id]
async_add_entities([AtagWaterHeater(coordinator, ENTITY_TYPES[WATER_HEATER])]) async_add_entities([AtagWaterHeater(coordinator, WATER_HEATER)])
class AtagWaterHeater(AtagEntity, WaterHeaterDevice): class AtagWaterHeater(AtagEntity, WaterHeaterEntity):
"""Representation of an ATAG water heater.""" """Representation of an ATAG water heater."""
@property @property
@ -35,12 +35,12 @@ class AtagWaterHeater(AtagEntity, WaterHeaterDevice):
@property @property
def current_temperature(self): def current_temperature(self):
"""Return the current temperature.""" """Return the current temperature."""
return self.coordinator.atag.dhw_temperature return self.coordinator.atag.dhw.temperature
@property @property
def current_operation(self): def current_operation(self):
"""Return current operation.""" """Return current operation."""
if self.coordinator.atag.dhw_status: if self.coordinator.atag.dhw.status:
return STATE_PERFORMANCE return STATE_PERFORMANCE
return STATE_OFF return STATE_OFF
@ -51,20 +51,20 @@ class AtagWaterHeater(AtagEntity, WaterHeaterDevice):
async def async_set_temperature(self, **kwargs): async def async_set_temperature(self, **kwargs):
"""Set new target temperature.""" """Set new target temperature."""
if await self.coordinator.atag.dhw_set_temp(kwargs.get(ATTR_TEMPERATURE)): if await self.coordinator.atag.dhw.set_temp(kwargs.get(ATTR_TEMPERATURE)):
self.async_write_ha_state() self.async_write_ha_state()
@property @property
def target_temperature(self): def target_temperature(self):
"""Return the setpoint if water demand, otherwise return base temp (comfort level).""" """Return the setpoint if water demand, otherwise return base temp (comfort level)."""
return self.coordinator.atag.dhw_target_temperature return self.coordinator.atag.dhw.target_temperature
@property @property
def max_temp(self): def max_temp(self):
"""Return the maximum temperature.""" """Return the maximum temperature."""
return self.coordinator.atag.dhw_max_temp return self.coordinator.atag.dhw.max_temp
@property @property
def min_temp(self): def min_temp(self):
"""Return the minimum temperature.""" """Return the minimum temperature."""
return self.coordinator.atag.dhw_min_temp return self.coordinator.atag.dhw.min_temp

View File

@ -1212,7 +1212,7 @@ pyalmond==0.0.2
pyarlo==0.2.3 pyarlo==0.2.3
# homeassistant.components.atag # homeassistant.components.atag
pyatag==0.2.19 pyatag==0.3.1.1
# homeassistant.components.netatmo # homeassistant.components.netatmo
pyatmo==3.3.1 pyatmo==3.3.1

View File

@ -515,7 +515,7 @@ pyalmond==0.0.2
pyarlo==0.2.3 pyarlo==0.2.3
# homeassistant.components.atag # homeassistant.components.atag
pyatag==0.2.19 pyatag==0.3.1.1
# homeassistant.components.netatmo # homeassistant.components.netatmo
pyatmo==3.3.1 pyatmo==3.3.1

View File

@ -3,13 +3,14 @@ from pyatag import AtagException
from homeassistant import config_entries, data_entry_flow from homeassistant import config_entries, data_entry_flow
from homeassistant.components.atag import DOMAIN from homeassistant.components.atag import DOMAIN
from homeassistant.const import CONF_DEVICE, CONF_HOST, CONF_PORT from homeassistant.const import CONF_DEVICE, CONF_EMAIL, CONF_HOST, CONF_PORT
from tests.async_mock import PropertyMock, patch from tests.async_mock import PropertyMock, patch
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
FIXTURE_USER_INPUT = { FIXTURE_USER_INPUT = {
CONF_HOST: "127.0.0.1", CONF_HOST: "127.0.0.1",
CONF_EMAIL: "test@domain.com",
CONF_PORT: 10000, CONF_PORT: 10000,
} }
FIXTURE_COMPLETE_ENTRY = FIXTURE_USER_INPUT.copy() FIXTURE_COMPLETE_ENTRY = FIXTURE_USER_INPUT.copy()
@ -42,7 +43,7 @@ async def test_connection_error(hass):
"""Test we show user form on Atag connection error.""" """Test we show user form on Atag connection error."""
with patch( with patch(
"homeassistant.components.atag.config_flow.AtagDataStore.async_check_pair_status", "homeassistant.components.atag.config_flow.AtagOne.authorize",
side_effect=AtagException(), side_effect=AtagException(),
): ):
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
@ -58,10 +59,10 @@ async def test_connection_error(hass):
async def test_full_flow_implementation(hass): async def test_full_flow_implementation(hass):
"""Test registering an integration and finishing flow works.""" """Test registering an integration and finishing flow works."""
with patch( with patch("homeassistant.components.atag.AtagOne.authorize",), patch(
"homeassistant.components.atag.AtagDataStore.async_check_pair_status", "homeassistant.components.atag.AtagOne.update",
), patch( ), patch(
"homeassistant.components.atag.AtagDataStore.device", "homeassistant.components.atag.AtagOne.id",
new_callable=PropertyMock(return_value="device_identifier"), new_callable=PropertyMock(return_value="device_identifier"),
): ):
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(