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,1921 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2026
|
|
3
|
+
"""
|
|
4
|
+
Model protocol interfaces.
|
|
5
|
+
|
|
6
|
+
This module defines protocol interfaces for Device, Channel, DataPoint,
|
|
7
|
+
Hub, and WeekProfile classes, allowing components to depend on specific
|
|
8
|
+
capabilities without coupling to the full implementation.
|
|
9
|
+
|
|
10
|
+
Protocol Hierarchy
|
|
11
|
+
------------------
|
|
12
|
+
|
|
13
|
+
Channel protocols (ChannelProtocol composed of):
|
|
14
|
+
- ChannelIdentityProtocol: Basic identification (address, name, no, type_name, unique_id, rega_id)
|
|
15
|
+
- ChannelDataPointAccessProtocol: DataPoint and event access methods
|
|
16
|
+
- ChannelGroupingProtocol: Channel group management (group_master, group_no, link_peer_channels)
|
|
17
|
+
- ChannelMetadataProtocol: Additional metadata (device, function, room, paramset_descriptions)
|
|
18
|
+
- ChannelLinkManagementProtocol: Central link operations
|
|
19
|
+
- ChannelLifecycleProtocol: Lifecycle methods (finalize_init, on_config_changed, remove)
|
|
20
|
+
|
|
21
|
+
Device protocols (DeviceProtocol composed of):
|
|
22
|
+
- DeviceIdentityProtocol: Basic identification (address, name, model, manufacturer, interface)
|
|
23
|
+
- DeviceChannelAccessProtocol: Channel and DataPoint access methods
|
|
24
|
+
- DeviceAvailabilityProtocol: Availability state management
|
|
25
|
+
- DeviceFirmwareProtocol: Firmware information and update operations
|
|
26
|
+
- DeviceLinkManagementProtocol: Central link operations
|
|
27
|
+
- DeviceGroupManagementProtocol: Channel group management
|
|
28
|
+
- DeviceConfigurationProtocol: Device configuration and metadata
|
|
29
|
+
- DeviceWeekProfileProtocol: Week profile support
|
|
30
|
+
- DeviceProvidersProtocol: Protocol interface providers
|
|
31
|
+
- DeviceLifecycleProtocol: Lifecycle methods
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
from abc import abstractmethod
|
|
37
|
+
from collections.abc import Mapping
|
|
38
|
+
from datetime import datetime
|
|
39
|
+
from typing import TYPE_CHECKING, Any, Protocol, TypeAlias, Unpack, runtime_checkable
|
|
40
|
+
|
|
41
|
+
from aiohomematic.const import (
|
|
42
|
+
DP_KEY_VALUE,
|
|
43
|
+
CallSource,
|
|
44
|
+
DataPointCategory,
|
|
45
|
+
DataPointKey,
|
|
46
|
+
DataPointUsage,
|
|
47
|
+
DeviceFirmwareState,
|
|
48
|
+
DeviceTriggerEventType,
|
|
49
|
+
EventData,
|
|
50
|
+
ForcedDeviceAvailability,
|
|
51
|
+
HubValueType,
|
|
52
|
+
Interface,
|
|
53
|
+
ParameterData,
|
|
54
|
+
ParameterStatus,
|
|
55
|
+
ParameterType,
|
|
56
|
+
ParamsetKey,
|
|
57
|
+
ProductGroup,
|
|
58
|
+
ProgramData,
|
|
59
|
+
RxMode,
|
|
60
|
+
)
|
|
61
|
+
from aiohomematic.decorators import inspector
|
|
62
|
+
from aiohomematic.interfaces.operations import (
|
|
63
|
+
DeviceDescriptionProviderProtocol,
|
|
64
|
+
DeviceDetailsProviderProtocol,
|
|
65
|
+
ParameterVisibilityProviderProtocol,
|
|
66
|
+
ParamsetDescriptionProviderProtocol,
|
|
67
|
+
TaskSchedulerProtocol,
|
|
68
|
+
)
|
|
69
|
+
from aiohomematic.property_decorators import state_property
|
|
70
|
+
from aiohomematic.type_aliases import DataPointUpdatedHandler, DeviceRemovedHandler, FirmwareUpdateHandler
|
|
71
|
+
|
|
72
|
+
if TYPE_CHECKING:
|
|
73
|
+
from aiohomematic.interfaces import (
|
|
74
|
+
CentralInfoProtocol,
|
|
75
|
+
ChannelLookupProtocol,
|
|
76
|
+
ClientProtocol,
|
|
77
|
+
ConfigProviderProtocol,
|
|
78
|
+
DataCacheProviderProtocol,
|
|
79
|
+
DataPointProviderProtocol,
|
|
80
|
+
EventBusProviderProtocol,
|
|
81
|
+
EventPublisherProtocol,
|
|
82
|
+
EventSubscriptionManagerProtocol,
|
|
83
|
+
)
|
|
84
|
+
from aiohomematic.interfaces.central import FirmwareDataRefresherProtocol
|
|
85
|
+
from aiohomematic.model.availability import AvailabilityInfo
|
|
86
|
+
from aiohomematic.model.custom import DeviceConfig
|
|
87
|
+
from aiohomematic.model.custom.mixins import StateChangeArgs
|
|
88
|
+
from aiohomematic.model.support import DataPointNameData
|
|
89
|
+
from aiohomematic.type_aliases import UnsubscribeCallback
|
|
90
|
+
|
|
91
|
+
# =============================================================================
|
|
92
|
+
# DataPoint Protocol Interfaces
|
|
93
|
+
# =============================================================================
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@runtime_checkable
|
|
97
|
+
class CallbackDataPointProtocol(Protocol):
|
|
98
|
+
"""
|
|
99
|
+
Protocol for callback-based data points.
|
|
100
|
+
|
|
101
|
+
Base protocol for all data point types, providing event handling,
|
|
102
|
+
subscription management, and timestamp tracking.
|
|
103
|
+
"""
|
|
104
|
+
|
|
105
|
+
__slots__ = ()
|
|
106
|
+
|
|
107
|
+
@property
|
|
108
|
+
@abstractmethod
|
|
109
|
+
def additional_information(self) -> dict[str, Any]:
|
|
110
|
+
"""Return additional information."""
|
|
111
|
+
|
|
112
|
+
@property
|
|
113
|
+
@abstractmethod
|
|
114
|
+
def available(self) -> bool:
|
|
115
|
+
"""Return the availability of the device."""
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
@abstractmethod
|
|
119
|
+
def category(self) -> DataPointCategory:
|
|
120
|
+
"""Return the category of the data point."""
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
@abstractmethod
|
|
124
|
+
def custom_id(self) -> str | None:
|
|
125
|
+
"""Return the custom id."""
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
@abstractmethod
|
|
129
|
+
def enabled_default(self) -> bool:
|
|
130
|
+
"""Return if data point should be enabled based on usage attribute."""
|
|
131
|
+
|
|
132
|
+
@property
|
|
133
|
+
@abstractmethod
|
|
134
|
+
def full_name(self) -> str:
|
|
135
|
+
"""Return the full name of the data point."""
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
@abstractmethod
|
|
139
|
+
def is_refreshed(self) -> bool:
|
|
140
|
+
"""Return if the data_point has been refreshed (received a value)."""
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
@abstractmethod
|
|
144
|
+
def is_registered(self) -> bool:
|
|
145
|
+
"""Return if data point is registered externally."""
|
|
146
|
+
|
|
147
|
+
@property
|
|
148
|
+
@abstractmethod
|
|
149
|
+
def is_status_valid(self) -> bool:
|
|
150
|
+
"""Return if the status indicates a valid value."""
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
@abstractmethod
|
|
154
|
+
def is_valid(self) -> bool:
|
|
155
|
+
"""Return if the value is valid (refreshed and status is OK)."""
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
@abstractmethod
|
|
159
|
+
def modified_at(self) -> datetime:
|
|
160
|
+
"""Return the last update datetime value."""
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
@abstractmethod
|
|
164
|
+
def name(self) -> str:
|
|
165
|
+
"""Return the name of the data point."""
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
@abstractmethod
|
|
169
|
+
def published_event_at(self) -> datetime:
|
|
170
|
+
"""Return the data point updated published an event at."""
|
|
171
|
+
|
|
172
|
+
@property
|
|
173
|
+
@abstractmethod
|
|
174
|
+
def published_event_recently(self) -> bool:
|
|
175
|
+
"""Return if the data point published an event recently."""
|
|
176
|
+
|
|
177
|
+
@property
|
|
178
|
+
@abstractmethod
|
|
179
|
+
def refreshed_at(self) -> datetime:
|
|
180
|
+
"""Return the last refresh datetime value."""
|
|
181
|
+
|
|
182
|
+
@property
|
|
183
|
+
@abstractmethod
|
|
184
|
+
def service_method_names(self) -> tuple[str, ...]:
|
|
185
|
+
"""Return all service method names."""
|
|
186
|
+
|
|
187
|
+
@property
|
|
188
|
+
@abstractmethod
|
|
189
|
+
def service_methods(self) -> Mapping[str, Any]:
|
|
190
|
+
"""Return all service methods."""
|
|
191
|
+
|
|
192
|
+
@property
|
|
193
|
+
@abstractmethod
|
|
194
|
+
def set_path(self) -> str:
|
|
195
|
+
"""Return the base set path of the data point."""
|
|
196
|
+
|
|
197
|
+
@property
|
|
198
|
+
@abstractmethod
|
|
199
|
+
def signature(self) -> str:
|
|
200
|
+
"""Return the data point signature."""
|
|
201
|
+
|
|
202
|
+
@property
|
|
203
|
+
@abstractmethod
|
|
204
|
+
def state_path(self) -> str:
|
|
205
|
+
"""Return the base state path of the data point."""
|
|
206
|
+
|
|
207
|
+
@property
|
|
208
|
+
@abstractmethod
|
|
209
|
+
def unique_id(self) -> str:
|
|
210
|
+
"""Return the unique id."""
|
|
211
|
+
|
|
212
|
+
@property
|
|
213
|
+
@abstractmethod
|
|
214
|
+
def usage(self) -> DataPointUsage:
|
|
215
|
+
"""Return the data point usage."""
|
|
216
|
+
|
|
217
|
+
@abstractmethod
|
|
218
|
+
def cleanup_subscriptions(self) -> None:
|
|
219
|
+
"""Clean up all EventBus subscriptions for this data point."""
|
|
220
|
+
|
|
221
|
+
@abstractmethod
|
|
222
|
+
def publish_data_point_updated_event(
|
|
223
|
+
self,
|
|
224
|
+
*,
|
|
225
|
+
data_point: CallbackDataPointProtocol | None = None,
|
|
226
|
+
custom_id: str | None = None,
|
|
227
|
+
old_value: Any = None,
|
|
228
|
+
new_value: Any = None,
|
|
229
|
+
) -> None:
|
|
230
|
+
"""Publish a data point updated event."""
|
|
231
|
+
|
|
232
|
+
@abstractmethod
|
|
233
|
+
def publish_device_removed_event(self) -> None:
|
|
234
|
+
"""Publish a device removed event."""
|
|
235
|
+
|
|
236
|
+
@abstractmethod
|
|
237
|
+
def subscribe_to_data_point_updated(
|
|
238
|
+
self, *, handler: DataPointUpdatedHandler, custom_id: str
|
|
239
|
+
) -> UnsubscribeCallback:
|
|
240
|
+
"""Subscribe to data point updated event."""
|
|
241
|
+
|
|
242
|
+
@abstractmethod
|
|
243
|
+
def subscribe_to_device_removed(self, *, handler: DeviceRemovedHandler) -> UnsubscribeCallback:
|
|
244
|
+
"""Subscribe to the device removed event."""
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@runtime_checkable
|
|
248
|
+
class GenericHubDataPointProtocol(CallbackDataPointProtocol, Protocol):
|
|
249
|
+
"""
|
|
250
|
+
Protocol for hub-level data points (programs, sysvars).
|
|
251
|
+
|
|
252
|
+
Extends CallbackDataPointProtocol with properties specific to
|
|
253
|
+
hub-level data points that are not bound to device channels.
|
|
254
|
+
"""
|
|
255
|
+
|
|
256
|
+
__slots__ = ()
|
|
257
|
+
|
|
258
|
+
@property
|
|
259
|
+
@abstractmethod
|
|
260
|
+
def channel(self) -> ChannelProtocol | None:
|
|
261
|
+
"""Return the identified channel."""
|
|
262
|
+
|
|
263
|
+
@property
|
|
264
|
+
@abstractmethod
|
|
265
|
+
def description(self) -> str | None:
|
|
266
|
+
"""Return data point description."""
|
|
267
|
+
|
|
268
|
+
@property
|
|
269
|
+
@abstractmethod
|
|
270
|
+
def legacy_name(self) -> str | None:
|
|
271
|
+
"""Return the original name."""
|
|
272
|
+
|
|
273
|
+
@property
|
|
274
|
+
@abstractmethod
|
|
275
|
+
def state_uncertain(self) -> bool:
|
|
276
|
+
"""Return if the state is uncertain."""
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
@runtime_checkable
|
|
280
|
+
class GenericSysvarDataPointProtocol(GenericHubDataPointProtocol, Protocol):
|
|
281
|
+
"""
|
|
282
|
+
Protocol for system variable data points.
|
|
283
|
+
|
|
284
|
+
Extends GenericHubDataPointProtocol with methods for reading
|
|
285
|
+
and writing system variables.
|
|
286
|
+
"""
|
|
287
|
+
|
|
288
|
+
__slots__ = ()
|
|
289
|
+
|
|
290
|
+
@property
|
|
291
|
+
@abstractmethod
|
|
292
|
+
def data_type(self) -> HubValueType | None:
|
|
293
|
+
"""Return the data type of the system variable."""
|
|
294
|
+
|
|
295
|
+
@property
|
|
296
|
+
@abstractmethod
|
|
297
|
+
def is_extended(self) -> bool:
|
|
298
|
+
"""Return if the data point is an extended type."""
|
|
299
|
+
|
|
300
|
+
@property
|
|
301
|
+
@abstractmethod
|
|
302
|
+
def max(self) -> float | int | None:
|
|
303
|
+
"""Return the max value."""
|
|
304
|
+
|
|
305
|
+
@property
|
|
306
|
+
@abstractmethod
|
|
307
|
+
def min(self) -> float | int | None:
|
|
308
|
+
"""Return the min value."""
|
|
309
|
+
|
|
310
|
+
@property
|
|
311
|
+
@abstractmethod
|
|
312
|
+
def previous_value(self) -> Any:
|
|
313
|
+
"""Return the previous value."""
|
|
314
|
+
|
|
315
|
+
@property
|
|
316
|
+
@abstractmethod
|
|
317
|
+
def unit(self) -> str | None:
|
|
318
|
+
"""Return the unit of the data point."""
|
|
319
|
+
|
|
320
|
+
@property
|
|
321
|
+
@abstractmethod
|
|
322
|
+
def value(self) -> Any:
|
|
323
|
+
"""Return the value."""
|
|
324
|
+
|
|
325
|
+
@property
|
|
326
|
+
@abstractmethod
|
|
327
|
+
def values(self) -> tuple[str, ...] | None:
|
|
328
|
+
"""Return the value list."""
|
|
329
|
+
|
|
330
|
+
@property
|
|
331
|
+
@abstractmethod
|
|
332
|
+
def vid(self) -> str:
|
|
333
|
+
"""Return sysvar id."""
|
|
334
|
+
|
|
335
|
+
@abstractmethod
|
|
336
|
+
async def event(self, *, value: Any, received_at: datetime) -> None:
|
|
337
|
+
"""Handle event for which this data point has subscribed."""
|
|
338
|
+
|
|
339
|
+
@abstractmethod
|
|
340
|
+
async def send_variable(self, *, value: Any) -> None:
|
|
341
|
+
"""Set variable value on the backend."""
|
|
342
|
+
|
|
343
|
+
@abstractmethod
|
|
344
|
+
def write_value(self, *, value: Any, write_at: datetime) -> None:
|
|
345
|
+
"""Set variable value on the backend."""
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
@runtime_checkable
|
|
349
|
+
class GenericProgramDataPointProtocol(GenericHubDataPointProtocol, Protocol):
|
|
350
|
+
"""
|
|
351
|
+
Protocol for program data points.
|
|
352
|
+
|
|
353
|
+
Extends GenericHubDataPointProtocol with methods for managing
|
|
354
|
+
CCU programs.
|
|
355
|
+
"""
|
|
356
|
+
|
|
357
|
+
__slots__ = ()
|
|
358
|
+
|
|
359
|
+
@property
|
|
360
|
+
@abstractmethod
|
|
361
|
+
def is_active(self) -> bool:
|
|
362
|
+
"""Return if the program is active."""
|
|
363
|
+
|
|
364
|
+
@property
|
|
365
|
+
@abstractmethod
|
|
366
|
+
def is_internal(self) -> bool:
|
|
367
|
+
"""Return if the program is internal."""
|
|
368
|
+
|
|
369
|
+
@property
|
|
370
|
+
@abstractmethod
|
|
371
|
+
def last_execute_time(self) -> str:
|
|
372
|
+
"""Return the last execute time."""
|
|
373
|
+
|
|
374
|
+
@property
|
|
375
|
+
@abstractmethod
|
|
376
|
+
def pid(self) -> str:
|
|
377
|
+
"""Return the program id."""
|
|
378
|
+
|
|
379
|
+
@abstractmethod
|
|
380
|
+
def update_data(self, *, data: ProgramData) -> None:
|
|
381
|
+
"""Update program data from backend."""
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
@runtime_checkable
|
|
385
|
+
class HubSensorDataPointProtocol(GenericHubDataPointProtocol, Protocol):
|
|
386
|
+
"""
|
|
387
|
+
Protocol for sensors bases on hub data points, that ar no sysvars.
|
|
388
|
+
|
|
389
|
+
Provides properties like data_type.
|
|
390
|
+
"""
|
|
391
|
+
|
|
392
|
+
@property
|
|
393
|
+
@abstractmethod
|
|
394
|
+
def data_type(self) -> HubValueType | None:
|
|
395
|
+
"""Return the data type of the system variable."""
|
|
396
|
+
|
|
397
|
+
@property
|
|
398
|
+
@abstractmethod
|
|
399
|
+
def unit(self) -> str | None:
|
|
400
|
+
"""Return the unit of the data point."""
|
|
401
|
+
|
|
402
|
+
@property
|
|
403
|
+
@abstractmethod
|
|
404
|
+
def value(self) -> Any:
|
|
405
|
+
"""Return the value."""
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
@runtime_checkable
|
|
409
|
+
class HubBinarySensorDataPointProtocol(GenericHubDataPointProtocol, Protocol):
|
|
410
|
+
"""
|
|
411
|
+
Protocol for binary sensor hub data points.
|
|
412
|
+
|
|
413
|
+
Provides properties for boolean sensor values like connectivity status.
|
|
414
|
+
"""
|
|
415
|
+
|
|
416
|
+
__slots__ = ()
|
|
417
|
+
|
|
418
|
+
@property
|
|
419
|
+
@abstractmethod
|
|
420
|
+
def data_type(self) -> HubValueType | None:
|
|
421
|
+
"""Return the data type of the sensor."""
|
|
422
|
+
|
|
423
|
+
@property
|
|
424
|
+
@abstractmethod
|
|
425
|
+
def value(self) -> bool:
|
|
426
|
+
"""Return the boolean value."""
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
@runtime_checkable
|
|
430
|
+
class GenericInstallModeDataPointProtocol(HubSensorDataPointProtocol, Protocol):
|
|
431
|
+
"""
|
|
432
|
+
Protocol for install mode sensor data point.
|
|
433
|
+
|
|
434
|
+
Provides properties and methods for monitoring the CCU install mode
|
|
435
|
+
countdown timer (device pairing).
|
|
436
|
+
"""
|
|
437
|
+
|
|
438
|
+
__slots__ = ()
|
|
439
|
+
|
|
440
|
+
@property
|
|
441
|
+
@abstractmethod
|
|
442
|
+
def is_active(self) -> bool:
|
|
443
|
+
"""Return if install mode is active."""
|
|
444
|
+
|
|
445
|
+
@abstractmethod
|
|
446
|
+
def start_countdown(self, *, seconds: int) -> None:
|
|
447
|
+
"""Start local countdown."""
|
|
448
|
+
|
|
449
|
+
@abstractmethod
|
|
450
|
+
def stop_countdown(self) -> None:
|
|
451
|
+
"""Stop countdown."""
|
|
452
|
+
|
|
453
|
+
@abstractmethod
|
|
454
|
+
def sync_from_backend(self, *, remaining_seconds: int) -> None:
|
|
455
|
+
"""Sync countdown from backend value."""
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
@runtime_checkable
|
|
459
|
+
class BaseDataPointProtocol(CallbackDataPointProtocol, Protocol):
|
|
460
|
+
"""
|
|
461
|
+
Protocol for channel-bound data points.
|
|
462
|
+
|
|
463
|
+
Extends CallbackDataPointProtocol with channel/device associations
|
|
464
|
+
and timer functionality.
|
|
465
|
+
"""
|
|
466
|
+
|
|
467
|
+
__slots__ = ()
|
|
468
|
+
|
|
469
|
+
@property
|
|
470
|
+
@abstractmethod
|
|
471
|
+
def channel(self) -> ChannelProtocol:
|
|
472
|
+
"""Return the channel of the data point."""
|
|
473
|
+
|
|
474
|
+
@property
|
|
475
|
+
@abstractmethod
|
|
476
|
+
def device(self) -> DeviceProtocol:
|
|
477
|
+
"""Return the device of the data point."""
|
|
478
|
+
|
|
479
|
+
@property
|
|
480
|
+
@abstractmethod
|
|
481
|
+
def function(self) -> str | None:
|
|
482
|
+
"""Return the function."""
|
|
483
|
+
|
|
484
|
+
@property
|
|
485
|
+
@abstractmethod
|
|
486
|
+
def is_in_multiple_channels(self) -> bool:
|
|
487
|
+
"""Return if the parameter is in multiple channels."""
|
|
488
|
+
|
|
489
|
+
@property
|
|
490
|
+
@abstractmethod
|
|
491
|
+
def name_data(self) -> DataPointNameData:
|
|
492
|
+
"""Return the data point name data."""
|
|
493
|
+
|
|
494
|
+
@property
|
|
495
|
+
@abstractmethod
|
|
496
|
+
def room(self) -> str | None:
|
|
497
|
+
"""Return the room if only one exists."""
|
|
498
|
+
|
|
499
|
+
@property
|
|
500
|
+
@abstractmethod
|
|
501
|
+
def rooms(self) -> set[str]:
|
|
502
|
+
"""Return the rooms assigned to the data point."""
|
|
503
|
+
|
|
504
|
+
@property
|
|
505
|
+
@abstractmethod
|
|
506
|
+
def timer_on_time(self) -> float | None:
|
|
507
|
+
"""Return the on_time."""
|
|
508
|
+
|
|
509
|
+
@property
|
|
510
|
+
@abstractmethod
|
|
511
|
+
def timer_on_time_running(self) -> bool:
|
|
512
|
+
"""Return if on_time is running."""
|
|
513
|
+
|
|
514
|
+
@abstractmethod
|
|
515
|
+
def force_usage(self, *, forced_usage: DataPointUsage) -> None:
|
|
516
|
+
"""Set the data point usage."""
|
|
517
|
+
|
|
518
|
+
@abstractmethod
|
|
519
|
+
@inspector(re_raise=False)
|
|
520
|
+
async def load_data_point_value(self, *, call_source: CallSource, direct_call: bool = False) -> None:
|
|
521
|
+
"""Initialize the data point data."""
|
|
522
|
+
|
|
523
|
+
@abstractmethod
|
|
524
|
+
def reset_timer_on_time(self) -> None:
|
|
525
|
+
"""Reset the on_time."""
|
|
526
|
+
|
|
527
|
+
@abstractmethod
|
|
528
|
+
def set_timer_on_time(self, *, on_time: float) -> None:
|
|
529
|
+
"""Set the on_time."""
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
@runtime_checkable
|
|
533
|
+
class BaseParameterDataPointProtocol[ParameterT](BaseDataPointProtocol, Protocol):
|
|
534
|
+
"""
|
|
535
|
+
Protocol for parameter-backed data points with typed values.
|
|
536
|
+
|
|
537
|
+
Extends BaseDataPointProtocol with value handling, unit conversion,
|
|
538
|
+
validation, and RPC communication for data points mapped to
|
|
539
|
+
Homematic device parameters.
|
|
540
|
+
|
|
541
|
+
Type Parameters:
|
|
542
|
+
ParameterT: The type of value this data point holds and returns.
|
|
543
|
+
"""
|
|
544
|
+
|
|
545
|
+
__slots__ = ()
|
|
546
|
+
|
|
547
|
+
@property
|
|
548
|
+
@abstractmethod
|
|
549
|
+
def default(self) -> ParameterT:
|
|
550
|
+
"""Return default value."""
|
|
551
|
+
|
|
552
|
+
@property
|
|
553
|
+
@abstractmethod
|
|
554
|
+
def dpk(self) -> DataPointKey:
|
|
555
|
+
"""Return data point key value."""
|
|
556
|
+
|
|
557
|
+
@property
|
|
558
|
+
@abstractmethod
|
|
559
|
+
def has_events(self) -> bool:
|
|
560
|
+
"""Return if data point supports events."""
|
|
561
|
+
|
|
562
|
+
@property
|
|
563
|
+
@abstractmethod
|
|
564
|
+
def hmtype(self) -> ParameterType:
|
|
565
|
+
"""Return the Homematic type."""
|
|
566
|
+
|
|
567
|
+
@property
|
|
568
|
+
@abstractmethod
|
|
569
|
+
def ignore_on_initial_load(self) -> bool:
|
|
570
|
+
"""Return if parameter should be ignored on initial load."""
|
|
571
|
+
|
|
572
|
+
@property
|
|
573
|
+
@abstractmethod
|
|
574
|
+
def is_forced_sensor(self) -> bool:
|
|
575
|
+
"""Return if data point is forced to read only."""
|
|
576
|
+
|
|
577
|
+
@property
|
|
578
|
+
@abstractmethod
|
|
579
|
+
def is_readable(self) -> bool:
|
|
580
|
+
"""Return if data point is readable."""
|
|
581
|
+
|
|
582
|
+
@property
|
|
583
|
+
@abstractmethod
|
|
584
|
+
def is_un_ignored(self) -> bool:
|
|
585
|
+
"""Return if the parameter is un-ignored."""
|
|
586
|
+
|
|
587
|
+
@property
|
|
588
|
+
@abstractmethod
|
|
589
|
+
def is_unit_fixed(self) -> bool:
|
|
590
|
+
"""Return if the unit is fixed."""
|
|
591
|
+
|
|
592
|
+
@property
|
|
593
|
+
@abstractmethod
|
|
594
|
+
def is_writable(self) -> bool:
|
|
595
|
+
"""Return if data point is writable."""
|
|
596
|
+
|
|
597
|
+
@property
|
|
598
|
+
@abstractmethod
|
|
599
|
+
def last_non_default_value(self) -> ParameterT | None:
|
|
600
|
+
"""Return the last meaningful (non-default) value of the data point."""
|
|
601
|
+
|
|
602
|
+
@property
|
|
603
|
+
@abstractmethod
|
|
604
|
+
def max(self) -> ParameterT:
|
|
605
|
+
"""Return max value."""
|
|
606
|
+
|
|
607
|
+
@property
|
|
608
|
+
@abstractmethod
|
|
609
|
+
def min(self) -> ParameterT:
|
|
610
|
+
"""Return min value."""
|
|
611
|
+
|
|
612
|
+
@property
|
|
613
|
+
@abstractmethod
|
|
614
|
+
def multiplier(self) -> float:
|
|
615
|
+
"""Return multiplier value."""
|
|
616
|
+
|
|
617
|
+
@property
|
|
618
|
+
@abstractmethod
|
|
619
|
+
def parameter(self) -> str:
|
|
620
|
+
"""Return parameter name."""
|
|
621
|
+
|
|
622
|
+
@property
|
|
623
|
+
@abstractmethod
|
|
624
|
+
def paramset_key(self) -> ParamsetKey:
|
|
625
|
+
"""Return paramset_key name."""
|
|
626
|
+
|
|
627
|
+
@property
|
|
628
|
+
@abstractmethod
|
|
629
|
+
def raw_unit(self) -> str | None:
|
|
630
|
+
"""Return raw unit value."""
|
|
631
|
+
|
|
632
|
+
@property
|
|
633
|
+
@abstractmethod
|
|
634
|
+
def requires_polling(self) -> bool:
|
|
635
|
+
"""Return whether the data point requires polling."""
|
|
636
|
+
|
|
637
|
+
@property
|
|
638
|
+
@abstractmethod
|
|
639
|
+
def service(self) -> bool:
|
|
640
|
+
"""Return if data point is relevant for service messages."""
|
|
641
|
+
|
|
642
|
+
@property
|
|
643
|
+
@abstractmethod
|
|
644
|
+
def state_uncertain(self) -> bool:
|
|
645
|
+
"""Return if the state is uncertain."""
|
|
646
|
+
|
|
647
|
+
@property
|
|
648
|
+
@abstractmethod
|
|
649
|
+
def status(self) -> ParameterStatus | None:
|
|
650
|
+
"""Return the current status of this parameter value."""
|
|
651
|
+
|
|
652
|
+
@property
|
|
653
|
+
@abstractmethod
|
|
654
|
+
def status_dpk(self) -> DataPointKey | None:
|
|
655
|
+
"""Return the DataPointKey for the STATUS parameter."""
|
|
656
|
+
|
|
657
|
+
@property
|
|
658
|
+
@abstractmethod
|
|
659
|
+
def unconfirmed_last_value_send(self) -> ParameterT:
|
|
660
|
+
"""Return the unconfirmed value send for the data point."""
|
|
661
|
+
|
|
662
|
+
@property
|
|
663
|
+
@abstractmethod
|
|
664
|
+
def unit(self) -> str | None:
|
|
665
|
+
"""Return unit value."""
|
|
666
|
+
|
|
667
|
+
@property
|
|
668
|
+
@abstractmethod
|
|
669
|
+
def values(self) -> tuple[str, ...] | None:
|
|
670
|
+
"""Return the values."""
|
|
671
|
+
|
|
672
|
+
@property
|
|
673
|
+
@abstractmethod
|
|
674
|
+
def visible(self) -> bool:
|
|
675
|
+
"""Return if data point is visible in backend."""
|
|
676
|
+
|
|
677
|
+
@state_property
|
|
678
|
+
@abstractmethod
|
|
679
|
+
def value(self) -> ParameterT:
|
|
680
|
+
"""Return the value."""
|
|
681
|
+
|
|
682
|
+
@abstractmethod
|
|
683
|
+
async def event(self, *, value: Any, received_at: datetime) -> None:
|
|
684
|
+
"""Handle event for which this handler has subscribed."""
|
|
685
|
+
|
|
686
|
+
@abstractmethod
|
|
687
|
+
def force_to_sensor(self) -> None:
|
|
688
|
+
"""Change the category of the data point to sensor (read-only)."""
|
|
689
|
+
|
|
690
|
+
@abstractmethod
|
|
691
|
+
def get_event_data(self, *, value: Any = None) -> EventData:
|
|
692
|
+
"""Get the event data."""
|
|
693
|
+
|
|
694
|
+
@abstractmethod
|
|
695
|
+
def update_parameter_data(self) -> None:
|
|
696
|
+
"""Update parameter data."""
|
|
697
|
+
|
|
698
|
+
@abstractmethod
|
|
699
|
+
def update_status(self, *, status_value: int | str) -> None:
|
|
700
|
+
"""Update the status from a STATUS parameter event."""
|
|
701
|
+
|
|
702
|
+
@abstractmethod
|
|
703
|
+
def write_temporary_value(self, *, value: Any, write_at: datetime) -> None:
|
|
704
|
+
"""Update the temporary value of the data point."""
|
|
705
|
+
|
|
706
|
+
@abstractmethod
|
|
707
|
+
def write_value(self, *, value: Any, write_at: datetime) -> tuple[ParameterT, ParameterT]:
|
|
708
|
+
"""Update value of the data point."""
|
|
709
|
+
|
|
710
|
+
|
|
711
|
+
@runtime_checkable
|
|
712
|
+
class GenericDataPointProtocol[ParameterT](BaseParameterDataPointProtocol[ParameterT], Protocol):
|
|
713
|
+
"""
|
|
714
|
+
Protocol for generic parameter-backed data points.
|
|
715
|
+
|
|
716
|
+
Extends BaseParameterDataPointProtocol with the usage property
|
|
717
|
+
and send_value method specific to generic data points.
|
|
718
|
+
|
|
719
|
+
Type Parameters:
|
|
720
|
+
ParameterT: The type of value this data point holds and returns.
|
|
721
|
+
"""
|
|
722
|
+
|
|
723
|
+
__slots__ = ()
|
|
724
|
+
|
|
725
|
+
@property
|
|
726
|
+
@abstractmethod
|
|
727
|
+
def usage(self) -> DataPointUsage:
|
|
728
|
+
"""Return the data point usage."""
|
|
729
|
+
|
|
730
|
+
@abstractmethod
|
|
731
|
+
async def finalize_init(self) -> None:
|
|
732
|
+
"""Finalize the data point init action."""
|
|
733
|
+
|
|
734
|
+
@abstractmethod
|
|
735
|
+
def is_state_change(self, *, value: ParameterT) -> bool:
|
|
736
|
+
"""Check if the state/value changes."""
|
|
737
|
+
|
|
738
|
+
@abstractmethod
|
|
739
|
+
async def on_config_changed(self) -> None:
|
|
740
|
+
"""Handle config changed event."""
|
|
741
|
+
|
|
742
|
+
@abstractmethod
|
|
743
|
+
async def send_value(
|
|
744
|
+
self,
|
|
745
|
+
*,
|
|
746
|
+
value: Any,
|
|
747
|
+
collector: Any | None = None,
|
|
748
|
+
collector_order: int = 50,
|
|
749
|
+
do_validate: bool = True,
|
|
750
|
+
) -> set[DP_KEY_VALUE]:
|
|
751
|
+
"""Send value to CCU or use collector if set."""
|
|
752
|
+
|
|
753
|
+
@abstractmethod
|
|
754
|
+
def subscribe_to_internal_data_point_updated(self, *, handler: DataPointUpdatedHandler) -> UnsubscribeCallback:
|
|
755
|
+
"""Subscribe to internal data point updated event."""
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
@runtime_checkable
|
|
759
|
+
class GenericEventProtocol[ParameterT](BaseParameterDataPointProtocol[ParameterT], Protocol):
|
|
760
|
+
"""
|
|
761
|
+
Protocol for event data points.
|
|
762
|
+
|
|
763
|
+
Extends BaseParameterDataPointProtocol with event-specific functionality
|
|
764
|
+
for handling button presses, device errors, and impulse notifications.
|
|
765
|
+
|
|
766
|
+
Type Parameters:
|
|
767
|
+
ParameterT: The type of value this event holds.
|
|
768
|
+
"""
|
|
769
|
+
|
|
770
|
+
__slots__ = ()
|
|
771
|
+
|
|
772
|
+
@property
|
|
773
|
+
@abstractmethod
|
|
774
|
+
def event_type(self) -> DeviceTriggerEventType:
|
|
775
|
+
"""Return the event type of the event."""
|
|
776
|
+
|
|
777
|
+
@property
|
|
778
|
+
@abstractmethod
|
|
779
|
+
def usage(self) -> DataPointUsage:
|
|
780
|
+
"""Return the data point usage."""
|
|
781
|
+
|
|
782
|
+
@abstractmethod
|
|
783
|
+
async def finalize_init(self) -> None:
|
|
784
|
+
"""Finalize the event init action."""
|
|
785
|
+
|
|
786
|
+
@abstractmethod
|
|
787
|
+
async def on_config_changed(self) -> None:
|
|
788
|
+
"""Handle config changed event."""
|
|
789
|
+
|
|
790
|
+
@abstractmethod
|
|
791
|
+
def publish_event(self, *, value: Any) -> None:
|
|
792
|
+
"""Publish an event."""
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
@runtime_checkable
|
|
796
|
+
class CustomDataPointProtocol(BaseDataPointProtocol, Protocol):
|
|
797
|
+
"""
|
|
798
|
+
Protocol for custom device-specific data points.
|
|
799
|
+
|
|
800
|
+
Defines the interface for composite data points that aggregate
|
|
801
|
+
multiple GenericDataPoints to represent complex devices.
|
|
802
|
+
"""
|
|
803
|
+
|
|
804
|
+
__slots__ = ()
|
|
805
|
+
|
|
806
|
+
@property
|
|
807
|
+
@abstractmethod
|
|
808
|
+
def allow_undefined_generic_data_points(self) -> bool:
|
|
809
|
+
"""Return if undefined generic data points are allowed."""
|
|
810
|
+
|
|
811
|
+
@property
|
|
812
|
+
@abstractmethod
|
|
813
|
+
def data_point_name_postfix(self) -> str:
|
|
814
|
+
"""Return the data point name postfix."""
|
|
815
|
+
|
|
816
|
+
@property
|
|
817
|
+
@abstractmethod
|
|
818
|
+
def device_config(self) -> DeviceConfig:
|
|
819
|
+
"""Return the custom config."""
|
|
820
|
+
|
|
821
|
+
@property
|
|
822
|
+
@abstractmethod
|
|
823
|
+
def group_no(self) -> int | None:
|
|
824
|
+
"""Return the base channel no of the data point."""
|
|
825
|
+
|
|
826
|
+
@property
|
|
827
|
+
@abstractmethod
|
|
828
|
+
def has_data_points(self) -> bool:
|
|
829
|
+
"""Return if there are data points."""
|
|
830
|
+
|
|
831
|
+
@property
|
|
832
|
+
@abstractmethod
|
|
833
|
+
def has_schedule(self) -> bool:
|
|
834
|
+
"""Return if device supports schedule."""
|
|
835
|
+
|
|
836
|
+
@property
|
|
837
|
+
@abstractmethod
|
|
838
|
+
def schedule(self) -> dict[Any, Any]:
|
|
839
|
+
"""Return cached schedule entries from device week profile."""
|
|
840
|
+
|
|
841
|
+
@property
|
|
842
|
+
@abstractmethod
|
|
843
|
+
def state_uncertain(self) -> bool:
|
|
844
|
+
"""Return if the state is uncertain."""
|
|
845
|
+
|
|
846
|
+
@property
|
|
847
|
+
@abstractmethod
|
|
848
|
+
def unconfirmed_last_values_send(self) -> Mapping[Any, Any]:
|
|
849
|
+
"""Return the unconfirmed values send for the data point."""
|
|
850
|
+
|
|
851
|
+
@abstractmethod
|
|
852
|
+
async def get_schedule(self, *, force_load: bool = False) -> dict[Any, Any]:
|
|
853
|
+
"""Get schedule from device week profile."""
|
|
854
|
+
|
|
855
|
+
@abstractmethod
|
|
856
|
+
def has_data_point_key(self, *, data_point_keys: set[DataPointKey]) -> bool:
|
|
857
|
+
"""Return if a data point with one of the keys is part of this data point."""
|
|
858
|
+
|
|
859
|
+
@abstractmethod
|
|
860
|
+
def is_state_change(self, **kwargs: Unpack[StateChangeArgs]) -> bool:
|
|
861
|
+
"""Check if the state changes due to kwargs."""
|
|
862
|
+
|
|
863
|
+
@abstractmethod
|
|
864
|
+
async def set_schedule(self, *, schedule_data: dict[Any, Any]) -> None:
|
|
865
|
+
"""Set schedule on device week profile."""
|
|
866
|
+
|
|
867
|
+
@abstractmethod
|
|
868
|
+
def unsubscribe_from_data_point_updated(self) -> None:
|
|
869
|
+
"""Unregister all internal update handlers."""
|
|
870
|
+
|
|
871
|
+
|
|
872
|
+
@runtime_checkable
|
|
873
|
+
class CalculatedDataPointProtocol(BaseDataPointProtocol, Protocol):
|
|
874
|
+
"""
|
|
875
|
+
Protocol for calculated data points.
|
|
876
|
+
|
|
877
|
+
Defines the interface for data points that derive their values
|
|
878
|
+
from other data points through calculations.
|
|
879
|
+
"""
|
|
880
|
+
|
|
881
|
+
__slots__ = ()
|
|
882
|
+
|
|
883
|
+
@staticmethod
|
|
884
|
+
@abstractmethod
|
|
885
|
+
def is_relevant_for_model(*, channel: ChannelProtocol) -> bool:
|
|
886
|
+
"""Return if this calculated data point is relevant for the channel."""
|
|
887
|
+
|
|
888
|
+
@property
|
|
889
|
+
@abstractmethod
|
|
890
|
+
def data_point_name_postfix(self) -> str:
|
|
891
|
+
"""Return the data point name postfix."""
|
|
892
|
+
|
|
893
|
+
@property
|
|
894
|
+
@abstractmethod
|
|
895
|
+
def default(self) -> Any:
|
|
896
|
+
"""Return default value."""
|
|
897
|
+
|
|
898
|
+
@property
|
|
899
|
+
@abstractmethod
|
|
900
|
+
def dpk(self) -> DataPointKey:
|
|
901
|
+
"""Return data point key value."""
|
|
902
|
+
|
|
903
|
+
@property
|
|
904
|
+
@abstractmethod
|
|
905
|
+
def has_data_points(self) -> bool:
|
|
906
|
+
"""Return if there are data points."""
|
|
907
|
+
|
|
908
|
+
@property
|
|
909
|
+
@abstractmethod
|
|
910
|
+
def has_events(self) -> bool:
|
|
911
|
+
"""Return if data point supports events."""
|
|
912
|
+
|
|
913
|
+
@property
|
|
914
|
+
@abstractmethod
|
|
915
|
+
def hmtype(self) -> ParameterType:
|
|
916
|
+
"""Return the Homematic type."""
|
|
917
|
+
|
|
918
|
+
@property
|
|
919
|
+
@abstractmethod
|
|
920
|
+
def is_readable(self) -> bool:
|
|
921
|
+
"""Return if data point is readable."""
|
|
922
|
+
|
|
923
|
+
@property
|
|
924
|
+
@abstractmethod
|
|
925
|
+
def is_writable(self) -> bool:
|
|
926
|
+
"""Return if data point is writable."""
|
|
927
|
+
|
|
928
|
+
@property
|
|
929
|
+
@abstractmethod
|
|
930
|
+
def max(self) -> Any:
|
|
931
|
+
"""Return max value."""
|
|
932
|
+
|
|
933
|
+
@property
|
|
934
|
+
@abstractmethod
|
|
935
|
+
def min(self) -> Any:
|
|
936
|
+
"""Return min value."""
|
|
937
|
+
|
|
938
|
+
@property
|
|
939
|
+
@abstractmethod
|
|
940
|
+
def multiplier(self) -> float:
|
|
941
|
+
"""Return multiplier value."""
|
|
942
|
+
|
|
943
|
+
@property
|
|
944
|
+
@abstractmethod
|
|
945
|
+
def parameter(self) -> str:
|
|
946
|
+
"""Return parameter name."""
|
|
947
|
+
|
|
948
|
+
@property
|
|
949
|
+
@abstractmethod
|
|
950
|
+
def paramset_key(self) -> ParamsetKey:
|
|
951
|
+
"""Return paramset_key name."""
|
|
952
|
+
|
|
953
|
+
@property
|
|
954
|
+
@abstractmethod
|
|
955
|
+
def service(self) -> bool:
|
|
956
|
+
"""Return if data point is relevant for service messages."""
|
|
957
|
+
|
|
958
|
+
@property
|
|
959
|
+
@abstractmethod
|
|
960
|
+
def state_uncertain(self) -> bool:
|
|
961
|
+
"""Return if the state is uncertain."""
|
|
962
|
+
|
|
963
|
+
@property
|
|
964
|
+
@abstractmethod
|
|
965
|
+
def unit(self) -> str | None:
|
|
966
|
+
"""Return unit value."""
|
|
967
|
+
|
|
968
|
+
@property
|
|
969
|
+
@abstractmethod
|
|
970
|
+
def value(self) -> Any:
|
|
971
|
+
"""Return the calculated value."""
|
|
972
|
+
|
|
973
|
+
@property
|
|
974
|
+
@abstractmethod
|
|
975
|
+
def values(self) -> tuple[str, ...] | None:
|
|
976
|
+
"""Return the values."""
|
|
977
|
+
|
|
978
|
+
@property
|
|
979
|
+
@abstractmethod
|
|
980
|
+
def visible(self) -> bool:
|
|
981
|
+
"""Return if data point is visible in backend."""
|
|
982
|
+
|
|
983
|
+
@abstractmethod
|
|
984
|
+
async def finalize_init(self) -> None:
|
|
985
|
+
"""Finalize the data point init action."""
|
|
986
|
+
|
|
987
|
+
@abstractmethod
|
|
988
|
+
def is_state_change(self, **kwargs: Unpack[StateChangeArgs]) -> bool:
|
|
989
|
+
"""Check if the state changes due to kwargs."""
|
|
990
|
+
|
|
991
|
+
@abstractmethod
|
|
992
|
+
async def on_config_changed(self) -> None:
|
|
993
|
+
"""Handle config changed event."""
|
|
994
|
+
|
|
995
|
+
@abstractmethod
|
|
996
|
+
def unsubscribe_from_data_point_updated(self) -> None:
|
|
997
|
+
"""Unsubscribe from all internal update subscriptions."""
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
# =============================================================================
|
|
1001
|
+
# Channel Sub-Protocol Interfaces
|
|
1002
|
+
# =============================================================================
|
|
1003
|
+
|
|
1004
|
+
|
|
1005
|
+
class ChannelIdentityProtocol(Protocol):
|
|
1006
|
+
"""
|
|
1007
|
+
Protocol for channel identification.
|
|
1008
|
+
|
|
1009
|
+
Provides basic identity information for a channel.
|
|
1010
|
+
"""
|
|
1011
|
+
|
|
1012
|
+
__slots__ = ()
|
|
1013
|
+
|
|
1014
|
+
@property
|
|
1015
|
+
@abstractmethod
|
|
1016
|
+
def address(self) -> str:
|
|
1017
|
+
"""Return the address of the channel."""
|
|
1018
|
+
|
|
1019
|
+
@property
|
|
1020
|
+
@abstractmethod
|
|
1021
|
+
def full_name(self) -> str:
|
|
1022
|
+
"""Return the full name of the channel."""
|
|
1023
|
+
|
|
1024
|
+
@property
|
|
1025
|
+
@abstractmethod
|
|
1026
|
+
def name(self) -> str:
|
|
1027
|
+
"""Return the name of the channel."""
|
|
1028
|
+
|
|
1029
|
+
@property
|
|
1030
|
+
@abstractmethod
|
|
1031
|
+
def no(self) -> int | None:
|
|
1032
|
+
"""Return the channel number."""
|
|
1033
|
+
|
|
1034
|
+
@property
|
|
1035
|
+
@abstractmethod
|
|
1036
|
+
def rega_id(self) -> int:
|
|
1037
|
+
"""Return the id of the channel."""
|
|
1038
|
+
|
|
1039
|
+
@property
|
|
1040
|
+
@abstractmethod
|
|
1041
|
+
def type_name(self) -> str:
|
|
1042
|
+
"""Return the type name of the channel."""
|
|
1043
|
+
|
|
1044
|
+
@property
|
|
1045
|
+
@abstractmethod
|
|
1046
|
+
def unique_id(self) -> str:
|
|
1047
|
+
"""Return the unique_id of the channel."""
|
|
1048
|
+
|
|
1049
|
+
|
|
1050
|
+
class ChannelDataPointAccessProtocol(Protocol):
|
|
1051
|
+
"""
|
|
1052
|
+
Protocol for channel data point access.
|
|
1053
|
+
|
|
1054
|
+
Provides methods to access and manage data points and events.
|
|
1055
|
+
"""
|
|
1056
|
+
|
|
1057
|
+
__slots__ = ()
|
|
1058
|
+
|
|
1059
|
+
@property
|
|
1060
|
+
@abstractmethod
|
|
1061
|
+
def calculated_data_points(self) -> tuple[CalculatedDataPointProtocol, ...]:
|
|
1062
|
+
"""Return the calculated data points."""
|
|
1063
|
+
|
|
1064
|
+
@property
|
|
1065
|
+
@abstractmethod
|
|
1066
|
+
def custom_data_point(self) -> CustomDataPointProtocol | None:
|
|
1067
|
+
"""Return the custom data point."""
|
|
1068
|
+
|
|
1069
|
+
@property
|
|
1070
|
+
@abstractmethod
|
|
1071
|
+
def data_point_paths(self) -> tuple[str, ...]:
|
|
1072
|
+
"""Return the data point paths."""
|
|
1073
|
+
|
|
1074
|
+
@property
|
|
1075
|
+
@abstractmethod
|
|
1076
|
+
def generic_data_points(self) -> tuple[GenericDataPointProtocolAny, ...]:
|
|
1077
|
+
"""Return the generic data points."""
|
|
1078
|
+
|
|
1079
|
+
@property
|
|
1080
|
+
@abstractmethod
|
|
1081
|
+
def generic_events(self) -> tuple[GenericEventProtocolAny, ...]:
|
|
1082
|
+
"""Return the generic events."""
|
|
1083
|
+
|
|
1084
|
+
@abstractmethod
|
|
1085
|
+
def add_data_point(self, *, data_point: CallbackDataPointProtocol) -> None:
|
|
1086
|
+
"""Add a data point to a channel."""
|
|
1087
|
+
|
|
1088
|
+
@abstractmethod
|
|
1089
|
+
def get_calculated_data_point(self, *, parameter: str) -> CalculatedDataPointProtocol | None:
|
|
1090
|
+
"""Return a calculated data_point from device."""
|
|
1091
|
+
|
|
1092
|
+
@abstractmethod
|
|
1093
|
+
def get_data_points(
|
|
1094
|
+
self,
|
|
1095
|
+
*,
|
|
1096
|
+
category: DataPointCategory | None = None,
|
|
1097
|
+
exclude_no_create: bool = True,
|
|
1098
|
+
registered: bool | None = None,
|
|
1099
|
+
) -> tuple[CallbackDataPointProtocol, ...]:
|
|
1100
|
+
"""Return all data points of the channel."""
|
|
1101
|
+
|
|
1102
|
+
@abstractmethod
|
|
1103
|
+
def get_events(
|
|
1104
|
+
self, *, event_type: DeviceTriggerEventType, registered: bool | None = None
|
|
1105
|
+
) -> tuple[GenericEventProtocolAny, ...]:
|
|
1106
|
+
"""Return a list of specific events of a channel."""
|
|
1107
|
+
|
|
1108
|
+
@abstractmethod
|
|
1109
|
+
def get_generic_data_point(
|
|
1110
|
+
self, *, parameter: str | None = None, paramset_key: ParamsetKey | None = None, state_path: str | None = None
|
|
1111
|
+
) -> GenericDataPointProtocolAny | None:
|
|
1112
|
+
"""Return a generic data_point from device."""
|
|
1113
|
+
|
|
1114
|
+
@abstractmethod
|
|
1115
|
+
def get_generic_event(
|
|
1116
|
+
self, *, parameter: str | None = None, state_path: str | None = None
|
|
1117
|
+
) -> GenericEventProtocolAny | None:
|
|
1118
|
+
"""Return a generic event from device."""
|
|
1119
|
+
|
|
1120
|
+
@abstractmethod
|
|
1121
|
+
def get_readable_data_points(self, *, paramset_key: ParamsetKey) -> tuple[GenericDataPointProtocolAny, ...]:
|
|
1122
|
+
"""Return the list of readable data points."""
|
|
1123
|
+
|
|
1124
|
+
|
|
1125
|
+
class ChannelGroupingProtocol(Protocol):
|
|
1126
|
+
"""
|
|
1127
|
+
Protocol for channel group management.
|
|
1128
|
+
|
|
1129
|
+
Provides access to channel grouping and peer relationships.
|
|
1130
|
+
"""
|
|
1131
|
+
|
|
1132
|
+
__slots__ = ()
|
|
1133
|
+
|
|
1134
|
+
@property
|
|
1135
|
+
@abstractmethod
|
|
1136
|
+
def group_master(self) -> ChannelProtocol | None:
|
|
1137
|
+
"""Return the group master channel."""
|
|
1138
|
+
|
|
1139
|
+
@property
|
|
1140
|
+
@abstractmethod
|
|
1141
|
+
def group_no(self) -> int | None:
|
|
1142
|
+
"""Return the no of the channel group."""
|
|
1143
|
+
|
|
1144
|
+
@property
|
|
1145
|
+
@abstractmethod
|
|
1146
|
+
def is_group_master(self) -> bool:
|
|
1147
|
+
"""Return if the channel is the group master."""
|
|
1148
|
+
|
|
1149
|
+
@property
|
|
1150
|
+
@abstractmethod
|
|
1151
|
+
def is_in_multi_group(self) -> bool | None:
|
|
1152
|
+
"""Return if the channel is in a multi-channel group."""
|
|
1153
|
+
|
|
1154
|
+
@property
|
|
1155
|
+
@abstractmethod
|
|
1156
|
+
def link_peer_channels(self) -> tuple[ChannelProtocol, ...]:
|
|
1157
|
+
"""Return the link peer channels."""
|
|
1158
|
+
|
|
1159
|
+
|
|
1160
|
+
class ChannelMetadataProtocol(Protocol):
|
|
1161
|
+
"""
|
|
1162
|
+
Protocol for channel metadata access.
|
|
1163
|
+
|
|
1164
|
+
Provides access to additional channel metadata and configuration.
|
|
1165
|
+
"""
|
|
1166
|
+
|
|
1167
|
+
__slots__ = ()
|
|
1168
|
+
|
|
1169
|
+
@property
|
|
1170
|
+
@abstractmethod
|
|
1171
|
+
def device(self) -> DeviceProtocol:
|
|
1172
|
+
"""Return the device of the channel."""
|
|
1173
|
+
|
|
1174
|
+
@property
|
|
1175
|
+
@abstractmethod
|
|
1176
|
+
def function(self) -> str | None:
|
|
1177
|
+
"""Return the function of the channel."""
|
|
1178
|
+
|
|
1179
|
+
@property
|
|
1180
|
+
@abstractmethod
|
|
1181
|
+
def is_schedule_channel(self) -> bool:
|
|
1182
|
+
"""Return if channel is a schedule channel."""
|
|
1183
|
+
|
|
1184
|
+
@property
|
|
1185
|
+
@abstractmethod
|
|
1186
|
+
def operation_mode(self) -> str | None:
|
|
1187
|
+
"""Return the operation mode of the channel."""
|
|
1188
|
+
|
|
1189
|
+
@property
|
|
1190
|
+
@abstractmethod
|
|
1191
|
+
def paramset_descriptions(self) -> Mapping[ParamsetKey, Mapping[str, ParameterData]]:
|
|
1192
|
+
"""Return the paramset descriptions."""
|
|
1193
|
+
|
|
1194
|
+
@property
|
|
1195
|
+
@abstractmethod
|
|
1196
|
+
def paramset_keys(self) -> tuple[ParamsetKey, ...]:
|
|
1197
|
+
"""Return the paramset keys of the channel."""
|
|
1198
|
+
|
|
1199
|
+
@property
|
|
1200
|
+
@abstractmethod
|
|
1201
|
+
def room(self) -> str | None:
|
|
1202
|
+
"""Return the room of the channel."""
|
|
1203
|
+
|
|
1204
|
+
@property
|
|
1205
|
+
@abstractmethod
|
|
1206
|
+
def rooms(self) -> set[str]:
|
|
1207
|
+
"""Return all rooms of the channel."""
|
|
1208
|
+
|
|
1209
|
+
|
|
1210
|
+
class ChannelLinkManagementProtocol(Protocol):
|
|
1211
|
+
"""
|
|
1212
|
+
Protocol for channel central link management.
|
|
1213
|
+
|
|
1214
|
+
Provides methods for creating and managing central links.
|
|
1215
|
+
"""
|
|
1216
|
+
|
|
1217
|
+
__slots__ = ()
|
|
1218
|
+
|
|
1219
|
+
@abstractmethod
|
|
1220
|
+
async def create_central_link(self) -> None:
|
|
1221
|
+
"""Create a central link to support press events."""
|
|
1222
|
+
|
|
1223
|
+
@abstractmethod
|
|
1224
|
+
def has_link_target_category(self, *, category: DataPointCategory) -> bool:
|
|
1225
|
+
"""Return if channel has the specified link target category."""
|
|
1226
|
+
|
|
1227
|
+
@abstractmethod
|
|
1228
|
+
async def remove_central_link(self) -> None:
|
|
1229
|
+
"""Remove a central link."""
|
|
1230
|
+
|
|
1231
|
+
@abstractmethod
|
|
1232
|
+
def subscribe_to_link_peer_changed(self, *, handler: Any) -> Any:
|
|
1233
|
+
"""Subscribe to link peer changed event."""
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
class ChannelLifecycleProtocol(Protocol):
|
|
1237
|
+
"""
|
|
1238
|
+
Protocol for channel lifecycle management.
|
|
1239
|
+
|
|
1240
|
+
Provides methods for initialization, configuration changes, and removal.
|
|
1241
|
+
"""
|
|
1242
|
+
|
|
1243
|
+
__slots__ = ()
|
|
1244
|
+
|
|
1245
|
+
@abstractmethod
|
|
1246
|
+
async def finalize_init(self) -> None:
|
|
1247
|
+
"""Finalize the channel init action after model setup."""
|
|
1248
|
+
|
|
1249
|
+
@abstractmethod
|
|
1250
|
+
async def init_link_peer(self) -> None:
|
|
1251
|
+
"""Initialize the link partners."""
|
|
1252
|
+
|
|
1253
|
+
@abstractmethod
|
|
1254
|
+
async def on_config_changed(self) -> None:
|
|
1255
|
+
"""Handle config changed event."""
|
|
1256
|
+
|
|
1257
|
+
@abstractmethod
|
|
1258
|
+
def remove(self) -> None:
|
|
1259
|
+
"""Remove data points from collections and central."""
|
|
1260
|
+
|
|
1261
|
+
|
|
1262
|
+
# =============================================================================
|
|
1263
|
+
# Channel Composite Protocol Interface
|
|
1264
|
+
# =============================================================================
|
|
1265
|
+
|
|
1266
|
+
|
|
1267
|
+
@runtime_checkable
|
|
1268
|
+
class ChannelProtocol(
|
|
1269
|
+
ChannelIdentityProtocol,
|
|
1270
|
+
ChannelDataPointAccessProtocol,
|
|
1271
|
+
ChannelGroupingProtocol,
|
|
1272
|
+
ChannelMetadataProtocol,
|
|
1273
|
+
ChannelLinkManagementProtocol,
|
|
1274
|
+
ChannelLifecycleProtocol,
|
|
1275
|
+
Protocol,
|
|
1276
|
+
):
|
|
1277
|
+
"""
|
|
1278
|
+
Composite protocol for complete channel access.
|
|
1279
|
+
|
|
1280
|
+
Combines all channel sub-protocols into a single interface.
|
|
1281
|
+
Implemented by Channel.
|
|
1282
|
+
|
|
1283
|
+
Sub-protocols:
|
|
1284
|
+
- ChannelIdentityProtocol: Basic identification (address, name, no, type_name, unique_id, rega_id)
|
|
1285
|
+
- ChannelDataPointAccessProtocol: DataPoint and event access methods
|
|
1286
|
+
- ChannelGroupingProtocol: Channel group management (group_master, group_no, link_peer_channels)
|
|
1287
|
+
- ChannelMetadataProtocol: Additional metadata (device, function, room, paramset_descriptions)
|
|
1288
|
+
- ChannelLinkManagementProtocol: Central link operations
|
|
1289
|
+
- ChannelLifecycleProtocol: Lifecycle methods (finalize_init, on_config_changed, remove)
|
|
1290
|
+
"""
|
|
1291
|
+
|
|
1292
|
+
__slots__ = ()
|
|
1293
|
+
|
|
1294
|
+
|
|
1295
|
+
# =============================================================================
|
|
1296
|
+
# Device Sub-Protocol Interfaces
|
|
1297
|
+
# =============================================================================
|
|
1298
|
+
|
|
1299
|
+
|
|
1300
|
+
class DeviceIdentityProtocol(Protocol):
|
|
1301
|
+
"""
|
|
1302
|
+
Protocol for device identification.
|
|
1303
|
+
|
|
1304
|
+
Provides basic identity information for a device.
|
|
1305
|
+
"""
|
|
1306
|
+
|
|
1307
|
+
__slots__ = ()
|
|
1308
|
+
|
|
1309
|
+
@property
|
|
1310
|
+
@abstractmethod
|
|
1311
|
+
def address(self) -> str:
|
|
1312
|
+
"""Return the address of the device."""
|
|
1313
|
+
|
|
1314
|
+
@property
|
|
1315
|
+
@abstractmethod
|
|
1316
|
+
def identifier(self) -> str:
|
|
1317
|
+
"""Return the identifier of the device."""
|
|
1318
|
+
|
|
1319
|
+
@property
|
|
1320
|
+
@abstractmethod
|
|
1321
|
+
def interface(self) -> Interface:
|
|
1322
|
+
"""Return the interface of the device."""
|
|
1323
|
+
|
|
1324
|
+
@property
|
|
1325
|
+
@abstractmethod
|
|
1326
|
+
def interface_id(self) -> str:
|
|
1327
|
+
"""Return the interface_id of the device."""
|
|
1328
|
+
|
|
1329
|
+
@property
|
|
1330
|
+
@abstractmethod
|
|
1331
|
+
def manufacturer(self) -> str:
|
|
1332
|
+
"""Return the manufacturer of the device."""
|
|
1333
|
+
|
|
1334
|
+
@property
|
|
1335
|
+
@abstractmethod
|
|
1336
|
+
def model(self) -> str:
|
|
1337
|
+
"""Return the model of the device."""
|
|
1338
|
+
|
|
1339
|
+
@property
|
|
1340
|
+
@abstractmethod
|
|
1341
|
+
def name(self) -> str:
|
|
1342
|
+
"""Return the name of the device."""
|
|
1343
|
+
|
|
1344
|
+
@property
|
|
1345
|
+
@abstractmethod
|
|
1346
|
+
def sub_model(self) -> str | None:
|
|
1347
|
+
"""Return the sub model of the device."""
|
|
1348
|
+
|
|
1349
|
+
|
|
1350
|
+
class DeviceChannelAccessProtocol(Protocol):
|
|
1351
|
+
"""
|
|
1352
|
+
Protocol for device channel and data point access.
|
|
1353
|
+
|
|
1354
|
+
Provides methods to access channels, data points, and events.
|
|
1355
|
+
"""
|
|
1356
|
+
|
|
1357
|
+
__slots__ = ()
|
|
1358
|
+
|
|
1359
|
+
@property
|
|
1360
|
+
@abstractmethod
|
|
1361
|
+
def channels(self) -> Mapping[str, ChannelProtocol]:
|
|
1362
|
+
"""Return the channels."""
|
|
1363
|
+
|
|
1364
|
+
@property
|
|
1365
|
+
@abstractmethod
|
|
1366
|
+
def data_point_paths(self) -> tuple[str, ...]:
|
|
1367
|
+
"""Return the data point paths."""
|
|
1368
|
+
|
|
1369
|
+
@property
|
|
1370
|
+
@abstractmethod
|
|
1371
|
+
def generic_data_points(self) -> tuple[GenericDataPointProtocolAny, ...]:
|
|
1372
|
+
"""Return all generic data points."""
|
|
1373
|
+
|
|
1374
|
+
@property
|
|
1375
|
+
@abstractmethod
|
|
1376
|
+
def generic_events(self) -> tuple[GenericEventProtocolAny, ...]:
|
|
1377
|
+
"""Return the generic events."""
|
|
1378
|
+
|
|
1379
|
+
@abstractmethod
|
|
1380
|
+
def get_channel(self, *, channel_address: str) -> ChannelProtocol | None:
|
|
1381
|
+
"""Return a channel by address."""
|
|
1382
|
+
|
|
1383
|
+
@abstractmethod
|
|
1384
|
+
def get_custom_data_point(self, *, channel_no: int) -> CustomDataPointProtocol | None:
|
|
1385
|
+
"""Return a custom data_point from device."""
|
|
1386
|
+
|
|
1387
|
+
@abstractmethod
|
|
1388
|
+
def get_data_points(
|
|
1389
|
+
self,
|
|
1390
|
+
*,
|
|
1391
|
+
category: DataPointCategory | None = None,
|
|
1392
|
+
exclude_no_create: bool = True,
|
|
1393
|
+
registered: bool | None = None,
|
|
1394
|
+
) -> tuple[CallbackDataPointProtocol, ...]:
|
|
1395
|
+
"""Return data points."""
|
|
1396
|
+
|
|
1397
|
+
@abstractmethod
|
|
1398
|
+
def get_events(
|
|
1399
|
+
self, *, event_type: DeviceTriggerEventType, registered: bool | None = None
|
|
1400
|
+
) -> Mapping[int | None, tuple[GenericEventProtocolAny, ...]]:
|
|
1401
|
+
"""Return a list of specific events of a channel."""
|
|
1402
|
+
|
|
1403
|
+
@abstractmethod
|
|
1404
|
+
def get_generic_data_point(
|
|
1405
|
+
self,
|
|
1406
|
+
*,
|
|
1407
|
+
channel_address: str | None = None,
|
|
1408
|
+
parameter: str | None = None,
|
|
1409
|
+
paramset_key: ParamsetKey | None = None,
|
|
1410
|
+
state_path: str | None = None,
|
|
1411
|
+
) -> GenericDataPointProtocolAny | None:
|
|
1412
|
+
"""Return a generic data_point from device."""
|
|
1413
|
+
|
|
1414
|
+
@abstractmethod
|
|
1415
|
+
def get_generic_event(
|
|
1416
|
+
self, *, channel_address: str | None = None, parameter: str | None = None, state_path: str | None = None
|
|
1417
|
+
) -> GenericEventProtocolAny | None:
|
|
1418
|
+
"""Return a generic event from device."""
|
|
1419
|
+
|
|
1420
|
+
@abstractmethod
|
|
1421
|
+
def get_readable_data_points(self, *, paramset_key: ParamsetKey) -> tuple[GenericDataPointProtocolAny, ...]:
|
|
1422
|
+
"""Return the list of readable data points."""
|
|
1423
|
+
|
|
1424
|
+
@abstractmethod
|
|
1425
|
+
def identify_channel(self, *, text: str) -> ChannelProtocol | None:
|
|
1426
|
+
"""Identify channel within a text."""
|
|
1427
|
+
|
|
1428
|
+
|
|
1429
|
+
class DeviceAvailabilityProtocol(Protocol):
|
|
1430
|
+
"""
|
|
1431
|
+
Protocol for device availability state.
|
|
1432
|
+
|
|
1433
|
+
Provides access to device availability and configuration state.
|
|
1434
|
+
"""
|
|
1435
|
+
|
|
1436
|
+
__slots__ = ()
|
|
1437
|
+
|
|
1438
|
+
@property
|
|
1439
|
+
@abstractmethod
|
|
1440
|
+
def availability(self) -> AvailabilityInfo:
|
|
1441
|
+
"""Return bundled availability information for the device."""
|
|
1442
|
+
|
|
1443
|
+
@property
|
|
1444
|
+
@abstractmethod
|
|
1445
|
+
def available(self) -> bool:
|
|
1446
|
+
"""Return the availability of the device."""
|
|
1447
|
+
|
|
1448
|
+
@property
|
|
1449
|
+
@abstractmethod
|
|
1450
|
+
def config_pending(self) -> bool:
|
|
1451
|
+
"""Return if a config change of the device is pending."""
|
|
1452
|
+
|
|
1453
|
+
@abstractmethod
|
|
1454
|
+
def set_forced_availability(self, *, forced_availability: ForcedDeviceAvailability) -> None:
|
|
1455
|
+
"""Set the availability of the device."""
|
|
1456
|
+
|
|
1457
|
+
|
|
1458
|
+
class DeviceFirmwareProtocol(Protocol):
|
|
1459
|
+
"""
|
|
1460
|
+
Protocol for device firmware management.
|
|
1461
|
+
|
|
1462
|
+
Provides access to firmware information and update operations.
|
|
1463
|
+
"""
|
|
1464
|
+
|
|
1465
|
+
__slots__ = ()
|
|
1466
|
+
|
|
1467
|
+
@property
|
|
1468
|
+
@abstractmethod
|
|
1469
|
+
def available_firmware(self) -> str | None:
|
|
1470
|
+
"""Return the available firmware of the device."""
|
|
1471
|
+
|
|
1472
|
+
@property
|
|
1473
|
+
@abstractmethod
|
|
1474
|
+
def firmware(self) -> str:
|
|
1475
|
+
"""Return the firmware of the device."""
|
|
1476
|
+
|
|
1477
|
+
@property
|
|
1478
|
+
@abstractmethod
|
|
1479
|
+
def firmware_updatable(self) -> bool:
|
|
1480
|
+
"""Return the firmware update state of the device."""
|
|
1481
|
+
|
|
1482
|
+
@property
|
|
1483
|
+
@abstractmethod
|
|
1484
|
+
def firmware_update_state(self) -> DeviceFirmwareState:
|
|
1485
|
+
"""Return the firmware update state of the device."""
|
|
1486
|
+
|
|
1487
|
+
@property
|
|
1488
|
+
@abstractmethod
|
|
1489
|
+
def is_updatable(self) -> bool:
|
|
1490
|
+
"""Return if the device is updatable."""
|
|
1491
|
+
|
|
1492
|
+
@abstractmethod
|
|
1493
|
+
def refresh_firmware_data(self) -> None:
|
|
1494
|
+
"""Refresh firmware data of the device."""
|
|
1495
|
+
|
|
1496
|
+
@abstractmethod
|
|
1497
|
+
def subscribe_to_firmware_updated(self, *, handler: FirmwareUpdateHandler) -> UnsubscribeCallback:
|
|
1498
|
+
"""Subscribe to firmware updated event."""
|
|
1499
|
+
|
|
1500
|
+
@abstractmethod
|
|
1501
|
+
async def update_firmware(self, *, refresh_after_update_intervals: tuple[int, ...]) -> bool:
|
|
1502
|
+
"""Update the device firmware."""
|
|
1503
|
+
|
|
1504
|
+
|
|
1505
|
+
class DeviceLinkManagementProtocol(Protocol):
|
|
1506
|
+
"""
|
|
1507
|
+
Protocol for device central link management.
|
|
1508
|
+
|
|
1509
|
+
Provides methods for managing central links and peer channels.
|
|
1510
|
+
"""
|
|
1511
|
+
|
|
1512
|
+
__slots__ = ()
|
|
1513
|
+
|
|
1514
|
+
@property
|
|
1515
|
+
@abstractmethod
|
|
1516
|
+
def link_peer_channels(self) -> Mapping[ChannelProtocol, tuple[ChannelProtocol, ...]]:
|
|
1517
|
+
"""Return the link peer channels."""
|
|
1518
|
+
|
|
1519
|
+
@abstractmethod
|
|
1520
|
+
async def create_central_links(self) -> None:
|
|
1521
|
+
"""Create central links to support press events."""
|
|
1522
|
+
|
|
1523
|
+
@abstractmethod
|
|
1524
|
+
async def remove_central_links(self) -> None:
|
|
1525
|
+
"""Remove central links."""
|
|
1526
|
+
|
|
1527
|
+
|
|
1528
|
+
class DeviceGroupManagementProtocol(Protocol):
|
|
1529
|
+
"""
|
|
1530
|
+
Protocol for device channel group management.
|
|
1531
|
+
|
|
1532
|
+
Provides methods for managing channel groups.
|
|
1533
|
+
"""
|
|
1534
|
+
|
|
1535
|
+
__slots__ = ()
|
|
1536
|
+
|
|
1537
|
+
@abstractmethod
|
|
1538
|
+
def add_channel_to_group(self, *, group_no: int, channel_no: int | None) -> None:
|
|
1539
|
+
"""Add a channel to a group."""
|
|
1540
|
+
|
|
1541
|
+
@abstractmethod
|
|
1542
|
+
def get_channel_group_no(self, *, channel_no: int | None) -> int | None:
|
|
1543
|
+
"""Return the channel group number."""
|
|
1544
|
+
|
|
1545
|
+
@abstractmethod
|
|
1546
|
+
def is_in_multi_channel_group(self, *, channel_no: int | None) -> bool:
|
|
1547
|
+
"""Return if multiple channels are in the group."""
|
|
1548
|
+
|
|
1549
|
+
|
|
1550
|
+
class DeviceConfigurationProtocol(Protocol):
|
|
1551
|
+
"""
|
|
1552
|
+
Protocol for device configuration and metadata.
|
|
1553
|
+
|
|
1554
|
+
Provides access to device configuration properties.
|
|
1555
|
+
"""
|
|
1556
|
+
|
|
1557
|
+
__slots__ = ()
|
|
1558
|
+
|
|
1559
|
+
@property
|
|
1560
|
+
@abstractmethod
|
|
1561
|
+
def allow_undefined_generic_data_points(self) -> bool:
|
|
1562
|
+
"""Return if undefined generic data points of this device are allowed."""
|
|
1563
|
+
|
|
1564
|
+
@property
|
|
1565
|
+
@abstractmethod
|
|
1566
|
+
def has_custom_data_point_definition(self) -> bool:
|
|
1567
|
+
"""Return if custom data point definition is available for the device."""
|
|
1568
|
+
|
|
1569
|
+
@property
|
|
1570
|
+
@abstractmethod
|
|
1571
|
+
def has_sub_devices(self) -> bool:
|
|
1572
|
+
"""Return if the device has sub devices."""
|
|
1573
|
+
|
|
1574
|
+
@property
|
|
1575
|
+
@abstractmethod
|
|
1576
|
+
def ignore_for_custom_data_point(self) -> bool:
|
|
1577
|
+
"""Return if the device should be ignored for custom data point creation."""
|
|
1578
|
+
|
|
1579
|
+
@property
|
|
1580
|
+
@abstractmethod
|
|
1581
|
+
def ignore_on_initial_load(self) -> bool:
|
|
1582
|
+
"""Return if the device should be ignored on initial load."""
|
|
1583
|
+
|
|
1584
|
+
@property
|
|
1585
|
+
@abstractmethod
|
|
1586
|
+
def product_group(self) -> ProductGroup:
|
|
1587
|
+
"""Return the product group of the device."""
|
|
1588
|
+
|
|
1589
|
+
@property
|
|
1590
|
+
@abstractmethod
|
|
1591
|
+
def rega_id(self) -> int:
|
|
1592
|
+
"""Return the id of the device."""
|
|
1593
|
+
|
|
1594
|
+
@property
|
|
1595
|
+
@abstractmethod
|
|
1596
|
+
def room(self) -> str | None:
|
|
1597
|
+
"""Return the room of the device."""
|
|
1598
|
+
|
|
1599
|
+
@property
|
|
1600
|
+
@abstractmethod
|
|
1601
|
+
def rooms(self) -> set[str]:
|
|
1602
|
+
"""Return all rooms of the device."""
|
|
1603
|
+
|
|
1604
|
+
@property
|
|
1605
|
+
@abstractmethod
|
|
1606
|
+
def rx_modes(self) -> tuple[RxMode, ...]:
|
|
1607
|
+
"""Return the rx modes."""
|
|
1608
|
+
|
|
1609
|
+
|
|
1610
|
+
class DeviceWeekProfileProtocol(Protocol):
|
|
1611
|
+
"""
|
|
1612
|
+
Protocol for device week profile support.
|
|
1613
|
+
|
|
1614
|
+
Provides access to week profile functionality.
|
|
1615
|
+
"""
|
|
1616
|
+
|
|
1617
|
+
__slots__ = ()
|
|
1618
|
+
|
|
1619
|
+
@property
|
|
1620
|
+
@abstractmethod
|
|
1621
|
+
def default_schedule_channel(self) -> ChannelProtocol | None:
|
|
1622
|
+
"""Return the default schedule channel."""
|
|
1623
|
+
|
|
1624
|
+
@property
|
|
1625
|
+
@abstractmethod
|
|
1626
|
+
def has_week_profile(self) -> bool:
|
|
1627
|
+
"""Return if the device supports week profile."""
|
|
1628
|
+
|
|
1629
|
+
@property
|
|
1630
|
+
@abstractmethod
|
|
1631
|
+
def week_profile(self) -> WeekProfileProtocol[dict[Any, Any]] | None:
|
|
1632
|
+
"""Return the week profile."""
|
|
1633
|
+
|
|
1634
|
+
@abstractmethod
|
|
1635
|
+
def init_week_profile(self, *, data_point: CustomDataPointProtocol) -> None:
|
|
1636
|
+
"""Initialize the week profile."""
|
|
1637
|
+
|
|
1638
|
+
|
|
1639
|
+
class DeviceProvidersProtocol(Protocol):
|
|
1640
|
+
"""
|
|
1641
|
+
Protocol for device dependency providers.
|
|
1642
|
+
|
|
1643
|
+
Provides access to protocol interface providers injected into the device.
|
|
1644
|
+
"""
|
|
1645
|
+
|
|
1646
|
+
__slots__ = ()
|
|
1647
|
+
|
|
1648
|
+
@property
|
|
1649
|
+
@abstractmethod
|
|
1650
|
+
def central_info(self) -> CentralInfoProtocol:
|
|
1651
|
+
"""Return the central info of the device."""
|
|
1652
|
+
|
|
1653
|
+
@property
|
|
1654
|
+
@abstractmethod
|
|
1655
|
+
def channel_lookup(self) -> ChannelLookupProtocol:
|
|
1656
|
+
"""Return the channel lookup provider."""
|
|
1657
|
+
|
|
1658
|
+
@property
|
|
1659
|
+
@abstractmethod
|
|
1660
|
+
def client(self) -> ClientProtocol:
|
|
1661
|
+
"""Return the client of the device."""
|
|
1662
|
+
|
|
1663
|
+
@property
|
|
1664
|
+
@abstractmethod
|
|
1665
|
+
def config_provider(self) -> ConfigProviderProtocol:
|
|
1666
|
+
"""Return the config provider."""
|
|
1667
|
+
|
|
1668
|
+
@property
|
|
1669
|
+
@abstractmethod
|
|
1670
|
+
def data_cache_provider(self) -> DataCacheProviderProtocol:
|
|
1671
|
+
"""Return the data cache provider."""
|
|
1672
|
+
|
|
1673
|
+
@property
|
|
1674
|
+
@abstractmethod
|
|
1675
|
+
def data_point_provider(self) -> DataPointProviderProtocol:
|
|
1676
|
+
"""Return the data point provider."""
|
|
1677
|
+
|
|
1678
|
+
@property
|
|
1679
|
+
@abstractmethod
|
|
1680
|
+
def device_data_refresher(self) -> FirmwareDataRefresherProtocol:
|
|
1681
|
+
"""Return the device data refresher."""
|
|
1682
|
+
|
|
1683
|
+
@property
|
|
1684
|
+
@abstractmethod
|
|
1685
|
+
def device_description_provider(self) -> DeviceDescriptionProviderProtocol:
|
|
1686
|
+
"""Return the device description provider."""
|
|
1687
|
+
|
|
1688
|
+
@property
|
|
1689
|
+
@abstractmethod
|
|
1690
|
+
def device_details_provider(self) -> DeviceDetailsProviderProtocol:
|
|
1691
|
+
"""Return the device details provider."""
|
|
1692
|
+
|
|
1693
|
+
@property
|
|
1694
|
+
@abstractmethod
|
|
1695
|
+
def event_bus_provider(self) -> EventBusProviderProtocol:
|
|
1696
|
+
"""Return the event bus provider."""
|
|
1697
|
+
|
|
1698
|
+
@property
|
|
1699
|
+
@abstractmethod
|
|
1700
|
+
def event_publisher(self) -> EventPublisherProtocol:
|
|
1701
|
+
"""Return the event publisher."""
|
|
1702
|
+
|
|
1703
|
+
@property
|
|
1704
|
+
@abstractmethod
|
|
1705
|
+
def event_subscription_manager(self) -> EventSubscriptionManagerProtocol:
|
|
1706
|
+
"""Return the event subscription manager."""
|
|
1707
|
+
|
|
1708
|
+
@property
|
|
1709
|
+
@abstractmethod
|
|
1710
|
+
def parameter_visibility_provider(self) -> ParameterVisibilityProviderProtocol:
|
|
1711
|
+
"""Return the parameter visibility provider."""
|
|
1712
|
+
|
|
1713
|
+
@property
|
|
1714
|
+
@abstractmethod
|
|
1715
|
+
def paramset_description_provider(self) -> ParamsetDescriptionProviderProtocol:
|
|
1716
|
+
"""Return the paramset description provider."""
|
|
1717
|
+
|
|
1718
|
+
@property
|
|
1719
|
+
@abstractmethod
|
|
1720
|
+
def task_scheduler(self) -> TaskSchedulerProtocol:
|
|
1721
|
+
"""Return the task scheduler."""
|
|
1722
|
+
|
|
1723
|
+
@property
|
|
1724
|
+
@abstractmethod
|
|
1725
|
+
def value_cache(self) -> Any:
|
|
1726
|
+
"""Return the value cache."""
|
|
1727
|
+
|
|
1728
|
+
|
|
1729
|
+
class DeviceLifecycleProtocol(Protocol):
|
|
1730
|
+
"""
|
|
1731
|
+
Protocol for device lifecycle management.
|
|
1732
|
+
|
|
1733
|
+
Provides methods for initialization, configuration changes, and removal.
|
|
1734
|
+
"""
|
|
1735
|
+
|
|
1736
|
+
__slots__ = ()
|
|
1737
|
+
|
|
1738
|
+
@abstractmethod
|
|
1739
|
+
async def export_device_definition(self) -> None:
|
|
1740
|
+
"""Export the device definition for current device."""
|
|
1741
|
+
|
|
1742
|
+
@abstractmethod
|
|
1743
|
+
async def finalize_init(self) -> None:
|
|
1744
|
+
"""Finalize the device init action after model setup."""
|
|
1745
|
+
|
|
1746
|
+
@abstractmethod
|
|
1747
|
+
async def on_config_changed(self) -> None:
|
|
1748
|
+
"""Handle config changed event."""
|
|
1749
|
+
|
|
1750
|
+
@abstractmethod
|
|
1751
|
+
def publish_device_updated_event(self, *, notify_data_points: bool = False) -> None:
|
|
1752
|
+
"""Publish device updated event."""
|
|
1753
|
+
|
|
1754
|
+
@abstractmethod
|
|
1755
|
+
def remove(self) -> None:
|
|
1756
|
+
"""Remove data points from collections and central."""
|
|
1757
|
+
|
|
1758
|
+
|
|
1759
|
+
# =============================================================================
|
|
1760
|
+
# Device Combined Sub-Protocol Interfaces
|
|
1761
|
+
# =============================================================================
|
|
1762
|
+
|
|
1763
|
+
|
|
1764
|
+
@runtime_checkable
|
|
1765
|
+
class DeviceRemovalInfoProtocol(DeviceIdentityProtocol, DeviceChannelAccessProtocol, Protocol):
|
|
1766
|
+
"""
|
|
1767
|
+
Combined protocol for device removal operations.
|
|
1768
|
+
|
|
1769
|
+
Used by cache and store components that need to remove device data.
|
|
1770
|
+
Provides access to device address, interface_id, and channel addresses.
|
|
1771
|
+
Reduces coupling compared to using full DeviceProtocol.
|
|
1772
|
+
|
|
1773
|
+
Implemented by: Device
|
|
1774
|
+
"""
|
|
1775
|
+
|
|
1776
|
+
__slots__ = ()
|
|
1777
|
+
|
|
1778
|
+
|
|
1779
|
+
# =============================================================================
|
|
1780
|
+
# Device Composite Protocol Interface
|
|
1781
|
+
# =============================================================================
|
|
1782
|
+
|
|
1783
|
+
|
|
1784
|
+
@runtime_checkable
|
|
1785
|
+
class DeviceProtocol(
|
|
1786
|
+
DeviceIdentityProtocol,
|
|
1787
|
+
DeviceChannelAccessProtocol,
|
|
1788
|
+
DeviceAvailabilityProtocol,
|
|
1789
|
+
DeviceFirmwareProtocol,
|
|
1790
|
+
DeviceLinkManagementProtocol,
|
|
1791
|
+
DeviceGroupManagementProtocol,
|
|
1792
|
+
DeviceConfigurationProtocol,
|
|
1793
|
+
DeviceWeekProfileProtocol,
|
|
1794
|
+
DeviceProvidersProtocol,
|
|
1795
|
+
DeviceLifecycleProtocol,
|
|
1796
|
+
Protocol,
|
|
1797
|
+
):
|
|
1798
|
+
"""
|
|
1799
|
+
Composite protocol for complete device access.
|
|
1800
|
+
|
|
1801
|
+
Combines all device sub-protocols into a single interface.
|
|
1802
|
+
Implemented by Device.
|
|
1803
|
+
|
|
1804
|
+
Sub-protocols:
|
|
1805
|
+
- DeviceIdentityProtocol: Basic identification (address, name, model, manufacturer, interface)
|
|
1806
|
+
- DeviceChannelAccessProtocol: Channel and DataPoint access methods
|
|
1807
|
+
- DeviceAvailabilityProtocol: Availability state management
|
|
1808
|
+
- DeviceFirmwareProtocol: Firmware information and update operations
|
|
1809
|
+
- DeviceLinkManagementProtocol: Central link operations
|
|
1810
|
+
- DeviceGroupManagementProtocol: Channel group management
|
|
1811
|
+
- DeviceConfigurationProtocol: Device configuration and metadata
|
|
1812
|
+
- DeviceWeekProfileProtocol: Week profile support
|
|
1813
|
+
- DeviceProvidersProtocol: Protocol interface providers
|
|
1814
|
+
- DeviceLifecycleProtocol: Lifecycle methods
|
|
1815
|
+
"""
|
|
1816
|
+
|
|
1817
|
+
__slots__ = ()
|
|
1818
|
+
|
|
1819
|
+
|
|
1820
|
+
# =============================================================================
|
|
1821
|
+
# Hub Protocol Interface
|
|
1822
|
+
# =============================================================================
|
|
1823
|
+
|
|
1824
|
+
|
|
1825
|
+
@runtime_checkable
|
|
1826
|
+
class HubProtocol(Protocol):
|
|
1827
|
+
"""
|
|
1828
|
+
Protocol for Hub-level operations.
|
|
1829
|
+
|
|
1830
|
+
Provides access to hub data points (inbox, update) and methods
|
|
1831
|
+
for fetching programs, system variables, and other hub data.
|
|
1832
|
+
Inherits fetch operations from HubFetchOperationsProtocol (interfaces.central).
|
|
1833
|
+
Implemented by Hub.
|
|
1834
|
+
"""
|
|
1835
|
+
|
|
1836
|
+
__slots__ = ()
|
|
1837
|
+
|
|
1838
|
+
@property
|
|
1839
|
+
@abstractmethod
|
|
1840
|
+
def inbox_dp(self) -> GenericHubDataPointProtocol | None:
|
|
1841
|
+
"""Return the inbox data point."""
|
|
1842
|
+
|
|
1843
|
+
@property
|
|
1844
|
+
@abstractmethod
|
|
1845
|
+
def update_dp(self) -> GenericHubDataPointProtocol | None:
|
|
1846
|
+
"""Return the system update data point."""
|
|
1847
|
+
|
|
1848
|
+
@abstractmethod
|
|
1849
|
+
async def fetch_inbox_data(self, *, scheduled: bool) -> None:
|
|
1850
|
+
"""Fetch inbox data for the hub."""
|
|
1851
|
+
|
|
1852
|
+
@abstractmethod
|
|
1853
|
+
def fetch_metrics_data(self, *, scheduled: bool) -> None:
|
|
1854
|
+
"""Refresh metrics hub sensors with current values."""
|
|
1855
|
+
|
|
1856
|
+
@abstractmethod
|
|
1857
|
+
async def fetch_program_data(self, *, scheduled: bool) -> None:
|
|
1858
|
+
"""Fetch program data for the hub."""
|
|
1859
|
+
|
|
1860
|
+
@abstractmethod
|
|
1861
|
+
async def fetch_system_update_data(self, *, scheduled: bool) -> None:
|
|
1862
|
+
"""Fetch system update data for the hub."""
|
|
1863
|
+
|
|
1864
|
+
@abstractmethod
|
|
1865
|
+
async def fetch_sysvar_data(self, *, scheduled: bool) -> None:
|
|
1866
|
+
"""Fetch sysvar data for the hub."""
|
|
1867
|
+
|
|
1868
|
+
|
|
1869
|
+
# =============================================================================
|
|
1870
|
+
# WeekProfile Protocol Interface
|
|
1871
|
+
# =============================================================================
|
|
1872
|
+
|
|
1873
|
+
|
|
1874
|
+
@runtime_checkable
|
|
1875
|
+
class WeekProfileProtocol[SCHEDULE_DICT_T: dict[Any, Any]](Protocol):
|
|
1876
|
+
"""
|
|
1877
|
+
Protocol for week profile operations.
|
|
1878
|
+
|
|
1879
|
+
Provides access to device weekly schedules for climate and non-climate devices.
|
|
1880
|
+
Implemented by WeekProfile (base), ClimeateWeekProfile, and DefaultWeekProfile.
|
|
1881
|
+
"""
|
|
1882
|
+
|
|
1883
|
+
__slots__ = ()
|
|
1884
|
+
|
|
1885
|
+
@property
|
|
1886
|
+
@abstractmethod
|
|
1887
|
+
def has_schedule(self) -> bool:
|
|
1888
|
+
"""Return if climate supports schedule."""
|
|
1889
|
+
|
|
1890
|
+
@property
|
|
1891
|
+
@abstractmethod
|
|
1892
|
+
def schedule(self) -> SCHEDULE_DICT_T:
|
|
1893
|
+
"""Return the schedule cache."""
|
|
1894
|
+
|
|
1895
|
+
@property
|
|
1896
|
+
@abstractmethod
|
|
1897
|
+
def schedule_channel_address(self) -> str | None:
|
|
1898
|
+
"""Return schedule channel address."""
|
|
1899
|
+
|
|
1900
|
+
@abstractmethod
|
|
1901
|
+
async def get_schedule(self, *, force_load: bool = False) -> SCHEDULE_DICT_T:
|
|
1902
|
+
"""Return the schedule dictionary."""
|
|
1903
|
+
|
|
1904
|
+
@abstractmethod
|
|
1905
|
+
async def reload_and_cache_schedule(self, *, force: bool = False) -> None:
|
|
1906
|
+
"""Reload schedule entries and update cache."""
|
|
1907
|
+
|
|
1908
|
+
@abstractmethod
|
|
1909
|
+
async def set_schedule(self, *, schedule_data: SCHEDULE_DICT_T) -> None:
|
|
1910
|
+
"""Persist the provided schedule dictionary."""
|
|
1911
|
+
|
|
1912
|
+
|
|
1913
|
+
# =============================================================================
|
|
1914
|
+
# Type Aliases for Heterogeneous Collections
|
|
1915
|
+
# =============================================================================
|
|
1916
|
+
# These aliases provide `[Any]`-parameterized versions of the generic protocols
|
|
1917
|
+
# for use in collections where different value types are mixed (e.g., device.generic_data_points).
|
|
1918
|
+
|
|
1919
|
+
BaseParameterDataPointProtocolAny: TypeAlias = BaseParameterDataPointProtocol[Any]
|
|
1920
|
+
GenericDataPointProtocolAny: TypeAlias = GenericDataPointProtocol[Any]
|
|
1921
|
+
GenericEventProtocolAny: TypeAlias = GenericEventProtocol[Any]
|