diff --git a/homeassistant/components/zha/api.py b/homeassistant/components/zha/api.py index 737bef5ddff..cc4dd45689e 100644 --- a/homeassistant/components/zha/api.py +++ b/homeassistant/components/zha/api.py @@ -346,7 +346,7 @@ async def websocket_get_groupable_devices( groupable_devices = [] for device in devices: - entity_refs = zha_gateway.device_registry.get(device.ieee) + entity_refs = zha_gateway.device_registry[device.ieee] for ep_id in device.async_get_groupable_endpoints(): groupable_devices.append( { @@ -456,6 +456,7 @@ async def websocket_add_group( group_id: int | None = msg.get(GROUP_ID) members: list[GroupMember] | None = msg.get(ATTR_MEMBERS) group = await zha_gateway.async_create_zigpy_group(group_name, members, group_id) + assert group connection.send_result(msg[ID], group.group_info) @@ -559,7 +560,7 @@ async def websocket_reconfigure_node( """Reconfigure a ZHA nodes entities by its ieee address.""" zha_gateway: ZHAGateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY] ieee: EUI64 = msg[ATTR_IEEE] - device: ZHADevice = zha_gateway.get_device(ieee) + device: ZHADevice | None = zha_gateway.get_device(ieee) async def forward_messages(data): """Forward events to websocket.""" @@ -577,6 +578,7 @@ async def websocket_reconfigure_node( connection.subscriptions[msg["id"]] = async_cleanup _LOGGER.debug("Reconfiguring node with ieee_address: %s", ieee) + assert device hass.async_create_task(device.async_configure()) @@ -905,6 +907,7 @@ async def websocket_bind_group( group_id: int = msg[GROUP_ID] bindings: list[ClusterBinding] = msg[BINDINGS] source_device = zha_gateway.get_device(source_ieee) + assert source_device await source_device.async_bind_to_group(group_id, bindings) @@ -927,6 +930,7 @@ async def websocket_unbind_group( group_id: int = msg[GROUP_ID] bindings: list[ClusterBinding] = msg[BINDINGS] source_device = zha_gateway.get_device(source_ieee) + assert source_device await source_device.async_unbind_from_group(group_id, bindings) @@ -941,6 +945,8 @@ async def async_binding_operation( source_device = zha_gateway.get_device(source_ieee) target_device = zha_gateway.get_device(target_ieee) + assert source_device + assert target_device clusters_to_bind = await get_matched_clusters(source_device, target_device) zdo = source_device.device.zdo @@ -997,7 +1003,7 @@ async def websocket_get_configuration( return cv.custom_serializer(schema) - data = {"schemas": {}, "data": {}} + data: dict[str, dict[str, Any]] = {"schemas": {}, "data": {}} for section, schema in ZHA_CONFIG_SCHEMAS.items(): if section == ZHA_ALARM_OPTIONS and not async_cluster_exists( hass, IasAce.cluster_id @@ -1084,7 +1090,7 @@ def async_load_api(hass: HomeAssistant) -> None: """Remove a node from the network.""" zha_gateway: ZHAGateway = hass.data[DATA_ZHA][DATA_ZHA_GATEWAY] ieee: EUI64 = service.data[ATTR_IEEE] - zha_device: ZHADevice = zha_gateway.get_device(ieee) + zha_device: ZHADevice | None = zha_gateway.get_device(ieee) if zha_device is not None and ( zha_device.is_coordinator and zha_device.ieee == zha_gateway.application_controller.ieee diff --git a/homeassistant/components/zha/button.py b/homeassistant/components/zha/button.py index ed0836042d2..29bfb2ca248 100644 --- a/homeassistant/components/zha/button.py +++ b/homeassistant/components/zha/button.py @@ -59,7 +59,7 @@ async def async_setup_entry( class ZHAButton(ZhaEntity, ButtonEntity): """Defines a ZHA button.""" - _command_name: str = None + _command_name: str def __init__( self, @@ -118,7 +118,7 @@ class ZHAIdentifyButton(ZHAButton): class ZHAAttributeButton(ZhaEntity, ButtonEntity): """Defines a ZHA button, which stes value to an attribute.""" - _attribute_name: str = None + _attribute_name: str _attribute_value: Any = None def __init__( diff --git a/homeassistant/components/zha/climate.py b/homeassistant/components/zha/climate.py index 291e8413e16..d8b2f0db3af 100644 --- a/homeassistant/components/zha/climate.py +++ b/homeassistant/components/zha/climate.py @@ -73,16 +73,16 @@ MULTI_MATCH = functools.partial(ZHA_ENTITIES.multipass_match, Platform.CLIMATE) RUNNING_MODE = {0x00: HVACMode.OFF, 0x03: HVACMode.COOL, 0x04: HVACMode.HEAT} SEQ_OF_OPERATION = { - 0x00: (HVACMode.OFF, HVACMode.COOL), # cooling only - 0x01: (HVACMode.OFF, HVACMode.COOL), # cooling with reheat - 0x02: (HVACMode.OFF, HVACMode.HEAT), # heating only - 0x03: (HVACMode.OFF, HVACMode.HEAT), # heating with reheat + 0x00: [HVACMode.OFF, HVACMode.COOL], # cooling only + 0x01: [HVACMode.OFF, HVACMode.COOL], # cooling with reheat + 0x02: [HVACMode.OFF, HVACMode.HEAT], # heating only + 0x03: [HVACMode.OFF, HVACMode.HEAT], # heating with reheat # cooling and heating 4-pipes - 0x04: (HVACMode.OFF, HVACMode.HEAT_COOL, HVACMode.COOL, HVACMode.HEAT), + 0x04: [HVACMode.OFF, HVACMode.HEAT_COOL, HVACMode.COOL, HVACMode.HEAT], # cooling and heating 4-pipes - 0x05: (HVACMode.OFF, HVACMode.HEAT_COOL, HVACMode.COOL, HVACMode.HEAT), - 0x06: (HVACMode.COOL, HVACMode.HEAT, HVACMode.OFF), # centralite specific - 0x07: (HVACMode.HEAT_COOL, HVACMode.OFF), # centralite specific + 0x05: [HVACMode.OFF, HVACMode.HEAT_COOL, HVACMode.COOL, HVACMode.HEAT], + 0x06: [HVACMode.COOL, HVACMode.HEAT, HVACMode.OFF], # centralite specific + 0x07: [HVACMode.HEAT_COOL, HVACMode.OFF], # centralite specific } HVAC_MODE_2_SYSTEM = { @@ -268,7 +268,7 @@ class Thermostat(ZhaEntity, ClimateEntity): return PRECISION_TENTHS @property - def preset_mode(self) -> str | None: + def preset_mode(self) -> str: """Return current preset mode.""" return self._preset @@ -389,7 +389,7 @@ class Thermostat(ZhaEntity, ClimateEntity): async def async_set_fan_mode(self, fan_mode: str) -> None: """Set fan mode.""" - if fan_mode not in self.fan_modes: + if not self.fan_modes or fan_mode not in self.fan_modes: self.warning("Unsupported '%s' fan mode", fan_mode) return @@ -415,8 +415,8 @@ class Thermostat(ZhaEntity, ClimateEntity): async def async_set_preset_mode(self, preset_mode: str) -> None: """Set new preset mode.""" - if preset_mode not in self.preset_modes: - self.debug("preset mode '%s' is not supported", preset_mode) + if not self.preset_modes or preset_mode not in self.preset_modes: + self.debug("Preset mode '%s' is not supported", preset_mode) return if self.preset_mode not in ( @@ -505,7 +505,7 @@ class SinopeTechnologiesThermostat(Thermostat): self._manufacturer_ch = self.cluster_channels["sinope_manufacturer_specific"] @property - def _rm_rs_action(self) -> str | None: + def _rm_rs_action(self) -> HVACAction: """Return the current HVAC action based on running mode and running state.""" running_mode = self._thrm.running_mode diff --git a/mypy.ini b/mypy.ini index b01acbe311f..1cc40dd3daf 100644 --- a/mypy.ini +++ b/mypy.ini @@ -2985,15 +2985,6 @@ ignore_errors = true [mypy-homeassistant.components.xiaomi_miio.switch] ignore_errors = true -[mypy-homeassistant.components.zha.api] -ignore_errors = true - -[mypy-homeassistant.components.zha.button] -ignore_errors = true - -[mypy-homeassistant.components.zha.climate] -ignore_errors = true - [mypy-homeassistant.components.zha.core.channels.base] ignore_errors = true diff --git a/script/hassfest/mypy_config.py b/script/hassfest/mypy_config.py index e5bb404b715..5a53323deb7 100644 --- a/script/hassfest/mypy_config.py +++ b/script/hassfest/mypy_config.py @@ -144,9 +144,6 @@ IGNORED_MODULES: Final[list[str]] = [ "homeassistant.components.xiaomi_miio.light", "homeassistant.components.xiaomi_miio.sensor", "homeassistant.components.xiaomi_miio.switch", - "homeassistant.components.zha.api", - "homeassistant.components.zha.button", - "homeassistant.components.zha.climate", "homeassistant.components.zha.core.channels.base", "homeassistant.components.zha.core.channels.homeautomation", "homeassistant.components.zha.core.channels.hvac",