# ๐Ÿ  pfv-bms โ€” the house brain > **Datacenter-grade monitoring and access control for a private residence + server room** โ€” > 372 entities, ~260 sensors, and a badge-actuated door, all deployed by `git push`. ![license](https://img.shields.io/badge/license-AGPLv3-blue) ![HA](https://img.shields.io/badge/Home%20Assistant-2026.8.3-41bdf5?logo=homeassistant&logoColor=white) ![HAOS](https://img.shields.io/badge/HAOS-18.2-orange) ![deploy](https://img.shields.io/badge/deploy-git%20push%20%E2%86%92%20live-4EAA25) ![entities](https://img.shields.io/badge/entities-372-9c27b0) Production Home Assistant configuration for the Turnsys PFV โ€” environmental monitoring (temperatures, power, UPS) across a seven-node Proxmox fleet plus single-board computers, server-room badge access control, and tiered alerting to mobile devices. Work tracking: [Redmine](https://projects.knownelement.com) ([#344](https://projects.knownelement.com/issues/344) umbrella) ยท Docs: [VP TechOps on Discourse](https://community.turnsys.com/c/vp-techops) --- ## ๐Ÿ—บ๏ธ System architecture ```mermaid flowchart LR subgraph FIELD[๐Ÿ“ก The field] TS[๐Ÿ–ฅ๏ธ 7ร— Proxmox hosts
lm-sensors + iDRAC extends] BOARDS[๐Ÿฅง SBCs
pfvsvrpi ยท jetson ยท 3ร— subopi] UPS[๐Ÿ”‹ UPS on tsys1
NUT server :3493] PDU[๐Ÿ”Œ Garage PDU
SNMPv1 relay] METER[โšก Utility meter
Smart Meter Texas] READER[๐Ÿชช Badge readers
pfvsvrpi ยท ultix-field] end subgraph HA[๐Ÿ  pfv-bms โ€” this repo] INGEST[๐Ÿ“ฆ packages/plant_snmp.yaml
SNMP pollers โ†’ raw sensors] TEMPLATE[๐Ÿงฎ template sensors
raw โ†’ ยฐF/units + thresholds] DOOR[๐Ÿšช packages/doorman.yaml
scan ingest + decision engine] ROSTER[๐Ÿ”’ roster sensors
REST poll of private access-roster] ENERGY[๐Ÿ“Š utility_meter +
Riemann-sum energy] AUTO[๐Ÿšจ automations.yaml
tiered thermal + UPS alerts] end subgraph OUT[๐Ÿ“ฒ Outcomes] ALERT[๐Ÿ“ฑ push alerts
companion apps] LOG[๐Ÿ““ logbook + history
every scan, every degree] DASH[๐Ÿ–ฅ๏ธ dashboards
server-room + plant] RELAY[โšก doorctl โ†’ usbrelay
โ†’ door strike] end READER -->|webhook| DOOR DOOR -->|whitelist| ROSTER DOOR -->|armed + valid| RELAY TS & BOARDS -->|SNMP| INGEST UPS -->|NUT| INGEST PDU -->|SNMP relay| INGEST METER -->|REST| INGEST INGEST --> TEMPLATE --> AUTO INGEST --> ENERGY AUTO --> ALERT TEMPLATE & DOOR --> LOG & DASH ``` ### ๐Ÿ›ก๏ธ Badge access lane (server-room door) | Component | Role | Lives | |-----------|------|-------| | USB HID readers | 13.56 MHz badge readers (keyboard-emulating) | door + dev bench | | [`KNEL/doorman`](https://git.knownelement.com/KNEL/doorman) | pure-bash listener, decode, webhook, doorctl | `pfvsvrpi` (prod), `ultix-field` (dev) | | `packages/doorman.yaml` | scan ingest, whitelist decision, alerts, unlock dispatch | **this repo** | | [`KNEL/access-roster`](https://git.knownelement.com/KNEL/access-roster) ๐Ÿ”’ | badge IDs + holders โ€” **private**, two-human PR gate | gitea (private) | | `doorctl` + usbrelay | socket-activated, token + source-IP ACL, EXIT-trap secured | `pfvsvrpi` | Fail-closed end to end: HA unreachable โ†’ the door does not open. Break-glass badges fire the relay locally (works with HA down) and report `local_unlock` so HA never double-fires. Arm switch (`input_boolean.doorman_unlock_enabled`) is founder-level control. Verified end-to-end 2026-09-03: real armed scan โ†’ dispatch โ†’ relay. --- ## ๐ŸŒก๏ธ Environmental monitoring Raw SNMP pollers (`packages/plant_snmp.yaml`) โ†’ unit-normalized template sensors โ†’ tiered automations. Every host contributes lm-sensors extends; iDRAC hosts add inlet/exhaust/CPU; NUT feeds UPS electricals. | Family | Coverage | |--------|----------| | ๐Ÿ–ฅ๏ธ Host silicon | CPU/drive/NVMe/PCH temps on 7 Proxmox hosts | | ๐ŸŒก๏ธ Thermal zones | rack ambient, DIMM banks, GPU, tsys7 iDRAC inletโ†’exhaust ฮ”T | | ๐Ÿฅง Boards | pfvsvrpi, jetson, 3ร— subopi | | ๐Ÿ”‹ UPS | tsys1 battery charge/voltage, on-battery + runtime alerts | | โšก Power | whole-house kWh (utility), tsys6/7 node watts + kWh integrals, garage PDU amps | | ๐Ÿ  Rooms | temp/humidity/battery sensors (Govee, cloud-fed) | ### ๐Ÿšจ Alert tiers (automations.yaml) | Trigger | Threshold | |---------|-----------| | Drive / DIMM temps | > 140 ยฐF | | NVMe | > 150 ยฐF | | PCH | > 160 ยฐF | | GPU | > 185 ยฐF | | Ambient | > 104 ยฐF | | UPS | on-battery transitions + runtime | | Watchdog | plant sensor freshness sweep every 30 min | ### ๐Ÿ“Š Snapshot (2026-09-03) 372 entities ยท ~260 sensors ยท 45 temperature sensors ยท 21 electrical/energy sensors ยท 8 todo lists ยท 2-way alerting to companion apps. --- ## ๐Ÿ” Security model (read this before forking) - **No secrets in git, ever.** Everything sensitive is `!secret` indirection into an on-box `secrets.yaml` (gitignored). Verified by full-history scans. - **Badge IDs are NOT in this repo.** The roster lives in the *private* [`KNEL/access-roster`](https://git.knownelement.com/KNEL/access-roster) repo (two-human PR gate) and is fetched live at runtime. - **Fail-closed access control** โ€” see the badge lane above. - Battery room sensors and locks are cloud-fed; credentials also live in `secrets.yaml`. ## ๐Ÿš€ Deployment pipeline ```mermaid flowchart LR PUSH[๐Ÿ“ git push] --> HOOK[gitea webhook
fast path] PUSH --> SHA[sha-watch
safety net ยท 300 s poll] HOOK & SHA --> CHECK{changed files?} CHECK -->|packages/**| RESTART[โ™ป๏ธ core restart
webhook triggers need it] CHECK -->|other YAML| RELOAD[โšก reload only
~5 min to live] ``` Gate before pushing `packages/**`: `ha core check` must pass on-box. Measured end-to-end: 4 m 52 s commit โ†’ live. ## ๐Ÿ—บ๏ธ Repo map | Path | What | |------|------| | `configuration.yaml` | entrypoint + package includes | | `packages/doorman.yaml` | ๐Ÿšช badge scan ingest + decisions | | `packages/plant_snmp.yaml` | ๐ŸŒก๏ธ SNMP pollers + templates | | `automations.yaml` | ๐Ÿšจ tiered alerts + watchdogs | | `dashboards/` | Lovelace dashboards | | `tools/` | operator tooling (websocket CLI) | | `docs/reference-packs/` | historical YAML references โ€” NOT loaded | ## ๐Ÿ”— Related - Badge listener + relay code: [`KNEL/doorman`](https://git.knownelement.com/KNEL/doorman) - Wider fleet (Proxmox, DNS, monitoring): [`KNEL/PFVCluster`](https://git.knownelement.com/KNEL/PFVCluster) - Badge roster (private): `KNEL/access-roster` ๐Ÿ”’ ## License Copyright ยฉ 2026 Known Element Enterprises / Charles Wyble. This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See [LICENSE](LICENSE) for the full text.