Initialize KNX expose value (#49623)

* simplify value extraction

* allow 0/1 and "True" / "False" for binary exposes

* initialize ExposeSensor value

* handle binary states

* use default for initialization
This commit is contained in:
Matthias Alphart 2021-05-26 11:21:11 +02:00 committed by GitHub
parent 19c9675d4a
commit 4f9b7254d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -13,7 +13,7 @@ from homeassistant.const import (
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
STATE_UNKNOWN, STATE_UNKNOWN,
) )
from homeassistant.core import Event, HomeAssistant, callback from homeassistant.core import Event, HomeAssistant, State, callback
from homeassistant.helpers.event import async_track_state_change_event from homeassistant.helpers.event import async_track_state_change_event
from homeassistant.helpers.typing import ConfigType, StateType from homeassistant.helpers.typing import ConfigType, StateType
@ -74,6 +74,7 @@ class KNXExposeSensor:
self.address = address self.address = address
self._remove_listener: Callable[[], None] | None = None self._remove_listener: Callable[[], None] | None = None
self.device: ExposeSensor = self.async_register() self.device: ExposeSensor = self.async_register()
self._init_expose_state()
@callback @callback
def async_register(self) -> ExposeSensor: def async_register(self) -> ExposeSensor:
@ -93,6 +94,15 @@ class KNXExposeSensor:
) )
return device return device
@callback
def _init_expose_state(self) -> None:
"""Initialize state of the exposure."""
init_state = self.hass.states.get(self.entity_id)
init_value = self._get_expose_value(init_state)
self.device.sensor_value.value = (
init_value if init_value is not None else self.expose_default
)
@callback @callback
def shutdown(self) -> None: def shutdown(self) -> None:
"""Prepare for deletion.""" """Prepare for deletion."""
@ -101,45 +111,40 @@ class KNXExposeSensor:
self._remove_listener = None self._remove_listener = None
self.device.shutdown() self.device.shutdown()
def _get_expose_value(self, state: State | None) -> StateType:
"""Extract value from state."""
if state is None or state.state in (STATE_UNKNOWN, STATE_UNAVAILABLE):
return None
value = (
state.state
if self.expose_attribute is None
else state.attributes.get(self.expose_attribute)
)
if self.type == "binary":
if value in (1, STATE_ON, "True"):
value = True
elif value in (0, STATE_OFF, "False"):
value = False
return value
async def _async_entity_changed(self, event: Event) -> None: async def _async_entity_changed(self, event: Event) -> None:
"""Handle entity change.""" """Handle entity change."""
new_state = event.data.get("new_state") new_state = event.data.get("new_state")
if new_state is None: new_value = self._get_expose_value(new_state)
if new_value is None:
return return
if new_state.state in (STATE_UNKNOWN, STATE_UNAVAILABLE):
return
old_state = event.data.get("old_state") old_state = event.data.get("old_state")
old_value = self._get_expose_value(old_state)
if self.expose_attribute is None: # don't send same value sequentially
if old_state is None or old_state.state != new_state.state: if new_value != old_value:
# don't send same value sequentially await self._async_set_knx_value(new_value)
await self._async_set_knx_value(new_state.state)
return
new_attribute = new_state.attributes.get(self.expose_attribute)
if old_state is not None:
old_attribute = old_state.attributes.get(self.expose_attribute)
if old_attribute == new_attribute:
# don't send same value sequentially
return
await self._async_set_knx_value(new_attribute)
async def _async_set_knx_value(self, value: StateType) -> None: async def _async_set_knx_value(self, value: StateType) -> None:
"""Set new value on xknx ExposeSensor.""" """Set new value on xknx ExposeSensor."""
assert self.device is not None
if value is None: if value is None:
if self.expose_default is None: if self.expose_default is None:
return return
value = self.expose_default value = self.expose_default
if self.type == "binary":
if value == STATE_ON:
value = True
elif value == STATE_OFF:
value = False
await self.device.set(value) await self.device.set(value)