lm-sensors is silent on SBCs (Pis, Jetson-class), so the wrapper now falls
back to /sys/class/thermal zones rendered in lm-sensors format when native
sensors output is empty; suppressed when native output exists to avoid
duplicates. TDD: 3 new unit tests (12 green). Sensor stack deployed to
jetson + pfvsvrpi + 3 subopis (verified from poller), HA pack extended to
16 sensors across 14 hosts, high-temp automation covers the SBC fleet.
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
293 lines
11 KiB
YAML
293 lines
11 KiB
YAML
# PFV physical-plant SNMP sensors for Home Assistant [#439]
|
|
#
|
|
# Paste the sensor block below into pfv-bms configuration.yaml (or an
|
|
# !include). All temperatures are converted C to F at the display layer per
|
|
# founder ruling 2026-08-27 (transport stays lm-sensors format, °C).
|
|
#
|
|
# Source: lmsensors-extend snmpd extend, deployed on all 7 Proxmox hosts +
|
|
# stlpc-artroom + stlpc-garage (see dcinfra/sensors/temper/).
|
|
# Extend OID: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
#
|
|
# Hosts resolve via knel.net DNS from pfv-bms (verify in Developer Tools >
|
|
# States after reload; if a host shows 'unknown' check DNS + the snmpd
|
|
# source ACL which already includes the pfv-bms LAN IP 192.168.3.12).
|
|
#
|
|
# Per founder ruling (#343): LibreNMS does NOT graph temperatures; these HA
|
|
# sensors are the canonical environmental record for the plant.
|
|
|
|
sensor:
|
|
# --- TEMPer USB probe hosts (External probe, Internal fallback) ---
|
|
- platform: snmp
|
|
name: "PFV artroom temperature"
|
|
host: stlpc-artroom.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_artroom_temperature
|
|
value_template: >-
|
|
{% set ext = value | regex_findall('External:\s*\+?(-?\d+\.?\d*)') %}
|
|
{% set int = value | regex_findall('Internal:\s*\+?(-?\d+\.?\d*)') %}
|
|
{% set c = (ext | first) if ext else ((int | first) if int else none) %}
|
|
{{ ((c | float * 9 / 5) + 32) | round(1) if c is not none else 'unknown' }}
|
|
|
|
- platform: snmp
|
|
name: "PFV garage temperature"
|
|
host: stlpc-garage.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_garage_temperature
|
|
value_template: >-
|
|
{% set ext = value | regex_findall('External:\s*\+?(-?\d+\.?\d*)') %}
|
|
{% set int = value | regex_findall('Internal:\s*\+?(-?\d+\.?\d*)') %}
|
|
{% set c = (ext | first) if ext else ((int | first) if int else none) %}
|
|
{{ ((c | float * 9 / 5) + 32) | round(1) if c is not none else 'unknown' }}
|
|
|
|
- platform: snmp
|
|
name: "PFV tsys1 rack temperature"
|
|
host: pfv-tsys1.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_tsys1_rack_temperature
|
|
value_template: >-
|
|
{% set ext = value | regex_findall('External:\s*\+?(-?\d+\.?\d*)') %}
|
|
{% set int = value | regex_findall('Internal:\s*\+?(-?\d+\.?\d*)') %}
|
|
{% set c = (ext | first) if ext else ((int | first) if int else none) %}
|
|
{{ ((c | float * 9 / 5) + 32) | round(1) if c is not none else 'unknown' }}
|
|
|
|
# --- Native lm-sensors hosts (label picked per host ground truth 2026-08-27) ---
|
|
# tsys3 Precision 7510: CPU package
|
|
- platform: snmp
|
|
name: "PFV tsys3 CPU temperature"
|
|
host: pfv-tsys3.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_tsys3_cpu_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('Package id 0:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
# tsys4 Precision T1700: Dell SMM ambient (board inlet)
|
|
- platform: snmp
|
|
name: "PFV tsys4 ambient temperature"
|
|
host: pfv-tsys4.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_tsys4_ambient_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('Ambient:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
# tsys5 Precision T7500: Dell SMM ambient (board inlet)
|
|
- platform: snmp
|
|
name: "PFV tsys5 ambient temperature"
|
|
host: pfv-tsys5.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_tsys5_ambient_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('Ambient:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
# tsys6 PowerEdge R610: socket-0 core temp (no Package label on Westmere)
|
|
- platform: snmp
|
|
name: "PFV tsys6 CPU temperature"
|
|
host: pfv-tsys6.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_tsys6_cpu_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('Core 0:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
# tsys6 ACPI power meter (node draw, watts)
|
|
- platform: snmp
|
|
name: "PFV tsys6 node power"
|
|
host: pfv-tsys6.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: power
|
|
state_class: measurement
|
|
unit_of_measurement: "W"
|
|
unique_id: pfv_tsys6_node_power
|
|
value_template: >-
|
|
{% set m = value | regex_findall('power1:\s*(\d+\.?\d*)\s*W') %}
|
|
{{ m | first | float if m else 'unknown' }}
|
|
|
|
# tsys7 PowerEdge R620: package temp
|
|
- platform: snmp
|
|
name: "PFV tsys7 CPU temperature"
|
|
host: pfv-tsys7.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_tsys7_cpu_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('Package id 0:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
# tsys7 ACPI power meter (node draw, watts)
|
|
- platform: snmp
|
|
name: "PFV tsys7 node power"
|
|
host: pfv-tsys7.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: power
|
|
state_class: measurement
|
|
unit_of_measurement: "W"
|
|
unique_id: pfv_tsys7_node_power
|
|
value_template: >-
|
|
{% set m = value | regex_findall('power1:\s*(\d+\.?\d*)\s*W') %}
|
|
{{ m | first | float if m else 'unknown' }}
|
|
|
|
# tsys9 OptiPlex 7080: package temp
|
|
- platform: snmp
|
|
name: "PFV tsys9 CPU temperature"
|
|
host: pfv-tsys9.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_tsys9_cpu_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('Package id 0:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
# --- SBC fleet (sysfs thermal fallback in lmsensors-extend v2; temp1 = zone0/SoC) ---
|
|
- platform: snmp
|
|
name: "PFV jetson temperature"
|
|
host: pfv-jetson-nano-1.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_jetson_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('temp1:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
- platform: snmp
|
|
name: "PFV svrpi temperature"
|
|
host: pfvsvrpi.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_svrpi_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('temp1:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
- platform: snmp
|
|
name: "PFV subopi3 temperature"
|
|
host: subopi3.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_subopi3_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('temp1:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
- platform: snmp
|
|
name: "PFV subopi-dev-3 temperature"
|
|
host: subopi-dev-3.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_subopi_dev_3_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('temp1:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
- platform: snmp
|
|
name: "PFV subopi-dev-4 temperature"
|
|
host: subopi-dev-4.knel.net
|
|
version: 2c
|
|
community: kn3lmgmt
|
|
baseoid: .1.3.6.1.4.1.8072.1.3.2.3.1.2.9.108.109.115.101.110.115.111.114.115
|
|
accept_errors: true
|
|
device_class: temperature
|
|
state_class: measurement
|
|
unit_of_measurement: "°F"
|
|
unique_id: pfv_subopi_dev_4_temperature
|
|
value_template: >-
|
|
{% set m = value | regex_findall('temp1:\s*\+?(-?\d+\.?\d*)') %}
|
|
{{ ((m | first | float * 9 / 5) + 32) | round(1) if m else 'unknown' }}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# PLACEHOLDERS — enable after dependencies land (do not invent OIDs live):
|
|
#
|
|
# Garage PDU (AP7830, SNMPv1, HA owns PDU power graphing per #343 ruling):
|
|
# Needs the custom v1 community from LibreNMS (founder: supply value as a
|
|
# HA secret) + OID discovery via snmpwalk of .1.3.6.1.4.1.318 subtree.
|
|
# - platform: snmp
|
|
# name: "PFV garage PDU current"
|
|
# host: <pdu-dns-name>
|
|
# version: 1
|
|
# community: !secret pdu_community
|
|
# baseoid: <discover: bank current OID>
|
|
#
|
|
# iDRAC6 feeds (pfv-tsys6-oob / pfv-tsys7-oob, community kn3lmgmt) once the
|
|
# OOB ports are cabled (#460): inlet temp + system power via Dell PowerNet
|
|
# MIB. OIDs to be walked and pinned post-cabling.
|
|
# ---------------------------------------------------------------------------
|