mirror of
https://github.com/meshcore-dev/meshcore_py.git
synced 2026-06-11 03:56:16 +00:00
add support for recv_errors in STATUS_PACKETS response
This commit is contained in:
@@ -523,7 +523,7 @@ All commands are async methods that return `Event` objects. Commands are organiz
|
|||||||
| **Statistics** ||||
|
| **Statistics** ||||
|
||||||
| `get_stats_core()` | None | `STATS_CORE` | Get core statistics (voltage, uptime, errors, queue length) |
|
| `get_stats_core()` | None | `STATS_CORE` | Get core statistics (voltage, uptime, errors, queue length) |
|
||||||
| `get_stats_radio()` | None | `STATS_RADIO` | Get radio statistics (noise floor, last RSSI/SNR, tx/rx time stats) |
|
| `get_stats_radio()` | None | `STATS_RADIO` | Get radio statistics (noise floor, last RSSI/SNR, tx/rx time stats) |
|
||||||
| `get_stats_packets()` | None | `STATS_PACKETS` | Get packet statistics (rx/tx totals, breakdown by flood vs. direct) |
|
| `get_stats_packets()` | None | `STATS_PACKETS` | Get packet statistics (rx/tx totals, flood vs. direct, recv_errors when present) |
|
||||||
| **Advanced Configuration** ||||
|
| **Advanced Configuration** ||||
|
||||||
| `set_multi_acks(multi_acks)` | `multi_acks: int` | `OK` | Set multi-acks mode (experimental ack repeats) |
|
| `set_multi_acks(multi_acks)` | `multi_acks: int` | `OK` | Set multi-acks mode (experimental ack repeats) |
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,11 @@ async def main():
|
|||||||
else:
|
else:
|
||||||
print("📦 Packet Statistics:")
|
print("📦 Packet Statistics:")
|
||||||
print(json.dumps(result.payload, indent=2))
|
print(json.dumps(result.payload, indent=2))
|
||||||
|
recv_errors = result.payload.get("recv_errors")
|
||||||
|
if recv_errors is not None:
|
||||||
|
print(f" Receive/CRC errors (RadioLib): {recv_errors}")
|
||||||
|
else:
|
||||||
|
print(" Receive/CRC errors (RadioLib): not reported (legacy 26-byte frame)")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -346,10 +346,11 @@ class MessageReader:
|
|||||||
await self.dispatcher.dispatch(Event(EventType.ERROR, {"reason": f"binary_parse_error: {e}"}))
|
await self.dispatcher.dispatch(Event(EventType.ERROR, {"reason": f"binary_parse_error: {e}"}))
|
||||||
|
|
||||||
elif stats_type == 2: # STATS_TYPE_PACKETS
|
elif stats_type == 2: # STATS_TYPE_PACKETS
|
||||||
# RESP_CODE_STATS + STATS_TYPE_PACKETS: 26 bytes total
|
# RESP_CODE_STATS + STATS_TYPE_PACKETS: 26 bytes (legacy) or 30 bytes (includes recv_errors)
|
||||||
# Format: <B B I I I I I I (response_code, stats_type, recv, sent, flood_tx, direct_tx, flood_rx, direct_rx)
|
# Format: <B B I I I I I I [I] (response_code, stats_type, recv, sent, flood_tx, direct_tx, flood_rx, direct_rx [, recv_errors])
|
||||||
|
logger.debug(f"stats packets payload len={len(data)} (expected 26 or 30)")
|
||||||
if len(data) < 26:
|
if len(data) < 26:
|
||||||
logger.error(f"Stats packets response too short: {len(data)} bytes, expected 26")
|
logger.error(f"Stats packets response too short: {len(data)} bytes, expected 26 or 30")
|
||||||
await self.dispatcher.dispatch(Event(EventType.ERROR, {"reason": "invalid_frame_length"}))
|
await self.dispatcher.dispatch(Event(EventType.ERROR, {"reason": "invalid_frame_length"}))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
@@ -362,6 +363,11 @@ class MessageReader:
|
|||||||
'flood_rx': flood_rx,
|
'flood_rx': flood_rx,
|
||||||
'direct_rx': direct_rx
|
'direct_rx': direct_rx
|
||||||
}
|
}
|
||||||
|
if len(data) >= 30:
|
||||||
|
(recv_errors,) = struct.unpack('<I', data[26:30])
|
||||||
|
res['recv_errors'] = recv_errors
|
||||||
|
else:
|
||||||
|
res['recv_errors'] = None # legacy 26-byte frame
|
||||||
logger.debug(f"parsed stats packets: {res}")
|
logger.debug(f"parsed stats packets: {res}")
|
||||||
await self.dispatcher.dispatch(Event(EventType.STATS_PACKETS, res))
|
await self.dispatcher.dispatch(Event(EventType.STATS_PACKETS, res))
|
||||||
except struct.error as e:
|
except struct.error as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user