Skip to content

Commit 7f14d01

Browse files
authored
Strict typing for lcn integration (#156800)
1 parent 963e27d commit 7f14d01

File tree

12 files changed

+51
-41
lines changed

12 files changed

+51
-41
lines changed

homeassistant/components/lcn/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from functools import partial
66
import logging
7+
from typing import cast
78

89
import pypck
910
from pypck.connection import (
@@ -48,7 +49,6 @@
4849
)
4950
from .helpers import (
5051
AddressType,
51-
InputType,
5252
LcnConfigEntry,
5353
LcnRuntimeData,
5454
async_update_config_entry,
@@ -285,7 +285,7 @@ def _async_fire_access_control_event(
285285
hass: HomeAssistant,
286286
device: dr.DeviceEntry | None,
287287
address: AddressType,
288-
inp: InputType,
288+
inp: pypck.inputs.ModStatusAccessControl,
289289
) -> None:
290290
"""Fire access control event (transponder, transmitter, fingerprint, codelock)."""
291291
event_data = {
@@ -299,7 +299,11 @@ def _async_fire_access_control_event(
299299

300300
if inp.periphery == pypck.lcn_defs.AccessControlPeriphery.TRANSMITTER:
301301
event_data.update(
302-
{"level": inp.level, "key": inp.key, "action": inp.action.value}
302+
{
303+
"level": inp.level,
304+
"key": inp.key,
305+
"action": cast(pypck.lcn_defs.KeyAction, inp.action).value,
306+
}
303307
)
304308

305309
event_name = f"lcn_{inp.periphery.value.lower()}"
@@ -310,7 +314,7 @@ def _async_fire_send_keys_event(
310314
hass: HomeAssistant,
311315
device: dr.DeviceEntry | None,
312316
address: AddressType,
313-
inp: InputType,
317+
inp: pypck.inputs.ModSendKeysHost,
314318
) -> None:
315319
"""Fire send_keys event."""
316320
for table, action in enumerate(inp.actions):

homeassistant/components/lcn/climate.py

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
100100
self._max_temp = config[CONF_DOMAIN_DATA][CONF_MAX_TEMP]
101101
self._min_temp = config[CONF_DOMAIN_DATA][CONF_MIN_TEMP]
102102

103-
self._current_temperature = None
104-
self._target_temperature = None
105103
self._is_on = True
106104

107105
self._attr_hvac_modes = [HVACMode.HEAT]
@@ -121,16 +119,6 @@ def temperature_unit(self) -> str:
121119
return UnitOfTemperature.FAHRENHEIT
122120
return UnitOfTemperature.CELSIUS
123121

124-
@property
125-
def current_temperature(self) -> float | None:
126-
"""Return the current temperature."""
127-
return self._current_temperature
128-
129-
@property
130-
def target_temperature(self) -> float | None:
131-
"""Return the temperature we try to reach."""
132-
return self._target_temperature
133-
134122
@property
135123
def hvac_mode(self) -> HVACMode:
136124
"""Return hvac operation ie. heat, cool mode.
@@ -166,7 +154,7 @@ async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
166154
):
167155
return
168156
self._is_on = False
169-
self._target_temperature = None
157+
self._attr_target_temperature = None
170158
self.async_write_ha_state()
171159

172160
async def async_set_temperature(self, **kwargs: Any) -> None:
@@ -178,7 +166,7 @@ async def async_set_temperature(self, **kwargs: Any) -> None:
178166
self.setpoint, temperature, self.unit
179167
):
180168
return
181-
self._target_temperature = temperature
169+
self._attr_target_temperature = temperature
182170
self.async_write_ha_state()
183171

184172
async def async_update(self) -> None:
@@ -198,10 +186,14 @@ def input_received(self, input_obj: InputType) -> None:
198186
return
199187

200188
if input_obj.get_var() == self.variable:
201-
self._current_temperature = input_obj.get_value().to_var_unit(self.unit)
189+
self._attr_current_temperature = float(
190+
input_obj.get_value().to_var_unit(self.unit)
191+
)
202192
elif input_obj.get_var() == self.setpoint:
203193
self._is_on = not input_obj.get_value().is_locked_regulator()
204194
if self._is_on:
205-
self._target_temperature = input_obj.get_value().to_var_unit(self.unit)
195+
self._attr_target_temperature = float(
196+
input_obj.get_value().to_var_unit(self.unit)
197+
)
206198

207199
self.async_write_ha_state()

homeassistant/components/lcn/config_flow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ async def async_step_user(
120120
errors={CONF_BASE: error},
121121
)
122122

123-
data: dict = {
123+
data: dict[str, Any] = {
124124
**user_input,
125125
CONF_DEVICES: [],
126126
CONF_ENTITIES: [],

homeassistant/components/lcn/cover.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Support for LCN covers."""
22

33
import asyncio
4-
from collections.abc import Iterable
4+
from collections.abc import Coroutine, Iterable
55
from datetime import timedelta
66
from functools import partial
77
from typing import Any
@@ -81,6 +81,8 @@ class LcnOutputsCover(LcnEntity, CoverEntity):
8181
_attr_is_opening = False
8282
_attr_assumed_state = True
8383

84+
reverse_time: pypck.lcn_defs.MotorReverseTime | None
85+
8486
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
8587
"""Initialize the LCN cover."""
8688
super().__init__(config, config_entry)
@@ -255,7 +257,15 @@ async def async_set_cover_position(self, **kwargs: Any) -> None:
255257

256258
async def async_update(self) -> None:
257259
"""Update the state of the entity."""
258-
coros = [self.device_connection.request_status_relays(SCAN_INTERVAL.seconds)]
260+
coros: list[
261+
Coroutine[
262+
Any,
263+
Any,
264+
pypck.inputs.ModStatusRelays
265+
| pypck.inputs.ModStatusMotorPositionBS4
266+
| None,
267+
]
268+
] = [self.device_connection.request_status_relays(SCAN_INTERVAL.seconds)]
259269
if self.positioning_mode == pypck.lcn_defs.MotorPositioningMode.BS4:
260270
coros.append(
261271
self.device_connection.request_status_motor_position(
@@ -283,7 +293,7 @@ def input_received(self, input_obj: InputType) -> None:
283293
)
284294
and input_obj.motor == self.motor.value
285295
):
286-
self._attr_current_cover_position = input_obj.position
296+
self._attr_current_cover_position = int(input_obj.position)
287297
if self._attr_current_cover_position in [0, 100]:
288298
self._attr_is_opening = False
289299
self._attr_is_closing = False

homeassistant/components/lcn/entity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def __init__(
3535
self.config = config
3636
self.config_entry = config_entry
3737
self.address: AddressType = config[CONF_ADDRESS]
38-
self._unregister_for_inputs: Callable | None = None
38+
self._unregister_for_inputs: Callable[[], None] | None = None
3939
self._name: str = config[CONF_NAME]
4040
self._attr_device_info = DeviceInfo(
4141
identifiers={

homeassistant/components/lcn/helpers.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class LcnRuntimeData:
6161

6262
type AddressType = tuple[int, int, bool]
6363

64-
type InputType = type[pypck.inputs.Input]
64+
type InputType = pypck.inputs.Input
6565

6666
# Regex for address validation
6767
PATTERN_ADDRESS = re.compile(
@@ -269,10 +269,10 @@ async def async_update_device_config(
269269
if device_config[CONF_NAME] != "":
270270
return
271271

272-
device_name = ""
272+
device_name: str | None = None
273273
if not is_group:
274274
device_name = await device_connection.request_name()
275-
if is_group or device_name == "":
275+
if is_group or device_name is None:
276276
module_type = "Group" if is_group else "Module"
277277
device_name = (
278278
f"{module_type} "

homeassistant/components/lcn/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@
99
"iot_class": "local_polling",
1010
"loggers": ["pypck"],
1111
"quality_scale": "bronze",
12-
"requirements": ["pypck==0.9.3", "lcn-frontend==0.2.7"]
12+
"requirements": ["pypck==0.9.4", "lcn-frontend==0.2.7"]
1313
}

homeassistant/components/lcn/quality_scale.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,4 @@ rules:
7474
status: exempt
7575
comment: |
7676
Integration is not making any HTTP requests.
77-
strict-typing: todo
77+
strict-typing: done

homeassistant/components/lcn/sensor.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,8 @@ def input_received(self, input_obj: InputType) -> None:
156156
class LcnLedLogicSensor(LcnEntity, SensorEntity):
157157
"""Representation of a LCN sensor for leds and logicops."""
158158

159+
source: pypck.lcn_defs.LedPort | pypck.lcn_defs.LogicOpPort
160+
159161
def __init__(self, config: ConfigType, config_entry: LcnConfigEntry) -> None:
160162
"""Initialize the LCN sensor."""
161163
super().__init__(config, config_entry)

homeassistant/components/lcn/websocket.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,9 @@ def get_config_entry(
104104

105105
@wraps(func)
106106
async def get_entry(
107-
hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict
107+
hass: HomeAssistant,
108+
connection: websocket_api.ActiveConnection,
109+
msg: dict[str, Any],
108110
) -> None:
109111
"""Get config_entry."""
110112
if not (config_entry := hass.config_entries.async_get_entry(msg["entry_id"])):
@@ -124,7 +126,7 @@ async def get_entry(
124126
async def websocket_get_device_configs(
125127
hass: HomeAssistant,
126128
connection: websocket_api.ActiveConnection,
127-
msg: dict,
129+
msg: dict[str, Any],
128130
config_entry: LcnConfigEntry,
129131
) -> None:
130132
"""Get device configs."""
@@ -144,7 +146,7 @@ async def websocket_get_device_configs(
144146
async def websocket_get_entity_configs(
145147
hass: HomeAssistant,
146148
connection: websocket_api.ActiveConnection,
147-
msg: dict,
149+
msg: dict[str, Any],
148150
config_entry: LcnConfigEntry,
149151
) -> None:
150152
"""Get entities configs."""
@@ -175,7 +177,7 @@ async def websocket_get_entity_configs(
175177
async def websocket_scan_devices(
176178
hass: HomeAssistant,
177179
connection: websocket_api.ActiveConnection,
178-
msg: dict,
180+
msg: dict[str, Any],
179181
config_entry: LcnConfigEntry,
180182
) -> None:
181183
"""Scan for new devices."""
@@ -207,7 +209,7 @@ async def websocket_scan_devices(
207209
async def websocket_add_device(
208210
hass: HomeAssistant,
209211
connection: websocket_api.ActiveConnection,
210-
msg: dict,
212+
msg: dict[str, Any],
211213
config_entry: LcnConfigEntry,
212214
) -> None:
213215
"""Add a device."""
@@ -253,7 +255,7 @@ async def websocket_add_device(
253255
async def websocket_delete_device(
254256
hass: HomeAssistant,
255257
connection: websocket_api.ActiveConnection,
256-
msg: dict,
258+
msg: dict[str, Any],
257259
config_entry: LcnConfigEntry,
258260
) -> None:
259261
"""Delete a device."""
@@ -315,7 +317,7 @@ async def websocket_delete_device(
315317
async def websocket_add_entity(
316318
hass: HomeAssistant,
317319
connection: websocket_api.ActiveConnection,
318-
msg: dict,
320+
msg: dict[str, Any],
319321
config_entry: LcnConfigEntry,
320322
) -> None:
321323
"""Add an entity."""
@@ -381,7 +383,7 @@ async def websocket_add_entity(
381383
async def websocket_delete_entity(
382384
hass: HomeAssistant,
383385
connection: websocket_api.ActiveConnection,
384-
msg: dict,
386+
msg: dict[str, Any],
385387
config_entry: LcnConfigEntry,
386388
) -> None:
387389
"""Delete an entity."""
@@ -451,7 +453,7 @@ async def async_create_or_update_device_in_config_entry(
451453

452454

453455
def get_entity_entry(
454-
hass: HomeAssistant, entity_config: dict, config_entry: LcnConfigEntry
456+
hass: HomeAssistant, entity_config: dict[str, Any], config_entry: LcnConfigEntry
455457
) -> er.RegistryEntry | None:
456458
"""Get entity RegistryEntry from entity_config."""
457459
entity_registry = er.async_get(hass)

0 commit comments

Comments
 (0)