Aggiunta stili CSS per Kiosk, struttura HTML per la Mappa e Riferimenti ai Sensori
• Creato un nuovo file CSS per gli stili del chiosco (kiosk) con variabili, stili per le schede (card) e animazioni. • Aggiunto un file HTML per l'interfaccia della mappa utilizzando Mapbox, inclusi gli stili e il JavaScript per le funzionalità della mappa. • Introdotto un file JSON per i riferimenti ai sensori, definendo percorsi ed elementi per i dati di temperatura, vento, onde, posizione, batteria, motore e sistema. Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
90
plugin/tools/kiosk/control-socket.js
Normal file
90
plugin/tools/kiosk/control-socket.js
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Kiosk plugin page bootstrap:
|
||||
* 1) legge config dal <meta> iniettato dal server del plugin
|
||||
* 2) carica template attivo via API
|
||||
* 3) apre WS locale SignalK per i valori live
|
||||
* 4) apre WS "leggero" al realtime server per comandi dalla console
|
||||
*/
|
||||
(async function () {
|
||||
function cfg(name, fallback) {
|
||||
const m = document.querySelector(`meta[name="${name}"]`);
|
||||
return (m && m.content) || fallback;
|
||||
}
|
||||
|
||||
const apiUrl = cfg('api-url', 'https://api.mebboat.it');
|
||||
const realtimeUrl = cfg('realtime-url', 'https://realtime.mebboat.it');
|
||||
const realtimeWsUrl = cfg('realtime-ws-url', 'wss://realtime.mebboat.it');
|
||||
const sensorCode = cfg('sensor-code', '');
|
||||
const sensorName = cfg('sensor-name', '');
|
||||
|
||||
window.kiosk.init({ apiUrl, sensorCode, sensorName });
|
||||
|
||||
// 1) template iniziale
|
||||
await window.kiosk.loadTemplate();
|
||||
|
||||
// 2) WS locale SignalK
|
||||
try {
|
||||
const skWs = new WebSocket(`ws://${location.host}/signalk/v1/stream?subscribe=all`);
|
||||
skWs.onmessage = (ev) => {
|
||||
let msg; try { msg = JSON.parse(ev.data); } catch { return; }
|
||||
for (const u of msg.updates || []) for (const v of u.values || []) {
|
||||
window.kiosk.updateValue(v.path, v.value);
|
||||
}
|
||||
};
|
||||
skWs.onclose = () => setTimeout(() => location.reload(), 5000);
|
||||
} catch (e) { console.error('[kiosk] signalk ws error', e); }
|
||||
|
||||
// 3) WS controllo verso realtime server
|
||||
if (!sensorCode || !sensorName) { window.kiosk.setStatus('no sensor config', true); return; }
|
||||
|
||||
let controlWs = null;
|
||||
let reconnectTm = null;
|
||||
|
||||
async function fetchSocketToken() {
|
||||
const r = await fetch(`${realtimeUrl}/connect`, {
|
||||
method: 'POST', headers: { 'Content-Type':'application/json' },
|
||||
body: JSON.stringify({ name: sensorName, code: sensorCode })
|
||||
});
|
||||
if (!r.ok) return null;
|
||||
const j = await r.json();
|
||||
return j.s === 'ok' ? j.t : null;
|
||||
}
|
||||
|
||||
async function connectControl() {
|
||||
clearTimeout(reconnectTm);
|
||||
const token = await fetchSocketToken();
|
||||
if (!token) { reconnectTm = setTimeout(connectControl, 5000); return; }
|
||||
const url = `${realtimeWsUrl}/kiosk?role=device&sensor=${encodeURIComponent(sensorName)}&token=${encodeURIComponent(token)}`;
|
||||
controlWs = new WebSocket(url);
|
||||
controlWs.onopen = () => {
|
||||
controlWs.send(JSON.stringify({ t:'hello', templateId: window.kiosk.currentTemplateId() }));
|
||||
};
|
||||
controlWs.onmessage = async (ev) => {
|
||||
let m; try { m = JSON.parse(ev.data); } catch { return; }
|
||||
let ok = true, err = null;
|
||||
try {
|
||||
switch (m.t) {
|
||||
case 'patch_box': ok = window.kiosk.patchBox(m.boxId, m.patch || {}); break;
|
||||
case 'add_box': ok = window.kiosk.addBox(m.box); break;
|
||||
case 'remove_box': ok = window.kiosk.removeBox(m.boxId); break;
|
||||
case 'load_template': {
|
||||
const tpl = await window.kiosk.loadTemplate(m.templateId);
|
||||
ok = !!tpl;
|
||||
break;
|
||||
}
|
||||
case 'apply_inline': ok = window.kiosk.applyInline(m.content); break;
|
||||
case 'persist': ok = true; break; // no-op locale, la persistenza è server-side
|
||||
case 'reload': location.reload(); return;
|
||||
default: ok = false; err = 'unknown cmd';
|
||||
}
|
||||
} catch (e) { ok = false; err = e.message; }
|
||||
if (m.cmdId) controlWs.send(JSON.stringify({ t:'ack', cmdId: m.cmdId, ok, err }));
|
||||
};
|
||||
controlWs.onclose = () => { reconnectTm = setTimeout(connectControl, 5000); };
|
||||
controlWs.onerror = () => { try { controlWs.close(); } catch {} };
|
||||
|
||||
setInterval(() => { if (controlWs && controlWs.readyState === 1) controlWs.send(JSON.stringify({ t:'heartbeat' })); }, 25000);
|
||||
}
|
||||
|
||||
connectControl();
|
||||
})();
|
||||
Reference in New Issue
Block a user