Files
venus/axiom-nmea/debug/check_006b.py
dev 9756538f16 Initial commit: Venus OS boat addons monorepo
Organizes 11 projects for Cerbo GX/Venus OS into a single repository:
- axiom-nmea: Raymarine LightHouse protocol decoder
- dbus-generator-ramp: Generator current ramp controller
- dbus-lightning: Blitzortung lightning monitor
- dbus-meteoblue-forecast: Meteoblue weather forecast
- dbus-no-foreign-land: noforeignland.com tracking
- dbus-tides: Tide prediction from depth + harmonics
- dbus-vrm-history: VRM cloud history proxy
- dbus-windy-station: Windy.com weather upload
- mfd-custom-app: MFD app deployment package
- venus-html5-app: Custom Victron HTML5 app fork
- watermaker: Watermaker PLC control UI

Adds root README, .gitignore, project template, and per-project
.gitignore files. Sensitive config files excluded via .gitignore
with .example templates provided.

Made-with: Cursor
2026-03-16 17:04:16 +00:00

80 lines
2.4 KiB
Python

#!/usr/bin/env python3
"""Check offset 0x006b thoroughly across all packets."""
import struct
from collections import Counter
def decode_float(data, offset):
if offset + 4 > len(data):
return None
try:
val = struct.unpack('<f', data[offset:offset+4])[0]
if val != val: # NaN check
return None
return val
except:
return None
def read_pcap(filename):
packets = []
with open(filename, 'rb') as f:
header = f.read(24)
magic = struct.unpack('<I', header[0:4])[0]
swapped = magic == 0xd4c3b2a1
endian = '>' if swapped else '<'
while True:
pkt_header = f.read(16)
if len(pkt_header) < 16:
break
ts_sec, ts_usec, incl_len, orig_len = struct.unpack(f'{endian}IIII', pkt_header)
pkt_data = f.read(incl_len)
if len(pkt_data) < incl_len:
break
if len(pkt_data) > 42 and pkt_data[12:14] == b'\x08\x00':
ip_header_len = (pkt_data[14] & 0x0F) * 4
payload_start = 14 + ip_header_len + 8
if payload_start < len(pkt_data):
packets.append(pkt_data[payload_start:])
return packets
OFFSET = 0x006b
for pcap in ["raymarine_sample_twd_69-73.pcap", "raymarine_sample.pcap"]:
print(f"\n{'='*60}")
print(f"FILE: {pcap}")
print(f"OFFSET: 0x{OFFSET:04x}")
print("="*60)
packets = read_pcap(pcap)
# Group by packet size
by_size = {}
for pkt in packets:
pkt_len = len(pkt)
if pkt_len not in by_size:
by_size[pkt_len] = []
by_size[pkt_len].append(pkt)
for pkt_len in sorted(by_size.keys()):
if pkt_len < 120: # Skip small packets
continue
pkts = by_size[pkt_len]
vals = []
for pkt in pkts:
v = decode_float(pkt, OFFSET)
if v is not None:
vals.append(v)
if vals:
# Convert to degrees
degs = [v * 57.2958 for v in vals if 0 <= v <= 6.5]
if degs:
avg = sum(degs) / len(degs)
print(f" {pkt_len:5d} bytes ({len(pkts):3d} pkts): avg={avg:6.1f}°, range={min(degs):.1f}°-{max(degs):.1f}°")
else:
# Not radians - show raw
print(f" {pkt_len:5d} bytes ({len(pkts):3d} pkts): raw values (not radians)")