From 02a32e252495e951741f325e0daa901b4230c5e3 Mon Sep 17 00:00:00 2001 From: legop3 Date: Sat, 12 Sep 2026 17:04:21 -0400 Subject: [PATCH] fix help while docked lol --- .../src/services/roverHelpService/monitor.js | 22 ++++++++++- .../services/roverHelpService/monitor.test.js | 38 +++++++++++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/server/src/services/roverHelpService/monitor.js b/server/src/services/roverHelpService/monitor.js index b8e74f09..22504f35 100644 --- a/server/src/services/roverHelpService/monitor.js +++ b/server/src/services/roverHelpService/monitor.js @@ -62,6 +62,25 @@ function createRoverHelpMonitor({ now = () => Date.now(), onChange = () => {} } if (!roverId || !sensors) return; const state = ensureState(roverId); const timestamp = now(); + const docked = Boolean(sensors?.chargingSources?.homeBase); + + if (docked) { + // A 600-series Roomba can legitimately rest on the dock with wheel-drop + // or cliff bits held by its physical position and the nearby surface. + // Home-base contact is therefore a stronger signal than every monitored + // fault here: reset all persistence history and do not let time spent + // docked contribute toward a later HELP after it leaves the base. + state.wheelDropSince = null; + state.cliffPattern = 0; + state.cliffPatternSince = null; + state.dockGuardSince = null; + state.dockGuardSawPassive = false; + updateReason(roverId, state, 'wheelDrop', false); + updateReason(roverId, state, 'cliff', false); + updateReason(roverId, state, 'docking', false); + return; + } + const wheelDrop = Boolean( sensors?.bumpsAndWheelDrops?.wheelDropLeft || sensors?.bumpsAndWheelDrops?.wheelDropRight, ); @@ -97,10 +116,9 @@ function createRoverHelpMonitor({ now = () => Date.now(), onChange = () => {} } ); if (state.dockGuardSince != null) { - const docked = Boolean(sensors?.chargingSources?.homeBase); const oiMode = sensors?.oiMode?.label || null; if (oiMode === 'passive') state.dockGuardSawPassive = true; - if (docked || (state.dockGuardSawPassive && oiMode && oiMode !== 'passive')) { + if (state.dockGuardSawPassive && oiMode && oiMode !== 'passive') { // Dock guard itself stops as soon as the 600-series wheels begin their // autonomous seek motion. Continue timing that seek after the guard // interval ends, and clear only on docking or a confirmed exit from the diff --git a/server/src/services/roverHelpService/monitor.test.js b/server/src/services/roverHelpService/monitor.test.js index b88aec70..debce9d2 100644 --- a/server/src/services/roverHelpService/monitor.test.js +++ b/server/src/services/roverHelpService/monitor.test.js @@ -97,3 +97,41 @@ test('clearing one reason retains help while another reason remains', () => { assert.equal(harness.changes.at(-1).needsHelp, true); assert.deepEqual(harness.changes.at(-1).reasons, ['cliff']); }); + +test('docked sensor conditions never accumulate help time', () => { + const harness = createHarness(); + const dockedFaults = { + chargingSources: { homeBase: true }, + bumpsAndWheelDrops: { wheelDropLeft: true }, + cliffLeft: true, + }; + harness.monitor.handleSensor('purple', dockedFaults); + harness.advance(WHEEL_DROP_HELP_MS + CLIFF_HELP_MS); + harness.monitor.handleSensor('purple', dockedFaults); + assert.equal(harness.changes.length, 0); + + // Leaving the dock begins fresh timers instead of inheriting the long period + // during which those same physical bits were harmlessly held at home base. + harness.monitor.handleSensor('purple', { + chargingSources: {}, + bumpsAndWheelDrops: { wheelDropLeft: true }, + cliffLeft: true, + }); + assert.equal(harness.changes.length, 0); +}); + +test('docking clears every active help reason', () => { + const harness = createHarness(); + const faults = { bumpsAndWheelDrops: { wheelDropRight: true }, cliffRight: true }; + harness.monitor.handleSensor('silver', faults); + harness.advance(WHEEL_DROP_HELP_MS); + harness.monitor.handleSensor('silver', faults); + assert.equal(harness.changes.at(-1).needsHelp, true); + + harness.monitor.handleSensor('silver', { + ...faults, + chargingSources: { homeBase: true }, + }); + assert.equal(harness.changes.at(-1).needsHelp, false); + assert.deepEqual(harness.changes.at(-1).reasons, []); +});