Migra dal codice salvato in locale al codice condiviso
This commit is contained in:
219
plugin/tools/logRecorder.js
Normal file
219
plugin/tools/logRecorder.js
Normal file
@@ -0,0 +1,219 @@
|
||||
/**
|
||||
* 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
|
||||
};
|
||||
Reference in New Issue
Block a user