Compare commits
1 Commits
6.6.1
...
6.6.1.beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae9b065387 |
@@ -1353,7 +1353,7 @@ Example of graph obtained with Plotly :
|
|||||||
|
|
||||||
|
|
||||||
## And always better and better with the NOTIFIER daemon app to notify events
|
## And always better and better with the NOTIFIER daemon app to notify events
|
||||||
This automation uses the excellent App Daemon named NOTIFIER developed by Horizon Domotique that you will find in demonstration [here](https://www.youtube.com/watch?v=chJylIK0ASo&ab_channel=HorizonDomotique) and the code is [here](https://github.com/jlpouffier/home-assistant-config/blob/master/appdaemon/apps/notifier.py). It allows you to notify the users of the accommodation when one of the events affecting safety occurs on one of the Versatile Thermostats.
|
This automation uses the excellent App Daemon named NOTIFIER developed by Horizon Domotique that you will find in demonstration [here](https://www.youtube.com/watch?v=chJylIK0ASo&ab_channel=HorizonDomotique) and the code is [here](https ://github.com/jlpouffier/home-assistant-config/blob/master/appdaemon/apps/notifier.py). It allows you to notify the users of the accommodation when one of the events affecting safety occurs on one of the Versatile Thermostats.
|
||||||
|
|
||||||
This is a great example of using the notifications described here [notification](#notifications).
|
This is a great example of using the notifications described here [notification](#notifications).
|
||||||
|
|
||||||
|
|||||||
@@ -178,20 +178,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
|
|
||||||
if hass.state == CoreState.running:
|
if hass.state == CoreState.running:
|
||||||
await api.reload_central_boiler_entities_list()
|
await api.reload_central_boiler_entities_list()
|
||||||
await api.init_vtherm_links(entry.entry_id)
|
await api.init_vtherm_links()
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||||
"""Update listener."""
|
"""Update listener."""
|
||||||
|
|
||||||
_LOGGER.debug(
|
|
||||||
"Calling update_listener entry: entry_id='%s', value='%s'",
|
|
||||||
entry.entry_id,
|
|
||||||
entry.data,
|
|
||||||
)
|
|
||||||
|
|
||||||
if entry.data.get(CONF_THERMOSTAT_TYPE) == CONF_THERMOSTAT_CENTRAL_CONFIG:
|
if entry.data.get(CONF_THERMOSTAT_TYPE) == CONF_THERMOSTAT_CENTRAL_CONFIG:
|
||||||
await reload_all_vtherm(hass)
|
await reload_all_vtherm(hass)
|
||||||
else:
|
else:
|
||||||
@@ -200,7 +193,7 @@ async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
|||||||
api: VersatileThermostatAPI = VersatileThermostatAPI.get_vtherm_api(hass)
|
api: VersatileThermostatAPI = VersatileThermostatAPI.get_vtherm_api(hass)
|
||||||
if api is not None:
|
if api is not None:
|
||||||
await api.reload_central_boiler_entities_list()
|
await api.reload_central_boiler_entities_list()
|
||||||
await api.init_vtherm_links(entry.entry_id)
|
await api.init_vtherm_links()
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||||
|
|||||||
@@ -19,10 +19,7 @@ from homeassistant.core import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from homeassistant.components.climate import ClimateEntity
|
from homeassistant.components.climate import ClimateEntity
|
||||||
from homeassistant.helpers.restore_state import (
|
from homeassistant.helpers.restore_state import RestoreEntity
|
||||||
RestoreEntity,
|
|
||||||
async_get as restore_async_get,
|
|
||||||
)
|
|
||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.helpers.device_registry import DeviceInfo, DeviceEntryType
|
from homeassistant.helpers.device_registry import DeviceInfo, DeviceEntryType
|
||||||
@@ -594,24 +591,14 @@ class BaseThermostat(ClimateEntity, RestoreEntity, Generic[T]):
|
|||||||
# issue 428. Link to others entities will start at link
|
# issue 428. Link to others entities will start at link
|
||||||
# await self.async_startup()
|
# await self.async_startup()
|
||||||
|
|
||||||
async def async_will_remove_from_hass(self):
|
|
||||||
"""Try to force backup of entity"""
|
|
||||||
_LOGGER_ENERGY.debug(
|
|
||||||
"%s - force write before remove. Energy is %s", self, self.total_energy
|
|
||||||
)
|
|
||||||
# Force dump in background
|
|
||||||
await restore_async_get(self.hass).async_dump_states()
|
|
||||||
|
|
||||||
def remove_thermostat(self):
|
def remove_thermostat(self):
|
||||||
"""Called when the thermostat will be removed"""
|
"""Called when the thermostat will be removed"""
|
||||||
_LOGGER.info("%s - Removing thermostat", self)
|
_LOGGER.info("%s - Removing thermostat", self)
|
||||||
|
|
||||||
for under in self._underlyings:
|
for under in self._underlyings:
|
||||||
under.remove_entity()
|
under.remove_entity()
|
||||||
|
|
||||||
async def async_startup(self, central_configuration):
|
async def async_startup(self, central_configuration):
|
||||||
"""Triggered on startup, used to get old state and set internal states accordingly. This is triggered by
|
"""Triggered on startup, used to get old state and set internal states accordingly"""
|
||||||
VTherm API"""
|
|
||||||
_LOGGER.debug("%s - Calling async_startup", self)
|
_LOGGER.debug("%s - Calling async_startup", self)
|
||||||
|
|
||||||
_LOGGER.debug("%s - Calling async_startup_internal", self)
|
_LOGGER.debug("%s - Calling async_startup_internal", self)
|
||||||
|
|||||||
@@ -109,17 +109,17 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
or self._infos.get(CONF_WINDOW_AUTO_OPEN_THRESHOLD) is not None
|
or self._infos.get(CONF_WINDOW_AUTO_OPEN_THRESHOLD) is not None
|
||||||
)
|
)
|
||||||
self._infos[CONF_USE_MOTION_FEATURE] = self._infos.get(
|
self._infos[CONF_USE_MOTION_FEATURE] = self._infos.get(
|
||||||
CONF_USE_MOTION_FEATURE, False
|
CONF_USE_MOTION_FEATURE
|
||||||
) and (self._infos.get(CONF_MOTION_SENSOR) is not None or is_central_config)
|
) and (self._infos.get(CONF_MOTION_SENSOR) is not None or is_central_config)
|
||||||
|
|
||||||
self._infos[CONF_USE_POWER_FEATURE] = self._infos.get(
|
self._infos[CONF_USE_POWER_FEATURE] = self._infos.get(
|
||||||
CONF_USE_POWER_CENTRAL_CONFIG, False
|
CONF_USE_POWER_CENTRAL_CONFIG
|
||||||
) or (
|
) or (
|
||||||
self._infos.get(CONF_POWER_SENSOR) is not None
|
self._infos.get(CONF_POWER_SENSOR) is not None
|
||||||
and self._infos.get(CONF_MAX_POWER_SENSOR) is not None
|
and self._infos.get(CONF_MAX_POWER_SENSOR) is not None
|
||||||
)
|
)
|
||||||
self._infos[CONF_USE_PRESENCE_FEATURE] = (
|
self._infos[CONF_USE_PRESENCE_FEATURE] = (
|
||||||
self._infos.get(CONF_USE_PRESENCE_CENTRAL_CONFIG, False)
|
self._infos.get(CONF_USE_PRESENCE_CENTRAL_CONFIG)
|
||||||
or self._infos.get(CONF_PRESENCE_SENSOR) is not None
|
or self._infos.get(CONF_PRESENCE_SENSOR) is not None
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self._infos[CONF_USE_AUTO_START_STOP_FEATURE] = (
|
self._infos[CONF_USE_AUTO_START_STOP_FEATURE] = (
|
||||||
self._infos.get(CONF_USE_AUTO_START_STOP_FEATURE, False) is True
|
self._infos.get(CONF_USE_AUTO_START_STOP_FEATURE) is True
|
||||||
and self._infos.get(CONF_THERMOSTAT_TYPE) == CONF_THERMOSTAT_CLIMATE
|
and self._infos.get(CONF_THERMOSTAT_TYPE) == CONF_THERMOSTAT_CLIMATE
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -145,17 +145,12 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
CONF_USE_PRESETS_CENTRAL_CONFIG,
|
CONF_USE_PRESETS_CENTRAL_CONFIG,
|
||||||
CONF_USE_PRESENCE_CENTRAL_CONFIG,
|
CONF_USE_PRESENCE_CENTRAL_CONFIG,
|
||||||
CONF_USE_ADVANCED_CENTRAL_CONFIG,
|
CONF_USE_ADVANCED_CENTRAL_CONFIG,
|
||||||
CONF_USE_CENTRAL_MODE,
|
|
||||||
):
|
):
|
||||||
if not is_empty:
|
if not is_empty:
|
||||||
current_config = self._infos.get(config, None)
|
current_config = self._infos.get(config, None)
|
||||||
|
self._infos[config] = current_config is True or (
|
||||||
self._infos[config] = self._central_config is not None and (
|
current_config is None and self._central_config is not None
|
||||||
current_config is True or current_config is None
|
|
||||||
)
|
)
|
||||||
# self._infos[config] = current_config is True or (
|
|
||||||
# current_config is None and self._central_config is not None
|
|
||||||
# )
|
|
||||||
else:
|
else:
|
||||||
self._infos[config] = self._central_config is not None
|
self._infos[config] = self._central_config is not None
|
||||||
|
|
||||||
@@ -214,9 +209,6 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
CONF_USE_PRESENCE_CENTRAL_CONFIG,
|
CONF_USE_PRESENCE_CENTRAL_CONFIG,
|
||||||
CONF_USE_PRESETS_CENTRAL_CONFIG,
|
CONF_USE_PRESETS_CENTRAL_CONFIG,
|
||||||
CONF_USE_ADVANCED_CENTRAL_CONFIG,
|
CONF_USE_ADVANCED_CENTRAL_CONFIG,
|
||||||
CONF_USE_CENTRAL_MODE,
|
|
||||||
# CONF_USE_CENTRAL_BOILER_FEATURE, this is for Central Config
|
|
||||||
CONF_USED_BY_CENTRAL_BOILER,
|
|
||||||
]:
|
]:
|
||||||
if data.get(conf) is True:
|
if data.get(conf) is True:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
@@ -314,22 +306,6 @@ class VersatileThermostatBaseConfigFlow(FlowHandler):
|
|||||||
):
|
):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if (
|
|
||||||
infos.get(CONF_PROP_FUNCTION, None) == PROPORTIONAL_FUNCTION_TPI
|
|
||||||
and infos.get(CONF_USE_TPI_CENTRAL_CONFIG, False) is False
|
|
||||||
and (
|
|
||||||
infos.get(CONF_TPI_COEF_INT, None) is None
|
|
||||||
or infos.get(CONF_TPI_COEF_EXT) is None
|
|
||||||
)
|
|
||||||
):
|
|
||||||
return False
|
|
||||||
|
|
||||||
if (
|
|
||||||
infos.get(CONF_USE_PRESETS_CENTRAL_CONFIG, False) is True
|
|
||||||
and self._central_config is None
|
|
||||||
):
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def merge_user_input(self, data_schema: vol.Schema, user_input: dict):
|
def merge_user_input(self, data_schema: vol.Schema, user_input: dict):
|
||||||
|
|||||||
@@ -150,11 +150,10 @@ class VersatileThermostatAPI(dict):
|
|||||||
return entity.state
|
return entity.state
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def init_vtherm_links(self, entry_id=None):
|
async def init_vtherm_links(self):
|
||||||
"""Initialize all VTherms entities links
|
"""Initialize all VTherms entities links
|
||||||
This method is called when HA is fully started (and all entities should be initialized)
|
This method is called when HA is fully started (and all entities should be initialized)
|
||||||
Or when we need to reload all VTherm links (with Number temp entities, central boiler, ...)
|
Or when we need to reload all VTherm links (with Number temp entities, central boiler, ...)
|
||||||
If entry_id is set, only the VTherm of this entry will be reloaded
|
|
||||||
"""
|
"""
|
||||||
await self.reload_central_boiler_binary_listener()
|
await self.reload_central_boiler_binary_listener()
|
||||||
await self.reload_central_boiler_entities_list()
|
await self.reload_central_boiler_entities_list()
|
||||||
@@ -176,8 +175,7 @@ class VersatileThermostatAPI(dict):
|
|||||||
entity.device_info
|
entity.device_info
|
||||||
and entity.device_info.get("model", None) == DOMAIN
|
and entity.device_info.get("model", None) == DOMAIN
|
||||||
):
|
):
|
||||||
if entry_id is None or entry_id == entity.unique_id:
|
await entity.async_startup(self.find_central_configuration())
|
||||||
await entity.async_startup(self.find_central_configuration())
|
|
||||||
|
|
||||||
async def init_vtherm_preset_with_central(self):
|
async def init_vtherm_preset_with_central(self):
|
||||||
"""Init all VTherm presets when the VTherm uses central temperature"""
|
"""Init all VTherm presets when the VTherm uses central temperature"""
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user