From 33f1e66b62e1f95727b24e312bc2405c53e28e63 Mon Sep 17 00:00:00 2001 From: legop3 Date: Tue, 5 May 2026 22:45:08 -0400 Subject: [PATCH] neato lidar antispam --- server/src/services/neatoService/index.js | 16 +++++++++++++++- server/src/services/neatoService/lidarRuntime.js | 16 +++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/server/src/services/neatoService/index.js b/server/src/services/neatoService/index.js index 4aa92358..ff2b9f80 100644 --- a/server/src/services/neatoService/index.js +++ b/server/src/services/neatoService/index.js @@ -28,6 +28,7 @@ function normalizeDeviceName(value) { const device = normalizeDeviceName(neatoConfig.device); const RESUME_DELAY_MS = 3000; +const OFFLINE_LIDAR_RETRY_MS = 10000; const brainslugHost = String(neatoConfig.brainslugHost || '').trim(); const brainslugPort = Number(neatoConfig.brainslugPort) || 6053; const brainslugKey = String(neatoConfig.brainslugKey || '').trim(); @@ -283,7 +284,20 @@ lidarRuntime = port: brainslugPort, key: brainslugKey, logFile: brainslugLogFile, - shouldPoll: () => Boolean(homeAssistantEnabled && isHomeAssistantConnected() && hasVerifiedSockets()), + getPollReadiness: () => { + const verifiedSockets = hasVerifiedSockets(); + if (!verifiedSockets) { + return { allowed: false, delayMs: 1000 }; + } + if (!homeAssistantEnabled || !isHomeAssistantConnected()) { + return { allowed: false, delayMs: OFFLINE_LIDAR_RETRY_MS }; + } + const neatoOnline = buildState().connected; + if (!neatoOnline) { + return { allowed: false, delayMs: OFFLINE_LIDAR_RETRY_MS }; + } + return { allowed: true, delayMs: 0 }; + }, requestScan: requestLidarScan, }) : null; diff --git a/server/src/services/neatoService/lidarRuntime.js b/server/src/services/neatoService/lidarRuntime.js index 2d7f7429..62608d63 100644 --- a/server/src/services/neatoService/lidarRuntime.js +++ b/server/src/services/neatoService/lidarRuntime.js @@ -5,6 +5,8 @@ const fs = require('fs'); const SCAN_TIMEOUT_MS = 8000; const RECONNECT_DELAY_MS = 5000; const IDLE_RETRY_MS = 1000; +const OFFLINE_RETRY_MS = 10000; +const REQUEST_FAILURE_RETRY_MS = 10000; function sanitizeLogText(value) { return String(value || '') @@ -56,7 +58,7 @@ function parseRotationSpeed(payload) { return Number(match[1]); } -function createLidarRuntime({ logger, host, port = 6053, key, logFile = '', shouldPoll, requestScan }) { +function createLidarRuntime({ logger, host, port = 6053, key, logFile = '', shouldPoll, getPollReadiness, requestScan }) { const events = new EventEmitter(); const state = { connected: false, @@ -341,11 +343,15 @@ function createLidarRuntime({ logger, host, port = 6053, key, logFile = '', shou async function tickPoll() { if (!state.connected) { - schedulePollRetry(); + schedulePollRetry(OFFLINE_RETRY_MS); return; } - if (!shouldPoll?.()) { - schedulePollRetry(); + const readiness = + typeof getPollReadiness === 'function' + ? getPollReadiness() + : { allowed: shouldPoll?.() !== false, delayMs: IDLE_RETRY_MS }; + if (!readiness?.allowed) { + schedulePollRetry(Number(readiness?.delayMs) || OFFLINE_RETRY_MS); return; } if (state.requestInFlight) return; @@ -364,7 +370,7 @@ function createLidarRuntime({ logger, host, port = 6053, key, logFile = '', shou } catch (err) { logger.warn('Failed to request Neato lidar scan', err.message); resetScanState(); - triggerPollSoon(); + schedulePollRetry(REQUEST_FAILURE_RETRY_MS); } }