Multi-domain IEQ (Indoor Environmental Quality) and performance contract framework for smart buildings. Includes pollutant IAQ, adaptive thermal comfort, sPMV, TSV augmentation, and personalised comfort models.
Project description
comfio
A multi-domain IEQ & performance contract framework for smart buildings.
comfio bridges the gap between raw building sensor data and actionable smart building management. It breaks the silos between different building physics disciplines — bringing together Thermal, Visual, Acoustic, and Indoor Air Quality (IAQ) metrics into a unified Global IEQ Index.
Designed for time-series data (IoT sensors, edge computing) and comfort-based performance contracts, comfio enables researchers and building managers to automate compliance tracking and generate smart-contract-ready outputs.
Why comfio?
- Silo-Breaking: Unifies separated domains (Thermal, Acoustic, Visual, IAQ) under a single Python API
- Data-Native: Built to ingest massive arrays of time-series data (Pandas/NumPy) rather than single-point calculations
- Actionable Output: Translates physical equations into compliance rates for building performance contracts
- Smart Contract Ready: Generates structured JSON outputs with formal ABI schemas for blockchain Oracle integration
- ML/DL Compatible: NumPy-native core with optional adapters for scikit-learn, PyTorch, and TensorFlow/Keras
- Advanced Physics Modules: Optional extras for Radiance daylighting, CRI/CCT color quality, RT60 reverberation, STI speech intelligibility, CO₂ decay ventilation, and full psychrometrics
- Pollutant IAQ: PM2.5, PM10, TVOC, formaldehyde, and CO evaluation against WHO, EPA NAAQS, and WELL Building Standard v2 thresholds
- Adaptive Thermal Comfort: ASHRAE 55-2023 and EN 16798-1:2019 adaptive models for naturally ventilated buildings
- Simplified PMV (sPMV): Buratti et al. (2009) seasonal model requiring only temperature and humidity
- TSV Augmentation: CDF-based remapping (quantile mapping) to augment sparse occupant votes to dense sensor timestamps while preserving the empirical distribution
- Personalised Comfort: OLS regression-based personalisation of model predictions to match occupant feedback (TSV), with per-season support
- Fast & Light: Core depends only on numpy, pandas, and pythermalcomfort
Installation
pip install comfio
With ML/DL framework support:
pip install comfio[ml] # scikit-learn
pip install comfio[torch] # PyTorch
pip install comfio[keras] # TensorFlow/Keras
pip install comfio[all] # All frameworks + advanced domains
Advanced physics-based domain evaluation (optional extras):
pip install comfio[daylighting] # pyradiance (Radiance ray-tracing)
pip install comfio[color] # colour-science (CRI, CCT)
pip install comfio[acoustics] # python-acoustics + pyroomacoustics (RT60, STI)
pip install comfio[psychrometrics] # PsychroLib (psychrometric properties, CO₂ decay ACH)
Quick Start
1. Evaluate Individual Domains
import numpy as np
from comfio import evaluate_thermal, evaluate_visual, evaluate_acoustic, evaluate_iaq
# Thermal comfort (ISO 7730 / ASHRAE 55)
thermal = evaluate_thermal(
tdb=np.array([24.0, 25.0, 26.0]), # air temp °C
tr=np.array([24.0, 25.0, 26.0]), # radiant temp °C
vr=np.array([0.1, 0.1, 0.1]), # air velocity m/s
rh=np.array([50.0, 50.0, 50.0]), # relative humidity %
met=1.2, # metabolic rate
clo=0.5, # clothing insulation
category="B", # ISO 7730 category
)
print(f"PMV: {thermal.pmv}, PPD: {thermal.ppd}")
# Visual comfort (EN 12464-1)
visual = evaluate_visual(
illuminance=np.array([450.0, 500.0, 600.0]),
task_type="office_writing",
)
# Acoustic comfort (NC curves)
acoustic = evaluate_acoustic(
laeq=np.array([35.0, 40.0, 45.0]),
nc_level="NC-35",
)
# IAQ (ASHRAE 62.1 indicators)
iaq = evaluate_iaq(
co2=np.array([700.0, 900.0, 1100.0]),
threshold_level="good",
)
2. Calculate Global IEQ Index
from comfio import calculate_global_ieq, default_weights
# Merge all domains into a single 0-100 score
ieq = calculate_global_ieq(
thermal=thermal,
visual=visual,
acoustic=acoustic,
iaq=iaq,
weights=default_weights(), # thermal=40%, iaq=25%, visual=20%, acoustic=15%
)
print(f"Global IEQ Index: {ieq.index}")
print(f"Domain scores: {ieq.domain_scores}")
3. Compliance Tracking & Contract Outputs
from comfio import calculate_compliance
report = calculate_compliance(ieq, threshold=80.0)
print(f"Compliance rate: {report.compliance_rate_pct:.1f}%")
print(f"Average IEQ: {report.ieq_index_avg:.1f}")
# Generate JSON for blockchain Oracle
contract_json = report.to_contract_json()
print(contract_json)
4. Time-Series Data with SensorData
import pandas as pd
from comfio import SensorData
# Load your sensor DataFrame
df = pd.read_csv("sensor_data.csv")
sensor = SensorData(df=df)
# Auto-detects column names (tdb, ta, temperature → air_temp_c, etc.)
print(sensor.available_domains()) # ['thermal', 'visual', 'acoustic', 'iaq']
# Validate data (NaN handling, physical bounds checking)
sensor.validate()
clean_temp = sensor.get_validated("air_temp_c")
ML/DL Integration
scikit-learn Pipeline
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestRegressor
from comfio.ml.sklearn_transformers import IEQFeatureExtractor
pipe = Pipeline([
("ieq", IEQFeatureExtractor()),
("model", RandomForestRegressor()),
])
pipe.fit(train_df, train_labels)
predictions = pipe.predict(test_df)
PyTorch DataLoader
from torch.utils.data import DataLoader
from comfio.ml.torch_dataset import IEQTimeSeriesDataset
dataset = IEQTimeSeriesDataset(df, window_size=24, stride=1)
loader = DataLoader(dataset, batch_size=32, shuffle=True)
for batch in loader:
raw = batch["raw"] # (32, 24, n_sensors)
ieq = batch["ieq_index"] # (32, 24)
TensorFlow/Keras
from comfio.ml.keras_adapter import IEQPreprocessingLayer
layer = IEQPreprocessingLayer()
layer.adapt(train_df)
features = layer(train_df) # tf.Tensor of IEQ features
Advanced Domain Evaluation
comfio offers optional physics-based modules that go beyond simple threshold checks. These require separate extras but integrate seamlessly with the Global IEQ Index.
from comfio import (
evaluate_reverberation, evaluate_speech_intelligibility,
evaluate_ventilation, get_psychrometrics,
calculate_global_ieq,
)
# Reverberation time (python-acoustics)
reverb = evaluate_reverberation(surfaces, absorption, volume, room_type="office")
# Speech intelligibility from impulse response (pyroomacoustics)
sti = evaluate_speech_intelligibility(ir_signal, sample_rate=16000)
# Ventilation rate from CO₂ decay (psychrolib)
vent = evaluate_ventilation(co2_array, timestamps, occupancy_type="office")
# Psychrometric properties (psychrolib)
psych = get_psychrometrics(tdb=25.0, rh=0.50)
# Blend advanced results into Global IEQ Index
result = calculate_global_ieq(
thermal=thermal, visual=visual, acoustic=acoustic, iaq=iaq,
reverberation=reverb, speech_intelligibility=sti, ventilation=vent,
)
See the User Guide for full documentation.
New Domain Modules
Pollutant IAQ
Evaluate PM2.5, PM10, TVOC, formaldehyde, and CO against health-based thresholds:
from comfio import evaluate_iaq_pollutants
pollutant = evaluate_iaq_pollutants(
pm25=np.array([8.0, 12.0, 35.0]),
tvoc=np.array([150.0, 300.0, 500.0]),
formaldehyde=np.array([20.0, 27.0, 50.0]),
co=np.array([1.5, 5.0, 10.0]),
threshold_level="good",
)
print(f"Pollutant IAQ score: {pollutant.score}")
Adaptive Thermal Comfort
from comfio import evaluate_adaptive_ashrae, evaluate_adaptive_en
# ASHRAE 55-2023 (naturally ventilated buildings)
ashrae = evaluate_adaptive_ashrae(
tdb=np.array([24.0, 25.0, 26.0]),
tr=np.array([24.0, 25.0, 26.0]),
t_prevail=20.0, # prevailing mean outdoor temp
acceptability=80,
)
# EN 16798-1:2019
en = evaluate_adaptive_en(
tdb=np.array([24.0, 25.0, 26.0]),
tr=np.array([24.0, 25.0, 26.0]),
t_running_mean=20.0,
category="ii",
)
Simplified PMV (sPMV)
from comfio import evaluate_spmv
spmv = evaluate_spmv(
indoor_temp=np.array([23.0, 24.0, 25.0]),
indoor_rh=np.array([50.0, 50.0, 50.0]),
season="mid", # or "winter" / "summer"
)
print(f"sPMV: {spmv.spmv}, score: {spmv.score}")
TSV Augmentation & Evaluation
from comfio import augment_tsv_cdf, evaluate_tsv
# Augment sparse occupant votes to dense sensor timestamps
augmented = augment_tsv_cdf(
sparse_votes=np.array([-2, -1, 0, 0, 1, 1, 2, -1, 0, 1]),
vote_timestamps=np.arange(10),
target_timestamps=np.arange(100), # dense sensor timestamps
)
# Evaluate TSV for compliance (ASHRAE 55-2023 Appendix L)
tsv_result = evaluate_tsv(augmented)
print(f"Mean TSV: {tsv_result.mean_tsv}")
print(f"Compliance rate: {tsv_result.compliance_rate:.1%}")
Personalised Thermal Comfort
from comfio import train_personalisation, evaluate_personalised_pmv
# Train: fit OLS regression TSV = alpha * PMV + beta
index = train_personalisation(
pmv=historical_pmv_array,
tsv=historical_tsv_array,
)
# Apply: personalise future PMV predictions
result = evaluate_personalised_pmv(
tdb=tdb, tr=tr, vr=vr, rh=rh, met=1.2, clo=0.5,
personalisation_index=index,
)
print(f"Personalised PMV: {result.personalised_pmv}")
Integration with Global IEQ Index
from comfio import calculate_global_ieq
ieq = calculate_global_ieq(
thermal=thermal_res,
visual=visual_res,
acoustic=acoustic_res,
iaq=iaq_res,
pollutant_iaq=pollutant_res, # blends 50/50 with IAQ score
tsv=tsv_res, # overrides thermal score (occupant feedback is ground truth)
)
Architecture
comfio operates on a 4-layer data flow:
Layer 1: Data Ingestion (SensorData)
↓ Pandas/NumPy time-series arrays
Layer 2: Single-Domain Modules (domains/)
↓ Thermal (pythermalcomfort) | Visual (EN 12464-1) | Acoustic (NC) | IAQ (ASHRAE 62.1)
Layer 3: Multi-Domain Integration (integration/)
↓ Global IEQ Index (0-100) with configurable weighting
Layer 4: Application & Contracts (performance/)
→ Compliance rates, JSON reports, smart contract ABI schemas
Key design principle — Decoupling: integration/ only talks to domains/, never to pythermalcomfort directly. If pythermalcomfort releases a breaking change, only domains/thermal.py needs updating.
Weighting Presets
| Preset | Thermal | IAQ | Visual | Acoustic | Use Case |
|---|---|---|---|---|---|
default |
40% | 25% | 20% | 15% | General (Pierson et al. 2019) |
equal |
25% | 25% | 25% | 25% | Equal weighting |
school |
27% | 26% | 24% | 23% | School children (Yang et al. 2020) |
office |
45% | 30% | 15% | 10% | Office workers |
healthcare |
25% | 40% | 15% | 20% | Healthcare facilities |
from comfio.integration.weights import preset_weights, custom_weights
weights = preset_weights("office")
weights = custom_weights(thermal=0.5, visual=0.2, acoustic=0.1, iaq=0.2)
Standards Referenced
- ISO 7730: Thermal comfort — PMV/PPD calculation
- ASHRAE 55: Thermal environmental conditions for human occupancy
- ASHRAE 55-2023 Appendix L: TSV compliance threshold (|TSV| ≤ 1.5)
- EN 16798-1:2019: Adaptive thermal comfort for naturally ventilated buildings
- EN 12464-1: Light and lighting — lighting of work places
- ASHRAE 62.1: Ventilation for acceptable indoor air quality
- WHO Air Quality Guidelines (2021): PM2.5, PM10 thresholds
- EPA NAAQS: Criteria pollutant thresholds
- WELL Building Standard v2: Feature A01 pollutant thresholds
Academic Attribution
comfio utilizes the validated pythermalcomfort library as its core engine for thermal metrics, while focusing its novel architecture on multi-domain integration and temporal performance evaluation.
Tartarini, F., Schiavon, S., 2020. pythermalcomfort: A Python package for thermal comfort research. SoftwareX 12, 100578. https://doi.org/10.1016/j.softx.2020.100578
Development
# Install with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Lint
ruff check src/ tests/
ruff format src/ tests/
# Type check
mypy src/comfio/
# Build
python -m build
Citation
A formal academic paper for comfio is in preparation. In the meantime, if you use comfio in your research, please cite it as:
@software{comfio,
author = {comfio Contributors},
title = {comfio: A Multi-Domain IEQ \& Performance Contract Framework for Smart Buildings},
year = {2025},
url = {https://github.com/NibrasAz7/Comfio},
version = {0.1.0},
}
Please also cite the underlying pythermalcomfort library:
@article{tartarini2020,
author = {Tartarini, Federico and Schiavon, Stefano},
title = {pythermalcomfort: A Python package for thermal comfort research},
journal = {SoftwareX},
volume = {12},
pages = {100578},
year = {2020},
doi = {10.1016/j.softx.2020.100578},
}
License
MIT — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file comfio-0.1.0.tar.gz.
File metadata
- Download URL: comfio-0.1.0.tar.gz
- Upload date:
- Size: 81.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
047881dde80c4e9ddaf154e2332901e0ec51797fcb6181cf2781022b8d884886
|
|
| MD5 |
78636dd5f29bdc33263bfb1f9617df83
|
|
| BLAKE2b-256 |
6d10d3d1d0e7186bd713c95b67bff0fbd5dbe9bdbe6264175423a3ab4814d537
|
File details
Details for the file comfio-0.1.0-py3-none-any.whl.
File metadata
- Download URL: comfio-0.1.0-py3-none-any.whl
- Upload date:
- Size: 82.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5e6502e0e3d2263749e1ee930654c7c82e309c8d0bd5baacc83146daaba95b6c
|
|
| MD5 |
31b57db4641fc3793db815f170f2c370
|
|
| BLAKE2b-256 |
01e7dfa54b7a2bf53c0986d9f7c1cd412257b14d5f8d288274397dbcc05a7251
|