feat(sensors): numeric -n mode + lmsensors_n extend for HA SNMP migration [#618]
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
Reference in New Issue
Block a user