smol changess

This commit is contained in:
legop3
2026-04-25 20:21:38 -04:00
parent e54b8e34ab
commit 1359c701bb
3 changed files with 63 additions and 18 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ Always pay attention to the chat.
Output contract: Output contract:
- Output must be either SKIP if you want to stay silent, or a message if you want to speak. - Output must be either SKIP if you want to stay silent, or a message if you want to speak.
- Allow 10 skips before speaking again, unless someone is talking to you. - Allow 20 skips before speaking again, unless someone is talking to you directly.
- If you choose to speak, send only one line. - If you choose to speak, send only one line.
- Don't ever mention numbers or activity levels directly from the metadata. They are for internal use only. - Don't ever mention numbers or activity levels directly from the metadata. They are for internal use only.
- Don't repeat the same or similar message over and over. - Don't repeat the same or similar message over and over.
+33 -17
View File
@@ -92,6 +92,19 @@ let presenceInterval = null;
let presenceShowGoal = false; let presenceShowGoal = false;
const VERIFY_APPROVE_EMOJI = '✅'; const VERIFY_APPROVE_EMOJI = '✅';
const VERIFY_DENY_EMOJI = '❌'; const VERIFY_DENY_EMOJI = '❌';
const ADMIN_ALERT_EVENT_TYPES = new Set([
'rover.online',
'rover.offline',
'rover.dockGuard',
'battery.warn',
'battery.urgent',
'battery.docked',
'battery.undocked',
'battery.charging.start',
'battery.charging.stop',
'battery.locked',
'battery.unlocked',
]);
function sanitizeMentions(text) { function sanitizeMentions(text) {
if (!text) return ''; if (!text) return '';
return String(text) return String(text)
@@ -169,7 +182,6 @@ function isCharging(sensors) {
function buildRoverStatusSnapshot(record) { function buildRoverStatusSnapshot(record) {
if (!record) return null; if (!record) return null;
if (!roverManager.canReplayRoverId(record.id)) return null;
const sensors = record.lastSensor?.decoded || record.lastSensor?.sensors || null; const sensors = record.lastSensor?.decoded || record.lastSensor?.sensors || null;
const docked = Boolean(sensors?.chargingSources?.homeBase); const docked = Boolean(sensors?.chargingSources?.homeBase);
const charging = isCharging(sensors); const charging = isCharging(sensors);
@@ -1208,10 +1220,11 @@ async function handleTimeStatusCommand(message) {
function buildBatteryStatusEmbed(color, records = null) { function buildBatteryStatusEmbed(color, records = null) {
const embed = buildEmbed({ title: 'Rover Battery Status', color: color || 0x2196f3 }); const embed = buildEmbed({ title: 'Rover Battery Status', color: color || 0x2196f3 });
const baseRecords = (records || Array.from(rovers.values())).filter((entry) => const sourceRecords = records || Array.from(rovers.values());
roverManager.canReplayRoverId(entry?.id), const baseRecords = records
); ? sourceRecords
const snapshots = baseRecords.map(buildRoverStatusSnapshot).filter(Boolean); : sourceRecords.filter((entry) => roverManager.canReplayRoverId(entry?.id));
const snapshots = baseRecords.map((entry) => buildRoverStatusSnapshot(entry)).filter(Boolean);
if (snapshots.length === 0) { if (snapshots.length === 0) {
embed.setDescription('No rovers online.'); embed.setDescription('No rovers online.');
return embed; return embed;
@@ -1286,9 +1299,6 @@ function buildAccessModeEmbed(mode, color) {
function buildBatteryCaption(type, payload) { function buildBatteryCaption(type, payload) {
const roverId = payload?.roverId || 'unknown'; const roverId = payload?.roverId || 'unknown';
if (!roverManager.canReplayRoverId(roverId)) {
return null;
}
const record = rovers.get(roverId) || findRoverRecord(roverId); const record = rovers.get(roverId) || findRoverRecord(roverId);
const snapshot = buildRoverStatusSnapshot(record); const snapshot = buildRoverStatusSnapshot(record);
const base = snapshot?.name || roverId; const base = snapshot?.name || roverId;
@@ -1323,6 +1333,12 @@ function buildBatteryCaption(type, payload) {
} }
} }
function getEventRoverRecord(payload) {
const roverId = String(payload?.roverId || '').trim();
if (!roverId) return null;
return rovers.get(roverId) || findRoverRecord(roverId) || null;
}
async function announce({ async function announce({
channelId, channelId,
content, content,
@@ -1379,7 +1395,7 @@ function handleBusEvent(event) {
const channels = discordConfig.channels || {}; const channels = discordConfig.channels || {};
const roles = discordConfig.roles || {}; const roles = discordConfig.roles || {};
const roverId = payload?.roverId || null; const roverId = payload?.roverId || null;
if (roverId && !roverManager.canReplayRoverId(roverId)) { if (roverId && !roverManager.canReplayRoverId(roverId) && !ADMIN_ALERT_EVENT_TYPES.has(type)) {
return; return;
} }
switch (type) { switch (type) {
@@ -1474,7 +1490,7 @@ function handleBusEvent(event) {
content: buildBatteryCaption(type, payload), content: buildBatteryCaption(type, payload),
title: 'Battery Status', title: 'Battery Status',
description: null, description: null,
embeds: [buildBatteryStatusEmbed(0xf0b651)], embeds: [buildBatteryStatusEmbed(0xf0b651, [getEventRoverRecord(payload)].filter(Boolean))],
}); });
break; break;
case 'battery.urgent': case 'battery.urgent':
@@ -1486,7 +1502,7 @@ function handleBusEvent(event) {
content: buildBatteryCaption(type, payload), content: buildBatteryCaption(type, payload),
title: 'Battery Status', title: 'Battery Status',
description: null, description: null,
embeds: [buildBatteryStatusEmbed(0xe53935)], embeds: [buildBatteryStatusEmbed(0xe53935, [getEventRoverRecord(payload)].filter(Boolean))],
}); });
break; break;
case 'battery.docked': case 'battery.docked':
@@ -1497,7 +1513,7 @@ function handleBusEvent(event) {
content: buildBatteryCaption(type, payload), content: buildBatteryCaption(type, payload),
title: 'Battery Status', title: 'Battery Status',
description: null, description: null,
embeds: [buildBatteryStatusEmbed(0x2196f3)], embeds: [buildBatteryStatusEmbed(0x2196f3, [getEventRoverRecord(payload)].filter(Boolean))],
}); });
break; break;
case 'battery.undocked': case 'battery.undocked':
@@ -1508,7 +1524,7 @@ function handleBusEvent(event) {
content: buildBatteryCaption(type, payload), content: buildBatteryCaption(type, payload),
title: 'Battery Status', title: 'Battery Status',
description: null, description: null,
embeds: [buildBatteryStatusEmbed(0x2196f3)], embeds: [buildBatteryStatusEmbed(0x2196f3, [getEventRoverRecord(payload)].filter(Boolean))],
}); });
break; break;
case 'battery.charging.start': case 'battery.charging.start':
@@ -1519,7 +1535,7 @@ function handleBusEvent(event) {
content: buildBatteryCaption(type, payload), content: buildBatteryCaption(type, payload),
title: 'Battery Status', title: 'Battery Status',
description: null, description: null,
embeds: [buildBatteryStatusEmbed(0x2196f3)], embeds: [buildBatteryStatusEmbed(0x2196f3, [getEventRoverRecord(payload)].filter(Boolean))],
}); });
break; break;
case 'battery.charging.stop': case 'battery.charging.stop':
@@ -1530,7 +1546,7 @@ function handleBusEvent(event) {
content: buildBatteryCaption(type, payload), content: buildBatteryCaption(type, payload),
title: 'Battery Status', title: 'Battery Status',
description: null, description: null,
embeds: [buildBatteryStatusEmbed(0xf0b651)], embeds: [buildBatteryStatusEmbed(0xf0b651, [getEventRoverRecord(payload)].filter(Boolean))],
}); });
break; break;
case 'battery.locked': case 'battery.locked':
@@ -1541,7 +1557,7 @@ function handleBusEvent(event) {
content: buildBatteryCaption(type, payload), content: buildBatteryCaption(type, payload),
title: 'Battery Status', title: 'Battery Status',
description: null, description: null,
embeds: [buildBatteryStatusEmbed(0xf0b651)], embeds: [buildBatteryStatusEmbed(0xf0b651, [getEventRoverRecord(payload)].filter(Boolean))],
}); });
schedulePresenceRotation(); schedulePresenceRotation();
break; break;
@@ -1553,7 +1569,7 @@ function handleBusEvent(event) {
content: buildBatteryCaption(type, payload), content: buildBatteryCaption(type, payload),
title: 'Battery Status', title: 'Battery Status',
description: null, description: null,
embeds: [buildBatteryStatusEmbed(0x4caf50)], embeds: [buildBatteryStatusEmbed(0x4caf50, [getEventRoverRecord(payload)].filter(Boolean))],
}); });
schedulePresenceRotation(); schedulePresenceRotation();
break; break;
@@ -6,6 +6,8 @@ const logger = require('../globals/logger').child('homeAssistantService');
const { loadConfig } = require('../helpers/configLoader'); const { loadConfig } = require('../helpers/configLoader');
const { getMode, MODES, modeEvents } = require('./modeManager'); const { getMode, MODES, modeEvents } = require('./modeManager');
const { isAdmin, isLockdownAdmin } = require('./roleService'); const { isAdmin, isLockdownAdmin } = require('./roleService');
const roverManager = require('./roverManager');
const { issueCommand } = require('./commandService');
const { publishEvent } = require('./eventBus'); const { publishEvent } = require('./eventBus');
const { getActiveDrivers, turnEvents } = require('./turnService'); const { getActiveDrivers, turnEvents } = require('./turnService');
@@ -192,6 +194,30 @@ function getControllableEntityIds() {
return Array.from(entityConfig.values()).map((meta) => String(meta.id)); return Array.from(entityConfig.values()).map((meta) => String(meta.id));
} }
function turnOffAllRoverNightVision() {
const records = Array.from(roverManager.rovers.values());
let attempted = 0;
let failed = 0;
records.forEach((record) => {
if (!record?.ws) return;
if (!record?.meta?.nightVision?.enabled) return;
attempted += 1;
try {
issueCommand(record.id, {
type: 'nightVision',
nightVision: { action: 'off' },
});
} catch (err) {
failed += 1;
logger.warn('Failed to auto turn off rover night vision after idle', {
roverId: record.id,
error: err.message,
});
}
});
return { attempted, failed };
}
function getActiveDriverCount() { function getActiveDriverCount() {
const active = getActiveDrivers(); const active = getActiveDrivers();
if (!active || typeof active !== 'object') return 0; if (!active || typeof active !== 'object') return 0;
@@ -225,8 +251,11 @@ function scheduleLightsIdleOffTimer() {
lightsIdleOffDeadline = null; lightsIdleOffDeadline = null;
try { try {
await setAllControllableEntitiesState('off'); await setAllControllableEntitiesState('off');
const nightVisionResult = turnOffAllRoverNightVision();
logger.info('Auto-turned off room lights due to no active drivers', { logger.info('Auto-turned off room lights due to no active drivers', {
idleMs: LIGHT_IDLE_OFF_MS, idleMs: LIGHT_IDLE_OFF_MS,
nightVisionRovers: nightVisionResult.attempted,
nightVisionFailures: nightVisionResult.failed,
}); });
} catch (err) { } catch (err) {
logger.warn('Failed auto light-off after idle', err.message); logger.warn('Failed auto light-off after idle', err.message);