aiohomematic 2025.10.9__py3-none-any.whl → 2025.10.11__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.
Potentially problematic release.
This version of aiohomematic might be problematic. Click here for more details.
- aiohomematic/central/__init__.py +20 -9
- aiohomematic/central/rpc_server.py +21 -27
- aiohomematic/client/__init__.py +4 -2
- aiohomematic/client/json_rpc.py +2 -2
- aiohomematic/const.py +18 -9
- aiohomematic/model/custom/climate.py +4 -4
- aiohomematic/model/data_point.py +3 -4
- aiohomematic/model/device.py +5 -5
- aiohomematic/model/update.py +2 -2
- aiohomematic/store/persistent.py +124 -71
- aiohomematic/support.py +9 -0
- {aiohomematic-2025.10.9.dist-info → aiohomematic-2025.10.11.dist-info}/METADATA +1 -1
- {aiohomematic-2025.10.9.dist-info → aiohomematic-2025.10.11.dist-info}/RECORD +16 -18
- aiohomematic-2025.10.11.dist-info/top_level.txt +1 -0
- aiohomematic-2025.10.9.dist-info/top_level.txt +0 -2
- aiohomematic_support/__init__.py +0 -1
- aiohomematic_support/client_local.py +0 -361
- {aiohomematic-2025.10.9.dist-info → aiohomematic-2025.10.11.dist-info}/WHEEL +0 -0
- {aiohomematic-2025.10.9.dist-info → aiohomematic-2025.10.11.dist-info}/licenses/LICENSE +0 -0
aiohomematic/central/__init__.py
CHANGED
|
@@ -96,8 +96,10 @@ from aiohomematic.const import (
|
|
|
96
96
|
DEFAULT_IGNORE_CUSTOM_DEVICE_DEFINITION_MODELS,
|
|
97
97
|
DEFAULT_INTERFACES_REQUIRING_PERIODIC_REFRESH,
|
|
98
98
|
DEFAULT_MAX_READ_WORKERS,
|
|
99
|
+
DEFAULT_OPTIONAL_SETTINGS,
|
|
99
100
|
DEFAULT_PERIODIC_REFRESH_INTERVAL,
|
|
100
101
|
DEFAULT_PROGRAM_MARKERS,
|
|
102
|
+
DEFAULT_SESSION_RECORDER_START_FOR_SECONDS,
|
|
101
103
|
DEFAULT_STORAGE_DIRECTORY,
|
|
102
104
|
DEFAULT_SYS_SCAN_INTERVAL,
|
|
103
105
|
DEFAULT_SYSVAR_MARKERS,
|
|
@@ -130,6 +132,7 @@ from aiohomematic.const import (
|
|
|
130
132
|
Interface,
|
|
131
133
|
InterfaceEventType,
|
|
132
134
|
Operations,
|
|
135
|
+
OptionalSettings,
|
|
133
136
|
Parameter,
|
|
134
137
|
ParamsetKey,
|
|
135
138
|
ProxyInitState,
|
|
@@ -223,7 +226,7 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
223
226
|
self._paramset_descriptions: Final = ParamsetDescriptionCache(central=self)
|
|
224
227
|
self._parameter_visibility: Final = ParameterVisibilityCache(central=self)
|
|
225
228
|
self._recorder: Final = SessionRecorder(
|
|
226
|
-
central=self,
|
|
229
|
+
central=self, ttl_seconds=600, active=central_config.session_recorder_start
|
|
227
230
|
)
|
|
228
231
|
self._primary_client: hmcl.Client | None = None
|
|
229
232
|
# {interface_id, client}
|
|
@@ -493,14 +496,14 @@ class CentralUnit(LogContextMixin, PayloadMixin):
|
|
|
493
496
|
_LOGGER.debug("START: Central %s already started", self.name)
|
|
494
497
|
return
|
|
495
498
|
|
|
496
|
-
if self._config.
|
|
499
|
+
if self._config.session_recorder_start:
|
|
497
500
|
await self._recorder.deactivate(
|
|
498
|
-
delay=self._config.
|
|
501
|
+
delay=self._config.session_recorder_start_for_seconds,
|
|
499
502
|
auto_save=True,
|
|
500
|
-
randomize_output=
|
|
501
|
-
|
|
503
|
+
randomize_output=self._config.session_recorder_randomize_output,
|
|
504
|
+
use_ts_in_file_name=False,
|
|
502
505
|
)
|
|
503
|
-
_LOGGER.debug("START: Starting Recorder for %s
|
|
506
|
+
_LOGGER.debug("START: Starting Recorder for %s seconds", self._config.session_recorder_start_for_seconds)
|
|
504
507
|
|
|
505
508
|
self._state = CentralUnitState.INITIALIZING
|
|
506
509
|
_LOGGER.debug("START: Initializing Central %s", self.name)
|
|
@@ -2009,10 +2012,10 @@ class CentralConfig:
|
|
|
2009
2012
|
listen_ip_addr: str | None = None,
|
|
2010
2013
|
listen_port_xml_rpc: int | None = None,
|
|
2011
2014
|
max_read_workers: int = DEFAULT_MAX_READ_WORKERS,
|
|
2015
|
+
optional_settings: tuple[OptionalSettings | str, ...] = DEFAULT_OPTIONAL_SETTINGS,
|
|
2012
2016
|
periodic_refresh_interval: int = DEFAULT_PERIODIC_REFRESH_INTERVAL,
|
|
2013
2017
|
program_markers: tuple[DescriptionMarker | str, ...] = DEFAULT_PROGRAM_MARKERS,
|
|
2014
2018
|
start_direct: bool = False,
|
|
2015
|
-
start_recorder_for_minutes: int = 0,
|
|
2016
2019
|
storage_directory: str = DEFAULT_STORAGE_DIRECTORY,
|
|
2017
2020
|
sys_scan_interval: int = DEFAULT_SYS_SCAN_INTERVAL,
|
|
2018
2021
|
sysvar_markers: tuple[DescriptionMarker | str, ...] = DEFAULT_SYSVAR_MARKERS,
|
|
@@ -2023,6 +2026,7 @@ class CentralConfig:
|
|
|
2023
2026
|
) -> None:
|
|
2024
2027
|
"""Init the client config."""
|
|
2025
2028
|
self._interface_configs: Final = interface_configs
|
|
2029
|
+
self._optional_settings: Final = frozenset(optional_settings or ())
|
|
2026
2030
|
self.requires_xml_rpc_server: Final = any(
|
|
2027
2031
|
ic for ic in interface_configs if ic.rpc_server == RpcServerType.XML_RPC
|
|
2028
2032
|
)
|
|
@@ -2048,8 +2052,15 @@ class CentralConfig:
|
|
|
2048
2052
|
self.periodic_refresh_interval = periodic_refresh_interval
|
|
2049
2053
|
self.program_markers: Final = program_markers
|
|
2050
2054
|
self.start_direct: Final = start_direct
|
|
2051
|
-
self.
|
|
2052
|
-
|
|
2055
|
+
self.session_recorder_randomize_output = (
|
|
2056
|
+
OptionalSettings.SR_DISABLE_RANDOMIZE_OUTPUT not in self._optional_settings
|
|
2057
|
+
)
|
|
2058
|
+
self.session_recorder_start_for_seconds: Final = (
|
|
2059
|
+
DEFAULT_SESSION_RECORDER_START_FOR_SECONDS
|
|
2060
|
+
if OptionalSettings.SR_RECORD_SYSTEM_INIT in self._optional_settings
|
|
2061
|
+
else 0
|
|
2062
|
+
)
|
|
2063
|
+
self.session_recorder_start = self.session_recorder_start_for_seconds > 0
|
|
2053
2064
|
self.storage_directory: Final = storage_directory
|
|
2054
2065
|
self.sys_scan_interval: Final = sys_scan_interval
|
|
2055
2066
|
self.sysvar_markers: Final = sysvar_markers
|
|
@@ -18,7 +18,7 @@ from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer
|
|
|
18
18
|
from aiohomematic import central as hmcu
|
|
19
19
|
from aiohomematic.central.decorators import callback_backend_system
|
|
20
20
|
from aiohomematic.const import IP_ANY_V4, PORT_ANY, BackendSystemEvent
|
|
21
|
-
from aiohomematic.support import
|
|
21
|
+
from aiohomematic.support import log_boundary_error
|
|
22
22
|
|
|
23
23
|
_LOGGER: Final = logging.getLogger(__name__)
|
|
24
24
|
|
|
@@ -177,23 +177,19 @@ class RpcServer(threading.Thread):
|
|
|
177
177
|
_initialized: bool = False
|
|
178
178
|
_instances: Final[dict[tuple[str, int], RpcServer]] = {}
|
|
179
179
|
|
|
180
|
-
def __init__(
|
|
181
|
-
self,
|
|
182
|
-
*,
|
|
183
|
-
ip_addr: str,
|
|
184
|
-
port: int,
|
|
185
|
-
) -> None:
|
|
180
|
+
def __init__(self, *, server: SimpleXMLRPCServer) -> None:
|
|
186
181
|
"""Init XmlRPC server."""
|
|
187
|
-
|
|
188
|
-
|
|
182
|
+
self._server = server
|
|
183
|
+
self._server.register_introspection_functions()
|
|
184
|
+
self._server.register_multicall_functions()
|
|
185
|
+
self._server.register_instance(RPCFunctions(rpc_server=self), allow_dotted_names=True)
|
|
189
186
|
self._initialized = True
|
|
190
|
-
self.
|
|
191
|
-
self.
|
|
192
|
-
self.
|
|
187
|
+
self._address: Final[tuple[str, int]] = cast(tuple[str, int], server.server_address)
|
|
188
|
+
self._listen_ip_addr: Final = self._address[0]
|
|
189
|
+
self._listen_port: Final = self._address[1]
|
|
193
190
|
self._centrals: Final[dict[str, hmcu.CentralUnit]] = {}
|
|
194
|
-
self._simple_rpc_server: SimpleXMLRPCServer
|
|
195
191
|
self._instances[self._address] = self
|
|
196
|
-
threading.Thread.__init__(self, name=f"RpcServer {
|
|
192
|
+
threading.Thread.__init__(self, name=f"RpcServer {self._listen_ip_addr}:{self._listen_port}")
|
|
197
193
|
|
|
198
194
|
def run(self) -> None:
|
|
199
195
|
"""Run the RPC-Server thread."""
|
|
@@ -202,15 +198,15 @@ class RpcServer(threading.Thread):
|
|
|
202
198
|
self._listen_ip_addr,
|
|
203
199
|
self._listen_port,
|
|
204
200
|
)
|
|
205
|
-
if self.
|
|
206
|
-
self.
|
|
201
|
+
if self._server:
|
|
202
|
+
self._server.serve_forever()
|
|
207
203
|
|
|
208
204
|
def stop(self) -> None:
|
|
209
205
|
"""Stop the RPC-Server."""
|
|
210
206
|
_LOGGER.debug("STOP: Shutting down RPC-Server")
|
|
211
|
-
self.
|
|
207
|
+
self._server.shutdown()
|
|
212
208
|
_LOGGER.debug("STOP: Stopping RPC-Server")
|
|
213
|
-
self.
|
|
209
|
+
self._server.server_close()
|
|
214
210
|
# Ensure the server thread has actually terminated to avoid slow teardown
|
|
215
211
|
with contextlib.suppress(RuntimeError):
|
|
216
212
|
self.join(timeout=1.0)
|
|
@@ -269,16 +265,14 @@ class XmlRpcServer(RpcServer):
|
|
|
269
265
|
|
|
270
266
|
if self._initialized:
|
|
271
267
|
return
|
|
272
|
-
super().__init__(
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
268
|
+
super().__init__(
|
|
269
|
+
server=HomematicXMLRPCServer(
|
|
270
|
+
addr=(ip_addr, port),
|
|
271
|
+
requestHandler=RequestHandler,
|
|
272
|
+
logRequests=False,
|
|
273
|
+
allow_none=True,
|
|
274
|
+
)
|
|
278
275
|
)
|
|
279
|
-
self._simple_rpc_server.register_introspection_functions()
|
|
280
|
-
self._simple_rpc_server.register_multicall_functions()
|
|
281
|
-
self._simple_rpc_server.register_instance(RPCFunctions(rpc_server=self), allow_dotted_names=True)
|
|
282
276
|
|
|
283
277
|
def __new__(cls, ip_addr: str, port: int) -> XmlRpcServer: # noqa: PYI034 # kwonly: disable
|
|
284
278
|
"""Create new RPC server."""
|
aiohomematic/client/__init__.py
CHANGED
|
@@ -60,7 +60,6 @@ from aiohomematic.client.rpc_proxy import AioXmlRpcProxy, BaseRpcProxy
|
|
|
60
60
|
from aiohomematic.const import (
|
|
61
61
|
CALLBACK_WARN_INTERVAL,
|
|
62
62
|
DATETIME_FORMAT_MILLIS,
|
|
63
|
-
DEFAULT_CUSTOM_ID,
|
|
64
63
|
DEFAULT_MAX_WORKERS,
|
|
65
64
|
DP_KEY_VALUE,
|
|
66
65
|
DUMMY_SERIAL,
|
|
@@ -81,6 +80,7 @@ from aiohomematic.const import (
|
|
|
81
80
|
ForcedDeviceAvailability,
|
|
82
81
|
Interface,
|
|
83
82
|
InterfaceEventType,
|
|
83
|
+
InternalCustomID,
|
|
84
84
|
Operations,
|
|
85
85
|
ParameterData,
|
|
86
86
|
ParameterType,
|
|
@@ -1815,7 +1815,9 @@ async def _track_single_data_point_state_change_or_timeout(
|
|
|
1815
1815
|
)
|
|
1816
1816
|
return
|
|
1817
1817
|
if (
|
|
1818
|
-
unsub := dp.register_data_point_updated_callback(
|
|
1818
|
+
unsub := dp.register_data_point_updated_callback(
|
|
1819
|
+
cb=_async_event_changed, custom_id=InternalCustomID.DEFAULT
|
|
1820
|
+
)
|
|
1819
1821
|
) is None:
|
|
1820
1822
|
return
|
|
1821
1823
|
|
aiohomematic/client/json_rpc.py
CHANGED
|
@@ -368,8 +368,8 @@ class AioJsonRpcAioHttpClient(LogContextMixin):
|
|
|
368
368
|
_LOGGER.debug("POST_SCRIPT: method: %s [%s]", method, script_name)
|
|
369
369
|
|
|
370
370
|
try:
|
|
371
|
-
if not response[_JsonKey.ERROR]:
|
|
372
|
-
response[_JsonKey.RESULT] = orjson.loads(
|
|
371
|
+
if not response[_JsonKey.ERROR] and (resp := response[_JsonKey.RESULT]) and isinstance(resp, str):
|
|
372
|
+
response[_JsonKey.RESULT] = orjson.loads(resp)
|
|
373
373
|
finally:
|
|
374
374
|
if not keep_session:
|
|
375
375
|
await self._do_logout(session_id=session_id)
|
aiohomematic/const.py
CHANGED
|
@@ -19,7 +19,7 @@ import sys
|
|
|
19
19
|
from types import MappingProxyType
|
|
20
20
|
from typing import Any, Final, NamedTuple, Required, TypeAlias, TypedDict
|
|
21
21
|
|
|
22
|
-
VERSION: Final = "2025.10.
|
|
22
|
+
VERSION: Final = "2025.10.11"
|
|
23
23
|
|
|
24
24
|
# Detect test speedup mode via environment
|
|
25
25
|
_TEST_SPEEDUP: Final = (
|
|
@@ -27,8 +27,6 @@ _TEST_SPEEDUP: Final = (
|
|
|
27
27
|
)
|
|
28
28
|
|
|
29
29
|
# default
|
|
30
|
-
DEFAULT_STORAGE_DIRECTORY: Final = "aiohomematic_storage"
|
|
31
|
-
DEFAULT_CUSTOM_ID: Final = "custom_id"
|
|
32
30
|
DEFAULT_DELAY_NEW_DEVICE_CREATION: Final = False
|
|
33
31
|
DEFAULT_ENABLE_DEVICE_FIRMWARE_CHECK: Final = False
|
|
34
32
|
DEFAULT_ENABLE_PROGRAM_SCAN: Final = True
|
|
@@ -40,8 +38,11 @@ DEFAULT_INCLUDE_INTERNAL_SYSVARS: Final = True
|
|
|
40
38
|
DEFAULT_MAX_READ_WORKERS: Final = 1
|
|
41
39
|
DEFAULT_MAX_WORKERS: Final = 1
|
|
42
40
|
DEFAULT_MULTIPLIER: Final = 1.0
|
|
41
|
+
DEFAULT_OPTIONAL_SETTINGS: Final[tuple[OptionalSettings | str, ...]] = ()
|
|
43
42
|
DEFAULT_PERIODIC_REFRESH_INTERVAL: Final = 15
|
|
44
43
|
DEFAULT_PROGRAM_MARKERS: Final[tuple[DescriptionMarker | str, ...]] = ()
|
|
44
|
+
DEFAULT_SESSION_RECORDER_START_FOR_SECONDS: Final = 180
|
|
45
|
+
DEFAULT_STORAGE_DIRECTORY: Final = "aiohomematic_storage"
|
|
45
46
|
DEFAULT_SYSVAR_MARKERS: Final[tuple[DescriptionMarker | str, ...]] = ()
|
|
46
47
|
DEFAULT_SYS_SCAN_INTERVAL: Final = 30
|
|
47
48
|
DEFAULT_TLS: Final = False
|
|
@@ -49,12 +50,6 @@ DEFAULT_UN_IGNORES: Final[frozenset[str]] = frozenset()
|
|
|
49
50
|
DEFAULT_USE_GROUP_CHANNEL_FOR_COVER_STATE: Final = True
|
|
50
51
|
DEFAULT_VERIFY_TLS: Final = False
|
|
51
52
|
|
|
52
|
-
MANU_TEMP_CUSTOM_ID: Final = "manu_temp"
|
|
53
|
-
INTERNAL_CUSTOM_IDS: Final[tuple[str, ...]] = (
|
|
54
|
-
DEFAULT_CUSTOM_ID,
|
|
55
|
-
MANU_TEMP_CUSTOM_ID,
|
|
56
|
-
)
|
|
57
|
-
|
|
58
53
|
# Default encoding for json service calls, persistent cache
|
|
59
54
|
UTF_8: Final = "utf-8"
|
|
60
55
|
# Default encoding for xmlrpc service calls and script files
|
|
@@ -214,6 +209,13 @@ class CommandRxMode(StrEnum):
|
|
|
214
209
|
WAKEUP = "WAKEUP"
|
|
215
210
|
|
|
216
211
|
|
|
212
|
+
class InternalCustomID(StrEnum):
|
|
213
|
+
"""Enum for Homematic internal custom IDs."""
|
|
214
|
+
|
|
215
|
+
DEFAULT = "cid_default"
|
|
216
|
+
MANU_TEMP = "cid_manu_temp"
|
|
217
|
+
|
|
218
|
+
|
|
217
219
|
class DataOperationResult(Enum):
|
|
218
220
|
"""Enum with data operation results."""
|
|
219
221
|
|
|
@@ -352,6 +354,13 @@ class Operations(IntEnum):
|
|
|
352
354
|
EVENT = 4
|
|
353
355
|
|
|
354
356
|
|
|
357
|
+
class OptionalSettings(StrEnum):
|
|
358
|
+
"""Enum with aiohomematic optional settings."""
|
|
359
|
+
|
|
360
|
+
SR_DISABLE_RANDOMIZE_OUTPUT = "SR_DISABLE_RANDOMIZED_OUTPUT"
|
|
361
|
+
SR_RECORD_SYSTEM_INIT = "SR_RECORD_SYSTEM_INIT"
|
|
362
|
+
|
|
363
|
+
|
|
355
364
|
class Parameter(StrEnum):
|
|
356
365
|
"""Enum with Homematic parameters."""
|
|
357
366
|
|
|
@@ -12,10 +12,10 @@ import logging
|
|
|
12
12
|
from typing import Any, Final, cast
|
|
13
13
|
|
|
14
14
|
from aiohomematic.const import (
|
|
15
|
-
MANU_TEMP_CUSTOM_ID,
|
|
16
15
|
SCHEDULER_PROFILE_PATTERN,
|
|
17
16
|
SCHEDULER_TIME_PATTERN,
|
|
18
17
|
DataPointCategory,
|
|
18
|
+
InternalCustomID,
|
|
19
19
|
Parameter,
|
|
20
20
|
ParamsetKey,
|
|
21
21
|
ProductGroup,
|
|
@@ -235,7 +235,7 @@ class BaseCustomDpClimate(CustomDataPoint):
|
|
|
235
235
|
)
|
|
236
236
|
self._unregister_callbacks.append(
|
|
237
237
|
self._dp_setpoint.register_data_point_updated_callback(
|
|
238
|
-
cb=self._manu_temp_changed, custom_id=
|
|
238
|
+
cb=self._manu_temp_changed, custom_id=InternalCustomID.MANU_TEMP
|
|
239
239
|
)
|
|
240
240
|
)
|
|
241
241
|
|
|
@@ -802,7 +802,7 @@ class CustomDpRfThermostat(BaseCustomDpClimate):
|
|
|
802
802
|
|
|
803
803
|
self._unregister_callbacks.append(
|
|
804
804
|
self._dp_control_mode.register_data_point_updated_callback(
|
|
805
|
-
cb=self._manu_temp_changed, custom_id=
|
|
805
|
+
cb=self._manu_temp_changed, custom_id=InternalCustomID.MANU_TEMP
|
|
806
806
|
)
|
|
807
807
|
)
|
|
808
808
|
|
|
@@ -1047,7 +1047,7 @@ class CustomDpIpThermostat(BaseCustomDpClimate):
|
|
|
1047
1047
|
|
|
1048
1048
|
self._unregister_callbacks.append(
|
|
1049
1049
|
self._dp_set_point_mode.register_data_point_updated_callback(
|
|
1050
|
-
cb=self._manu_temp_changed, custom_id=
|
|
1050
|
+
cb=self._manu_temp_changed, custom_id=InternalCustomID.MANU_TEMP
|
|
1051
1051
|
)
|
|
1052
1052
|
)
|
|
1053
1053
|
|
aiohomematic/model/data_point.py
CHANGED
|
@@ -39,11 +39,9 @@ from aiohomematic import central as hmcu, client as hmcl, support as hms, valida
|
|
|
39
39
|
from aiohomematic.async_support import loop_check
|
|
40
40
|
from aiohomematic.const import (
|
|
41
41
|
CALLBACK_TYPE,
|
|
42
|
-
DEFAULT_CUSTOM_ID,
|
|
43
42
|
DEFAULT_MULTIPLIER,
|
|
44
43
|
DP_KEY_VALUE,
|
|
45
44
|
INIT_DATETIME,
|
|
46
|
-
INTERNAL_CUSTOM_IDS,
|
|
47
45
|
KEY_CHANNEL_OPERATION_MODE_VISIBILITY,
|
|
48
46
|
KWARGS_ARG_CUSTOM_ID,
|
|
49
47
|
KWARGS_ARG_DATA_POINT,
|
|
@@ -55,6 +53,7 @@ from aiohomematic.const import (
|
|
|
55
53
|
DataPointUsage,
|
|
56
54
|
EventKey,
|
|
57
55
|
Flag,
|
|
56
|
+
InternalCustomID,
|
|
58
57
|
Operations,
|
|
59
58
|
Parameter,
|
|
60
59
|
ParameterData,
|
|
@@ -309,11 +308,11 @@ class CallbackDataPoint(ABC, LogContextMixin):
|
|
|
309
308
|
|
|
310
309
|
def register_internal_data_point_updated_callback(self, *, cb: Callable) -> CALLBACK_TYPE:
|
|
311
310
|
"""Register internal data_point updated callback."""
|
|
312
|
-
return self.register_data_point_updated_callback(cb=cb, custom_id=
|
|
311
|
+
return self.register_data_point_updated_callback(cb=cb, custom_id=InternalCustomID.DEFAULT)
|
|
313
312
|
|
|
314
313
|
def register_data_point_updated_callback(self, *, cb: Callable, custom_id: str) -> CALLBACK_TYPE:
|
|
315
314
|
"""Register data_point updated callback."""
|
|
316
|
-
if custom_id not in
|
|
315
|
+
if custom_id not in InternalCustomID:
|
|
317
316
|
if self._custom_id is not None and self._custom_id != custom_id:
|
|
318
317
|
raise AioHomematicException(
|
|
319
318
|
f"REGISTER_data_point_updated_CALLBACK failed: hm_data_point: {self.full_name} is already registered by {self._custom_id}"
|
aiohomematic/model/device.py
CHANGED
|
@@ -1293,7 +1293,7 @@ class _DefinitionExporter:
|
|
|
1293
1293
|
str, dict[ParamsetKey, dict[str, ParameterData]]
|
|
1294
1294
|
] = await self._client.get_all_paramset_descriptions(device_descriptions=tuple(device_descriptions.values()))
|
|
1295
1295
|
model = device_descriptions[self._device_address]["TYPE"]
|
|
1296
|
-
|
|
1296
|
+
file_name = f"{model}.json"
|
|
1297
1297
|
|
|
1298
1298
|
# anonymize device_descriptions
|
|
1299
1299
|
anonymize_device_descriptions: list[DeviceDescription] = []
|
|
@@ -1316,14 +1316,14 @@ class _DefinitionExporter:
|
|
|
1316
1316
|
# Save device_descriptions for device to file.
|
|
1317
1317
|
await self._save(
|
|
1318
1318
|
directory=f"{self._storage_directory}/{DEVICE_DESCRIPTIONS_DIR}",
|
|
1319
|
-
|
|
1319
|
+
file_name=file_name,
|
|
1320
1320
|
data=anonymize_device_descriptions,
|
|
1321
1321
|
)
|
|
1322
1322
|
|
|
1323
1323
|
# Save device_descriptions for device to file.
|
|
1324
1324
|
await self._save(
|
|
1325
1325
|
directory=f"{self._storage_directory}/{PARAMSET_DESCRIPTIONS_DIR}",
|
|
1326
|
-
|
|
1326
|
+
file_name=file_name,
|
|
1327
1327
|
data=anonymize_paramset_descriptions,
|
|
1328
1328
|
)
|
|
1329
1329
|
|
|
@@ -1332,13 +1332,13 @@ class _DefinitionExporter:
|
|
|
1332
1332
|
address_parts[0] = self._random_id
|
|
1333
1333
|
return ADDRESS_SEPARATOR.join(address_parts)
|
|
1334
1334
|
|
|
1335
|
-
async def _save(self, *, directory: str,
|
|
1335
|
+
async def _save(self, *, directory: str, file_name: str, data: Any) -> DataOperationResult:
|
|
1336
1336
|
"""Save file to disk."""
|
|
1337
1337
|
|
|
1338
1338
|
def perform_save() -> DataOperationResult:
|
|
1339
1339
|
if not check_or_create_directory(directory=directory):
|
|
1340
1340
|
return DataOperationResult.NO_SAVE # pragma: no cover
|
|
1341
|
-
with open(file=os.path.join(directory,
|
|
1341
|
+
with open(file=os.path.join(directory, file_name), mode="wb") as fptr:
|
|
1342
1342
|
fptr.write(orjson.dumps(data, option=orjson.OPT_INDENT_2 | orjson.OPT_NON_STR_KEYS))
|
|
1343
1343
|
return DataOperationResult.SAVE_SUCCESS
|
|
1344
1344
|
|
aiohomematic/model/update.py
CHANGED
|
@@ -11,11 +11,11 @@ from typing import Final
|
|
|
11
11
|
|
|
12
12
|
from aiohomematic.const import (
|
|
13
13
|
CALLBACK_TYPE,
|
|
14
|
-
DEFAULT_CUSTOM_ID,
|
|
15
14
|
HMIP_FIRMWARE_UPDATE_IN_PROGRESS_STATES,
|
|
16
15
|
HMIP_FIRMWARE_UPDATE_READY_STATES,
|
|
17
16
|
DataPointCategory,
|
|
18
17
|
Interface,
|
|
18
|
+
InternalCustomID,
|
|
19
19
|
)
|
|
20
20
|
from aiohomematic.decorators import inspector
|
|
21
21
|
from aiohomematic.exceptions import AioHomematicException
|
|
@@ -114,7 +114,7 @@ class DpUpdate(CallbackDataPoint, PayloadMixin):
|
|
|
114
114
|
|
|
115
115
|
def register_data_point_updated_callback(self, *, cb: Callable, custom_id: str) -> CALLBACK_TYPE:
|
|
116
116
|
"""Register update callback."""
|
|
117
|
-
if custom_id !=
|
|
117
|
+
if custom_id != InternalCustomID.DEFAULT:
|
|
118
118
|
if self._custom_id is not None:
|
|
119
119
|
raise AioHomematicException(
|
|
120
120
|
f"REGISTER_UPDATE_CALLBACK failed: hm_data_point: {self.full_name} is already registered by {self._custom_id}"
|