CAMBER capabilities reference
A single index of what CAMBER does, grouped by the building-analytics layers, with the key API, the option flags that tune each capability, the module, and the standard it cites. Deeper write-ups are linked where they exist.
Everything is vendor-neutral via the Role model, dependency-light (stdlib + numpy / pandas /
pyarrow / matplotlib), and clean-room (every method cites a public standard; every rule ships a
synthetic fixture).
flowchart TD
src["BAS sources (CSV/SQL/Haystack/Modbus/MQTT/BACnet/OPC-UA)"] --> ingest["Ingest (SourceAdapter)"]
ingest --> model["Semantic model (Role + MappingProvider + entities)"]
model --> fdd["FDD (rules.Registry)"]
model --> mv["M&V (mandv change-point / TOWT)"]
model --> stream["Streaming (OnlineFDD / OnlineCusum / forecast)"]
model --> domain["Domain analytics (comfort/carbon/GEB/ventilation)"]
fdd --> triage["Triage + lifecycle (rules.triage / faultlifecycle)"]
triage --> advisory["Advisory (aso / actionplan / scorecard)"]
mv --> report["Reporting (AuditReport / fleet)"]
advisory --> report
domain --> report
report --> platform["Platform (store / api / integrate / plugins / charts)"]
The capability families, all speaking the vendor-neutral Role model.
Ingest
Adapters normalize any source to named point series on a common time grid (SourceAdapter:
point_names / load_points / units). See INGEST-PROTOCOLS.md and
SECURITY.md.
- CSV —
ingest.csv_perpoint.PerPointCsvAdapter(a folder of per-point files),ingest.csv_wide.WideCsvAdapter(one wide table), andingest.csv_long.LongCsvAdapter(timestamp,point,valuehistorian shape). Flags:resample,profile. - Vendor formats — one shared multi-format timestamp parser (
tsparse: ISO / US / EU-dayfirst / BAS / epoch / Excel-serial) + value/status coercion (coerce: thousands, null tokens, On/Off/Open/ Closed/Fault status) + named vendor profiles (ingest.profiles: niagara_n4/metasys/webctrl/tracer/ desigo).load_csv(..., profile=…). See INGEST-FORMATS.md. - Project-Haystack —
ingest.haystack.HaystackAdapterover an injectable transport (http_json_transport, orclient_transportto wrap a maintained client). Flags:range_str,resample. - SQL / historian —
ingest.sql.SqlSource/read_pointsover any PEP-249 connection. Flags:ts_col/point_col/value_col/unit_col,where. - Network protocols (read-only) — Modbus (
[modbus]), MQTT/Sparkplug ([mqtt]), BACnet incl. experimental BACnet/SC ([bacnet]), OPC-UA ([opcua]). Read-only by construction; historian-first posture. Per-adapter flags documented in INGEST-PROTOCOLS.md. - Data quality —
ingest.quality.assess(coverage, gaps, flatline, outliers, duplicate timestamps, composite score) andclean. Also reads two-regime structure (n_regimes/regime_threshold/regime_outlier_frac) so a duty-cycled point — a BTU meter, a lead pump, a status — is not scored as broken for cycling; a split is claimed only on mass and separation and temporal coherence, so a randomly-railed sensor is never mistaken for a schedule. Pooledoutlier_frackeeps its meaning and is never masked. Flags:expected_freq,drop_outliers,regime_aware(off by default —sensorhealthopts in per role, since scoring a duty cycle as normal is the direction that could mask a fault). - Time / DST —
timegrid:interval_hours,regularize(sort + de-duplicate the DST fall-back hour),localize(tz-localize resolving DST ambiguous/nonexistent),dst_anomalies.load_csvde-duplicates timestamps by default. See TIME-HANDLING.md.
Semantic model
- Roles + mapping —
model.roles.Rolevocabulary;model.mapping.MappingProvider(alias + pattern → role).resolve.resolve(equip, roles)assembles a role-named frame. Flags:resample. - Entities + completeness —
model.entities(Site/Equip/Point) with equipment-template completeness validation. - Brick interop —
interop.mapping_from_brick/roles_from_brick(import);interop.to_brickandinterop.site_to_ttl/site_from_ttl(export + whole-site round-trip). Flags:backend(auto/rdflib/minimal; rdflib via the[brick]extra). - Project-Haystack semantics —
interop.haystack_tags/equip_haystack_tags(role→tags export) and, new in 0.6,interop.role_from_tags/roles_from_haystack/mapping_from_haystack(tag→role import) — closing the round-trip to Brick-level parity (all 54 roles recover). - ASHRAE 223P —
interop.semantic223.site_to_223/site_from_223map a site (roles + equipment) to/from a 223P-shaped RDF subset (connections, medium, points;ROLE_TO_223quantity-kinds, broadened in 0.6 to 44 of 54 roles — the full plant/DX/refrigerant side; status/command roles are documented as intentionally unmapped). Flags:profile(minimal/full),include_relations. See ONTOLOGY.md.
FDD — fault detection & diagnostics
Rule engine (rules.base.Registry, rules.builtin.builtin_registry); each rule consumes a
role-frame and returns a Finding. Run with registry.run(name, equip_refs, mapping, min_trust=…).
- Air-side (G36 + PNNL Re-tuning) — simultaneous heat/cool, reheat (penalty + G36 minimization),
SAT reset, overcooling (min-flow + severity), economizer / OA-fraction (incl. under-ventilation),
night/weekend setback, duct-static, zone census, and unmet-setpoint hours (
unmet_setpoint_hours— occupied space temp outside the heating/cooling band, the operator-facing comfort/capacity metric). Per-rule flags (e.g.threshold,min_oa_pct,occupied_only,tol_F). - Central plant & hydronic — chiller kW/ton efficiency, chiller staging + multi-chiller fleet
over-staging, cooling-tower approach, condenser-water reset, CHW/HW pump (riding-curve + VFD-min),
CHW reset + low-ΔT, boiler summer-lockout + short-cycle. Flags include design targets
(
design_kw_per_ton,max_starts_per_day, …). - Control stability —
control_hunting: flags a modulating output (valve/damper) that reverses direction excessively (unstable loop) by counting reversals/hour beyond a deadband. Flags:warn_per_hr,fault_per_hr,deadband.supply_air_control: flags supply-air temperature that fails to track its setpoint (control/capacity fault; running hours only). Flags:tol_F,warn_pct,fault_pct.airflow_tracking: flags measured VAV airflow that fails to track its setpoint (stuck/undersized damper, failed actuator, starvation, bad flow sensor). Flags:tol_frac,warn_pct,fault_pct. - Peer/cohort —
cohort.CohortDeviation(fleet rule): flags a unit running unlike its peers on a role (robust z of a mean/peak/load-shape summary). Shipped instancescohort_airflow,cohort_space_temp; construct your own for any role. Flags:k,summary,min_cohort. - Economizer / free cooling —
economizer_high_limit(OA damper open above the high limit — not locked out),free_cooling_missed(mechanical cooling ran while OAT was cool enough for free),static_pressure_reset(duct-static setpoint that doesn't trim with demand). Flags:high_limit_f,min_damper,min_range_inwc. - Packaged / DX & refrigerant-side (
docs/FDD-DX.md) —compressor_short_cycleandcompressor_staging(RTU/DX cycling + staging),heatpump_defrost(excess reversing-valve cycling),filter_fouling(filter ΔP at/above change-out), andchiller_approach_fouling(condenser/evaporator approach-temperature degradation — refrigerant-side fouling without refrigerant-pressure sensors). New equipment templates: RTU, HeatPump/VRF, DOAS, FCU. - Drift-detection families — catches equipment degrading over time against its own frozen,
load-normalized baseline (the "is this slowly getting worse than it used to be, at matched load?"
question), all on one shared engine (
camber.chillerbaseline/camber.chillerdrift), each pairing a period statistic with a streaming sustained-shift CUSUM alarm and honest threshold labels (screening-grade magnitude floors vs. provisional-untuned CUSUM timing): - Chiller (CHILLER-DRIFT.md) — condenser/evaporator approach, liquid-line subcooling (charge), suction superheat (evaporator feed), condenser-water range.
- Pump / hydronic (PUMP-DRIFT.md) — the distribution side at matched duty.
- AHU / air-side (AHU-DRIFT.md) — supply fans, coils, filters, duct-static
control, with a per-AHU co-movement roll-up (
diagnose_ahu_drift) that names the locus. - VAV / zone-terminal (VAV-DRIFT.md) — the box's damper, airflow tracking, and
reheat coil, with a per-box roll-up (
diagnose_vav_drift) disambiguating box vs upstream starvation. Each family ships a physics simulator (ahusim/condensersim/evaporatorsim/vavsim) for ROC validation;camber.driftvalidationcalibrates thresholds against labelled data. Period rules, run viaRegistry.run_periodswith a frozen baseline store. Driven from a config'sdriftsection orcamber drift run|report|freeze|list(camber.driftrun) — one page per run viareport.drift_report_html. Scoring is read-only toward the store; onlyfreezecreates a reference and only the attributedaccept_new_normalmoves one, and an equipment nothing could evaluate is listed as not evaluated rather than diagnosed steady. See CLI.md. - Trim-and-Respond / G36 reset analytics (TR-RESET.md) — asks whether the plant's
setpoint-reset logic does what ASHRAE Guideline 36 intends (
camber.g36_resetengine). Five detectors:supply_air_reset_compliance(SAT held colder than the §5.16.2.2 OAT→SAT target — a reheat opportunity),sat/static_reset_effectiveness(does the reset setpoint actually trim and respond to its zone requests, or is it stuck / not-responding / not-trimming / diverging?), andsat/static_rogue_zone_census(fleet rules finding the one zone monopolizing the requests and dragging the whole reset). Screening / opportunity-grade. - G36 §5.16.14 engine —
fdd_g36.run_g36_afddscores AHU fault conditions FC1–FC15 with operating-state gating; cross-validated vs open-fdd and accuracy-scored in the synthetic harness (VALIDATION.md). - Sensor health / data trust —
sensorhealth(physical bounds, cross-sensor consistency, per-role trust roll-up +trusted_rolesgate),sensordrift(bias / drift / tracking vs a reference — fetch one withweather_source.oat_reference(NASA POWER by lat/lon),oat_reference_for(by address, via a keyless geocoder), oroat_reference_isd(station-precise, NOAA/ISD); see WEATHER.md),mapping_confidence. The runner'smin_trustflag makes a rule decline when its inputs aren't trusted. - Prioritization & lifecycle —
rules.triage:rank_findings(severity, or a magnitude/cost key),group_findings(root-cause grouping),FaultRegister(new/ongoing/resolved across runs). Persistent, cross-process:faultlifecycle.FaultLifecycle— a fingerprint-keyed fault store with an assignment/status workflow, SLA/aging tracking, and atomic JSON persistence. Flags:magnitude_key,actionable_only,reopen_on_recurrence,auto_resolve_absent. - Fault economics —
fault_economics: per-fault annual $ impact → rank by money. Flags:params(assumptions),models,min_severity(viarank_by_cost). Triage-gradeDEFAULT_MODELScover simultaneous heat/cool, reheat, chiller/tower/pump efficiency, duct-static, boiler cycling, and the Trim-and-Respond reset family (SAT-below-target and static/SAT reset-not-trimming → reheat/fan waste;not_responding/stuck/divergesare comfort/indeterminate → uncosted by design). Drift findings are also uncosted by design — a drift is a leading recommission indicator, not a spend (its magnitude is a condition-space residual, not a priceable energy quantity). Every estimate carries itsbasis+assumptionsand returns uncosted (never a fabricated figure) when the sizing it needs is missing. - Ventilation (ASHRAE 62.1) —
ventilation.assess_62_1(Ventilation Rate Procedure: required vs delivered OA, deficit) andassess_dcv(DCV modulation vs occupancy/CO₂), with theVentilationRateProcedure/DemandControlledVentilationrules andRole.OA_AIRFLOW. Flags:space_typevsrp/ra,ez,aggregate,min_corr,min_modulation. See VENTILATION.md. - Accuracy + CI gating —
eval.benchmark+validation.metrics_with_ci(Wilson CIs), andeval.check_against_baselineto gate accuracy (TPR/FPR/diagnosis) against a committed baseline in CI (--json/--gate/--tol/--update-baseline). See VALIDATION.md. - Validation dossier —
camber.dossier/camber validateaggregates all four validation tracks (synthetic, generated-fleet, real-data FDD, real-data M&V) into one text/HTML/JSON credibility artifact: live-recomputed pure tracks + cited real-data results with Wilson CIs and honest boundaries. See VALIDATION.md.
Sequence-of-Operations conformance
soo — a declarative clause engine (gated predicates over roles, JSON-authorable) measuring
operated-vs-designed behavior as a conformance %, with soo_library (packaged ASHRAE G36 clauses).
Flags: persistence window, per-class spec.
M&V — measurement & verification
See MANDV.md. Change-point models (mandv.models, 2P–5P + zero variants), LBNL
TOWT (mandv.towt), fit statistics + G14 fractional savings uncertainty (mandv.stats), CUSUM
(mandv.cusum), weather normalization (mandv.weather), normalized annual savings
(mandv.normalized), non-routine adjustment (mandv.nonroutine), Option-B retrofit isolation
(mandv.retrofit_isolation), CalTRACK alignment (mandv.caltrack), a variable-base degree-day
baseline (mandv.degreeday, HDD/CDD regression with an auto-fit balance point), IPMVP Option A
(mandv.option_a, measured Δparameter × stipulated duty), and IPMVP Option D (mandv.rc_model, a
1R1C or 2R2C grey-box calibrated to metered energy — grid-τ + OLS, G14-gated — run as-found vs
as-corrected for a modeled pre-implementation saving, with multi-zone stacked-OLS calibration and
an optional EnergyPlus cross-validator (interop.energyplus); see OPTION-D.md).
CAMBER now
covers IPMVP Options A/B/C/D. Flags: confidence, exclude_non_routine, model kinds, aggregate,
balance_point, interval.
Streaming / online
Incremental monitors for a live BAS feed — bounded state, O(1)–O(window) per sample. See STREAMING.md and FORECAST.md.
- Online M&V —
mandv.online.OnlineCusum(incremental tabular CUSUM of savings/waste vs a baseline model → savings-erosion alarm) andRollingAnomaly(rolling median/MAD residual z-score). Flags:limit,slack,window,k,min_samples. - Online FDD —
rules.online.OnlineFDD: sliding trailing-window rule evaluation emitting aTransitiononly on a verdict change (no per-sample re-alert), per-equipment isolation. Flags:window,eval_every,min_samples,emit_ok. - Forecasting + learned-normal anomalies —
forecast.seasonal_forecast(time-of-week shape + additive drift, no ML dep),backtest(MAE / MAPE / CV(RMSE) honesty check),forecast_anomalies(robust residual band → FDD signal). Flags:drift_window,k,test_frac.
Commissioning (RCx / MBCx)
rcx: functional_test (FPT pass-rate), before_after (MBCx persistence across an intervention
date), track_measures (measure register → verified/regressed/inconclusive/insufficient).
Money & compliance
- Tariffs —
tariff(URDB-shaped: TOU energy + tiers, TOU/flat demand, ratchet, fixed → monthly + annual bill),tariff.validate_bill(vs actual invoices, MAPE + per-month status),interop.openei(URDB fetch),[tariff]PySAM bridge. Flags:tol_pct. - ECM finance —
finance: payback, NPV, IRR, SIR with escalation / O&M / salvage. - Demand & peak —
demand: peak + drivers, load factor, baseload, night/weekend baseload anomaly, peak-shave $ value. Flags:near_peak_frac,start_hour/end_hour,target_kw. - BPS compliance —
bps:site_eui,emissions_intensity,assess_bps/assess_eui(compliant?, margin, penalty exposure). Limits are caller-supplied (no hard-coded legal values).
Grid-interactive (GEB) & carbon timing
Beyond using less energy — quantify shifting and shedding load, and the carbon cost of when power is used. Advisory analytics (read-only toward the BAS). See GEB.md and CARBON.md.
- Demand response & flexibility —
geb.demand_response(shed kW/kWh/% + rebound vs a baseline),geb.flexibility(sheddable load above baseload, peak-to-average headroom). Flags:rebound_hours,baseload_pct. - Load timing —
geb.carbon_aware_shift(CO₂ saved shifting load dirty→clean hours) andgeb.operation_score(load timing vs a price/carbon signal, rearrangement-inequality bounds). - Hourly / marginal Scope-2 —
carbon_hourly.hourly_emissions(time-varying factor → co2e, effective factor, timing premium) andmarginal_vs_average(load-shift value uses marginal; reporting uses average). Flags:unit_kg_per_kwh. - OpenADR export —
interop.openadr.to_openadr_report: map ademand_responseresult to an OpenADR-3.0-shaped report payload for a DR program.
Domain analytics
comfort (Std-55 PMV/PPD), iaq (CO₂ ventilation adequacy), cost, carbon, water (irrigation
/ cooling-tower / leak), loadprofile, pv (+ interop.pvlib_bridge, [pv]),
interop.psychro (PsychroLib, [psychro]), lighting. Plus:
- Schedule inference — schedule.detect_schedule / compare_schedule: the actual weekly
operating schedule from interval load vs a stated one (setback opportunity). SCHEDULE.md.
- Change-point detection — changedetect.detect_level_shifts: when a signal's mean shifts
(MBCx persistence/regression). CHANGEDETECT.md.
- Free-cooling opportunity — freecooling.free_cooling_opportunity: missed economizer hours →
recoverable kWh/$. FREECOOLING.md.
- Load disaggregation — disaggregate.disaggregate_load: baseload / weather / other split.
DISAGGREGATE.md.
Advisory & synthesis
Read-only, human-in-the-loop layers on top of the findings:
- ASO — aso.recommend / recommend_findings: an actionable finding → a suggested setpoint/
sequence change, grounded (cites the rule + G36/PNNL), never a BAS command. ASO.md.
- Action plan — actionplan.build_action_plan: findings + fault_economics ($/yr) + aso,
ranked worst-dollars-first; embeds in the audit report + config runs. ACTIONPLAN.md.
- Health scorecard — scorecard.build_scorecard: per-category scores + an overall A–F grade.
SCORECARD.md.
AI-assist (advisory, provider-agnostic)
Dependency-light, advisory-only, read-only toward the BAS. The LLM path is fully provider-agnostic — no vendor named, no SDK, no network (an AST guard enforces it) — and everything works with no LLM wired via deterministic fallbacks.
- Assisted point mapping —
mapping_assist.suggest_roles/review_unmapped: suggest roles for unmapped tags (a human-confirmed review list; never mutates aMappingProvider).FeatureSuggester(numpy baseline: string + unit + physical-range fit), optionalMLSuggester([ml]extra, scikit-learn, no pretrained weights), andLLMSuggester(agent seam; proposals validated + re-scored deterministically). See MAPPING-ASSIST.md. - Grounded explanation & Q&A —
agent.explain/agent.ask: cited, plain-language explanations and NL Q&A over the findings/costs/recommendations/scorecard/completeness/history/mapping. AContextof citableFacts (order-stable ids), number-traceability verification (agent.check), a deterministic template fallback, and an injectedcomplete(prompt, **opts)seam (client_from_callable). See AGENT.md. - Portfolio triage —
agent.facts_from_fleetbuilds grounded facts from areport.FleetReport(per-building EUI / faults / recoverable $), andbuild_context(fleet=…)makes a multi-site context, soask/explainanswer portfolio-wide ("which building is worst?").
Storage
store.ParquetStore — entity-keyed, hive-partitioned (site/year) Parquet with tag-filtered reads,
rollups, retention pruning, year-partition pruning + column projection + cached catalog. See
SCALE.md. Flags: read_long(columns=…, start/end), rollup(freq, agg),
prune(before_year).
Reporting, integration & API
- Audit —
report.AuditReport(ASHRAE/ACCA Standard 211, text/HTML) with prioritized findings. - Portfolio rollup —
report.build_fleet_report(cross-sectional EUI benchmark + fault rollup, ranked by recoverable $). Flags:price,loads,peer_median_eui,top_n. - Outbound —
integrate: CMMS work-orders (finding_to_ticket/findings_to_tickets→ neutral dict), notifiers (dispatch_findingsoverwebhook_transport/email_transport, withslack_payload/teams_payloadformatters; severity filter + fingerprint dedupe), and findings/ metrics export (export_findings: CSV / Parquet / JSON). All opt-in, from the findings layer — never writing to the BAS. Flags:channel,min_severity,dedupe,dry_run,format,flatten_metrics. See INTEGRATIONS.md. - Charts + dashboard — the full visualization pattern catalog A–J: readiness ribbon (A),
fault-annotated multi-trend (B), load carpet (E), data-quality dashboard (I), OAT cloud-shape
scatter (D,
oat_scatter), templated diagnostic scatters (G,diagnostic), rules as a chart engine (J,evidence— every rule renders its own proof), cohort small-multiples (C,cohort), M&V savings with uncertainty (H,savings), load profiles / load-duration curves (F,loadprofile_chart), plus the legacy scatters/CUSUM/energy-signature.report.build_dashboardassembles them into one self-contained HTML (matplotlib inlined, no web framework), embeds each finding's evidence (rules=), and offers a brush-able inline-SVG scatter (interactive=True). Flags:sections,rank_by,top_n,normalize,rules,evidence,interactive. See VISUALIZATION.md. - Read-only API + live web UI —
api.server(camber serve <store>orpython -m camber.api.server <store> [port]): GET/about/health/facilities/points/history, plus a live vanilla-JS dashboard at/ui(facility/equip/role selectors + a synchronized multitrend, brush-linked viawindow.CAMBER, polling for fresh data). Read-only, localhost-bound, CSP-locked, no framework. Env:CAMBER_STORE/CAMBER_API_HOST/CAMBER_API_PORT. See VISUALIZATION.md.
Orchestration & distribution
- Config-driven runs —
config: one JSON config (source → mapping → equipment → rules → report) runs a whole analysis:python -m camber.config run.json. - CLI — the
camberconsole script:run/report/explain/ask/fleet/charts/validate/serve/drift/edgesubcommands, with a vendor-neutral--llm-cmdseam for the agent. See CLI.md. - Plugins —
plugins: third-party rules / ingest adapters / report formats discovered via Python entry points (camber.rules/camber.adapters/camber.reports) or registered in-process, duck-typed against the existing protocols with per-plugin error isolation. See PLUGINS.md. - Distribution & deployment — slim multi-stage Docker image + compose bundle
(DOCKER.md), PyPI (
camber-toolkit) + GHCR via the tag-driven release workflow, CI on 3.10/3.11, and reference Kubernetes / conda-recipe manifests (deploy/). See DEPLOY.md.
See also: ARCHITECTURE.md, ECOSYSTEM.md (fork-vs-depend analysis), and the ROADMAP.