Files
terra-view/templates/partials/slm_diagnostics_card.html

207 lines
11 KiB
HTML

<!-- Compact Diagnostics Card for {{ unit.id }} -->
<div class="h-full flex flex-col p-6">
<!-- Header -->
<div class="flex items-center justify-between mb-6">
<div>
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">{{ unit.id }}</h2>
<p class="text-sm text-gray-600 dark:text-gray-400">
{% if unit.slm_model %}{{ unit.slm_model }}{% endif %}
{% if unit.slm_serial_number %} • S/N: {{ unit.slm_serial_number }}{% endif %}
</p>
</div>
<!-- Status Badge -->
<span id="diag-status-badge" class="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg font-medium">
Loading...
</span>
</div>
<!-- Connection Status -->
<div class="bg-white dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700 mb-4">
<div class="flex items-center justify-between">
<div class="flex items-center">
<svg class="w-5 h-5 text-gray-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M5.05 3.636a1 1 0 010 1.414 7 7 0 000 9.9 1 1 0 11-1.414 1.414 9 9 0 010-12.728 1 1 0 011.414 0zm9.9 0a1 1 0 011.414 0 9 9 0 010 12.728 1 1 0 11-1.414-1.414 7 7 0 000-9.9 1 1 0 010-1.414zM7.879 6.464a1 1 0 010 1.414 3 3 0 000 4.243 1 1 0 11-1.415 1.414 5 5 0 010-7.07 1 1 0 011.415 0zm4.242 0a1 1 0 011.415 0 5 5 0 010 7.072 1 1 0 01-1.415-1.415 3 3 0 000-4.242 1 1 0 010-1.415zM10 9a1 1 0 011 1v.01a1 1 0 11-2 0V10a1 1 0 011-1z" clip-rule="evenodd"/>
</svg>
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Connection</span>
</div>
<div>
{% if modem %}
<span class="text-sm text-gray-600 dark:text-gray-400">via {{ modem.id }}</span>
{% elif modem_ip %}
<span class="text-sm text-gray-600 dark:text-gray-400">Direct: {{ modem_ip }}</span>
{% else %}
<span class="text-sm text-red-600 dark:text-red-400">Not configured</span>
{% endif %}
<span id="connection-status" class="ml-2 w-2 h-2 bg-gray-400 rounded-full inline-block"></span>
</div>
</div>
</div>
<!-- Current Sound Levels -->
<div class="grid grid-cols-2 gap-3 mb-4">
<div class="bg-blue-50 dark:bg-blue-900/20 rounded-lg p-4">
<p class="text-xs text-gray-600 dark:text-gray-400 mb-1">Lp (Instant)</p>
<p id="diag-lp" class="text-2xl font-bold text-blue-600 dark:text-blue-400">--</p>
<p class="text-xs text-gray-500 dark:text-gray-400">dB</p>
</div>
<div class="bg-green-50 dark:bg-green-900/20 rounded-lg p-4">
<p class="text-xs text-gray-600 dark:text-gray-400 mb-1">Leq (Average)</p>
<p id="diag-leq" class="text-2xl font-bold text-green-600 dark:text-green-400">--</p>
<p class="text-xs text-gray-500 dark:text-gray-400">dB</p>
</div>
<div class="bg-red-50 dark:bg-red-900/20 rounded-lg p-4">
<p class="text-xs text-gray-600 dark:text-gray-400 mb-1">Lmax (Max)</p>
<p id="diag-lmax" class="text-2xl font-bold text-red-600 dark:text-red-400">--</p>
<p class="text-xs text-gray-500 dark:text-gray-400">dB</p>
</div>
<div class="bg-purple-50 dark:bg-purple-900/20 rounded-lg p-4">
<p class="text-xs text-gray-600 dark:text-gray-400 mb-1">Lmin (Min)</p>
<p id="diag-lmin" class="text-2xl font-bold text-purple-600 dark:text-purple-400">--</p>
<p class="text-xs text-gray-500 dark:text-gray-400">dB</p>
</div>
</div>
<!-- Battery and Power -->
<div class="grid grid-cols-2 gap-3 mb-4">
<div class="bg-white dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700">
<div class="flex items-center justify-between mb-2">
<span class="text-xs text-gray-600 dark:text-gray-400">Battery</span>
<svg class="w-4 h-4 text-gray-500" fill="currentColor" viewBox="0 0 20 20">
<path d="M6 2a2 2 0 00-2 2v12a2 2 0 002 2h8a2 2 0 002-2V4a2 2 0 00-2-2H6zm0 2h8v12H6V4zm7 2a1 1 0 011 1v6a1 1 0 11-2 0V7a1 1 0 011-1z"/>
</svg>
</div>
<div id="diag-battery-level" class="text-xl font-bold text-gray-900 dark:text-white">--</div>
<div class="mt-2 bg-gray-200 dark:bg-gray-700 rounded-full h-2">
<div id="diag-battery-bar" class="bg-gray-400 h-2 rounded-full transition-all" style="width: 0%"></div>
</div>
</div>
<div class="bg-white dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700">
<div class="flex items-center justify-between mb-2">
<span class="text-xs text-gray-600 dark:text-gray-400">Power</span>
<svg class="w-4 h-4 text-gray-500" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M11.3 1.046A1 1 0 0112 2v5h4a1 1 0 01.82 1.573l-7 10A1 1 0 018 18v-5H4a1 1 0 01-.82-1.573l7-10a1 1 0 011.12-.38z" clip-rule="evenodd"/>
</svg>
</div>
<div id="diag-power-source" class="text-lg font-semibold text-gray-900 dark:text-white">--</div>
</div>
</div>
<!-- Last Check-in -->
<div class="bg-white dark:bg-gray-800 rounded-lg p-4 border border-gray-200 dark:border-gray-700 mb-6">
<div class="flex items-center justify-between">
<div class="flex items-center">
<svg class="w-5 h-5 text-gray-500 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm1-12a1 1 0 10-2 0v4a1 1 0 00.293.707l2.828 2.829a1 1 0 101.415-1.415L11 9.586V6z" clip-rule="evenodd"/>
</svg>
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Last Check-in</span>
</div>
<div>
{% if unit.slm_last_check %}
<span class="text-sm text-gray-600 dark:text-gray-400">{{ unit.slm_last_check.strftime('%Y-%m-%d %H:%M:%S') }}</span>
{% else %}
<span class="text-sm text-gray-500 dark:text-gray-500">Never</span>
{% endif %}
</div>
</div>
</div>
<!-- Open Command Center Button -->
<div class="mt-auto">
<button onclick="openCommandCenter('{{ unit.id }}')"
class="w-full px-6 py-3 bg-seismo-orange hover:bg-orange-600 text-white rounded-lg font-medium flex items-center justify-center transition-colors">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19V6l12-3v13M9 19c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zm12-3c0 1.105-1.343 2-3 2s-3-.895-3-2 1.343-2 3-2 3 .895 3 2zM9 10l12-3"/>
</svg>
Open Command Center
</button>
</div>
</div>
<script>
(function() {
const diagUnitId = '{{ unit.id }}';
// Clear any existing connections before starting new ones
window.SLMConnectionManager.setCurrentUnit(diagUnitId);
function updateDiagnosticsData() {
fetch(`/api/slmm/${diagUnitId}/live`)
.then(response => response.json())
.then(result => {
if (result.status === 'ok' && result.data) {
const data = result.data;
// Update status badge
const statusBadge = document.getElementById('diag-status-badge');
if (statusBadge) {
const isMeasuring = data.measurement_state === 'Start';
if (isMeasuring) {
statusBadge.className = 'px-4 py-2 bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-400 rounded-lg font-medium flex items-center';
statusBadge.innerHTML = '<span class="w-2 h-2 bg-green-500 rounded-full mr-2 animate-pulse"></span>Measuring';
} else {
statusBadge.className = 'px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-700 dark:text-gray-300 rounded-lg font-medium';
statusBadge.textContent = 'Stopped';
}
}
// Update sound levels
['lp', 'leq', 'lmax', 'lmin'].forEach(metric => {
const el = document.getElementById(`diag-${metric}`);
if (el) el.textContent = data[metric] || '--';
});
// Update battery
const batteryEl = document.getElementById('diag-battery-level');
const batteryBar = document.getElementById('diag-battery-bar');
if (batteryEl && data.battery_level) {
const level = parseInt(data.battery_level);
batteryEl.textContent = `${level}%`;
if (batteryBar) {
batteryBar.style.width = `${level}%`;
if (level > 50) {
batteryBar.className = 'bg-green-500 h-2 rounded-full transition-all';
} else if (level > 20) {
batteryBar.className = 'bg-yellow-500 h-2 rounded-full transition-all';
} else {
batteryBar.className = 'bg-red-500 h-2 rounded-full transition-all';
}
}
}
// Update power source
const powerEl = document.getElementById('diag-power-source');
if (powerEl) powerEl.textContent = data.power_source || '--';
// Update connection status
const connStatus = document.getElementById('connection-status');
if (connStatus) {
connStatus.className = 'ml-2 w-2 h-2 bg-green-500 rounded-full inline-block';
}
}
})
.catch(error => {
console.error('Failed to refresh diagnostics:', error);
const connStatus = document.getElementById('connection-status');
if (connStatus) {
connStatus.className = 'ml-2 w-2 h-2 bg-red-500 rounded-full inline-block';
}
});
}
// Initial update
updateDiagnosticsData();
// Set up refresh interval and register it
const interval = setInterval(updateDiagnosticsData, 10000);
window.SLMConnectionManager.registerInterval(interval);
console.log(`Diagnostics card for ${diagUnitId} initialized`);
})();
</script>