220 lines
6.1 KiB
JavaScript
220 lines
6.1 KiB
JavaScript
/**
|
|
* logRecorder.js - Gestione registrazione dati separata
|
|
* Centralizza tutte le funzioni di logging del dataset
|
|
*/
|
|
|
|
const path = require('path');
|
|
const { datasetInit, appendData } = require('../datasetModels/datasetCore');
|
|
|
|
let app = null;
|
|
let recordingInterval = null;
|
|
let isRecording = false;
|
|
|
|
// Stato condiviso della registrazione
|
|
const recordingState = {
|
|
active: false,
|
|
startTime: null,
|
|
entryCount: 0,
|
|
currentFile: null,
|
|
stream: null
|
|
};
|
|
|
|
/**
|
|
* Inizializza il recorder con l'istanza di SignalK app
|
|
*/
|
|
function init(signalkApp) {
|
|
app = signalkApp;
|
|
console.log('[LogRecorder] Inizializzato');
|
|
}
|
|
|
|
/**
|
|
* Raccoglie i dati dai sensori SignalK
|
|
*/
|
|
function collectSensorData() {
|
|
const getSK = (p) => {
|
|
const v = app.getSelfPath(p);
|
|
return v && v.value !== undefined && v.value !== null ? v.value : null;
|
|
};
|
|
|
|
return {
|
|
timestamp: new Date().toISOString(),
|
|
|
|
// Posizione
|
|
latitude: getSK('navigation.position')?.latitude ?? null,
|
|
longitude: getSK('navigation.position')?.longitude ?? null,
|
|
speed: getSK('navigation.speedOverGround'),
|
|
heading: getSK('navigation.headingTrue'),
|
|
|
|
// Batteria Trazione
|
|
traction_voltage: getSK('electrical.batteries.traction.Voltage'),
|
|
traction_current: getSK('electrical.batteries.traction.current'),
|
|
traction_soc: getSK('electrical.batteries.traction.stateOfCharge'),
|
|
traction_temperature: getSK('electrical.batteries.traction.temperature'),
|
|
traction_power: getSK('electrical.batteries.traction.power'),
|
|
|
|
// Batteria Servizio
|
|
service_voltage: getSK('electrical.batteries.service.Voltage'),
|
|
service_current: getSK('electrical.batteries.service.current'),
|
|
service_soc: getSK('electrical.batteries.service.stateOfCharge'),
|
|
service_temperature: getSK('electrical.batteries.service.temperature'),
|
|
|
|
// Meteo (da OpenMeteo condiviso)
|
|
temperature: getSK('meb.temperature'),
|
|
windSpeed: getSK('meb.appleWindSpeed'),
|
|
windDirection: getSK('meb.appleWindDirection'),
|
|
|
|
// Onde
|
|
waveHeight: getSK('meb.waves.waveHeight'),
|
|
wavePeriod: getSK('meb.waves.wavePeriod'),
|
|
waveDirection: getSK('meb.waves.waveDirection')
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Crea un nuovo file di log
|
|
*/
|
|
function createNewLogFile() {
|
|
const headers = [
|
|
'timestamp',
|
|
'latitude', 'longitude', 'speed', 'heading',
|
|
'traction_voltage', 'traction_current', 'traction_soc', 'traction_temperature', 'traction_power',
|
|
'service_voltage', 'service_current', 'service_soc', 'service_temperature',
|
|
'temperature', 'windSpeed', 'windDirection',
|
|
'waveHeight', 'wavePeriod', 'waveDirection'
|
|
];
|
|
|
|
const result = datasetInit(headers);
|
|
if (result) {
|
|
recordingState.currentFile = result.fileName;
|
|
recordingState.stream = result.stream;
|
|
console.log(`[LogRecorder] Nuovo file: ${result.fileName}`);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Scrive una riga di dati nel log
|
|
*/
|
|
function writeLogEntry(data) {
|
|
if (!recordingState.stream) return false;
|
|
|
|
const values = [
|
|
data.timestamp,
|
|
data.latitude, data.longitude, data.speed, data.heading,
|
|
data.traction_voltage, data.traction_current, data.traction_soc, data.traction_temperature, data.traction_power,
|
|
data.service_voltage, data.service_current, data.service_soc, data.service_temperature,
|
|
data.temperature, data.windSpeed, data.windDirection,
|
|
data.waveHeight, data.wavePeriod, data.waveDirection
|
|
];
|
|
|
|
appendData(values);
|
|
recordingState.entryCount++;
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Avvia la registrazione
|
|
* @param {number} intervalMs - Intervallo in millisecondi (default 2000)
|
|
*/
|
|
function startRecording(intervalMs = 2000) {
|
|
if (isRecording) {
|
|
console.log('[LogRecorder] Registrazione già attiva');
|
|
return false;
|
|
}
|
|
|
|
if (!app) {
|
|
console.error('[LogRecorder] App non inizializzata');
|
|
return false;
|
|
}
|
|
|
|
const fileResult = createNewLogFile();
|
|
if (!fileResult) {
|
|
console.error('[LogRecorder] Impossibile creare file di log');
|
|
return false;
|
|
}
|
|
|
|
recordingState.active = true;
|
|
recordingState.startTime = Date.now();
|
|
recordingState.entryCount = 0;
|
|
isRecording = true;
|
|
|
|
recordingInterval = setInterval(() => {
|
|
const data = collectSensorData();
|
|
writeLogEntry(data);
|
|
}, intervalMs);
|
|
|
|
console.log(`[LogRecorder] Registrazione avviata (ogni ${intervalMs}ms)`);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Ferma la registrazione
|
|
*/
|
|
function stopRecording() {
|
|
if (!isRecording) {
|
|
console.log('[LogRecorder] Nessuna registrazione attiva');
|
|
return false;
|
|
}
|
|
|
|
if (recordingInterval) {
|
|
clearInterval(recordingInterval);
|
|
recordingInterval = null;
|
|
}
|
|
|
|
if (recordingState.stream) {
|
|
recordingState.stream.end();
|
|
}
|
|
|
|
const duration = Date.now() - recordingState.startTime;
|
|
console.log(`[LogRecorder] Registrazione fermata. Durata: ${Math.round(duration / 1000)}s, Entries: ${recordingState.entryCount}`);
|
|
|
|
recordingState.active = false;
|
|
recordingState.stream = null;
|
|
isRecording = false;
|
|
|
|
return {
|
|
duration,
|
|
entries: recordingState.entryCount,
|
|
file: recordingState.currentFile
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Riavvia la registrazione (nuovo file)
|
|
*/
|
|
function restartRecording(intervalMs = 2000) {
|
|
stopRecording();
|
|
return startRecording(intervalMs);
|
|
}
|
|
|
|
/**
|
|
* Ottiene lo stato corrente della registrazione
|
|
*/
|
|
function getStatus() {
|
|
return {
|
|
isRecording,
|
|
active: recordingState.active,
|
|
startTime: recordingState.startTime,
|
|
entryCount: recordingState.entryCount,
|
|
currentFile: recordingState.currentFile,
|
|
runningTime: isRecording ? Date.now() - recordingState.startTime : 0
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Verifica se la registrazione è attiva
|
|
*/
|
|
function isActive() {
|
|
return isRecording;
|
|
}
|
|
|
|
module.exports = {
|
|
init,
|
|
startRecording,
|
|
stopRecording,
|
|
restartRecording,
|
|
getStatus,
|
|
isActive,
|
|
collectSensorData
|
|
};
|