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,157 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2021-2026
3
+ """
4
+ Backup handler.
5
+
6
+ Handles backup creation and download operations.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ from datetime import datetime
13
+ import logging
14
+ from typing import TYPE_CHECKING, Final
15
+
16
+ from aiohomematic import i18n
17
+ from aiohomematic.client.handlers.base import BaseHandler
18
+ from aiohomematic.const import BackupData, BackupStatus, SystemInformation
19
+ from aiohomematic.decorators import inspector
20
+ from aiohomematic.interfaces import BackupOperationsProtocol
21
+ from aiohomematic.property_decorators import DelegatedProperty
22
+
23
+ if TYPE_CHECKING:
24
+ from aiohomematic.client import AioJsonRpcAioHttpClient, BaseRpcProxy
25
+ from aiohomematic.const import Interface
26
+ from aiohomematic.interfaces import ClientDependenciesProtocol
27
+
28
+ _LOGGER: Final = logging.getLogger(__name__)
29
+
30
+
31
+ class BackupHandler(BaseHandler, BackupOperationsProtocol):
32
+ """
33
+ Handler for backup operations.
34
+
35
+ Implements BackupOperationsProtocol protocol for ISP-compliant client operations.
36
+
37
+ Handles:
38
+ - Creating backups on the CCU
39
+ - Downloading backup files
40
+ """
41
+
42
+ __slots__ = ("_has_backup", "_system_information")
43
+
44
+ def __init__(
45
+ self,
46
+ *,
47
+ client_deps: ClientDependenciesProtocol,
48
+ interface: Interface,
49
+ interface_id: str,
50
+ json_rpc_client: AioJsonRpcAioHttpClient,
51
+ proxy: BaseRpcProxy,
52
+ proxy_read: BaseRpcProxy,
53
+ has_backup: bool,
54
+ system_information: SystemInformation,
55
+ ) -> None:
56
+ """Initialize the backup handler."""
57
+ super().__init__(
58
+ client_deps=client_deps,
59
+ interface=interface,
60
+ interface_id=interface_id,
61
+ json_rpc_client=json_rpc_client,
62
+ proxy=proxy,
63
+ proxy_read=proxy_read,
64
+ )
65
+ self._has_backup: Final = has_backup
66
+ self._system_information: Final = system_information
67
+
68
+ has_backup: Final = DelegatedProperty[bool](path="_has_backup")
69
+
70
+ @inspector(re_raise=False)
71
+ async def create_backup_and_download(
72
+ self,
73
+ *,
74
+ max_wait_time: float = 300.0,
75
+ poll_interval: float = 5.0,
76
+ ) -> BackupData | None:
77
+ """
78
+ Create a backup on the CCU and download it.
79
+
80
+ Start the backup process in the background and poll for completion.
81
+ This avoids blocking the ReGa scripting engine during backup creation.
82
+
83
+ Args:
84
+ max_wait_time: Maximum time to wait for backup completion in seconds.
85
+ poll_interval: Time between status polls in seconds.
86
+
87
+ Returns:
88
+ BackupData with filename and content, or None if backup creation or download failed.
89
+
90
+ """
91
+ if not self._has_backup:
92
+ _LOGGER.debug("CREATE_BACKUP_AND_DOWNLOAD: Not supported by client for %s", self._interface_id)
93
+ return None
94
+
95
+ # Start backup in background
96
+ if not await self._json_rpc_client.create_backup_start():
97
+ _LOGGER.warning( # i18n-log: ignore
98
+ "CREATE_BACKUP_AND_DOWNLOAD: Failed to start backup process"
99
+ )
100
+ return None
101
+
102
+ _LOGGER.debug("CREATE_BACKUP_AND_DOWNLOAD: Backup process started, polling for completion")
103
+
104
+ # Poll for completion
105
+ elapsed = 0.0
106
+ while elapsed < max_wait_time:
107
+ await asyncio.sleep(poll_interval)
108
+ elapsed += poll_interval
109
+
110
+ status_data = await self._json_rpc_client.create_backup_status()
111
+
112
+ if status_data.status == BackupStatus.COMPLETED:
113
+ _LOGGER.info(
114
+ i18n.tr(
115
+ key="log.client.create_backup_and_download.completed",
116
+ filename=status_data.filename,
117
+ size=status_data.size,
118
+ )
119
+ )
120
+ if (content := await self._json_rpc_client.download_backup()) is None:
121
+ return None
122
+ return BackupData(filename=self._generate_filename(), content=content)
123
+
124
+ if status_data.status == BackupStatus.FAILED:
125
+ _LOGGER.warning(i18n.tr(key="log.client.create_backup_and_download.failed"))
126
+ return None
127
+
128
+ if status_data.status == BackupStatus.IDLE:
129
+ _LOGGER.warning(i18n.tr(key="log.client.create_backup_and_download.idle"))
130
+ return None
131
+
132
+ _LOGGER.info(
133
+ i18n.tr(
134
+ key="log.client.create_backup_and_download.running",
135
+ elapsed=elapsed,
136
+ )
137
+ )
138
+
139
+ _LOGGER.warning(
140
+ i18n.tr(
141
+ key="log.client.create_backup_and_download.timeout",
142
+ max_wait_time=max_wait_time,
143
+ )
144
+ )
145
+ return None
146
+
147
+ def _generate_filename(self) -> str:
148
+ """
149
+ Generate backup filename with hostname, version, and timestamp.
150
+
151
+ Format: <hostname>-<version>-<date>-<time>.sbk
152
+ Example: Otto-3.83.6.20251025-2025-12-10-1937.sbk
153
+ """
154
+ hostname = self._system_information.hostname or "CCU"
155
+ version = self._system_information.version or "unknown"
156
+ timestamp = datetime.now().strftime("%Y-%m-%d-%H%M")
157
+ return f"{hostname}-{version}-{timestamp}.sbk"
@@ -0,0 +1,79 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2021-2026
3
+ """
4
+ Base handler class for client operations.
5
+
6
+ Provides common dependencies and shared functionality for all handler classes.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import logging
12
+ from typing import TYPE_CHECKING, Final
13
+
14
+ from aiohomematic.const import Interface
15
+ from aiohomematic.decorators import inspector
16
+ from aiohomematic.property_decorators import DelegatedProperty
17
+
18
+ if TYPE_CHECKING:
19
+ from aiohomematic.client import AioJsonRpcAioHttpClient, BaseRpcProxy
20
+ from aiohomematic.interfaces import ClientDependenciesProtocol
21
+
22
+ _LOGGER: Final = logging.getLogger(__name__)
23
+
24
+
25
+ class BaseHandler:
26
+ """
27
+ Base class for all client handler classes.
28
+
29
+ Provides access to common dependencies needed by all handlers.
30
+ """
31
+
32
+ __slots__ = (
33
+ "_client_deps",
34
+ "_interface",
35
+ "_interface_id",
36
+ "_json_rpc_client",
37
+ "_proxy",
38
+ "_proxy_read",
39
+ )
40
+
41
+ def __init__(
42
+ self,
43
+ *,
44
+ client_deps: ClientDependenciesProtocol,
45
+ interface: Interface,
46
+ interface_id: str,
47
+ json_rpc_client: AioJsonRpcAioHttpClient,
48
+ proxy: BaseRpcProxy,
49
+ proxy_read: BaseRpcProxy,
50
+ ) -> None:
51
+ """
52
+ Initialize the base handler.
53
+
54
+ Args:
55
+ client_deps: Client dependencies for accessing central functionality.
56
+ interface: The interface type (e.g., HMIP_RF, BIDCOS_RF).
57
+ interface_id: Unique identifier for this interface.
58
+ json_rpc_client: JSON-RPC client for CCU communication.
59
+ proxy: XML-RPC proxy for write operations.
60
+ proxy_read: XML-RPC proxy for read operations (higher concurrency).
61
+
62
+ """
63
+ self._client_deps: Final = client_deps
64
+ self._interface: Final = interface
65
+ self._interface_id: Final = interface_id
66
+ self._json_rpc_client: Final = json_rpc_client
67
+ self._proxy: Final = proxy
68
+ self._proxy_read: Final = proxy_read
69
+
70
+ client_deps: Final = DelegatedProperty["ClientDependenciesProtocol"](path="_client_deps")
71
+ interface: Final = DelegatedProperty[Interface](path="_interface")
72
+ interface_id: Final = DelegatedProperty[str](path="_interface_id")
73
+ json_rpc_client: Final = DelegatedProperty["AioJsonRpcAioHttpClient"](path="_json_rpc_client")
74
+ proxy: Final = DelegatedProperty["BaseRpcProxy"](path="_proxy")
75
+ proxy_read: Final = DelegatedProperty["BaseRpcProxy"](path="_proxy_read")
76
+
77
+
78
+ # Re-export inspector decorator for use in handlers
79
+ __all__ = ["BaseHandler", "inspector"]