Epic: More Metrics
Why
Today temperature.go reports only the CPU/SoC thermal zone (plus the same-die "GPU" value via vcgencmd). But a Pi can expose several genuinely separate temperature sensors through the kernel hwmon subsystem — depending on the board and attached hardware: the SoC sensor itself, a PoE-HAT fan controller, NVMe/SSD drives (notably on Pi 5), and user-attached I²C/1-Wire sensors (e.g. DS18B20, BME280, LM75). The fixed thermal-zone lookup can't see these. A generic hwmon collector surfaces all present sensors automatically, with no extra dependency and no vcgencmd.
Scope
Add a collector that walks /sys/class/hwmon/hwmon*/:
- For each
temp*_input file (millidegrees Celsius, integer), read the value.
- Read the sibling
temp*_label for a human-readable name when present; fall back to the chip name file + channel index otherwise.
- Return a list of
{chip, label, celsius} entries.
This is pure sysfs parsing, fixture-testable, and follows the existing collector pattern. It naturally includes the SoC sensor and any attached/onboard sensors. Keep the parser independent of real /sys access (feed synthetic hwmon trees in tests).
Reuse & touch points
- New
internal/collector/hwmon.go + hwmon_test.go, following the collector + fixture-test pattern (see cpu.go / cpu_test.go, and the millidegree parsing in temperature.go readThermalZoneMilliC, line 58).
- Reuse
testhelpers_test.go (writeTempFile) to build synthetic hwmon*/temp*_input + temp*_label trees.
- New
Sensors []TemperatureSensor field in internal/collector/types.go; assemble in collector.go.
- Optionally show extra sensors in the Temperature card (
internal/web/assets/).
API & config impact
Additive sensors[] array in the snapshot (omitempty when none); no breaking change. Consider a hwmon_enabled config toggle. Update docs/API.md.
Acceptance criteria
- A synthetic
hwmon tree with multiple chips/channels parses to the expected {chip, label, celsius} list, including correct millidegree→°C conversion.
- Missing
temp*_label falls back to chip name + index.
- Off-Pi / no
hwmon directory: empty list, no error.
Relationship to existing temperature collector & D6
- The existing dedicated CPU-temperature reading (
temperature.go) stays as the primary, clearly-labelled value for the dashboard gauge; this collector is additive breadth, not a replacement (avoids changing the existing temperature JSON shape — v1 stability).
- The Pi PMIC sensor is not exposed via hwmon on Raspberry Pi OS, so it is out of scope here and handled separately in D6 (
vcgencmd measure_temp pmic). D6 and D7 are complementary.
Epic: More Metrics
Why
Today
temperature.goreports only the CPU/SoC thermal zone (plus the same-die "GPU" value viavcgencmd). But a Pi can expose several genuinely separate temperature sensors through the kernelhwmonsubsystem — depending on the board and attached hardware: the SoC sensor itself, a PoE-HAT fan controller, NVMe/SSD drives (notably on Pi 5), and user-attached I²C/1-Wire sensors (e.g. DS18B20, BME280, LM75). The fixed thermal-zone lookup can't see these. A generichwmoncollector surfaces all present sensors automatically, with no extra dependency and novcgencmd.Scope
Add a collector that walks
/sys/class/hwmon/hwmon*/:temp*_inputfile (millidegrees Celsius, integer), read the value.temp*_labelfor a human-readable name when present; fall back to the chipnamefile + channel index otherwise.{chip, label, celsius}entries.This is pure sysfs parsing, fixture-testable, and follows the existing collector pattern. It naturally includes the SoC sensor and any attached/onboard sensors. Keep the parser independent of real
/sysaccess (feed synthetic hwmon trees in tests).Reuse & touch points
internal/collector/hwmon.go+hwmon_test.go, following the collector + fixture-test pattern (seecpu.go/cpu_test.go, and the millidegree parsing intemperature.goreadThermalZoneMilliC, line 58).testhelpers_test.go(writeTempFile) to build synthetichwmon*/temp*_input+temp*_labeltrees.Sensors []TemperatureSensorfield ininternal/collector/types.go; assemble incollector.go.internal/web/assets/).API & config impact
Additive
sensors[]array in the snapshot (omitemptywhen none); no breaking change. Consider ahwmon_enabledconfig toggle. Updatedocs/API.md.Acceptance criteria
hwmontree with multiple chips/channels parses to the expected{chip, label, celsius}list, including correct millidegree→°C conversion.temp*_labelfalls back to chipname+ index.hwmondirectory: empty list, no error.Relationship to existing temperature collector & D6
temperature.go) stays as the primary, clearly-labelled value for the dashboard gauge; this collector is additive breadth, not a replacement (avoids changing the existingtemperatureJSON shape — v1 stability).vcgencmd measure_temp pmic). D6 and D7 are complementary.