Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 1.3.7 Restore Device States after HA Restart #68

Merged
merged 101 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
45bb772
change import * to explicit imports for homeassistant.const
grimmpp Feb 12, 2024
831c1c6
fix for GatewayConnectionState entity
grimmpp Feb 12, 2024
d9d21d7
debug last message received
grimmpp Feb 12, 2024
abf908a
debug last message received
grimmpp Feb 12, 2024
714eea7
debug last message received
grimmpp Feb 12, 2024
b8dd8fb
debug last message received
grimmpp Feb 12, 2024
5ce66d4
debug last message received
grimmpp Feb 12, 2024
a71a302
debug last message received
grimmpp Feb 12, 2024
c6d80f1
debug last message received
grimmpp Feb 13, 2024
7a5558b
debug last message received
grimmpp Feb 13, 2024
86e5512
debug last message received
grimmpp Feb 13, 2024
9671f93
debug last message received
grimmpp Feb 13, 2024
03d4901
debug last message received
grimmpp Feb 13, 2024
75fd9f1
debug last message received
grimmpp Feb 13, 2024
ce8761e
debug last message received
grimmpp Feb 13, 2024
cac6e4d
debug last message received
grimmpp Feb 13, 2024
0b7c4fa
debug last message received
grimmpp Feb 13, 2024
83f9eae
debug last message received
grimmpp Feb 13, 2024
17dc736
debug last message received
grimmpp Feb 13, 2024
90d4956
debug last message received
grimmpp Feb 13, 2024
3b07d86
debug last message received
grimmpp Feb 13, 2024
1132b24
debug last message received
grimmpp Feb 13, 2024
840e7d1
debug last message received
grimmpp Feb 13, 2024
5a899b6
debug last message received
grimmpp Feb 13, 2024
c51292b
debug last message received
grimmpp Feb 13, 2024
4b68eae
debug last message received
grimmpp Feb 13, 2024
78c4cd1
debug last message received
grimmpp Feb 13, 2024
b609bae
debug last message received
grimmpp Feb 13, 2024
c7bbbf8
debug last message received
grimmpp Feb 13, 2024
8892898
debug last message received
grimmpp Feb 13, 2024
04863d8
debug last message received
grimmpp Feb 13, 2024
921e6f8
debug last message received
grimmpp Feb 13, 2024
decd37f
debug last message received
grimmpp Feb 13, 2024
9a31367
debug last message received
grimmpp Feb 13, 2024
79753c6
debug last message received
grimmpp Feb 13, 2024
7e9bce6
debug last message received
grimmpp Feb 13, 2024
d5a54f8
debug last message received
grimmpp Feb 13, 2024
93f26a5
debug last message received
grimmpp Feb 13, 2024
408b726
debug last message received
grimmpp Feb 13, 2024
6a0aa61
debug last message received
grimmpp Feb 13, 2024
9dd8f67
debug last message received
grimmpp Feb 13, 2024
664bad5
debug last message received
grimmpp Feb 13, 2024
c396bd7
debug last message received
grimmpp Feb 13, 2024
8cc9d24
debug last message received
grimmpp Feb 13, 2024
debc852
debug last message received
grimmpp Feb 14, 2024
47b2de2
debug last message received
grimmpp Feb 14, 2024
cc05a8d
debug last message received
grimmpp Feb 14, 2024
e148fb9
debug last message received
grimmpp Feb 14, 2024
33f8bcf
debug last message received
grimmpp Feb 14, 2024
3b09afd
debug last message received
grimmpp Feb 14, 2024
d9ab8ae
debug last message received
grimmpp Feb 14, 2024
540b0de
refactored initial loading and added tests
grimmpp Feb 14, 2024
bc83321
light tests extended
grimmpp Feb 14, 2024
73ef31a
debug initial loading
grimmpp Feb 14, 2024
20b7a20
light tests extended
grimmpp Feb 14, 2024
24998a4
debug initial loading
grimmpp Feb 15, 2024
58f966d
debug cover states
grimmpp Feb 15, 2024
7d0216f
debug cover states
grimmpp Feb 15, 2024
6ed9506
debug cover states
grimmpp Feb 15, 2024
97f0782
debug cover states
grimmpp Feb 15, 2024
8e01739
debug cover states
grimmpp Feb 15, 2024
186f618
debug cover states
grimmpp Feb 15, 2024
efe4d8b
debug cover states
grimmpp Feb 15, 2024
d92a452
debug cover states
grimmpp Feb 15, 2024
e7068e6
debug cover states
grimmpp Feb 15, 2024
6d20fb8
debug cover states
grimmpp Feb 15, 2024
303cab8
debug cover states
grimmpp Feb 15, 2024
1420147
debug initial loading
grimmpp Feb 15, 2024
313f273
debug eneity key error
grimmpp Feb 15, 2024
5a9b3f7
debug eneity key error
grimmpp Feb 15, 2024
cc01d48
debug eneity key error
grimmpp Feb 15, 2024
ddeecf0
debug eneity key error
grimmpp Feb 15, 2024
5600160
debug eneity key error
grimmpp Feb 15, 2024
ca8d6f9
debug eneity key error
grimmpp Feb 15, 2024
b176690
debug eneity key error
grimmpp Feb 15, 2024
61483cf
debug eneity key error
grimmpp Feb 15, 2024
c030533
entitiy ids changed.
grimmpp Feb 15, 2024
8b8b275
change entity id schema
grimmpp Feb 15, 2024
435d8ec
debug cleanup entities
grimmpp Feb 15, 2024
0373d2e
debug removal of entires
grimmpp Feb 15, 2024
2d808bf
debug cleanup entities
grimmpp Feb 15, 2024
a6ba6fd
debug cleanup entities
grimmpp Feb 15, 2024
17004b6
debug cleanup entities
grimmpp Feb 15, 2024
246ef44
debug cleanup entities
grimmpp Feb 15, 2024
9f49a6d
debug cleanup entities
grimmpp Feb 15, 2024
0ec27df
debug cleanup entities
grimmpp Feb 15, 2024
4baccf8
debug cleanup entities
grimmpp Feb 15, 2024
20c5f36
debug cleanup entities
grimmpp Feb 15, 2024
be07e7f
debug cleanup entities
grimmpp Feb 15, 2024
677f0b8
debug cleanup entities
grimmpp Feb 15, 2024
1a4589e
debug cleanup entities
grimmpp Feb 15, 2024
1be96e6
debug cleanup entities
grimmpp Feb 15, 2024
985e0ca
debug cleanup entities
grimmpp Feb 15, 2024
856b9d5
cleaned up
grimmpp Feb 15, 2024
2e51b99
cleaned up
grimmpp Feb 15, 2024
c9cab8b
added initial load for climate
grimmpp Feb 15, 2024
5263209
added initial load for climate
grimmpp Feb 15, 2024
038b6a6
added initial load for climate
grimmpp Feb 15, 2024
070a383
added initial load for climate
grimmpp Feb 16, 2024
cac505d
docs updated
grimmpp Feb 16, 2024
9cb120e
docs updated
grimmpp Feb 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions changes.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
# Changes and Feature List

## Version 1.3.7 Import Cleanup
* Trial to remove import warnings (Reported Issue: https://github.com/grimmpp/home-assistant-eltako/issues/61)
## Version 1.3.7 Restore Device States after HA Restart
* Trial to remove import warnings
Reported Issue: https://github.com/grimmpp/home-assistant-eltako/issues/61
* 🐞 Removed entity_id bug from GatewayConnectionState 🐞 => Requires removing and adding gateway again ❗
* Added state cache of device entities. When restarting HA entities like temperature sensors will show previouse state/value after restart.
Reported Feature: https://github.com/grimmpp/home-assistant-eltako/issues/63

## Version 1.3.6 Dependencies fixed for 1.3.5
* 🐞 Wrong dependency in manifest 🐞
Expand Down
56 changes: 34 additions & 22 deletions custom_components/eltako/binary_sensor.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
"""Support for Eltako binary sensors."""
from __future__ import annotations
from typing import Literal, final

from eltakobus.util import AddressExpression, b2a, b2s
from eltakobus.eep import *

from homeassistant.components.binary_sensor import BinarySensorEntity
from homeassistant import config_entries
from homeassistant.const import CONF_DEVICE_CLASS
from homeassistant.const import CONF_DEVICE_CLASS, STATE_ON, STATE_OFF
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.entity import DeviceInfo
Expand All @@ -33,13 +34,13 @@ async def async_setup_entry(

platform = Platform.BINARY_SENSOR

for platform in [Platform.BINARY_SENSOR, Platform.SENSOR]:
if platform in config:
for entity_config in config[platform]:
for platform_id in [Platform.BINARY_SENSOR, Platform.SENSOR]:
if platform_id in config:
for entity_config in config[platform_id]:
try:
dev_conf = config_helpers.DeviceConf(entity_config, [CONF_DEVICE_CLASS, CONF_INVERT_SIGNAL])
if dev_conf.eep.eep_string in CONF_EEP_SUPPORTED_BINARY_SENSOR:
entities.append(EltakoBinarySensor(platform, gateway, dev_conf.id, dev_conf.name, dev_conf.eep,
entities.append(EltakoBinarySensor(platform_id, gateway, dev_conf.id, dev_conf.name, dev_conf.eep,
dev_conf.get(CONF_DEVICE_CLASS), dev_conf.get(CONF_INVERT_SIGNAL)))

except Exception as e:
Expand All @@ -52,9 +53,29 @@ async def async_setup_entry(
# dev_id validation not possible because there can be bus sensors as well as decentralized sensors.
log_entities_to_be_added(entities, platform)
async_add_entities(entities)


class AbstractBinarySensor(EltakoEntity, RestoreEntity, BinarySensorEntity):

def load_value_initially(self, latest_state:State):
try:
if 'unknown' == latest_state.state:
self._attr_is_on = None
else:
if latest_state.state in ['on', 'off']:
self._attr_is_on = 'on' == latest_state.state
else:
self._attr_is_on = None

except Exception as e:
self._attr_is_on = None
raise e

self.schedule_update_ha_state()

class EltakoBinarySensor(EltakoEntity, BinarySensorEntity):
LOGGER.debug(f"[binary_sensor {self.dev_id}] value initially loaded: [is_on: {self.is_on}, state: {self.state}]")

class EltakoBinarySensor(AbstractBinarySensor):
"""Representation of Eltako binary sensors such as wall switches.

Supported EEPs (EnOcean Equipment Profiles):
Expand All @@ -69,16 +90,7 @@ def __init__(self, platform: str, gateway: EnOceanGateway, dev_id: AddressExpres
super().__init__(platform, gateway, dev_id, dev_name, dev_eep)
self.invert_signal = invert_signal
self._attr_device_class = device_class

@property
def last_received_signal(self):
"""Return timestamp of last received signal."""
return self._attr_last_received_signal

@property
def data(self):
"""Return telegram data for rocker switch."""
return self._attr_data


def value_changed(self, msg: ESP2Message):
"""Fire an event with the data that have changed.
Expand Down Expand Up @@ -229,17 +241,17 @@ def value_changed(self, msg: ESP2Message):
},
)

class GatewayConnectionState(EltakoEntity, BinarySensorEntity):
class GatewayConnectionState(AbstractBinarySensor):
"""Protocols last time when message received"""

def __init__(self, platform: str, gateway: EnOceanGateway):
super().__init__(platform, gateway, gateway.base_id, "Connected" )
key = "Gateway_Connection_State"

self._attr_unique_id = f"{self.identifier}_Last Received Message - Gateway "+str(gateway.dev_id)
self._attr_icon = "mdi:connection"
self._attr_name = "Connected"

super().__init__(platform, gateway, gateway.base_id, dev_name="Connected", description_key=key)
self.gateway.set_connection_state_changed_handler(self.async_value_changed)
self.icon = "mdi:connection"
self.name = "Connected"
self.has_entity_name = True

@property
def device_info(self) -> DeviceInfo:
Expand Down
10 changes: 4 additions & 6 deletions custom_components/eltako/button.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,16 @@ def __init__(self, platform: str, gateway: EnOceanGateway, dev_id: AddressExpres
_dev_name = dev_name
if _dev_name == "":
_dev_name = "temperature-controller-teach-in-button"
super().__init__(platform, gateway, dev_id, _dev_name, dev_eep)
self.entity_description = ButtonEntityDescription(
key="teach_in_button",
name="Send teach-in telegram from "+sender_id.plain_address().hex(),
icon="mdi:button-cursor",
device_class=ButtonDeviceClass.UPDATE,
has_entity_name= True,
)
self._attr_unique_id = f"{self.identifier}_{self.entity_description.key}"
self.sender_id = sender_id

super().__init__(platform, gateway, dev_id, _dev_name, dev_eep)

async def async_press(self) -> None:
"""
Handle the button press.
Expand All @@ -101,15 +100,14 @@ class GatewayReconnectButton(EltakoEntity, ButtonEntity):
"""Button for reconnecting serial bus"""

def __init__(self, platform: str, gateway: EnOceanGateway):
super().__init__(platform, gateway, gateway.base_id, gateway.dev_name, None)
self.entity_description = ButtonEntityDescription(
key="gateway_" + str(gateway.dev_id) + "Serial Reconnection",
name="Reconnect Gateway "+str(gateway.dev_id),
icon="mdi:button-pointer",
device_class=ButtonDeviceClass.UPDATE,
has_entity_name= True,
)
self._attr_unique_id = f"{self.identifier}_{self.entity_description.key}"

super().__init__(platform, gateway, gateway.base_id, gateway.dev_name, None)

@property
def device_info(self) -> DeviceInfo:
Expand Down
39 changes: 35 additions & 4 deletions custom_components/eltako/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
ClimateEntityFeature
)
from homeassistant import config_entries
from homeassistant.const import CONF_ID, CONF_NAME, Platform, TEMP_CELSIUS, CONF_TEMPERATURE_UNIT, Platform
from homeassistant.const import Platform, CONF_TEMPERATURE_UNIT, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.typing import ConfigType

from .gateway import EnOceanGateway
Expand Down Expand Up @@ -83,13 +82,13 @@ async def async_setup_entry(
async_add_entities(entities)


def validate_ids_of_climate(entities:[EltakoEntity]):
def validate_ids_of_climate(entities:list[EltakoEntity]):
for e in entities:
e.validate_dev_id()
e.validate_sender_id()
if hasattr(e, "cooling_sender_id"):
e.validate_sender_id(e.cooling_sender_id)
class ClimateController(EltakoEntity, ClimateEntity):
class ClimateController(EltakoEntity, ClimateEntity, RestoreEntity):
"""Representation of an Eltako heating and cooling actor."""

_update_frequency = 55 # sec
Expand Down Expand Up @@ -146,6 +145,38 @@ def __init__(self, platform: str, gateway: EnOceanGateway, dev_id: AddressExpres
self._update_task = asyncio.ensure_future(self._wrapped_update(), loop=self._loop)


def load_value_initially(self, latest_state:State):
# LOGGER.debug(f"[climate {self.dev_id}] eneity unique_id: {self.unique_id}")
# LOGGER.debug(f"[climate {self.dev_id}] latest state - state: {latest_state.state}")
# LOGGER.debug(f"[climate {self.dev_id}] latest state - attributes: {latest_state.attributes}")

try:
self.hvac_modes = []
for m_str in latest_state.attributes.get('hvac_modes', []):
for m_enum in HVACMode:
if m_str == m_enum.value:
self.hvac_modes.append(m_enum)

self._attr_current_temperature = latest_state.attributes.get('current_temperature', None)
self._attr_target_temperature = latest_state.attributes.get('temperature', None)

self._attr_hvac_mode = None
for m_enum in HVACMode:
if latest_state.state == m_enum.value:
self._attr_hvac_mode = m_enum
break

except Exception as e:
self._attr_hvac_mode = None
self._attr_current_temperature = None
self._attr_target_temperature = None
raise e

self.schedule_update_ha_state()

LOGGER.debug(f"[climate {self.dev_id}] value initially loaded: [state: {self.state}, modes: [{self.hvac_modes}], current temp: {self.current_temperature}, target temp: {self.target_temperature}]")


async def _wrapped_update(self, *args) -> None:
while True:
try:
Expand Down
2 changes: 1 addition & 1 deletion custom_components/eltako/config_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ def get_gateway_name(dev_name:str, dev_type:str, dev_id: int, base_id:AddressExp
return f"{dev_name} - {dev_type} (Id: {dev_id}, BaseId: {format_address(base_id)})"

def format_address(address: AddressExpression, separator:str='-') -> str:
return b2a(address[0], '-').upper()
return b2a(address[0], separator).upper()

def get_device_name(dev_name: str, dev_id: AddressExpression, general_config: dict) -> str:
if general_config[CONF_SHOW_DEV_ID_IN_DEV_NAME]:
Expand Down
Loading
Loading