Add preview to Threshold config & option flow (#117181)
Co-authored-by: Erik Montnemery <erik@montnemery.com> Co-authored-by: Franck Nijhof <git@frenck.dev>
This commit is contained in:
parent
2b2c4e8262
commit
1c2aa9a49b
4 changed files with 351 additions and 9 deletions
|
@ -2,6 +2,7 @@
|
|||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable, Mapping
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
|
@ -22,7 +23,13 @@ from homeassistant.const import (
|
|||
STATE_UNAVAILABLE,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
from homeassistant.core import Event, EventStateChangedData, HomeAssistant, callback
|
||||
from homeassistant.core import (
|
||||
CALLBACK_TYPE,
|
||||
Event,
|
||||
EventStateChangedData,
|
||||
HomeAssistant,
|
||||
callback,
|
||||
)
|
||||
from homeassistant.helpers import (
|
||||
config_validation as cv,
|
||||
device_registry as dr,
|
||||
|
@ -111,7 +118,6 @@ async def async_setup_entry(
|
|||
async_add_entities(
|
||||
[
|
||||
ThresholdSensor(
|
||||
hass,
|
||||
entity_id,
|
||||
name,
|
||||
lower,
|
||||
|
@ -145,7 +151,7 @@ async def async_setup_platform(
|
|||
async_add_entities(
|
||||
[
|
||||
ThresholdSensor(
|
||||
hass, entity_id, name, lower, upper, hysteresis, device_class, None
|
||||
entity_id, name, lower, upper, hysteresis, device_class, None
|
||||
)
|
||||
],
|
||||
)
|
||||
|
@ -167,7 +173,6 @@ class ThresholdSensor(BinarySensorEntity):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
hass: HomeAssistant,
|
||||
entity_id: str,
|
||||
name: str,
|
||||
lower: float | None,
|
||||
|
@ -178,6 +183,7 @@ class ThresholdSensor(BinarySensorEntity):
|
|||
device_info: DeviceInfo | None = None,
|
||||
) -> None:
|
||||
"""Initialize the Threshold sensor."""
|
||||
self._preview_callback: Callable[[str, Mapping[str, Any]], None] | None = None
|
||||
self._attr_unique_id = unique_id
|
||||
self._attr_device_info = device_info
|
||||
self._entity_id = entity_id
|
||||
|
@ -193,9 +199,17 @@ class ThresholdSensor(BinarySensorEntity):
|
|||
self._state: bool | None = None
|
||||
self.sensor_value: float | None = None
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Run when entity about to be added to hass."""
|
||||
self._async_setup_sensor()
|
||||
|
||||
@callback
|
||||
def _async_setup_sensor(self) -> None:
|
||||
"""Set up the sensor and start tracking state changes."""
|
||||
|
||||
def _update_sensor_state() -> None:
|
||||
"""Handle sensor state changes."""
|
||||
if (new_state := hass.states.get(self._entity_id)) is None:
|
||||
if (new_state := self.hass.states.get(self._entity_id)) is None:
|
||||
return
|
||||
|
||||
try:
|
||||
|
@ -210,17 +224,26 @@ class ThresholdSensor(BinarySensorEntity):
|
|||
|
||||
self._update_state()
|
||||
|
||||
if self._preview_callback:
|
||||
calculated_state = self._async_calculate_state()
|
||||
self._preview_callback(
|
||||
calculated_state.state, calculated_state.attributes
|
||||
)
|
||||
|
||||
@callback
|
||||
def async_threshold_sensor_state_listener(
|
||||
event: Event[EventStateChangedData],
|
||||
) -> None:
|
||||
"""Handle sensor state changes."""
|
||||
_update_sensor_state()
|
||||
self.async_write_ha_state()
|
||||
|
||||
# only write state to the state machine if we are not in preview mode
|
||||
if not self._preview_callback:
|
||||
self.async_write_ha_state()
|
||||
|
||||
self.async_on_remove(
|
||||
async_track_state_change_event(
|
||||
hass, [entity_id], async_threshold_sensor_state_listener
|
||||
self.hass, [self._entity_id], async_threshold_sensor_state_listener
|
||||
)
|
||||
)
|
||||
_update_sensor_state()
|
||||
|
@ -305,3 +328,26 @@ class ThresholdSensor(BinarySensorEntity):
|
|||
self._state_position = POSITION_IN_RANGE
|
||||
self._state = True
|
||||
return
|
||||
|
||||
@callback
|
||||
def async_start_preview(
|
||||
self,
|
||||
preview_callback: Callable[[str, Mapping[str, Any]], None],
|
||||
) -> CALLBACK_TYPE:
|
||||
"""Render a preview."""
|
||||
# abort early if there is no entity_id
|
||||
# as without we can't track changes
|
||||
# or if neither lower nor upper thresholds are set
|
||||
if not self._entity_id or (
|
||||
not hasattr(self, "_threshold_lower")
|
||||
and not hasattr(self, "_threshold_upper")
|
||||
):
|
||||
self._attr_available = False
|
||||
calculated_state = self._async_calculate_state()
|
||||
preview_callback(calculated_state.state, calculated_state.attributes)
|
||||
return self._call_on_remove_callbacks
|
||||
|
||||
self._preview_callback = preview_callback
|
||||
|
||||
self._async_setup_sensor()
|
||||
return self._call_on_remove_callbacks
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue