SLM dashboard rework, diagnostics and command pages added
This commit is contained in:
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user