From 3fdc4bb0f829cd2b7fafe8218cc70905cd28fc67 Mon Sep 17 00:00:00 2001 From: Dave Code <34915602+dave-code-ruiz@users.noreply.github.com> Date: Fri, 5 Jul 2024 10:38:46 +0200 Subject: [PATCH] Try to solves asev#52 Try to solves asev#52 --- custom_components/uponor/__init__.py | 22 ++++++++++------ custom_components/uponor/climate.py | 38 ++++++++++++++-------------- custom_components/uponor/switch.py | 37 +++++++++++++++++++-------- 3 files changed, 59 insertions(+), 38 deletions(-) diff --git a/custom_components/uponor/__init__.py b/custom_components/uponor/__init__.py index fef59dd..53709a1 100644 --- a/custom_components/uponor/__init__.py +++ b/custom_components/uponor/__init__.py @@ -6,6 +6,7 @@ from homeassistant.const import Platform from homeassistant.const import CONF_HOST +from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.storage import Store from UponorJnap import UponorJnap @@ -13,6 +14,7 @@ from .const import ( DOMAIN, + SIGNAL_UPONOR_STATE_UPDATE, SCAN_INTERVAL, STORAGE_KEY, STORAGE_VERSION, @@ -33,6 +35,7 @@ _LOGGER = logging.getLogger(__name__) +PLATFORMS = [Platform.CLIMATE, Platform.SWITCH] async def async_setup(hass: HomeAssistant, config: dict): hass.data.setdefault(DOMAIN, {}) @@ -60,8 +63,7 @@ def handle_set_variable(call): hass.services.async_register(DOMAIN, "set_variable", handle_set_variable) - await hass.config_entries.async_forward_entry_setup(config_entry, Platform.CLIMATE) - await hass.config_entries.async_forward_entry_setup(config_entry, Platform.SWITCH) + await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS) async_track_time_interval(hass, state_proxy.async_update, SCAN_INTERVAL) @@ -223,6 +225,7 @@ async def async_switch_to_cooling(self): await self._hass.async_add_executor_job(lambda: self._client.send_data({'sys_heat_cool_mode': '1'})) self._data['sys_heat_cool_mode'] = '1' + self._hass.async_add_job(async_dispatcher_send, self._hass, SIGNAL_UPONOR_STATE_UPDATE) async def async_switch_to_heating(self): for thermostat in self._hass.data[DOMAIN]['thermostats']: @@ -231,6 +234,7 @@ async def async_switch_to_heating(self): await self._hass.async_add_executor_job(lambda: self._client.send_data({'sys_heat_cool_mode': '0'})) self._data['sys_heat_cool_mode'] = '0' + self._hass.async_add_job(async_dispatcher_send, self._hass, SIGNAL_UPONOR_STATE_UPDATE) async def async_turn_on(self, thermostat): data = await self._store.async_load() @@ -269,6 +273,7 @@ async def async_set_away(self, is_away): data = "1" if is_away else "0" await self._hass.async_add_executor_job(lambda: self._client.send_data({var: data})) self._data[var] = data + self._hass.async_add_job(async_dispatcher_send, self._hass, SIGNAL_UPONOR_STATE_UPDATE) def is_eco(self, thermostat): if self.get_eco_setback(thermostat) == 0: @@ -288,21 +293,22 @@ def get_last_update(self): # Rest async def async_update(self,_=None): - '# try to change update calls doing one in same second' - 'TODO call self.async_write_ha_state() in climate and switch' - if self.next_sp_from_dt is None or dt_util.now() >= self.next_sp_from_dt: + try: self.next_sp_from_dt = dt_util.now() self._data = await self._hass.async_add_executor_job(lambda: self._client.get_data()) - else: - _LOGGER.warning("A lot of asyn_update calls at " + str(dt_util.now())) - + self._hass.async_add_job(async_dispatcher_send, self._hass, SIGNAL_UPONOR_STATE_UPDATE) + except Exception as ex: + _LOGGER.error("Uponor thermostat was unable to update: %s", ex) + def set_variable(self, var_name, var_value): _LOGGER.debug("Called set variable: name: %s, value: %s, data: %s", var_name, var_value, self._data) self._client.send_data({var_name: var_value}) self._data[var_name] = var_value + self._hass.async_add_job(async_dispatcher_send, self._hass, SIGNAL_UPONOR_STATE_UPDATE) async def set_setpoint(self, thermostat, temp): var = thermostat + '_setpoint' setpoint = int(temp * 18 + self.get_active_setback(thermostat, temp) + 320) await self._hass.async_add_executor_job(lambda: self._client.send_data({var: setpoint})) self._data[var] = setpoint + self._hass.async_add_job(async_dispatcher_send, self._hass, SIGNAL_UPONOR_STATE_UPDATE) diff --git a/custom_components/uponor/climate.py b/custom_components/uponor/climate.py index 846533a..d476269 100644 --- a/custom_components/uponor/climate.py +++ b/custom_components/uponor/climate.py @@ -1,6 +1,8 @@ import logging from homeassistant.components.climate import ClimateEntity +from homeassistant.core import callback +from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.const import ( ATTR_TEMPERATURE, @@ -17,6 +19,7 @@ from .const import ( DOMAIN, + SIGNAL_UPONOR_STATE_UPDATE, DEVICE_MANUFACTURER ) @@ -63,6 +66,22 @@ def device_info(self): def name(self): return self._name + @property + def should_poll(self): + return False + + async def async_added_to_hass(self): + async_dispatcher_connect( + self.hass, SIGNAL_UPONOR_STATE_UPDATE, self._update_callback + ) + + @callback + def _update_callback(self): + temp = self._state_proxy.get_setpoint(self._thermostat) + is_cool = self._state_proxy.is_cool_enabled() + self._is_on = not ((is_cool and temp >= self.max_temp) or (not is_cool and temp <= self.min_temp)) + self.async_schedule_update_ha_state(True) + @property def unique_id(self): return self._state_proxy.get_thermostat_id(self._thermostat) @@ -149,19 +168,6 @@ async def async_turn_on(self): await self._state_proxy.async_turn_on(self._thermostat) self._is_on = True - # ** Actions ** - async def async_update(self): - # Update uponor (to get HC mode) and thermostat - try: - ### se ha elimininado el 0 del update - await self._state_proxy.async_update() - temp = self._state_proxy.get_setpoint(self._thermostat) - is_cool = self._state_proxy.is_cool_enabled() - self._is_on = not ((is_cool and temp >= self.max_temp) or (not is_cool and temp <= self.min_temp)) - - except Exception as ex: - _LOGGER.error("Uponor thermostat was unable to update: %s", ex) - async def async_set_hvac_mode(self, hvac_mode): if hvac_mode == HVACMode.OFF and self._is_on: await self._state_proxy.async_turn_off(self._thermostat) @@ -169,12 +175,6 @@ async def async_set_hvac_mode(self, hvac_mode): if (hvac_mode == HVACMode.HEAT or hvac_mode == HVACMode.COOL) and not self._is_on: await self._state_proxy.async_turn_on(self._thermostat) self._is_on = True - - # if (hvac_mode == HVACMode.HEAT): - # await self._state_proxy.async_switch_to_heating() - # if (hvac_mode == HVACMode.COOL): - # await self._state_proxy.async_switch_to_cooling() - async def async_set_temperature(self, **kwargs): if kwargs.get(ATTR_TEMPERATURE) is None: diff --git a/custom_components/uponor/switch.py b/custom_components/uponor/switch.py index 42ca2ab..4fa85ae 100644 --- a/custom_components/uponor/switch.py +++ b/custom_components/uponor/switch.py @@ -1,8 +1,11 @@ from homeassistant.components.switch import SwitchEntity +from homeassistant.core import callback +from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.const import CONF_NAME from .const import ( DOMAIN, + SIGNAL_UPONOR_STATE_UPDATE, DEVICE_MANUFACTURER ) @@ -30,9 +33,9 @@ def name(self) -> str: def icon(self): return "mdi:home-export-outline" - # @property - # def should_poll(self): - # return False + @property + def should_poll(self): + return False @property def is_on(self): @@ -43,9 +46,15 @@ async def async_turn_on(self, **kwargs): async def async_turn_off(self, **kwargs): await self._state_proxy.async_set_away(False) + + async def async_added_to_hass(self): + async_dispatcher_connect( + self.hass, SIGNAL_UPONOR_STATE_UPDATE, self._update_callback + ) - async def async_update(self): - await self._state_proxy.async_update() + @callback + def _update_callback(self): + self.async_schedule_update_ha_state(True) @property def unique_id(self): @@ -74,9 +83,9 @@ def name(self) -> str: def icon(self): return "mdi:snowflake" - # @property - # def should_poll(self): - # return False + @property + def should_poll(self): + return False @property def is_on(self): @@ -87,9 +96,15 @@ async def async_turn_on(self, **kwargs): async def async_turn_off(self, **kwargs): await self._state_proxy.async_switch_to_heating() - - async def async_update(self): - await self._state_proxy.async_update() + + async def async_added_to_hass(self): + async_dispatcher_connect( + self.hass, SIGNAL_UPONOR_STATE_UPDATE, self._update_callback + ) + + @callback + def _update_callback(self): + self.async_schedule_update_ha_state(True) @property def unique_id(self):