mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-01 21:10:13 +00:00
fix: Add hasCPU/hasNVMe flags to prevent false 'no CPU sensor' errors
Addresses #101 v4.23.0 introduced a regression where systems with only NVMe temperatures (no CPU sensor) would display "No CPU sensor" in the UI. This was caused by the Available flag being set to true when NVMe temps existed, even without CPU data, triggering the error message in the frontend. Backend changes: - Add HasCPU and HasNVMe boolean fields to Temperature model - Extend CPU sensor detection to support more chip types: zenpower, k8temp, acpitz, it87 (case-insensitive matching) - HasCPU is set based on CPU chip detection (coretemp, k10temp, etc.), not value thresholds - This prevents false negatives when sensors report 0°C during resets - CPU temperature values now accepted even when 0 (checked with !IsNaN instead of > 0) - extractTempInput returns NaN instead of 0 when no data found - Available flag means "any temperature data exists" for backward compatibility - Update mock generator to properly set the new flags - Add unit tests for NVMe-only and 0°C scenarios to prevent regression - Removed amd_energy from CPU chip list (power sensor, not temperature) Frontend changes: - Add hasCPU and hasNVMe optional fields to Temperature interface - Update NodeSummaryTable to check hasCPU flag with fallback to available for backward compatibility with older API responses - Update NodeCard temperature display logic with same fallback pattern - Systems with only NVMe temps now show "-" instead of error message - Fallback ensures UI works with both old and new API responses Testing: - All unit tests pass including NVMe-only and 0°C test cases - Fix prevents false "no CPU sensor" errors when sensors temporarily report 0°C - Fix eliminates false "no CPU sensor" errors for NVMe-only systems
This commit is contained in:
parent
97066d8351
commit
dd9bd65a2e
7 changed files with 146 additions and 35 deletions
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -153,6 +154,8 @@ func (tc *TemperatureCollector) parseSensorsJSON(jsonStr string) (*models.Temper
|
|||
NVMe: []models.NVMeTemp{},
|
||||
}
|
||||
|
||||
foundCPUChip := false
|
||||
|
||||
// Parse each sensor chip
|
||||
for chipName, chipData := range sensorsData {
|
||||
chipMap, ok := chipData.(map[string]interface{})
|
||||
|
|
@ -160,8 +163,15 @@ func (tc *TemperatureCollector) parseSensorsJSON(jsonStr string) (*models.Temper
|
|||
continue
|
||||
}
|
||||
|
||||
// Handle CPU temperature sensors (coretemp, k10temp, etc.)
|
||||
if strings.Contains(chipName, "coretemp") || strings.Contains(chipName, "k10temp") {
|
||||
// Handle CPU temperature sensors
|
||||
chipLower := strings.ToLower(chipName)
|
||||
if strings.Contains(chipLower, "coretemp") ||
|
||||
strings.Contains(chipLower, "k10temp") ||
|
||||
strings.Contains(chipLower, "zenpower") ||
|
||||
strings.Contains(chipLower, "k8temp") ||
|
||||
strings.Contains(chipLower, "acpitz") ||
|
||||
strings.Contains(chipLower, "it87") {
|
||||
foundCPUChip = true
|
||||
tc.parseCPUTemps(chipMap, temp)
|
||||
}
|
||||
|
||||
|
|
@ -180,11 +190,13 @@ func (tc *TemperatureCollector) parseSensorsJSON(jsonStr string) (*models.Temper
|
|||
}
|
||||
}
|
||||
|
||||
if temp.CPUPackage > 0 || temp.CPUMax > 0 || len(temp.Cores) > 0 || len(temp.NVMe) > 0 {
|
||||
temp.Available = true
|
||||
} else {
|
||||
temp.Available = false
|
||||
}
|
||||
// Set individual sensor type flags based on chip presence, not value thresholds
|
||||
// This prevents false negatives when sensors report 0°C during resets or temporarily
|
||||
temp.HasCPU = foundCPUChip
|
||||
temp.HasNVMe = len(temp.NVMe) > 0
|
||||
|
||||
// Available means any temperature data exists (backward compatibility)
|
||||
temp.Available = temp.HasCPU || temp.HasNVMe
|
||||
|
||||
return temp, nil
|
||||
}
|
||||
|
|
@ -199,7 +211,7 @@ func (tc *TemperatureCollector) parseCPUTemps(chipMap map[string]interface{}, te
|
|||
|
||||
// Look for Package id (Intel) or Tdie (AMD)
|
||||
if strings.Contains(sensorName, "Package id") || strings.Contains(sensorName, "Tdie") {
|
||||
if tempVal := extractTempInput(sensorMap); tempVal > 0 {
|
||||
if tempVal := extractTempInput(sensorMap); !math.IsNaN(tempVal) {
|
||||
temp.CPUPackage = tempVal
|
||||
}
|
||||
}
|
||||
|
|
@ -207,7 +219,7 @@ func (tc *TemperatureCollector) parseCPUTemps(chipMap map[string]interface{}, te
|
|||
// Look for individual cores
|
||||
if strings.HasPrefix(sensorName, "Core ") {
|
||||
coreNum := extractCoreNumber(sensorName)
|
||||
if tempVal := extractTempInput(sensorMap); tempVal > 0 {
|
||||
if tempVal := extractTempInput(sensorMap); !math.IsNaN(tempVal) {
|
||||
temp.Cores = append(temp.Cores, models.CoreTemp{
|
||||
Core: coreNum,
|
||||
Temp: tempVal,
|
||||
|
|
@ -233,7 +245,7 @@ func (tc *TemperatureCollector) parseNVMeTemps(chipName string, chipMap map[stri
|
|||
|
||||
// Look for Composite temperature (main NVMe temp)
|
||||
if strings.Contains(sensorName, "Composite") || strings.Contains(sensorName, "Sensor 1") {
|
||||
if tempVal := extractTempInput(sensorMap); tempVal > 0 {
|
||||
if tempVal := extractTempInput(sensorMap); !math.IsNaN(tempVal) && tempVal > 0 {
|
||||
temp.NVMe = append(temp.NVMe, models.NVMeTemp{
|
||||
Device: device,
|
||||
Temp: tempVal,
|
||||
|
|
@ -261,7 +273,7 @@ func extractTempInput(sensorMap map[string]interface{}) float64 {
|
|||
}
|
||||
}
|
||||
}
|
||||
return 0
|
||||
return math.NaN()
|
||||
}
|
||||
|
||||
// extractCoreNumber extracts the core number from a sensor name like "Core 0"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue