mirror of
https://github.com/smittix/intercept.git
synced 2026-07-26 09:48:09 -07:00
fix: meshcore serial connection and battery calculation issues
- Fix _pollUntilConnected overwriting real error with generic timeout message — stop polling once backend reaches error state - Fix battery % calculation: was battery_mv/42 (71% at empty); now (battery_mv-3000)/12 for a proper 0-100% LiPo curve - Improve auto-detect: scan available ports rather than blindly using /dev/ttyUSB0; update label to show fallback so users know what to expect - Add port refresh button (↻) — previously required switching modes and back if device was plugged in after panel opened - Add baud rate selector to serial config strip (default 115200, options up to 921600) and wire it through to the connect request Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -79,6 +79,7 @@ const MeshCore = (function () {
|
|||||||
let body = { transport: _transport };
|
let body = { transport: _transport };
|
||||||
if (_transport === 'serial') {
|
if (_transport === 'serial') {
|
||||||
body.port = document.getElementById('meshcorePortSelect').value || null;
|
body.port = document.getElementById('meshcorePortSelect').value || null;
|
||||||
|
body.baud = parseInt(document.getElementById('meshcoreBaudSelect')?.value || '115200', 10);
|
||||||
} else if (_transport === 'tcp') {
|
} else if (_transport === 'tcp') {
|
||||||
body.host = document.getElementById('meshcoreTcpHost').value;
|
body.host = document.getElementById('meshcoreTcpHost').value;
|
||||||
body.port = parseInt(document.getElementById('meshcoreTcpPort').value, 10);
|
body.port = parseInt(document.getElementById('meshcoreTcpPort').value, 10);
|
||||||
@@ -98,13 +99,20 @@ const MeshCore = (function () {
|
|||||||
function _pollUntilConnected(attempts) {
|
function _pollUntilConnected(attempts) {
|
||||||
if (_connected) return;
|
if (_connected) return;
|
||||||
if (attempts > 45) {
|
if (attempts > 45) {
|
||||||
// Backend retry window (5+15+45s) has elapsed — give up
|
// Backend retry window (5+15+45s) has elapsed — give up only if
|
||||||
|
// the backend hasn't already reported a real error (which would
|
||||||
|
// have been shown by _updateStatusUI and we don't want to overwrite).
|
||||||
|
const dot = document.getElementById('meshcoreStatusDot');
|
||||||
|
if (dot && dot.classList.contains('error')) return;
|
||||||
_updateStatusUI('error', 'Connection timed out');
|
_updateStatusUI('error', 'Connection timed out');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
await _checkStatus();
|
await _checkStatus();
|
||||||
if (!_connected) _pollUntilConnected(attempts + 1);
|
// Stop polling once the backend has settled into a terminal state
|
||||||
|
const dot = document.getElementById('meshcoreStatusDot');
|
||||||
|
const inTerminal = dot && dot.classList.contains('error');
|
||||||
|
if (!_connected && !inTerminal) _pollUntilConnected(attempts + 1);
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +131,7 @@ const MeshCore = (function () {
|
|||||||
const sel = document.getElementById('meshcorePortSelect');
|
const sel = document.getElementById('meshcorePortSelect');
|
||||||
if (!sel) return;
|
if (!sel) return;
|
||||||
const current = sel.value;
|
const current = sel.value;
|
||||||
sel.innerHTML = '<option value="">Auto-detect</option>';
|
sel.innerHTML = '<option value="">Auto-detect (/dev/ttyUSB0)</option>';
|
||||||
(d.ports || []).forEach(p => {
|
(d.ports || []).forEach(p => {
|
||||||
const o = document.createElement('option');
|
const o = document.createElement('option');
|
||||||
o.value = p; o.textContent = p;
|
o.value = p; o.textContent = p;
|
||||||
@@ -133,6 +141,10 @@ const MeshCore = (function () {
|
|||||||
} catch (e) { /* ignore */ }
|
} catch (e) { /* ignore */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function refreshPorts() {
|
||||||
|
await _loadPorts();
|
||||||
|
}
|
||||||
|
|
||||||
async function scanBle() {
|
async function scanBle() {
|
||||||
const btn = document.querySelector('[onclick="MeshCore.scanBle()"]');
|
const btn = document.querySelector('[onclick="MeshCore.scanBle()"]');
|
||||||
const sel = document.getElementById('meshcoreBleSelect');
|
const sel = document.getElementById('meshcoreBleSelect');
|
||||||
@@ -522,6 +534,7 @@ const MeshCore = (function () {
|
|||||||
connect,
|
connect,
|
||||||
disconnect,
|
disconnect,
|
||||||
selectTransport,
|
selectTransport,
|
||||||
|
refreshPorts,
|
||||||
scanBle,
|
scanBle,
|
||||||
sendMessage,
|
sendMessage,
|
||||||
switchTab,
|
switchTab,
|
||||||
|
|||||||
@@ -22,6 +22,13 @@
|
|||||||
<select id="meshcorePortSelect" class="meshcore-strip-select">
|
<select id="meshcorePortSelect" class="meshcore-strip-select">
|
||||||
<option value="">Auto-detect</option>
|
<option value="">Auto-detect</option>
|
||||||
</select>
|
</select>
|
||||||
|
<button class="meshcore-strip-btn" onclick="MeshCore.refreshPorts()" title="Refresh port list">↻</button>
|
||||||
|
<select id="meshcoreBaudSelect" class="meshcore-strip-select" style="width:90px;">
|
||||||
|
<option value="115200" selected>115200</option>
|
||||||
|
<option value="921600">921600</option>
|
||||||
|
<option value="57600">57600</option>
|
||||||
|
<option value="38400">38400</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div id="meshcoreTcpConfig" class="meshcore-strip-group" style="display:none;">
|
<div id="meshcoreTcpConfig" class="meshcore-strip-group" style="display:none;">
|
||||||
<input id="meshcoreTcpHost" type="text" placeholder="Host / IP" value="localhost" class="meshcore-strip-input" style="width:120px;">
|
<input id="meshcoreTcpHost" type="text" placeholder="Host / IP" value="localhost" class="meshcore-strip-input" style="width:120px;">
|
||||||
|
|||||||
@@ -100,7 +100,15 @@ class AsyncWorker:
|
|||||||
cfg = self._config
|
cfg = self._config
|
||||||
|
|
||||||
if isinstance(cfg, SerialConfig):
|
if isinstance(cfg, SerialConfig):
|
||||||
port = cfg.port or "/dev/ttyUSB0"
|
from utils.meshcore import list_serial_ports
|
||||||
|
|
||||||
|
if cfg.port:
|
||||||
|
port = cfg.port
|
||||||
|
else:
|
||||||
|
# Auto-detect: prefer ttyUSB0, then first available port
|
||||||
|
candidates = list_serial_ports()
|
||||||
|
port = next((p for p in candidates if "ttyUSB0" in p), None) or \
|
||||||
|
(candidates[0] if candidates else "/dev/ttyUSB0")
|
||||||
self._mc = await MeshCore.create_serial(port=port, baudrate=cfg.baud, debug=False)
|
self._mc = await MeshCore.create_serial(port=port, baudrate=cfg.baud, debug=False)
|
||||||
transport, device = "serial", port
|
transport, device = "serial", port
|
||||||
elif isinstance(cfg, TCPConfig):
|
elif isinstance(cfg, TCPConfig):
|
||||||
@@ -205,7 +213,8 @@ class AsyncWorker:
|
|||||||
p = event.payload
|
p = event.payload
|
||||||
node_id = "self" # stats_core is always for the local node
|
node_id = "self" # stats_core is always for the local node
|
||||||
battery_mv = p.get("battery_mv")
|
battery_mv = p.get("battery_mv")
|
||||||
battery_pct = min(int(battery_mv / 42), 100) if battery_mv else None # rough: 4200mv = 100%
|
# LiPo linear approximation: 3000mV = 0%, 4200mV = 100%
|
||||||
|
battery_pct = max(0, min(int((battery_mv - 3000) / 12), 100)) if battery_mv else None
|
||||||
t = MeshcoreTelemetry(
|
t = MeshcoreTelemetry(
|
||||||
node_id=node_id,
|
node_id=node_id,
|
||||||
timestamp=datetime.now(timezone.utc),
|
timestamp=datetime.now(timezone.utc),
|
||||||
|
|||||||
Reference in New Issue
Block a user