aiohomematic 2025.10.1__py3-none-any.whl → 2025.10.2__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/async_support.py +7 -7
- aiohomematic/caches/dynamic.py +31 -26
- aiohomematic/caches/persistent.py +34 -32
- aiohomematic/caches/visibility.py +19 -7
- aiohomematic/central/__init__.py +87 -74
- aiohomematic/central/decorators.py +2 -2
- aiohomematic/central/xml_rpc_server.py +27 -24
- aiohomematic/client/__init__.py +72 -56
- aiohomematic/client/_rpc_errors.py +3 -3
- aiohomematic/client/json_rpc.py +33 -25
- aiohomematic/client/xml_rpc.py +14 -9
- aiohomematic/const.py +2 -1
- aiohomematic/converter.py +19 -19
- aiohomematic/exceptions.py +2 -1
- aiohomematic/model/__init__.py +4 -3
- aiohomematic/model/calculated/__init__.py +1 -1
- aiohomematic/model/calculated/climate.py +9 -9
- aiohomematic/model/calculated/data_point.py +13 -7
- aiohomematic/model/calculated/operating_voltage_level.py +2 -2
- aiohomematic/model/calculated/support.py +7 -7
- aiohomematic/model/custom/__init__.py +3 -3
- aiohomematic/model/custom/climate.py +57 -34
- aiohomematic/model/custom/cover.py +32 -18
- aiohomematic/model/custom/data_point.py +9 -7
- aiohomematic/model/custom/definition.py +23 -17
- aiohomematic/model/custom/light.py +52 -23
- aiohomematic/model/custom/lock.py +16 -12
- aiohomematic/model/custom/siren.py +6 -3
- aiohomematic/model/custom/switch.py +3 -2
- aiohomematic/model/custom/valve.py +3 -2
- aiohomematic/model/data_point.py +62 -49
- aiohomematic/model/device.py +48 -42
- aiohomematic/model/event.py +6 -5
- aiohomematic/model/generic/__init__.py +6 -4
- aiohomematic/model/generic/action.py +1 -1
- aiohomematic/model/generic/data_point.py +7 -5
- aiohomematic/model/generic/number.py +3 -3
- aiohomematic/model/generic/select.py +1 -1
- aiohomematic/model/generic/sensor.py +2 -2
- aiohomematic/model/generic/switch.py +3 -3
- aiohomematic/model/hub/__init__.py +17 -16
- aiohomematic/model/hub/data_point.py +12 -7
- aiohomematic/model/hub/number.py +3 -3
- aiohomematic/model/hub/select.py +3 -3
- aiohomematic/model/hub/text.py +2 -2
- aiohomematic/model/support.py +8 -7
- aiohomematic/model/update.py +6 -6
- aiohomematic/support.py +44 -38
- aiohomematic/validator.py +6 -6
- {aiohomematic-2025.10.1.dist-info → aiohomematic-2025.10.2.dist-info}/METADATA +1 -1
- aiohomematic-2025.10.2.dist-info/RECORD +78 -0
- aiohomematic_support/client_local.py +19 -12
- aiohomematic-2025.10.1.dist-info/RECORD +0 -78
- {aiohomematic-2025.10.1.dist-info → aiohomematic-2025.10.2.dist-info}/WHEEL +0 -0
- {aiohomematic-2025.10.1.dist-info → aiohomematic-2025.10.2.dist-info}/licenses/LICENSE +0 -0
- {aiohomematic-2025.10.1.dist-info → aiohomematic-2025.10.2.dist-info}/top_level.txt +0 -0
|
@@ -52,7 +52,7 @@ def callback_backend_system(system_event: BackendSystemEvent) -> Callable:
|
|
|
52
52
|
central = unit.get_central(interface_id=str(args[1]))
|
|
53
53
|
if central:
|
|
54
54
|
central.looper.create_task(
|
|
55
|
-
_exec_backend_system_callback(*args, **kwargs),
|
|
55
|
+
target=_exec_backend_system_callback(*args, **kwargs),
|
|
56
56
|
name="wrapper_backend_system_callback",
|
|
57
57
|
)
|
|
58
58
|
except Exception as exc:
|
|
@@ -123,7 +123,7 @@ def callback_event[**P, R](func: Callable[P, R]) -> Callable:
|
|
|
123
123
|
unit = args[0]
|
|
124
124
|
if isinstance(unit, hmcu.CentralUnit):
|
|
125
125
|
unit.looper.create_task(
|
|
126
|
-
_async_wrap_sync(_exec_event_callback, *args, **kwargs),
|
|
126
|
+
target=_async_wrap_sync(_exec_event_callback, *args, **kwargs),
|
|
127
127
|
name="wrapper_event_callback",
|
|
128
128
|
)
|
|
129
129
|
return
|
|
@@ -27,15 +27,15 @@ _LOGGER: Final = logging.getLogger(__name__)
|
|
|
27
27
|
class RPCFunctions:
|
|
28
28
|
"""The XML-RPC functions the backend will expect."""
|
|
29
29
|
|
|
30
|
-
def __init__(self, xml_rpc_server: XmlRpcServer) -> None:
|
|
30
|
+
def __init__(self, *, xml_rpc_server: XmlRpcServer) -> None:
|
|
31
31
|
"""Init RPCFunctions."""
|
|
32
32
|
self._xml_rpc_server: Final = xml_rpc_server
|
|
33
33
|
|
|
34
|
-
def event(self, interface_id: str, channel_address: str, parameter: str, value: Any) -> None:
|
|
34
|
+
def event(self, interface_id: str, channel_address: str, parameter: str, value: Any, /) -> None:
|
|
35
35
|
"""If a device emits some sort event, we will handle it here."""
|
|
36
|
-
if central := self.get_central(interface_id):
|
|
36
|
+
if central := self.get_central(interface_id=interface_id):
|
|
37
37
|
central.looper.create_task(
|
|
38
|
-
central.data_point_event(
|
|
38
|
+
target=central.data_point_event(
|
|
39
39
|
interface_id=interface_id,
|
|
40
40
|
channel_address=channel_address,
|
|
41
41
|
parameter=parameter,
|
|
@@ -45,7 +45,7 @@ class RPCFunctions:
|
|
|
45
45
|
)
|
|
46
46
|
|
|
47
47
|
@callback_backend_system(system_event=BackendSystemEvent.ERROR)
|
|
48
|
-
def error(self, interface_id: str, error_code: str, msg: str) -> None:
|
|
48
|
+
def error(self, interface_id: str, error_code: str, msg: str, /) -> None:
|
|
49
49
|
"""When some error occurs the backend will send its error message here."""
|
|
50
50
|
# Structured boundary log (warning level). XML-RPC server received error notification.
|
|
51
51
|
try:
|
|
@@ -66,32 +66,34 @@ class RPCFunctions:
|
|
|
66
66
|
str(msg),
|
|
67
67
|
)
|
|
68
68
|
|
|
69
|
-
def listDevices(self, interface_id: str) -> list[dict[str, Any]]:
|
|
69
|
+
def listDevices(self, interface_id: str, /) -> list[dict[str, Any]]:
|
|
70
70
|
"""Return already existing devices to the backend."""
|
|
71
|
-
if central := self.get_central(interface_id):
|
|
71
|
+
if central := self.get_central(interface_id=interface_id):
|
|
72
72
|
return [dict(device_description) for device_description in central.list_devices(interface_id=interface_id)]
|
|
73
73
|
return []
|
|
74
74
|
|
|
75
|
-
def newDevices(self, interface_id: str, device_descriptions: list[dict[str, Any]]) -> None:
|
|
75
|
+
def newDevices(self, interface_id: str, device_descriptions: list[dict[str, Any]], /) -> None:
|
|
76
76
|
"""Add new devices send from the backend."""
|
|
77
77
|
central: hmcu.CentralUnit | None
|
|
78
|
-
if central := self.get_central(interface_id):
|
|
78
|
+
if central := self.get_central(interface_id=interface_id):
|
|
79
79
|
central.looper.create_task(
|
|
80
|
-
central.add_new_devices(
|
|
80
|
+
target=central.add_new_devices(
|
|
81
|
+
interface_id=interface_id, device_descriptions=tuple(device_descriptions)
|
|
82
|
+
),
|
|
81
83
|
name=f"newDevices-{interface_id}",
|
|
82
84
|
)
|
|
83
85
|
|
|
84
|
-
def deleteDevices(self, interface_id: str, addresses: list[str]) -> None:
|
|
86
|
+
def deleteDevices(self, interface_id: str, addresses: list[str], /) -> None:
|
|
85
87
|
"""Delete devices send from the backend."""
|
|
86
88
|
central: hmcu.CentralUnit | None
|
|
87
|
-
if central := self.get_central(interface_id):
|
|
89
|
+
if central := self.get_central(interface_id=interface_id):
|
|
88
90
|
central.looper.create_task(
|
|
89
|
-
central.delete_devices(interface_id=interface_id, addresses=tuple(addresses)),
|
|
91
|
+
target=central.delete_devices(interface_id=interface_id, addresses=tuple(addresses)),
|
|
90
92
|
name=f"deleteDevices-{interface_id}",
|
|
91
93
|
)
|
|
92
94
|
|
|
93
95
|
@callback_backend_system(system_event=BackendSystemEvent.UPDATE_DEVICE)
|
|
94
|
-
def updateDevice(self, interface_id: str, address: str, hint: int) -> None:
|
|
96
|
+
def updateDevice(self, interface_id: str, address: str, hint: int, /) -> None:
|
|
95
97
|
"""
|
|
96
98
|
Update a device.
|
|
97
99
|
|
|
@@ -106,7 +108,7 @@ class RPCFunctions:
|
|
|
106
108
|
)
|
|
107
109
|
|
|
108
110
|
@callback_backend_system(system_event=BackendSystemEvent.REPLACE_DEVICE)
|
|
109
|
-
def replaceDevice(self, interface_id: str, old_device_address: str, new_device_address: str) -> None:
|
|
111
|
+
def replaceDevice(self, interface_id: str, old_device_address: str, new_device_address: str, /) -> None:
|
|
110
112
|
"""Replace a device. Probably irrelevant for us."""
|
|
111
113
|
_LOGGER.debug(
|
|
112
114
|
"REPLACEDEVICE: interface_id = %s, oldDeviceAddress = %s, newDeviceAddress = %s",
|
|
@@ -116,7 +118,7 @@ class RPCFunctions:
|
|
|
116
118
|
)
|
|
117
119
|
|
|
118
120
|
@callback_backend_system(system_event=BackendSystemEvent.RE_ADDED_DEVICE)
|
|
119
|
-
def readdedDevice(self, interface_id: str, addresses: list[str]) -> None:
|
|
121
|
+
def readdedDevice(self, interface_id: str, addresses: list[str], /) -> None:
|
|
120
122
|
"""
|
|
121
123
|
Re-Add device from the backend.
|
|
122
124
|
|
|
@@ -130,9 +132,9 @@ class RPCFunctions:
|
|
|
130
132
|
str(addresses),
|
|
131
133
|
)
|
|
132
134
|
|
|
133
|
-
def get_central(self, interface_id: str) -> hmcu.CentralUnit | None:
|
|
135
|
+
def get_central(self, *, interface_id: str) -> hmcu.CentralUnit | None:
|
|
134
136
|
"""Return the central by interface_id."""
|
|
135
|
-
return self._xml_rpc_server.get_central(interface_id)
|
|
137
|
+
return self._xml_rpc_server.get_central(interface_id=interface_id)
|
|
136
138
|
|
|
137
139
|
|
|
138
140
|
# Restrict to specific paths.
|
|
@@ -159,7 +161,7 @@ class AioHomematicXMLRPCServer(SimpleXMLRPCServer):
|
|
|
159
161
|
system_listMethods(self, interface_id: str.
|
|
160
162
|
"""
|
|
161
163
|
|
|
162
|
-
def system_listMethods(self, interface_id: str | None = None) -> list[str]:
|
|
164
|
+
def system_listMethods(self, interface_id: str | None = None, /) -> list[str]:
|
|
163
165
|
"""Return a list of the methods supported by the server."""
|
|
164
166
|
return SimpleXMLRPCServer.system_listMethods(self)
|
|
165
167
|
|
|
@@ -172,6 +174,7 @@ class XmlRpcServer(threading.Thread):
|
|
|
172
174
|
|
|
173
175
|
def __init__(
|
|
174
176
|
self,
|
|
177
|
+
*,
|
|
175
178
|
ip_addr: str,
|
|
176
179
|
port: int,
|
|
177
180
|
) -> None:
|
|
@@ -192,7 +195,7 @@ class XmlRpcServer(threading.Thread):
|
|
|
192
195
|
)
|
|
193
196
|
self._simple_xml_rpc_server.register_introspection_functions()
|
|
194
197
|
self._simple_xml_rpc_server.register_multicall_functions()
|
|
195
|
-
self._simple_xml_rpc_server.register_instance(RPCFunctions(self), allow_dotted_names=True)
|
|
198
|
+
self._simple_xml_rpc_server.register_instance(RPCFunctions(xml_rpc_server=self), allow_dotted_names=True)
|
|
196
199
|
self._centrals: Final[dict[str, hmcu.CentralUnit]] = {}
|
|
197
200
|
|
|
198
201
|
def __new__(cls, ip_addr: str, port: int) -> XmlRpcServer: # noqa: PYI034
|
|
@@ -240,17 +243,17 @@ class XmlRpcServer(threading.Thread):
|
|
|
240
243
|
"""Return if thread is active."""
|
|
241
244
|
return self._started.is_set() is True # type: ignore[attr-defined]
|
|
242
245
|
|
|
243
|
-
def add_central(self, central: hmcu.CentralUnit) -> None:
|
|
246
|
+
def add_central(self, *, central: hmcu.CentralUnit) -> None:
|
|
244
247
|
"""Register a central in the XmlRPC-Server."""
|
|
245
248
|
if not self._centrals.get(central.name):
|
|
246
249
|
self._centrals[central.name] = central
|
|
247
250
|
|
|
248
|
-
def remove_central(self, central: hmcu.CentralUnit) -> None:
|
|
251
|
+
def remove_central(self, *, central: hmcu.CentralUnit) -> None:
|
|
249
252
|
"""Unregister a central from XmlRPC-Server."""
|
|
250
253
|
if self._centrals.get(central.name):
|
|
251
254
|
del self._centrals[central.name]
|
|
252
255
|
|
|
253
|
-
def get_central(self, interface_id: str) -> hmcu.CentralUnit | None:
|
|
256
|
+
def get_central(self, *, interface_id: str) -> hmcu.CentralUnit | None:
|
|
254
257
|
"""Return a central by interface_id."""
|
|
255
258
|
for central in self._centrals.values():
|
|
256
259
|
if central.has_client(interface_id=interface_id):
|
|
@@ -263,7 +266,7 @@ class XmlRpcServer(threading.Thread):
|
|
|
263
266
|
return len(self._centrals) == 0
|
|
264
267
|
|
|
265
268
|
|
|
266
|
-
def create_xml_rpc_server(ip_addr: str = IP_ANY_V4, port: int = PORT_ANY) -> XmlRpcServer:
|
|
269
|
+
def create_xml_rpc_server(*, ip_addr: str = IP_ANY_V4, port: int = PORT_ANY) -> XmlRpcServer:
|
|
267
270
|
"""Register the xml rpc server."""
|
|
268
271
|
xml_rpc = XmlRpcServer(ip_addr=ip_addr, port=port)
|
|
269
272
|
if not xml_rpc.started:
|