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,1096 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2026
|
|
3
|
+
"""
|
|
4
|
+
Client protocol interfaces.
|
|
5
|
+
|
|
6
|
+
This module defines protocol interfaces for client operations,
|
|
7
|
+
allowing components to depend on client functionality without coupling
|
|
8
|
+
to specific implementations (ClientCCU, ClientJsonCCU, ClientHomegear).
|
|
9
|
+
|
|
10
|
+
Protocol Hierarchy
|
|
11
|
+
------------------
|
|
12
|
+
|
|
13
|
+
Client protocols are organized following the Interface Segregation Principle:
|
|
14
|
+
|
|
15
|
+
**Core Protocols (4):**
|
|
16
|
+
- `ClientIdentityProtocol`: Basic identification (interface, interface_id, model, version)
|
|
17
|
+
- `ClientConnectionProtocol`: Connection state management (available, is_connected, reconnect)
|
|
18
|
+
- `ClientLifecycleProtocol`: Lifecycle operations (init_client, stop, proxy management)
|
|
19
|
+
|
|
20
|
+
**Handler-Based Protocols (9):**
|
|
21
|
+
- `DeviceDiscoveryOperationsProtocol`: Device discovery (list_devices, get_device_description)
|
|
22
|
+
- `ParamsetOperationsProtocol`: Paramset operations (get_paramset, put_paramset, fetch)
|
|
23
|
+
- `ValueOperationsProtocol`: Value operations (get_value, set_value, report_value_usage)
|
|
24
|
+
- `LinkOperationsProtocol`: Device linking (add_link, remove_link, get_link_peers)
|
|
25
|
+
- `FirmwareOperationsProtocol`: Firmware updates (update_device_firmware, trigger_firmware_update)
|
|
26
|
+
- `SystemVariableOperationsProtocol`: System variables (get/set/delete_system_variable)
|
|
27
|
+
- `ProgramOperationsProtocol`: Program execution (get_all_programs, execute_program)
|
|
28
|
+
- `BackupOperationsProtocol`: Backup creation (create_backup_and_download)
|
|
29
|
+
- `MetadataOperationsProtocol`: Metadata, rooms, functions, install mode, inbox, service messages
|
|
30
|
+
|
|
31
|
+
**Composite Protocol:**
|
|
32
|
+
- `ClientProtocol`: Combines all sub-protocols for complete client access
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from __future__ import annotations
|
|
36
|
+
|
|
37
|
+
from abc import abstractmethod
|
|
38
|
+
from collections.abc import Mapping
|
|
39
|
+
from datetime import datetime
|
|
40
|
+
from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
|
|
41
|
+
|
|
42
|
+
from aiohomematic.const import (
|
|
43
|
+
BackupData,
|
|
44
|
+
CallSource,
|
|
45
|
+
CentralState,
|
|
46
|
+
ClientState,
|
|
47
|
+
DataPointKey,
|
|
48
|
+
DeviceDescription,
|
|
49
|
+
FailureReason,
|
|
50
|
+
InboxDeviceData,
|
|
51
|
+
Interface,
|
|
52
|
+
ParameterData,
|
|
53
|
+
ParamsetKey,
|
|
54
|
+
ProductGroup,
|
|
55
|
+
ProgramData,
|
|
56
|
+
ProxyInitState,
|
|
57
|
+
SystemInformation,
|
|
58
|
+
)
|
|
59
|
+
from aiohomematic.interfaces.operations import TaskSchedulerProtocol
|
|
60
|
+
from aiohomematic.metrics._protocols import ClientProviderForMetricsProtocol
|
|
61
|
+
|
|
62
|
+
if TYPE_CHECKING:
|
|
63
|
+
from aiohomematic.central import CentralConnectionState, DeviceRegistry
|
|
64
|
+
from aiohomematic.central.coordinators import CacheCoordinator, DeviceCoordinator, EventCoordinator
|
|
65
|
+
from aiohomematic.central.events import EventBus
|
|
66
|
+
from aiohomematic.client import AioJsonRpcAioHttpClient, InterfaceConfig
|
|
67
|
+
from aiohomematic.client.backends.capabilities import BackendCapabilities
|
|
68
|
+
from aiohomematic.interfaces.central import CentralConfigProtocol
|
|
69
|
+
from aiohomematic.interfaces.model import DeviceProtocol
|
|
70
|
+
from aiohomematic.store.persistent import SessionRecorder
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
# =============================================================================
|
|
74
|
+
# Client Sub-Protocol Interfaces
|
|
75
|
+
# =============================================================================
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class ClientStateMachineProtocol(Protocol):
|
|
79
|
+
"""
|
|
80
|
+
Protocol for client state machine operations.
|
|
81
|
+
|
|
82
|
+
Provides access to state machine properties for failure tracking.
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
__slots__ = ()
|
|
86
|
+
|
|
87
|
+
@property
|
|
88
|
+
def failure_message(self) -> str:
|
|
89
|
+
"""Return human-readable failure message."""
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def failure_reason(self) -> FailureReason:
|
|
93
|
+
"""Return the reason for the failed state."""
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def is_failed(self) -> bool:
|
|
97
|
+
"""Return True if client is in failed state."""
|
|
98
|
+
|
|
99
|
+
@property
|
|
100
|
+
def state(self) -> ClientState:
|
|
101
|
+
"""Return the current state."""
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class ClientIdentityProtocol(Protocol):
|
|
105
|
+
"""
|
|
106
|
+
Protocol for client identification.
|
|
107
|
+
|
|
108
|
+
Provides basic identity information for a client.
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
__slots__ = ()
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def central(self) -> ClientDependenciesProtocol:
|
|
115
|
+
"""Return the central of the client."""
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def interface(self) -> Interface:
|
|
119
|
+
"""Return the interface of the client."""
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def interface_id(self) -> str:
|
|
123
|
+
"""Return the interface id of the client."""
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def is_initialized(self) -> bool:
|
|
127
|
+
"""Return if interface is initialized."""
|
|
128
|
+
|
|
129
|
+
@property
|
|
130
|
+
def model(self) -> str:
|
|
131
|
+
"""Return the model of the backend."""
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def system_information(self) -> SystemInformation:
|
|
135
|
+
"""Return the system_information of the client."""
|
|
136
|
+
|
|
137
|
+
@property
|
|
138
|
+
def version(self) -> str:
|
|
139
|
+
"""Return the version id of the client."""
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class ClientConnectionProtocol(Protocol):
|
|
143
|
+
"""
|
|
144
|
+
Protocol for client connection state management.
|
|
145
|
+
|
|
146
|
+
Provides connection state and health check operations.
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
__slots__ = ()
|
|
150
|
+
|
|
151
|
+
@property
|
|
152
|
+
def all_circuit_breakers_closed(self) -> bool:
|
|
153
|
+
"""Return True if all circuit breakers are in closed state."""
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def available(self) -> bool:
|
|
157
|
+
"""Return the availability of the client."""
|
|
158
|
+
|
|
159
|
+
@property
|
|
160
|
+
def modified_at(self) -> datetime:
|
|
161
|
+
"""Return the last update datetime value."""
|
|
162
|
+
|
|
163
|
+
@modified_at.setter
|
|
164
|
+
def modified_at(self, value: datetime) -> None:
|
|
165
|
+
"""Write the last update datetime value."""
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
def state(self) -> ClientState:
|
|
169
|
+
"""Return the current client state."""
|
|
170
|
+
|
|
171
|
+
@property
|
|
172
|
+
def state_machine(self) -> ClientStateMachineProtocol:
|
|
173
|
+
"""Return the client state machine."""
|
|
174
|
+
|
|
175
|
+
async def check_connection_availability(self, *, handle_ping_pong: bool) -> bool:
|
|
176
|
+
"""Check if proxy is still initialized."""
|
|
177
|
+
|
|
178
|
+
def clear_json_rpc_session(self) -> None:
|
|
179
|
+
"""Clear the JSON-RPC session to force re-authentication on next request."""
|
|
180
|
+
|
|
181
|
+
def is_callback_alive(self) -> bool:
|
|
182
|
+
"""Return if XmlRPC-Server is alive based on received events for this client."""
|
|
183
|
+
|
|
184
|
+
async def is_connected(self) -> bool:
|
|
185
|
+
"""Perform actions required for connectivity check."""
|
|
186
|
+
|
|
187
|
+
async def reconnect(self) -> bool:
|
|
188
|
+
"""Re-init all RPC clients."""
|
|
189
|
+
|
|
190
|
+
def reset_circuit_breakers(self) -> None:
|
|
191
|
+
"""Reset all circuit breakers to closed state."""
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class ClientLifecycleProtocol(Protocol):
|
|
195
|
+
"""
|
|
196
|
+
Protocol for client lifecycle operations.
|
|
197
|
+
|
|
198
|
+
Provides initialization and shutdown operations.
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
__slots__ = ()
|
|
202
|
+
|
|
203
|
+
async def deinitialize_proxy(self) -> ProxyInitState:
|
|
204
|
+
"""De-init to stop the backend from sending events for this remote."""
|
|
205
|
+
|
|
206
|
+
async def init_client(self) -> None:
|
|
207
|
+
"""Initialize the client."""
|
|
208
|
+
|
|
209
|
+
async def initialize_proxy(self) -> ProxyInitState:
|
|
210
|
+
"""Initialize the proxy has to tell the backend where to send the events."""
|
|
211
|
+
|
|
212
|
+
async def reinitialize_proxy(self) -> ProxyInitState:
|
|
213
|
+
"""Reinit Proxy."""
|
|
214
|
+
|
|
215
|
+
async def stop(self) -> None:
|
|
216
|
+
"""Stop depending services."""
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
class DeviceDiscoveryOperationsProtocol(Protocol):
|
|
220
|
+
"""
|
|
221
|
+
Protocol for device discovery operations.
|
|
222
|
+
|
|
223
|
+
Provides methods for listing and discovering devices from the backend.
|
|
224
|
+
Implemented by DeviceHandler.
|
|
225
|
+
"""
|
|
226
|
+
|
|
227
|
+
__slots__ = ()
|
|
228
|
+
|
|
229
|
+
async def fetch_all_device_data(self) -> None:
|
|
230
|
+
"""Fetch all device data from the backend."""
|
|
231
|
+
|
|
232
|
+
async def fetch_device_details(self) -> None:
|
|
233
|
+
"""Get all names via JSON-RPC and store in data."""
|
|
234
|
+
|
|
235
|
+
async def get_all_device_descriptions(self, *, device_address: str) -> tuple[DeviceDescription, ...]:
|
|
236
|
+
"""Get all device descriptions from the backend."""
|
|
237
|
+
|
|
238
|
+
async def get_device_description(self, *, address: str) -> DeviceDescription | None:
|
|
239
|
+
"""Get device descriptions from the backend."""
|
|
240
|
+
|
|
241
|
+
async def list_devices(self) -> tuple[DeviceDescription, ...] | None:
|
|
242
|
+
"""List devices of the backend."""
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
class ParamsetOperationsProtocol(Protocol):
|
|
246
|
+
"""
|
|
247
|
+
Protocol for paramset operations.
|
|
248
|
+
|
|
249
|
+
Provides methods for reading and writing paramsets and paramset descriptions.
|
|
250
|
+
Implemented by DeviceHandler.
|
|
251
|
+
"""
|
|
252
|
+
|
|
253
|
+
__slots__ = ()
|
|
254
|
+
|
|
255
|
+
async def fetch_paramset_description(self, *, channel_address: str, paramset_key: ParamsetKey) -> None:
|
|
256
|
+
"""Fetch a specific paramset and add it to the known ones."""
|
|
257
|
+
|
|
258
|
+
async def fetch_paramset_descriptions(self, *, device_description: DeviceDescription) -> None:
|
|
259
|
+
"""Fetch paramsets for provided device description."""
|
|
260
|
+
|
|
261
|
+
async def get_all_paramset_descriptions(
|
|
262
|
+
self, *, device_descriptions: tuple[DeviceDescription, ...]
|
|
263
|
+
) -> dict[str, dict[ParamsetKey, dict[str, ParameterData]]]:
|
|
264
|
+
"""Get all paramset descriptions for provided device descriptions."""
|
|
265
|
+
|
|
266
|
+
async def get_paramset(
|
|
267
|
+
self,
|
|
268
|
+
*,
|
|
269
|
+
address: str,
|
|
270
|
+
paramset_key: ParamsetKey | str,
|
|
271
|
+
call_source: CallSource = CallSource.MANUAL_OR_SCHEDULED,
|
|
272
|
+
) -> dict[str, Any]:
|
|
273
|
+
"""Return a paramset from the backend."""
|
|
274
|
+
|
|
275
|
+
async def get_paramset_descriptions(
|
|
276
|
+
self, *, device_description: DeviceDescription
|
|
277
|
+
) -> dict[str, dict[ParamsetKey, dict[str, ParameterData]]]:
|
|
278
|
+
"""Get paramsets for provided device description."""
|
|
279
|
+
|
|
280
|
+
async def put_paramset(
|
|
281
|
+
self,
|
|
282
|
+
*,
|
|
283
|
+
channel_address: str,
|
|
284
|
+
paramset_key_or_link_address: ParamsetKey | str,
|
|
285
|
+
values: dict[str, Any],
|
|
286
|
+
wait_for_callback: int | None = None,
|
|
287
|
+
rx_mode: Any | None = None,
|
|
288
|
+
check_against_pd: bool = False,
|
|
289
|
+
) -> set[Any]:
|
|
290
|
+
"""Set paramsets manually."""
|
|
291
|
+
|
|
292
|
+
async def update_paramset_descriptions(self, *, device_address: str) -> None:
|
|
293
|
+
"""Update paramsets descriptions for provided device_address."""
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class ValueOperationsProtocol(Protocol):
|
|
297
|
+
"""
|
|
298
|
+
Protocol for value read/write operations.
|
|
299
|
+
|
|
300
|
+
Provides methods for reading and writing single parameter values.
|
|
301
|
+
Implemented by DeviceHandler.
|
|
302
|
+
"""
|
|
303
|
+
|
|
304
|
+
__slots__ = ()
|
|
305
|
+
|
|
306
|
+
async def get_value(
|
|
307
|
+
self,
|
|
308
|
+
*,
|
|
309
|
+
channel_address: str,
|
|
310
|
+
paramset_key: ParamsetKey,
|
|
311
|
+
parameter: str,
|
|
312
|
+
call_source: CallSource = CallSource.MANUAL_OR_SCHEDULED,
|
|
313
|
+
) -> Any:
|
|
314
|
+
"""Return a value from the backend."""
|
|
315
|
+
|
|
316
|
+
async def report_value_usage(self, *, address: str, value_id: str, ref_counter: int) -> bool:
|
|
317
|
+
"""Report value usage."""
|
|
318
|
+
|
|
319
|
+
async def set_value(
|
|
320
|
+
self,
|
|
321
|
+
*,
|
|
322
|
+
channel_address: str,
|
|
323
|
+
paramset_key: ParamsetKey,
|
|
324
|
+
parameter: str,
|
|
325
|
+
value: Any,
|
|
326
|
+
wait_for_callback: int | None = None,
|
|
327
|
+
rx_mode: Any | None = None,
|
|
328
|
+
check_against_pd: bool = False,
|
|
329
|
+
) -> set[Any]:
|
|
330
|
+
"""Set single value on paramset VALUES."""
|
|
331
|
+
|
|
332
|
+
|
|
333
|
+
class LinkOperationsProtocol(Protocol):
|
|
334
|
+
"""
|
|
335
|
+
Protocol for device linking operations.
|
|
336
|
+
|
|
337
|
+
Provides methods for creating and managing direct links between devices.
|
|
338
|
+
Implemented by LinkHandler.
|
|
339
|
+
"""
|
|
340
|
+
|
|
341
|
+
__slots__ = ()
|
|
342
|
+
|
|
343
|
+
async def add_link(self, *, sender_address: str, receiver_address: str, name: str, description: str) -> None:
|
|
344
|
+
"""Add a link between two devices."""
|
|
345
|
+
|
|
346
|
+
async def get_link_peers(self, *, address: str) -> tuple[str, ...]:
|
|
347
|
+
"""Return a list of link peers."""
|
|
348
|
+
|
|
349
|
+
async def get_links(self, *, address: str, flags: int) -> dict[str, Any]:
|
|
350
|
+
"""Return a list of links."""
|
|
351
|
+
|
|
352
|
+
async def remove_link(self, *, sender_address: str, receiver_address: str) -> None:
|
|
353
|
+
"""Remove a link between two devices."""
|
|
354
|
+
|
|
355
|
+
|
|
356
|
+
class FirmwareOperationsProtocol(Protocol):
|
|
357
|
+
"""
|
|
358
|
+
Protocol for firmware update operations.
|
|
359
|
+
|
|
360
|
+
Provides methods for updating device and system firmware.
|
|
361
|
+
Implemented by FirmwareHandler.
|
|
362
|
+
"""
|
|
363
|
+
|
|
364
|
+
__slots__ = ()
|
|
365
|
+
|
|
366
|
+
async def trigger_firmware_update(self) -> bool:
|
|
367
|
+
"""Trigger the CCU firmware update process."""
|
|
368
|
+
|
|
369
|
+
async def update_device_firmware(self, *, device_address: str) -> bool:
|
|
370
|
+
"""Update the firmware of a Homematic device."""
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
class SystemVariableOperationsProtocol(Protocol):
|
|
374
|
+
"""
|
|
375
|
+
Protocol for system variable operations.
|
|
376
|
+
|
|
377
|
+
Provides methods for managing CCU system variables.
|
|
378
|
+
Implemented by SystemVariableHandler.
|
|
379
|
+
"""
|
|
380
|
+
|
|
381
|
+
__slots__ = ()
|
|
382
|
+
|
|
383
|
+
async def delete_system_variable(self, *, name: str) -> bool:
|
|
384
|
+
"""Delete a system variable from the backend."""
|
|
385
|
+
|
|
386
|
+
async def get_all_system_variables(self, *, markers: tuple[Any, ...]) -> tuple[Any, ...] | None:
|
|
387
|
+
"""Get all system variables from the backend."""
|
|
388
|
+
|
|
389
|
+
async def get_system_variable(self, *, name: str) -> Any:
|
|
390
|
+
"""Get single system variable from the backend."""
|
|
391
|
+
|
|
392
|
+
async def set_system_variable(self, *, legacy_name: str, value: Any) -> bool:
|
|
393
|
+
"""Set a system variable on the backend."""
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
class ProgramOperationsProtocol(Protocol):
|
|
397
|
+
"""
|
|
398
|
+
Protocol for program operations.
|
|
399
|
+
|
|
400
|
+
Provides methods for managing CCU programs.
|
|
401
|
+
Implemented by ProgramHandler.
|
|
402
|
+
"""
|
|
403
|
+
|
|
404
|
+
__slots__ = ()
|
|
405
|
+
|
|
406
|
+
async def execute_program(self, *, pid: str) -> bool:
|
|
407
|
+
"""Execute a program on the backend."""
|
|
408
|
+
|
|
409
|
+
async def get_all_programs(self, *, markers: tuple[Any, ...]) -> tuple[ProgramData, ...]:
|
|
410
|
+
"""Get all programs, if available."""
|
|
411
|
+
|
|
412
|
+
async def has_program_ids(self, *, rega_id: int) -> bool:
|
|
413
|
+
"""Return if a channel has program ids."""
|
|
414
|
+
|
|
415
|
+
async def set_program_state(self, *, pid: str, state: bool) -> bool:
|
|
416
|
+
"""Set the program state on the backend."""
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
class BackupOperationsProtocol(Protocol):
|
|
420
|
+
"""
|
|
421
|
+
Protocol for backup operations.
|
|
422
|
+
|
|
423
|
+
Provides methods for creating and downloading CCU backups.
|
|
424
|
+
Implemented by ClientCCU.
|
|
425
|
+
"""
|
|
426
|
+
|
|
427
|
+
__slots__ = ()
|
|
428
|
+
|
|
429
|
+
async def create_backup_and_download(
|
|
430
|
+
self,
|
|
431
|
+
*,
|
|
432
|
+
max_wait_time: float = ...,
|
|
433
|
+
poll_interval: float = ...,
|
|
434
|
+
) -> BackupData | None:
|
|
435
|
+
"""Create a backup on the CCU and download it."""
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
class MetadataOperationsProtocol(Protocol):
|
|
439
|
+
"""
|
|
440
|
+
Protocol for metadata and system operations.
|
|
441
|
+
|
|
442
|
+
Provides methods for metadata, rooms, functions, install mode, inbox devices,
|
|
443
|
+
service messages, and other system-level operations.
|
|
444
|
+
Implemented by MetadataHandler.
|
|
445
|
+
"""
|
|
446
|
+
|
|
447
|
+
__slots__ = ()
|
|
448
|
+
|
|
449
|
+
async def accept_device_in_inbox(self, *, device_address: str) -> bool:
|
|
450
|
+
"""Accept a device from the CCU inbox."""
|
|
451
|
+
|
|
452
|
+
async def get_all_functions(self) -> dict[str, set[str]]:
|
|
453
|
+
"""Get all functions from the backend."""
|
|
454
|
+
|
|
455
|
+
async def get_all_rooms(self) -> dict[str, set[str]]:
|
|
456
|
+
"""Get all rooms from the backend."""
|
|
457
|
+
|
|
458
|
+
async def get_inbox_devices(self) -> tuple[InboxDeviceData, ...]:
|
|
459
|
+
"""Get all devices in the inbox (not yet configured)."""
|
|
460
|
+
|
|
461
|
+
async def get_install_mode(self) -> int:
|
|
462
|
+
"""Return the remaining time in install mode."""
|
|
463
|
+
|
|
464
|
+
async def get_metadata(self, *, address: str, data_id: str) -> dict[str, Any]:
|
|
465
|
+
"""Return the metadata for an object."""
|
|
466
|
+
|
|
467
|
+
async def get_rega_id_by_address(self, *, address: str) -> int | None:
|
|
468
|
+
"""Get the ReGa ID for a device or channel address."""
|
|
469
|
+
|
|
470
|
+
async def get_service_messages(self, *, message_type: Any | None = None) -> tuple[Any, ...]:
|
|
471
|
+
"""Get all active service messages from the backend."""
|
|
472
|
+
|
|
473
|
+
async def get_system_update_info(self) -> Any | None:
|
|
474
|
+
"""Get system update information from the backend."""
|
|
475
|
+
|
|
476
|
+
async def rename_channel(self, *, rega_id: int, new_name: str) -> bool:
|
|
477
|
+
"""Rename a channel on the CCU."""
|
|
478
|
+
|
|
479
|
+
async def rename_device(self, *, rega_id: int, new_name: str) -> bool:
|
|
480
|
+
"""Rename a device on the CCU."""
|
|
481
|
+
|
|
482
|
+
async def set_install_mode(
|
|
483
|
+
self,
|
|
484
|
+
*,
|
|
485
|
+
on: bool = True,
|
|
486
|
+
time: int = 60,
|
|
487
|
+
mode: int = 1,
|
|
488
|
+
device_address: str | None = None,
|
|
489
|
+
) -> bool:
|
|
490
|
+
"""Set the install mode on the backend."""
|
|
491
|
+
|
|
492
|
+
async def set_metadata(self, *, address: str, data_id: str, value: dict[str, Any]) -> dict[str, Any]:
|
|
493
|
+
"""Write the metadata for an object."""
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
class ClientSupportProtocol(Protocol):
|
|
497
|
+
"""
|
|
498
|
+
Protocol for client support operations.
|
|
499
|
+
|
|
500
|
+
Provides utility methods and caches that are implemented directly by ClientCCU
|
|
501
|
+
rather than by handlers.
|
|
502
|
+
"""
|
|
503
|
+
|
|
504
|
+
__slots__ = ()
|
|
505
|
+
|
|
506
|
+
@property
|
|
507
|
+
def last_value_send_tracker(self) -> CommandTrackerProtocol:
|
|
508
|
+
"""Return the last value send tracker."""
|
|
509
|
+
|
|
510
|
+
@property
|
|
511
|
+
def ping_pong_tracker(self) -> PingPongTrackerProtocol:
|
|
512
|
+
"""Return the ping pong cache."""
|
|
513
|
+
|
|
514
|
+
def get_product_group(self, *, model: str) -> ProductGroup:
|
|
515
|
+
"""Return the product group."""
|
|
516
|
+
|
|
517
|
+
def get_virtual_remote(self) -> DeviceProtocol | None:
|
|
518
|
+
"""Get the virtual remote for the Client."""
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
# =============================================================================
|
|
522
|
+
# Client Combined Sub-Protocol Interfaces
|
|
523
|
+
# =============================================================================
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
@runtime_checkable
|
|
527
|
+
class ValueAndParamsetOperationsProtocol(ValueOperationsProtocol, ParamsetOperationsProtocol, Protocol):
|
|
528
|
+
"""
|
|
529
|
+
Combined protocol for value and paramset operations.
|
|
530
|
+
|
|
531
|
+
Used by components that need to send values to the backend,
|
|
532
|
+
either individually (set_value) or in batches (put_paramset).
|
|
533
|
+
Reduces coupling compared to using full ClientProtocol.
|
|
534
|
+
|
|
535
|
+
Implemented by: ClientCCU, ClientJsonCCU, ClientHomegear
|
|
536
|
+
"""
|
|
537
|
+
|
|
538
|
+
__slots__ = ()
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
@runtime_checkable
|
|
542
|
+
class DeviceDiscoveryWithIdentityProtocol(DeviceDiscoveryOperationsProtocol, ClientIdentityProtocol, Protocol):
|
|
543
|
+
"""
|
|
544
|
+
Combined protocol for device discovery with client identity.
|
|
545
|
+
|
|
546
|
+
Used by components that need to discover devices and access
|
|
547
|
+
basic client identification (interface_id, interface).
|
|
548
|
+
Reduces coupling compared to using full ClientProtocol.
|
|
549
|
+
|
|
550
|
+
Implemented by: ClientCCU, ClientJsonCCU, ClientHomegear
|
|
551
|
+
"""
|
|
552
|
+
|
|
553
|
+
__slots__ = ()
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
@runtime_checkable
|
|
557
|
+
class DeviceDiscoveryAndMetadataProtocol(DeviceDiscoveryOperationsProtocol, MetadataOperationsProtocol, Protocol):
|
|
558
|
+
"""
|
|
559
|
+
Combined protocol for device discovery and metadata operations.
|
|
560
|
+
|
|
561
|
+
Used by components that need to discover devices and perform
|
|
562
|
+
metadata operations like renaming devices/channels.
|
|
563
|
+
Reduces coupling compared to using full ClientProtocol.
|
|
564
|
+
|
|
565
|
+
Implemented by: ClientCCU, ClientJsonCCU, ClientHomegear
|
|
566
|
+
"""
|
|
567
|
+
|
|
568
|
+
__slots__ = ()
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
# =============================================================================
|
|
572
|
+
# Client Composite Protocol Interface
|
|
573
|
+
# =============================================================================
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
@runtime_checkable
|
|
577
|
+
class ClientProtocol(
|
|
578
|
+
ClientIdentityProtocol,
|
|
579
|
+
ClientConnectionProtocol,
|
|
580
|
+
ClientLifecycleProtocol,
|
|
581
|
+
DeviceDiscoveryOperationsProtocol,
|
|
582
|
+
ParamsetOperationsProtocol,
|
|
583
|
+
ValueOperationsProtocol,
|
|
584
|
+
LinkOperationsProtocol,
|
|
585
|
+
FirmwareOperationsProtocol,
|
|
586
|
+
SystemVariableOperationsProtocol,
|
|
587
|
+
ProgramOperationsProtocol,
|
|
588
|
+
BackupOperationsProtocol,
|
|
589
|
+
MetadataOperationsProtocol,
|
|
590
|
+
ClientSupportProtocol,
|
|
591
|
+
Protocol,
|
|
592
|
+
):
|
|
593
|
+
"""
|
|
594
|
+
Composite protocol for complete Homematic client operations.
|
|
595
|
+
|
|
596
|
+
Combines all client sub-protocols into a single interface providing full
|
|
597
|
+
access to backend communication, device management, and system operations.
|
|
598
|
+
Implemented by ClientCCU, ClientJsonCCU, and ClientHomegear.
|
|
599
|
+
|
|
600
|
+
Sub-protocols:
|
|
601
|
+
- ClientIdentityProtocol: Basic identification
|
|
602
|
+
- ClientConnectionProtocol: Connection state management
|
|
603
|
+
- ClientLifecycleProtocol: Lifecycle operations
|
|
604
|
+
- DeviceDiscoveryOperationsProtocol: Device discovery
|
|
605
|
+
- ParamsetOperationsProtocol: Paramset operations
|
|
606
|
+
- ValueOperationsProtocol: Value read/write
|
|
607
|
+
- LinkOperationsProtocol: Device linking
|
|
608
|
+
- FirmwareOperationsProtocol: Firmware updates
|
|
609
|
+
- SystemVariableOperationsProtocol: System variables
|
|
610
|
+
- ProgramOperationsProtocol: Program execution
|
|
611
|
+
- BackupOperationsProtocol: Backup creation
|
|
612
|
+
- MetadataOperationsProtocol: Metadata and system operations
|
|
613
|
+
- ClientSupportProtocol: Utility methods and caches
|
|
614
|
+
"""
|
|
615
|
+
|
|
616
|
+
__slots__ = ()
|
|
617
|
+
|
|
618
|
+
@property
|
|
619
|
+
def capabilities(self) -> BackendCapabilities:
|
|
620
|
+
"""Return the capability flags for this backend."""
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
# =============================================================================
|
|
624
|
+
# Client-Related Protocols
|
|
625
|
+
# =============================================================================
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
@runtime_checkable
|
|
629
|
+
class ClientProviderProtocol(ClientProviderForMetricsProtocol, Protocol):
|
|
630
|
+
"""
|
|
631
|
+
Protocol for accessing client instances.
|
|
632
|
+
|
|
633
|
+
Extends ClientProviderForMetricsProtocol with additional properties and methods.
|
|
634
|
+
Implemented by CentralUnit.
|
|
635
|
+
"""
|
|
636
|
+
|
|
637
|
+
@property
|
|
638
|
+
@abstractmethod
|
|
639
|
+
def has_clients(self) -> bool:
|
|
640
|
+
"""Check if any clients exist."""
|
|
641
|
+
|
|
642
|
+
@property
|
|
643
|
+
@abstractmethod
|
|
644
|
+
def interface_ids(self) -> frozenset[str]:
|
|
645
|
+
"""Get all interface IDs."""
|
|
646
|
+
|
|
647
|
+
@abstractmethod
|
|
648
|
+
def get_client(self, *, interface_id: str | None = None, interface: Interface | None = None) -> ClientProtocol:
|
|
649
|
+
"""Get client by interface_id or interface type."""
|
|
650
|
+
|
|
651
|
+
@abstractmethod
|
|
652
|
+
def has_client(self, *, interface_id: str) -> bool:
|
|
653
|
+
"""Check if a client exists for the given interface."""
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
@runtime_checkable
|
|
657
|
+
class ClientFactoryProtocol(Protocol):
|
|
658
|
+
"""
|
|
659
|
+
Protocol for creating client instances.
|
|
660
|
+
|
|
661
|
+
Implemented by CentralUnit.
|
|
662
|
+
"""
|
|
663
|
+
|
|
664
|
+
@abstractmethod
|
|
665
|
+
async def create_client_instance(
|
|
666
|
+
self,
|
|
667
|
+
*,
|
|
668
|
+
interface_config: InterfaceConfig,
|
|
669
|
+
) -> ClientProtocol:
|
|
670
|
+
"""
|
|
671
|
+
Create a client for the given interface configuration.
|
|
672
|
+
|
|
673
|
+
Args:
|
|
674
|
+
interface_config: Configuration for the interface.
|
|
675
|
+
|
|
676
|
+
Returns:
|
|
677
|
+
Client instance for the interface.
|
|
678
|
+
|
|
679
|
+
"""
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
@runtime_checkable
|
|
683
|
+
class ClientCoordinationProtocol(Protocol):
|
|
684
|
+
"""
|
|
685
|
+
Protocol for client coordination operations.
|
|
686
|
+
|
|
687
|
+
Implemented by CentralUnit.
|
|
688
|
+
"""
|
|
689
|
+
|
|
690
|
+
@property
|
|
691
|
+
@abstractmethod
|
|
692
|
+
def all_clients_active(self) -> bool:
|
|
693
|
+
"""Check if all clients are active."""
|
|
694
|
+
|
|
695
|
+
@property
|
|
696
|
+
@abstractmethod
|
|
697
|
+
def clients(self) -> tuple[ClientProtocol, ...]:
|
|
698
|
+
"""Get all clients as a tuple (snapshot for safe iteration)."""
|
|
699
|
+
|
|
700
|
+
@property
|
|
701
|
+
@abstractmethod
|
|
702
|
+
def interface_ids(self) -> frozenset[str]:
|
|
703
|
+
"""Get all interface IDs."""
|
|
704
|
+
|
|
705
|
+
@property
|
|
706
|
+
@abstractmethod
|
|
707
|
+
def poll_clients(self) -> tuple[ClientProtocol, ...] | None:
|
|
708
|
+
"""Get clients that require polling."""
|
|
709
|
+
|
|
710
|
+
@abstractmethod
|
|
711
|
+
def get_client(self, *, interface_id: str | None = None, interface: Interface | None = None) -> ClientProtocol:
|
|
712
|
+
"""Get client by interface_id or interface type."""
|
|
713
|
+
|
|
714
|
+
@abstractmethod
|
|
715
|
+
async def restart_clients(self) -> None:
|
|
716
|
+
"""Restart all clients."""
|
|
717
|
+
|
|
718
|
+
|
|
719
|
+
@runtime_checkable
|
|
720
|
+
class PrimaryClientProviderProtocol(Protocol):
|
|
721
|
+
"""
|
|
722
|
+
Protocol for accessing primary client.
|
|
723
|
+
|
|
724
|
+
Implemented by CentralUnit.
|
|
725
|
+
"""
|
|
726
|
+
|
|
727
|
+
@property
|
|
728
|
+
@abstractmethod
|
|
729
|
+
def primary_client(self) -> ClientProtocol | None:
|
|
730
|
+
"""Get primary client."""
|
|
731
|
+
|
|
732
|
+
|
|
733
|
+
@runtime_checkable
|
|
734
|
+
class LastEventTrackerProtocol(Protocol):
|
|
735
|
+
"""
|
|
736
|
+
Protocol for tracking last event times per interface.
|
|
737
|
+
|
|
738
|
+
Implemented by CentralUnit.
|
|
739
|
+
"""
|
|
740
|
+
|
|
741
|
+
@abstractmethod
|
|
742
|
+
def get_last_event_seen_for_interface(self, *, interface_id: str) -> datetime | None:
|
|
743
|
+
"""Get the last event timestamp for an interface."""
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
@runtime_checkable
|
|
747
|
+
class DeviceLookupProtocol(Protocol):
|
|
748
|
+
"""
|
|
749
|
+
Protocol for looking up devices and data points.
|
|
750
|
+
|
|
751
|
+
Implemented by CentralUnit.
|
|
752
|
+
"""
|
|
753
|
+
|
|
754
|
+
@abstractmethod
|
|
755
|
+
def get_device(self, *, address: str) -> DeviceProtocol | None:
|
|
756
|
+
"""Get device by address."""
|
|
757
|
+
|
|
758
|
+
@abstractmethod
|
|
759
|
+
def get_generic_data_point(
|
|
760
|
+
self,
|
|
761
|
+
*,
|
|
762
|
+
channel_address: str,
|
|
763
|
+
parameter: str,
|
|
764
|
+
paramset_key: ParamsetKey,
|
|
765
|
+
) -> Any | None:
|
|
766
|
+
"""Get generic data point."""
|
|
767
|
+
|
|
768
|
+
|
|
769
|
+
@runtime_checkable
|
|
770
|
+
class NewDeviceHandlerProtocol(Protocol):
|
|
771
|
+
"""
|
|
772
|
+
Protocol for handling new device registration.
|
|
773
|
+
|
|
774
|
+
Implemented by CentralUnit.
|
|
775
|
+
"""
|
|
776
|
+
|
|
777
|
+
@abstractmethod
|
|
778
|
+
async def add_new_devices(
|
|
779
|
+
self,
|
|
780
|
+
*,
|
|
781
|
+
interface_id: str,
|
|
782
|
+
device_descriptions: tuple[DeviceDescription, ...],
|
|
783
|
+
) -> None:
|
|
784
|
+
"""Add new devices from the backend."""
|
|
785
|
+
|
|
786
|
+
|
|
787
|
+
@runtime_checkable
|
|
788
|
+
class DataCacheWriterProtocol(Protocol):
|
|
789
|
+
"""
|
|
790
|
+
Protocol for writing data to the central data cache.
|
|
791
|
+
|
|
792
|
+
Implemented by CentralDataCache.
|
|
793
|
+
"""
|
|
794
|
+
|
|
795
|
+
@abstractmethod
|
|
796
|
+
def add_data(self, *, interface: Interface, all_device_data: Mapping[str, Any]) -> None:
|
|
797
|
+
"""Add all device data to the cache."""
|
|
798
|
+
|
|
799
|
+
|
|
800
|
+
@runtime_checkable
|
|
801
|
+
class ParamsetDescriptionWriterProtocol(Protocol):
|
|
802
|
+
"""
|
|
803
|
+
Protocol for writing paramset descriptions.
|
|
804
|
+
|
|
805
|
+
Implemented by ParamsetDescriptionRegistry.
|
|
806
|
+
"""
|
|
807
|
+
|
|
808
|
+
@abstractmethod
|
|
809
|
+
def add(
|
|
810
|
+
self,
|
|
811
|
+
*,
|
|
812
|
+
interface_id: str,
|
|
813
|
+
channel_address: str,
|
|
814
|
+
paramset_key: ParamsetKey,
|
|
815
|
+
paramset_description: dict[str, Any],
|
|
816
|
+
) -> None:
|
|
817
|
+
"""Add a paramset description."""
|
|
818
|
+
|
|
819
|
+
|
|
820
|
+
@runtime_checkable
|
|
821
|
+
class DeviceDetailsWriterProtocol(Protocol):
|
|
822
|
+
"""
|
|
823
|
+
Protocol for writing device details.
|
|
824
|
+
|
|
825
|
+
Implemented by DeviceDetailsCache.
|
|
826
|
+
"""
|
|
827
|
+
|
|
828
|
+
@property
|
|
829
|
+
@abstractmethod
|
|
830
|
+
def device_channel_rega_ids(self) -> Mapping[str, int]:
|
|
831
|
+
"""Return the device channel ReGa IDs."""
|
|
832
|
+
|
|
833
|
+
@abstractmethod
|
|
834
|
+
def add_address_rega_id(self, *, address: str, rega_id: int) -> None:
|
|
835
|
+
"""Add a ReGa ID for an address."""
|
|
836
|
+
|
|
837
|
+
@abstractmethod
|
|
838
|
+
def add_interface(self, *, address: str, interface: Interface) -> None:
|
|
839
|
+
"""Add an interface for an address."""
|
|
840
|
+
|
|
841
|
+
@abstractmethod
|
|
842
|
+
def add_name(self, *, address: str, name: str) -> None:
|
|
843
|
+
"""Add a name for an address."""
|
|
844
|
+
|
|
845
|
+
|
|
846
|
+
@runtime_checkable
|
|
847
|
+
class DeviceDescriptionsAccessProtocol(Protocol):
|
|
848
|
+
"""
|
|
849
|
+
Protocol for accessing device descriptions from cache.
|
|
850
|
+
|
|
851
|
+
Implemented by DeviceDescriptionRegistry.
|
|
852
|
+
"""
|
|
853
|
+
|
|
854
|
+
@abstractmethod
|
|
855
|
+
def find_device_description(
|
|
856
|
+
self,
|
|
857
|
+
*,
|
|
858
|
+
interface_id: str,
|
|
859
|
+
device_address: str,
|
|
860
|
+
) -> DeviceDescription | None:
|
|
861
|
+
"""Find a device description."""
|
|
862
|
+
|
|
863
|
+
@abstractmethod
|
|
864
|
+
def get_device_descriptions(self, *, interface_id: str) -> Mapping[str, DeviceDescription]:
|
|
865
|
+
"""Get all device descriptions for an interface."""
|
|
866
|
+
|
|
867
|
+
|
|
868
|
+
@runtime_checkable
|
|
869
|
+
class ConnectionStateProviderProtocol(Protocol):
|
|
870
|
+
"""
|
|
871
|
+
Protocol for accessing connection state.
|
|
872
|
+
|
|
873
|
+
Implemented by CentralUnit.
|
|
874
|
+
"""
|
|
875
|
+
|
|
876
|
+
@property
|
|
877
|
+
@abstractmethod
|
|
878
|
+
def connection_state(self) -> CentralConnectionState:
|
|
879
|
+
"""Get connection state."""
|
|
880
|
+
|
|
881
|
+
|
|
882
|
+
@runtime_checkable
|
|
883
|
+
class SessionRecorderProviderProtocol(Protocol):
|
|
884
|
+
"""
|
|
885
|
+
Protocol for accessing session recorder.
|
|
886
|
+
|
|
887
|
+
Implemented by CentralUnit.
|
|
888
|
+
"""
|
|
889
|
+
|
|
890
|
+
@property
|
|
891
|
+
@abstractmethod
|
|
892
|
+
def recorder(self) -> SessionRecorder:
|
|
893
|
+
"""Get session recorder."""
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
@runtime_checkable
|
|
897
|
+
class JsonRpcClientProviderProtocol(Protocol):
|
|
898
|
+
"""
|
|
899
|
+
Protocol for accessing JSON-RPC client.
|
|
900
|
+
|
|
901
|
+
Implemented by CentralUnit.
|
|
902
|
+
"""
|
|
903
|
+
|
|
904
|
+
@property
|
|
905
|
+
@abstractmethod
|
|
906
|
+
def json_rpc_client(self) -> AioJsonRpcAioHttpClient:
|
|
907
|
+
"""Get JSON-RPC client."""
|
|
908
|
+
|
|
909
|
+
|
|
910
|
+
@runtime_checkable
|
|
911
|
+
class CallbackAddressProviderProtocol(Protocol):
|
|
912
|
+
"""
|
|
913
|
+
Protocol for accessing callback address information.
|
|
914
|
+
|
|
915
|
+
Implemented by CentralUnit.
|
|
916
|
+
"""
|
|
917
|
+
|
|
918
|
+
@property
|
|
919
|
+
@abstractmethod
|
|
920
|
+
def callback_ip_addr(self) -> str:
|
|
921
|
+
"""Get callback IP address."""
|
|
922
|
+
|
|
923
|
+
@property
|
|
924
|
+
@abstractmethod
|
|
925
|
+
def listen_port_xml_rpc(self) -> int:
|
|
926
|
+
"""Get XML-RPC listen port."""
|
|
927
|
+
|
|
928
|
+
|
|
929
|
+
@runtime_checkable
|
|
930
|
+
class CommandTrackerProtocol(Protocol):
|
|
931
|
+
"""Protocol for command tracker operations."""
|
|
932
|
+
|
|
933
|
+
@abstractmethod
|
|
934
|
+
def add_put_paramset(
|
|
935
|
+
self, *, channel_address: str, paramset_key: ParamsetKey, values: dict[str, Any]
|
|
936
|
+
) -> set[tuple[DataPointKey, Any]]:
|
|
937
|
+
"""Add data from put paramset command."""
|
|
938
|
+
|
|
939
|
+
@abstractmethod
|
|
940
|
+
def add_set_value(
|
|
941
|
+
self,
|
|
942
|
+
*,
|
|
943
|
+
channel_address: str,
|
|
944
|
+
parameter: str,
|
|
945
|
+
value: Any,
|
|
946
|
+
) -> set[tuple[DataPointKey, Any]]:
|
|
947
|
+
"""Add data from set value command."""
|
|
948
|
+
|
|
949
|
+
@abstractmethod
|
|
950
|
+
def clear(self) -> None:
|
|
951
|
+
"""Clear all tracked command entries."""
|
|
952
|
+
|
|
953
|
+
@abstractmethod
|
|
954
|
+
def get_last_value_send(self, *, dpk: DataPointKey, max_age: int = ...) -> Any:
|
|
955
|
+
"""Return the last send value."""
|
|
956
|
+
|
|
957
|
+
@abstractmethod
|
|
958
|
+
def remove_last_value_send(
|
|
959
|
+
self,
|
|
960
|
+
*,
|
|
961
|
+
dpk: DataPointKey,
|
|
962
|
+
value: Any = None,
|
|
963
|
+
max_age: int = ...,
|
|
964
|
+
) -> None:
|
|
965
|
+
"""Remove the last send value."""
|
|
966
|
+
|
|
967
|
+
|
|
968
|
+
@runtime_checkable
|
|
969
|
+
class PingPongTrackerProtocol(Protocol):
|
|
970
|
+
"""Protocol for ping/pong cache operations."""
|
|
971
|
+
|
|
972
|
+
@abstractmethod
|
|
973
|
+
def clear(self) -> None:
|
|
974
|
+
"""Clear the cache."""
|
|
975
|
+
|
|
976
|
+
@abstractmethod
|
|
977
|
+
def handle_received_pong(self, *, pong_token: str) -> None:
|
|
978
|
+
"""Handle received pong token."""
|
|
979
|
+
|
|
980
|
+
@abstractmethod
|
|
981
|
+
def handle_send_ping(self, *, ping_token: str) -> None:
|
|
982
|
+
"""Handle send ping token."""
|
|
983
|
+
|
|
984
|
+
|
|
985
|
+
@runtime_checkable
|
|
986
|
+
class ClientDependenciesProtocol(Protocol):
|
|
987
|
+
"""
|
|
988
|
+
Composite protocol for all dependencies required by Client classes.
|
|
989
|
+
|
|
990
|
+
This protocol combines all the individual protocols needed by ClientCCU,
|
|
991
|
+
ClientConfig, and related classes. CentralUnit implements this protocol.
|
|
992
|
+
|
|
993
|
+
Using a composite protocol allows clients to depend on a single interface
|
|
994
|
+
instead of many individual protocols, while still maintaining decoupling
|
|
995
|
+
from the full CentralUnit implementation.
|
|
996
|
+
"""
|
|
997
|
+
|
|
998
|
+
# CentralInfoProtocol
|
|
999
|
+
@property
|
|
1000
|
+
@abstractmethod
|
|
1001
|
+
def available(self) -> bool:
|
|
1002
|
+
"""Check if central is available."""
|
|
1003
|
+
|
|
1004
|
+
@property
|
|
1005
|
+
@abstractmethod
|
|
1006
|
+
def cache_coordinator(self) -> CacheCoordinator:
|
|
1007
|
+
"""Get cache coordinator."""
|
|
1008
|
+
|
|
1009
|
+
@property
|
|
1010
|
+
@abstractmethod
|
|
1011
|
+
def callback_ip_addr(self) -> str:
|
|
1012
|
+
"""Return callback IP address."""
|
|
1013
|
+
|
|
1014
|
+
@property
|
|
1015
|
+
@abstractmethod
|
|
1016
|
+
def config(self) -> CentralConfigProtocol:
|
|
1017
|
+
"""Return central configuration."""
|
|
1018
|
+
|
|
1019
|
+
@property
|
|
1020
|
+
@abstractmethod
|
|
1021
|
+
def connection_state(self) -> CentralConnectionState:
|
|
1022
|
+
"""Return connection state."""
|
|
1023
|
+
|
|
1024
|
+
@property
|
|
1025
|
+
@abstractmethod
|
|
1026
|
+
def device_coordinator(self) -> DeviceCoordinator:
|
|
1027
|
+
"""Return the device coordinator."""
|
|
1028
|
+
|
|
1029
|
+
@property
|
|
1030
|
+
@abstractmethod
|
|
1031
|
+
def device_registry(self) -> DeviceRegistry:
|
|
1032
|
+
"""Return the device registry."""
|
|
1033
|
+
|
|
1034
|
+
@property
|
|
1035
|
+
@abstractmethod
|
|
1036
|
+
def event_bus(self) -> EventBus:
|
|
1037
|
+
"""Return the event bus."""
|
|
1038
|
+
|
|
1039
|
+
@property
|
|
1040
|
+
@abstractmethod
|
|
1041
|
+
def event_coordinator(self) -> EventCoordinator:
|
|
1042
|
+
"""Return the event coordinator for publishing events."""
|
|
1043
|
+
|
|
1044
|
+
@property
|
|
1045
|
+
@abstractmethod
|
|
1046
|
+
def info_payload(self) -> Mapping[str, Any]:
|
|
1047
|
+
"""Return the info payload."""
|
|
1048
|
+
|
|
1049
|
+
@property
|
|
1050
|
+
@abstractmethod
|
|
1051
|
+
def json_rpc_client(self) -> AioJsonRpcAioHttpClient:
|
|
1052
|
+
"""Return JSON-RPC client."""
|
|
1053
|
+
|
|
1054
|
+
@property
|
|
1055
|
+
@abstractmethod
|
|
1056
|
+
def listen_port_xml_rpc(self) -> int:
|
|
1057
|
+
"""Return XML-RPC listen port."""
|
|
1058
|
+
|
|
1059
|
+
@property
|
|
1060
|
+
@abstractmethod
|
|
1061
|
+
def looper(self) -> TaskSchedulerProtocol:
|
|
1062
|
+
"""Return task scheduler/looper."""
|
|
1063
|
+
|
|
1064
|
+
@property
|
|
1065
|
+
@abstractmethod
|
|
1066
|
+
def model(self) -> str | None:
|
|
1067
|
+
"""Return backend model."""
|
|
1068
|
+
|
|
1069
|
+
@property
|
|
1070
|
+
@abstractmethod
|
|
1071
|
+
def name(self) -> str:
|
|
1072
|
+
"""Return central name."""
|
|
1073
|
+
|
|
1074
|
+
@property
|
|
1075
|
+
@abstractmethod
|
|
1076
|
+
def state(self) -> CentralState:
|
|
1077
|
+
"""Return the current central state from the state machine."""
|
|
1078
|
+
|
|
1079
|
+
@abstractmethod
|
|
1080
|
+
def get_generic_data_point(
|
|
1081
|
+
self,
|
|
1082
|
+
*,
|
|
1083
|
+
channel_address: str,
|
|
1084
|
+
parameter: str,
|
|
1085
|
+
paramset_key: ParamsetKey,
|
|
1086
|
+
) -> Any | None:
|
|
1087
|
+
"""Return generic data point."""
|
|
1088
|
+
|
|
1089
|
+
@abstractmethod
|
|
1090
|
+
async def save_files(
|
|
1091
|
+
self,
|
|
1092
|
+
*,
|
|
1093
|
+
save_device_descriptions: bool = False,
|
|
1094
|
+
save_paramset_descriptions: bool = False,
|
|
1095
|
+
) -> None:
|
|
1096
|
+
"""Save persistent files to disk."""
|