python-mobius 0.10.2__py3-none-any.whl → 0.10.3__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.
- mobius/__init__.py +1 -1
- mobius/device.py +29 -0
- {python_mobius-0.10.2.dist-info → python_mobius-0.10.3.dist-info}/METADATA +1 -1
- {python_mobius-0.10.2.dist-info → python_mobius-0.10.3.dist-info}/RECORD +7 -7
- {python_mobius-0.10.2.dist-info → python_mobius-0.10.3.dist-info}/WHEEL +0 -0
- {python_mobius-0.10.2.dist-info → python_mobius-0.10.3.dist-info}/entry_points.txt +0 -0
- {python_mobius-0.10.2.dist-info → python_mobius-0.10.3.dist-info}/licenses/LICENSE +0 -0
mobius/__init__.py
CHANGED
mobius/device.py
CHANGED
|
@@ -12,6 +12,7 @@ from __future__ import annotations
|
|
|
12
12
|
import asyncio
|
|
13
13
|
import datetime
|
|
14
14
|
import struct
|
|
15
|
+
import logging
|
|
15
16
|
import time
|
|
16
17
|
from dataclasses import dataclass, field
|
|
17
18
|
from typing import Optional, Callable, Any
|
|
@@ -79,6 +80,8 @@ CHAR_TX_DATA = "01ff0103-ba5e-f4ee-5ca1-eb1e5e4b1ce0" # write: app -> device,
|
|
|
79
80
|
CHAR_TX_FINAL = "01ff0104-ba5e-f4ee-5ca1-eb1e5e4b1ce0" # write: app -> device, last fragment
|
|
80
81
|
|
|
81
82
|
# count=0xFFFF requests every element of a list attribute.
|
|
83
|
+
_LOGGER = logging.getLogger(__name__)
|
|
84
|
+
|
|
82
85
|
ALL_ELEMENTS = 0xFFFF
|
|
83
86
|
|
|
84
87
|
# Write fragment size when the ATT MTU is unknown or the minimum (23).
|
|
@@ -87,6 +90,23 @@ DEFAULT_WRITE_SIZE = 20
|
|
|
87
90
|
MTU_WRITE_OVERHEAD = 5
|
|
88
91
|
|
|
89
92
|
|
|
93
|
+
def _log_bad_frame(raw: bytes, frame, trace: list[tuple[str, int]]) -> None:
|
|
94
|
+
"""Debug details of a received frame that doesn't parse or fails its
|
|
95
|
+
CRC: what was received against what its header declares, and the
|
|
96
|
+
notifications it was assembled from (D = RX_DATA, F = RX_FINAL)."""
|
|
97
|
+
if not _LOGGER.isEnabledFor(logging.DEBUG):
|
|
98
|
+
return
|
|
99
|
+
declared = struct.unpack_from("<H", raw, 7)[0] + 11 if len(raw) >= 9 else None
|
|
100
|
+
pieces = " ".join(f"{kind}{length}" for kind, length in trace)
|
|
101
|
+
_LOGGER.debug(
|
|
102
|
+
"Received a frame that %s: %d bytes, header declares %s; op_group=%s op_code=%s msg_id=%s; "
|
|
103
|
+
"%d notifications [%s]; first bytes %s; last bytes %s",
|
|
104
|
+
"doesn't parse" if frame is None else "fails its CRC", len(raw), declared,
|
|
105
|
+
f"{frame.op_group:#04x}" if frame else "?", frame.op_code if frame else "?",
|
|
106
|
+
frame.message_id if frame else "?", len(trace), pieces, raw[:24].hex(), raw[-24:].hex(),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
|
|
90
110
|
def write_size_for_mtu(att_mtu: Optional[int]) -> int:
|
|
91
111
|
"""Write fragment size for a negotiated ATT MTU: `att_mtu` minus 5, as
|
|
92
112
|
the app does, or DEFAULT_WRITE_SIZE when it is unknown or not above the
|
|
@@ -917,6 +937,9 @@ class MobiusDevice:
|
|
|
917
937
|
self.adapter = adapter
|
|
918
938
|
self._client: Optional[BleakClient] = None
|
|
919
939
|
self._rx_buffer = bytearray()
|
|
940
|
+
# ("D"/"F", length) of each notification of the frame being
|
|
941
|
+
# received, logged when it fails its CRC.
|
|
942
|
+
self._rx_trace: list[tuple[str, int]] = []
|
|
920
943
|
# Pending direct requests, keyed by FSCI message ID.
|
|
921
944
|
self._pending: dict[int, asyncio.Future] = {}
|
|
922
945
|
# Pending relayed requests, keyed by CoAP token (see mobius.relay).
|
|
@@ -1014,12 +1037,18 @@ class MobiusDevice:
|
|
|
1014
1037
|
|
|
1015
1038
|
def _on_rx_data(self, _handle, data: bytearray):
|
|
1016
1039
|
self._rx_buffer.extend(data)
|
|
1040
|
+
self._rx_trace.append(("D", len(data)))
|
|
1017
1041
|
|
|
1018
1042
|
def _on_rx_final(self, _handle, data: bytearray):
|
|
1019
1043
|
self._rx_buffer.extend(data)
|
|
1044
|
+
self._rx_trace.append(("F", len(data)))
|
|
1020
1045
|
raw = bytes(self._rx_buffer)
|
|
1046
|
+
trace = self._rx_trace
|
|
1021
1047
|
self._rx_buffer.clear()
|
|
1048
|
+
self._rx_trace = []
|
|
1022
1049
|
frame = parse_frame(raw)
|
|
1050
|
+
if frame is None or not frame.crc_ok:
|
|
1051
|
+
_log_bad_frame(raw, frame, trace)
|
|
1023
1052
|
if frame is None:
|
|
1024
1053
|
return
|
|
1025
1054
|
if self.on_any_frame is not None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: python-mobius
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.3
|
|
4
4
|
Summary: Reverse-engineered Python client for the Mobius BLE protocol (EcoTech Marine VorTech/Radion, AquaIllumination, Neptune Systems, NYOS)
|
|
5
5
|
Project-URL: Homepage, https://code.r3pek.org/r3pek/python-mobius
|
|
6
6
|
Project-URL: Documentation, https://code.r3pek.org/r3pek/python-mobius/src/branch/main/documentation
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
mobius/__init__.py,sha256=
|
|
1
|
+
mobius/__init__.py,sha256=vXZoC15RSsPkTLgOhdRb6T0zjIuL4KX_PByrCGlUzuY,8555
|
|
2
2
|
mobius/checksums.py,sha256=PB9RqvaZu9AqfT6tU6NI2qbbZXrqaHUnow3Qi_6UFHs,5191
|
|
3
3
|
mobius/cli.py,sha256=tyft0SzbuLgbmzps-Ym1hCzcr6A9D5MsALkg6o4ynBs,57876
|
|
4
4
|
mobius/coap.py,sha256=-XV3kI4q-JoL8r0oLFNnHAdZAc_yUP-aICagKh-qbf4,4862
|
|
5
5
|
mobius/constants.py,sha256=pcG9Su_b81pmMA_GxR41lZz9UM9BjtV0T6nuslMICko,41138
|
|
6
6
|
mobius/crc.py,sha256=LOCHZe3a1UnR5thdpZ4S4SFP8BdmoMEnhDNiNMd0iJI,2508
|
|
7
|
-
mobius/device.py,sha256=
|
|
7
|
+
mobius/device.py,sha256=fIoN0YvF0VE85Ln0hHMqqGW7SxRDMbyEqLDH3jNH_xY,134445
|
|
8
8
|
mobius/device_status.py,sha256=XclYijAknrgT8SdSW4XvyBemWHUQqw6UPE4tmwq6Yug,15658
|
|
9
9
|
mobius/discovery.py,sha256=poNeXGekB44cpHOFbGyps9d4mwW_hJptmJODwSMTUSg,7176
|
|
10
10
|
mobius/dump.py,sha256=eQBYoi8J6CxRd2ojgWK5QoB8z416oywLRTBnnh0pLwo,9253
|
|
@@ -19,8 +19,8 @@ mobius/relay.py,sha256=trGkWQSarwURF05gXHeb5jTJ9UvWbQGu8NarEP6sRqE,10107
|
|
|
19
19
|
mobius/scenes.py,sha256=VLfDdTKSv3qTsBt2bJGg8iPtUkfNEmNgu0TTtYT6jJE,4274
|
|
20
20
|
mobius/schedule.py,sha256=si9uJdYOj5vh6owuxxMyMyZRY0-tAmCPt3s6ROAeRww,13243
|
|
21
21
|
mobius/timezone.py,sha256=Q7oPKtCdEYcEHXLx4lt-VPq6KH-MNgQwVnDtIXJV-kQ,2267
|
|
22
|
-
python_mobius-0.10.
|
|
23
|
-
python_mobius-0.10.
|
|
24
|
-
python_mobius-0.10.
|
|
25
|
-
python_mobius-0.10.
|
|
26
|
-
python_mobius-0.10.
|
|
22
|
+
python_mobius-0.10.3.dist-info/METADATA,sha256=XZMR0-mC2Ph-T0tOxBn_Gl3hPEXzmRcwjim4Nem0QMs,5829
|
|
23
|
+
python_mobius-0.10.3.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
24
|
+
python_mobius-0.10.3.dist-info/entry_points.txt,sha256=Q2hlcek-bWm70zvd12v32essflPgC2su-dKDHAqbPoE,48
|
|
25
|
+
python_mobius-0.10.3.dist-info/licenses/LICENSE,sha256=7a72Msu2Q-TnoiFxemxEGkwafJGObk1W3rw9hzmyM_Y,17984
|
|
26
|
+
python_mobius-0.10.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|