1
0
mirror of https://github.com/home-assistant/core.git synced 2026-04-17 23:53:49 +01:00

Improve type hints for pilight (#165719)

This commit is contained in:
Robert Resch
2026-03-16 20:55:04 +01:00
committed by GitHub
parent 54745dc1f2
commit 3c2f696a23
5 changed files with 71 additions and 56 deletions

View File

@@ -20,7 +20,7 @@ from homeassistant.const import (
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP, EVENT_HOMEASSISTANT_STOP,
) )
from homeassistant.core import HomeAssistant, ServiceCall from homeassistant.core import Event, HomeAssistant, ServiceCall
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.event import track_point_in_utc_time from homeassistant.helpers.event import track_point_in_utc_time
from homeassistant.helpers.typing import ConfigType from homeassistant.helpers.typing import ConfigType
@@ -37,6 +37,7 @@ DEFAULT_SEND_DELAY = 0.0
DOMAIN = "pilight" DOMAIN = "pilight"
EVENT = "pilight_received" EVENT = "pilight_received"
type EVENT_TYPE = Event[dict[str, Any]]
# The Pilight code schema depends on the protocol. Thus only require to have # The Pilight code schema depends on the protocol. Thus only require to have
# the protocol information. Ensure that protocol is in a list otherwise # the protocol information. Ensure that protocol is in a list otherwise

View File

@@ -3,6 +3,7 @@
from __future__ import annotations from __future__ import annotations
import datetime import datetime
from typing import Any
import voluptuous as vol import voluptuous as vol
@@ -24,7 +25,7 @@ from homeassistant.helpers.event import track_point_in_time
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from . import EVENT from . import EVENT, EVENT_TYPE
CONF_VARIABLE = "variable" CONF_VARIABLE = "variable"
CONF_RESET_DELAY_SEC = "reset_delay_sec" CONF_RESET_DELAY_SEC = "reset_delay_sec"
@@ -46,6 +47,8 @@ PLATFORM_SCHEMA = BINARY_SENSOR_PLATFORM_SCHEMA.extend(
} }
) )
type _PAYLOAD_SET_TYPE = str | int | float
def setup_platform( def setup_platform(
hass: HomeAssistant, hass: HomeAssistant,
@@ -59,12 +62,12 @@ def setup_platform(
[ [
PilightTriggerSensor( PilightTriggerSensor(
hass=hass, hass=hass,
name=config.get(CONF_NAME), name=config[CONF_NAME],
variable=config.get(CONF_VARIABLE), variable=config[CONF_VARIABLE],
payload=config.get(CONF_PAYLOAD), payload=config[CONF_PAYLOAD],
on_value=config.get(CONF_PAYLOAD_ON), on_value=config[CONF_PAYLOAD_ON],
off_value=config.get(CONF_PAYLOAD_OFF), off_value=config[CONF_PAYLOAD_OFF],
rst_dly_sec=config.get(CONF_RESET_DELAY_SEC), rst_dly_sec=config[CONF_RESET_DELAY_SEC],
) )
] ]
) )
@@ -73,11 +76,11 @@ def setup_platform(
[ [
PilightBinarySensor( PilightBinarySensor(
hass=hass, hass=hass,
name=config.get(CONF_NAME), name=config[CONF_NAME],
variable=config.get(CONF_VARIABLE), variable=config[CONF_VARIABLE],
payload=config.get(CONF_PAYLOAD), payload=config[CONF_PAYLOAD],
on_value=config.get(CONF_PAYLOAD_ON), on_value=config[CONF_PAYLOAD_ON],
off_value=config.get(CONF_PAYLOAD_OFF), off_value=config[CONF_PAYLOAD_OFF],
) )
] ]
) )
@@ -86,7 +89,15 @@ def setup_platform(
class PilightBinarySensor(BinarySensorEntity): class PilightBinarySensor(BinarySensorEntity):
"""Representation of a binary sensor that can be updated using Pilight.""" """Representation of a binary sensor that can be updated using Pilight."""
def __init__(self, hass, name, variable, payload, on_value, off_value): def __init__(
self,
hass: HomeAssistant,
name: str,
variable: str,
payload: dict[str, Any],
on_value: _PAYLOAD_SET_TYPE,
off_value: _PAYLOAD_SET_TYPE,
) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
self._attr_is_on = False self._attr_is_on = False
self._hass = hass self._hass = hass
@@ -98,7 +109,7 @@ class PilightBinarySensor(BinarySensorEntity):
hass.bus.listen(EVENT, self._handle_code) hass.bus.listen(EVENT, self._handle_code)
def _handle_code(self, call): def _handle_code(self, call: EVENT_TYPE) -> None:
"""Handle received code by the pilight-daemon. """Handle received code by the pilight-daemon.
If the code matches the defined payload If the code matches the defined payload
@@ -126,8 +137,15 @@ class PilightTriggerSensor(BinarySensorEntity):
"""Representation of a binary sensor that can be updated using Pilight.""" """Representation of a binary sensor that can be updated using Pilight."""
def __init__( def __init__(
self, hass, name, variable, payload, on_value, off_value, rst_dly_sec=30 self,
): hass: HomeAssistant,
name: str,
variable: str,
payload: dict[str, Any],
on_value: _PAYLOAD_SET_TYPE,
off_value: _PAYLOAD_SET_TYPE,
rst_dly_sec: int,
) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
self._attr_is_on = False self._attr_is_on = False
self._hass = hass self._hass = hass
@@ -137,17 +155,17 @@ class PilightTriggerSensor(BinarySensorEntity):
self._on_value = on_value self._on_value = on_value
self._off_value = off_value self._off_value = off_value
self._reset_delay_sec = rst_dly_sec self._reset_delay_sec = rst_dly_sec
self._delay_after = None self._delay_after: datetime.datetime | None = None
self._hass = hass self._hass = hass
hass.bus.listen(EVENT, self._handle_code) hass.bus.listen(EVENT, self._handle_code)
def _reset_state(self, call): def _reset_state(self, _: datetime.datetime) -> None:
self._attr_is_on = False self._attr_is_on = False
self._delay_after = None self._delay_after = None
self.schedule_update_ha_state() self.schedule_update_ha_state()
def _handle_code(self, call): def _handle_code(self, call: EVENT_TYPE) -> None:
"""Handle received code by the pilight-daemon. """Handle received code by the pilight-daemon.
If the code matches the defined payload If the code matches the defined payload

View File

@@ -1,5 +1,7 @@
"""Base class for pilight.""" """Base class for pilight."""
from typing import Any
import voluptuous as vol import voluptuous as vol
from homeassistant.const import ( from homeassistant.const import (
@@ -10,8 +12,10 @@ from homeassistant.const import (
STATE_OFF, STATE_OFF,
STATE_ON, STATE_ON,
) )
from homeassistant.core import HomeAssistant
from homeassistant.helpers import config_validation as cv from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.restore_state import RestoreEntity
from homeassistant.helpers.typing import ConfigType
from . import DOMAIN, EVENT, SERVICE_NAME from . import DOMAIN, EVENT, SERVICE_NAME
from .const import ( from .const import (
@@ -60,19 +64,19 @@ class PilightBaseDevice(RestoreEntity):
_attr_assumed_state = True _attr_assumed_state = True
_attr_should_poll = False _attr_should_poll = False
def __init__(self, hass, name, config): def __init__(self, hass: HomeAssistant, name: str, config: ConfigType) -> None:
"""Initialize a device.""" """Initialize a device."""
self._hass = hass self._hass = hass
self._attr_name = config.get(CONF_NAME, name) self._attr_name = config.get(CONF_NAME, name)
self._attr_is_on = False self._attr_is_on: bool | None = False
self._code_on = config.get(CONF_ON_CODE) self._code_on = config.get(CONF_ON_CODE)
self._code_off = config.get(CONF_OFF_CODE) self._code_off = config.get(CONF_OFF_CODE)
code_on_receive = config.get(CONF_ON_CODE_RECEIVE, []) code_on_receive = config.get(CONF_ON_CODE_RECEIVE, [])
code_off_receive = config.get(CONF_OFF_CODE_RECEIVE, []) code_off_receive = config.get(CONF_OFF_CODE_RECEIVE, [])
self._code_on_receive = [] self._code_on_receive: list[_ReceiveHandle] = []
self._code_off_receive = [] self._code_off_receive: list[_ReceiveHandle] = []
for code_list, conf in ( for code_list, conf in (
(self._code_on_receive, code_on_receive), (self._code_on_receive, code_on_receive),
@@ -85,7 +89,7 @@ class PilightBaseDevice(RestoreEntity):
if any(self._code_on_receive) or any(self._code_off_receive): if any(self._code_on_receive) or any(self._code_off_receive):
hass.bus.listen(EVENT, self._handle_code) hass.bus.listen(EVENT, self._handle_code)
self._brightness = 255 self._brightness: int | None = 255
async def async_added_to_hass(self) -> None: async def async_added_to_hass(self) -> None:
"""Call when entity about to be added to hass.""" """Call when entity about to be added to hass."""
@@ -147,18 +151,18 @@ class PilightBaseDevice(RestoreEntity):
class _ReceiveHandle: class _ReceiveHandle:
def __init__(self, config, echo): def __init__(self, config: dict[str, Any], echo: bool) -> None:
"""Initialize the handle.""" """Initialize the handle."""
self.config_items = config.items() self.config_items = config.items()
self.echo = echo self.echo = echo
def match(self, code): def match(self, code: dict[str, Any]) -> bool:
"""Test if the received code matches the configured values. """Test if the received code matches the configured values.
The received values have to be a subset of the configured options. The received values have to be a subset of the configured options.
""" """
return self.config_items <= code.items() return self.config_items <= code.items()
def run(self, switch, turn_on): def run(self, switch: PilightBaseDevice, turn_on: bool) -> None:
"""Change the state of the switch.""" """Change the state of the switch."""
switch.set_state(turn_on=turn_on, send_code=self.echo) switch.set_state(turn_on=turn_on, send_code=self.echo)

View File

@@ -55,11 +55,11 @@ class PilightLight(PilightBaseDevice, LightEntity):
_attr_color_mode = ColorMode.BRIGHTNESS _attr_color_mode = ColorMode.BRIGHTNESS
_attr_supported_color_modes = {ColorMode.BRIGHTNESS} _attr_supported_color_modes = {ColorMode.BRIGHTNESS}
def __init__(self, hass, name, config): def __init__(self, hass: HomeAssistant, name: str, config: ConfigType) -> None:
"""Initialize a switch.""" """Initialize a switch."""
super().__init__(hass, name, config) super().__init__(hass, name, config)
self._dimlevel_min = config.get(CONF_DIMLEVEL_MIN) self._dimlevel_min: int = config[CONF_DIMLEVEL_MIN]
self._dimlevel_max = config.get(CONF_DIMLEVEL_MAX) self._dimlevel_max: int = config[CONF_DIMLEVEL_MAX]
@property @property
def brightness(self) -> int | None: def brightness(self) -> int | None:

View File

@@ -3,6 +3,7 @@
from __future__ import annotations from __future__ import annotations
import logging import logging
from typing import Any
import voluptuous as vol import voluptuous as vol
@@ -16,7 +17,7 @@ from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from . import EVENT from . import EVENT, EVENT_TYPE
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@@ -44,9 +45,9 @@ def setup_platform(
[ [
PilightSensor( PilightSensor(
hass=hass, hass=hass,
name=config.get(CONF_NAME), name=config[CONF_NAME],
variable=config.get(CONF_VARIABLE), variable=config[CONF_VARIABLE],
payload=config.get(CONF_PAYLOAD), payload=config[CONF_PAYLOAD],
unit_of_measurement=config.get(CONF_UNIT_OF_MEASUREMENT), unit_of_measurement=config.get(CONF_UNIT_OF_MEASUREMENT),
) )
] ]
@@ -58,33 +59,24 @@ class PilightSensor(SensorEntity):
_attr_should_poll = False _attr_should_poll = False
def __init__(self, hass, name, variable, payload, unit_of_measurement): def __init__(
self,
hass: HomeAssistant,
name: str,
variable: str,
payload: dict[str, Any],
unit_of_measurement: str | None,
) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
self._state = None
self._hass = hass self._hass = hass
self._name = name self._attr_name = name
self._variable = variable self._variable = variable
self._payload = payload self._payload = payload
self._unit_of_measurement = unit_of_measurement self._attr_native_unit_of_measurement = unit_of_measurement
hass.bus.listen(EVENT, self._handle_code) hass.bus.listen(EVENT, self._handle_code)
@property def _handle_code(self, call: EVENT_TYPE) -> None:
def name(self):
"""Return the name of the sensor."""
return self._name
@property
def native_unit_of_measurement(self):
"""Return the unit this state is expressed in."""
return self._unit_of_measurement
@property
def native_value(self):
"""Return the state of the entity."""
return self._state
def _handle_code(self, call):
"""Handle received code by the pilight-daemon. """Handle received code by the pilight-daemon.
If the code matches the defined payload If the code matches the defined payload
@@ -96,7 +88,7 @@ class PilightSensor(SensorEntity):
if self._payload.items() <= call.data.items(): if self._payload.items() <= call.data.items():
try: try:
value = call.data[self._variable] value = call.data[self._variable]
self._state = value self._attr_native_value = value
self.schedule_update_ha_state() self.schedule_update_ha_state()
except KeyError: except KeyError:
_LOGGER.error( _LOGGER.error(