HVAC FDD Rule Cookbook
Open-source, standards-first fault detection for commercial HVAC. Rules use generic semantic variables / Haystack roles (discharge-air-temp, outside-air-temp, fan-cmd, …) — portable across modeled sites and generic BAS telemetry.
Two catalogs (do not conflate):
| Catalog | Count | Role |
|---|---|---|
DataFusion SQL — sql_rules/registry.yaml |
66 | Production FDD in Open-FDD Rust / central (POST /api/fdd/run) |
Pandas — open_fdd.rules (pip install "open-fdd[oracle]") |
62 | Oracle / docs / notebooks — packaged on PyPI; consumers pin the wheel |
Parity honesty (parity matrix, generated report): see live sql_rules/registry.yaml counts. SQL presence ≠ oracle-proven. Do not claim “54 full parity.”
Two cookbooks — complementary, not identical
| Cookbook | Runtime | Use when |
|---|---|---|
| DataFusion SQL | Open-FDD central / edge | Live historian, registry SQL FDD, confirmation engine |
| Pandas | Docs + PyPI oracle | CSV exports, notebooks, RCx studies, parity oracles |
SQL adds rollups (FAN-RUNTIME-HOURS, AVG-ZONE-TEMP, ZONE-COMFORT-PCT, FAULT-ELAPSED-HOURS) and aliases FC13 → FC13-SAT-HIGH. Rolling / multi-sensor screens (e.g. SV-RATE, PID-HUNT-1) may ship a simplified SQL variant with an explicit caveat — full logic stays Pandas-validated until proven.
Product UI is the React SPA. Pandas stays on PyPI for third-party tooling.
Framework
| Doc | Description |
|---|---|
| P0 rule catalog | Full metadata for every validated rule |
| Public taxonomy | Equipment classes, rule families, severity |
| Rule schema | Declarative metadata — compiles to SQL + Pandas |
| Gap matrix | Coverage vs ASHRAE GL36, Berkeley, PNNL, NIST |
| Parity matrix | SQL ↔ Pandas audit |
| Roadmap | Priority-ranked expansion |
| Prerequisite macros | Occupancy, fan proven, override / operational gates |
| Benchmark strategy | Fixtures + regression (scripts/cookbook_parity_check.py) |
| Doc template | Standard per-rule documentation |
Rule inventory (validated)
| Family | Count | Examples |
|---|---|---|
| Sensor validation (sweep) | 5 | SV-RANGE, SV-FLATLINE, SV-SPIKE, SV-STALE, SV-RATE |
| Control hunting | 1 | PID-HUNT-1 |
| Air handling / economizer | 32 | FC1–FC15, ECON-1–7, OAT-METEO, VLV-1, DMP-1, CMD-1, RESET-1 |
| VAV terminals | 9 | VAV-1–7, VAV-REHEAT, VAV-AHU-LEAVE |
| Central plant / CW | 8 | CHW-1–4, CHW-NOLOAD-1, CW-APR-1, CW-FAN-1, CW-OPT-1 |
| Heat pump | 1 | HP-1 |
| Weather | 1 | WX-1 |
| Trim & respond | 3 | TRIM-1, TRIM-3, TRIM-4 |
| Schedule | 2 | SCHED-1, SCHED-247 |
Total validated: 62. Default confirmation: 300 s (5 min) unless noted per rule.
Additional rules documented under Not yet in validated catalog remain in the cookbooks for continuity (flagged, not legacy UI-parity-tested).
Quick start
- Assignments — bind driver points → Haystack → FDD inputs (modeling guide)
- Plots — confirm historian columns
- SQL FDD Rules — paste SQL, test with
confirmation_seconds: 300, activate (integrator) - Pandas parity — export same window, run matching Pandas section
API quick test
curl -s -X POST http://127.0.0.1:8080/api/fdd-rules/RULE_ID/test-sql \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"sql":"<SELECT ... fault_raw>","confirmation_seconds":300}' | jq '.ok, .engine'
Safety (edge)
- SELECT only — DDL/DML rejected
- Every rule exposes
fault_raw(boolean) - Integrator JWT required to activate rules
- Thresholds are defaults — always site-adjustable