# Hamfy analysis: sensor choice and greenhouse VPD alerts

Version 1. Analysis completed 19 September 2026.

Hamfy performed the data audit, calculations, charts and interpretation in this
package. The underlying measurements were collected for the third Autonomous
Greenhouse Challenge at Wageningen University & Research's experimental
facilities in Bleiswijk, Netherlands, in 2022. This is an original analysis of
public measurements, not a report of a Hamfy installation.

## Input and permission

We use the complete `Reference/GreenhouseClimate.csv` file from the first lettuce
experiment, distributed by CEA Open Data as `GH_Lettuce/Koidra.AGC2022.1`.
The collection credits the challenge organizers and processing by Koala Team,
Koidra Tech Inc. Its README specifies the MIT license. `SOURCE-LICENSE.txt`
preserves the copyright and permission notice. The source is pinned to:

- Repository commit: `873e10bc43ccff58fc6c5a14afc4e661b241690f`
- Data: https://raw.githubusercontent.com/CEAOD/Data/873e10bc43ccff58fc6c5a14afc4e661b241690f/GH_Lettuce/Koidra.AGC2022.1/Reference/GreenhouseClimate.csv
- Dictionary: https://github.com/CEAOD/Data/blob/873e10bc43ccff58fc6c5a14afc4e661b241690f/GH_Lettuce/Koidra.AGC2022.1/README.md
- License: https://github.com/CEAOD/Data/blob/873e10bc43ccff58fc6c5a14afc4e661b241690f/GH_Lettuce/Koidra.AGC2022.1/LICENSE
- SHA-256 of unchanged input: `a58349fab639dae58064aaa0e143636399b5165471d15e866d4ce867f56b3abf`

The full collection spans several compartments and different harvest dates.
Our selected file contains 12,384 records from 2022-02-01 00:00 through
2022-03-15 23:55. We selected the named Reference compartment for an audit of
measurement streams, not to rank competition teams. No days in this file were
excluded because of their results.

## Method

1. Read `Tair` / `Rhair` (label P, primary climate stream) and `Tair_sigrow` /
   `Rhair_sigrow` (label S, Sigrow stream). Temperatures are degrees Celsius and
   relative humidity is percent. "Primary" denotes column names, not a calibrated
   ground truth. Missing either field makes that stream unavailable for that row.
2. Check finite values and broad physical bounds: -20 to 60 degrees C, 0 to 100%
   RH. All non-missing pairs pass. These checks do not establish calibration.
3. Normalize recorded minutes to the nearest five-minute grid. Exactly 5,504
   timestamps move forward one minute; 6,880 do not move. This produces a complete,
   unique five-minute grid. No measured temperature or RH value is changed and no
   missing value is interpolated. Raw timestamps remain in the unchanged input.
4. The source dictionary does not specify a timezone. ISO CSV exports assume
   UTC+01:00, consistent with Dutch winter civil time during this period. This
   assumption does not affect elapsed durations, paired comparisons or VPD.
   We do not infer sunrise, actual photoperiod or outdoor-weather alignment.
5. For every available pair, calculate air VPD in kPa:
   `0.6108 * exp(17.27*T / (T + 237.3)) * (1 - RH/100)`.
   The saturation-pressure relationship is given in FAO-56, chapter 3:
   https://www.fao.org/4/x0490e/x0490e07.htm
   Calculate before averaging. No leaf temperature is used.
6. Hold each available value to the next grid timestamp for at most five minutes.
   The final timestamp has no following interval, so contributes no duration.
   Thus the analysis spans 1,031 h 55 min, not a padded 1,032 h. Missing intervals
   are unknown. Do not bridge them or count them as zero VPD.
7. Compare sensors only where both pairs are present: 11,258 paired rows,
   11,257 contributing intervals, 938 h 05 min. All paired means, threshold shares
   and disagreement rates use that same denominator. Full-stream coverage figures
   use each stream independently.
8. Use a strict `< 0.4 kPa` review flag, without hysteresis or minimum duration.
   It is an analytical threshold, not a recommended lettuce setpoint, disease
   diagnosis or reconstruction of the experiment's actual alarms. Also calculate
   thresholds 0.3, 0.5 and 0.6 kPa, rather than relying on one threshold.
9. Check timestamp sensitivity by retaining original 4/5/6-minute intervals.
   The fractions below 0.4 kPa become 29.8049% and 53.0842%, versus 29.8037% and
   53.0959% on the regular grid: less than 0.02 percentage points difference.

## Results

| Quantity | P: Tair / Rhair | S: Sigrow |
| --- | ---: | ---: |
| Valid rows / 12,384 | 12,359 | 11,283 |
| Missing rows | 25 | 1,101 |
| Available duration, entire stream | 1,029 h 50 min | 940 h 10 min |
| Missing duration, entire stream | 2 h 05 min | 91 h 45 min |
| Longest consecutive missing block | 1 h 30 min | 69 h 35 min |
| Paired mean air temperature | 18.0761 C | 19.5837 C |
| Paired mean RH | 74.5786% | 81.8909% |
| Paired mean air VPD | 0.550233 kPa | 0.425115 kPa |
| Paired time below 0.4 kPa | 279 h 35 min | 498 h 05 min |
| Paired fraction below 0.4 kPa | 29.8037% | 53.0959% |

At 0.4 kPa the streams disagree in 4,468 of 11,257 paired intervals (39.6909%),
equivalent to 372 h 20 min under the interval assumption. These are classified
intervals, not 4,468 distinct alarms or independent experimental replicates.
Both streams are below in 2,432 intervals; only P in 923; only S in 3,545;
neither in 4,357. These four counts sum to 11,257.

S minus P has a paired mean difference of +1.5076 C, +7.3123 percentage points RH
and -0.125117 kPa air VPD. The mean absolute VPD difference is 0.172301 kPa.
At thresholds 0.3 / 0.4 / 0.5 / 0.6 kPa, disagreement is respectively
24.1 / 39.7 / 33.3 / 26.1% of matched time.

The longest missing S block is 4 February 11:55 to 7 February 09:30 on the
normalized source clock. Missing values in the published export do not prove a
hardware outage. The source does not let us separate sensor placement,
microclimate, calibration, export processing and equipment status.

## Reproduce

Extract the complete ZIP into a new folder, then run with Python 3.10 or later:

```text
python analyse.py --source source-climate.csv --out reproduced
```

The script uses only Python's standard library, checks the source SHA-256 and
writes JSON/CSV without network calls. Compare `reproduced/summary.json` with
`results/summary.json`. Plot generation additionally uses matplotlib and pandas:

```text
python plot.py --root . --out charts
```

The published figures have also been visually checked. Hamfy independently
cross-checked the calculations with pandas/NumPy and with the website's sensor
analyser. Agreement is numerical verification, not field calibration.

To reproduce the comparison in https://hamfy.eu/en/tools/sensor-analysis :

- Upload `results/primary-paired.csv`, then `results/sigrow-paired.csv` separately.
- Use cadence 5 minutes, UTC offset +1, VPD minimum 0.4 kPa and maximum 1.6 kPa.
- Read the mean air VPD and time *below* the minimum. Do not combine the
  above-maximum duration with the below-minimum result.
- Both paired CSVs cover 938 h 05 min and retain gaps. They deliberately exclude
  intervals available from only one stream, to enable a matched comparison.
- `results/primary.csv` and `results/sigrow.csv` retain every valid pair in each
  original stream; use those to reproduce individual data availability instead.
- All four CSVs have `timestamp`, `temperature_c`, `humidity_pct`. There is no
  measured leaf temperature, artificial PPFD or imputed climate value.

`results/daily.csv` supplies the chart: daily mean VPD only over matched intervals,
and separate valid-row percentages. A day's mean can reflect only part of a day.
`results/thresholds.csv` supplies the threshold table.

## Interpretation

Our finding is that these two published measurement streams would give different
answers to the same review rule. The next operational step is to verify sensor
positions, calibration and logging before changing a control threshold. A
documented side-by-side measurement against a reference could help separate
location effects from instrument differences. Actual alarm evaluation also needs
the controller's averaging, delay and hysteresis settings.

This observational, single-compartment analysis does not measure crop losses,
energy savings, disease, controller performance or the accuracy of either sensor.
It does not establish that the same numerical differences apply to a sealed
indoor farm. It provides an auditable method for reviewing that farm's own data.

## Reuse

Source data: Copyright 2023 Koidra Tech Inc.; included MIT permission notice.
Hamfy analysis code, derived results and charts: Copyright 2026 Bate AI Control
s.r.o.; MIT license, see `HAMFY-LICENSE.txt`. Please identify the original
measurement source separately from Hamfy's analysis when citing this work.
