MeshCore library exposes command methods (get_channel, send_msg,
send_advert, etc.) on mc.commands, not directly on the MeshCore
instance. Updated all DeviceManager calls accordingly.
Fixes: channels not loading, message sending, advert, battery, etc.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add _connect_with_retry() with exponential backoff (10 attempts)
- Guard against self_info being None after meshcore library disconnects
due to unresponsive device
- Prevents crash when device is busy (e.g. held by orphan container)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add _detect_serial_port() to DeviceManager — resolves 'auto' to
actual device via /dev/serial/by-id with common path fallbacks
- Make channel_idx optional in get_channel_messages() so status and
channel-updates endpoints can query across all channels
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add pkt_payload column to direct_messages table for stable packet
hash generation and Analyzer URL linking
- Update insert_direct_message() and DeviceManager to store pkt_payload
- Add test for DM pkt_payload storage (43 tests pass)
- Update watchdog to monitor only mc-webui (meshcore-bridge removed)
- USB reset trigger now fires for mc-webui container failures
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Background thread runs meshcore async event loop. Supports both
serial and TCP transports. Flask routes bridge sync→async via
execute() method. Event subscriptions marked as TODO for Phase 1.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>