mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-16 09:31:20 -04:00
wiki links for barcodes
This commit is contained in:
@@ -3,17 +3,20 @@
|
||||
"r001": {
|
||||
"type": "rover",
|
||||
"entityId": "Freaky",
|
||||
"label": "Freaky"
|
||||
"label": "Freaky",
|
||||
"wikiUrl": "https://wiki.otter.land/Roombas/Freaky%20(Roomba)%20(Aka%20Freakier)"
|
||||
},
|
||||
"r002": {
|
||||
"type": "rover",
|
||||
"entityId": "WALL-E",
|
||||
"label": "WALL-E"
|
||||
"label": "WALL-E",
|
||||
"wikiUrl": "https://wiki.otter.land/Roombas/WALL-E%20(roomba)"
|
||||
},
|
||||
"r003": {
|
||||
"type": "rover",
|
||||
"entityId": "Bweeble",
|
||||
"label": "Bweeble"
|
||||
"label": "Bweeble",
|
||||
"wikiUrl": "https://wiki.otter.land/Roombas/Bweeble%20(Roomba)"
|
||||
},
|
||||
|
||||
|
||||
@@ -22,7 +25,8 @@
|
||||
"o001": {
|
||||
"type": "object",
|
||||
"entityId": "woodblock",
|
||||
"label": "Wooden block"
|
||||
"label": "Wooden block",
|
||||
"wikiUrl": "https://wiki.otter.land/Room%20Objects/Wooden%20Block"
|
||||
},
|
||||
"o002": {
|
||||
"type":"object",
|
||||
|
||||
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
@@ -78,8 +78,8 @@
|
||||
<script defer src="https://analytics.otter.land/script.js" data-website-id="82dd56a5-db44-4279-bd1e-a4d9fee39af7" data-domains="rover.otter.land"></script>
|
||||
<script defer src="https://analytics.otter.land/recorder.js" data-website-id="82dd56a5-db44-4279-bd1e-a4d9fee39af7" data-domains="rover.otter.land" data-sample-rate="0.15" data-mask-level="moderate" data-max-duration="300000"></script>
|
||||
<title>Roomba Rover</title>
|
||||
<script type="module" crossorigin src="/assets/index-ciE1vQRQ.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-Cxghvfjc.css">
|
||||
<script type="module" crossorigin src="/assets/index-C_lCnw5U.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-D-tAn_fb.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
@@ -6,7 +6,6 @@ const io = require('../../globals/io');
|
||||
const logger = require('../../globals/logger').child('barcodeScannerService');
|
||||
const { resolveDataDir, resolveDataPath } = require('../../helpers/dataPaths');
|
||||
const { getMode, MODES, modeEvents } = require('../modeManager');
|
||||
const { sendAlert } = require('../alertService');
|
||||
const { publishEvent } = require('../eventBus');
|
||||
const { ensureAudioForText, warmAudioForTexts } = require('./ttsCache');
|
||||
|
||||
@@ -49,11 +48,13 @@ function createDefaultRegistry() {
|
||||
type: 'rover',
|
||||
entityId: 'rover1',
|
||||
label: 'rover 1',
|
||||
wikiUrl: '',
|
||||
},
|
||||
o001: {
|
||||
type: 'object',
|
||||
entityId: 'object1',
|
||||
label: 'object 1',
|
||||
wikiUrl: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -91,6 +92,7 @@ function validateRegistry(rawRegistry) {
|
||||
}
|
||||
const entityId = String(rawEntry.entityId || '').trim();
|
||||
const label = String(rawEntry.label || '').replace(/\s+/g, ' ').trim();
|
||||
const wikiUrl = String(rawEntry.wikiUrl || rawEntry.wiki || '').trim();
|
||||
if (!entityId) {
|
||||
throw new Error(`registry entry ${code} needs entityId`);
|
||||
}
|
||||
@@ -101,6 +103,11 @@ function validateRegistry(rawRegistry) {
|
||||
type,
|
||||
entityId,
|
||||
label,
|
||||
// wikiUrl is optional because existing physical labels may be scanned
|
||||
// before their wiki pages are written. Keeping the field empty instead
|
||||
// of rejecting the registry lets operators add links gradually while the
|
||||
// rest of the barcode system keeps working.
|
||||
wikiUrl,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -165,16 +172,27 @@ function broadcastState() {
|
||||
io.to(SCANNER_SOCKET_ROOM).emit('barcode:state', buildStatePayload());
|
||||
}
|
||||
|
||||
function sendBarcodeScanAlert(result) {
|
||||
function buildPublicScanPayload(result) {
|
||||
// Public clients only need resolved metadata for display. This intentionally
|
||||
// omits scanner-only state and generated audio buffers so normal web UI pages
|
||||
// can listen for scans without inheriting the heavy scanner-page concerns.
|
||||
return {
|
||||
code: result?.code || '',
|
||||
known: Boolean(result?.known),
|
||||
type: result?.type || null,
|
||||
entityId: result?.entityId || null,
|
||||
label: result?.label || result?.code || 'unknown',
|
||||
wikiUrl: result?.wikiUrl || '',
|
||||
scannedAt: Number.isFinite(result?.scannedAt) ? result.scannedAt : Date.now(),
|
||||
};
|
||||
}
|
||||
|
||||
function broadcastPublicScan(result) {
|
||||
if (!result) return;
|
||||
// Barcode scan toasts use the existing alert feed so drivers/spectators get a
|
||||
// lightweight system notice without adding any scanner-specific panels. The
|
||||
// scanner page remains the source of the big local display and speech output.
|
||||
sendAlert({
|
||||
color: result.known ? '#22c55e' : '#f59e0b',
|
||||
title: 'Barcode Scanned',
|
||||
message: result.label || result.code || 'unknown',
|
||||
});
|
||||
// Use a distinct event name from the client-to-server barcode:scan command.
|
||||
// That keeps packet direction obvious when debugging socket traffic and lets
|
||||
// AlertFeed subscribe without joining the scanner-only state/audio room.
|
||||
io.emit('barcode:scanned', buildPublicScanPayload(result));
|
||||
}
|
||||
|
||||
function resolveScan(rawCode) {
|
||||
@@ -236,6 +254,7 @@ function resolveScan(rawCode) {
|
||||
type: entry.type,
|
||||
entityId: entry.entityId,
|
||||
label: entry.label,
|
||||
wikiUrl: entry.wikiUrl || '',
|
||||
speechText: entry.label,
|
||||
scannedAt,
|
||||
registryError: loaded.error || null,
|
||||
@@ -266,6 +285,7 @@ async function applyScan(rawCode) {
|
||||
registryError: result.registryError || null,
|
||||
};
|
||||
broadcastState();
|
||||
broadcastPublicScan(result);
|
||||
// Barcode games listen to the normalized scan event instead of being called
|
||||
// directly from this service. That keeps the scanner station's IO concerns
|
||||
// separate from optional game rules, scoring, voting, and player attribution.
|
||||
@@ -287,7 +307,6 @@ async function applyScan(rawCode) {
|
||||
error: err.message,
|
||||
});
|
||||
});
|
||||
sendBarcodeScanAlert(result);
|
||||
return { result };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user