ramses-rf 0.53.5__py3-none-any.whl → 0.53.6__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_rf/dispatcher.py +5 -1
- ramses_rf/schemas.py +2 -0
- ramses_rf/version.py +1 -1
- {ramses_rf-0.53.5.dist-info → ramses_rf-0.53.6.dist-info}/METADATA +3 -3
- {ramses_rf-0.53.5.dist-info → ramses_rf-0.53.6.dist-info}/RECORD +12 -12
- ramses_tx/protocol_fsm.py +11 -4
- ramses_tx/schemas.py +2 -0
- ramses_tx/transport.py +24 -11
- ramses_tx/version.py +1 -1
- {ramses_rf-0.53.5.dist-info → ramses_rf-0.53.6.dist-info}/WHEEL +0 -0
- {ramses_rf-0.53.5.dist-info → ramses_rf-0.53.6.dist-info}/entry_points.txt +0 -0
- {ramses_rf-0.53.5.dist-info → ramses_rf-0.53.6.dist-info}/licenses/LICENSE +0 -0
ramses_rf/dispatcher.py
CHANGED
|
@@ -270,7 +270,11 @@ def process_msg(gwy: Gateway, msg: Message) -> None:
|
|
|
270
270
|
)
|
|
271
271
|
|
|
272
272
|
except (AttributeError, LookupError, TypeError, ValueError) as err:
|
|
273
|
-
|
|
273
|
+
if getattr(gwy.config, "enforce_strict_handling", False):
|
|
274
|
+
raise
|
|
275
|
+
_LOGGER.warning(
|
|
276
|
+
"%s < %s(%s)", msg._pkt, err.__class__.__name__, err, exc_info=True
|
|
277
|
+
)
|
|
274
278
|
|
|
275
279
|
else:
|
|
276
280
|
logger_xxxx(msg)
|
ramses_rf/schemas.py
CHANGED
|
@@ -245,6 +245,7 @@ SCH_GLOBAL_SCHEMAS = vol.Schema(SCH_GLOBAL_SCHEMAS_DICT, extra=vol.PREVENT_EXTRA
|
|
|
245
245
|
# 4/7: Gateway (parser/state) configuration
|
|
246
246
|
SZ_DISABLE_DISCOVERY: Final = "disable_discovery"
|
|
247
247
|
SZ_ENABLE_EAVESDROP: Final = "enable_eavesdrop"
|
|
248
|
+
SZ_ENFORCE_STRICT_HANDLING: Final = "enforce_strict_handling"
|
|
248
249
|
SZ_MAX_ZONES: Final = "max_zones" # TODO: move to TCS-attr from GWY-layer
|
|
249
250
|
SZ_REDUCE_PROCESSING: Final = "reduce_processing"
|
|
250
251
|
SZ_USE_ALIASES: Final = "use_aliases" # use friendly device names from known_list
|
|
@@ -253,6 +254,7 @@ SZ_USE_NATIVE_OT: Final = "use_native_ot" # favour OT (3220s) over RAMSES
|
|
|
253
254
|
SCH_GATEWAY_DICT = {
|
|
254
255
|
vol.Optional(SZ_DISABLE_DISCOVERY, default=False): bool,
|
|
255
256
|
vol.Optional(SZ_ENABLE_EAVESDROP, default=False): bool,
|
|
257
|
+
vol.Optional(SZ_ENFORCE_STRICT_HANDLING, default=False): bool,
|
|
256
258
|
vol.Optional(SZ_MAX_ZONES, default=DEFAULT_MAX_ZONES): vol.All(
|
|
257
259
|
int, vol.Range(min=1, max=16)
|
|
258
260
|
), # NOTE: no default
|
ramses_rf/version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ramses_rf
|
|
3
|
-
Version: 0.53.
|
|
3
|
+
Version: 0.53.6
|
|
4
4
|
Summary: A stateful RAMSES-II protocol decoder & analyser.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ramses-rf/ramses_rf
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/ramses-rf/ramses_rf/issues
|
|
@@ -62,11 +62,11 @@ To install the `ramses_rf` command line client:
|
|
|
62
62
|
```
|
|
63
63
|
git clone https://github.com/ramses-rf/ramses_rf
|
|
64
64
|
cd ramses_rf
|
|
65
|
-
pip install -r requirements.txt
|
|
65
|
+
pip install -r requirements/requirements.txt
|
|
66
66
|
pip install -e .
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
The CLI is called
|
|
69
|
+
The CLI is called `client.py` and is included in the code root.
|
|
70
70
|
It has options to monitor and parse Ramses-II traffic to screen or a log file, and to parse a file containing Ramses-II messages to the screen.
|
|
71
71
|
See the [client.py CLI wiki page](https://github.com/ramses-rf/ramses_rf/wiki/2.-The-client.py-command-line) for instructions.
|
|
72
72
|
|
|
@@ -9,15 +9,15 @@ ramses_rf/__init__.py,sha256=AXsCK1Eh9FWeAI9D_zY_2KB0dqrTb9a5TNY1NvyQaDM,1271
|
|
|
9
9
|
ramses_rf/binding_fsm.py,sha256=fuqvcc9YW-wr8SPH8zadpPqrHAvzl_eeWF-IBtlLppY,26632
|
|
10
10
|
ramses_rf/const.py,sha256=L3z31CZ-xqno6oZp_h-67CB_5tDDqTwSWXsqRtsjMcs,5460
|
|
11
11
|
ramses_rf/database.py,sha256=eARZ8F5lcITK6d_MfvozmMxSGNkiy1kbtAh0NOIHMoc,24066
|
|
12
|
-
ramses_rf/dispatcher.py,sha256=
|
|
12
|
+
ramses_rf/dispatcher.py,sha256=pHNrXOLeAp6i9TUZEPNOB1AevlKkQyUfX2dkr-EzrDw,11517
|
|
13
13
|
ramses_rf/entity_base.py,sha256=Lv4N3dyIRfsz_5Ztgcu4bc49UE-N4c1VuN732_HQp-g,59255
|
|
14
14
|
ramses_rf/exceptions.py,sha256=mt_T7irqHSDKir6KLaf6oDglUIdrw0S40JbOrWJk5jc,3657
|
|
15
15
|
ramses_rf/gateway.py,sha256=BsS3gyFcSOCLuzQ_OxgyqHTcn2wAVsEJaV6B5PbYre0,31087
|
|
16
16
|
ramses_rf/helpers.py,sha256=TNk_QkpIOB3alOp1sqnA9LOzi4fuDCeapNlW3zTzNas,4250
|
|
17
17
|
ramses_rf/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
ramses_rf/schemas.py,sha256=
|
|
18
|
+
ramses_rf/schemas.py,sha256=k0IN2OvIgNGZ9lGkFMuM81jcjUqWvdGNfaccDBwfh_8,13672
|
|
19
19
|
ramses_rf/storage.py,sha256=ZFUhvgsWRCVS1_r6LL032XFEJwZVp1RAK8Nfba8nf7o,7052
|
|
20
|
-
ramses_rf/version.py,sha256=
|
|
20
|
+
ramses_rf/version.py,sha256=Qfhbwe6tvYg3scyTH0mknbjnE0tb-XQ19FcHCCdu8CM,125
|
|
21
21
|
ramses_rf/device/__init__.py,sha256=sUbH5dhbYFXSoM_TPFRutpRutBRpup7_cQ9smPtDTy8,4858
|
|
22
22
|
ramses_rf/device/base.py,sha256=Tu5I8Lj7KplfRsIBQAYjilS6YPgTyjpU8qgKugMR2Jk,18281
|
|
23
23
|
ramses_rf/device/heat.py,sha256=CU6GlIgjuYD21braJ_RJlS56zP47TGXNxXnZeavfEMY,54654
|
|
@@ -42,16 +42,16 @@ ramses_tx/opentherm.py,sha256=58PXz9l5x8Ou6Fm3y-R_UnGHCYahoi2RKIDdYStUMzk,42378
|
|
|
42
42
|
ramses_tx/packet.py,sha256=_nzuInS_WhdOI26SYvgsdDqIaDvVNguc2YDwdPOVCbU,7661
|
|
43
43
|
ramses_tx/parsers.py,sha256=ALUoi21ewd_GZHvxq4051AcVwETOTgVr5feWaY7zdls,148659
|
|
44
44
|
ramses_tx/protocol.py,sha256=E62vWb8qY7_SB5tb_NcywAED4d9NJJJ-1NgMaK3HG5s,33198
|
|
45
|
-
ramses_tx/protocol_fsm.py,sha256=
|
|
45
|
+
ramses_tx/protocol_fsm.py,sha256=uT0jLuTsz_6zUJSvdMG200xbYQIFgqfzJ0t3l5bTTTc,27741
|
|
46
46
|
ramses_tx/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
47
|
ramses_tx/ramses.py,sha256=89EFL91zwnArefVcEVw3KoyqF92d3r3aBoJapMNAT0I,54389
|
|
48
|
-
ramses_tx/schemas.py,sha256=
|
|
49
|
-
ramses_tx/transport.py,sha256=
|
|
48
|
+
ramses_tx/schemas.py,sha256=Bh877L2lmsrtq86ygQEnlbalcyRSEvfsjRnub-9P6X4,13495
|
|
49
|
+
ramses_tx/transport.py,sha256=W2y6em3PQytTYnREZsm2b2-FQeZQCciY2UprBa8-PM8,77057
|
|
50
50
|
ramses_tx/typed_dicts.py,sha256=w-0V5t2Q3GiNUOrRAWiW9GtSwbta_7luME6GfIb1zhI,10869
|
|
51
51
|
ramses_tx/typing.py,sha256=eF2SlPWhNhEFQj6WX2AhTXiyRQVXYnFutiepllYl2rI,5042
|
|
52
|
-
ramses_tx/version.py,sha256=
|
|
53
|
-
ramses_rf-0.53.
|
|
54
|
-
ramses_rf-0.53.
|
|
55
|
-
ramses_rf-0.53.
|
|
56
|
-
ramses_rf-0.53.
|
|
57
|
-
ramses_rf-0.53.
|
|
52
|
+
ramses_tx/version.py,sha256=wG4Me_pyFvCD82_aAFqAut5OXMh7AJllw7_gB6uBe5M,123
|
|
53
|
+
ramses_rf-0.53.6.dist-info/METADATA,sha256=RDKvYo4RMR13qU0XyXjxv9HumiHUaZeXfaWQc4SlLNs,4190
|
|
54
|
+
ramses_rf-0.53.6.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
55
|
+
ramses_rf-0.53.6.dist-info/entry_points.txt,sha256=NnyK29baOCNg8DinPYiZ368h7MTH7bgTW26z2A1NeIE,50
|
|
56
|
+
ramses_rf-0.53.6.dist-info/licenses/LICENSE,sha256=ptVutrtSMr7X-ek6LduiD8Cce4JsNn_8sR8MYlm-fvo,1086
|
|
57
|
+
ramses_rf-0.53.6.dist-info/RECORD,,
|
ramses_tx/protocol_fsm.py
CHANGED
|
@@ -145,13 +145,20 @@ class ProtocolContext:
|
|
|
145
145
|
# nope, was not successful, so multiplier should be incremented...
|
|
146
146
|
self._multiplier = min(3, old_val + 1)
|
|
147
147
|
|
|
148
|
+
if self._cmd_tx_count < 3:
|
|
149
|
+
level = logging.DEBUG
|
|
150
|
+
elif self._cmd_tx_count == 3:
|
|
151
|
+
level = logging.INFO
|
|
152
|
+
else:
|
|
153
|
+
level = logging.WARNING
|
|
154
|
+
|
|
148
155
|
if isinstance(self._state, WantEcho):
|
|
149
|
-
_LOGGER.
|
|
150
|
-
f"Timeout expired waiting for echo: {self} (delay={delay})"
|
|
156
|
+
_LOGGER.log(
|
|
157
|
+
level, f"Timeout expired waiting for echo: {self} (delay={delay})"
|
|
151
158
|
)
|
|
152
159
|
else: # isinstance(self._state, WantRply):
|
|
153
|
-
_LOGGER.
|
|
154
|
-
f"Timeout expired waiting for reply: {self} (delay={delay})"
|
|
160
|
+
_LOGGER.log(
|
|
161
|
+
level, f"Timeout expired waiting for reply: {self} (delay={delay})"
|
|
155
162
|
)
|
|
156
163
|
|
|
157
164
|
assert isinstance(self.is_sending, bool), (
|
ramses_tx/schemas.py
CHANGED
|
@@ -407,6 +407,7 @@ def select_device_filter_mode(
|
|
|
407
407
|
# 5/5: Gateway (engine) configuration
|
|
408
408
|
|
|
409
409
|
SZ_DISABLE_SENDING: Final = "disable_sending"
|
|
410
|
+
SZ_AUTOSTART: Final = "autostart"
|
|
410
411
|
SZ_DISABLE_QOS: Final = "disable_qos"
|
|
411
412
|
SZ_ENFORCE_KNOWN_LIST: Final[str] = f"enforce_{SZ_KNOWN_LIST}"
|
|
412
413
|
SZ_EVOFW_FLAG: Final = "evofw_flag"
|
|
@@ -418,6 +419,7 @@ SZ_USE_REGEX: Final = "use_regex"
|
|
|
418
419
|
|
|
419
420
|
SCH_ENGINE_DICT = {
|
|
420
421
|
vol.Optional(SZ_DISABLE_SENDING, default=False): bool,
|
|
422
|
+
vol.Optional(SZ_AUTOSTART, default=False): bool,
|
|
421
423
|
vol.Optional(SZ_DISABLE_QOS, default=None): vol.Any(
|
|
422
424
|
None, # None is selective QoS (e.g. QoS only for bindings, schedule, etc.)
|
|
423
425
|
bool,
|
ramses_tx/transport.py
CHANGED
|
@@ -1278,8 +1278,9 @@ class PortTransport(_RegHackMixin, _FullTransport, _PortTransportAbstractor): #
|
|
|
1278
1278
|
|
|
1279
1279
|
super()._close(exc)
|
|
1280
1280
|
|
|
1281
|
-
if
|
|
1282
|
-
|
|
1281
|
+
# Use getattr because _init_task may not be set if initialization failed
|
|
1282
|
+
if init_task := getattr(self, "_init_task", None):
|
|
1283
|
+
init_task.cancel()
|
|
1283
1284
|
|
|
1284
1285
|
if self._leaker_task:
|
|
1285
1286
|
self._leaker_task.cancel()
|
|
@@ -1810,6 +1811,7 @@ class CallbackTransport(_FullTransport, _CallbackTransportAbstractor):
|
|
|
1810
1811
|
protocol: RamsesProtocolT,
|
|
1811
1812
|
io_writer: Callable[[str], Awaitable[None]],
|
|
1812
1813
|
disable_sending: bool = False,
|
|
1814
|
+
autostart: bool = False,
|
|
1813
1815
|
**kwargs: Any,
|
|
1814
1816
|
) -> None:
|
|
1815
1817
|
"""Initialize the callback transport.
|
|
@@ -1820,6 +1822,8 @@ class CallbackTransport(_FullTransport, _CallbackTransportAbstractor):
|
|
|
1820
1822
|
:type io_writer: Callable[[str], Awaitable[None]]
|
|
1821
1823
|
:param disable_sending: Whether to disable sending, defaults to False.
|
|
1822
1824
|
:type disable_sending: bool, optional
|
|
1825
|
+
:param autostart: Whether to start reading immediately, defaults to False.
|
|
1826
|
+
:type autostart: bool, optional
|
|
1823
1827
|
"""
|
|
1824
1828
|
# Pass kwargs up the chain. _ReadTransport will extract 'loop' if present.
|
|
1825
1829
|
# _BaseTransport will pass 'loop' to _CallbackTransportAbstractor, which consumes it.
|
|
@@ -1834,9 +1838,11 @@ class CallbackTransport(_FullTransport, _CallbackTransportAbstractor):
|
|
|
1834
1838
|
# Section 6.1: Object Lifecycle Logging
|
|
1835
1839
|
_LOGGER.info(f"CallbackTransport created with io_writer={io_writer}")
|
|
1836
1840
|
|
|
1837
|
-
#
|
|
1838
|
-
|
|
1839
|
-
|
|
1841
|
+
# Handshake: Notify protocol immediately (Safe: idempotent)
|
|
1842
|
+
self._protocol.connection_made(self, ramses=True)
|
|
1843
|
+
|
|
1844
|
+
if autostart:
|
|
1845
|
+
self.resume_reading()
|
|
1840
1846
|
|
|
1841
1847
|
async def write_frame(self, frame: str, disable_tx_limits: bool = False) -> None:
|
|
1842
1848
|
"""Process a frame for transmission by passing it to the external writer.
|
|
@@ -1879,19 +1885,19 @@ class CallbackTransport(_FullTransport, _CallbackTransportAbstractor):
|
|
|
1879
1885
|
:type dtm: str | None, optional
|
|
1880
1886
|
"""
|
|
1881
1887
|
_LOGGER.debug(
|
|
1882
|
-
f"Received frame from external source: frame=
|
|
1888
|
+
f"Received frame from external source: frame={repr(frame)}, timestamp={dtm}"
|
|
1883
1889
|
)
|
|
1884
1890
|
|
|
1885
|
-
#
|
|
1891
|
+
# Circuit Breaker implementation (Packet gating)
|
|
1886
1892
|
if not self._reading:
|
|
1887
1893
|
_LOGGER.debug(f"Dropping received frame (transport paused): {repr(frame)}")
|
|
1888
1894
|
return
|
|
1889
1895
|
|
|
1890
1896
|
dtm = dtm or dt_now().isoformat()
|
|
1891
1897
|
|
|
1892
|
-
#
|
|
1898
|
+
# Boundary Logging (Incoming)
|
|
1893
1899
|
_LOGGER.debug(
|
|
1894
|
-
f"Ingesting frame into transport: frame=
|
|
1900
|
+
f"Ingesting frame into transport: frame={repr(frame)}, timestamp={dtm}"
|
|
1895
1901
|
)
|
|
1896
1902
|
|
|
1897
1903
|
# Pass to the standard processing pipeline
|
|
@@ -1949,7 +1955,7 @@ async def transport_factory(
|
|
|
1949
1955
|
extra: dict[str, Any] | None = None,
|
|
1950
1956
|
loop: asyncio.AbstractEventLoop | None = None,
|
|
1951
1957
|
log_all: bool = False,
|
|
1952
|
-
**kwargs: Any, # HACK: odd/misc params
|
|
1958
|
+
**kwargs: Any, # HACK: odd/misc params, inc. autostart
|
|
1953
1959
|
) -> RamsesTransportT:
|
|
1954
1960
|
"""Create and return a Ramses-specific async packet Transport.
|
|
1955
1961
|
|
|
@@ -1980,11 +1986,18 @@ async def transport_factory(
|
|
|
1980
1986
|
:raises exc.TransportSourceInvalid: If the packet source is invalid or multiple sources are specified.
|
|
1981
1987
|
"""
|
|
1982
1988
|
|
|
1989
|
+
# Extract autostart (default to False if missing), used in transport_constructor only
|
|
1990
|
+
autostart = kwargs.pop("autostart", False)
|
|
1991
|
+
|
|
1983
1992
|
# If a constructor is provided, delegate entirely to it.
|
|
1984
1993
|
if transport_constructor:
|
|
1985
1994
|
_LOGGER.debug("transport_factory: Delegating to external transport_constructor")
|
|
1986
1995
|
return await transport_constructor(
|
|
1987
|
-
protocol,
|
|
1996
|
+
protocol,
|
|
1997
|
+
disable_sending=disable_sending,
|
|
1998
|
+
extra=extra,
|
|
1999
|
+
autostart=autostart, # <--- Pass it explicitly
|
|
2000
|
+
**kwargs,
|
|
1988
2001
|
)
|
|
1989
2002
|
|
|
1990
2003
|
# kwargs are specific to a transport. The above transports have:
|
ramses_tx/version.py
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|