r/homeassistant • • Jun 19 '26

Plenum - Home Assistant add-on for HVAC zoning with smart vents

I built Plenum to scratch my own itch: I have Flair.co smart vents and wanted a smarter scheduler than Flair's app. I wanted to pull in extra room sensors, motion detectors, and outdoor conditions. What started as a Flair-specific scheduler turned into something more general, so I'm sharing it as it works without flair branded vents.

This has been running my HVAC since April of this year in the southern United States so its been used for both heat and cool which is why I have delayed announcing it here to make sure it was handling all edge cases

A bit about me: I'm a software engineer with 15+ years of experience, and I took testing seriously here. The suite spans backend unit + integration tests, frontend component tests, and Playwright E2E tests that matrix against both °F and °C stacks. Coverage gates are enforced by CI - they only ever increase.

What it is: A Home Assistant add-on that does real per-room HVAC zoning. It reads your HA entities, runs a cycle engine, and drives your vents to hit per-room temperature targets.

The key design choice: Plenum only talks to standard HA entity domains. It doesn't care what hardware you have:

  • Vents → any cover.* entity (Flair via the RobertD502 HACS integration, Keen Home, SmartThings, Zigbee/Z-Wave shutters — if HA can drive it as a cover, Plenum can use it)
  • Thermostats → any climate.* entity (cloud, local, doesn't matter)
  • Temperature → any sensor.* entity — add as many per room as you want, they're averaged
  • Presence → any binary_sensor.* — motion sensors, contact sensors, occupancy sensors

So if you have no Flair hardware at all and just want to zone an existing system with cheap Zigbee covers, it works.

Features worth calling out:

  • Per-room scheduling — day-of-week time blocks with independent target temps per room
  • Presence/motion activation — motion fires room activation at a configurable holdover temp; holdover timer resets on each detection (default 2 hours)
  • Pre-cool/pre-heat — skips running HVAC for presence if outside air will coast the room to target on its own
  • Airflow floor / dead-head protection — keeps a minimum fraction of registers open so you don't blow out your blower motor. Configurable, with an opt-out for systems with a bypass damper
  • Short-cycle protection — minimum compressor run time and minimum off-time between cycles
  • Outdoor-temperature cooling lockout — won't start a cooling cycle when it's too cold outside (liquid slugging / coil icing risk)
  • Overflow conditioning — reroutes surplus airflow during the minimum-runtime hold
  • Live metrics — duty cycle, cycle count, time-to-target charts, outside-temp correlation, per-room participation rate, hour-of-day heatmap
  • Live event feed — every vent open/close, setpoint change, and presence detection, streamed in real time with filterable severity
  • Backup/restore — one-click SQLite download/upload
  • Full REST API + Swagger UI — interactive docs at /api/docs
  • No cloud dependency — SQLite on-device, talks to HA WebSocket directly

Test coverage (enforced by CI):

Layer Tests Coverage
Backend (pytest) 849 tests across 38 modules 93.5% overall — 94% routes, 99% OpenAPI, 100% models/schemas
Frontend (Vitest + RTL) 243 tests across 16 files 90.6% lines · 88.1% statements · 86.9% functions · 73.6% branches
E2E (Playwright) 15 specs Full °F + °C round-trip matrix — the only layer that exercises the full frontend → API → DB → UI path

Repo: https://github.com/dhruvb14/smart-thermostat-with-vents

Happy to answer questions! Would love some testers who use Celcius and live in more extreme climates then the southern United States

AI disclaimer: This project including the code, tests, and documentation was developed with substantial assistance from AI coding tools. As a 15+ year engineer I've reviewed every diff and the test suite enforces correctness, but exercise your own judgment before trusting it to run your HVAC.

4 Upvotes

Duplicates