TC Lab Blog

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:

MetricTemperatureHumidity
Min18.4°C27.0%
Max32.3°C49.2%
Mean23.0°C38.6%

For tissue culture, the target ranges are 20-25°C and 40-70% humidity. The numbers aren’t great:

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