mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 09:31:20 -04:00
remove neato plsy sound and update user pings
This commit is contained in:
@@ -8,15 +8,7 @@ const WATCHED_EVENT_TYPES = new Set([
|
|||||||
'mode.changed',
|
'mode.changed',
|
||||||
'globalObjective.updated',
|
'globalObjective.updated',
|
||||||
'communityGoal.updated',
|
'communityGoal.updated',
|
||||||
'rover.online',
|
|
||||||
'rover.offline',
|
|
||||||
'rover.locked',
|
|
||||||
'rover.unlocked',
|
|
||||||
'rovers.allUnlocked',
|
'rovers.allUnlocked',
|
||||||
'rover.privateOpened',
|
|
||||||
'rover.privateClosed',
|
|
||||||
'battery.locked',
|
|
||||||
'battery.unlocked',
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
function createUserAnnouncements(deps) {
|
function createUserAnnouncements(deps) {
|
||||||
@@ -35,6 +27,7 @@ function createUserAnnouncements(deps) {
|
|||||||
const siteUrl = discordConfig?.siteUrl ? String(discordConfig.siteUrl) : '';
|
const siteUrl = discordConfig?.siteUrl ? String(discordConfig.siteUrl) : '';
|
||||||
|
|
||||||
let previousSnapshot = buildSnapshot();
|
let previousSnapshot = buildSnapshot();
|
||||||
|
let skippedFirstModeChange = false;
|
||||||
|
|
||||||
function isPublicMode(mode) {
|
function isPublicMode(mode) {
|
||||||
return PUBLIC_MODES.has(String(mode || ''));
|
return PUBLIC_MODES.has(String(mode || ''));
|
||||||
@@ -44,12 +37,6 @@ function createUserAnnouncements(deps) {
|
|||||||
return String(record?.meta?.name || record?.id || fallback);
|
return String(record?.meta?.name || record?.id || fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEventRoverName(payload = {}) {
|
|
||||||
const roverId = payload?.roverId ? String(payload.roverId) : '';
|
|
||||||
if (!roverId) return 'A rover';
|
|
||||||
return getRecordName(rovers.get(roverId), roverId);
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatPercent(record) {
|
function formatPercent(record) {
|
||||||
const percent = record?.batteryState?.percentDisplay;
|
const percent = record?.batteryState?.percentDisplay;
|
||||||
return percent == null ? '' : `${percent}%`;
|
return percent == null ? '' : `${percent}%`;
|
||||||
@@ -95,33 +82,45 @@ function createUserAnnouncements(deps) {
|
|||||||
const embed = new EmbedBuilder().setTitle(title).setColor(color).setTimestamp(new Date());
|
const embed = new EmbedBuilder().setTitle(title).setColor(color).setTimestamp(new Date());
|
||||||
if (description) embed.setDescription(description);
|
if (description) embed.setDescription(description);
|
||||||
|
|
||||||
if (snapshot.readyRecords.length) {
|
|
||||||
embed.addFields({
|
|
||||||
name: 'Ready',
|
|
||||||
value: snapshot.readyRecords.map((record) => formatRecordLine(record)).join('\n').slice(0, 1024),
|
|
||||||
inline: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (snapshot.unavailableRecords.length) {
|
|
||||||
embed.addFields({
|
|
||||||
name: 'Not Ready',
|
|
||||||
value: snapshot.unavailableRecords.map((record) => formatRecordLine(record, true)).join('\n').slice(0, 1024),
|
|
||||||
inline: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
embed.addFields({
|
embed.addFields({
|
||||||
name: 'Mode',
|
name: 'Mode',
|
||||||
value: String(snapshot.mode || 'unknown'),
|
value: String(snapshot.mode || 'unknown'),
|
||||||
inline: true,
|
inline: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
embed.addFields({
|
||||||
|
name: 'Ready Count',
|
||||||
|
value: `${snapshot.readyCount}/${snapshot.totalCount}`,
|
||||||
|
inline: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (snapshot.readyRecords.length) {
|
||||||
|
embed.addFields({
|
||||||
|
name: 'Ready',
|
||||||
|
value: snapshot.readyRecords.map((record) => formatRecordLine(record)).join(', ').slice(0, 1024),
|
||||||
|
inline: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
embed.addFields({
|
||||||
|
name: 'Ready',
|
||||||
|
value: 'none',
|
||||||
|
inline: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snapshot.unavailableRecords.length) {
|
||||||
|
embed.addFields({
|
||||||
|
name: 'Not Ready',
|
||||||
|
value: snapshot.unavailableRecords.map((record) => formatRecordLine(record, true)).join(', ').slice(0, 1024),
|
||||||
|
inline: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (snapshot.objectiveText) {
|
if (snapshot.objectiveText) {
|
||||||
embed.addFields({
|
embed.addFields({
|
||||||
name: 'Objective',
|
name: 'Objective',
|
||||||
value: snapshot.objectiveText.slice(0, 1024),
|
value: snapshot.objectiveText.slice(0, 1024),
|
||||||
inline: false,
|
inline: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,122 +148,65 @@ function createUserAnnouncements(deps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasAnyReadyRover(snapshot) {
|
|
||||||
return snapshot.publicMode && snapshot.readyCount > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function wasAnyReadyRover(snapshot) {
|
|
||||||
return snapshot?.publicMode && snapshot.readyCount > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function didObjectiveChange(prev, next) {
|
function didObjectiveChange(prev, next) {
|
||||||
return String(prev?.objectiveText || '') !== String(next?.objectiveText || '');
|
return String(prev?.objectiveText || '') !== String(next?.objectiveText || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPositiveReadyTransition(prev, next) {
|
// Mode-open pings: ping only when the server is switched to open/turns, never for the first mode event after startup.
|
||||||
return next.publicMode && prev?.readyCount === 0 && next.readyCount > 0;
|
async function maybeAnnouncePublicMode(event, next) {
|
||||||
}
|
if (event?.type !== 'mode.changed') return false;
|
||||||
|
if (!skippedFirstModeChange) {
|
||||||
function isNegativeReadyTransition(prev, next) {
|
skippedFirstModeChange = true;
|
||||||
return next.publicMode && prev?.readyCount > 0 && next.readyCount === 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!next.publicMode) return false;
|
||||||
function didPublicAccessClose(prev, next) {
|
|
||||||
return prev?.publicMode && !next.publicMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findNewReadyRecord(prev, next) {
|
|
||||||
return next.readyRecords.find((record) => !prev?.readyIds?.has(String(record.id))) || next.readyRecords[0] || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Positive availability messages: these are the only rover availability posts that ping subscribers.
|
|
||||||
async function maybeAnnounceRoversAvailable(event, prev, next) {
|
|
||||||
if (!isPositiveReadyTransition(prev, next)) return false;
|
|
||||||
const eventType = event?.type || '';
|
|
||||||
const record = eventType === 'mode.changed' ? null : findNewReadyRecord(prev, next);
|
|
||||||
const title = eventType === 'mode.changed'
|
|
||||||
? 'Rovers Are Open'
|
|
||||||
: `${getRecordName(record)} Is Ready`;
|
|
||||||
const content = eventType === 'mode.changed'
|
|
||||||
? `Rovers are open: ${next.readyCount} ready`
|
|
||||||
: `${getRecordName(record)} is ready`;
|
|
||||||
const description = `${next.readyCount}/${next.totalCount} public rovers ready.`;
|
|
||||||
|
|
||||||
await sendAnnouncement({
|
await sendAnnouncement({
|
||||||
content,
|
content: `Server mode changed to ${next.mode}.`,
|
||||||
ping: true,
|
ping: true,
|
||||||
embeds: [buildAvailabilityEmbed({ title, description, snapshot: next, color: 0x4caf50 })],
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public access closed messages: useful context, but never ping for negative server state.
|
|
||||||
async function maybeAnnounceAccessPaused(prev, next) {
|
|
||||||
if (!didPublicAccessClose(prev, next)) return false;
|
|
||||||
await sendAnnouncement({
|
|
||||||
content: 'Rovers are paused',
|
|
||||||
embeds: [buildAvailabilityEmbed({
|
embeds: [buildAvailabilityEmbed({
|
||||||
title: 'Rovers Are Paused',
|
title: `Server Mode Changed To ${next.mode}`,
|
||||||
description: 'Public driving is currently closed.',
|
description: `The server was switched to **${next.mode}** mode.`,
|
||||||
snapshot: next,
|
snapshot: next,
|
||||||
color: 0xf0b651,
|
color: 0x4caf50,
|
||||||
})],
|
})],
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// All-ready-lost messages: useful context, but never ping for negative rover state.
|
// All-unlocked pings: ping only when every rover has been unlocked.
|
||||||
async function maybeAnnounceNoReadyRovers(event, prev, next) {
|
async function maybeAnnounceAllUnlocked(event, next) {
|
||||||
if (!isNegativeReadyTransition(prev, next)) return false;
|
if (event?.type !== 'rovers.allUnlocked') return false;
|
||||||
const roverName = event?.payload?.roverId ? getEventRoverName(event.payload) : null;
|
|
||||||
const content = roverName ? `${roverName} is not ready` : 'No rovers are ready right now';
|
|
||||||
const title = roverName ? `${roverName} Is Not Ready` : 'No Rovers Are Ready';
|
|
||||||
|
|
||||||
await sendAnnouncement({
|
await sendAnnouncement({
|
||||||
content,
|
content: 'All rovers are unlocked.',
|
||||||
|
ping: true,
|
||||||
embeds: [buildAvailabilityEmbed({
|
embeds: [buildAvailabilityEmbed({
|
||||||
title,
|
title: 'All Rovers Unlocked',
|
||||||
description: 'Public access is open, but there are no ready rovers.',
|
description: 'Every rover is now unlocked.',
|
||||||
snapshot: next,
|
snapshot: next,
|
||||||
color: 0xf0b651,
|
color: 0x4caf50,
|
||||||
})],
|
})],
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Objective messages: setting a useful objective pings only when there are usable public rovers.
|
// Objective pings: ping whenever the objective text changes, and say the objective in the message text.
|
||||||
async function maybeAnnounceObjective(event, prev, next) {
|
async function maybeAnnounceObjective(event, prev, next) {
|
||||||
if (event?.type !== 'globalObjective.updated' && event?.type !== 'communityGoal.updated') return false;
|
if (event?.type !== 'globalObjective.updated' && event?.type !== 'communityGoal.updated') return false;
|
||||||
if (!didObjectiveChange(prev, next)) return false;
|
if (!didObjectiveChange(prev, next)) return false;
|
||||||
|
|
||||||
if (next.objectiveText && hasAnyReadyRover(next)) {
|
const objectiveText = next.objectiveText || 'cleared';
|
||||||
await sendAnnouncement({
|
await sendAnnouncement({
|
||||||
content: 'New objective',
|
content: `Objective changed to: ${objectiveText}`,
|
||||||
ping: true,
|
ping: true,
|
||||||
embeds: [buildAvailabilityEmbed({
|
embeds: [buildAvailabilityEmbed({
|
||||||
title: 'New Objective',
|
title: 'Objective Changed',
|
||||||
description: next.objectiveText,
|
description: next.objectiveText ? `New objective: ${next.objectiveText}` : 'The objective was cleared.',
|
||||||
snapshot: next,
|
snapshot: next,
|
||||||
color: 0x8bc34a,
|
color: 0x8bc34a,
|
||||||
})],
|
})],
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
if (!next.objectiveText && wasAnyReadyRover(prev)) {
|
|
||||||
await sendAnnouncement({
|
|
||||||
content: 'Objective cleared',
|
|
||||||
embeds: [buildAvailabilityEmbed({
|
|
||||||
title: 'Objective Cleared',
|
|
||||||
description: 'There is no current objective.',
|
|
||||||
snapshot: next,
|
|
||||||
color: 0x2196f3,
|
|
||||||
})],
|
|
||||||
});
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleBusEvent(event) {
|
async function handleBusEvent(event) {
|
||||||
@@ -277,9 +219,8 @@ function createUserAnnouncements(deps) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (await maybeAnnounceObjective(event, prev, next)) return;
|
if (await maybeAnnounceObjective(event, prev, next)) return;
|
||||||
if (await maybeAnnounceRoversAvailable(event, prev, next)) return;
|
if (await maybeAnnouncePublicMode(event, next)) return;
|
||||||
if (await maybeAnnounceAccessPaused(prev, next)) return;
|
await maybeAnnounceAllUnlocked(event, next);
|
||||||
await maybeAnnounceNoReadyRovers(event, prev, next);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// The caller logs send failures; this catch keeps one announcement bug from breaking event dispatch.
|
// The caller logs send failures; this catch keeps one announcement bug from breaking event dispatch.
|
||||||
const logger = deps.logger;
|
const logger = deps.logger;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const liftUp = require('./liftUp');
|
|||||||
const liftDown = require('./liftDown');
|
const liftDown = require('./liftDown');
|
||||||
const neatoStart = require('./neatoStart');
|
const neatoStart = require('./neatoStart');
|
||||||
const neatoSendHome = require('./neatoSendHome');
|
const neatoSendHome = require('./neatoSendHome');
|
||||||
const neatoLocate = require('./neatoLocate');
|
// const neatoLocate = require('./neatoLocate');
|
||||||
const neatoClearErrors = require('./neatoClearErrors');
|
const neatoClearErrors = require('./neatoClearErrors');
|
||||||
const haSetEntity = require('./haSetEntity');
|
const haSetEntity = require('./haSetEntity');
|
||||||
const buttonBoxAddCount = require('./buttonBoxAddCount');
|
const buttonBoxAddCount = require('./buttonBoxAddCount');
|
||||||
@@ -22,7 +22,7 @@ const TOOL_DEFINITIONS = [
|
|||||||
liftDown,
|
liftDown,
|
||||||
neatoStart,
|
neatoStart,
|
||||||
neatoSendHome,
|
neatoSendHome,
|
||||||
neatoLocate,
|
// neatoLocate,
|
||||||
neatoClearErrors,
|
neatoClearErrors,
|
||||||
haSetEntity,
|
haSetEntity,
|
||||||
buttonBoxAddCount,
|
buttonBoxAddCount,
|
||||||
|
|||||||
Reference in New Issue
Block a user