add data record, download csv
Signed-off-by: YoungSoo Shin <shinys000114@gmail.com>
This commit is contained in:
@@ -141,8 +141,9 @@
|
|||||||
<div class="card border-top-0 rounded-0 rounded-bottom">
|
<div class="card border-top-0 rounded-0 rounded-bottom">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex justify-content-end mb-3">
|
<div class="d-flex justify-content-end mb-3">
|
||||||
<a class="btn btn-primary" download="datalog.csv" href="/datalog.csv" style="display: none"><i
|
<button id="record-button" class="btn btn-success me-2"><i class="bi bi-record-circle me-1"></i>Record</button>
|
||||||
class="bi bi-download me-1"></i> Download CSV</a>
|
<button id="stop-button" class="btn btn-danger me-2" style="display: none;"><i class="bi bi-stop-circle me-1"></i>Stop</button>
|
||||||
|
<button id="download-csv-button" class="btn btn-primary" style="display: none;"><i class="bi bi-download me-1"></i>Download CSV</button>
|
||||||
</div>
|
</div>
|
||||||
<h5 class="card-title text-center mb-3">Power Metrics</h5>
|
<h5 class="card-title text-center mb-3">Power Metrics</h5>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ import {setupEventListeners} from './events.js';
|
|||||||
|
|
||||||
// --- Globals ---
|
// --- Globals ---
|
||||||
// StatusMessage is imported directly from the generated proto.js file.
|
// StatusMessage is imported directly from the generated proto.js file.
|
||||||
|
let isRecording = false;
|
||||||
|
let recordedData = [];
|
||||||
|
|
||||||
// --- DOM Elements ---
|
// --- DOM Elements ---
|
||||||
const loginContainer = document.getElementById('login-container');
|
const loginContainer = document.getElementById('login-container');
|
||||||
@@ -50,6 +52,11 @@ const newUsernameInput = document.getElementById('new-username');
|
|||||||
const newPasswordInput = document.getElementById('new-password');
|
const newPasswordInput = document.getElementById('new-password');
|
||||||
const confirmPasswordInput = document.getElementById('confirm-password');
|
const confirmPasswordInput = document.getElementById('confirm-password');
|
||||||
|
|
||||||
|
// Metrics Tab DOM Elements
|
||||||
|
const recordButton = document.getElementById('record-button');
|
||||||
|
const stopButton = document.getElementById('stop-button');
|
||||||
|
const downloadCsvButton = document.getElementById('download-csv-button');
|
||||||
|
|
||||||
|
|
||||||
// --- WebSocket Event Handlers ---
|
// --- WebSocket Event Handlers ---
|
||||||
|
|
||||||
@@ -88,10 +95,15 @@ function onWsMessage(event) {
|
|||||||
USB: sensorData.usb,
|
USB: sensorData.usb,
|
||||||
MAIN: sensorData.main,
|
MAIN: sensorData.main,
|
||||||
VIN: sensorData.vin,
|
VIN: sensorData.vin,
|
||||||
timestamp: sensorData.timestampMs
|
timestamp: sensorData.timestampMs,
|
||||||
|
uptime: sensorData.uptimeMs
|
||||||
};
|
};
|
||||||
updateSensorUI(sensorPayload);
|
updateSensorUI(sensorPayload);
|
||||||
|
|
||||||
|
if (isRecording) {
|
||||||
|
recordedData.push(sensorPayload);
|
||||||
|
}
|
||||||
|
|
||||||
// Update uptime separately from the sensor data payload
|
// Update uptime separately from the sensor data payload
|
||||||
if (sensorData.uptimeMs !== undefined) {
|
if (sensorData.uptimeMs !== undefined) {
|
||||||
updateUptimeUI(sensorData.uptimeMs / 1000);
|
updateUptimeUI(sensorData.uptimeMs / 1000);
|
||||||
@@ -233,6 +245,63 @@ function setupThemeToggles() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Recording and Downloading Functions ---
|
||||||
|
|
||||||
|
function startRecording() {
|
||||||
|
isRecording = true;
|
||||||
|
recordedData = [];
|
||||||
|
recordButton.style.display = 'none';
|
||||||
|
stopButton.style.display = 'inline-block';
|
||||||
|
downloadCsvButton.style.display = 'none';
|
||||||
|
console.log('Recording started.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopRecording() {
|
||||||
|
isRecording = false;
|
||||||
|
recordButton.style.display = 'inline-block';
|
||||||
|
stopButton.style.display = 'none';
|
||||||
|
if (recordedData.length > 0) {
|
||||||
|
downloadCsvButton.style.display = 'inline-block';
|
||||||
|
}
|
||||||
|
console.log('Recording stopped. Data points captured:', recordedData.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadCSV() {
|
||||||
|
if (recordedData.length === 0) {
|
||||||
|
alert('No data to download.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = [
|
||||||
|
'timestamp', 'uptime_ms',
|
||||||
|
'vin_voltage', 'vin_current', 'vin_power',
|
||||||
|
'main_voltage', 'main_current', 'main_power',
|
||||||
|
'usb_voltage', 'usb_current', 'usb_power'
|
||||||
|
];
|
||||||
|
const csvRows = [headers.join(',')];
|
||||||
|
|
||||||
|
recordedData.forEach(data => {
|
||||||
|
const timestamp = new Date(data.timestamp).toISOString();
|
||||||
|
const row = [
|
||||||
|
timestamp,
|
||||||
|
data.uptime,
|
||||||
|
data.VIN.voltage, data.VIN.current, data.VIN.power,
|
||||||
|
data.MAIN.voltage, data.MAIN.current, data.MAIN.power,
|
||||||
|
data.USB.voltage, data.USB.current, data.USB.power
|
||||||
|
];
|
||||||
|
csvRows.push(row.join(','));
|
||||||
|
});
|
||||||
|
|
||||||
|
const blob = new Blob([csvRows.join('\n')], { type: 'text/csv;charset=utf-8;' });
|
||||||
|
const link = document.createElement('a');
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
link.setAttribute('href', url);
|
||||||
|
link.setAttribute('download', 'powermate_log.csv');
|
||||||
|
link.style.visibility = 'hidden';
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
}
|
||||||
|
|
||||||
// --- Application Initialization ---
|
// --- Application Initialization ---
|
||||||
|
|
||||||
@@ -263,6 +332,12 @@ function initializeMainAppContent() {
|
|||||||
initializeVersion();
|
initializeVersion();
|
||||||
setupEventListeners(); // Attach main app event listeners
|
setupEventListeners(); // Attach main app event listeners
|
||||||
logoutButton.addEventListener('click', handleLogout); // Attach logout listener
|
logoutButton.addEventListener('click', handleLogout); // Attach logout listener
|
||||||
|
|
||||||
|
// Attach listeners for recording/downloading
|
||||||
|
recordButton.addEventListener('click', startRecording);
|
||||||
|
stopButton.addEventListener('click', stopRecording);
|
||||||
|
downloadCsvButton.addEventListener('click', downloadCSV);
|
||||||
|
|
||||||
connect();
|
connect();
|
||||||
|
|
||||||
// Attach user settings form listener
|
// Attach user settings form listener
|
||||||
|
|||||||
Reference in New Issue
Block a user