ramses-rf 0.22.2__py3-none-any.whl → 0.51.1__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.
- ramses_cli/__init__.py +18 -0
- ramses_cli/client.py +597 -0
- ramses_cli/debug.py +20 -0
- ramses_cli/discovery.py +405 -0
- ramses_cli/utils/cat_slow.py +17 -0
- ramses_cli/utils/convert.py +60 -0
- ramses_rf/__init__.py +31 -10
- ramses_rf/binding_fsm.py +787 -0
- ramses_rf/const.py +124 -105
- ramses_rf/database.py +297 -0
- ramses_rf/device/__init__.py +69 -39
- ramses_rf/device/base.py +187 -376
- ramses_rf/device/heat.py +540 -552
- ramses_rf/device/hvac.py +286 -171
- ramses_rf/dispatcher.py +153 -177
- ramses_rf/entity_base.py +478 -361
- ramses_rf/exceptions.py +82 -0
- ramses_rf/gateway.py +378 -514
- ramses_rf/helpers.py +57 -19
- ramses_rf/py.typed +0 -0
- ramses_rf/schemas.py +148 -194
- ramses_rf/system/__init__.py +16 -23
- ramses_rf/system/faultlog.py +363 -0
- ramses_rf/system/heat.py +295 -302
- ramses_rf/system/schedule.py +312 -198
- ramses_rf/system/zones.py +318 -238
- ramses_rf/version.py +2 -8
- ramses_rf-0.51.1.dist-info/METADATA +72 -0
- ramses_rf-0.51.1.dist-info/RECORD +55 -0
- {ramses_rf-0.22.2.dist-info → ramses_rf-0.51.1.dist-info}/WHEEL +1 -2
- ramses_rf-0.51.1.dist-info/entry_points.txt +2 -0
- {ramses_rf-0.22.2.dist-info → ramses_rf-0.51.1.dist-info/licenses}/LICENSE +1 -1
- ramses_tx/__init__.py +160 -0
- {ramses_rf/protocol → ramses_tx}/address.py +65 -59
- ramses_tx/command.py +1454 -0
- ramses_tx/const.py +903 -0
- ramses_tx/exceptions.py +92 -0
- {ramses_rf/protocol → ramses_tx}/fingerprints.py +56 -15
- {ramses_rf/protocol → ramses_tx}/frame.py +132 -131
- ramses_tx/gateway.py +338 -0
- ramses_tx/helpers.py +883 -0
- {ramses_rf/protocol → ramses_tx}/logger.py +67 -53
- {ramses_rf/protocol → ramses_tx}/message.py +155 -191
- ramses_tx/opentherm.py +1260 -0
- ramses_tx/packet.py +210 -0
- ramses_tx/parsers.py +2957 -0
- ramses_tx/protocol.py +801 -0
- ramses_tx/protocol_fsm.py +672 -0
- ramses_tx/py.typed +0 -0
- {ramses_rf/protocol → ramses_tx}/ramses.py +262 -185
- {ramses_rf/protocol → ramses_tx}/schemas.py +150 -133
- ramses_tx/transport.py +1471 -0
- ramses_tx/typed_dicts.py +492 -0
- ramses_tx/typing.py +181 -0
- ramses_tx/version.py +4 -0
- ramses_rf/discovery.py +0 -398
- ramses_rf/protocol/__init__.py +0 -59
- ramses_rf/protocol/backports.py +0 -42
- ramses_rf/protocol/command.py +0 -1561
- ramses_rf/protocol/const.py +0 -697
- ramses_rf/protocol/exceptions.py +0 -111
- ramses_rf/protocol/helpers.py +0 -390
- ramses_rf/protocol/opentherm.py +0 -1170
- ramses_rf/protocol/packet.py +0 -235
- ramses_rf/protocol/parsers.py +0 -2673
- ramses_rf/protocol/protocol.py +0 -613
- ramses_rf/protocol/transport.py +0 -1011
- ramses_rf/protocol/version.py +0 -10
- ramses_rf/system/hvac.py +0 -82
- ramses_rf-0.22.2.dist-info/METADATA +0 -64
- ramses_rf-0.22.2.dist-info/RECORD +0 -42
- ramses_rf-0.22.2.dist-info/top_level.txt +0 -1
ramses_rf/device/__init__.py
CHANGED
|
@@ -1,29 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
|
|
3
|
-
#
|
|
4
|
-
"""RAMSES RF - a RAMSES-II protocol decoder & analyser.
|
|
2
|
+
"""RAMSES RF - Heating devices (e.g. CTL, OTB, BDR, TRV)."""
|
|
5
3
|
|
|
6
|
-
Heating devices.
|
|
7
|
-
"""
|
|
8
4
|
from __future__ import annotations
|
|
9
5
|
|
|
10
6
|
import logging
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
11
8
|
|
|
12
|
-
from
|
|
13
|
-
from
|
|
14
|
-
from
|
|
9
|
+
from ramses_rf.const import DEV_TYPE_MAP
|
|
10
|
+
from ramses_tx.const import DevType
|
|
11
|
+
from ramses_tx.schemas import SZ_CLASS, SZ_FAKED
|
|
15
12
|
|
|
16
|
-
# skipcq: PY-W2000
|
|
17
|
-
from ..const import ( # noqa: F401, isort: skip, pylint: disable=unused-import
|
|
18
|
-
I_,
|
|
19
|
-
RP,
|
|
20
|
-
RQ,
|
|
21
|
-
W_,
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
# skipcq: PY-W2000
|
|
25
13
|
from .base import ( # noqa: F401, isort: skip, pylint: disable=unused-import
|
|
26
|
-
BASE_CLASS_BY_SLUG,
|
|
14
|
+
BASE_CLASS_BY_SLUG as _BASE_CLASS_BY_SLUG,
|
|
27
15
|
Device,
|
|
28
16
|
Fakeable,
|
|
29
17
|
DeviceHeat,
|
|
@@ -31,9 +19,9 @@ from .base import ( # noqa: F401, isort: skip, pylint: disable=unused-import
|
|
|
31
19
|
DeviceHvac,
|
|
32
20
|
)
|
|
33
21
|
|
|
34
|
-
|
|
22
|
+
|
|
35
23
|
from .heat import ( # noqa: F401, isort: skip, pylint: disable=unused-import
|
|
36
|
-
HEAT_CLASS_BY_SLUG,
|
|
24
|
+
HEAT_CLASS_BY_SLUG as _HEAT_CLASS_BY_SLUG,
|
|
37
25
|
BdrSwitch,
|
|
38
26
|
Controller,
|
|
39
27
|
DhwSensor,
|
|
@@ -47,9 +35,9 @@ from .heat import ( # noqa: F401, isort: skip, pylint: disable=unused-import
|
|
|
47
35
|
class_dev_heat,
|
|
48
36
|
)
|
|
49
37
|
|
|
50
|
-
|
|
38
|
+
|
|
51
39
|
from .hvac import ( # noqa: F401, isort: skip, pylint: disable=unused-import
|
|
52
|
-
HVAC_CLASS_BY_SLUG,
|
|
40
|
+
HVAC_CLASS_BY_SLUG as _HVAC_CLASS_BY_SLUG,
|
|
53
41
|
HvacCarbonDioxideSensor,
|
|
54
42
|
HvacHumiditySensor,
|
|
55
43
|
HvacRemote,
|
|
@@ -58,42 +46,82 @@ from .hvac import ( # noqa: F401, isort: skip, pylint: disable=unused-import
|
|
|
58
46
|
class_dev_hvac,
|
|
59
47
|
)
|
|
60
48
|
|
|
61
|
-
|
|
49
|
+
if TYPE_CHECKING:
|
|
50
|
+
from ramses_rf import Gateway
|
|
51
|
+
from ramses_tx import Address, Message
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
__all__ = [
|
|
55
|
+
# .base
|
|
56
|
+
"Device",
|
|
57
|
+
"Fakeable",
|
|
58
|
+
"DeviceHeat",
|
|
59
|
+
"HgiGateway",
|
|
60
|
+
"DeviceHvac",
|
|
61
|
+
# .heat
|
|
62
|
+
"BdrSwitch",
|
|
63
|
+
"Controller",
|
|
64
|
+
"DhwSensor",
|
|
65
|
+
"OtbGateway",
|
|
66
|
+
"OutSensor",
|
|
67
|
+
"Temperature",
|
|
68
|
+
"Thermostat",
|
|
69
|
+
"TrvActuator",
|
|
70
|
+
"UfhCircuit",
|
|
71
|
+
"UfhController",
|
|
72
|
+
"class_dev_heat",
|
|
73
|
+
# .hvac
|
|
74
|
+
"HvacCarbonDioxideSensor",
|
|
75
|
+
"HvacHumiditySensor",
|
|
76
|
+
"HvacRemote",
|
|
77
|
+
"HvacVentilator",
|
|
78
|
+
"RfsGateway",
|
|
79
|
+
"class_dev_hvac",
|
|
80
|
+
#
|
|
81
|
+
"best_dev_role",
|
|
82
|
+
"device_factory",
|
|
83
|
+
]
|
|
62
84
|
|
|
63
85
|
_LOGGER = logging.getLogger(__name__)
|
|
64
|
-
if DEV_MODE:
|
|
65
|
-
_LOGGER.setLevel(logging.DEBUG)
|
|
66
86
|
|
|
67
87
|
|
|
68
|
-
_CLASS_BY_SLUG =
|
|
88
|
+
_CLASS_BY_SLUG = _BASE_CLASS_BY_SLUG | _HEAT_CLASS_BY_SLUG | _HVAC_CLASS_BY_SLUG
|
|
89
|
+
|
|
90
|
+
HEAT_DEV_CLASS_BY_SLUG = {
|
|
91
|
+
k: v for k, v in _HEAT_CLASS_BY_SLUG.items() if k is not DevType.HEA
|
|
92
|
+
}
|
|
93
|
+
HVAC_DEV_CLASS_BY_SLUG = {
|
|
94
|
+
k: v for k, v in _HVAC_CLASS_BY_SLUG.items() if k is not DevType.HVC
|
|
95
|
+
}
|
|
69
96
|
|
|
70
97
|
|
|
71
98
|
def best_dev_role(
|
|
72
99
|
dev_addr: Address,
|
|
73
100
|
*,
|
|
74
|
-
msg: Message = None,
|
|
101
|
+
msg: Message | None = None,
|
|
75
102
|
eavesdrop: bool = False,
|
|
76
|
-
**schema,
|
|
103
|
+
**schema: Any,
|
|
77
104
|
) -> type[Device]:
|
|
78
105
|
"""Return the best device role (object class) for a given device id/msg/schema.
|
|
79
106
|
|
|
80
107
|
Heat (CH/DHW) devices can reliably be determined by their address type (e.g. '04:').
|
|
81
108
|
Any device without a known Heat type is considered a HVAC device.
|
|
82
109
|
|
|
83
|
-
HVAC devices must be
|
|
110
|
+
HVAC devices must be explicitly typed, or fingerprinted/eavesdropped.
|
|
84
111
|
The generic HVAC class can be promoted later on, when more information is available.
|
|
85
112
|
"""
|
|
86
113
|
|
|
87
|
-
cls:
|
|
88
|
-
slug:
|
|
114
|
+
cls: type[Device]
|
|
115
|
+
slug: str
|
|
89
116
|
|
|
90
117
|
try: # convert (say) 'dhw_sensor' to DHW
|
|
91
|
-
slug = DEV_TYPE_MAP.slug(schema.get(SZ_CLASS))
|
|
118
|
+
slug = DEV_TYPE_MAP.slug(schema.get(SZ_CLASS)) # type: ignore[arg-type]
|
|
92
119
|
except KeyError:
|
|
93
120
|
slug = schema.get(SZ_CLASS)
|
|
94
121
|
|
|
95
|
-
# a specified device class always takes
|
|
96
|
-
if
|
|
122
|
+
# a specified device class always takes precedence (even if it is wrong)...
|
|
123
|
+
if slug in _CLASS_BY_SLUG:
|
|
124
|
+
cls = _CLASS_BY_SLUG[slug]
|
|
97
125
|
_LOGGER.debug(
|
|
98
126
|
f"Using an explicitly-defined class for: {dev_addr!r} ({cls._SLUG})"
|
|
99
127
|
)
|
|
@@ -101,12 +129,12 @@ def best_dev_role(
|
|
|
101
129
|
|
|
102
130
|
if dev_addr.type == DEV_TYPE_MAP.HGI:
|
|
103
131
|
_LOGGER.debug(f"Using the default class for: {dev_addr!r} ({HgiGateway._SLUG})")
|
|
104
|
-
return HgiGateway
|
|
132
|
+
return HgiGateway
|
|
105
133
|
|
|
106
134
|
try: # or, is it a well-known CH/DHW class, derived from the device type...
|
|
107
135
|
if cls := class_dev_heat(dev_addr, msg=msg, eavesdrop=eavesdrop):
|
|
108
136
|
_LOGGER.debug(
|
|
109
|
-
f"Using the default Heat class for: {dev_addr!r} ({cls._SLUG})"
|
|
137
|
+
f"Using the default Heat class for: {dev_addr!r} ({cls._SLUG})"
|
|
110
138
|
)
|
|
111
139
|
return cls
|
|
112
140
|
except TypeError:
|
|
@@ -115,7 +143,7 @@ def best_dev_role(
|
|
|
115
143
|
try: # or, a HVAC class, eavesdropped from the message code/payload...
|
|
116
144
|
if cls := class_dev_hvac(dev_addr, msg=msg, eavesdrop=eavesdrop):
|
|
117
145
|
_LOGGER.debug(
|
|
118
|
-
f"Using eavesdropped HVAC class for: {dev_addr!r} ({cls._SLUG})"
|
|
146
|
+
f"Using eavesdropped HVAC class for: {dev_addr!r} ({cls._SLUG})"
|
|
119
147
|
)
|
|
120
148
|
return cls # includes DeviceHvac
|
|
121
149
|
except TypeError:
|
|
@@ -125,10 +153,12 @@ def best_dev_role(
|
|
|
125
153
|
_LOGGER.debug(
|
|
126
154
|
f"Using a promotable HVAC class for: {dev_addr!r} ({DeviceHvac._SLUG})"
|
|
127
155
|
)
|
|
128
|
-
return DeviceHvac
|
|
156
|
+
return DeviceHvac
|
|
129
157
|
|
|
130
158
|
|
|
131
|
-
def device_factory(
|
|
159
|
+
def device_factory(
|
|
160
|
+
gwy: Gateway, dev_addr: Address, *, msg: Message | None = None, **traits: Any
|
|
161
|
+
) -> Device:
|
|
132
162
|
"""Return the initial device class for a given device id/msg/traits.
|
|
133
163
|
|
|
134
164
|
Devices of certain classes are promotable to a compatible sub class.
|