Add lacrosse to strict-typing (#86527)

Add lacrosse to strict-typing
This commit is contained in:
Marc Mueller 2023-01-24 14:27:01 +01:00 committed by GitHub
parent 73c4ac53d2
commit e717f56113
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 27 deletions

View File

@ -175,6 +175,7 @@ homeassistant.components.jewish_calendar.*
homeassistant.components.kaleidescape.* homeassistant.components.kaleidescape.*
homeassistant.components.knx.* homeassistant.components.knx.*
homeassistant.components.kraken.* homeassistant.components.kraken.*
homeassistant.components.lacrosse.*
homeassistant.components.lacrosse_view.* homeassistant.components.lacrosse_view.*
homeassistant.components.lametric.* homeassistant.components.lametric.*
homeassistant.components.laundrify.* homeassistant.components.laundrify.*

View File

@ -1,8 +1,9 @@
"""Support for LaCrosse sensor components.""" """Support for LaCrosse sensor components."""
from __future__ import annotations from __future__ import annotations
from datetime import timedelta from datetime import datetime, timedelta
import logging import logging
from typing import Any
import pylacrosse import pylacrosse
from serial import SerialException from serial import SerialException
@ -25,7 +26,7 @@ from homeassistant.const import (
PERCENTAGE, PERCENTAGE,
UnitOfTemperature, UnitOfTemperature,
) )
from homeassistant.core import HomeAssistant, callback from homeassistant.core import CALLBACK_TYPE, HomeAssistant, callback
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import async_generate_entity_id from homeassistant.helpers.entity import async_generate_entity_id
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
@ -44,7 +45,7 @@ CONF_TOGGLE_INTERVAL = "toggle_interval"
CONF_TOGGLE_MASK = "toggle_mask" CONF_TOGGLE_MASK = "toggle_mask"
DEFAULT_DEVICE = "/dev/ttyUSB0" DEFAULT_DEVICE = "/dev/ttyUSB0"
DEFAULT_BAUD = "57600" DEFAULT_BAUD = 57600
DEFAULT_EXPIRE_AFTER = 300 DEFAULT_EXPIRE_AFTER = 300
TYPES = ["battery", "humidity", "temperature"] TYPES = ["battery", "humidity", "temperature"]
@ -61,7 +62,7 @@ SENSOR_SCHEMA = vol.Schema(
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend( PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{ {
vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(SENSOR_SCHEMA), vol.Required(CONF_SENSORS): cv.schema_with_slug_keys(SENSOR_SCHEMA),
vol.Optional(CONF_BAUD, default=DEFAULT_BAUD): cv.string, vol.Optional(CONF_BAUD, default=DEFAULT_BAUD): cv.positive_int,
vol.Optional(CONF_DATARATE): cv.positive_int, vol.Optional(CONF_DATARATE): cv.positive_int,
vol.Optional(CONF_DEVICE, default=DEFAULT_DEVICE): cv.string, vol.Optional(CONF_DEVICE, default=DEFAULT_DEVICE): cv.string,
vol.Optional(CONF_FREQUENCY): cv.positive_int, vol.Optional(CONF_FREQUENCY): cv.positive_int,
@ -79,9 +80,9 @@ def setup_platform(
discovery_info: DiscoveryInfoType | None = None, discovery_info: DiscoveryInfoType | None = None,
) -> None: ) -> None:
"""Set up the LaCrosse sensors.""" """Set up the LaCrosse sensors."""
usb_device = config[CONF_DEVICE] usb_device: str = config[CONF_DEVICE]
baud = int(config[CONF_BAUD]) baud: int = config[CONF_BAUD]
expire_after = config.get(CONF_EXPIRE_AFTER) expire_after: int | None = config.get(CONF_EXPIRE_AFTER)
_LOGGER.debug("%s %s", usb_device, baud) _LOGGER.debug("%s %s", usb_device, baud)
@ -92,7 +93,7 @@ def setup_platform(
_LOGGER.warning("Unable to open serial port: %s", exc) _LOGGER.warning("Unable to open serial port: %s", exc)
return return
hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, lambda event: lacrosse.close()) hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, lambda event: lacrosse.close()) # type: ignore[no-any-return]
if CONF_JEELINK_LED in config: if CONF_JEELINK_LED in config:
lacrosse.led_mode_state(config.get(CONF_JEELINK_LED)) lacrosse.led_mode_state(config.get(CONF_JEELINK_LED))
@ -107,13 +108,13 @@ def setup_platform(
lacrosse.start_scan() lacrosse.start_scan()
sensors = [] sensors: list[LaCrosseSensor] = []
for device, device_config in config[CONF_SENSORS].items(): for device, device_config in config[CONF_SENSORS].items():
_LOGGER.debug("%s %s", device, device_config) _LOGGER.debug("%s %s", device, device_config)
typ = device_config.get(CONF_TYPE) typ: str = device_config[CONF_TYPE]
sensor_class = TYPE_CLASSES[typ] sensor_class = TYPE_CLASSES[typ]
name = device_config.get(CONF_NAME, device) name: str = device_config.get(CONF_NAME, device)
sensors.append( sensors.append(
sensor_class(hass, lacrosse, device, name, expire_after, device_config) sensor_class(hass, lacrosse, device, name, expire_after, device_config)
@ -125,21 +126,28 @@ def setup_platform(
class LaCrosseSensor(SensorEntity): class LaCrosseSensor(SensorEntity):
"""Implementation of a Lacrosse sensor.""" """Implementation of a Lacrosse sensor."""
_temperature = None _temperature: float | None = None
_humidity = None _humidity: int | None = None
_low_battery = None _low_battery: bool | None = None
_new_battery = None _new_battery: bool | None = None
def __init__(self, hass, lacrosse, device_id, name, expire_after, config): def __init__(
self,
hass: HomeAssistant,
lacrosse: pylacrosse.LaCrosse,
device_id: str,
name: str,
expire_after: int | None,
config: ConfigType,
) -> None:
"""Initialize the sensor.""" """Initialize the sensor."""
self.hass = hass self.hass = hass
self.entity_id = async_generate_entity_id( self.entity_id = async_generate_entity_id(
ENTITY_ID_FORMAT, device_id, hass=hass ENTITY_ID_FORMAT, device_id, hass=hass
) )
self._config = config self._config = config
self._value = None
self._expire_after = expire_after self._expire_after = expire_after
self._expiration_trigger = None self._expiration_trigger: CALLBACK_TYPE | None = None
self._attr_name = name self._attr_name = name
lacrosse.register_callback( lacrosse.register_callback(
@ -147,14 +155,16 @@ class LaCrosseSensor(SensorEntity):
) )
@property @property
def extra_state_attributes(self): def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes.""" """Return the state attributes."""
return { return {
"low_battery": self._low_battery, "low_battery": self._low_battery,
"new_battery": self._new_battery, "new_battery": self._new_battery,
} }
def _callback_lacrosse(self, lacrosse_sensor, user_data): def _callback_lacrosse(
self, lacrosse_sensor: pylacrosse.LaCrosseSensor, user_data: None
) -> None:
"""Handle a function that is called from pylacrosse with new values.""" """Handle a function that is called from pylacrosse with new values."""
if self._expire_after is not None and self._expire_after > 0: if self._expire_after is not None and self._expire_after > 0:
# Reset old trigger # Reset old trigger
@ -175,10 +185,9 @@ class LaCrosseSensor(SensorEntity):
self._new_battery = lacrosse_sensor.new_battery self._new_battery = lacrosse_sensor.new_battery
@callback @callback
def value_is_expired(self, *_): def value_is_expired(self, *_: datetime) -> None:
"""Triggered when value is expired.""" """Triggered when value is expired."""
self._expiration_trigger = None self._expiration_trigger = None
self._value = None
self.async_write_ha_state() self.async_write_ha_state()
@ -190,7 +199,7 @@ class LaCrosseTemperature(LaCrosseSensor):
_attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS _attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS
@property @property
def native_value(self): def native_value(self) -> float | None:
"""Return the state of the sensor.""" """Return the state of the sensor."""
return self._temperature return self._temperature
@ -203,7 +212,7 @@ class LaCrosseHumidity(LaCrosseSensor):
_attr_icon = "mdi:water-percent" _attr_icon = "mdi:water-percent"
@property @property
def native_value(self): def native_value(self) -> int | None:
"""Return the state of the sensor.""" """Return the state of the sensor."""
return self._humidity return self._humidity
@ -212,7 +221,7 @@ class LaCrosseBattery(LaCrosseSensor):
"""Implementation of a Lacrosse battery sensor.""" """Implementation of a Lacrosse battery sensor."""
@property @property
def native_value(self): def native_value(self) -> str | None:
"""Return the state of the sensor.""" """Return the state of the sensor."""
if self._low_battery is None: if self._low_battery is None:
return None return None
@ -221,7 +230,7 @@ class LaCrosseBattery(LaCrosseSensor):
return "ok" return "ok"
@property @property
def icon(self): def icon(self) -> str:
"""Icon to use in the frontend.""" """Icon to use in the frontend."""
if self._low_battery is None: if self._low_battery is None:
return "mdi:battery-unknown" return "mdi:battery-unknown"
@ -230,7 +239,7 @@ class LaCrosseBattery(LaCrosseSensor):
return "mdi:battery" return "mdi:battery"
TYPE_CLASSES = { TYPE_CLASSES: dict[str, type[LaCrosseSensor]] = {
"temperature": LaCrosseTemperature, "temperature": LaCrosseTemperature,
"humidity": LaCrosseHumidity, "humidity": LaCrosseHumidity,
"battery": LaCrosseBattery, "battery": LaCrosseBattery,

View File

@ -1504,6 +1504,16 @@ disallow_untyped_defs = true
warn_return_any = true warn_return_any = true
warn_unreachable = true warn_unreachable = true
[mypy-homeassistant.components.lacrosse.*]
check_untyped_defs = true
disallow_incomplete_defs = true
disallow_subclassing_any = true
disallow_untyped_calls = true
disallow_untyped_decorators = true
disallow_untyped_defs = true
warn_return_any = true
warn_unreachable = true
[mypy-homeassistant.components.lacrosse_view.*] [mypy-homeassistant.components.lacrosse_view.*]
check_untyped_defs = true check_untyped_defs = true
disallow_incomplete_defs = true disallow_incomplete_defs = true