battery manager / discord bot fix. add discord tag in chat.

This commit is contained in:
legop3
2025-11-22 02:30:51 -05:00
parent 62075df80d
commit 042f653798
7 changed files with 60 additions and 6 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
@@ -5,8 +5,8 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>webui</title>
<script type="module" crossorigin src="/assets/index-Bw29mQyW.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-vVHPhuT9.css">
<script type="module" crossorigin src="/assets/index-DAo0n__B.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-BjMfmH4X.css">
</head>
<body>
<div id="root"></div>
+26 -1
View File
@@ -21,6 +21,7 @@ function getState(roverId) {
warned: false,
urgent: false,
dockedCharging: false,
charging: false,
batteryLocked: false,
});
}
@@ -64,6 +65,21 @@ function handleSensorEvent({ roverId, sensors, batteryState }) {
const chargingSources = sensors?.chargingSources;
const onDock = Boolean(chargingSources?.homeBase);
const isCharging = chargingState === 1 || chargingState === 2 || chargingState === 3;
if (isCharging && !state.charging) {
state.charging = true;
publishEvent({
source: 'batteryManager',
type: 'battery.charging.start',
payload: { roverId, batteryState },
});
} else if (!isCharging && state.charging) {
state.charging = false;
publishEvent({
source: 'batteryManager',
type: 'battery.charging.stop',
payload: { roverId, batteryState },
});
}
const dockedCharging = onDock && isCharging;
if (dockedCharging && !state.dockedCharging) {
state.dockedCharging = true;
@@ -74,6 +90,11 @@ function handleSensorEvent({ roverId, sensors, batteryState }) {
});
} else if (!dockedCharging && state.dockedCharging) {
state.dockedCharging = false;
publishEvent({
source: 'batteryManager',
type: 'battery.undocked',
payload: { roverId, batteryState },
});
}
const fullThreshold =
@@ -82,7 +103,9 @@ function handleSensorEvent({ roverId, sensors, batteryState }) {
(batteryState?.charge != null && fullThreshold != null && batteryState.charge >= fullThreshold) ||
(batteryState?.percent != null && batteryState.percent >= 0.99);
if (dockedCharging && lockable && !state.batteryLocked && !isFull) {
const needsCharge = state.warned;
if (dockedCharging && lockable && needsCharge && !state.batteryLocked && !isFull) {
logger.info('Auto-locking rover for charging', { roverId });
lockRover(roverId, true, { reason: 'battery' });
state.batteryLocked = true;
@@ -105,6 +128,8 @@ function handleSensorEvent({ roverId, sensors, batteryState }) {
});
lockRover(roverId, false, { reason: 'battery' });
state.batteryLocked = false;
state.warned = false;
state.urgent = false;
publishEvent({
source: 'batteryManager',
type: 'battery.unlocked',
+24
View File
@@ -306,6 +306,30 @@ function handleBusEvent(event) {
description: `${payload?.roverId} is docked and charging.`,
});
break;
case 'battery.undocked':
announce({
channelId: channels.adminAlerts,
color: 0x2196f3,
title: 'Undocked',
description: `${payload?.roverId} undocked.`,
});
break;
case 'battery.charging.start':
announce({
channelId: channels.adminAlerts,
color: 0x2196f3,
title: 'Charging Started',
description: `${payload?.roverId} started charging.`,
});
break;
case 'battery.charging.stop':
announce({
channelId: channels.adminAlerts,
color: 0xf0b651,
title: 'Charging Stopped',
description: `${payload?.roverId} stopped charging.`,
});
break;
case 'battery.locked':
announce({
channelId: channels.adminAlerts,
+6 -1
View File
@@ -73,13 +73,18 @@ export default function ChatPanel() {
<div
key={msg.id}
className={`surface-muted text-sm flex items-start gap-1 ${
isAdmin ? 'border border-amber-400/30' : ''
isAdmin ? 'border border-amber-400/30' : msg.fromDiscord? 'border border-indigo-400/30' : ''
}`}
>
<span className="text-[0.75rem] text-slate-400">{formatTime(msg.ts)}</span>
<span className={`font-semibold text-[0.85rem] ${roleColors(msg.role)}`}>
{displayName(msg)}
</span>
{msg.fromDiscord && (
<span className="rounded bg-indigo-500/30 px-1 text-[0.7rem] text-indigo-100">
Discord
</span>
)}
{msg.roverId && (
<span className="rounded bg-slate-800 px-1 text-[0.7rem]">rover {msg.roverId}</span>
)}