This commit is contained in:
legop3
2026-05-01 18:41:10 -04:00
parent 7180d3352d
commit fa981ef298
9 changed files with 53 additions and 12 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -11,8 +11,8 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" /> <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" /> <meta name="apple-mobile-web-app-title" content="Multi Roomba Rover" />
<title>Multi Roomba Rover</title> <title>Multi Roomba Rover</title>
<script type="module" crossorigin src="/assets/index-BQtp08e2.js"></script> <script type="module" crossorigin src="/assets/index-FrukTaHm.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CGvUXLso.css"> <link rel="stylesheet" crossorigin href="/assets/index-DYarsG-0.css">
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
+10
View File
@@ -275,6 +275,13 @@ function broadcastLidarScan(payload) {
} }
} }
function broadcastLidarLine(payload) {
for (const socket of io.sockets.sockets.values()) {
if (!isVerified(socket)) continue;
socket.volatile.emit('neato:lidarLine', payload);
}
}
lidarRuntime = lidarRuntime =
brainslugHost && brainslugKey brainslugHost && brainslugKey
? createLidarRuntime({ ? createLidarRuntime({
@@ -292,6 +299,9 @@ if (lidarRuntime) {
lidarRuntime.on('scan', (payload) => { lidarRuntime.on('scan', (payload) => {
broadcastLidarScan(payload); broadcastLidarScan(payload);
}); });
lidarRuntime.on('line', (payload) => {
broadcastLidarLine(payload);
});
lidarRuntime.on('status', () => { lidarRuntime.on('status', () => {
emitUpdate(); emitUpdate();
}); });
@@ -212,6 +212,10 @@ function createLidarRuntime({ logger, host, port = 6053, key, logFile = '', shou
const lines = state[bufferKey].split(/\r?\n/); const lines = state[bufferKey].split(/\r?\n/);
state[bufferKey] = lines.pop() || ''; state[bufferKey] = lines.pop() || '';
for (const line of lines) { for (const line of lines) {
events.emit('line', {
source: sourceLabel || 'unknown',
line: sanitizeLogText(line),
});
const payload = parsePayloadFromLine(line); const payload = parsePayloadFromLine(line);
handlePayload(payload); handlePayload(payload);
} }
+2
View File
@@ -16,6 +16,7 @@ export default function VipPanel() {
const { const {
session, session,
neatoLidar, neatoLidar,
neatoLidarLines,
identifySession, identifySession,
requestVerification, requestVerification,
requestPrivateRoverAccess, requestPrivateRoverAccess,
@@ -80,6 +81,7 @@ export default function VipPanel() {
<VipNeatoCard <VipNeatoCard
neato={session?.neato || null} neato={session?.neato || null}
lidar={neatoLidar} lidar={neatoLidar}
lidarLines={neatoLidarLines}
onStart={neatoStart} onStart={neatoStart}
onSendHome={neatoSendHome} onSendHome={neatoSendHome}
onLocate={neatoLocate} onLocate={neatoLocate}
+14
View File
@@ -58,6 +58,7 @@ function buildLidarDots(points = []) {
export default function VipNeatoCard({ export default function VipNeatoCard({
neato, neato,
lidar, lidar,
lidarLines,
onStart, onStart,
onSendHome, onSendHome,
onLocate, onLocate,
@@ -84,6 +85,7 @@ export default function VipNeatoCard({
const robotError = normalizeState(neato?.telemetry?.robotError) || '--'; const robotError = normalizeState(neato?.telemetry?.robotError) || '--';
const robotAlert = normalizeState(neato?.telemetry?.robotAlert) || '--'; const robotAlert = normalizeState(neato?.telemetry?.robotAlert) || '--';
const lidarPoints = Array.isArray(lidar?.points) ? lidar.points : []; const lidarPoints = Array.isArray(lidar?.points) ? lidar.points : [];
const recentLidarLines = Array.isArray(lidarLines) ? lidarLines : [];
const lidarDots = buildLidarDots(lidarPoints); const lidarDots = buildLidarDots(lidarPoints);
const lidarStatus = normalizeState(lidar?.status) || '--'; const lidarStatus = normalizeState(lidar?.status) || '--';
const lidarDebug = lidar?.debug && typeof lidar.debug === 'object' ? lidar.debug : null; const lidarDebug = lidar?.debug && typeof lidar.debug === 'object' ? lidar.debug : null;
@@ -288,6 +290,18 @@ export default function VipNeatoCard({
<div>Rotation no scan: {lidarStats?.rotationsWithoutScan ?? '--'}</div> <div>Rotation no scan: {lidarStats?.rotationsWithoutScan ?? '--'}</div>
<div>Parseable payloads: {lidarStats?.parseablePayloads ?? '--'}</div> <div>Parseable payloads: {lidarStats?.parseablePayloads ?? '--'}</div>
<div>Point payloads: {lidarStats?.pointPayloads ?? '--'}</div> <div>Point payloads: {lidarStats?.pointPayloads ?? '--'}</div>
<div className="mt-0.5 border-t border-slate-700 pt-0.5 text-slate-400">Raw ESP lines</div>
<div className="mt-0.25 max-h-40 overflow-y-auto rounded bg-black/30 px-0.5 py-0.5 text-[0.62rem] leading-tight text-slate-300">
{recentLidarLines.length ? (
recentLidarLines.map((entry, index) => (
<div key={`${index}-${entry.source || 'line'}`} className="break-all">
<span className="text-slate-500">[{entry.source || 'line'}]</span> {entry.line}
</div>
))
) : (
<div className="text-slate-500">No raw lines yet</div>
)}
</div>
</div> </div>
) : null} ) : null}
</div> </div>
+11
View File
@@ -9,6 +9,7 @@ const INITIAL_STATE = {
connected: false, connected: false,
session: null, session: null,
neatoLidar: null, neatoLidar: null,
neatoLidarLines: [],
logs: [], logs: [],
adminLogs: [], adminLogs: [],
llmCommentaryState: null, llmCommentaryState: null,
@@ -132,9 +133,18 @@ export function SessionProvider({ children }) {
const next = payload && typeof payload === 'object' ? payload : null; const next = payload && typeof payload === 'object' ? payload : null;
setState((prev) => ({ ...prev, neatoLidar: next })); setState((prev) => ({ ...prev, neatoLidar: next }));
} }
function handleNeatoLidarLine(payload = null) {
const next = payload && typeof payload === 'object' ? payload : null;
if (!next?.line) return;
setState((prev) => ({
...prev,
neatoLidarLines: [...prev.neatoLidarLines.slice(-199), next],
}));
}
socket.on('session:sync', handleSession); socket.on('session:sync', handleSession);
socket.on('neato:lidar', handleNeatoLidar); socket.on('neato:lidar', handleNeatoLidar);
socket.on('neato:lidarLine', handleNeatoLidarLine);
socket.on('log:init', handleLogInit); socket.on('log:init', handleLogInit);
socket.on('log:entry', handleLogEntry); socket.on('log:entry', handleLogEntry);
socket.on('adminlog:init', handleAdminLogInit); socket.on('adminlog:init', handleAdminLogInit);
@@ -144,6 +154,7 @@ export function SessionProvider({ children }) {
return () => { return () => {
socket.off('session:sync', handleSession); socket.off('session:sync', handleSession);
socket.off('neato:lidar', handleNeatoLidar); socket.off('neato:lidar', handleNeatoLidar);
socket.off('neato:lidarLine', handleNeatoLidarLine);
socket.off('log:init', handleLogInit); socket.off('log:init', handleLogInit);
socket.off('log:entry', handleLogEntry); socket.off('log:entry', handleLogEntry);
socket.off('adminlog:init', handleAdminLogInit); socket.off('adminlog:init', handleAdminLogInit);