Files
signalk-plugin/plugin/tools/kiosk/core.js
Giuseppe Raffa c2c1598226 feat: Implement rulesets and layout management for kiosk plugin
- Added rulesets manager to handle various data types and updates via HTTP and WebSocket.
- Introduced layout store for managing kiosk layouts with caching and server synchronization.
- Enhanced dashboard and data routes to support new layout and ruleset features.
- Updated kiosk HTML and JavaScript to utilize new layout rendering and data binding.
- Removed obsolete map route and integrated map functionality into the new tile renderer.
- Improved Telegram commands to reflect changes in data structure and logging.
- Refactored weather fetching intervals to prevent multiple instances.
- Added SSE stream for real-time layout updates in the kiosk.
2026-05-12 10:17:54 +02:00

100 lines
3.1 KiB
JavaScript

const paths = [
"navigation.speedOverGround",
"environment.depth.belowTransducer",
]
window.skPaths = paths;
mapboxgl.accessToken = document.querySelector('meta[name="mapbox-key"]')?.content || '';
let map = null;
let boatMark = null;
let followBoat = true;
window.initMapInstance = (containerId) => {
map = new mapboxgl.Map({
container: containerId,
style: {
"version": 8,
"sources": {
"osm": { "type": "raster", "tiles": ["https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"], "tileSize": 256 },
"openseamap": { "type": "raster", "tiles": ["https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png"], "tileSize": 256 }
},
"layers": [
{ "id": "osm-layer", "type": "raster", "source": "osm", "minzoom": 0, "maxzoom": 22 },
{ "id": "openseamap-layer", "type": "raster", "source": "openseamap", "minzoom": 0, "maxzoom": 18 }
]
}
});
map.on('dragstart', () => {
followBoat = false;
});
boatMark = new mapboxgl.Marker({ color: 'red' })
.setLngLat([9, 9])
.addTo(map);
map.on('load', () => {
// Area Protetta mock
map.addSource('area-protetta', {
'type': 'geojson',
'data': {
'type': 'Feature',
'geometry': {
'type': 'Polygon',
'coordinates': [[[9.05, 45.05], [9.15, 45.05], [9.15, 45.15], [9.05, 45.15], [9.05, 45.05]]]
}
}
});
map.addLayer({
'id': 'area-layer',
'type': 'fill',
'source': 'area-protetta',
'paint': { 'fill-color': '#0080ff', 'fill-opacity': 0.3 }
});
});
};
window.resizeMapInstance = () => {
if (map) map.resize();
};
function movePosition(lng, lat) {
if (!followBoat || !map) return;
map.flyTo({ center: [lng, lat], zoom: 14, speed: 1.2 });
}
const host = window.location.host;
const connection = `ws://${host}/signalk/v1/stream?subscribe=all`;
const ws = new WebSocket(connection);
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.updates) {
msg.updates.forEach(update => {
if (update.values) {
update.values.forEach(v => {
// Aggiorna le card nel dashboard tramite canvas.js
if (window.updateKioskData) {
window.updateKioskData(v.path, v.value);
}
if (v.path === "navigation.position" && boatMark) {
const lng = v.value.longitude;
const lat = v.value.latitude;
boatMark.setLngLat([lng, lat]);
movePosition(lng, lat);
}
});
}
});
}
};
ws.onerror = (err) => console.error("Errore WebSocket:", err);
ws.onclose = () => {
console.log("WebSocket chiuso. Riconnessione tra 5s...");
setTimeout(() => location.reload(), 5000);
};
// style: 'mapbox://styles/sesee3/cmn9767jg003l01qsbpmace1t/draft'