Automating reservoir top-up and nutrient dosing with ESP32 and n8n: build log and reliability data

By Geert Warmenbol · Published 30 May 2026

Automating reservoir top-up and nutrient dosing with ESP32 and n8n: build log and reliability data

Key takeaways

In 8 months of logged operation across two Bangkok DWC systems, the ESP32-based reservoir automation ran 1,847 dosing events with a 96.2 percent success rate -- the 71 failure events split almost evenly between sensor drift requiring recalibration, pump cavitation from air in the nutrient line, and n8n workflow timeouts during Bangkok power fluctuations (Plant Mood automation log, 2024).

The single most damaging failure mode in a DIY reservoir dosing system is not hardware failure -- it is a stuck float sensor combined with no maximum runtime limit on the fill pump, which in two documented events ran the pump for 38 and 41 minutes respectively before an alert fired, flooding the grow tray overflow and wasting 4 to 6 liters of nutrient solution.

EC sensors in a Bangkok DWC reservoir require recalibration every 3 to 4 weeks during hot season due to temperature-driven probe drift -- a sensor reading EC 1.4 in February at 24 degrees Celsius reservoir temperature reads EC 1.7 to 1.9 at 30 degrees Celsius without temperature compensation applied, causing the dosing logic to withhold nutrients from a crop that actually needs them.

n8n running on a local Raspberry Pi inside the apartment is a more reliable automation orchestrator for this use case than cloud-based alternatives because Bangkok power fluctuations that disconnect the apartment from the internet do not interrupt local workflow execution -- 14 of the 71 failure events were traced to cloud webhook timeouts during outages that a local n8n instance would not have produced.

The minimum viable safety layer for any automated dosing system is a hardware watchdog independent of the microcontroller: a mechanical float valve as a physical overflow backstop, a maximum pump runtime fuse in the relay logic, and an out-of-band alert (SMS or Line message) that fires if any pump runs longer than 90 seconds without a confirming sensor reading.

TL;DR

The automation works. Eight months of data says 96.2 percent of dosing events executed correctly without manual intervention, which is better than any manual checking schedule I could maintain across two systems in Bangkok heat. The 3.8 percent failure rate is not random -- it clusters around sensor drift, air in the dosing lines, and edge cases in the control logic that only appear under conditions the initial build did not anticipate. Building the hardware is the easy half. Building the failure modes out of the logic is the half that takes the rest of the year.

The 41-minute pump event

2:17am. The float sensor in reservoir two had been reading 'low' continuously for 41 minutes. The fill pump had been running the entire time. The n8n workflow had no maximum runtime check on the fill cycle -- it trusted the float sensor to report 'full' and stop the pump. The float sensor arm had lodged against the reservoir wall when the water level rose and the arm did not move. The pump kept running. By the time the alert fired on a secondary EC threshold check that noticed the reservoir EC had dropped to 0.3 -- heavily diluted from 41 minutes of plain water input -- the grow tray overflow had been running for at least 20 minutes and the floor had 2 liters of diluted nutrient solution on it.

That event did not happen because the hardware failed. The ESP32 was functioning correctly. The pump was functioning correctly. The float sensor had a mechanical fault -- a 40-baht component -- and the software had no backstop for it. Every subsequent build decision came from that night. The question stopped being 'how do I automate this' and became 'what does this system do when one component behaves in a way I did not anticipate.' The answer to that question is the actual engineering work in a DIY automation build.

More sensors make the system less reliable until you solve the right problem

Each additional sensor is an additional failure surface. A sensor that drifts, reads incorrectly, or goes offline does not produce a gap in the data -- in a naive dosing system it produces an incorrect decision. An EC sensor reading high due to temperature drift triggers the dosing logic to withhold nutrients. A float sensor that sticks triggers the fill pump to run indefinitely. A pH probe with a fouled junction produces a reading that causes the pH dosing pump to add acid to a reservoir that is already in range. The additional sensor does not add reliability until the control logic contains an explicit model of how that sensor fails and what the system should do when it does. Adding sensors without adding failure mode handling adds complexity and failure surface simultaneously. The most reliable version of this system after 8 months is simpler in sensor count than the version built in month one -- not because the data from those sensors was not useful, but because three of the sensors required more failure handling logic than they contributed in decision quality.

The month-one build included a flow sensor on the nutrient dosing lines to confirm that each pump had actually delivered fluid when triggered. The flow sensor added two additional failure modes: false negatives when micro-bubbles in the line interrupted the flow reading and triggered a redundant dose, and false positives when the sensor fouled and reported flow during a pump-off state. Removing the flow sensor and replacing it with a timed dose volume calculation -- pump X runs for Y milliseconds to deliver Z milliliters at a known flow rate -- reduced dosing failure events by 11 over the following three months at the cost of one monthly pump flow rate calibration check (Plant Mood automation log, 2024).

Adding sensors improves reliability. More data points mean better decisions, faster detection of problems, and fewer crop failures. A dosing system with EC, pH, temperature, water level, and flow sensors is more reliable than one with just EC and a float.

Eight months of automation by the numbers

1,847 dosing events, 96.2 percent success rate

Total automated reservoir top-up and nutrient dosing events logged across two Bangkok DWC systems from January to August 2024. Success defined as a dosing event that completed within the expected time window and produced a confirming sensor reading within tolerance. 71 failure events logged, categorized, and root-caused (Plant Mood automation log, 2024).

3 to 4 weeks

Recalibration interval required for EC probes in a Bangkok DWC reservoir during hot season (March to May) due to temperature-driven drift. Without temperature compensation applied in firmware, a probe calibrated at 24 degrees Celsius reservoir temperature reads 1.7 to 1.9 EC at 30 degrees Celsius for a solution actually at 1.4 EC -- a 21 to 36 percent overread that causes the dosing logic to withhold nutrients from a crop that is underfed (Plant Mood sensor calibration records, 2024).

Longest documented pump runtime in a single stuck-float event before the secondary alert threshold fired and the pump was stopped. Two stuck-float events occurred across the 8-month period: 38 minutes and 41 minutes respectively. Both occurred between midnight and 4am. Both were caused by the float arm lodging against the reservoir wall as water level rose (Plant Mood automation log, 2024).

Failure events directly attributable to cloud webhook timeouts during Bangkok power fluctuations, where the n8n instance was cloud-hosted and lost connectivity during brief outages. After migrating n8n to a local Raspberry Pi, zero failure events of this type occurred in the following four months despite multiple power fluctuations being logged by the UPS monitoring the grow room circuit (Plant Mood automation log, 2024).

How the system is built and why the architecture decisions matter

The core loop is straightforward: an ESP32 microcontroller reads EC, pH, and water level sensors at a configurable interval (currently every 4 minutes), pushes readings to a Supabase table via HTTP POST, and n8n polls that table on a trigger schedule. When a reading falls outside the defined threshold band -- EC below 1.3, pH above 6.5, water level below the low float trigger -- n8n fires a webhook back to the ESP32 to activate the relevant relay: nutrient A pump, nutrient B pump, pH down pump, or fill pump. The ESP32 holds the relay open for a calculated duration based on reservoir volume and target correction, then closes it and waits for a confirming sensor reading before considering the event complete. If the confirming reading does not arrive within a timeout window, n8n sends an alert via Line Notify and flags the event as failed in the log table.

The decision to route control logic through n8n rather than running it entirely on the ESP32 was deliberate and has a direct reliability implication. An ESP32 running local control logic can act faster -- no network round trip -- but it cannot be updated without physical access to the device, cannot log to a remote database without additional code, and cannot integrate with external alerting systems without significant firmware complexity. n8n running on a local Raspberry Pi handles all of that in a visual workflow that can be modified without touching the ESP32 firmware. The trade-off is the network hop between the ESP32 and the Pi, which adds 50 to 200 milliseconds of latency to each control decision. For reservoir dosing, where the relevant timescales are minutes to hours, this latency is irrelevant. For a system requiring sub-second response -- an emergency shutoff triggered by a leak sensor, for example -- it would not be.

Temperature compensation for EC readings deserves specific mention because it is the most commonly skipped firmware step in DIY hydroponic automation and the most consequential in Bangkok conditions. The conductivity of a nutrient solution increases by approximately 2 percent per degree Celsius. A reservoir at 30 degrees Celsius will read approximately 12 percent higher EC than the same solution at 24 degrees Celsius on an uncompensated probe. The compensation formula is EC_compensated = EC_raw divided by (1 + 0.02 multiplied by (temperature minus 25)), where temperature is the reservoir temperature in Celsius and 25 is the standard reference temperature. This is four lines of code. Skipping it in Bangkok hot season means the dosing system is systematically underfeeding crops from March to May while reporting normal EC values.

What the 8-month build log actually shows

Of 71 logged failure events, 26 were sensor drift or calibration failures (EC probe overread in hot season, pH probe junction fouling), 21 were pump or line issues (cavitation from air in the nutrient concentrate line, peristaltic pump tube wear causing reduced flow volume), and 14 were network or orchestration failures (cloud n8n webhook timeouts, one Supabase API rate limit hit during a logging backfill). The remaining 10 were logic edge cases -- the stuck float event twice, a scenario where simultaneous low-EC and low-water-level triggers fired the nutrient pumps and fill pump concurrently and the conflicting inputs produced an inconclusive confirming reading, and three events where a power cycle during a dose event left a relay in an indeterminate state. No ESP32 hardware failures occurred across the 8-month period.

Failure events cluster into three categories, not randomly distributed across hardware

A grower building this system for the first time should allocate engineering effort in the same proportion as the failure distribution: probe calibration and temperature compensation first, pump line maintenance and tube replacement schedule second, local-first orchestration architecture third. Hardware reliability of the ESP32 itself is not where the system fails.

The first four months of operation used a cloud-hosted n8n instance with the ESP32 posting readings to Supabase and n8n polling via cloud webhook. Bangkok experiences frequent brief power fluctuations -- the grow room UPS logged 23 input power events across the full 8-month period, ranging from 80ms dips to one 4-minute full outage. During the cloud-hosted period, 14 of the 37 failure events in that phase were traceable to webhook delivery failures during these fluctuations, where the ESP32 was posting correctly but the cloud n8n instance was not receiving or processing the webhook reliably. After migrating n8n to a Raspberry Pi 4 on the same local network as the ESP32, with the Pi protected by the same UPS, network-related failure events dropped to zero across the following four months. The Supabase logging continued as the remote data store -- the change was moving the control logic local while keeping the data remote.

Migrating n8n from cloud to local Raspberry Pi eliminated 20 percent of all failure events

For a Bangkok grow room automation build, local n8n on a Raspberry Pi is not a performance optimization -- it is a reliability requirement given local power infrastructure. Cloud-first architecture for control logic in a market with frequent brief outages adds a failure surface that local architecture eliminates entirely.

The flow sensor on the nutrient lines was removed in month three after analysis showed it contributed more failure events than it prevented. The replacement approach calibrates each peristaltic pump once per month: run the pump for exactly 60 seconds into a graduated cylinder, record the volume delivered, update the dose duration calculation in the n8n workflow. At the current pump condition, 1 mL of nutrient A requires 380 milliseconds of pump runtime. The n8n workflow calculates dose duration from target volume rather than measuring flow. Monthly calibration takes 8 minutes per pump. The dose accuracy across the subsequent five months was within 4 percent of target volume on average, with maximum deviation of 9 percent on one occasion when tube wear had progressed faster than expected between calibrations. Tube replacement is now on a 6-week schedule regardless of apparent performance.

Timed dose volume outperformed flow sensor confirmation across all metrics after month three

Flow sensors add complexity and failure surface to a peristaltic pump dosing system. Timed volume calculation with monthly calibration achieves comparable accuracy with lower maintenance burden and fewer failure modes. The calibration check also functions as a pump health indicator -- a significant change in the volume-per-second ratio between calibrations signals tube wear before it affects dose accuracy.

Plant Mood ESP32 automation log and Supabase grow data, January to August 2024

The build problems that look like hardware but are not

My EC readings are all over the place and I cannot trust the automation to dose correctly.

In Bangkok hot season, an uncompensated EC probe in a reservoir swinging between 24 and 31 degrees Celsius across a day will produce readings that vary by 15 to 20 percent on the same solution. This is not sensor malfunction -- it is physics. The fix is temperature compensation in the firmware using the formula EC_compensated = EC_raw divided by (1 + 0.02 multiplied by (temperature minus 25)), which requires a simultaneous temperature reading from a DS18B20 or similar probe in the reservoir. If the firmware does not include temperature compensation, the EC readings will never be trustworthy in Bangkok conditions regardless of probe quality or calibration frequency.

My dosing pump runs but the EC does not change after a dose event.

Air in the nutrient concentrate line. Peristaltic pumps will run and appear to function while pumping air through a partially empty or poorly primed supply tube. The pump head movement is audible but no fluid is delivered to the reservoir. Prime the supply lines by running each pump manually until fluid exits the outlet tube with no bubbles before trusting automated dose calculations. Also check that nutrient concentrate bottles are not positioned above the pump head -- the fluid should flow toward the pump, not away from it. If the bottles are higher than the pump, the line may drain back between doses and require re-priming each time.

The automation was working fine for two months and then started making incorrect dosing decisions.

Probe drift. EC and pH probes do not maintain calibration indefinitely -- the EC probe junction accumulates mineral deposits and reads progressively higher, the pH probe reference junction dries or fouls and reads increasingly inaccurate. In Bangkok hot season, EC probe drift is significant enough to affect dosing decisions within 3 to 4 weeks of calibration. A system that was calibrated in February and never recalibrated will be making decisions in April based on readings that are 15 to 25 percent off the actual solution values. The fix is a fixed recalibration schedule -- EC monthly, pH every 3 weeks during hot season -- written into the maintenance calendar and treated as non-negotiable, not done reactively when the readings look wrong.

My n8n workflow keeps timing out and I am missing dose events.

If n8n is cloud-hosted, Bangkok power fluctuations that disconnect the apartment from the internet interrupt webhook delivery between the ESP32 and the workflow. The ESP32 may be posting correctly to Supabase but the n8n cloud instance is not processing the trigger reliably during connectivity gaps. Migrate n8n to a local Raspberry Pi on the same network as the ESP32 and protect both devices with a UPS. The control logic should not depend on internet connectivity to function -- the internet connection is for alerting and remote monitoring, not for the core dosing decision loop.

What the build log revealed that the build guides did not mention

Both stuck-float events in the 8-month log occurred between midnight and 4am -- the window when no manual check would occur and the pump could run longest before discovery. This is not a coincidence. The automated system runs most autonomously during sleeping hours, which is exactly when the edge cases that require human intervention have the longest time to develop before they are caught. The safety layer design for a DIY automation system should be specifically stress-tested against the question: what is the worst thing this system can do for 6 hours with no one watching? Every failure mode that passes that test without a hardware backstop is an unacceptable risk in a system running in a Bangkok apartment.

The failure mode that matters most happens at the worst time

Three of the 71 logged failure events occurred when a power interruption happened during an active dose event -- the relay was open and the pump was running when power dropped. On power restoration, the ESP32 boots into a default state where all relays are open (pumps off), which is the correct fail-safe behavior. But the n8n workflow had no record of the interrupted event completing, and the Supabase log showed the event as open with no confirming reading. In two of three cases the workflow re-triggered the dose event on the next polling cycle, producing a double dose. Adding an event completion flag written to Supabase before the confirming read -- and a startup check that marks any open events from before the current boot as failed rather than pending -- prevented all three of these scenarios from recurring.

Power cycling during a dose event leaves relays in an indeterminate state

Nutrient A and B concentrates are more viscous at cool temperatures and less viscous in Bangkok heat. A peristaltic pump calibrated at 28 degrees Celsius ambient delivers a different volume per second at 22 degrees Celsius during Bangkok cool season. The difference is small -- approximately 3 to 5 percent across the temperature range encountered in the grow room -- but it accumulates across repeated doses. Monthly calibration catches this drift, but a calibration done in December will be slightly off by March as ambient temperatures rise. For crops where EC precision matters -- basil in DWC is more sensitive to EC overshoot than lettuce -- a seasonal recalibration in February and again in June is more accurate than a fixed annual schedule.

Nutrient concentrate viscosity changes with temperature and affects peristaltic pump flow rate

The month-one alert configuration sent a Line Notify message for every reading outside threshold, every failed confirming read, and every pump event completion. Within three weeks the alert volume was high enough that messages were being dismissed without reading. The stuck-float alert that eventually fired at 2:17am was in a notification stream that had sent 34 messages in the previous 48 hours. Alert design for a grow room automation system requires the same triage that a production engineering team applies to monitoring: critical alerts that require immediate action must be visually and audibly distinct from informational alerts that can be reviewed the next morning. The current configuration has three alert levels -- immediate Line call-style notification for pump runtime above 90 seconds or EC above 2.8, standard Line message for out-of-range readings, and a daily digest for calibration reminders and event summaries.

Alert fatigue is as dangerous as no alerts

What the build looks like after 8 months of reliability iteration

Anyone building a first ESP32 hydroponic dosing system

Build the hardware watchdog before writing the first line of dosing logic. This means: a mechanical float valve installed 2 cm above the electronic float sensor as a physical overflow backstop that operates independently of all software, a maximum pump runtime limit hardcoded in the ESP32 relay logic (not in n8n -- in the microcontroller firmware, so it fires even if the network is down), and an out-of-band alert that fires if any pump relay stays open longer than 90 seconds. These three components cost under 200 baht in hardware and an hour to implement. They are the only things that prevented the two stuck-float events from becoming equipment damage events.

A system where the worst-case hardware failure -- stuck sensor, runaway pump -- produces a mess and a wasted nutrient solution rather than a flooded grow room or a burned-out pump motor.

Growers running n8n as the automation orchestrator

Run n8n locally on a Raspberry Pi on the same network as the ESP32, with both devices on a UPS. The control logic -- the decision to dose, the calculation of dose volume, the confirmation check -- should not depend on internet connectivity. Supabase or any other remote database can continue to receive logs and serve the monitoring dashboard over the internet connection, but if the internet drops, the dosing decisions should continue executing locally. Configure n8n with a local Supabase mirror or a local SQLite fallback for the polling trigger if full offline operation is required.

Zero control logic failures during Bangkok power fluctuations or ISP outages -- the category that produced 20 percent of all failure events in the cloud-hosted phase of this build.

Growers in Bangkok running EC-based automated dosing year-round

Implement temperature compensation for EC readings in the ESP32 firmware before deploying automated dosing. Add a DS18B20 waterproof temperature probe to the reservoir alongside the EC probe. Apply the compensation formula in firmware: EC_compensated = EC_raw divided by (1 + 0.02 multiplied by (T minus 25)), where T is reservoir temperature in Celsius. Set the calibration schedule to monthly during hot season and every 6 weeks during cool season. Write the next calibration date into the n8n daily digest alert so it appears in the morning summary rather than requiring a separate calendar entry.

EC readings that reflect actual nutrient concentration rather than temperature-inflated probe output -- which in Bangkok hot season is the difference between a dosing system that feeds crops correctly and one that systematically underfeeds from March to May while reporting normal values.

Growers using peristaltic pumps for nutrient dosing

Replace flow sensor confirmation with timed volume calculation and a monthly manual calibration. Each month, run each peristaltic pump for exactly 60 seconds into a graduated cylinder, record the volume, and update the dose duration formula in n8n. Replace pump tubing on a fixed 6-week schedule regardless of apparent performance -- tube wear changes flow rate gradually in a way that is not visible until dose accuracy has already degraded. Store the calibration history in Supabase: a significant change in volume-per-second between two consecutive calibrations signals accelerating tube wear and an earlier replacement.

Dose accuracy within 5 percent of target volume across all pump conditions, with tube wear detected before it affects crop nutrition rather than after an unexplained EC trend reveals the problem.

Growers configuring alerting for an automated grow room system

Design three distinct alert levels before deploying any automation. Level one is an immediate interrupt-style notification -- Line call or loud phone alert -- reserved for pump runtime above 90 seconds, EC above 2.5 or below 0.8, and pH above 7.0 or below 5.5. These are the readings that can kill a crop or damage equipment within hours. Level two is a standard push notification for any reading outside normal operating range that does not meet level-one thresholds. Level three is a daily digest sent each morning summarising the previous 24 hours of events, next calibration due date, and any failed events requiring manual review. If level-two notifications exceed 5 in a 24-hour period, that threshold triggers a level-one alert -- alert volume itself is a signal that something systematic is wrong.

Alert notifications that are read and acted on rather than dismissed, with critical events producing a response within minutes and informational events reviewed on a schedule rather than creating background noise that trains the grower to ignore the notification stream.

Writing an explicit startup routine that checks for and resolves interrupted dose events before the ESP32 begins normal operation after a power cycle. Most DIY builds boot into normal polling mode immediately on power restoration, which causes n8n to re-trigger any open events from before the interruption and produce double doses. A 10-line startup function that queries Supabase for any events with an open status and a timestamp older than the current boot time, marks them as interrupted, and sends a level-two alert before entering normal operation prevents every double-dose event that power cycling would otherwise cause -- and costs less than 20 minutes to implement.

FAQ

How reliable is ESP32-based automated reservoir dosing for hydroponics?

In Plant Mood automation log data across 8 months and two Bangkok DWC systems, 1,847 dosing events ran with a 96.2 percent success rate. The 71 failure events split across three categories: sensor drift and calibration failures (26 events), pump and line issues including cavitation and tube wear (21 events), and network or orchestration failures (14 events, all during the cloud-hosted n8n phase). No ESP32 hardware failures occurred. The 96.2 percent rate reflects a mature build after iterative failure mode resolution -- the first-month rate was lower.

What is the biggest failure risk in a DIY hydroponic dosing system?

A stuck float sensor with no maximum pump runtime limit. In two events in Plant Mood automation logs, the fill pump ran for 38 and 41 minutes respectively after the float arm lodged against the reservoir wall. The pump had no hardware runtime limit and the software watchdog did not fire until a secondary EC threshold dropped below 0.3 from dilution. Both events happened between midnight and 4am. A mechanical float valve as a physical overflow backstop and a hardcoded 90-second maximum pump runtime in the ESP32 firmware are the two components that prevent this from causing equipment damage.

Does n8n work well for hydroponic automation in Bangkok?

Local n8n on a Raspberry Pi works well. Cloud-hosted n8n produced 14 failure events in 4 months due to webhook delivery failures during Bangkok power fluctuations. After migrating n8n to a local Raspberry Pi on the same network as the ESP32 -- with both devices on a UPS -- network-related failure events dropped to zero across the following four months. For Bangkok grow room automation, the control logic should not depend on internet connectivity. Supabase can continue to receive logs remotely, but dosing decisions should execute locally.

Why are my hydroponic EC readings inconsistent in hot weather?

Uncompensated EC probes read higher as reservoir temperature rises -- approximately 2 percent per degree Celsius. A probe calibrated at 24 degrees Celsius reads 1.7 to 1.9 EC for a solution actually at 1.4 EC when reservoir temperature reaches 30 degrees Celsius. The fix is temperature compensation in the ESP32 firmware: EC_compensated = EC_raw divided by (1 + 0.02 multiplied by (T minus 25)), where T is reservoir temperature from a DS18B20 probe. Without this, automated dosing systems in Bangkok hot season systematically underfeed crops from March to May while reporting normal EC values.

Should I use a flow sensor or timed dosing for peristaltic pump nutrient delivery?

Timed volume calculation with monthly calibration outperformed flow sensor confirmation in Plant Mood automation data. The flow sensor contributed 11 failure events in the first three months through false negatives from micro-bubbles and false positives from sensor fouling. Removing it and replacing with a timed dose calculation -- pump runs for a calculated duration based on monthly-calibrated flow rate -- reduced failure events and simplified the system. Monthly calibration takes 8 minutes per pump and also functions as a tube wear indicator: significant flow rate change between calibrations signals early tube replacement.

How do I stop my automated hydroponic system from making double doses after a power cut?

Add a startup routine that queries Supabase for any dose events with an open status and a timestamp older than the current boot time, marks them as interrupted, and sends an alert before entering normal polling mode. Without this, the ESP32 boots into normal operation after a power cycle and n8n re-triggers any open events from before the interruption. Three of 71 failure events in Plant Mood automation logs were double-dose events caused by exactly this scenario. The startup check is approximately 10 lines of code and prevents every instance of this failure mode.

How often do EC and pH probes need recalibration in a Bangkok hydroponic system?

EC probes require recalibration every 3 to 4 weeks during Bangkok hot season (March to May) due to temperature-driven drift and mineral deposit accumulation. pH probes require recalibration every 3 weeks during hot season as the reference junction dries faster at higher temperatures. During Bangkok cool season (November to February), both probes hold calibration longer -- a 6-week interval is adequate for EC and 4 weeks for pH. In Plant Mood automation data, probe drift was the largest single failure category at 26 of 71 events, all of which were preventable with a fixed recalibration schedule.