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,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"]
|