Skip to content

Repository files navigation

GreenFlux

A greenhouse simulator whose physics you can trace, calibrated against measured data.

Docs Python License: MIT Status

GreenFlux models greenhouse climate — air temperature, humidity, CO2 — together with tomato crop growth, the equipment that drives them, and the economics of running the whole thing. Every state is driven by a named heat, vapour, CO2 or radiation balance rather than by a fitted black box, so a result can be traced back to the term that produced it. The import package and command-line executable are both greenflux.

It exists for two connected goals:

  1. Build reusable greenhouse models that stay traceable to physical balances, equipment parameters and measured-data validation.
  2. Generate structured datasets for machine-learning research: unsupervised anomaly and fault detection, stochastic and optimal control, sensor observability and placement, synthetic benchmarks.

The implementation is inspired by greenhouse Modelica literature and reference models, including queraltab/Greenhouses-Library, but the public package does not require cloned vendor repositories.

📖 Full documentation → lirei.ca/greenflux

What it produces

Both figures are tracked in this repository (outputs/calibration/validation_figures/hps_physical/) and show the measured_replay_physical profile, which projects select by default. Regenerating them needs the measured GreenLight dataset, which the public repository does not ship — see docs/data_access.md — and then:

uv run --extra plots python examples/plot_validation.py --installation HPS

Accuracy across the whole season, out of sample. Each bar is one replay window; orange is the single window the calibration was fitted on, the dashed line is the mean over the windows that were not. Reported this way because a single in-sample window is not evidence — earlier one-day figures of ~2 °C degraded to 15–22 °C when replayed elsewhere in the season.

Per-period RMSE across the GreenLight HPS dataset

What a replay actually looks like, including where it is wrong: CO2 and vapour pressure track the measurement closely, air temperature runs roughly 2 °C cold and clips the daytime peaks, and relative humidity sits biased high enough to saturate. Those two biases are open, documented and under investigation — they are not smoothed out of the figure.

Simulated vs measured climate over a seven-day HPS window

Core Ideas

  • Physics first: greenhouse states are driven by heat, vapour, CO2, crop, ventilation, radiation and equipment balances rather than black-box predictors.
  • Project based: each greenhouse project carries site, geometry, equipment, crop, weather references, calibration profiles and named simulation cases.
  • Experiment ready: the upper workflow is organized as Project -> Problem -> Experiment -> Benchmark so studies can be repeated, compared and exported.
  • ML ready outputs: simulations produce aligned time series, state variables, actuator traces, crop states, fluxes and validation diagnostics.
  • Validation aware: measured replay, dynamic error layers, operating-regime diagnostics and crop calibration are part of the public package contract.

What Is Included

  • reusable equations for psychrometrics, heat, vapour, CO2 and ventilation
  • equipment models for lighting, screens, heating, humidity control, CO2, irrigation and envelope losses
  • shared actuation commands and management policies for controllable greenhouse operation
  • tomato crop and biomass models with calibration utilities
  • project definitions for site, geometry, equipment, crop and simulation cases
  • problem, experiment and benchmark wrappers for reproducible greenhouse studies
  • calibrated GreenLight HPS/LED Bleiswijk tomato projects
  • EPW/TMY weather adapters through optional pvlib
  • layered validation metrics, including increment error and drift diagnostics
  • hidden-residual attribution for heat, vapour and CO2 balance gaps
  • optional SciPy, Optuna, pandas/xarray, plotting and performance extras

Requirements And Setup

GreenFlux is a Python package managed with uv.

Required tools:

  • Python 3.10 or newer. Python 3.11+ is recommended for the standard-library TOML parser and faster local development.
  • uv for dependency resolution, virtual environments and running commands.
  • git for cloning the repository.

Install uv if it is not already available:

curl -LsSf https://astral.sh/uv/install.sh | sh
uv --version

Clone and prepare the project:

git clone https://github.com/lirei-lab/greenflux.git
cd greenflux
uv sync

Run the test suite and build the package:

uv run --extra dev pytest tests/
uv build

Optional features are installed through extras when needed:

uv run --extra plots python examples/tomato_plots.py
uv run --extra data --extra plots greenflux run examples/scenarios/tomato.toml --staged --plots --xarray
uv run --extra simulation python -m unittest tests.test_scipy_simulator
uv run --extra optimization python examples/calibrate_greenlight_replay.py --installation HPS --limit 289
uv run --extra solar python -m unittest tests.test_weather

Real measured-data calibration requires external datasets under data/raw/. The public repository does not include raw datasets, generated outputs or vendored reference repositories; see docs/data_access.md for download instructions, licenses and the expected local dataset layout.

To download and prepare the supported calibration datasets automatically:

uv run python scripts/download_calibration_data.py --dataset all

Typical Workflows

Simulate a Project

uv run --extra plots greenflux project-run projects/greenlight_hps_bleiswijk/project.json --run-id baseline --plots

Project runs write outputs under the project itself, for example projects/greenlight_hps_bleiswijk/results/measured_open_loop/baseline/. This keeps reusable examples separate from project-specific data products. With --plots, the same folder also receives climate.png, actuation.png and crop.png.

Project runs default to deterministic fixed-step integration. To use the adaptive SciPy full-state IVP path:

uv run greenflux project-run projects/greenlight_hps_bleiswijk/project.json --solver ivp
uv run python examples/compare_project_solvers.py projects/greenlight_hps_bleiswijk/project.json

Each project run also writes resources/resource_statistics.* with simulated heat, electricity, CO2, irrigation and drainage totals. When an AGC forcing case has a matching Resources.csv under data/raw/agc_2019/<team>/, GreenFlux also writes resources/resource_comparison.* for measured-vs-simulated resource bias checks.

For project cases backed by GreenLight or AGC raw data, project-run uses measured actuator traces when available: roof vents, screens, lighting, CO2 dosing and a grow-pipe heating proxy. Pass --constant-controls to ignore those traces and use the CLI control arguments instead.

Run a Study

A study is a declarative analysis over a project — studies/<id>/study.json names a project, picks an analysis type (stochastic planning or anomaly detection) and supplies its parameters.

uv run --extra simulation --extra planning greenflux study run studies/plan_led_demo/study.json
uv run --extra simulation greenflux study run studies/anomaly_led_demo/study.json

Results land in studies/<id>/results/<run_id>/result.json. See docs/studies.md for the schema, both study types and how studies relate to the Project -> Problem -> Experiment -> Benchmark framework.

Generate ML Datasets

Use projects, scenarios or experiments to generate clean baseline traces, perturbed actuator traces, synthetic weather stress tests and fault-injected variants. The resulting time series can be exported as CSV or xarray/NetCDF for downstream pipelines.

uv run --extra plots --extra data greenflux run examples/scenarios/tomato.toml --staged --plots --xarray
uv run python examples/validate_greenlight_long_crop_coupled.py --installation HPS --days 7

Validate Against Measured Data

uv run python examples/calibrate_greenlight_replay.py --installation HPS --limit 289 --scipy-max-evaluations 300
uv run python examples/validate_greenlight_period_sufficiency.py --installation HPS --project projects/greenlight_hps_bleiswijk/project.json --period-days 7 --stride-days 7
uv run python examples/replay_greenlight_with_humidity_schedule.py --installation HPS --parameters outputs/calibration/greenlight_hps_replay/parameters.json --schedule outputs/calibration/greenlight_hps_replay/validation/humidity_control_inference.csv --limit 289
uv run python examples/calibrate_agc_crop.py --team Reference --days 100
uv run --extra plots python examples/plot_validation.py --installation HPS

plot_validation.py renders the validation figure set — simulated-vs-measured overlays, parity scatter, error trajectories, per-period RMSE across the dataset and regime-split error. The two shown at the top of this README come from that set.

Validation reports include conventional level errors and dynamic diagnostics: increment error, increment-rate error, drift, horizon-window metrics and physical residual attribution. GreenLight validation folders now include both timeseries.csv, residuals.csv and humidity_control_inference.csv, so calibration gaps can be inspected as equivalent hidden heat, vapour and CO2 source terms, plus diagnostic dehumidifier/fogging control schedules inferred from vapour residuals. Period-sufficiency validation screens non-overlapping replay windows for minimum duration, sample count and operating-regime coverage before accepting a candidate calibration. The default GreenLight environment calibration also uses a residual-aware objective, which penalizes large hidden heat, vapour and CO2 corrections in addition to state RMSE. The residual-aware objective is the default for new calibration runs; exported project JSON files should be regenerated after accepting a new calibrated artifact. The greenhouse unit also exposes optional dynamic cover-condensation states and diagnostics (cover_condensation_kg_m2_s, cover_temperature_k and cover_surface_vapour_pressure_pa). These parameters are serialized in projects and calibration artifacts, but current GreenLight period validation does not yet support making dynamic cover condensation the default baseline.

Build Control and Observability Studies

The greenflux.problems, greenflux.experiments and greenflux.benchmarks layers provide deterministic simulation environments that can later be adapted to stochastic control, optimal control, MPC, reinforcement learning, observability analysis and sensor-placement experiments.

For declarative, CLI-runnable analyses over a project, the studies/ layer ships three study types today — stochastic_planning (a two-stage convex program), stochastic_mpc (receding-horizon closed loop), and anomaly_detection (residual-diagnostic fault detection). See docs/studies.md.

See docs/experiment_framework.md for the dataset-generation philosophy and the Project -> Problem -> Experiment -> Benchmark workflow.

Quick Run

uv run python examples/run_examples.py
uv run --extra dev pytest tests/

Examples:

uv run --extra plots python examples/tomato_plots.py
uv run --extra simulation python -m unittest tests.test_scipy_simulator
uv run python examples/tomato_sensitivity.py
uv run python examples/greenhouse_1_full.py
uv run greenflux run examples/scenarios/tomato.toml --output-dir outputs/scenario
uv run --extra plots --extra data greenflux run examples/scenarios/tomato.toml --staged --plots --xarray
uv run python examples/export_greenlight_calibrated_projects.py
uv run --extra plots greenflux project-run projects/greenlight_hps_bleiswijk/project.json --run-id baseline --plots

This writes tomato example plots and CSV/NetCDF time series into outputs/. examples/greenhouse_1_full.py writes a traceable Python approximation of Greenhouses.Examples.Greenhouse_1, including headline Modelica variables, component inventory and a full interval time series.

Optional Extras

  • simulation: SciPy-backed adaptive ODE integration and bounded calibration.
  • optimization: Optuna-backed bounded parameter search.
  • planning: cvxpy convex solver for the stochastic_planning and stochastic_mpc study types.
  • data: xarray/pandas result export.
  • config: Pydantic settings for strict external configuration.
  • scenarios: YAML scenario loading.
  • solar: EPW/TMY weather loading via pvlib.
  • edm: optional energydatamodel inheritance for energy asset objects.

Scenario files can be loaded as typed configs:

from greenflux import load_scenario_config

scenario = load_scenario_config("examples/scenarios/tomato.toml")

Or executed from the command line:

greenflux run examples/scenarios/tomato.toml --output-dir outputs/scenario

The example implementations use packaged reference tables under greenflux.resources.modelica_examples, so no vendor/ checkout is needed to run the simulator.

Validation Status

GreenFlux is validated through reproducible Python simulations and measured greenhouse datasets:

  • GreenLight HPS/LED Bleiswijk measured comparisons.
  • AGC 2019 tomato crop/yield calibration against measured production data.
  • Packaged reference-table greenhouse examples.
  • Unit and integration tests across equations, equipment, projects, weather, crop, calibration and simulation runners.

Accuracy is reported out of sample. The exported GreenLight projects use a staged Optuna calibration plus floor/soil thermal-mass and moisture-buffer nodes, replayed across windows that span the full ~112-day dataset. On measured_replay_physical — the profile projects select by default — the tracked figure set gives:

installation air temperature relative humidity vapour pressure CO2
HPS 2.19 °C 7.85 % 289 Pa 54 ppm
LED 2.00 °C 7.34 % 256 Pa see below

Both temperatures sit under the project's 2.5 °C acceptance target. The numbers are printed on the figures themselves (outputs/calibration/validation_figures/{hps,led}_physical/period_rmse.png), so the table and the plots cannot drift apart.

Three limits that belong next to those numbers:

  • CO2 is a diagnostic, not a prediction. The dataset's injection signal is a binary status flag, not a flux, and it reads off 97 % of the time while CO2 is dosed to ~780 ppm. HPS lands at 54 ppm because its dosing gain is identifiable; LED's is not, and its CO2 RMSE is an order of magnitude worse. Do not use either as a CO2 accuracy claim.
  • Two open biases, visible in the overlay figure above: air temperature runs ~2 °C cold and clips daytime peaks, and relative humidity is biased high. Both are traced to the lumped heat balance rather than to calibration.
  • Short-window replay and data generation are what this is for. Long-horizon open-loop prediction is still improving.

Earlier single-window figures of ~2 °C were in-sample on one day and degraded to 15–22 °C / 35–48 pp when replayed elsewhere in the season; the thermal-mass node fixed a night-time temperature divergence and the moisture-buffer node fixed a day-wet/night-dry humidity swing. That history is why accuracy here is always quoted across windows.

The latest full local run completed 1060 unit/integration tests (1 skipped, 76 subtests) and uv build successfully.

The implementation is intentionally modular: equations, flows, equipment, actuation, management, systems, projects, problems, experiments and validation tools live in separate files. This makes it easier to add new crops, equipment, control policies, fault injectors and dataset exporters without turning the simulator into a single monolithic script.

Documentation Map

The published site is lirei.ca/greenflux, organised by what a reader is trying to do. The same pages live under docs/ in this repository.

I want to… Page
define a greenhouse project_management.md · weather_management.md · models_equipment_controls.md
run a simulation project_run_forward.md · forward_heating_mode.md · forward_ventilation_mode.md · forward_co2_mode.md
choose a solver numerical_solvers.md
ask a research question studies.md · experiment_framework.md
understand the model usable_physical_models.md · actuation_management.md · project_structure.md
get the datasets data_access.md
contribute CONTRIBUTING.md

Working notes, audits and reviews live in docs/internal/, which is deliberately unpublished and untracked: it is a log of how the work was done, not the work. The same rule keeps unverified studies and generated outputs out of the public tree — a study in this repository reads as a result, and a result should have been checked first.

About

Modular greenhouse climate, crop and energy simulator with traceable physics, measured-data calibration, and declarative studies for MPC, planning under uncertainty and anomaly detection.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages