feat(sensors): numeric -n mode + lmsensors_n extend for HA SNMP migration [#618]

This commit is contained in:
2026-09-01 18:02:09 -05:00
parent 196d0f597e
commit 7b922c507c
3 changed files with 99 additions and 1 deletions
+1
View File
@@ -127,6 +127,7 @@ sed -i 's/^agentaddress/#agentaddress/' "$SNMPD_CONF"
echo "rocommunity $COMMUNITY $src" echo "rocommunity $COMMUNITY $src"
done done
echo "extend lmsensors $WRAP_DST" echo "extend lmsensors $WRAP_DST"
echo "extend lmsensors_n $WRAP_DST -n"
echo "$MARK_END" echo "$MARK_END"
} >>"$SNMPD_CONF" } >>"$SNMPD_CONF"
log "agentaddress: $AGENT_ADDRS" log "agentaddress: $AGENT_ADDRS"
+34 -1
View File
@@ -37,6 +37,39 @@ format_block() {
} }
# True when a TEMPer USB dongle (0c45:7401) is attached and the venv exists. # True when a TEMPer USB dongle (0c45:7401) is attached and the venv exists.
# Numeric mode: print ONE Celsius float for snmpd extend lmsensors_n [#618].
# Preference: TEMPer external > TEMPer internal > first native/sysfs temp
# reading. Consumed by HA's SNMP config-entry integration (device_class
# temperature; HA renders C in the instance display unit).
numeric_pick() {
local internal="${1:-}" external="${2:-}" native="${3:-}" pick
local num_re='^-?[0-9]+(\.[0-9]+)?$'
for pick in "$external" "$internal"; do
pick="${pick#+}"
[[ "$pick" =~ $num_re ]] && { printf '%s\n' "$pick"; return 0; }
done
if [[ -n "$native" ]]; then
pick="$(grep -oE '\-?[0-9]+(\.[0-9]+)?' <<<"$native" | head -1)"
[[ "$pick" =~ $num_re ]] && { printf '%s\n' "$pick"; return 0; }
fi
return 1
}
numeric_main() {
local internal external line
if has_temper_probe; then
if read -r internal external <<<"$(read_temper 2>/dev/null)"; then
numeric_pick "${internal:-}" "${external:-}" "" && return 0
fi
fi
line="$(run_native_sensors | grep -m1 '°C')"
[[ -n "$line" ]] && numeric_pick "" "" "$line" && return 0
line="$(read_sysfs_thermal 2>/dev/null | head -1 | awk '{printf "+%.1f°C", $2/1000}')"
[[ -n "$line" ]] && numeric_pick "" "" "$line" && return 0
echo "error: numeric mode found no sensor source" >&2
return 1
}
has_temper_probe() { has_temper_probe() {
command -v lsusb >/dev/null 2>&1 || return 1 command -v lsusb >/dev/null 2>&1 || return 1
[[ -x "$VENV_PY" ]] || return 1 [[ -x "$VENV_PY" ]] || return 1
@@ -130,5 +163,5 @@ main() {
} }
if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
main if [[ "${1:-}" == "-n" ]]; then numeric_main; else main; fi
fi fi
+64
View File
@@ -0,0 +1,64 @@
#!/bin/bash
# Unit tests for lmsensors-extend.sh -n numeric mode [#618]
set -euo pipefail
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
SCRIPT="$PROJECT_ROOT/dcinfra/sensors/temper/lmsensors-extend.sh"
failed=0
if [[ -f "$SCRIPT" ]] && (source "$SCRIPT"); then
echo "✅ script exists + sources cleanly"
else
echo "❌ script missing or fails to source: $SCRIPT"
exit 1
fi
# shellcheck disable=SC1091
source "$SCRIPT"
# numeric_pick: TEMPer external > TEMPer internal > first native/sysfs value
test_numeric_prefers_external() {
if [[ "$(numeric_pick "22.5" "18.2" "" )" == "18.2" ]]; then
echo "✅ numeric_pick prefers external probe"
else
echo "❌ numeric_pick external preference broken"
((++failed))
fi
}
test_numeric_falls_back_internal() {
if [[ "$(numeric_pick "22.5" "" "")" == "22.5" ]]; then
echo "✅ numeric_pick falls back to internal"
else
echo "❌ numeric_pick internal fallback broken"
((++failed))
fi
}
test_numeric_uses_first_line_value() {
if [[ "$(numeric_pick "" "" "+27.5°C")" == "27.5" ]]; then
echo "✅ numeric_pick parses first native temp"
else
echo "❌ numeric_pick native parse broken: got '$(numeric_pick "" "" "+27.5°C")'"
((++failed))
fi
}
test_numeric_empty_is_error() {
if numeric_pick "" "" "" >/dev/null 2>&1; then
echo "❌ numeric_pick should fail on no data"
((++failed))
else
echo "✅ numeric_pick errors on no data"
fi
}
test_numeric_prefers_external
test_numeric_falls_back_internal
test_numeric_uses_first_line_value
test_numeric_empty_is_error
if ((failed > 0)); then
echo "$failed numeric-mode test(s) failed"
exit 1
fi
echo "✅ all numeric-mode tests passed"