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:
Giuseppe Raffa
2026-04-23 16:19:11 +02:00
parent 41f33ce181
commit bb8d267cd4
85 changed files with 4293 additions and 5083 deletions

View File

@@ -1,58 +1,59 @@
const dataHub = require('../../tools/dataHub');
const skFlow = require('../../config/skFlow');
const { liveMarkup } = require('../utility/live');
/**
* Formatta i dati sensore in un messaggio Telegram leggibile.
* @returns {string} Testo formattato Markdown
*/
function formatSensorData() {
const sensors = dataHub.getSensorData();
if (!sensors) {
return 'Nessun dato sensore disponibile.\nI sensori potrebbero non essere ancora attivi.';
}
let text = '*Dati Sensori*\n';
text += `_${new Date().toLocaleTimeString('it-IT')}_\n\n`;
let hasData = false;
for (const [key, value] of Object.entries(sensors)) {
if (key.startsWith('_')) continue; // Skip campi interni
hasData = true;
let label = key.replace(/_/g, ' ');
label = label.charAt(0).toUpperCase() + label.slice(1);
const formatted = (value !== null && value !== undefined)
? (typeof value === 'number' ? value.toFixed(2) : String(value))
: 'N/A';
text += `*${label}:* ${formatted}\n`;
}
if (!hasData) {
text += '_Nessun dato configurato. Controlla sensors.references.json_\n';
}
return text;
}
const logsPaths = [
"navigation.position",
"navigation.headingTrue",
"navigation.speedOverGround",
"propulsion.p1.temperature"
];
module.exports = {
command: 'data',
description: 'Mostra i dati sensori attuali',
pattern: /\/data/,
execute: async (bot, msg) => {
handler: (bot, msg) => {
const chatId = msg.chat.id;
const text = formatSensorData();
let text = '';
await bot.sendMessage(chatId, text, {
parse_mode: 'Markdown',
reply_markup: {
inline_keyboard: [
[{ text: 'Aggiorna', callback_data: 'data-refresh' }]
]
// Telemetria
const logs = skFlow.getFrom(logsPaths);
text += '*Telemetria di Bordo*\n\n';
if (logs && Object.keys(logs).length > 0) {
for (const [path, value] of Object.entries(logs)) {
const displayValue = typeof value === 'object' ? JSON.stringify(value) : value;
text += `*${path}*: ${displayValue}\n`;
}
} else {
text += 'Nessun dato disponibile.\n';
}
// Meteo
const weather = skFlow.getWithFilter('meb.forecast');
text += '\n*Dati Meteo*\n\n';
if (weather && Object.keys(weather).length > 0) {
for (const [path, value] of Object.entries(weather)) {
const displayValue = typeof value === 'object' ? JSON.stringify(value) : value;
text += `*${path}*: ${displayValue}\n`;
}
} else {
text += 'Nessun dato disponibile.\n';
}
// Mare
const marine = skFlow.getWithFilter('meb.marine');
text += '\n*Dati Meteo del mare*\n\n';
if (marine && Object.keys(marine).length > 0) {
for (const [path, value] of Object.entries(marine)) {
const displayValue = typeof value === 'object' ? JSON.stringify(value) : value;
text += `*${path}*: ${displayValue}\n`;
}
} else {
text += 'Nessun dato disponibile.\n';
}
bot.sendMessage(chatId, text, {
parse_mode: 'Markdown',
reply_to_message_id: msg.message_id,
reply_markup: liveMarkup(msg.message_id, 'data')
});
},
formatSensorData
}
};