aiohomematic 2026.1.29__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aiohomematic/__init__.py +110 -0
- aiohomematic/_log_context_protocol.py +29 -0
- aiohomematic/api.py +410 -0
- aiohomematic/async_support.py +250 -0
- aiohomematic/backend_detection.py +462 -0
- aiohomematic/central/__init__.py +103 -0
- aiohomematic/central/async_rpc_server.py +760 -0
- aiohomematic/central/central_unit.py +1152 -0
- aiohomematic/central/config.py +463 -0
- aiohomematic/central/config_builder.py +772 -0
- aiohomematic/central/connection_state.py +160 -0
- aiohomematic/central/coordinators/__init__.py +38 -0
- aiohomematic/central/coordinators/cache.py +414 -0
- aiohomematic/central/coordinators/client.py +480 -0
- aiohomematic/central/coordinators/connection_recovery.py +1141 -0
- aiohomematic/central/coordinators/device.py +1166 -0
- aiohomematic/central/coordinators/event.py +514 -0
- aiohomematic/central/coordinators/hub.py +532 -0
- aiohomematic/central/decorators.py +184 -0
- aiohomematic/central/device_registry.py +229 -0
- aiohomematic/central/events/__init__.py +104 -0
- aiohomematic/central/events/bus.py +1392 -0
- aiohomematic/central/events/integration.py +424 -0
- aiohomematic/central/events/types.py +194 -0
- aiohomematic/central/health.py +762 -0
- aiohomematic/central/rpc_server.py +353 -0
- aiohomematic/central/scheduler.py +794 -0
- aiohomematic/central/state_machine.py +391 -0
- aiohomematic/client/__init__.py +203 -0
- aiohomematic/client/_rpc_errors.py +187 -0
- aiohomematic/client/backends/__init__.py +48 -0
- aiohomematic/client/backends/base.py +335 -0
- aiohomematic/client/backends/capabilities.py +138 -0
- aiohomematic/client/backends/ccu.py +487 -0
- aiohomematic/client/backends/factory.py +116 -0
- aiohomematic/client/backends/homegear.py +294 -0
- aiohomematic/client/backends/json_ccu.py +252 -0
- aiohomematic/client/backends/protocol.py +316 -0
- aiohomematic/client/ccu.py +1857 -0
- aiohomematic/client/circuit_breaker.py +459 -0
- aiohomematic/client/config.py +64 -0
- aiohomematic/client/handlers/__init__.py +40 -0
- aiohomematic/client/handlers/backup.py +157 -0
- aiohomematic/client/handlers/base.py +79 -0
- aiohomematic/client/handlers/device_ops.py +1085 -0
- aiohomematic/client/handlers/firmware.py +144 -0
- aiohomematic/client/handlers/link_mgmt.py +199 -0
- aiohomematic/client/handlers/metadata.py +436 -0
- aiohomematic/client/handlers/programs.py +144 -0
- aiohomematic/client/handlers/sysvars.py +100 -0
- aiohomematic/client/interface_client.py +1304 -0
- aiohomematic/client/json_rpc.py +2068 -0
- aiohomematic/client/request_coalescer.py +282 -0
- aiohomematic/client/rpc_proxy.py +629 -0
- aiohomematic/client/state_machine.py +324 -0
- aiohomematic/const.py +2207 -0
- aiohomematic/context.py +275 -0
- aiohomematic/converter.py +270 -0
- aiohomematic/decorators.py +390 -0
- aiohomematic/exceptions.py +185 -0
- aiohomematic/hmcli.py +997 -0
- aiohomematic/i18n.py +193 -0
- aiohomematic/interfaces/__init__.py +407 -0
- aiohomematic/interfaces/central.py +1067 -0
- aiohomematic/interfaces/client.py +1096 -0
- aiohomematic/interfaces/coordinators.py +63 -0
- aiohomematic/interfaces/model.py +1921 -0
- aiohomematic/interfaces/operations.py +217 -0
- aiohomematic/logging_context.py +134 -0
- aiohomematic/metrics/__init__.py +125 -0
- aiohomematic/metrics/_protocols.py +140 -0
- aiohomematic/metrics/aggregator.py +534 -0
- aiohomematic/metrics/dataclasses.py +489 -0
- aiohomematic/metrics/emitter.py +292 -0
- aiohomematic/metrics/events.py +183 -0
- aiohomematic/metrics/keys.py +300 -0
- aiohomematic/metrics/observer.py +563 -0
- aiohomematic/metrics/stats.py +172 -0
- aiohomematic/model/__init__.py +189 -0
- aiohomematic/model/availability.py +65 -0
- aiohomematic/model/calculated/__init__.py +89 -0
- aiohomematic/model/calculated/climate.py +276 -0
- aiohomematic/model/calculated/data_point.py +315 -0
- aiohomematic/model/calculated/field.py +147 -0
- aiohomematic/model/calculated/operating_voltage_level.py +286 -0
- aiohomematic/model/calculated/support.py +232 -0
- aiohomematic/model/custom/__init__.py +214 -0
- aiohomematic/model/custom/capabilities/__init__.py +67 -0
- aiohomematic/model/custom/capabilities/climate.py +41 -0
- aiohomematic/model/custom/capabilities/light.py +87 -0
- aiohomematic/model/custom/capabilities/lock.py +44 -0
- aiohomematic/model/custom/capabilities/siren.py +63 -0
- aiohomematic/model/custom/climate.py +1130 -0
- aiohomematic/model/custom/cover.py +722 -0
- aiohomematic/model/custom/data_point.py +360 -0
- aiohomematic/model/custom/definition.py +300 -0
- aiohomematic/model/custom/field.py +89 -0
- aiohomematic/model/custom/light.py +1174 -0
- aiohomematic/model/custom/lock.py +322 -0
- aiohomematic/model/custom/mixins.py +445 -0
- aiohomematic/model/custom/profile.py +945 -0
- aiohomematic/model/custom/registry.py +251 -0
- aiohomematic/model/custom/siren.py +462 -0
- aiohomematic/model/custom/switch.py +195 -0
- aiohomematic/model/custom/text_display.py +289 -0
- aiohomematic/model/custom/valve.py +78 -0
- aiohomematic/model/data_point.py +1416 -0
- aiohomematic/model/device.py +1840 -0
- aiohomematic/model/event.py +216 -0
- aiohomematic/model/generic/__init__.py +327 -0
- aiohomematic/model/generic/action.py +40 -0
- aiohomematic/model/generic/action_select.py +62 -0
- aiohomematic/model/generic/binary_sensor.py +30 -0
- aiohomematic/model/generic/button.py +31 -0
- aiohomematic/model/generic/data_point.py +177 -0
- aiohomematic/model/generic/dummy.py +150 -0
- aiohomematic/model/generic/number.py +76 -0
- aiohomematic/model/generic/select.py +56 -0
- aiohomematic/model/generic/sensor.py +76 -0
- aiohomematic/model/generic/switch.py +54 -0
- aiohomematic/model/generic/text.py +33 -0
- aiohomematic/model/hub/__init__.py +100 -0
- aiohomematic/model/hub/binary_sensor.py +24 -0
- aiohomematic/model/hub/button.py +28 -0
- aiohomematic/model/hub/connectivity.py +190 -0
- aiohomematic/model/hub/data_point.py +342 -0
- aiohomematic/model/hub/hub.py +864 -0
- aiohomematic/model/hub/inbox.py +135 -0
- aiohomematic/model/hub/install_mode.py +393 -0
- aiohomematic/model/hub/metrics.py +208 -0
- aiohomematic/model/hub/number.py +42 -0
- aiohomematic/model/hub/select.py +52 -0
- aiohomematic/model/hub/sensor.py +37 -0
- aiohomematic/model/hub/switch.py +43 -0
- aiohomematic/model/hub/text.py +30 -0
- aiohomematic/model/hub/update.py +221 -0
- aiohomematic/model/support.py +592 -0
- aiohomematic/model/update.py +140 -0
- aiohomematic/model/week_profile.py +1827 -0
- aiohomematic/property_decorators.py +719 -0
- aiohomematic/py.typed +0 -0
- aiohomematic/rega_scripts/accept_device_in_inbox.fn +51 -0
- aiohomematic/rega_scripts/create_backup_start.fn +28 -0
- aiohomematic/rega_scripts/create_backup_status.fn +89 -0
- aiohomematic/rega_scripts/fetch_all_device_data.fn +97 -0
- aiohomematic/rega_scripts/get_backend_info.fn +25 -0
- aiohomematic/rega_scripts/get_inbox_devices.fn +61 -0
- aiohomematic/rega_scripts/get_program_descriptions.fn +31 -0
- aiohomematic/rega_scripts/get_serial.fn +44 -0
- aiohomematic/rega_scripts/get_service_messages.fn +83 -0
- aiohomematic/rega_scripts/get_system_update_info.fn +39 -0
- aiohomematic/rega_scripts/get_system_variable_descriptions.fn +31 -0
- aiohomematic/rega_scripts/set_program_state.fn +17 -0
- aiohomematic/rega_scripts/set_system_variable.fn +19 -0
- aiohomematic/rega_scripts/trigger_firmware_update.fn +67 -0
- aiohomematic/schemas.py +256 -0
- aiohomematic/store/__init__.py +55 -0
- aiohomematic/store/dynamic/__init__.py +43 -0
- aiohomematic/store/dynamic/command.py +250 -0
- aiohomematic/store/dynamic/data.py +175 -0
- aiohomematic/store/dynamic/details.py +187 -0
- aiohomematic/store/dynamic/ping_pong.py +416 -0
- aiohomematic/store/persistent/__init__.py +71 -0
- aiohomematic/store/persistent/base.py +285 -0
- aiohomematic/store/persistent/device.py +233 -0
- aiohomematic/store/persistent/incident.py +380 -0
- aiohomematic/store/persistent/paramset.py +241 -0
- aiohomematic/store/persistent/session.py +556 -0
- aiohomematic/store/serialization.py +150 -0
- aiohomematic/store/storage.py +689 -0
- aiohomematic/store/types.py +526 -0
- aiohomematic/store/visibility/__init__.py +40 -0
- aiohomematic/store/visibility/parser.py +141 -0
- aiohomematic/store/visibility/registry.py +722 -0
- aiohomematic/store/visibility/rules.py +307 -0
- aiohomematic/strings.json +237 -0
- aiohomematic/support.py +706 -0
- aiohomematic/tracing.py +236 -0
- aiohomematic/translations/de.json +237 -0
- aiohomematic/translations/en.json +237 -0
- aiohomematic/type_aliases.py +51 -0
- aiohomematic/validator.py +128 -0
- aiohomematic-2026.1.29.dist-info/METADATA +296 -0
- aiohomematic-2026.1.29.dist-info/RECORD +188 -0
- aiohomematic-2026.1.29.dist-info/WHEEL +5 -0
- aiohomematic-2026.1.29.dist-info/entry_points.txt +2 -0
- aiohomematic-2026.1.29.dist-info/licenses/LICENSE +21 -0
- aiohomematic-2026.1.29.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2026
|
|
3
|
+
"""
|
|
4
|
+
Custom lock data points for door locks and access control.
|
|
5
|
+
|
|
6
|
+
Public API of this module is defined by __all__.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from abc import abstractmethod
|
|
12
|
+
from enum import StrEnum
|
|
13
|
+
from typing import Final
|
|
14
|
+
|
|
15
|
+
from aiohomematic.const import DataPointCategory, DeviceProfile, Field, Parameter
|
|
16
|
+
from aiohomematic.model.custom.capabilities.lock import BUTTON_LOCK_CAPABILITIES, IP_LOCK_CAPABILITIES, LockCapabilities
|
|
17
|
+
from aiohomematic.model.custom.data_point import CustomDataPoint
|
|
18
|
+
from aiohomematic.model.custom.field import DataPointField
|
|
19
|
+
from aiohomematic.model.custom.registry import DeviceConfig, DeviceProfileRegistry, ExtendedDeviceConfig
|
|
20
|
+
from aiohomematic.model.data_point import CallParameterCollector, bind_collector
|
|
21
|
+
from aiohomematic.model.generic import DpAction, DpActionSelect, DpSensor, DpSwitch
|
|
22
|
+
from aiohomematic.property_decorators import state_property
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class _LockActivity(StrEnum):
|
|
26
|
+
"""Enum with lock activities."""
|
|
27
|
+
|
|
28
|
+
LOCKING = "DOWN"
|
|
29
|
+
UNLOCKING = "UP"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class _LockError(StrEnum):
|
|
33
|
+
"""Enum with lock errors."""
|
|
34
|
+
|
|
35
|
+
NO_ERROR = "NO_ERROR"
|
|
36
|
+
CLUTCH_FAILURE = "CLUTCH_FAILURE"
|
|
37
|
+
MOTOR_ABORTED = "MOTOR_ABORTED"
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class _LockTargetLevel(StrEnum):
|
|
41
|
+
"""Enum with lock target levels."""
|
|
42
|
+
|
|
43
|
+
LOCKED = "LOCKED"
|
|
44
|
+
OPEN = "OPEN"
|
|
45
|
+
UNLOCKED = "UNLOCKED"
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class LockState(StrEnum):
|
|
49
|
+
"""Enum with lock states."""
|
|
50
|
+
|
|
51
|
+
LOCKED = "LOCKED"
|
|
52
|
+
UNKNOWN = "UNKNOWN"
|
|
53
|
+
UNLOCKED = "UNLOCKED"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class BaseCustomDpLock(CustomDataPoint):
|
|
57
|
+
"""Class for HomematicIP lock data point."""
|
|
58
|
+
|
|
59
|
+
__slots__ = ("_capabilities",)
|
|
60
|
+
|
|
61
|
+
_category = DataPointCategory.LOCK
|
|
62
|
+
_ignore_multiple_channels_for_name = True
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def capabilities(self) -> LockCapabilities:
|
|
66
|
+
"""Return the lock capabilities."""
|
|
67
|
+
if (caps := getattr(self, "_capabilities", None)) is None:
|
|
68
|
+
caps = self._compute_capabilities()
|
|
69
|
+
object.__setattr__(self, "_capabilities", caps)
|
|
70
|
+
return caps
|
|
71
|
+
|
|
72
|
+
@state_property
|
|
73
|
+
def is_jammed(self) -> bool:
|
|
74
|
+
"""Return true if lock is jammed."""
|
|
75
|
+
return False
|
|
76
|
+
|
|
77
|
+
@state_property
|
|
78
|
+
@abstractmethod
|
|
79
|
+
def is_locked(self) -> bool:
|
|
80
|
+
"""Return true if lock is on."""
|
|
81
|
+
|
|
82
|
+
@state_property
|
|
83
|
+
def is_locking(self) -> bool | None:
|
|
84
|
+
"""Return true if the lock is locking."""
|
|
85
|
+
return None
|
|
86
|
+
|
|
87
|
+
@state_property
|
|
88
|
+
def is_unlocking(self) -> bool | None:
|
|
89
|
+
"""Return true if the lock is unlocking."""
|
|
90
|
+
return None
|
|
91
|
+
|
|
92
|
+
@abstractmethod
|
|
93
|
+
@bind_collector
|
|
94
|
+
async def lock(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
95
|
+
"""Lock the lock."""
|
|
96
|
+
|
|
97
|
+
@abstractmethod
|
|
98
|
+
@bind_collector
|
|
99
|
+
async def open(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
100
|
+
"""Open the lock."""
|
|
101
|
+
|
|
102
|
+
@abstractmethod
|
|
103
|
+
@bind_collector
|
|
104
|
+
async def unlock(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
105
|
+
"""Unlock the lock."""
|
|
106
|
+
|
|
107
|
+
@abstractmethod
|
|
108
|
+
def _compute_capabilities(self) -> LockCapabilities:
|
|
109
|
+
"""Compute static capabilities. Implemented by subclasses."""
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class CustomDpIpLock(BaseCustomDpLock):
|
|
113
|
+
"""Class for HomematicIP lock data point."""
|
|
114
|
+
|
|
115
|
+
__slots__ = () # Required to prevent __dict__ creation (descriptors are class-level)
|
|
116
|
+
|
|
117
|
+
# Declarative data point field definitions
|
|
118
|
+
_dp_direction: Final = DataPointField(field=Field.DIRECTION, dpt=DpSensor[str | None])
|
|
119
|
+
_dp_lock_state: Final = DataPointField(field=Field.LOCK_STATE, dpt=DpSensor[str | None])
|
|
120
|
+
_dp_lock_target_level: Final = DataPointField(field=Field.LOCK_TARGET_LEVEL, dpt=DpActionSelect)
|
|
121
|
+
|
|
122
|
+
@state_property
|
|
123
|
+
def is_locked(self) -> bool:
|
|
124
|
+
"""Return true if lock is on."""
|
|
125
|
+
return self._dp_lock_state.value == LockState.LOCKED
|
|
126
|
+
|
|
127
|
+
@state_property
|
|
128
|
+
def is_locking(self) -> bool | None:
|
|
129
|
+
"""Return true if the lock is locking."""
|
|
130
|
+
if self._dp_direction.value is not None:
|
|
131
|
+
return str(self._dp_direction.value) == _LockActivity.LOCKING
|
|
132
|
+
return None
|
|
133
|
+
|
|
134
|
+
@state_property
|
|
135
|
+
def is_unlocking(self) -> bool | None:
|
|
136
|
+
"""Return true if the lock is unlocking."""
|
|
137
|
+
if self._dp_direction.value is not None:
|
|
138
|
+
return str(self._dp_direction.value) == _LockActivity.UNLOCKING
|
|
139
|
+
return None
|
|
140
|
+
|
|
141
|
+
@bind_collector
|
|
142
|
+
async def lock(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
143
|
+
"""Lock the lock."""
|
|
144
|
+
await self._dp_lock_target_level.send_value(value=_LockTargetLevel.LOCKED, collector=collector)
|
|
145
|
+
|
|
146
|
+
@bind_collector
|
|
147
|
+
async def open(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
148
|
+
"""Open the lock."""
|
|
149
|
+
await self._dp_lock_target_level.send_value(value=_LockTargetLevel.OPEN, collector=collector)
|
|
150
|
+
|
|
151
|
+
@bind_collector
|
|
152
|
+
async def unlock(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
153
|
+
"""Unlock the lock."""
|
|
154
|
+
await self._dp_lock_target_level.send_value(value=_LockTargetLevel.UNLOCKED, collector=collector)
|
|
155
|
+
|
|
156
|
+
def _compute_capabilities(self) -> LockCapabilities:
|
|
157
|
+
"""Compute static capabilities. IP locks support open."""
|
|
158
|
+
return IP_LOCK_CAPABILITIES
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class CustomDpButtonLock(BaseCustomDpLock):
|
|
162
|
+
"""Class for HomematicIP button lock data point."""
|
|
163
|
+
|
|
164
|
+
__slots__ = () # Required to prevent __dict__ creation (descriptors are class-level)
|
|
165
|
+
|
|
166
|
+
# Declarative data point field definitions
|
|
167
|
+
_dp_button_lock: Final = DataPointField(field=Field.BUTTON_LOCK, dpt=DpSwitch)
|
|
168
|
+
|
|
169
|
+
@property
|
|
170
|
+
def data_point_name_postfix(self) -> str:
|
|
171
|
+
"""Return the data_point name postfix."""
|
|
172
|
+
return "BUTTON_LOCK"
|
|
173
|
+
|
|
174
|
+
@state_property
|
|
175
|
+
def is_locked(self) -> bool:
|
|
176
|
+
"""Return true if lock is on."""
|
|
177
|
+
return self._dp_button_lock.value is True
|
|
178
|
+
|
|
179
|
+
@bind_collector
|
|
180
|
+
async def lock(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
181
|
+
"""Lock the lock."""
|
|
182
|
+
await self._dp_button_lock.turn_on(collector=collector)
|
|
183
|
+
|
|
184
|
+
@bind_collector
|
|
185
|
+
async def open(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
186
|
+
"""Open the lock."""
|
|
187
|
+
return
|
|
188
|
+
|
|
189
|
+
@bind_collector
|
|
190
|
+
async def unlock(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
191
|
+
"""Unlock the lock."""
|
|
192
|
+
await self._dp_button_lock.turn_off(collector=collector)
|
|
193
|
+
|
|
194
|
+
def _compute_capabilities(self) -> LockCapabilities:
|
|
195
|
+
"""Compute static capabilities. Button locks do not support open."""
|
|
196
|
+
return BUTTON_LOCK_CAPABILITIES
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class CustomDpRfLock(BaseCustomDpLock):
|
|
200
|
+
"""Class for classic Homematic lock data point."""
|
|
201
|
+
|
|
202
|
+
__slots__ = () # Required to prevent __dict__ creation (descriptors are class-level)
|
|
203
|
+
|
|
204
|
+
# Declarative data point field definitions
|
|
205
|
+
_dp_direction: Final = DataPointField(field=Field.DIRECTION, dpt=DpSensor[str | None])
|
|
206
|
+
_dp_error: Final = DataPointField(field=Field.ERROR, dpt=DpSensor[str | None])
|
|
207
|
+
_dp_open: Final = DataPointField(field=Field.OPEN, dpt=DpAction)
|
|
208
|
+
_dp_state: Final = DataPointField(field=Field.STATE, dpt=DpSwitch)
|
|
209
|
+
|
|
210
|
+
@state_property
|
|
211
|
+
def is_jammed(self) -> bool:
|
|
212
|
+
"""Return true if lock is jammed."""
|
|
213
|
+
return self._dp_error.value is not None and self._dp_error.value != _LockError.NO_ERROR
|
|
214
|
+
|
|
215
|
+
@state_property
|
|
216
|
+
def is_locked(self) -> bool:
|
|
217
|
+
"""Return true if lock is on."""
|
|
218
|
+
return self._dp_state.value is not True
|
|
219
|
+
|
|
220
|
+
@state_property
|
|
221
|
+
def is_locking(self) -> bool | None:
|
|
222
|
+
"""Return true if the lock is locking."""
|
|
223
|
+
if self._dp_direction.value is not None:
|
|
224
|
+
return str(self._dp_direction.value) == _LockActivity.LOCKING
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
@state_property
|
|
228
|
+
def is_unlocking(self) -> bool | None:
|
|
229
|
+
"""Return true if the lock is unlocking."""
|
|
230
|
+
if self._dp_direction.value is not None:
|
|
231
|
+
return str(self._dp_direction.value) == _LockActivity.UNLOCKING
|
|
232
|
+
return None
|
|
233
|
+
|
|
234
|
+
@bind_collector
|
|
235
|
+
async def lock(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
236
|
+
"""Lock the lock."""
|
|
237
|
+
await self._dp_state.send_value(value=False, collector=collector)
|
|
238
|
+
|
|
239
|
+
@bind_collector
|
|
240
|
+
async def open(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
241
|
+
"""Open the lock."""
|
|
242
|
+
await self._dp_open.send_value(value=True, collector=collector)
|
|
243
|
+
|
|
244
|
+
@bind_collector
|
|
245
|
+
async def unlock(self, *, collector: CallParameterCollector | None = None) -> None:
|
|
246
|
+
"""Unlock the lock."""
|
|
247
|
+
await self._dp_state.send_value(value=True, collector=collector)
|
|
248
|
+
|
|
249
|
+
def _compute_capabilities(self) -> LockCapabilities:
|
|
250
|
+
"""Compute static capabilities. RF locks support open."""
|
|
251
|
+
return IP_LOCK_CAPABILITIES
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
# =============================================================================
|
|
255
|
+
# DeviceProfileRegistry Registration
|
|
256
|
+
# =============================================================================
|
|
257
|
+
|
|
258
|
+
# RF Lock (HM-Sec-Key)
|
|
259
|
+
DeviceProfileRegistry.register(
|
|
260
|
+
category=DataPointCategory.LOCK,
|
|
261
|
+
models="HM-Sec-Key",
|
|
262
|
+
data_point_class=CustomDpRfLock,
|
|
263
|
+
profile_type=DeviceProfile.RF_LOCK,
|
|
264
|
+
channels=(1,),
|
|
265
|
+
extended=ExtendedDeviceConfig(
|
|
266
|
+
additional_data_points={
|
|
267
|
+
1: (
|
|
268
|
+
Parameter.DIRECTION,
|
|
269
|
+
Parameter.ERROR,
|
|
270
|
+
),
|
|
271
|
+
}
|
|
272
|
+
),
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
# IP Lock with Button Lock (HmIP-DLD - multiple configs)
|
|
276
|
+
DeviceProfileRegistry.register_multiple(
|
|
277
|
+
category=DataPointCategory.LOCK,
|
|
278
|
+
models="HmIP-DLD",
|
|
279
|
+
configs=(
|
|
280
|
+
DeviceConfig(
|
|
281
|
+
data_point_class=CustomDpIpLock,
|
|
282
|
+
profile_type=DeviceProfile.IP_LOCK,
|
|
283
|
+
extended=ExtendedDeviceConfig(
|
|
284
|
+
additional_data_points={
|
|
285
|
+
0: (Parameter.ERROR_JAMMED,),
|
|
286
|
+
}
|
|
287
|
+
),
|
|
288
|
+
),
|
|
289
|
+
DeviceConfig(
|
|
290
|
+
data_point_class=CustomDpButtonLock,
|
|
291
|
+
profile_type=DeviceProfile.IP_BUTTON_LOCK,
|
|
292
|
+
channels=(0,),
|
|
293
|
+
),
|
|
294
|
+
),
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
# RF Button Lock
|
|
298
|
+
DeviceProfileRegistry.register(
|
|
299
|
+
category=DataPointCategory.LOCK,
|
|
300
|
+
models="HM-TC-IT-WM-W-EU",
|
|
301
|
+
data_point_class=CustomDpButtonLock,
|
|
302
|
+
profile_type=DeviceProfile.RF_BUTTON_LOCK,
|
|
303
|
+
channels=(None,),
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
# IP Button Lock (various thermostats and controls)
|
|
307
|
+
DeviceProfileRegistry.register(
|
|
308
|
+
category=DataPointCategory.LOCK,
|
|
309
|
+
models=(
|
|
310
|
+
"ALPHA-IP-RBG",
|
|
311
|
+
"HmIP-BWTH",
|
|
312
|
+
"HmIP-FAL",
|
|
313
|
+
"HmIP-WGT",
|
|
314
|
+
"HmIP-WTH",
|
|
315
|
+
"HmIP-eTRV",
|
|
316
|
+
"HmIPW-FAL",
|
|
317
|
+
"HmIPW-WTH",
|
|
318
|
+
),
|
|
319
|
+
data_point_class=CustomDpButtonLock,
|
|
320
|
+
profile_type=DeviceProfile.IP_BUTTON_LOCK,
|
|
321
|
+
channels=(0,),
|
|
322
|
+
)
|