aiohomematic 2025.10.8__py3-none-any.whl → 2025.10.9__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/__init__.py +3 -3
- aiohomematic/async_support.py +1 -1
- aiohomematic/central/__init__.py +58 -30
- aiohomematic/central/decorators.py +1 -1
- aiohomematic/central/rpc_server.py +1 -1
- aiohomematic/client/__init__.py +18 -12
- aiohomematic/client/_rpc_errors.py +1 -1
- aiohomematic/client/json_rpc.py +29 -3
- aiohomematic/client/rpc_proxy.py +20 -2
- aiohomematic/const.py +23 -6
- aiohomematic/context.py +1 -1
- aiohomematic/converter.py +1 -1
- aiohomematic/decorators.py +1 -1
- aiohomematic/exceptions.py +1 -1
- aiohomematic/hmcli.py +1 -1
- aiohomematic/model/__init__.py +1 -1
- aiohomematic/model/calculated/__init__.py +1 -1
- aiohomematic/model/calculated/climate.py +1 -1
- aiohomematic/model/calculated/data_point.py +1 -1
- aiohomematic/model/calculated/operating_voltage_level.py +1 -1
- aiohomematic/model/calculated/support.py +1 -1
- aiohomematic/model/custom/__init__.py +1 -1
- aiohomematic/model/custom/climate.py +7 -4
- aiohomematic/model/custom/const.py +1 -1
- aiohomematic/model/custom/cover.py +1 -1
- aiohomematic/model/custom/data_point.py +1 -1
- aiohomematic/model/custom/definition.py +1 -1
- aiohomematic/model/custom/light.py +1 -1
- aiohomematic/model/custom/lock.py +1 -1
- aiohomematic/model/custom/siren.py +1 -1
- aiohomematic/model/custom/support.py +1 -1
- aiohomematic/model/custom/switch.py +1 -1
- aiohomematic/model/custom/valve.py +1 -1
- aiohomematic/model/data_point.py +3 -2
- aiohomematic/model/device.py +10 -10
- aiohomematic/model/event.py +1 -1
- aiohomematic/model/generic/__init__.py +1 -1
- aiohomematic/model/generic/action.py +1 -1
- aiohomematic/model/generic/binary_sensor.py +1 -1
- aiohomematic/model/generic/button.py +1 -1
- aiohomematic/model/generic/data_point.py +1 -1
- aiohomematic/model/generic/number.py +1 -1
- aiohomematic/model/generic/select.py +1 -1
- aiohomematic/model/generic/sensor.py +1 -1
- aiohomematic/model/generic/switch.py +1 -1
- aiohomematic/model/generic/text.py +1 -1
- aiohomematic/model/hub/__init__.py +1 -1
- aiohomematic/model/hub/binary_sensor.py +1 -1
- aiohomematic/model/hub/button.py +1 -1
- aiohomematic/model/hub/data_point.py +1 -1
- aiohomematic/model/hub/number.py +1 -1
- aiohomematic/model/hub/select.py +1 -1
- aiohomematic/model/hub/sensor.py +1 -1
- aiohomematic/model/hub/switch.py +1 -1
- aiohomematic/model/hub/text.py +1 -1
- aiohomematic/model/support.py +1 -1
- aiohomematic/model/update.py +1 -1
- aiohomematic/property_decorators.py +2 -2
- aiohomematic/store/__init__.py +34 -0
- aiohomematic/{caches → store}/dynamic.py +4 -4
- aiohomematic/store/persistent.py +933 -0
- aiohomematic/{caches → store}/visibility.py +4 -4
- aiohomematic/support.py +16 -12
- aiohomematic/validator.py +1 -1
- {aiohomematic-2025.10.8.dist-info → aiohomematic-2025.10.9.dist-info}/METADATA +1 -1
- aiohomematic-2025.10.9.dist-info/RECORD +78 -0
- aiohomematic_support/client_local.py +2 -2
- aiohomematic/caches/__init__.py +0 -12
- aiohomematic/caches/persistent.py +0 -478
- aiohomematic-2025.10.8.dist-info/RECORD +0 -78
- {aiohomematic-2025.10.8.dist-info → aiohomematic-2025.10.9.dist-info}/WHEEL +0 -0
- {aiohomematic-2025.10.8.dist-info → aiohomematic-2025.10.9.dist-info}/licenses/LICENSE +0 -0
- {aiohomematic-2025.10.8.dist-info → aiohomematic-2025.10.9.dist-info}/top_level.txt +0 -0
aiohomematic/decorators.py
CHANGED
aiohomematic/exceptions.py
CHANGED
aiohomematic/hmcli.py
CHANGED
aiohomematic/model/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2021-2025
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
3
|
"""Module for data points implemented using the climate category."""
|
|
4
4
|
|
|
5
5
|
from __future__ import annotations
|
|
@@ -12,6 +12,7 @@ import logging
|
|
|
12
12
|
from typing import Any, Final, cast
|
|
13
13
|
|
|
14
14
|
from aiohomematic.const import (
|
|
15
|
+
MANU_TEMP_CUSTOM_ID,
|
|
15
16
|
SCHEDULER_PROFILE_PATTERN,
|
|
16
17
|
SCHEDULER_TIME_PATTERN,
|
|
17
18
|
DataPointCategory,
|
|
@@ -233,7 +234,9 @@ class BaseCustomDpClimate(CustomDataPoint):
|
|
|
233
234
|
field=Field.TEMPERATURE_MINIMUM, data_point_type=DpFloat
|
|
234
235
|
)
|
|
235
236
|
self._unregister_callbacks.append(
|
|
236
|
-
self._dp_setpoint.register_data_point_updated_callback(
|
|
237
|
+
self._dp_setpoint.register_data_point_updated_callback(
|
|
238
|
+
cb=self._manu_temp_changed, custom_id=MANU_TEMP_CUSTOM_ID
|
|
239
|
+
)
|
|
237
240
|
)
|
|
238
241
|
|
|
239
242
|
@abstractmethod
|
|
@@ -799,7 +802,7 @@ class CustomDpRfThermostat(BaseCustomDpClimate):
|
|
|
799
802
|
|
|
800
803
|
self._unregister_callbacks.append(
|
|
801
804
|
self._dp_control_mode.register_data_point_updated_callback(
|
|
802
|
-
cb=self._manu_temp_changed, custom_id=
|
|
805
|
+
cb=self._manu_temp_changed, custom_id=MANU_TEMP_CUSTOM_ID
|
|
803
806
|
)
|
|
804
807
|
)
|
|
805
808
|
|
|
@@ -1044,7 +1047,7 @@ class CustomDpIpThermostat(BaseCustomDpClimate):
|
|
|
1044
1047
|
|
|
1045
1048
|
self._unregister_callbacks.append(
|
|
1046
1049
|
self._dp_set_point_mode.register_data_point_updated_callback(
|
|
1047
|
-
cb=self._manu_temp_changed, custom_id=
|
|
1050
|
+
cb=self._manu_temp_changed, custom_id=MANU_TEMP_CUSTOM_ID
|
|
1048
1051
|
)
|
|
1049
1052
|
)
|
|
1050
1053
|
|
aiohomematic/model/data_point.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2021-2025
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
3
|
"""
|
|
4
4
|
Core data point model for AioHomematic.
|
|
5
5
|
|
|
@@ -43,6 +43,7 @@ from aiohomematic.const import (
|
|
|
43
43
|
DEFAULT_MULTIPLIER,
|
|
44
44
|
DP_KEY_VALUE,
|
|
45
45
|
INIT_DATETIME,
|
|
46
|
+
INTERNAL_CUSTOM_IDS,
|
|
46
47
|
KEY_CHANNEL_OPERATION_MODE_VISIBILITY,
|
|
47
48
|
KWARGS_ARG_CUSTOM_ID,
|
|
48
49
|
KWARGS_ARG_DATA_POINT,
|
|
@@ -312,7 +313,7 @@ class CallbackDataPoint(ABC, LogContextMixin):
|
|
|
312
313
|
|
|
313
314
|
def register_data_point_updated_callback(self, *, cb: Callable, custom_id: str) -> CALLBACK_TYPE:
|
|
314
315
|
"""Register data_point updated callback."""
|
|
315
|
-
if custom_id
|
|
316
|
+
if custom_id not in INTERNAL_CUSTOM_IDS:
|
|
316
317
|
if self._custom_id is not None and self._custom_id != custom_id:
|
|
317
318
|
raise AioHomematicException(
|
|
318
319
|
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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2021-2025
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
3
|
"""
|
|
4
4
|
Device and channel model for AioHomematic.
|
|
5
5
|
|
|
@@ -671,7 +671,7 @@ class Device(LogContextMixin, PayloadMixin):
|
|
|
671
671
|
channel_address=channel_address,
|
|
672
672
|
paramset_key=paramset_key,
|
|
673
673
|
)
|
|
674
|
-
await self._central.
|
|
674
|
+
await self._central.save_files(save_paramset_descriptions=True)
|
|
675
675
|
for dp in self.generic_data_points:
|
|
676
676
|
dp.update_parameter_data()
|
|
677
677
|
self.fire_device_updated_callback()
|
|
@@ -1240,7 +1240,7 @@ class _ValueCache:
|
|
|
1240
1240
|
*,
|
|
1241
1241
|
dpk: DataPointKey,
|
|
1242
1242
|
) -> Any:
|
|
1243
|
-
"""Load data from
|
|
1243
|
+
"""Load data from store."""
|
|
1244
1244
|
# Try to get data from central cache
|
|
1245
1245
|
if (
|
|
1246
1246
|
dpk.paramset_key == ParamsetKey.VALUES
|
|
@@ -1269,14 +1269,14 @@ class _DefinitionExporter:
|
|
|
1269
1269
|
"_device_address",
|
|
1270
1270
|
"_interface_id",
|
|
1271
1271
|
"_random_id",
|
|
1272
|
-
"
|
|
1272
|
+
"_storage_directory",
|
|
1273
1273
|
)
|
|
1274
1274
|
|
|
1275
1275
|
def __init__(self, *, device: Device) -> None:
|
|
1276
1276
|
"""Init the device exporter."""
|
|
1277
1277
|
self._client: Final = device.client
|
|
1278
1278
|
self._central: Final = device.client.central
|
|
1279
|
-
self.
|
|
1279
|
+
self._storage_directory: Final = self._central.config.storage_directory
|
|
1280
1280
|
self._interface_id: Final = device.interface_id
|
|
1281
1281
|
self._device_address: Final = device.address
|
|
1282
1282
|
self._random_id: Final[str] = f"VCU{int(random.randint(1000000, 9999999))}"
|
|
@@ -1315,14 +1315,14 @@ class _DefinitionExporter:
|
|
|
1315
1315
|
|
|
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
|
filename=filename,
|
|
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
|
filename=filename,
|
|
1327
1327
|
data=anonymize_paramset_descriptions,
|
|
1328
1328
|
)
|
|
@@ -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, *,
|
|
1335
|
+
async def _save(self, *, directory: str, filename: str, data: Any) -> DataOperationResult:
|
|
1336
1336
|
"""Save file to disk."""
|
|
1337
1337
|
|
|
1338
1338
|
def perform_save() -> DataOperationResult:
|
|
1339
|
-
if not check_or_create_directory(directory=
|
|
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(
|
|
1341
|
+
with open(file=os.path.join(directory, filename), 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/event.py
CHANGED
aiohomematic/model/hub/button.py
CHANGED
aiohomematic/model/hub/number.py
CHANGED
aiohomematic/model/hub/select.py
CHANGED
aiohomematic/model/hub/sensor.py
CHANGED
aiohomematic/model/hub/switch.py
CHANGED
aiohomematic/model/hub/text.py
CHANGED
aiohomematic/model/support.py
CHANGED
aiohomematic/model/update.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2021-2025
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
3
|
"""
|
|
4
4
|
Decorators and helpers for declaring public attributes on data point classes.
|
|
5
5
|
|
|
@@ -15,7 +15,7 @@ All decorators accept an optional keyword-only argument log_context. If set to
|
|
|
15
15
|
True, the property will be included in the LogContextMixin.log_context mapping.
|
|
16
16
|
|
|
17
17
|
Notes on caching
|
|
18
|
-
- Marked with cached=True always
|
|
18
|
+
- Marked with cached=True always store on first access and invalidates on set/delete.
|
|
19
19
|
"""
|
|
20
20
|
|
|
21
21
|
from __future__ import annotations
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
|
+
"""
|
|
4
|
+
Store packages for AioHomematic.
|
|
5
|
+
|
|
6
|
+
This package groups store implementations used throughout the library:
|
|
7
|
+
- persistent: Long-lived on-disk store for device and paramset descriptions.
|
|
8
|
+
- dynamic: Short-lived in-memory store for runtime values and connection health.
|
|
9
|
+
- visibility: Parameter visibility rules to decide which parameters are relevant.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
from aiohomematic.store.dynamic import CentralDataCache, CommandCache, DeviceDetailsCache, PingPongCache
|
|
15
|
+
from aiohomematic.store.persistent import (
|
|
16
|
+
DeviceDescriptionCache,
|
|
17
|
+
ParamsetDescriptionCache,
|
|
18
|
+
SessionRecorder,
|
|
19
|
+
cleanup_files,
|
|
20
|
+
)
|
|
21
|
+
from aiohomematic.store.visibility import ParameterVisibilityCache, check_ignore_parameters_is_clean
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"CentralDataCache",
|
|
25
|
+
"CommandCache",
|
|
26
|
+
"DeviceDescriptionCache",
|
|
27
|
+
"DeviceDetailsCache",
|
|
28
|
+
"ParameterVisibilityCache",
|
|
29
|
+
"ParamsetDescriptionCache",
|
|
30
|
+
"PingPongCache",
|
|
31
|
+
"SessionRecorder",
|
|
32
|
+
"cleanup_files",
|
|
33
|
+
"check_ignore_parameters_is_clean",
|
|
34
|
+
]
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# SPDX-License-Identifier: MIT
|
|
2
|
-
# Copyright (c) 2021-2025
|
|
2
|
+
# Copyright (c) 2021-2025
|
|
3
3
|
"""
|
|
4
|
-
Dynamic
|
|
4
|
+
Dynamic store used at runtime by the central unit and clients.
|
|
5
5
|
|
|
6
|
-
This module provides short-lived, in-memory
|
|
6
|
+
This module provides short-lived, in-memory store that support robust and efficient
|
|
7
7
|
communication with Homematic interfaces:
|
|
8
8
|
|
|
9
9
|
- CommandCache: Tracks recently sent commands and their values per data point,
|
|
@@ -16,7 +16,7 @@ communication with Homematic interfaces:
|
|
|
16
16
|
- PingPongCache: Tracks ping/pong timestamps to detect connection health issues
|
|
17
17
|
and emits interface events on mismatch thresholds.
|
|
18
18
|
|
|
19
|
-
The
|
|
19
|
+
The store are intentionally ephemeral and cleared/aged according to the rules in
|
|
20
20
|
constants to keep memory footprint predictable while improving responsiveness.
|
|
21
21
|
"""
|
|
22
22
|
|