Add coordinator to Smarty (#129083)

* Add coordinator to Smarty

* Add coordinator to Smarty

* Fix
This commit is contained in:
Joost Lekkerkerker 2024-10-24 22:41:21 +02:00 committed by GitHub
parent 1c5193aa4d
commit 6df2c0bab5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 159 additions and 179 deletions

View File

@ -1,23 +1,20 @@
"""Support to control a Salda Smarty XP/XV ventilation unit.""" """Support to control a Salda Smarty XP/XV ventilation unit."""
from datetime import timedelta
import ipaddress import ipaddress
import logging import logging
from pysmarty2 import Smarty
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.config_entries import SOURCE_IMPORT
from homeassistant.const import CONF_HOST, CONF_NAME, Platform from homeassistant.const import CONF_HOST, CONF_NAME, Platform
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
from homeassistant.data_entry_flow import FlowResultType from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers import issue_registry as ir from homeassistant.helpers import issue_registry as ir
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.dispatcher import async_dispatcher_send
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
from .const import DOMAIN, SIGNAL_UPDATE_SMARTY from .const import DOMAIN
from .coordinator import SmartyConfigEntry, SmartyCoordinator
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -35,8 +32,6 @@ CONFIG_SCHEMA = vol.Schema(
PLATFORMS = [Platform.BINARY_SENSOR, Platform.FAN, Platform.SENSOR] PLATFORMS = [Platform.BINARY_SENSOR, Platform.FAN, Platform.SENSOR]
type SmartyConfigEntry = ConfigEntry[Smarty]
async def async_setup(hass: HomeAssistant, hass_config: ConfigType) -> bool: async def async_setup(hass: HomeAssistant, hass_config: ConfigType) -> bool:
"""Create a smarty system.""" """Create a smarty system."""
@ -89,27 +84,11 @@ async def _async_import(hass: HomeAssistant, config: ConfigType) -> None:
async def async_setup_entry(hass: HomeAssistant, entry: SmartyConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: SmartyConfigEntry) -> bool:
"""Set up the Smarty environment from a config entry.""" """Set up the Smarty environment from a config entry."""
def _setup_smarty() -> Smarty: coordinator = SmartyCoordinator(hass)
smarty = Smarty(host=entry.data[CONF_HOST])
smarty.update()
return smarty
smarty = await hass.async_add_executor_job(_setup_smarty) await coordinator.async_config_entry_first_refresh()
entry.runtime_data = smarty entry.runtime_data = coordinator
async def poll_device_update(event_time) -> None:
"""Update Smarty device."""
_LOGGER.debug("Updating Smarty device")
if await hass.async_add_executor_job(smarty.update):
_LOGGER.debug("Update success")
async_dispatcher_send(hass, SIGNAL_UPDATE_SMARTY)
else:
_LOGGER.debug("Update failed")
entry.async_on_unload(
async_track_time_interval(hass, poll_device_update, timedelta(seconds=30))
)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)

View File

@ -4,17 +4,15 @@ from __future__ import annotations
import logging import logging
from pysmarty2 import Smarty
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
BinarySensorDeviceClass, BinarySensorDeviceClass,
BinarySensorEntity, BinarySensorEntity,
) )
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from . import SIGNAL_UPDATE_SMARTY, SmartyConfigEntry from .coordinator import SmartyConfigEntry, SmartyCoordinator
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -26,88 +24,76 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the Smarty Binary Sensor Platform.""" """Set up the Smarty Binary Sensor Platform."""
smarty = entry.runtime_data coordinator = entry.runtime_data
entry_id = entry.entry_id
sensors = [ sensors = [
AlarmSensor(entry.title, smarty, entry_id), AlarmSensor(coordinator),
WarningSensor(entry.title, smarty, entry_id), WarningSensor(coordinator),
BoostSensor(entry.title, smarty, entry_id), BoostSensor(coordinator),
] ]
async_add_entities(sensors, True) async_add_entities(sensors)
class SmartyBinarySensor(BinarySensorEntity): class SmartyBinarySensor(CoordinatorEntity[SmartyCoordinator], BinarySensorEntity):
"""Representation of a Smarty Binary Sensor.""" """Representation of a Smarty Binary Sensor."""
_attr_should_poll = False
def __init__( def __init__(
self, self,
coordinator: SmartyCoordinator,
name: str, name: str,
device_class: BinarySensorDeviceClass | None, device_class: BinarySensorDeviceClass | None,
smarty: Smarty,
) -> None: ) -> None:
"""Initialize the entity.""" """Initialize the entity."""
self._attr_name = name super().__init__(coordinator)
self._attr_name = f"{coordinator.config_entry.title} {name}"
self._attr_device_class = device_class self._attr_device_class = device_class
self._smarty = smarty
async def async_added_to_hass(self) -> None:
"""Call to update."""
async_dispatcher_connect(self.hass, SIGNAL_UPDATE_SMARTY, self._update_callback)
@callback
def _update_callback(self) -> None:
"""Call update method."""
self.async_schedule_update_ha_state(True)
class BoostSensor(SmartyBinarySensor): class BoostSensor(SmartyBinarySensor):
"""Boost State Binary Sensor.""" """Boost State Binary Sensor."""
def __init__(self, name: str, smarty: Smarty, entry_id: str) -> None: def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Alarm Sensor Init.""" """Alarm Sensor Init."""
super().__init__(name=f"{name} Boost State", device_class=None, smarty=smarty) super().__init__(coordinator, name="Boost State", device_class=None)
self._attr_unique_id = f"{entry_id}_boost" self._attr_unique_id = f"{coordinator.config_entry.entry_id}_boost"
def update(self) -> None: @property
"""Update state.""" def is_on(self) -> bool | None:
_LOGGER.debug("Updating sensor %s", self._attr_name) """Return true if the binary sensor is on."""
self._attr_is_on = self._smarty.boost return self.coordinator.client.boost
class AlarmSensor(SmartyBinarySensor): class AlarmSensor(SmartyBinarySensor):
"""Alarm Binary Sensor.""" """Alarm Binary Sensor."""
def __init__(self, name: str, smarty: Smarty, entry_id: str) -> None: def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Alarm Sensor Init.""" """Alarm Sensor Init."""
super().__init__( super().__init__(
name=f"{name} Alarm", coordinator,
name="Alarm",
device_class=BinarySensorDeviceClass.PROBLEM, device_class=BinarySensorDeviceClass.PROBLEM,
smarty=smarty,
) )
self._attr_unique_id = f"{entry_id}_alarm" self._attr_unique_id = f"{coordinator.config_entry.entry_id}_alarm"
def update(self) -> None: @property
"""Update state.""" def is_on(self) -> bool | None:
_LOGGER.debug("Updating sensor %s", self._attr_name) """Return true if the binary sensor is on."""
self._attr_is_on = self._smarty.alarm return self.coordinator.client.alarm
class WarningSensor(SmartyBinarySensor): class WarningSensor(SmartyBinarySensor):
"""Warning Sensor.""" """Warning Sensor."""
def __init__(self, name: str, smarty: Smarty, entry_id: str) -> None: def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Warning Sensor Init.""" """Warning Sensor Init."""
super().__init__( super().__init__(
name=f"{name} Warning", coordinator,
name="Warning",
device_class=BinarySensorDeviceClass.PROBLEM, device_class=BinarySensorDeviceClass.PROBLEM,
smarty=smarty,
) )
self._attr_unique_id = f"{entry_id}_warning" self._attr_unique_id = f"{coordinator.config_entry.entry_id}_warning"
def update(self) -> None: @property
"""Update state.""" def is_on(self) -> bool | None:
_LOGGER.debug("Updating sensor %s", self._attr_name) """Return true if the binary sensor is on."""
self._attr_is_on = self._smarty.warning return self.coordinator.client.warning

View File

@ -1,5 +1,3 @@
"""Constants for the Smarty component.""" """Constants for the Smarty component."""
DOMAIN = "smarty" DOMAIN = "smarty"
SIGNAL_UPDATE_SMARTY = "smarty_update"

View File

@ -0,0 +1,36 @@
"""Smarty Coordinator."""
from datetime import timedelta
import logging
from pysmarty2 import Smarty
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST
from homeassistant.core import HomeAssistant
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
_LOGGER = logging.getLogger(__name__)
type SmartyConfigEntry = ConfigEntry[SmartyCoordinator]
class SmartyCoordinator(DataUpdateCoordinator[None]):
"""Smarty Coordinator."""
config_entry: SmartyConfigEntry
def __init__(self, hass: HomeAssistant) -> None:
"""Initialize."""
super().__init__(
hass,
logger=_LOGGER,
name="Smarty",
update_interval=timedelta(seconds=30),
)
self.client = Smarty(host=self.config_entry.data[CONF_HOST])
async def _async_update_data(self) -> None:
"""Fetch data from Smarty."""
if not await self.hass.async_add_executor_job(self.client.update):
raise UpdateFailed("Failed to update Smarty data")

View File

@ -9,15 +9,16 @@ from typing import Any
from homeassistant.components.fan import FanEntity, FanEntityFeature from homeassistant.components.fan import FanEntity, FanEntityFeature
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util.percentage import ( from homeassistant.util.percentage import (
percentage_to_ranged_value, percentage_to_ranged_value,
ranged_value_to_percentage, ranged_value_to_percentage,
) )
from homeassistant.util.scaling import int_states_in_range from homeassistant.util.scaling import int_states_in_range
from . import SIGNAL_UPDATE_SMARTY, SmartyConfigEntry from . import SmartyConfigEntry
from .coordinator import SmartyCoordinator
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -32,16 +33,15 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the Smarty Fan Platform.""" """Set up the Smarty Fan Platform."""
smarty = entry.runtime_data coordinator = entry.runtime_data
async_add_entities([SmartyFan(entry.title, smarty, entry.entry_id)], True) async_add_entities([SmartyFan(coordinator)])
class SmartyFan(FanEntity): class SmartyFan(CoordinatorEntity[SmartyCoordinator], FanEntity):
"""Representation of a Smarty Fan.""" """Representation of a Smarty Fan."""
_attr_icon = "mdi:air-conditioner" _attr_icon = "mdi:air-conditioner"
_attr_should_poll = False
_attr_supported_features = ( _attr_supported_features = (
FanEntityFeature.SET_SPEED FanEntityFeature.SET_SPEED
| FanEntityFeature.TURN_OFF | FanEntityFeature.TURN_OFF
@ -49,12 +49,13 @@ class SmartyFan(FanEntity):
) )
_enable_turn_on_off_backwards_compatibility = False _enable_turn_on_off_backwards_compatibility = False
def __init__(self, name, smarty, entry_id): def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Initialize the entity.""" """Initialize the entity."""
self._attr_name = name super().__init__(coordinator)
self._attr_name = coordinator.config_entry.title
self._smarty_fan_speed = 0 self._smarty_fan_speed = 0
self._smarty = smarty self._smarty = coordinator.client
self._attr_unique_id = entry_id self._attr_unique_id = coordinator.config_entry.entry_id
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
@ -108,17 +109,8 @@ class SmartyFan(FanEntity):
self._smarty_fan_speed = 0 self._smarty_fan_speed = 0
self.schedule_update_ha_state() self.schedule_update_ha_state()
async def async_added_to_hass(self) -> None:
"""Call to update fan."""
self.async_on_remove(
async_dispatcher_connect(
self.hass, SIGNAL_UPDATE_SMARTY, self._update_callback
)
)
@callback @callback
def _update_callback(self) -> None: def _handle_coordinator_update(self) -> None:
"""Call update method.""" """Call update method."""
_LOGGER.debug("Updating state")
self._smarty_fan_speed = self._smarty.fan_speed self._smarty_fan_speed = self._smarty.fan_speed
self.async_write_ha_state() super()._handle_coordinator_update()

View File

@ -2,19 +2,17 @@
from __future__ import annotations from __future__ import annotations
import datetime as dt from datetime import datetime, timedelta
import logging import logging
from pysmarty2 import Smarty
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
from homeassistant.const import UnitOfTemperature from homeassistant.const import UnitOfTemperature
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.update_coordinator import CoordinatorEntity
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from . import SIGNAL_UPDATE_SMARTY, SmartyConfigEntry from .coordinator import SmartyConfigEntry, SmartyCoordinator
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -26,162 +24,153 @@ async def async_setup_entry(
) -> None: ) -> None:
"""Set up the Smarty Sensor Platform.""" """Set up the Smarty Sensor Platform."""
smarty = entry.runtime_data coordinator = entry.runtime_data
entry_id = entry.entry_id
sensors = [ sensors = [
SupplyAirTemperatureSensor(entry.title, smarty, entry_id), SupplyAirTemperatureSensor(coordinator),
ExtractAirTemperatureSensor(entry.title, smarty, entry_id), ExtractAirTemperatureSensor(coordinator),
OutdoorAirTemperatureSensor(entry.title, smarty, entry_id), OutdoorAirTemperatureSensor(coordinator),
SupplyFanSpeedSensor(entry.title, smarty, entry_id), SupplyFanSpeedSensor(coordinator),
ExtractFanSpeedSensor(entry.title, smarty, entry_id), ExtractFanSpeedSensor(coordinator),
FilterDaysLeftSensor(entry.title, smarty, entry_id), FilterDaysLeftSensor(coordinator),
] ]
async_add_entities(sensors, True) async_add_entities(sensors)
class SmartySensor(SensorEntity): class SmartySensor(CoordinatorEntity[SmartyCoordinator], SensorEntity):
"""Representation of a Smarty Sensor.""" """Representation of a Smarty Sensor."""
_attr_should_poll = False
def __init__( def __init__(
self, self,
coordinator: SmartyCoordinator,
name: str, name: str,
key: str,
device_class: SensorDeviceClass | None, device_class: SensorDeviceClass | None,
smarty: Smarty,
unit_of_measurement: str | None, unit_of_measurement: str | None,
) -> None: ) -> None:
"""Initialize the entity.""" """Initialize the entity."""
self._attr_name = name super().__init__(coordinator)
self._attr_name = f"{coordinator.config_entry.title} {name}"
self._attr_unique_id = f"{coordinator.config_entry.entry_id}_{key}"
self._attr_native_value = None self._attr_native_value = None
self._attr_device_class = device_class self._attr_device_class = device_class
self._attr_native_unit_of_measurement = unit_of_measurement self._attr_native_unit_of_measurement = unit_of_measurement
self._smarty = smarty
async def async_added_to_hass(self) -> None:
"""Call to update."""
async_dispatcher_connect(self.hass, SIGNAL_UPDATE_SMARTY, self._update_callback)
@callback
def _update_callback(self) -> None:
"""Call update method."""
self.async_schedule_update_ha_state(True)
class SupplyAirTemperatureSensor(SmartySensor): class SupplyAirTemperatureSensor(SmartySensor):
"""Supply Air Temperature Sensor.""" """Supply Air Temperature Sensor."""
def __init__(self, name: str, smarty: Smarty, entry_id: str) -> None: def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Supply Air Temperature Init.""" """Supply Air Temperature Init."""
super().__init__( super().__init__(
name=f"{name} Supply Air Temperature", coordinator,
name="Supply Air Temperature",
key="supply_air_temperature",
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
unit_of_measurement=UnitOfTemperature.CELSIUS, unit_of_measurement=UnitOfTemperature.CELSIUS,
smarty=smarty,
) )
self._attr_unique_id = f"{entry_id}_supply_air_temperature"
def update(self) -> None: @property
"""Update state.""" def native_value(self) -> float | None:
_LOGGER.debug("Updating sensor %s", self._attr_name) """Return the state of the sensor."""
self._attr_native_value = self._smarty.supply_air_temperature return self.coordinator.client.supply_air_temperature
class ExtractAirTemperatureSensor(SmartySensor): class ExtractAirTemperatureSensor(SmartySensor):
"""Extract Air Temperature Sensor.""" """Extract Air Temperature Sensor."""
def __init__(self, name: str, smarty: Smarty, entry_id: str) -> None: def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Supply Air Temperature Init.""" """Supply Air Temperature Init."""
super().__init__( super().__init__(
name=f"{name} Extract Air Temperature", coordinator,
name="Extract Air Temperature",
key="extract_air_temperature",
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
unit_of_measurement=UnitOfTemperature.CELSIUS, unit_of_measurement=UnitOfTemperature.CELSIUS,
smarty=smarty,
) )
self._attr_unique_id = f"{entry_id}_extract_air_temperature"
def update(self) -> None: @property
"""Update state.""" def native_value(self) -> float | None:
_LOGGER.debug("Updating sensor %s", self._attr_name) """Return the state of the sensor."""
self._attr_native_value = self._smarty.extract_air_temperature return self.coordinator.client.extract_air_temperature
class OutdoorAirTemperatureSensor(SmartySensor): class OutdoorAirTemperatureSensor(SmartySensor):
"""Extract Air Temperature Sensor.""" """Extract Air Temperature Sensor."""
def __init__(self, name: str, smarty: Smarty, entry_id: str) -> None: def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Outdoor Air Temperature Init.""" """Outdoor Air Temperature Init."""
super().__init__( super().__init__(
name=f"{name} Outdoor Air Temperature", coordinator,
name="Outdoor Air Temperature",
key="outdoor_air_temperature",
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
unit_of_measurement=UnitOfTemperature.CELSIUS, unit_of_measurement=UnitOfTemperature.CELSIUS,
smarty=smarty,
) )
self._attr_unique_id = f"{entry_id}_outdoor_air_temperature"
def update(self) -> None: @property
"""Update state.""" def native_value(self) -> float | None:
_LOGGER.debug("Updating sensor %s", self._attr_name) """Return the state of the sensor."""
self._attr_native_value = self._smarty.outdoor_air_temperature return self.coordinator.client.outdoor_air_temperature
class SupplyFanSpeedSensor(SmartySensor): class SupplyFanSpeedSensor(SmartySensor):
"""Supply Fan Speed RPM.""" """Supply Fan Speed RPM."""
def __init__(self, name: str, smarty: Smarty, entry_id: str) -> None: def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Supply Fan Speed RPM Init.""" """Supply Fan Speed RPM Init."""
super().__init__( super().__init__(
name=f"{name} Supply Fan Speed", coordinator,
name="Supply Fan Speed",
key="supply_fan_speed",
device_class=None, device_class=None,
unit_of_measurement=None, unit_of_measurement=None,
smarty=smarty,
) )
self._attr_unique_id = f"{entry_id}_supply_fan_speed"
def update(self) -> None: @property
"""Update state.""" def native_value(self) -> float | None:
_LOGGER.debug("Updating sensor %s", self._attr_name) """Return the state of the sensor."""
self._attr_native_value = self._smarty.supply_fan_speed return self.coordinator.client.supply_fan_speed
class ExtractFanSpeedSensor(SmartySensor): class ExtractFanSpeedSensor(SmartySensor):
"""Extract Fan Speed RPM.""" """Extract Fan Speed RPM."""
def __init__(self, name: str, smarty: Smarty, entry_id: str) -> None: def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Extract Fan Speed RPM Init.""" """Extract Fan Speed RPM Init."""
super().__init__( super().__init__(
name=f"{name} Extract Fan Speed", coordinator,
name="Extract Fan Speed",
key="extract_fan_speed",
device_class=None, device_class=None,
unit_of_measurement=None, unit_of_measurement=None,
smarty=smarty,
) )
self._attr_unique_id = f"{entry_id}_extract_fan_speed"
def update(self) -> None: @property
"""Update state.""" def native_value(self) -> float | None:
_LOGGER.debug("Updating sensor %s", self._attr_name) """Return the state of the sensor."""
self._attr_native_value = self._smarty.extract_fan_speed return self.coordinator.client.extract_fan_speed
class FilterDaysLeftSensor(SmartySensor): class FilterDaysLeftSensor(SmartySensor):
"""Filter Days Left.""" """Filter Days Left."""
def __init__(self, name: str, smarty: Smarty, entry_id: str) -> None: def __init__(self, coordinator: SmartyCoordinator) -> None:
"""Filter Days Left Init.""" """Filter Days Left Init."""
super().__init__( super().__init__(
name=f"{name} Filter Days Left", coordinator,
name="Filter Days Left",
key="filter_days_left",
device_class=SensorDeviceClass.TIMESTAMP, device_class=SensorDeviceClass.TIMESTAMP,
unit_of_measurement=None, unit_of_measurement=None,
smarty=smarty,
) )
self._days_left = 91 self._days_left = 91
self._attr_unique_id = f"{entry_id}_filter_days_left"
def update(self) -> None: @property
"""Update state.""" def native_value(self) -> datetime | None:
_LOGGER.debug("Updating sensor %s", self._attr_name) """Return the state of the sensor."""
days_left = self._smarty.filter_timer days_left = self.coordinator.client.filter_timer
if days_left is not None and days_left != self._days_left: if days_left is not None and days_left != self._days_left:
self._attr_native_value = dt_util.now() + dt.timedelta(days=days_left)
self._days_left = days_left self._days_left = days_left
return dt_util.now() + timedelta(days=days_left)
return None

View File

@ -27,7 +27,7 @@ def mock_smarty() -> Generator[AsyncMock]:
"""Mock a Smarty client.""" """Mock a Smarty client."""
with ( with (
patch( patch(
"homeassistant.components.smarty.Smarty", "homeassistant.components.smarty.coordinator.Smarty",
autospec=True, autospec=True,
) as mock_client, ) as mock_client,
patch( patch(