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.
Files changed (188) hide show
  1. aiohomematic/__init__.py +110 -0
  2. aiohomematic/_log_context_protocol.py +29 -0
  3. aiohomematic/api.py +410 -0
  4. aiohomematic/async_support.py +250 -0
  5. aiohomematic/backend_detection.py +462 -0
  6. aiohomematic/central/__init__.py +103 -0
  7. aiohomematic/central/async_rpc_server.py +760 -0
  8. aiohomematic/central/central_unit.py +1152 -0
  9. aiohomematic/central/config.py +463 -0
  10. aiohomematic/central/config_builder.py +772 -0
  11. aiohomematic/central/connection_state.py +160 -0
  12. aiohomematic/central/coordinators/__init__.py +38 -0
  13. aiohomematic/central/coordinators/cache.py +414 -0
  14. aiohomematic/central/coordinators/client.py +480 -0
  15. aiohomematic/central/coordinators/connection_recovery.py +1141 -0
  16. aiohomematic/central/coordinators/device.py +1166 -0
  17. aiohomematic/central/coordinators/event.py +514 -0
  18. aiohomematic/central/coordinators/hub.py +532 -0
  19. aiohomematic/central/decorators.py +184 -0
  20. aiohomematic/central/device_registry.py +229 -0
  21. aiohomematic/central/events/__init__.py +104 -0
  22. aiohomematic/central/events/bus.py +1392 -0
  23. aiohomematic/central/events/integration.py +424 -0
  24. aiohomematic/central/events/types.py +194 -0
  25. aiohomematic/central/health.py +762 -0
  26. aiohomematic/central/rpc_server.py +353 -0
  27. aiohomematic/central/scheduler.py +794 -0
  28. aiohomematic/central/state_machine.py +391 -0
  29. aiohomematic/client/__init__.py +203 -0
  30. aiohomematic/client/_rpc_errors.py +187 -0
  31. aiohomematic/client/backends/__init__.py +48 -0
  32. aiohomematic/client/backends/base.py +335 -0
  33. aiohomematic/client/backends/capabilities.py +138 -0
  34. aiohomematic/client/backends/ccu.py +487 -0
  35. aiohomematic/client/backends/factory.py +116 -0
  36. aiohomematic/client/backends/homegear.py +294 -0
  37. aiohomematic/client/backends/json_ccu.py +252 -0
  38. aiohomematic/client/backends/protocol.py +316 -0
  39. aiohomematic/client/ccu.py +1857 -0
  40. aiohomematic/client/circuit_breaker.py +459 -0
  41. aiohomematic/client/config.py +64 -0
  42. aiohomematic/client/handlers/__init__.py +40 -0
  43. aiohomematic/client/handlers/backup.py +157 -0
  44. aiohomematic/client/handlers/base.py +79 -0
  45. aiohomematic/client/handlers/device_ops.py +1085 -0
  46. aiohomematic/client/handlers/firmware.py +144 -0
  47. aiohomematic/client/handlers/link_mgmt.py +199 -0
  48. aiohomematic/client/handlers/metadata.py +436 -0
  49. aiohomematic/client/handlers/programs.py +144 -0
  50. aiohomematic/client/handlers/sysvars.py +100 -0
  51. aiohomematic/client/interface_client.py +1304 -0
  52. aiohomematic/client/json_rpc.py +2068 -0
  53. aiohomematic/client/request_coalescer.py +282 -0
  54. aiohomematic/client/rpc_proxy.py +629 -0
  55. aiohomematic/client/state_machine.py +324 -0
  56. aiohomematic/const.py +2207 -0
  57. aiohomematic/context.py +275 -0
  58. aiohomematic/converter.py +270 -0
  59. aiohomematic/decorators.py +390 -0
  60. aiohomematic/exceptions.py +185 -0
  61. aiohomematic/hmcli.py +997 -0
  62. aiohomematic/i18n.py +193 -0
  63. aiohomematic/interfaces/__init__.py +407 -0
  64. aiohomematic/interfaces/central.py +1067 -0
  65. aiohomematic/interfaces/client.py +1096 -0
  66. aiohomematic/interfaces/coordinators.py +63 -0
  67. aiohomematic/interfaces/model.py +1921 -0
  68. aiohomematic/interfaces/operations.py +217 -0
  69. aiohomematic/logging_context.py +134 -0
  70. aiohomematic/metrics/__init__.py +125 -0
  71. aiohomematic/metrics/_protocols.py +140 -0
  72. aiohomematic/metrics/aggregator.py +534 -0
  73. aiohomematic/metrics/dataclasses.py +489 -0
  74. aiohomematic/metrics/emitter.py +292 -0
  75. aiohomematic/metrics/events.py +183 -0
  76. aiohomematic/metrics/keys.py +300 -0
  77. aiohomematic/metrics/observer.py +563 -0
  78. aiohomematic/metrics/stats.py +172 -0
  79. aiohomematic/model/__init__.py +189 -0
  80. aiohomematic/model/availability.py +65 -0
  81. aiohomematic/model/calculated/__init__.py +89 -0
  82. aiohomematic/model/calculated/climate.py +276 -0
  83. aiohomematic/model/calculated/data_point.py +315 -0
  84. aiohomematic/model/calculated/field.py +147 -0
  85. aiohomematic/model/calculated/operating_voltage_level.py +286 -0
  86. aiohomematic/model/calculated/support.py +232 -0
  87. aiohomematic/model/custom/__init__.py +214 -0
  88. aiohomematic/model/custom/capabilities/__init__.py +67 -0
  89. aiohomematic/model/custom/capabilities/climate.py +41 -0
  90. aiohomematic/model/custom/capabilities/light.py +87 -0
  91. aiohomematic/model/custom/capabilities/lock.py +44 -0
  92. aiohomematic/model/custom/capabilities/siren.py +63 -0
  93. aiohomematic/model/custom/climate.py +1130 -0
  94. aiohomematic/model/custom/cover.py +722 -0
  95. aiohomematic/model/custom/data_point.py +360 -0
  96. aiohomematic/model/custom/definition.py +300 -0
  97. aiohomematic/model/custom/field.py +89 -0
  98. aiohomematic/model/custom/light.py +1174 -0
  99. aiohomematic/model/custom/lock.py +322 -0
  100. aiohomematic/model/custom/mixins.py +445 -0
  101. aiohomematic/model/custom/profile.py +945 -0
  102. aiohomematic/model/custom/registry.py +251 -0
  103. aiohomematic/model/custom/siren.py +462 -0
  104. aiohomematic/model/custom/switch.py +195 -0
  105. aiohomematic/model/custom/text_display.py +289 -0
  106. aiohomematic/model/custom/valve.py +78 -0
  107. aiohomematic/model/data_point.py +1416 -0
  108. aiohomematic/model/device.py +1840 -0
  109. aiohomematic/model/event.py +216 -0
  110. aiohomematic/model/generic/__init__.py +327 -0
  111. aiohomematic/model/generic/action.py +40 -0
  112. aiohomematic/model/generic/action_select.py +62 -0
  113. aiohomematic/model/generic/binary_sensor.py +30 -0
  114. aiohomematic/model/generic/button.py +31 -0
  115. aiohomematic/model/generic/data_point.py +177 -0
  116. aiohomematic/model/generic/dummy.py +150 -0
  117. aiohomematic/model/generic/number.py +76 -0
  118. aiohomematic/model/generic/select.py +56 -0
  119. aiohomematic/model/generic/sensor.py +76 -0
  120. aiohomematic/model/generic/switch.py +54 -0
  121. aiohomematic/model/generic/text.py +33 -0
  122. aiohomematic/model/hub/__init__.py +100 -0
  123. aiohomematic/model/hub/binary_sensor.py +24 -0
  124. aiohomematic/model/hub/button.py +28 -0
  125. aiohomematic/model/hub/connectivity.py +190 -0
  126. aiohomematic/model/hub/data_point.py +342 -0
  127. aiohomematic/model/hub/hub.py +864 -0
  128. aiohomematic/model/hub/inbox.py +135 -0
  129. aiohomematic/model/hub/install_mode.py +393 -0
  130. aiohomematic/model/hub/metrics.py +208 -0
  131. aiohomematic/model/hub/number.py +42 -0
  132. aiohomematic/model/hub/select.py +52 -0
  133. aiohomematic/model/hub/sensor.py +37 -0
  134. aiohomematic/model/hub/switch.py +43 -0
  135. aiohomematic/model/hub/text.py +30 -0
  136. aiohomematic/model/hub/update.py +221 -0
  137. aiohomematic/model/support.py +592 -0
  138. aiohomematic/model/update.py +140 -0
  139. aiohomematic/model/week_profile.py +1827 -0
  140. aiohomematic/property_decorators.py +719 -0
  141. aiohomematic/py.typed +0 -0
  142. aiohomematic/rega_scripts/accept_device_in_inbox.fn +51 -0
  143. aiohomematic/rega_scripts/create_backup_start.fn +28 -0
  144. aiohomematic/rega_scripts/create_backup_status.fn +89 -0
  145. aiohomematic/rega_scripts/fetch_all_device_data.fn +97 -0
  146. aiohomematic/rega_scripts/get_backend_info.fn +25 -0
  147. aiohomematic/rega_scripts/get_inbox_devices.fn +61 -0
  148. aiohomematic/rega_scripts/get_program_descriptions.fn +31 -0
  149. aiohomematic/rega_scripts/get_serial.fn +44 -0
  150. aiohomematic/rega_scripts/get_service_messages.fn +83 -0
  151. aiohomematic/rega_scripts/get_system_update_info.fn +39 -0
  152. aiohomematic/rega_scripts/get_system_variable_descriptions.fn +31 -0
  153. aiohomematic/rega_scripts/set_program_state.fn +17 -0
  154. aiohomematic/rega_scripts/set_system_variable.fn +19 -0
  155. aiohomematic/rega_scripts/trigger_firmware_update.fn +67 -0
  156. aiohomematic/schemas.py +256 -0
  157. aiohomematic/store/__init__.py +55 -0
  158. aiohomematic/store/dynamic/__init__.py +43 -0
  159. aiohomematic/store/dynamic/command.py +250 -0
  160. aiohomematic/store/dynamic/data.py +175 -0
  161. aiohomematic/store/dynamic/details.py +187 -0
  162. aiohomematic/store/dynamic/ping_pong.py +416 -0
  163. aiohomematic/store/persistent/__init__.py +71 -0
  164. aiohomematic/store/persistent/base.py +285 -0
  165. aiohomematic/store/persistent/device.py +233 -0
  166. aiohomematic/store/persistent/incident.py +380 -0
  167. aiohomematic/store/persistent/paramset.py +241 -0
  168. aiohomematic/store/persistent/session.py +556 -0
  169. aiohomematic/store/serialization.py +150 -0
  170. aiohomematic/store/storage.py +689 -0
  171. aiohomematic/store/types.py +526 -0
  172. aiohomematic/store/visibility/__init__.py +40 -0
  173. aiohomematic/store/visibility/parser.py +141 -0
  174. aiohomematic/store/visibility/registry.py +722 -0
  175. aiohomematic/store/visibility/rules.py +307 -0
  176. aiohomematic/strings.json +237 -0
  177. aiohomematic/support.py +706 -0
  178. aiohomematic/tracing.py +236 -0
  179. aiohomematic/translations/de.json +237 -0
  180. aiohomematic/translations/en.json +237 -0
  181. aiohomematic/type_aliases.py +51 -0
  182. aiohomematic/validator.py +128 -0
  183. aiohomematic-2026.1.29.dist-info/METADATA +296 -0
  184. aiohomematic-2026.1.29.dist-info/RECORD +188 -0
  185. aiohomematic-2026.1.29.dist-info/WHEEL +5 -0
  186. aiohomematic-2026.1.29.dist-info/entry_points.txt +2 -0
  187. aiohomematic-2026.1.29.dist-info/licenses/LICENSE +21 -0
  188. aiohomematic-2026.1.29.dist-info/top_level.txt +1 -0
@@ -0,0 +1,316 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2021-2026
3
+ # pylint: disable=unnecessary-ellipsis
4
+ """
5
+ Backend operations protocol.
6
+
7
+ Defines the interface for all backend-specific RPC operations,
8
+ abstracting transport-layer differences between CCU, CCU-Jack, and Homegear.
9
+
10
+ Public API
11
+ ----------
12
+ - : Protocol for backend implementations
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ from typing import TYPE_CHECKING, Any, Protocol, runtime_checkable
18
+
19
+ if TYPE_CHECKING:
20
+ from aiohomematic.client.backends.capabilities import BackendCapabilities
21
+ from aiohomematic.client.circuit_breaker import CircuitBreaker
22
+ from aiohomematic.const import (
23
+ BackupData,
24
+ CommandRxMode,
25
+ DescriptionMarker,
26
+ DeviceDescription,
27
+ DeviceDetail,
28
+ InboxDeviceData,
29
+ Interface,
30
+ ParameterData,
31
+ ParamsetKey,
32
+ ProgramData,
33
+ ServiceMessageData,
34
+ ServiceMessageType,
35
+ SystemInformation,
36
+ SystemUpdateData,
37
+ SystemVariableData,
38
+ )
39
+
40
+ __all__ = ["BackendOperationsProtocol"]
41
+
42
+
43
+ @runtime_checkable
44
+ class BackendOperationsProtocol(Protocol):
45
+ """
46
+ Protocol for backend-specific RPC operations.
47
+
48
+ This protocol abstracts all transport-layer differences between backends:
49
+ - CCU: XML-RPC for device ops, JSON-RPC for metadata
50
+ - CCU-Jack: JSON-RPC exclusively
51
+ - Homegear: XML-RPC with Homegear-specific methods
52
+
53
+ Implementations handle the actual RPC calls; handlers contain business logic.
54
+ """
55
+
56
+ # =========================================================================
57
+ # Properties
58
+ # =========================================================================
59
+
60
+ @property
61
+ def all_circuit_breakers_closed(self) -> bool:
62
+ """Return True if all circuit breakers are in closed state."""
63
+ ...
64
+
65
+ @property
66
+ def capabilities(self) -> BackendCapabilities:
67
+ """Return the capability flags for this backend."""
68
+ ...
69
+
70
+ @property
71
+ def circuit_breaker(self) -> CircuitBreaker | None:
72
+ """Return the primary circuit breaker for metrics access."""
73
+ ...
74
+
75
+ @property
76
+ def interface(self) -> Interface:
77
+ """Return the interface type."""
78
+ ...
79
+
80
+ @property
81
+ def interface_id(self) -> str:
82
+ """Return the interface identifier."""
83
+ ...
84
+
85
+ @property
86
+ def model(self) -> str:
87
+ """Return the backend model name (CCU, Homegear, pydevccu)."""
88
+ ...
89
+
90
+ @property
91
+ def system_information(self) -> SystemInformation:
92
+ """Return system information retrieved during initialization."""
93
+ ...
94
+
95
+ async def accept_device_in_inbox(self, *, device_address: str) -> bool:
96
+ """Accept a device from the inbox."""
97
+ ...
98
+
99
+ async def add_link(
100
+ self,
101
+ *,
102
+ sender_address: str,
103
+ receiver_address: str,
104
+ name: str,
105
+ description: str,
106
+ ) -> None:
107
+ """Add a link between two devices."""
108
+ ...
109
+
110
+ async def check_connection(self, *, handle_ping_pong: bool, caller_id: str | None = None) -> bool:
111
+ """Check if the connection to the backend is alive."""
112
+ ...
113
+
114
+ async def create_backup_and_download(
115
+ self,
116
+ *,
117
+ max_wait_time: float = 300.0,
118
+ poll_interval: float = 5.0,
119
+ ) -> BackupData | None:
120
+ """Create a backup and download it."""
121
+ ...
122
+
123
+ async def deinit_proxy(self, *, init_url: str) -> None:
124
+ """De-initialize the proxy to stop receiving callbacks."""
125
+ ...
126
+
127
+ async def delete_system_variable(self, *, name: str) -> bool:
128
+ """Delete a system variable."""
129
+ ...
130
+
131
+ async def execute_program(self, *, pid: str) -> bool:
132
+ """Execute a program by ID."""
133
+ ...
134
+
135
+ async def get_all_device_data(self, *, interface: Interface) -> dict[str, Any] | None:
136
+ """Return all current values for devices on an interface."""
137
+ ...
138
+
139
+ async def get_all_functions(self) -> dict[str, set[str]]:
140
+ """Return all functions with their assigned channel addresses."""
141
+ ...
142
+
143
+ async def get_all_programs(self, *, markers: tuple[DescriptionMarker | str, ...]) -> tuple[ProgramData, ...]:
144
+ """Return all programs matching markers."""
145
+ ...
146
+
147
+ async def get_all_rooms(self) -> dict[str, set[str]]:
148
+ """Return all rooms with their assigned channel addresses."""
149
+ ...
150
+
151
+ async def get_all_system_variables(
152
+ self, *, markers: tuple[DescriptionMarker | str, ...]
153
+ ) -> tuple[SystemVariableData, ...] | None:
154
+ """Return all system variables matching markers."""
155
+ ...
156
+
157
+ async def get_device_description(self, *, address: str) -> DeviceDescription | None:
158
+ """Return device description for a single address."""
159
+ ...
160
+
161
+ async def get_device_details(self, *, addresses: tuple[str, ...] | None = None) -> list[DeviceDetail] | None:
162
+ """
163
+ Return device names, interfaces, and rega IDs.
164
+
165
+ Args:
166
+ addresses: Optional tuple of device addresses to fetch details for.
167
+ Used by Homegear backend which requires explicit addresses.
168
+ CCU backend ignores this parameter (uses JSON-RPC).
169
+
170
+ """
171
+ ...
172
+
173
+ async def get_inbox_devices(self) -> tuple[InboxDeviceData, ...]:
174
+ """Return devices in the inbox (not yet configured)."""
175
+ ...
176
+
177
+ async def get_install_mode(self) -> int:
178
+ """Return remaining time in install mode (seconds)."""
179
+ ...
180
+
181
+ async def get_link_peers(self, *, address: str) -> tuple[str, ...]:
182
+ """Return link peers for an address."""
183
+ ...
184
+
185
+ async def get_links(self, *, address: str, flags: int) -> dict[str, Any]:
186
+ """Return links for an address."""
187
+ ...
188
+
189
+ async def get_metadata(self, *, address: str, data_id: str) -> dict[str, Any]:
190
+ """Return metadata for an address."""
191
+ ...
192
+
193
+ async def get_paramset(self, *, address: str, paramset_key: ParamsetKey | str) -> dict[str, Any]:
194
+ """Return a paramset from the backend."""
195
+ ...
196
+
197
+ async def get_paramset_description(
198
+ self, *, address: str, paramset_key: ParamsetKey
199
+ ) -> dict[str, ParameterData] | None:
200
+ """Return paramset description for an address and paramset key."""
201
+ ...
202
+
203
+ async def get_rega_id_by_address(self, *, address: str) -> int | None:
204
+ """Return the ReGa ID for an address."""
205
+ ...
206
+
207
+ async def get_service_messages(
208
+ self, *, message_type: ServiceMessageType | None = None
209
+ ) -> tuple[ServiceMessageData, ...]:
210
+ """Return active service messages."""
211
+ ...
212
+
213
+ async def get_system_update_info(self) -> SystemUpdateData | None:
214
+ """Return system update information."""
215
+ ...
216
+
217
+ async def get_system_variable(self, *, name: str) -> Any:
218
+ """Return the value of a system variable."""
219
+ ...
220
+
221
+ async def get_value(self, *, address: str, parameter: str) -> Any:
222
+ """Return a single parameter value."""
223
+ ...
224
+
225
+ async def has_program_ids(self, *, rega_id: int) -> bool:
226
+ """Check if a channel has associated program IDs."""
227
+ ...
228
+
229
+ async def init_proxy(self, *, init_url: str, interface_id: str) -> None:
230
+ """Initialize the proxy with callback URL."""
231
+ ...
232
+
233
+ async def initialize(self) -> None:
234
+ """Initialize the backend (fetch system info, create proxies)."""
235
+ ...
236
+
237
+ async def list_devices(self) -> tuple[DeviceDescription, ...] | None:
238
+ """Return all device descriptions from the backend."""
239
+ ...
240
+
241
+ async def put_paramset(
242
+ self,
243
+ *,
244
+ address: str,
245
+ paramset_key: ParamsetKey | str,
246
+ values: dict[str, Any],
247
+ rx_mode: CommandRxMode | None = None,
248
+ ) -> None:
249
+ """Set multiple values in a paramset."""
250
+ ...
251
+
252
+ async def remove_link(self, *, sender_address: str, receiver_address: str) -> None:
253
+ """Remove a link between two devices."""
254
+ ...
255
+
256
+ async def rename_channel(self, *, rega_id: int, new_name: str) -> bool:
257
+ """Rename a channel."""
258
+ ...
259
+
260
+ async def rename_device(self, *, rega_id: int, new_name: str) -> bool:
261
+ """Rename a device."""
262
+ ...
263
+
264
+ async def report_value_usage(self, *, address: str, value_id: str, ref_counter: int) -> bool:
265
+ """Report value usage to the backend."""
266
+ ...
267
+
268
+ def reset_circuit_breakers(self) -> None:
269
+ """Reset all circuit breakers."""
270
+ ...
271
+
272
+ async def set_install_mode(
273
+ self,
274
+ *,
275
+ on: bool = True,
276
+ time: int = 60,
277
+ mode: int = 1,
278
+ device_address: str | None = None,
279
+ ) -> bool:
280
+ """Enable or disable install mode."""
281
+ ...
282
+
283
+ async def set_metadata(self, *, address: str, data_id: str, value: dict[str, Any]) -> dict[str, Any]:
284
+ """Set metadata for an address."""
285
+ ...
286
+
287
+ async def set_program_state(self, *, pid: str, state: bool) -> bool:
288
+ """Enable or disable a program."""
289
+ ...
290
+
291
+ async def set_system_variable(self, *, name: str, value: Any) -> bool:
292
+ """Set the value of a system variable."""
293
+ ...
294
+
295
+ async def set_value(
296
+ self,
297
+ *,
298
+ address: str,
299
+ parameter: str,
300
+ value: Any,
301
+ rx_mode: CommandRxMode | None = None,
302
+ ) -> None:
303
+ """Set a single parameter value."""
304
+ ...
305
+
306
+ async def stop(self) -> None:
307
+ """Stop the backend and release resources."""
308
+ ...
309
+
310
+ async def trigger_firmware_update(self) -> bool:
311
+ """Trigger system firmware update."""
312
+ ...
313
+
314
+ async def update_device_firmware(self, *, device_address: str) -> bool:
315
+ """Update firmware on a device."""
316
+ ...