- Remove audit/internal/tui/ (~3000 LOC, bubbletea/lipgloss/reanimator deps) - Add /api/* REST+SSE endpoints: audit, SAT (nvidia/memory/storage/cpu), services, network, export, tools, live metrics stream - Add async job manager with SSE streaming for long-running operations - Add platform.SampleLiveMetrics() for live fan/temp/power/GPU polling - Add multi-page web UI (vanilla JS): Dashboard, Metrics charts, Tests, Burn-in, Network, Services, Export, Tools - Add bee-desktop.service: openbox + Xorg + Chromium opening http://localhost/ - Add openbox/tint2/xorg/xinit/xterm/chromium to ISO package list - Update .profile, bee.sh, and bible-local docs Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
46 lines
1.3 KiB
Go
46 lines
1.3 KiB
Go
package platform
|
|
|
|
import "time"
|
|
|
|
// LiveMetricSample is a single point-in-time snapshot of server metrics
|
|
// collected for the web UI metrics page.
|
|
type LiveMetricSample struct {
|
|
Timestamp time.Time `json:"ts"`
|
|
Fans []FanReading `json:"fans"`
|
|
Temps []TempReading `json:"temps"`
|
|
PowerW float64 `json:"power_w"`
|
|
GPUs []GPUMetricRow `json:"gpus"`
|
|
}
|
|
|
|
// TempReading is a named temperature sensor value.
|
|
type TempReading struct {
|
|
Name string `json:"name"`
|
|
Celsius float64 `json:"celsius"`
|
|
}
|
|
|
|
// SampleLiveMetrics collects a single metrics snapshot from all available
|
|
// sources: GPU (via nvidia-smi), fans and temperatures (via ipmitool/sensors),
|
|
// and system power (via ipmitool dcmi). Missing sources are silently skipped.
|
|
func SampleLiveMetrics() LiveMetricSample {
|
|
s := LiveMetricSample{Timestamp: time.Now().UTC()}
|
|
|
|
// GPU metrics — skipped silently if nvidia-smi unavailable
|
|
gpus, _ := SampleGPUMetrics(nil)
|
|
s.GPUs = gpus
|
|
|
|
// Fan speeds — skipped silently if ipmitool unavailable
|
|
fans, _ := sampleFanSpeeds()
|
|
s.Fans = fans
|
|
|
|
// CPU/system temperature — returns 0 if unavailable
|
|
cpuTemp := sampleCPUMaxTemp()
|
|
if cpuTemp > 0 {
|
|
s.Temps = append(s.Temps, TempReading{Name: "CPU", Celsius: cpuTemp})
|
|
}
|
|
|
|
// System power — returns 0 if unavailable
|
|
s.PowerW = sampleSystemPower()
|
|
|
|
return s
|
|
}
|