aiohomematic 2025.10.19__tar.gz → 2025.10.20__tar.gz
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-2025.10.19/aiohomematic.egg-info → aiohomematic-2025.10.20}/PKG-INFO +5 -5
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/central/__init__.py +55 -1
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/const.py +1 -1
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/data_point.py +5 -5
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/support.py +2 -2
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/support.py +1 -53
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20/aiohomematic.egg-info}/PKG-INFO +5 -5
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic.egg-info/SOURCES.txt +1 -0
- aiohomematic-2025.10.20/aiohomematic.egg-info/requires.txt +4 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/pyproject.toml +4 -8
- aiohomematic-2025.10.20/requirements.txt +4 -0
- aiohomematic-2025.10.19/aiohomematic.egg-info/requires.txt +0 -4
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/LICENSE +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/MANIFEST.in +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/README.md +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/__init__.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/async_support.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/central/decorators.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/central/rpc_server.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/client/__init__.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/client/_rpc_errors.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/client/json_rpc.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/client/rpc_proxy.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/context.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/converter.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/decorators.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/exceptions.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/hmcli.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/__init__.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/calculated/__init__.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/calculated/climate.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/calculated/data_point.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/calculated/operating_voltage_level.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/calculated/support.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/__init__.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/climate.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/const.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/cover.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/definition.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/light.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/lock.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/siren.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/support.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/switch.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/custom/valve.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/data_point.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/device.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/event.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/__init__.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/action.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/binary_sensor.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/button.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/data_point.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/number.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/select.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/sensor.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/switch.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/text.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/hub/__init__.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/hub/binary_sensor.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/hub/button.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/hub/data_point.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/hub/number.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/hub/select.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/hub/sensor.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/hub/switch.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/hub/text.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/update.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/property_decorators.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/py.typed +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/rega_scripts/fetch_all_device_data.fn +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/rega_scripts/get_program_descriptions.fn +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/rega_scripts/get_serial.fn +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/rega_scripts/get_system_variable_descriptions.fn +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/rega_scripts/set_program_state.fn +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/rega_scripts/set_system_variable.fn +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/store/__init__.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/store/dynamic.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/store/persistent.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/store/visibility.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/validator.py +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic.egg-info/dependency_links.txt +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic.egg-info/top_level.txt +0 -0
- {aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiohomematic
|
|
3
|
-
Version: 2025.10.
|
|
3
|
+
Version: 2025.10.20
|
|
4
4
|
Summary: Homematic interface for Home Assistant running on Python 3.
|
|
5
5
|
Home-page: https://github.com/sukramj/aiohomematic
|
|
6
6
|
Author-email: SukramJ <sukramj@icloud.com>, Daniel Perna <danielperna84@gmail.com>
|
|
@@ -9,7 +9,7 @@ Project-URL: Source Code, https://github.com/sukramj/aiohomematic
|
|
|
9
9
|
Project-URL: Bug Reports, https://github.com/sukramj/aiohomematic/issues
|
|
10
10
|
Project-URL: Docs: Dev, https://github.com/sukramj/aiohomematic
|
|
11
11
|
Project-URL: Forum, https://github.com/sukramj/aiohomematic/discussions
|
|
12
|
-
Keywords: home,automation,homematic
|
|
12
|
+
Keywords: home,automation,homematic,openccu,homegear
|
|
13
13
|
Classifier: Development Status :: 5 - Production/Stable
|
|
14
14
|
Classifier: Intended Audience :: End Users/Desktop
|
|
15
15
|
Classifier: Intended Audience :: Developers
|
|
@@ -21,10 +21,10 @@ Classifier: Topic :: Home Automation
|
|
|
21
21
|
Requires-Python: >=3.13.0
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
-
Requires-Dist: aiohttp>=3.
|
|
25
|
-
Requires-Dist: orjson>=3.
|
|
24
|
+
Requires-Dist: aiohttp>=3.12.0
|
|
25
|
+
Requires-Dist: orjson>=3.11.0
|
|
26
26
|
Requires-Dist: python-slugify>=8.0.0
|
|
27
|
-
Requires-Dist: voluptuous>=0.
|
|
27
|
+
Requires-Dist: voluptuous>=0.15.0
|
|
28
28
|
Dynamic: license-file
|
|
29
29
|
|
|
30
30
|
[![releasebadge]][release]
|
|
@@ -110,6 +110,7 @@ from aiohomematic.const import (
|
|
|
110
110
|
DEVICE_FIRMWARE_CHECK_INTERVAL,
|
|
111
111
|
DEVICE_FIRMWARE_DELIVERING_CHECK_INTERVAL,
|
|
112
112
|
DEVICE_FIRMWARE_UPDATING_CHECK_INTERVAL,
|
|
113
|
+
IDENTIFIER_SEPARATOR,
|
|
113
114
|
IGNORE_FOR_UN_IGNORE_PARAMETERS,
|
|
114
115
|
IP_ANY_V4,
|
|
115
116
|
LOCAL_HOST,
|
|
@@ -173,12 +174,16 @@ from aiohomematic.store import (
|
|
|
173
174
|
from aiohomematic.support import (
|
|
174
175
|
LogContextMixin,
|
|
175
176
|
PayloadMixin,
|
|
176
|
-
|
|
177
|
+
check_or_create_directory,
|
|
178
|
+
check_password,
|
|
177
179
|
extract_device_addresses_from_device_descriptions,
|
|
178
180
|
extract_exc_args,
|
|
179
181
|
get_channel_no,
|
|
180
182
|
get_device_address,
|
|
181
183
|
get_ip_addr,
|
|
184
|
+
is_hostname,
|
|
185
|
+
is_ipv4_address,
|
|
186
|
+
is_port,
|
|
182
187
|
)
|
|
183
188
|
|
|
184
189
|
__all__ = ["CentralConfig", "CentralUnit", "INTERFACE_EVENT_SCHEMA"]
|
|
@@ -2219,6 +2224,55 @@ class CentralConnectionState:
|
|
|
2219
2224
|
)
|
|
2220
2225
|
|
|
2221
2226
|
|
|
2227
|
+
def check_config(
|
|
2228
|
+
*,
|
|
2229
|
+
central_name: str,
|
|
2230
|
+
host: str,
|
|
2231
|
+
username: str,
|
|
2232
|
+
password: str,
|
|
2233
|
+
storage_directory: str,
|
|
2234
|
+
callback_host: str | None,
|
|
2235
|
+
callback_port_xml_rpc: int | None,
|
|
2236
|
+
json_port: int | None,
|
|
2237
|
+
interface_configs: AbstractSet[hmcl.InterfaceConfig] | None = None,
|
|
2238
|
+
) -> list[str]:
|
|
2239
|
+
"""Check config. Throws BaseHomematicException on failure."""
|
|
2240
|
+
config_failures: list[str] = []
|
|
2241
|
+
if central_name and IDENTIFIER_SEPARATOR in central_name:
|
|
2242
|
+
config_failures.append(f"Instance name must not contain {IDENTIFIER_SEPARATOR}")
|
|
2243
|
+
|
|
2244
|
+
if not (is_hostname(hostname=host) or is_ipv4_address(address=host)):
|
|
2245
|
+
config_failures.append("Invalid hostname or ipv4 address")
|
|
2246
|
+
if not username:
|
|
2247
|
+
config_failures.append("Username must not be empty")
|
|
2248
|
+
if not password:
|
|
2249
|
+
config_failures.append("Password is required")
|
|
2250
|
+
if not check_password(password=password):
|
|
2251
|
+
config_failures.append("Password is not valid")
|
|
2252
|
+
try:
|
|
2253
|
+
check_or_create_directory(directory=storage_directory)
|
|
2254
|
+
except BaseHomematicException as bhexc:
|
|
2255
|
+
config_failures.append(extract_exc_args(exc=bhexc)[0])
|
|
2256
|
+
if callback_host and not (is_hostname(hostname=callback_host) or is_ipv4_address(address=callback_host)):
|
|
2257
|
+
config_failures.append("Invalid callback hostname or ipv4 address")
|
|
2258
|
+
if callback_port_xml_rpc and not is_port(port=callback_port_xml_rpc):
|
|
2259
|
+
config_failures.append("Invalid xml rpc callback port")
|
|
2260
|
+
if json_port and not is_port(port=json_port):
|
|
2261
|
+
config_failures.append("Invalid json port")
|
|
2262
|
+
if interface_configs and not _has_primary_client(interface_configs=interface_configs):
|
|
2263
|
+
config_failures.append(f"No primary interface ({', '.join(PRIMARY_CLIENT_CANDIDATE_INTERFACES)}) defined")
|
|
2264
|
+
|
|
2265
|
+
return config_failures
|
|
2266
|
+
|
|
2267
|
+
|
|
2268
|
+
def _has_primary_client(*, interface_configs: AbstractSet[hmcl.InterfaceConfig]) -> bool:
|
|
2269
|
+
"""Check if all configured clients exists in central."""
|
|
2270
|
+
for interface_config in interface_configs:
|
|
2271
|
+
if interface_config.interface in PRIMARY_CLIENT_CANDIDATE_INTERFACES:
|
|
2272
|
+
return True
|
|
2273
|
+
return False
|
|
2274
|
+
|
|
2275
|
+
|
|
2222
2276
|
def _get_new_data_points(
|
|
2223
2277
|
*,
|
|
2224
2278
|
new_devices: set[Device],
|
|
@@ -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.20"
|
|
23
23
|
|
|
24
24
|
# Detect test speedup mode via environment
|
|
25
25
|
_TEST_SPEEDUP: Final = (
|
|
@@ -204,12 +204,12 @@ class CustomDataPoint(BaseDataPoint):
|
|
|
204
204
|
def _init_data_points(self) -> None:
|
|
205
205
|
"""Init data point collection."""
|
|
206
206
|
# Add repeating fields
|
|
207
|
-
for field_name, parameter in self._device_def.get(
|
|
207
|
+
for field_name, parameter in self._device_def.get(CDPD.REPEATABLE_FIELDS, {}).items():
|
|
208
208
|
if dp := self._device.get_generic_data_point(channel_address=self._channel.address, parameter=parameter):
|
|
209
209
|
self._add_data_point(field=field_name, data_point=dp, is_visible=False)
|
|
210
210
|
|
|
211
211
|
# Add visible repeating fields
|
|
212
|
-
for field_name, parameter in self._device_def.get(
|
|
212
|
+
for field_name, parameter in self._device_def.get(CDPD.VISIBLE_REPEATABLE_FIELDS, {}).items():
|
|
213
213
|
if dp := self._device.get_generic_data_point(channel_address=self._channel.address, parameter=parameter):
|
|
214
214
|
self._add_data_point(field=field_name, data_point=dp, is_visible=True)
|
|
215
215
|
|
|
@@ -229,11 +229,11 @@ class CustomDataPoint(BaseDataPoint):
|
|
|
229
229
|
|
|
230
230
|
# Add device fields
|
|
231
231
|
self._add_data_points(
|
|
232
|
-
field_dict_name=
|
|
232
|
+
field_dict_name=CDPD.FIELDS,
|
|
233
233
|
)
|
|
234
234
|
# Add visible device fields
|
|
235
235
|
self._add_data_points(
|
|
236
|
-
field_dict_name=
|
|
236
|
+
field_dict_name=CDPD.VISIBLE_FIELDS,
|
|
237
237
|
is_visible=True,
|
|
238
238
|
)
|
|
239
239
|
|
|
@@ -243,7 +243,7 @@ class CustomDataPoint(BaseDataPoint):
|
|
|
243
243
|
if hmed.get_include_default_data_points(device_profile=self._device_profile):
|
|
244
244
|
self._mark_data_points(custom_data_point_def=hmed.get_default_data_points())
|
|
245
245
|
|
|
246
|
-
def _add_data_points(self, *, field_dict_name:
|
|
246
|
+
def _add_data_points(self, *, field_dict_name: CDPD, is_visible: bool | None = None) -> None:
|
|
247
247
|
"""Add data points to custom data point."""
|
|
248
248
|
fields = self._device_def.get(field_dict_name, {})
|
|
249
249
|
for channel_no, channel in fields.items():
|
|
@@ -32,7 +32,7 @@ from aiohomematic.const import (
|
|
|
32
32
|
ParameterType,
|
|
33
33
|
)
|
|
34
34
|
from aiohomematic.model import device as hmd
|
|
35
|
-
from aiohomematic.model.custom import
|
|
35
|
+
from aiohomematic.model.custom.const import CDPD
|
|
36
36
|
from aiohomematic.support import to_bool
|
|
37
37
|
|
|
38
38
|
__all__ = [
|
|
@@ -565,7 +565,7 @@ def check_channel_is_the_only_primary_channel(
|
|
|
565
565
|
device_has_multiple_channels: bool,
|
|
566
566
|
) -> bool:
|
|
567
567
|
"""Check if this channel is the only primary channel."""
|
|
568
|
-
primary_channel: int = device_def[
|
|
568
|
+
primary_channel: int = device_def[CDPD.PRIMARY_CHANNEL]
|
|
569
569
|
return bool(primary_channel == current_channel_no and device_has_multiple_channels is False)
|
|
570
570
|
|
|
571
571
|
|
|
@@ -10,7 +10,7 @@ from __future__ import annotations
|
|
|
10
10
|
|
|
11
11
|
import base64
|
|
12
12
|
from collections import defaultdict
|
|
13
|
-
from collections.abc import Callable, Collection, Mapping
|
|
13
|
+
from collections.abc import Callable, Collection, Mapping
|
|
14
14
|
import contextlib
|
|
15
15
|
from dataclasses import dataclass
|
|
16
16
|
from datetime import datetime
|
|
@@ -30,7 +30,6 @@ from typing import Any, Final, cast
|
|
|
30
30
|
|
|
31
31
|
import orjson
|
|
32
32
|
|
|
33
|
-
from aiohomematic import client as hmcl
|
|
34
33
|
from aiohomematic.const import (
|
|
35
34
|
ADDRESS_SEPARATOR,
|
|
36
35
|
ALLOWED_HOSTNAME_PATTERN,
|
|
@@ -38,12 +37,10 @@ from aiohomematic.const import (
|
|
|
38
37
|
CHANNEL_ADDRESS_PATTERN,
|
|
39
38
|
DEVICE_ADDRESS_PATTERN,
|
|
40
39
|
HTMLTAG_PATTERN,
|
|
41
|
-
IDENTIFIER_SEPARATOR,
|
|
42
40
|
INIT_DATETIME,
|
|
43
41
|
ISO_8859_1,
|
|
44
42
|
MAX_CACHE_AGE,
|
|
45
43
|
NO_CACHE_ENTRY,
|
|
46
|
-
PRIMARY_CLIENT_CANDIDATE_INTERFACES,
|
|
47
44
|
TIMEOUT,
|
|
48
45
|
UTF_8,
|
|
49
46
|
CommandRxMode,
|
|
@@ -95,55 +92,6 @@ def build_xml_rpc_headers(
|
|
|
95
92
|
return [("Authorization", f"Basic {base64_message}")]
|
|
96
93
|
|
|
97
94
|
|
|
98
|
-
def check_config(
|
|
99
|
-
*,
|
|
100
|
-
central_name: str,
|
|
101
|
-
host: str,
|
|
102
|
-
username: str,
|
|
103
|
-
password: str,
|
|
104
|
-
storage_directory: str,
|
|
105
|
-
callback_host: str | None,
|
|
106
|
-
callback_port_xml_rpc: int | None,
|
|
107
|
-
json_port: int | None,
|
|
108
|
-
interface_configs: AbstractSet[hmcl.InterfaceConfig] | None = None,
|
|
109
|
-
) -> list[str]:
|
|
110
|
-
"""Check config. Throws BaseHomematicException on failure."""
|
|
111
|
-
config_failures: list[str] = []
|
|
112
|
-
if central_name and IDENTIFIER_SEPARATOR in central_name:
|
|
113
|
-
config_failures.append(f"Instance name must not contain {IDENTIFIER_SEPARATOR}")
|
|
114
|
-
|
|
115
|
-
if not (is_hostname(hostname=host) or is_ipv4_address(address=host)):
|
|
116
|
-
config_failures.append("Invalid hostname or ipv4 address")
|
|
117
|
-
if not username:
|
|
118
|
-
config_failures.append("Username must not be empty")
|
|
119
|
-
if not password:
|
|
120
|
-
config_failures.append("Password is required")
|
|
121
|
-
if not check_password(password=password):
|
|
122
|
-
config_failures.append("Password is not valid")
|
|
123
|
-
try:
|
|
124
|
-
check_or_create_directory(directory=storage_directory)
|
|
125
|
-
except BaseHomematicException as bhexc:
|
|
126
|
-
config_failures.append(extract_exc_args(exc=bhexc)[0])
|
|
127
|
-
if callback_host and not (is_hostname(hostname=callback_host) or is_ipv4_address(address=callback_host)):
|
|
128
|
-
config_failures.append("Invalid callback hostname or ipv4 address")
|
|
129
|
-
if callback_port_xml_rpc and not is_port(port=callback_port_xml_rpc):
|
|
130
|
-
config_failures.append("Invalid xml rpc callback port")
|
|
131
|
-
if json_port and not is_port(port=json_port):
|
|
132
|
-
config_failures.append("Invalid json port")
|
|
133
|
-
if interface_configs and not has_primary_client(interface_configs=interface_configs):
|
|
134
|
-
config_failures.append(f"No primary interface ({', '.join(PRIMARY_CLIENT_CANDIDATE_INTERFACES)}) defined")
|
|
135
|
-
|
|
136
|
-
return config_failures
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
def has_primary_client(*, interface_configs: AbstractSet[hmcl.InterfaceConfig]) -> bool:
|
|
140
|
-
"""Check if all configured clients exists in central."""
|
|
141
|
-
for interface_config in interface_configs:
|
|
142
|
-
if interface_config.interface in PRIMARY_CLIENT_CANDIDATE_INTERFACES:
|
|
143
|
-
return True
|
|
144
|
-
return False
|
|
145
|
-
|
|
146
|
-
|
|
147
95
|
def delete_file(directory: str, file_name: str) -> None: # kwonly: disable
|
|
148
96
|
"""Delete the file. File can contain a wildcard."""
|
|
149
97
|
if os.path.exists(directory):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aiohomematic
|
|
3
|
-
Version: 2025.10.
|
|
3
|
+
Version: 2025.10.20
|
|
4
4
|
Summary: Homematic interface for Home Assistant running on Python 3.
|
|
5
5
|
Home-page: https://github.com/sukramj/aiohomematic
|
|
6
6
|
Author-email: SukramJ <sukramj@icloud.com>, Daniel Perna <danielperna84@gmail.com>
|
|
@@ -9,7 +9,7 @@ Project-URL: Source Code, https://github.com/sukramj/aiohomematic
|
|
|
9
9
|
Project-URL: Bug Reports, https://github.com/sukramj/aiohomematic/issues
|
|
10
10
|
Project-URL: Docs: Dev, https://github.com/sukramj/aiohomematic
|
|
11
11
|
Project-URL: Forum, https://github.com/sukramj/aiohomematic/discussions
|
|
12
|
-
Keywords: home,automation,homematic
|
|
12
|
+
Keywords: home,automation,homematic,openccu,homegear
|
|
13
13
|
Classifier: Development Status :: 5 - Production/Stable
|
|
14
14
|
Classifier: Intended Audience :: End Users/Desktop
|
|
15
15
|
Classifier: Intended Audience :: Developers
|
|
@@ -21,10 +21,10 @@ Classifier: Topic :: Home Automation
|
|
|
21
21
|
Requires-Python: >=3.13.0
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
License-File: LICENSE
|
|
24
|
-
Requires-Dist: aiohttp>=3.
|
|
25
|
-
Requires-Dist: orjson>=3.
|
|
24
|
+
Requires-Dist: aiohttp>=3.12.0
|
|
25
|
+
Requires-Dist: orjson>=3.11.0
|
|
26
26
|
Requires-Dist: python-slugify>=8.0.0
|
|
27
|
-
Requires-Dist: voluptuous>=0.
|
|
27
|
+
Requires-Dist: voluptuous>=0.15.0
|
|
28
28
|
Dynamic: license-file
|
|
29
29
|
|
|
30
30
|
[![releasebadge]][release]
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "aiohomematic"
|
|
7
|
-
dynamic = ["version"]
|
|
7
|
+
dynamic = ["version", "dependencies"]
|
|
8
8
|
license = {text = "MIT License"}
|
|
9
9
|
description = "Homematic interface for Home Assistant running on Python 3."
|
|
10
10
|
readme = "README.md"
|
|
@@ -12,7 +12,7 @@ authors = [
|
|
|
12
12
|
{name = "SukramJ", email = "sukramj@icloud.com"},
|
|
13
13
|
{name = "Daniel Perna", email = "danielperna84@gmail.com"},
|
|
14
14
|
]
|
|
15
|
-
keywords = ["home", "automation", "homematic"]
|
|
15
|
+
keywords = ["home", "automation", "homematic", "openccu", "homegear"]
|
|
16
16
|
classifiers = [
|
|
17
17
|
"Development Status :: 5 - Production/Stable",
|
|
18
18
|
"Intended Audience :: End Users/Desktop",
|
|
@@ -24,12 +24,6 @@ classifiers = [
|
|
|
24
24
|
"Topic :: Home Automation",
|
|
25
25
|
]
|
|
26
26
|
requires-python = ">=3.13.0"
|
|
27
|
-
dependencies = [
|
|
28
|
-
"aiohttp>=3.10.0",
|
|
29
|
-
"orjson>=3.10.0",
|
|
30
|
-
"python-slugify>=8.0.0",
|
|
31
|
-
"voluptuous>=0.14.0",
|
|
32
|
-
]
|
|
33
27
|
|
|
34
28
|
[project.urls]
|
|
35
29
|
"Source Code" = "https://github.com/sukramj/aiohomematic"
|
|
@@ -45,6 +39,7 @@ include-package-data = true
|
|
|
45
39
|
|
|
46
40
|
[tool.setuptools.dynamic]
|
|
47
41
|
version = {attr = "aiohomematic.const.VERSION"}
|
|
42
|
+
dependencies = { file = ["requirements.txt"] }
|
|
48
43
|
|
|
49
44
|
[tool.setuptools.packages.find]
|
|
50
45
|
include = ["aiohomematic", "aiohomematic.*"]
|
|
@@ -131,6 +126,7 @@ disable = [
|
|
|
131
126
|
"cyclic-import",
|
|
132
127
|
"duplicate-code",
|
|
133
128
|
"inconsistent-return-statements",
|
|
129
|
+
"import-outside-toplevel", # C0415
|
|
134
130
|
"locally-disabled",
|
|
135
131
|
"not-context-manager",
|
|
136
132
|
"too-few-public-methods",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/calculated/__init__.py
RENAMED
|
File without changes
|
{aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/calculated/climate.py
RENAMED
|
File without changes
|
{aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/calculated/data_point.py
RENAMED
|
File without changes
|
|
File without changes
|
{aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/calculated/support.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/binary_sensor.py
RENAMED
|
File without changes
|
|
File without changes
|
{aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/model/generic/data_point.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/rega_scripts/set_program_state.fn
RENAMED
|
File without changes
|
{aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic/rega_scripts/set_system_variable.fn
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aiohomematic-2025.10.19 → aiohomematic-2025.10.20}/aiohomematic.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|