pi stats from roverd to webui slop

This commit is contained in:
legop3
2026-06-03 12:14:47 -04:00
parent 290985bf47
commit dd7e685934
18 changed files with 1177 additions and 131 deletions
@@ -32,6 +32,11 @@ function handleMessage(roverId, msg) {
case 'sensor':
roverManager.handleSensorFrame(roverId, msg);
break;
case 'hostStats':
// Host stats are periodic Pi metadata, not user-facing rover events, so
// they are routed directly to roverManager instead of becoming alerts.
roverManager.handleHostStats(roverId, msg);
break;
case 'event': {
const nightVisionOn = coerceBool(msg.data?.nightVisionOn);
if (msg.event === 'nightVision.state' && nightVisionOn != null) {
@@ -88,6 +93,10 @@ roverWSS.on('connection', (ws) => {
if (!roverId) return;
if (msg.type === 'sensor') {
roverManager.handleSensorFrame(roverId, msg);
} else if (msg.type === 'hostStats') {
// Keep the Pi health stream separate from both Roomba sensorFrame data
// and generic rover events, which are surfaced as alerts.
roverManager.handleHostStats(roverId, msg);
} else if (msg.type === 'ack') {
handleAck(msg);
} else if (msg.type === 'event') {
@@ -127,6 +127,7 @@ const {
getRosterForSocket,
broadcastRoster,
setNightVisionState,
handleHostStats,
canSeeRover,
canRequestControl,
} = rosterLifecycle;
@@ -244,6 +245,7 @@ module.exports = {
getRosterForSocket,
broadcastRoster,
setNightVisionState,
handleHostStats,
handleSensorFrame,
requestControl,
releaseControl,
@@ -33,6 +33,7 @@ function createRosterLifecycle(deps) {
meta: null,
ws: null,
lastSensor: null,
lastHostStats: null,
docked: null,
lastBumpAt: null,
drivers: new Set(),
@@ -269,6 +270,30 @@ function createRosterLifecycle(deps) {
managerEvents.emit('rover', { roverId, action: 'nightVision', record });
}
function handleHostStats(roverId, msg = {}) {
const record = rovers.get(roverId);
if (!record) return;
const stats = msg && typeof msg.stats === 'object' && msg.stats ? msg.stats : {};
const receivedAt = Date.now();
// Host stats describe the Pi/Linux side of a rover, so they are stored
// separately from lastSensor and emitted on their own browser event. That
// keeps raw Roomba sensor frames from becoming a mixed metadata channel.
record.lastHostStats = {
raw: msg,
stats,
receivedAt,
};
record.lastSeen = receivedAt;
io.to(record.room).volatile.emit('roverHostStats', {
roverId,
stats,
receivedAt,
});
managerEvents.emit('hostStats', { roverId, stats, receivedAt });
}
function canSeeRover(roverId, socket) {
const record = rovers.get(String(roverId));
return isRoverVisibleToSocket(record, socket);
@@ -292,6 +317,7 @@ function createRosterLifecycle(deps) {
syncSpectatorRooms,
broadcastRoster,
setNightVisionState,
handleHostStats,
canSeeRover,
canRequestControl,
};