Initial import: nasmon health monitor, split out of home_nas
Go service (nasmon/) plus nfpm packaging (packaging/), carried over from the home_nas monorepo. Adds rpm packaging alongside the existing deb build (Fedora/RHEL/Rocky dependency names via nfpm overrides, per-format systemd unit path, dpkg+rpm-compatible maintainer scripts) and a Gitea Actions workflow that builds both formats on every push. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
package collect
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Temp struct {
|
||||
Chip string `json:"chip"`
|
||||
Label string `json:"label"`
|
||||
C float64 `json:"c"`
|
||||
}
|
||||
|
||||
// ReadTemps lists every hwmon temperature input; falls back to thermal zones.
|
||||
func ReadTemps() []Temp {
|
||||
temps := readHwmon("/sys/class/hwmon")
|
||||
if len(temps) == 0 {
|
||||
temps = readThermalZones("/sys/class/thermal")
|
||||
}
|
||||
sort.Slice(temps, func(i, j int) bool {
|
||||
if temps[i].Chip != temps[j].Chip {
|
||||
return temps[i].Chip < temps[j].Chip
|
||||
}
|
||||
return temps[i].Label < temps[j].Label
|
||||
})
|
||||
return temps
|
||||
}
|
||||
|
||||
func readHwmon(root string) []Temp {
|
||||
var out []Temp
|
||||
chips, _ := filepath.Glob(filepath.Join(root, "hwmon*"))
|
||||
for _, chip := range chips {
|
||||
name := readTrim(filepath.Join(chip, "name"))
|
||||
inputs, _ := filepath.Glob(filepath.Join(chip, "temp*_input"))
|
||||
for _, in := range inputs {
|
||||
v, err := strconv.ParseFloat(readTrim(in), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
base := strings.TrimSuffix(in, "_input")
|
||||
label := readTrim(base + "_label")
|
||||
if label == "" {
|
||||
label = filepath.Base(base)
|
||||
}
|
||||
out = append(out, Temp{Chip: name, Label: label, C: v / 1000})
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func readThermalZones(root string) []Temp {
|
||||
var out []Temp
|
||||
zones, _ := filepath.Glob(filepath.Join(root, "thermal_zone*"))
|
||||
for _, z := range zones {
|
||||
v, err := strconv.ParseFloat(readTrim(filepath.Join(z, "temp")), 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
out = append(out, Temp{Chip: "thermal", Label: readTrim(filepath.Join(z, "type")), C: v / 1000})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// CPUTemp picks the most plausible CPU package temperature from the list.
|
||||
func CPUTemp(temps []Temp) (float64, bool) {
|
||||
best, found := 0.0, false
|
||||
for _, t := range temps {
|
||||
chip := strings.ToLower(t.Chip)
|
||||
lbl := strings.ToLower(t.Label)
|
||||
isCPU := chip == "coretemp" || chip == "k10temp" || chip == "zenpower" ||
|
||||
strings.Contains(lbl, "package") || strings.Contains(lbl, "tctl") || strings.Contains(lbl, "tdie") ||
|
||||
strings.Contains(lbl, "x86_pkg_temp") || strings.Contains(lbl, "cpu")
|
||||
if isCPU && (!found || t.C > best) {
|
||||
best, found = t.C, true
|
||||
}
|
||||
}
|
||||
return best, found
|
||||
}
|
||||
|
||||
func readTrim(p string) string {
|
||||
b, err := os.ReadFile(p)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(string(b))
|
||||
}
|
||||
Reference in New Issue
Block a user