Remote Access and First Data Analysis
The lab API was accessible via Cloudflare Tunnel at lab.egc.land, but I needed SSH access to the Pi from anywhere too — not just the home network. And with two days of sensor data accumulating, it was time to look at what the numbers actually say.
SSH from anywhere
Added a second ingress rule to the existing Cloudflare Tunnel: ssh.egc.land now routes to localhost:22 on the Pi. On the client side, an SSH config entry uses cloudflared access ssh as a ProxyCommand. No Cloudflare Access policies or Zero Trust setup needed — SSH key authentication is the security layer.
To verify it worked from a truly remote connection, I tethered my laptop to my phone’s hotspot. First mistake: the phone was still on the home WiFi while running the hotspot, so the laptop could reach the Pi’s LAN IP through the phone. Turning off the phone’s WiFi forced it to cellular-only. The LAN IP timed out (correct), and ssh.egc.land connected (correct). Remote access confirmed.
First real data
With 32 hours of continuous readings (3,936 data points at 30-second intervals), I ran the first statistical analysis:
| Metric | Temperature | Humidity |
|---|---|---|
| Min | 18.4°C | 27.0% |
| Max | 32.3°C | 49.2% |
| Mean | 23.0°C | 38.6% |
For tissue culture, the target ranges are 20-25°C and 40-70% humidity. The numbers aren’t great:
- Only 50% of temperature readings fall within the 20-25°C target range
- The temperature swings nearly 14°C between night and day
- Humidity is chronically low, averaging 38.6% against a 40% floor
- Combined suitability — both temperature AND humidity simultaneously in range — was only 22.9%
That last number is the real killer. Individual metrics look marginal. Together, they’re disqualifying.
The radiator discovery
The analysis initially flagged “a suspicious spike to 30°C+” on March 3. Digging deeper revealed it wasn’t a spike at all — it was a 5-hour sustained heating event.
From 09:51 to 14:54 on March 3, temperature exceeded 28°C for 5 continuous hours, with 73 minutes above 30°C. The peak was 32.3°C. Meanwhile, humidity plummeted — the two metrics showed a Pearson correlation of -0.914. Temperature and humidity were almost perfectly inversely coupled.
The cause: a freestanding electric radiator about 1.5 metres from the sensor. I’d turned it on while working in the room on March 3 but was sick on March 4 and didn’t enter the room — the radiator stayed off. March 4’s data showed dramatically better conditions: tighter temperature range, higher humidity, no spikes. The radiator was the sole driver of both problems.
This took three iterations to get right. The first analysis report had errors in the hourly breakdown. The second corrected the statistics but miscounted the spike duration. The third finally got it all consistent. Even AI-assisted analysis needs sanity-checking — which is itself a useful lesson for the project.
The fix is simple: turn off the freestanding radiator permanently. The room’s central heating maintains 20-23°C naturally. For fine-grained temperature control in experiments, the Shelly Plug S on a heat mat will be far more precise than a room heater.
This room needs work before cultures can go in. But at least now I have data to quantify exactly how much work — and I know the single biggest environmental problem is a radiator I can just unplug.
Protecting the data
The Pi’s SD card is the single point of failure for all sensor data. The ESP32 is stateless — it POSTs readings and immediately forgets them. If the SD card dies, everything is gone.
Set up automated daily backups: a cron job on my laptop SCPs the SQLite database from the Pi every night via the Cloudflare tunnel. Thirty-day rolling retention. At ~200KB per day of new data, a 64GB SD card would last centuries — but SD cards fail mechanically, not from capacity. The backup is insurance against hardware death, not storage limits.
First backup: 300KB, covering ~3,900+ readings.
Lessons
- Phone hotspots can bridge to home WiFi. If the phone is connected to the home network while running a hotspot, the laptop can reach LAN devices through the phone. To test true remote-only access, turn off WiFi on the phone so the hotspot uses cellular only.
cloudflared access sshmust be installed on the client machine, not just the server. The ProxyCommand runs locally.- WSL2 cron only runs when the laptop is awake. Missed backup nights aren’t critical at this data rate, but worth knowing.
- The SD card is the real risk, not storage capacity. Always back up off-device.