mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-03-28 17:42:45 +01:00
fix(v2): Serial port auto-detection and channel_messages query
- 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>
This commit is contained in:
@@ -194,36 +194,31 @@ class Database:
|
||||
)
|
||||
return cursor.lastrowid
|
||||
|
||||
def get_channel_messages(self, channel_idx: int, limit: int = 50,
|
||||
def get_channel_messages(self, channel_idx: int = None, limit: int = 50,
|
||||
offset: int = 0, days: int = None) -> List[Dict]:
|
||||
with self._connect() as conn:
|
||||
query = "SELECT * FROM channel_messages WHERE channel_idx = ?"
|
||||
params: list = [channel_idx]
|
||||
conditions = []
|
||||
params: list = []
|
||||
|
||||
if channel_idx is not None:
|
||||
conditions.append("channel_idx = ?")
|
||||
params.append(channel_idx)
|
||||
|
||||
if days is not None and days > 0:
|
||||
cutoff = int((datetime.now() - timedelta(days=days)).timestamp())
|
||||
query += " AND timestamp >= ?"
|
||||
conditions.append("timestamp >= ?")
|
||||
params.append(cutoff)
|
||||
|
||||
query += " ORDER BY timestamp ASC"
|
||||
where = (" WHERE " + " AND ".join(conditions)) if conditions else ""
|
||||
|
||||
if limit > 0:
|
||||
# Get the last N messages (most recent) with offset
|
||||
query = f"""SELECT * FROM ({query} LIMIT -1 OFFSET ?)
|
||||
ORDER BY timestamp ASC"""
|
||||
# We need a subquery approach to get "last N"
|
||||
# Simpler: reverse order, limit, then re-reverse
|
||||
query = """SELECT * FROM (
|
||||
SELECT * FROM channel_messages
|
||||
WHERE channel_idx = ?"""
|
||||
params = [channel_idx]
|
||||
if days is not None and days > 0:
|
||||
cutoff = int((datetime.now() - timedelta(days=days)).timestamp())
|
||||
query += " AND timestamp >= ?"
|
||||
params.append(cutoff)
|
||||
query += " ORDER BY timestamp DESC LIMIT ? OFFSET ?"
|
||||
if limit and limit > 0:
|
||||
query = f"""SELECT * FROM (
|
||||
SELECT * FROM channel_messages{where}
|
||||
ORDER BY timestamp DESC LIMIT ? OFFSET ?
|
||||
) ORDER BY timestamp ASC"""
|
||||
params.extend([limit, offset])
|
||||
query += ") ORDER BY timestamp ASC"
|
||||
else:
|
||||
query = f"SELECT * FROM channel_messages{where} ORDER BY timestamp ASC"
|
||||
|
||||
rows = conn.execute(query, params).fetchall()
|
||||
return [dict(r) for r in rows]
|
||||
|
||||
@@ -74,6 +74,33 @@ class DeviceManager:
|
||||
self._loop.run_until_complete(self._connect())
|
||||
self._loop.run_forever()
|
||||
|
||||
def _detect_serial_port(self) -> str:
|
||||
"""Auto-detect serial port when configured as 'auto'."""
|
||||
port = self.config.MC_SERIAL_PORT
|
||||
if port.lower() != 'auto':
|
||||
return port
|
||||
|
||||
from pathlib import Path
|
||||
by_id = Path('/dev/serial/by-id')
|
||||
if by_id.exists():
|
||||
devices = list(by_id.iterdir())
|
||||
if len(devices) == 1:
|
||||
resolved = str(devices[0].resolve())
|
||||
logger.info(f"Auto-detected serial port: {resolved}")
|
||||
return resolved
|
||||
elif len(devices) > 1:
|
||||
logger.warning(f"Multiple serial devices found: {[d.name for d in devices]}")
|
||||
else:
|
||||
logger.warning("No serial devices found in /dev/serial/by-id")
|
||||
|
||||
# Fallback: try common paths
|
||||
for candidate in ['/dev/ttyUSB0', '/dev/ttyACM0', '/dev/ttyUSB1', '/dev/ttyACM1']:
|
||||
if Path(candidate).exists():
|
||||
logger.info(f"Auto-detected serial port (fallback): {candidate}")
|
||||
return candidate
|
||||
|
||||
raise RuntimeError("No serial port detected. Set MC_SERIAL_PORT explicitly.")
|
||||
|
||||
async def _connect(self):
|
||||
"""Connect to device via serial or TCP and subscribe to events."""
|
||||
from meshcore import MeshCore
|
||||
@@ -87,9 +114,10 @@ class DeviceManager:
|
||||
auto_reconnect=self.config.MC_AUTO_RECONNECT,
|
||||
)
|
||||
else:
|
||||
logger.info(f"Connecting via serial: {self.config.MC_SERIAL_PORT}")
|
||||
port = self._detect_serial_port()
|
||||
logger.info(f"Connecting via serial: {port}")
|
||||
self.mc = await MeshCore.create_serial(
|
||||
port=self.config.MC_SERIAL_PORT,
|
||||
port=port,
|
||||
auto_reconnect=self.config.MC_AUTO_RECONNECT,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user