From 1dcd7e5d7d019199faeb3740dd10d787f77c7fc9 Mon Sep 17 00:00:00 2001 From: legop3 Date: Sun, 18 Oct 2026 14:32:59 -0400 Subject: [PATCH] add beeps for overcurrent, HELP clear, and low battery --- server/src/services/batteryManager/index.js | 6 ++++++ .../services/overcurrentProtectionService/index.js | 1 + server/src/services/roverHelpService/index.js | 14 +++++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/server/src/services/batteryManager/index.js b/server/src/services/batteryManager/index.js index 2eed063f..06ddd6f1 100644 --- a/server/src/services/batteryManager/index.js +++ b/server/src/services/batteryManager/index.js @@ -4,6 +4,7 @@ const logger = require('../../globals/logger').child('batteryManager'); const { publishEvent } = require('../eventBus'); const { managerEvents, lockRover, rovers } = require('../roverManager'); +const { issueCommand } = require('../commandService'); const STATES = { NORMAL: 'normal', @@ -61,6 +62,11 @@ function handleSensorEvent({ roverId, sensors, batteryState }) { } if (!state.urgent && batteryState?.urgentActive) { state.urgent = true; + try { + issueCommand(roverId, { type: 'song', song: { notes: [{ note: 72, duration: 8 }, { note: 0, duration: 8 }, { note: 72, duration: 16 }] } }); + } catch (err) { + logger.warn('Failed to play urgent battery warning', { roverId, error: err.message }); + } publishEvent({ source: 'batteryManager', type: 'battery.urgent', diff --git a/server/src/services/overcurrentProtectionService/index.js b/server/src/services/overcurrentProtectionService/index.js index 2b30489a..ca207676 100644 --- a/server/src/services/overcurrentProtectionService/index.js +++ b/server/src/services/overcurrentProtectionService/index.js @@ -400,6 +400,7 @@ function createOvercurrentProtectionService(options = {}) { type: 'drive', driveDirect: { left: 0, right: 0 }, }); + issueAdjustedCommand(roverId, { type: 'song', song: { notes: [{ note: 76, duration: 8 }, { note: 72, duration: 8 }, { note: 67, duration: 16 }] } }); logger.warn('Stopped rover after persistent wheel overcurrent', { roverId, motor: stalledWheel, diff --git a/server/src/services/roverHelpService/index.js b/server/src/services/roverHelpService/index.js index cdbdd342..bf87e435 100644 --- a/server/src/services/roverHelpService/index.js +++ b/server/src/services/roverHelpService/index.js @@ -2,20 +2,19 @@ // Purpose: Publishes sustained 600-series Roomba trouble as roster and alert state. // Scope: Integrates the pure monitor with roverManager, browser alerts, and the event bus. const roverManager = require('../roverManager'); +const { issueCommand } = require('../commandService'); const { sendAlert } = require('../alertService'); const { publishEvent } = require('../eventBus'); const { REASON_LABELS, createRoverHelpMonitor } = require('./monitor'); const { createHelpHornNotifier } = require('./hornNotifier'); +const logger = require('../../globals/logger').child('roverHelpService'); const HELP_ALERT_COLOR = '#ef4444'; const hornNotifier = createHelpHornNotifier({ getRover: (roverId) => roverManager.rovers.get(String(roverId)), - // commandService imports roverManager, so resolving it only when a chirp is - // actually issued avoids turning server startup order into a circular module - // dependency while retaining the established command transport. - issueCommand: (roverId, payload) => require('../commandService').issueCommand(roverId, payload), - logger: require('../../globals/logger').child('roverHelpService'), + issueCommand, + logger, }); const monitor = createRoverHelpMonitor({ @@ -42,6 +41,11 @@ const monitor = createRoverHelpMonitor({ }); } else if (wasNeedingHelp && !needsHelp) { hornNotifier.stop(roverId); + try { + issueCommand(roverId, { type: 'song', song: { notes: [{ note: 72, duration: 8 }, { note: 79, duration: 16 }] } }); + } catch (err) { + logger.warn('Failed to play HELP-cleared confirmation', { roverId, error: err.message }); + } publishEvent({ source: 'roverHelpService', type: 'rover.helpCleared',