SLM dashboard rework, diagnostics and command pages added

This commit is contained in:
serversdwn
2026-01-12 04:42:08 +00:00
parent ee025f1f34
commit e1b965c24c
4 changed files with 513 additions and 155 deletions

View File

@@ -686,8 +686,13 @@ async function controlUnit(unitId, action) {
if (typeof window.refreshInterval === 'undefined') {
window.refreshInterval = null;
}
const REFRESH_INTERVAL_MS = 30000; // 30 seconds
const unit_id = '{{ unit.id }}';
if (typeof window.REFRESH_INTERVAL_MS === 'undefined') {
window.REFRESH_INTERVAL_MS = 30000; // 30 seconds
}
if (typeof window.unit_id === 'undefined' || window.unit_id !== '{{ unit.id }}') {
// Keep HTMX reloads from reusing the old unit id
window.unit_id = '{{ unit.id }}';
}
function updateDeviceStatus() {
fetch(`/api/slmm/${unit_id}/live`)
@@ -755,7 +760,7 @@ function startAutoRefresh() {
updateDeviceStatus();
// Set up interval
refreshInterval = setInterval(updateDeviceStatus, REFRESH_INTERVAL_MS);
refreshInterval = setInterval(updateDeviceStatus, window.REFRESH_INTERVAL_MS);
console.log('Auto-refresh started (30s interval)');
}
@@ -778,6 +783,12 @@ if (typeof window.timerInterval === 'undefined') {
window.timerInterval = null;
window.measurementStartTime = null; // ISO string from backend
}
if (typeof window.timerSource === 'undefined') {
window.timerSource = null;
}
if (typeof window.lastFtpErrorTime === 'undefined') {
window.lastFtpErrorTime = null;
}
// Format elapsed time as HH:MM:SS
function formatElapsedTime(milliseconds) {
@@ -818,42 +829,52 @@ function updateTimerDisplay() {
async function syncTimerWithBackend(measurementState, measurementStartTime) {
// Device returns "Start" when measuring, "Stop" when stopped
const isMeasuring = measurementState === 'Start';
const now = Date.now();
if (isMeasuring && measurementStartTime) {
// Measurement is running - check both backend and FTP timestamps
// Use whichever is earlier (older = actual measurement start)
// First check FTP for potentially older timestamp
try {
const response = await fetch(`/api/slmm/${unit_id}/ftp/latest-measurement-time`);
const result = await response.json();
if (result.status === 'ok' && result.latest_timestamp) {
const backendTime = new Date(measurementStartTime + 'Z');
const ftpTime = new Date(result.latest_timestamp + 'Z');
// Use the earlier timestamp (represents actual measurement start)
if (ftpTime < backendTime) {
window.measurementStartTime = result.latest_timestamp;
window.timerSource = 'ftp';
console.log('Timer synced with FTP folder (earlier):', result.latest_folder, '@', result.latest_timestamp);
} else {
window.measurementStartTime = measurementStartTime;
window.timerSource = 'backend';
console.log('Timer synced with backend state (earlier):', measurementStartTime);
}
} else {
// No FTP timestamp, use backend
window.measurementStartTime = measurementStartTime;
window.timerSource = 'backend';
console.log('Timer synced with backend state:', measurementStartTime);
}
} catch (error) {
console.error('Failed to check FTP timestamp:', error);
// Fallback to backend on error
const shouldSkipFtp = window.lastFtpErrorTime && (now - window.lastFtpErrorTime < 10000);
if (shouldSkipFtp) {
window.measurementStartTime = measurementStartTime;
window.timerSource = 'backend';
console.log('Timer synced with backend state (FTP check failed):', measurementStartTime);
console.log('Timer using backend state (skipping FTP due to recent error):', measurementStartTime);
} else {
try {
const response = await fetch(`/api/slmm/${unit_id}/ftp/latest-measurement-time`);
const result = await response.json();
if (result.status === 'ok' && result.latest_timestamp) {
const backendTime = new Date(measurementStartTime + 'Z');
const ftpTime = new Date(result.latest_timestamp + 'Z');
// Use the earlier timestamp (represents actual measurement start)
if (ftpTime < backendTime) {
window.measurementStartTime = result.latest_timestamp;
window.timerSource = 'ftp';
console.log('Timer synced with FTP folder (earlier):', result.latest_folder, '@', result.latest_timestamp);
} else {
window.measurementStartTime = measurementStartTime;
window.timerSource = 'backend';
console.log('Timer synced with backend state (earlier):', measurementStartTime);
}
window.lastFtpErrorTime = null;
} else {
// No FTP timestamp, use backend
window.measurementStartTime = measurementStartTime;
window.timerSource = 'backend';
console.log('Timer synced with backend state:', measurementStartTime);
}
} catch (error) {
console.error('Failed to check FTP timestamp:', error);
window.lastFtpErrorTime = now;
// Fallback to backend on error
window.measurementStartTime = measurementStartTime;
window.timerSource = 'backend';
console.log('Timer synced with backend state (FTP check failed):', measurementStartTime);
}
}
// Start interval if not already running
@@ -869,27 +890,34 @@ async function syncTimerWithBackend(measurementState, measurementStartTime) {
// Try FTP fallback to get measurement start from latest folder timestamp
if (!window.measurementStartTime || window.timerSource !== 'ftp') {
console.log('Device measuring but no backend start time - checking FTP fallback...');
try {
const response = await fetch(`/api/slmm/${unit_id}/ftp/latest-measurement-time`);
const result = await response.json();
const skipFtp = window.lastFtpErrorTime && (Date.now() - window.lastFtpErrorTime < 10000);
if (!skipFtp) {
try {
const response = await fetch(`/api/slmm/${unit_id}/ftp/latest-measurement-time`);
const result = await response.json();
if (result.status === 'ok' && result.latest_timestamp) {
window.measurementStartTime = result.latest_timestamp;
window.timerSource = 'ftp';
console.log('Timer synced with FTP folder:', result.latest_folder, '@', result.latest_timestamp);
if (result.status === 'ok' && result.latest_timestamp) {
window.measurementStartTime = result.latest_timestamp;
window.timerSource = 'ftp';
console.log('Timer synced with FTP folder:', result.latest_folder, '@', result.latest_timestamp);
// Start timer interval if not already running
if (!window.timerInterval) {
window.timerInterval = setInterval(updateTimerDisplay, 1000);
console.log('Timer display started (FTP source)');
// Start timer interval if not already running
if (!window.timerInterval) {
window.timerInterval = setInterval(updateTimerDisplay, 1000);
console.log('Timer display started (FTP source)');
}
updateTimerDisplay();
window.lastFtpErrorTime = null;
} else {
console.log('No FTP timestamp available');
}
updateTimerDisplay();
} else {
console.log('No FTP timestamp available');
} catch (error) {
console.error('Failed to get FTP timestamp:', error);
window.lastFtpErrorTime = Date.now();
}
} catch (error) {
console.error('Failed to get FTP timestamp:', error);
} else {
console.log('Skipping FTP fallback due to recent error');
}
}
} else {