Update typing 14 (#48078)

This commit is contained in:
Marc Mueller 2021-03-18 15:08:35 +01:00 committed by GitHub
parent 7d196abc4a
commit dcca29ef68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
73 changed files with 614 additions and 521 deletions

View file

@ -1,6 +1,8 @@
"""The Z-Wave JS integration."""
from __future__ import annotations
import asyncio
from typing import Callable, List
from typing import Callable
from async_timeout import timeout
from zwave_js_server.client import Client as ZwaveClient
@ -226,7 +228,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
entry_hass_data[DATA_CONNECT_FAILED_LOGGED] = False
entry_hass_data[DATA_INVALID_SERVER_VERSION_LOGGED] = False
unsubscribe_callbacks: List[Callable] = []
unsubscribe_callbacks: list[Callable] = []
entry_hass_data[DATA_CLIENT] = client
entry_hass_data[DATA_UNSUBSCRIBE] = unsubscribe_callbacks

View file

@ -3,7 +3,7 @@ from __future__ import annotations
import asyncio
from functools import partial
from typing import Any, Callable, Optional, TypeVar, cast
from typing import Any, Callable, TypeVar, cast
from homeassistant.components.hassio import (
async_create_snapshot,
@ -66,9 +66,9 @@ class AddonManager:
def __init__(self, hass: HomeAssistant) -> None:
"""Set up the add-on manager."""
self._hass = hass
self._install_task: Optional[asyncio.Task] = None
self._start_task: Optional[asyncio.Task] = None
self._update_task: Optional[asyncio.Task] = None
self._install_task: asyncio.Task | None = None
self._start_task: asyncio.Task | None = None
self._update_task: asyncio.Task | None = None
def task_in_progress(self) -> bool:
"""Return True if any of the add-on tasks are in progress."""

View file

@ -1,7 +1,8 @@
"""Websocket API for Z-Wave JS."""
from __future__ import annotations
import dataclasses
import json
from typing import Dict
from aiohttp import hdrs, web, web_exceptions
import voluptuous as vol
@ -399,7 +400,7 @@ def convert_log_level_to_enum(value: str) -> LogLevel:
return LogLevel[value.upper()]
def filename_is_present_if_logging_to_file(obj: Dict) -> Dict:
def filename_is_present_if_logging_to_file(obj: dict) -> dict:
"""Validate that filename is provided if log_to_file is True."""
if obj.get(LOG_TO_FILE, False) and FILENAME not in obj:
raise vol.Invalid("`filename` must be provided if logging to file")

View file

@ -1,7 +1,8 @@
"""Representation of Z-Wave binary sensors."""
from __future__ import annotations
import logging
from typing import Callable, List, Optional, TypedDict
from typing import Callable, TypedDict
from zwave_js_server.client import Client as ZwaveClient
from zwave_js_server.const import CommandClass
@ -56,14 +57,14 @@ class NotificationSensorMapping(TypedDict, total=False):
"""Represent a notification sensor mapping dict type."""
type: int # required
states: List[str]
states: list[str]
device_class: str
enabled: bool
# Mappings for Notification sensors
# https://github.com/zwave-js/node-zwave-js/blob/master/packages/config/config/notifications.json
NOTIFICATION_SENSOR_MAPPINGS: List[NotificationSensorMapping] = [
NOTIFICATION_SENSOR_MAPPINGS: list[NotificationSensorMapping] = [
{
# NotificationType 1: Smoke Alarm - State Id's 1 and 2 - Smoke detected
"type": NOTIFICATION_SMOKE_ALARM,
@ -201,13 +202,13 @@ class PropertySensorMapping(TypedDict, total=False):
"""Represent a property sensor mapping dict type."""
property_name: str # required
on_states: List[str] # required
on_states: list[str] # required
device_class: str
enabled: bool
# Mappings for property sensors
PROPERTY_SENSOR_MAPPINGS: List[PropertySensorMapping] = [
PROPERTY_SENSOR_MAPPINGS: list[PropertySensorMapping] = [
{
"property_name": PROPERTY_DOOR_STATUS,
"on_states": ["open"],
@ -226,7 +227,7 @@ async def async_setup_entry(
@callback
def async_add_binary_sensor(info: ZwaveDiscoveryInfo) -> None:
"""Add Z-Wave Binary Sensor."""
entities: List[BinarySensorEntity] = []
entities: list[BinarySensorEntity] = []
if info.platform_hint == "notification":
# Get all sensors from Notification CC states
@ -268,14 +269,14 @@ class ZWaveBooleanBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
self._name = self.generate_name(include_value_name=True)
@property
def is_on(self) -> Optional[bool]:
def is_on(self) -> bool | None:
"""Return if the sensor is on or off."""
if self.info.primary_value.value is None:
return None
return bool(self.info.primary_value.value)
@property
def device_class(self) -> Optional[str]:
def device_class(self) -> str | None:
"""Return device class."""
if self.info.primary_value.command_class == CommandClass.BATTERY:
return DEVICE_CLASS_BATTERY
@ -314,14 +315,14 @@ class ZWaveNotificationBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
self._mapping_info = self._get_sensor_mapping()
@property
def is_on(self) -> Optional[bool]:
def is_on(self) -> bool | None:
"""Return if the sensor is on or off."""
if self.info.primary_value.value is None:
return None
return int(self.info.primary_value.value) == int(self.state_key)
@property
def device_class(self) -> Optional[str]:
def device_class(self) -> str | None:
"""Return device class."""
return self._mapping_info.get("device_class")
@ -365,14 +366,14 @@ class ZWavePropertyBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
self._name = self.generate_name(include_value_name=True)
@property
def is_on(self) -> Optional[bool]:
def is_on(self) -> bool | None:
"""Return if the sensor is on or off."""
if self.info.primary_value.value is None:
return None
return self.info.primary_value.value in self._mapping_info["on_states"]
@property
def device_class(self) -> Optional[str]:
def device_class(self) -> str | None:
"""Return device class."""
return self._mapping_info.get("device_class")

View file

@ -1,5 +1,7 @@
"""Representation of Z-Wave thermostats."""
from typing import Any, Callable, Dict, List, Optional, cast
from __future__ import annotations
from typing import Any, Callable, cast
from zwave_js_server.client import Client as ZwaveClient
from zwave_js_server.const import (
@ -50,7 +52,7 @@ from .entity import ZWaveBaseEntity
# Map Z-Wave HVAC Mode to Home Assistant value
# Note: We treat "auto" as "heat_cool" as most Z-Wave devices
# report auto_changeover as auto without schedule support.
ZW_HVAC_MODE_MAP: Dict[int, str] = {
ZW_HVAC_MODE_MAP: dict[int, str] = {
ThermostatMode.OFF: HVAC_MODE_OFF,
ThermostatMode.HEAT: HVAC_MODE_HEAT,
ThermostatMode.COOL: HVAC_MODE_COOL,
@ -67,7 +69,7 @@ ZW_HVAC_MODE_MAP: Dict[int, str] = {
ThermostatMode.FULL_POWER: HVAC_MODE_HEAT,
}
HVAC_CURRENT_MAP: Dict[int, str] = {
HVAC_CURRENT_MAP: dict[int, str] = {
ThermostatOperatingState.IDLE: CURRENT_HVAC_IDLE,
ThermostatOperatingState.PENDING_HEAT: CURRENT_HVAC_IDLE,
ThermostatOperatingState.HEATING: CURRENT_HVAC_HEAT,
@ -94,7 +96,7 @@ async def async_setup_entry(
@callback
def async_add_climate(info: ZwaveDiscoveryInfo) -> None:
"""Add Z-Wave Climate."""
entities: List[ZWaveBaseEntity] = []
entities: list[ZWaveBaseEntity] = []
entities.append(ZWaveClimate(config_entry, client, info))
async_add_entities(entities)
@ -116,14 +118,14 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
) -> None:
"""Initialize lock."""
super().__init__(config_entry, client, info)
self._hvac_modes: Dict[str, Optional[int]] = {}
self._hvac_presets: Dict[str, Optional[int]] = {}
self._unit_value: Optional[ZwaveValue] = None
self._hvac_modes: dict[str, int | None] = {}
self._hvac_presets: dict[str, int | None] = {}
self._unit_value: ZwaveValue | None = None
self._current_mode = self.get_zwave_value(
THERMOSTAT_MODE_PROPERTY, command_class=CommandClass.THERMOSTAT_MODE
)
self._setpoint_values: Dict[ThermostatSetpointType, ZwaveValue] = {}
self._setpoint_values: dict[ThermostatSetpointType, ZwaveValue] = {}
for enum in ThermostatSetpointType:
self._setpoint_values[enum] = self.get_zwave_value(
THERMOSTAT_SETPOINT_PROPERTY,
@ -184,8 +186,8 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
def _set_modes_and_presets(self) -> None:
"""Convert Z-Wave Thermostat modes into Home Assistant modes and presets."""
all_modes: Dict[str, Optional[int]] = {}
all_presets: Dict[str, Optional[int]] = {PRESET_NONE: None}
all_modes: dict[str, int | None] = {}
all_presets: dict[str, int | None] = {PRESET_NONE: None}
# Z-Wave uses one list for both modes and presets.
# Iterate over all Z-Wave ThermostatModes and extract the hvac modes and presets.
@ -208,7 +210,7 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
self._hvac_presets = all_presets
@property
def _current_mode_setpoint_enums(self) -> List[Optional[ThermostatSetpointType]]:
def _current_mode_setpoint_enums(self) -> list[ThermostatSetpointType | None]:
"""Return the list of enums that are relevant to the current thermostat mode."""
if self._current_mode is None:
# Thermostat(valve) with no support for setting a mode is considered heating-only
@ -238,12 +240,12 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
return ZW_HVAC_MODE_MAP.get(int(self._current_mode.value), HVAC_MODE_HEAT_COOL)
@property
def hvac_modes(self) -> List[str]:
def hvac_modes(self) -> list[str]:
"""Return the list of available hvac operation modes."""
return list(self._hvac_modes)
@property
def hvac_action(self) -> Optional[str]:
def hvac_action(self) -> str | None:
"""Return the current running hvac operation if supported."""
if not self._operating_state:
return None
@ -253,17 +255,17 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
return HVAC_CURRENT_MAP.get(int(self._operating_state.value))
@property
def current_humidity(self) -> Optional[int]:
def current_humidity(self) -> int | None:
"""Return the current humidity level."""
return self._current_humidity.value if self._current_humidity else None
@property
def current_temperature(self) -> Optional[float]:
def current_temperature(self) -> float | None:
"""Return the current temperature."""
return self._current_temp.value if self._current_temp else None
@property
def target_temperature(self) -> Optional[float]:
def target_temperature(self) -> float | None:
"""Return the temperature we try to reach."""
if self._current_mode and self._current_mode.value is None:
# guard missing value
@ -275,7 +277,7 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
return temp.value if temp else None
@property
def target_temperature_high(self) -> Optional[float]:
def target_temperature_high(self) -> float | None:
"""Return the highbound target temperature we try to reach."""
if self._current_mode and self._current_mode.value is None:
# guard missing value
@ -287,7 +289,7 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
return temp.value if temp else None
@property
def target_temperature_low(self) -> Optional[float]:
def target_temperature_low(self) -> float | None:
"""Return the lowbound target temperature we try to reach."""
if self._current_mode and self._current_mode.value is None:
# guard missing value
@ -297,7 +299,7 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
return None
@property
def preset_mode(self) -> Optional[str]:
def preset_mode(self) -> str | None:
"""Return the current preset mode, e.g., home, away, temp."""
if self._current_mode and self._current_mode.value is None:
# guard missing value
@ -310,12 +312,12 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
return PRESET_NONE
@property
def preset_modes(self) -> Optional[List[str]]:
def preset_modes(self) -> list[str] | None:
"""Return a list of available preset modes."""
return list(self._hvac_presets)
@property
def fan_mode(self) -> Optional[str]:
def fan_mode(self) -> str | None:
"""Return the fan setting."""
if (
self._fan_mode
@ -326,14 +328,14 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
return None
@property
def fan_modes(self) -> Optional[List[str]]:
def fan_modes(self) -> list[str] | None:
"""Return the list of available fan modes."""
if self._fan_mode and self._fan_mode.metadata.states:
return list(self._fan_mode.metadata.states.values())
return None
@property
def extra_state_attributes(self) -> Optional[Dict[str, str]]:
def extra_state_attributes(self) -> dict[str, str] | None:
"""Return the optional state attributes."""
if (
self._fan_state
@ -373,7 +375,7 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
hvac_mode: Optional[str] = kwargs.get(ATTR_HVAC_MODE)
hvac_mode: str | None = kwargs.get(ATTR_HVAC_MODE)
if hvac_mode is not None:
await self.async_set_hvac_mode(hvac_mode)
@ -381,7 +383,7 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
setpoint: ZwaveValue = self._setpoint_value(
self._current_mode_setpoint_enums[0]
)
target_temp: Optional[float] = kwargs.get(ATTR_TEMPERATURE)
target_temp: float | None = kwargs.get(ATTR_TEMPERATURE)
if target_temp is not None:
await self.info.node.async_set_value(setpoint, target_temp)
elif len(self._current_mode_setpoint_enums) == 2:
@ -391,8 +393,8 @@ class ZWaveClimate(ZWaveBaseEntity, ClimateEntity):
setpoint_high: ZwaveValue = self._setpoint_value(
self._current_mode_setpoint_enums[1]
)
target_temp_low: Optional[float] = kwargs.get(ATTR_TARGET_TEMP_LOW)
target_temp_high: Optional[float] = kwargs.get(ATTR_TARGET_TEMP_HIGH)
target_temp_low: float | None = kwargs.get(ATTR_TARGET_TEMP_LOW)
target_temp_high: float | None = kwargs.get(ATTR_TARGET_TEMP_HIGH)
if target_temp_low is not None:
await self.info.node.async_set_value(setpoint_low, target_temp_low)
if target_temp_high is not None:

View file

@ -1,7 +1,9 @@
"""Config flow for Z-Wave JS integration."""
from __future__ import annotations
import asyncio
import logging
from typing import Any, Dict, Optional, cast
from typing import Any, cast
import aiohttp
from async_timeout import timeout
@ -76,18 +78,18 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
def __init__(self) -> None:
"""Set up flow instance."""
self.network_key: Optional[str] = None
self.usb_path: Optional[str] = None
self.network_key: str | None = None
self.usb_path: str | None = None
self.use_addon = False
self.ws_address: Optional[str] = None
self.ws_address: str | None = None
# If we install the add-on we should uninstall it on entry remove.
self.integration_created_addon = False
self.install_task: Optional[asyncio.Task] = None
self.start_task: Optional[asyncio.Task] = None
self.install_task: asyncio.Task | None = None
self.start_task: asyncio.Task | None = None
async def async_step_user(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Handle the initial step."""
if is_hassio(self.hass): # type: ignore # no-untyped-call
return await self.async_step_on_supervisor()
@ -95,8 +97,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return await self.async_step_manual()
async def async_step_manual(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Handle a manual configuration."""
if user_input is None:
return self.async_show_form(
@ -133,8 +135,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
)
async def async_step_hassio( # type: ignore # override
self, discovery_info: Dict[str, Any]
) -> Dict[str, Any]:
self, discovery_info: dict[str, Any]
) -> dict[str, Any]:
"""Receive configuration from add-on discovery info.
This flow is triggered by the Z-Wave JS add-on.
@ -151,8 +153,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return await self.async_step_hassio_confirm()
async def async_step_hassio_confirm(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Confirm the add-on discovery."""
if user_input is not None:
return await self.async_step_on_supervisor(
@ -162,7 +164,7 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_show_form(step_id="hassio_confirm")
@callback
def _async_create_entry_from_vars(self) -> Dict[str, Any]:
def _async_create_entry_from_vars(self) -> dict[str, Any]:
"""Return a config entry for the flow."""
return self.async_create_entry(
title=TITLE,
@ -176,8 +178,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
)
async def async_step_on_supervisor(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Handle logic when on Supervisor host."""
if user_input is None:
return self.async_show_form(
@ -200,8 +202,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return await self.async_step_install_addon()
async def async_step_install_addon(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Install Z-Wave JS add-on."""
if not self.install_task:
self.install_task = self.hass.async_create_task(self._async_install_addon())
@ -220,18 +222,18 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_show_progress_done(next_step_id="configure_addon")
async def async_step_install_failed(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Add-on installation failed."""
return self.async_abort(reason="addon_install_failed")
async def async_step_configure_addon(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Ask for config for Z-Wave JS add-on."""
addon_config = await self._async_get_addon_config()
errors: Dict[str, str] = {}
errors: dict[str, str] = {}
if user_input is not None:
self.network_key = user_input[CONF_NETWORK_KEY]
@ -262,8 +264,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
)
async def async_step_start_addon(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Start Z-Wave JS add-on."""
if not self.start_task:
self.start_task = self.hass.async_create_task(self._async_start_addon())
@ -280,8 +282,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_show_progress_done(next_step_id="finish_addon_setup")
async def async_step_start_failed(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Add-on start failed."""
return self.async_abort(reason="addon_start_failed")
@ -317,8 +319,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
)
async def async_step_finish_addon_setup(
self, user_input: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
self, user_input: dict[str, Any] | None = None
) -> dict[str, Any]:
"""Prepare info needed to complete the config entry.
Get add-on discovery info and server version info.

View file

@ -1,6 +1,8 @@
"""Support for Z-Wave cover devices."""
from __future__ import annotations
import logging
from typing import Any, Callable, List, Optional
from typing import Any, Callable
from zwave_js_server.client import Client as ZwaveClient
from zwave_js_server.model.value import Value as ZwaveValue
@ -42,7 +44,7 @@ async def async_setup_entry(
@callback
def async_add_cover(info: ZwaveDiscoveryInfo) -> None:
"""Add Z-Wave cover."""
entities: List[ZWaveBaseEntity] = []
entities: list[ZWaveBaseEntity] = []
if info.platform_hint == "motorized_barrier":
entities.append(ZwaveMotorizedBarrier(config_entry, client, info))
else:
@ -72,7 +74,7 @@ class ZWaveCover(ZWaveBaseEntity, CoverEntity):
"""Representation of a Z-Wave Cover device."""
@property
def is_closed(self) -> Optional[bool]:
def is_closed(self) -> bool | None:
"""Return true if cover is closed."""
if self.info.primary_value.value is None:
# guard missing value
@ -80,7 +82,7 @@ class ZWaveCover(ZWaveBaseEntity, CoverEntity):
return bool(self.info.primary_value.value == 0)
@property
def current_cover_position(self) -> Optional[int]:
def current_cover_position(self) -> int | None:
"""Return the current position of cover where 0 means closed and 100 is fully open."""
if self.info.primary_value.value is None:
# guard missing value
@ -130,31 +132,31 @@ class ZwaveMotorizedBarrier(ZWaveBaseEntity, CoverEntity):
)
@property
def supported_features(self) -> Optional[int]:
def supported_features(self) -> int | None:
"""Flag supported features."""
return SUPPORT_OPEN | SUPPORT_CLOSE
@property
def device_class(self) -> Optional[str]:
def device_class(self) -> str | None:
"""Return the class of this device, from component DEVICE_CLASSES."""
return DEVICE_CLASS_GARAGE
@property
def is_opening(self) -> Optional[bool]:
def is_opening(self) -> bool | None:
"""Return if the cover is opening or not."""
if self.info.primary_value.value is None:
return None
return bool(self.info.primary_value.value == BARRIER_STATE_OPENING)
@property
def is_closing(self) -> Optional[bool]:
def is_closing(self) -> bool | None:
"""Return if the cover is closing or not."""
if self.info.primary_value.value is None:
return None
return bool(self.info.primary_value.value == BARRIER_STATE_CLOSING)
@property
def is_closed(self) -> Optional[bool]:
def is_closed(self) -> bool | None:
"""Return if the cover is closed or not."""
if self.info.primary_value.value is None:
return None

View file

@ -1,7 +1,8 @@
"""Map Z-Wave nodes and values to Home Assistant entities."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Generator, List, Optional, Set, Union
from typing import Generator
from zwave_js_server.const import CommandClass
from zwave_js_server.model.device_class import DeviceClassItem
@ -22,7 +23,7 @@ class ZwaveDiscoveryInfo:
# the home assistant platform for which an entity should be created
platform: str
# hint for the platform about this discovered entity
platform_hint: Optional[str] = ""
platform_hint: str | None = ""
@dataclass
@ -35,13 +36,13 @@ class ZWaveValueDiscoverySchema:
"""
# [optional] the value's command class must match ANY of these values
command_class: Optional[Set[int]] = None
command_class: set[int] | None = None
# [optional] the value's endpoint must match ANY of these values
endpoint: Optional[Set[int]] = None
endpoint: set[int] | None = None
# [optional] the value's property must match ANY of these values
property: Optional[Set[Union[str, int]]] = None
property: set[str | int] | None = None
# [optional] the value's metadata_type must match ANY of these values
type: Optional[Set[str]] = None
type: set[str] | None = None
@dataclass
@ -58,25 +59,25 @@ class ZWaveDiscoverySchema:
# primary value belonging to this discovery scheme
primary_value: ZWaveValueDiscoverySchema
# [optional] hint for platform
hint: Optional[str] = None
hint: str | None = None
# [optional] the node's manufacturer_id must match ANY of these values
manufacturer_id: Optional[Set[int]] = None
manufacturer_id: set[int] | None = None
# [optional] the node's product_id must match ANY of these values
product_id: Optional[Set[int]] = None
product_id: set[int] | None = None
# [optional] the node's product_type must match ANY of these values
product_type: Optional[Set[int]] = None
product_type: set[int] | None = None
# [optional] the node's firmware_version must match ANY of these values
firmware_version: Optional[Set[str]] = None
firmware_version: set[str] | None = None
# [optional] the node's basic device class must match ANY of these values
device_class_basic: Optional[Set[Union[str, int]]] = None
device_class_basic: set[str | int] | None = None
# [optional] the node's generic device class must match ANY of these values
device_class_generic: Optional[Set[Union[str, int]]] = None
device_class_generic: set[str | int] | None = None
# [optional] the node's specific device class must match ANY of these values
device_class_specific: Optional[Set[Union[str, int]]] = None
device_class_specific: set[str | int] | None = None
# [optional] additional values that ALL need to be present on the node for this scheme to pass
required_values: Optional[List[ZWaveValueDiscoverySchema]] = None
required_values: list[ZWaveValueDiscoverySchema] | None = None
# [optional] additional values that MAY NOT be present on the node for this scheme to pass
absent_values: Optional[List[ZWaveValueDiscoverySchema]] = None
absent_values: list[ZWaveValueDiscoverySchema] | None = None
# [optional] bool to specify if this primary value may be discovered by multiple platforms
allow_multi: bool = False
@ -487,7 +488,7 @@ def check_value(value: ZwaveValue, schema: ZWaveValueDiscoverySchema) -> bool:
@callback
def check_device_class(
device_class: DeviceClassItem, required_value: Optional[Set[Union[str, int]]]
device_class: DeviceClassItem, required_value: set[str | int] | None
) -> bool:
"""Check if device class id or label matches."""
if required_value is None:

View file

@ -1,7 +1,7 @@
"""Generic Z-Wave Entity Class."""
from __future__ import annotations
import logging
from typing import List, Optional, Union
from zwave_js_server.client import Client as ZwaveClient
from zwave_js_server.model.value import Value as ZwaveValue, get_value_id
@ -97,8 +97,8 @@ class ZWaveBaseEntity(Entity):
def generate_name(
self,
include_value_name: bool = False,
alternate_value_name: Optional[str] = None,
additional_info: Optional[List[str]] = None,
alternate_value_name: str | None = None,
additional_info: list[str] | None = None,
) -> str:
"""Generate entity name."""
if additional_info is None:
@ -167,13 +167,13 @@ class ZWaveBaseEntity(Entity):
@callback
def get_zwave_value(
self,
value_property: Union[str, int],
command_class: Optional[int] = None,
endpoint: Optional[int] = None,
value_property_key: Optional[int] = None,
value_property: str | int,
command_class: int | None = None,
endpoint: int | None = None,
value_property_key: int | None = None,
add_to_watched_value_ids: bool = True,
check_all_endpoints: bool = False,
) -> Optional[ZwaveValue]:
) -> ZwaveValue | None:
"""Return specific ZwaveValue on this ZwaveNode."""
# use commandclass and endpoint from primary value if omitted
return_value = None

View file

@ -1,6 +1,8 @@
"""Support for Z-Wave fans."""
from __future__ import annotations
import math
from typing import Any, Callable, List, Optional
from typing import Any, Callable
from zwave_js_server.client import Client as ZwaveClient
@ -36,7 +38,7 @@ async def async_setup_entry(
@callback
def async_add_fan(info: ZwaveDiscoveryInfo) -> None:
"""Add Z-Wave fan."""
entities: List[ZWaveBaseEntity] = []
entities: list[ZWaveBaseEntity] = []
entities.append(ZwaveFan(config_entry, client, info))
async_add_entities(entities)
@ -52,7 +54,7 @@ async def async_setup_entry(
class ZwaveFan(ZWaveBaseEntity, FanEntity):
"""Representation of a Z-Wave fan."""
async def async_set_percentage(self, percentage: Optional[int]) -> None:
async def async_set_percentage(self, percentage: int | None) -> None:
"""Set the speed percentage of the fan."""
target_value = self.get_zwave_value("targetValue")
@ -68,9 +70,9 @@ class ZwaveFan(ZWaveBaseEntity, FanEntity):
async def async_turn_on(
self,
speed: Optional[str] = None,
percentage: Optional[int] = None,
preset_mode: Optional[str] = None,
speed: str | None = None,
percentage: int | None = None,
preset_mode: str | None = None,
**kwargs: Any,
) -> None:
"""Turn the device on."""
@ -82,7 +84,7 @@ class ZwaveFan(ZWaveBaseEntity, FanEntity):
await self.info.node.async_set_value(target_value, 0)
@property
def is_on(self) -> Optional[bool]: # type: ignore
def is_on(self) -> bool | None: # type: ignore
"""Return true if device is on (speed above 0)."""
if self.info.primary_value.value is None:
# guard missing value
@ -90,7 +92,7 @@ class ZwaveFan(ZWaveBaseEntity, FanEntity):
return bool(self.info.primary_value.value > 0)
@property
def percentage(self) -> Optional[int]:
def percentage(self) -> int | None:
"""Return the current speed percentage."""
if self.info.primary_value.value is None:
# guard missing value

View file

@ -1,5 +1,7 @@
"""Helper functions for Z-Wave JS integration."""
from typing import List, Tuple, cast
from __future__ import annotations
from typing import cast
from zwave_js_server.client import Client as ZwaveClient
from zwave_js_server.model.node import Node as ZwaveNode
@ -19,13 +21,13 @@ def get_unique_id(home_id: str, value_id: str) -> str:
@callback
def get_device_id(client: ZwaveClient, node: ZwaveNode) -> Tuple[str, str]:
def get_device_id(client: ZwaveClient, node: ZwaveNode) -> tuple[str, str]:
"""Get device registry identifier for Z-Wave node."""
return (DOMAIN, f"{client.driver.controller.home_id}-{node.node_id}")
@callback
def get_home_and_node_id_from_device_id(device_id: Tuple[str, str]) -> List[str]:
def get_home_and_node_id_from_device_id(device_id: tuple[str, str]) -> list[str]:
"""
Get home ID and node ID for Z-Wave device registry entry.

View file

@ -1,6 +1,8 @@
"""Support for Z-Wave lights."""
from __future__ import annotations
import logging
from typing import Any, Callable, Dict, Optional, Tuple
from typing import Any, Callable
from zwave_js_server.client import Client as ZwaveClient
from zwave_js_server.const import ColorComponent, CommandClass
@ -85,9 +87,9 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity):
self._supports_color = False
self._supports_white_value = False
self._supports_color_temp = False
self._hs_color: Optional[Tuple[float, float]] = None
self._white_value: Optional[int] = None
self._color_temp: Optional[int] = None
self._hs_color: tuple[float, float] | None = None
self._white_value: int | None = None
self._color_temp: int | None = None
self._min_mireds = 153 # 6500K as a safe default
self._max_mireds = 370 # 2700K as a safe default
self._supported_features = SUPPORT_BRIGHTNESS
@ -126,17 +128,17 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity):
return self.brightness > 0
@property
def hs_color(self) -> Optional[Tuple[float, float]]:
def hs_color(self) -> tuple[float, float] | None:
"""Return the hs color."""
return self._hs_color
@property
def white_value(self) -> Optional[int]:
def white_value(self) -> int | None:
"""Return the white value of this light between 0..255."""
return self._white_value
@property
def color_temp(self) -> Optional[int]:
def color_temp(self) -> int | None:
"""Return the color temperature."""
return self._color_temp
@ -220,7 +222,7 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity):
"""Turn the light off."""
await self._async_set_brightness(0, kwargs.get(ATTR_TRANSITION))
async def _async_set_colors(self, colors: Dict[ColorComponent, int]) -> None:
async def _async_set_colors(self, colors: dict[ColorComponent, int]) -> None:
"""Set (multiple) defined colors to given value(s)."""
# prefer the (new) combined color property
# https://github.com/zwave-js/node-zwave-js/pull/1782
@ -258,7 +260,7 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity):
await self.info.node.async_set_value(target_zwave_value, new_value)
async def _async_set_brightness(
self, brightness: Optional[int], transition: Optional[int] = None
self, brightness: int | None, transition: int | None = None
) -> None:
"""Set new brightness to light."""
if brightness is None:
@ -273,9 +275,7 @@ class ZwaveLight(ZWaveBaseEntity, LightEntity):
# setting a value requires setting targetValue
await self.info.node.async_set_value(self._target_value, zwave_brightness)
async def _async_set_transition_duration(
self, duration: Optional[int] = None
) -> None:
async def _async_set_transition_duration(self, duration: int | None = None) -> None:
"""Set the transition time for the brightness value."""
if self._dimming_duration is None:
return

View file

@ -1,6 +1,8 @@
"""Representation of Z-Wave locks."""
from __future__ import annotations
import logging
from typing import Any, Callable, Dict, List, Optional, Union
from typing import Any, Callable
import voluptuous as vol
from zwave_js_server.client import Client as ZwaveClient
@ -28,7 +30,7 @@ from .entity import ZWaveBaseEntity
LOGGER = logging.getLogger(__name__)
STATE_TO_ZWAVE_MAP: Dict[int, Dict[str, Union[int, bool]]] = {
STATE_TO_ZWAVE_MAP: dict[int, dict[str, int | bool]] = {
CommandClass.DOOR_LOCK: {
STATE_UNLOCKED: DoorLockMode.UNSECURED,
STATE_LOCKED: DoorLockMode.SECURED,
@ -52,7 +54,7 @@ async def async_setup_entry(
@callback
def async_add_lock(info: ZwaveDiscoveryInfo) -> None:
"""Add Z-Wave Lock."""
entities: List[ZWaveBaseEntity] = []
entities: list[ZWaveBaseEntity] = []
entities.append(ZWaveLock(config_entry, client, info))
async_add_entities(entities)
@ -88,7 +90,7 @@ class ZWaveLock(ZWaveBaseEntity, LockEntity):
"""Representation of a Z-Wave lock."""
@property
def is_locked(self) -> Optional[bool]:
def is_locked(self) -> bool | None:
"""Return true if the lock is locked."""
if self.info.primary_value.value is None:
# guard missing value
@ -100,7 +102,7 @@ class ZWaveLock(ZWaveBaseEntity, LockEntity):
) == int(self.info.primary_value.value)
async def _set_lock_state(
self, target_state: str, **kwargs: Dict[str, Any]
self, target_state: str, **kwargs: dict[str, Any]
) -> None:
"""Set the lock state."""
target_value: ZwaveValue = self.get_zwave_value(
@ -112,11 +114,11 @@ class ZWaveLock(ZWaveBaseEntity, LockEntity):
STATE_TO_ZWAVE_MAP[self.info.primary_value.command_class][target_state],
)
async def async_lock(self, **kwargs: Dict[str, Any]) -> None:
async def async_lock(self, **kwargs: dict[str, Any]) -> None:
"""Lock the lock."""
await self._set_lock_state(STATE_LOCKED)
async def async_unlock(self, **kwargs: Dict[str, Any]) -> None:
async def async_unlock(self, **kwargs: dict[str, Any]) -> None:
"""Unlock the lock."""
await self._set_lock_state(STATE_UNLOCKED)

View file

@ -1,6 +1,7 @@
"""Functions used to migrate unique IDs for Z-Wave JS entities."""
from __future__ import annotations
import logging
from typing import List
from zwave_js_server.client import Client as ZwaveClient
from zwave_js_server.model.value import Value as ZwaveValue
@ -85,7 +86,7 @@ def async_migrate_discovered_value(
@callback
def get_old_value_ids(value: ZwaveValue) -> List[str]:
def get_old_value_ids(value: ZwaveValue) -> list[str]:
"""Get old value IDs so we can migrate entity unique ID."""
value_ids = []

View file

@ -1,5 +1,7 @@
"""Support for Z-Wave controls using the number platform."""
from typing import Callable, List, Optional
from __future__ import annotations
from typing import Callable
from zwave_js_server.client import Client as ZwaveClient
@ -22,7 +24,7 @@ async def async_setup_entry(
@callback
def async_add_number(info: ZwaveDiscoveryInfo) -> None:
"""Add Z-Wave number entity."""
entities: List[ZWaveBaseEntity] = []
entities: list[ZWaveBaseEntity] = []
entities.append(ZwaveNumberEntity(config_entry, client, info))
async_add_entities(entities)
@ -66,14 +68,14 @@ class ZwaveNumberEntity(ZWaveBaseEntity, NumberEntity):
return float(self.info.primary_value.metadata.max)
@property
def value(self) -> Optional[float]: # type: ignore
def value(self) -> float | None: # type: ignore
"""Return the entity value."""
if self.info.primary_value.value is None:
return None
return float(self.info.primary_value.value)
@property
def unit_of_measurement(self) -> Optional[str]:
def unit_of_measurement(self) -> str | None:
"""Return the unit of measurement of this entity, if any."""
if self.info.primary_value.metadata.unit is None:
return None

View file

@ -1,7 +1,8 @@
"""Representation of Z-Wave sensors."""
from __future__ import annotations
import logging
from typing import Callable, Dict, List, Optional
from typing import Callable
from zwave_js_server.client import Client as ZwaveClient
from zwave_js_server.const import CommandClass
@ -39,7 +40,7 @@ async def async_setup_entry(
@callback
def async_add_sensor(info: ZwaveDiscoveryInfo) -> None:
"""Add Z-Wave Sensor."""
entities: List[ZWaveBaseEntity] = []
entities: list[ZWaveBaseEntity] = []
if info.platform_hint == "string_sensor":
entities.append(ZWaveStringSensor(config_entry, client, info))
@ -80,7 +81,7 @@ class ZwaveSensorBase(ZWaveBaseEntity):
self._name = self.generate_name(include_value_name=True)
@property
def device_class(self) -> Optional[str]:
def device_class(self) -> str | None:
"""Return the device class of the sensor."""
if self.info.primary_value.command_class == CommandClass.BATTERY:
return DEVICE_CLASS_BATTERY
@ -122,14 +123,14 @@ class ZWaveStringSensor(ZwaveSensorBase):
"""Representation of a Z-Wave String sensor."""
@property
def state(self) -> Optional[str]:
def state(self) -> str | None:
"""Return state of the sensor."""
if self.info.primary_value.value is None:
return None
return str(self.info.primary_value.value)
@property
def unit_of_measurement(self) -> Optional[str]:
def unit_of_measurement(self) -> str | None:
"""Return unit of measurement the value is expressed in."""
if self.info.primary_value.metadata.unit is None:
return None
@ -161,7 +162,7 @@ class ZWaveNumericSensor(ZwaveSensorBase):
return round(float(self.info.primary_value.value), 2)
@property
def unit_of_measurement(self) -> Optional[str]:
def unit_of_measurement(self) -> str | None:
"""Return unit of measurement the value is expressed in."""
if self.info.primary_value.metadata.unit is None:
return None
@ -191,7 +192,7 @@ class ZWaveListSensor(ZwaveSensorBase):
)
@property
def state(self) -> Optional[str]:
def state(self) -> str | None:
"""Return state of the sensor."""
if self.info.primary_value.value is None:
return None
@ -205,7 +206,7 @@ class ZWaveListSensor(ZwaveSensorBase):
)
@property
def extra_state_attributes(self) -> Optional[Dict[str, str]]:
def extra_state_attributes(self) -> dict[str, str] | None:
"""Return the device specific state attributes."""
# add the value's int value as property for multi-value (list) items
return {"value": self.info.primary_value.value}

View file

@ -1,7 +1,7 @@
"""Methods and classes related to executing Z-Wave commands and publishing these to hass."""
from __future__ import annotations
import logging
from typing import Dict, Set, Union
import voluptuous as vol
from zwave_js_server.model.node import Node as ZwaveNode
@ -20,8 +20,8 @@ _LOGGER = logging.getLogger(__name__)
def parameter_name_does_not_need_bitmask(
val: Dict[str, Union[int, str]]
) -> Dict[str, Union[int, str]]:
val: dict[str, int | str]
) -> dict[str, int | str]:
"""Validate that if a parameter name is provided, bitmask is not as well."""
if isinstance(val[const.ATTR_CONFIG_PARAMETER], str) and (
val.get(const.ATTR_CONFIG_PARAMETER_BITMASK)
@ -88,7 +88,7 @@ class ZWaveServices:
async def async_set_config_parameter(self, service: ServiceCall) -> None:
"""Set a config value on a node."""
nodes: Set[ZwaveNode] = set()
nodes: set[ZwaveNode] = set()
if ATTR_ENTITY_ID in service.data:
nodes |= {
async_get_node_from_entity_id(self._hass, entity_id)

View file

@ -1,7 +1,8 @@
"""Representation of Z-Wave switches."""
from __future__ import annotations
import logging
from typing import Any, Callable, List, Optional
from typing import Any, Callable
from zwave_js_server.client import Client as ZwaveClient
@ -30,7 +31,7 @@ async def async_setup_entry(
@callback
def async_add_switch(info: ZwaveDiscoveryInfo) -> None:
"""Add Z-Wave Switch."""
entities: List[ZWaveBaseEntity] = []
entities: list[ZWaveBaseEntity] = []
if info.platform_hint == "barrier_event_signaling_state":
entities.append(
ZWaveBarrierEventSignalingSwitch(config_entry, client, info)
@ -53,7 +54,7 @@ class ZWaveSwitch(ZWaveBaseEntity, SwitchEntity):
"""Representation of a Z-Wave switch."""
@property
def is_on(self) -> Optional[bool]: # type: ignore
def is_on(self) -> bool | None: # type: ignore
"""Return a boolean for the state of the switch."""
if self.info.primary_value.value is None:
# guard missing value
@ -85,7 +86,7 @@ class ZWaveBarrierEventSignalingSwitch(ZWaveBaseEntity, SwitchEntity):
"""Initialize a ZWaveBarrierEventSignalingSwitch entity."""
super().__init__(config_entry, client, info)
self._name = self.generate_name(include_value_name=True)
self._state: Optional[bool] = None
self._state: bool | None = None
self._update_state()
@ -100,7 +101,7 @@ class ZWaveBarrierEventSignalingSwitch(ZWaveBaseEntity, SwitchEntity):
return self._name
@property
def is_on(self) -> Optional[bool]: # type: ignore
def is_on(self) -> bool | None: # type: ignore
"""Return a boolean for the state of the switch."""
return self._state