Irrigation System
A hose timer tells you a valve opened. This tells you what came out of it. Seven zones, a hall-effect flow meter on every one of them, plus pressure, water temperature and TDS at the manifold and a second pair of meters straddling the fertiliser injector so you know how much concentrate actually went into the line. It runs about 1500 ft of drip tubing across a garden, blueberries, trees, blackberries, a mister run, a hose drop and the front beds.
Flow per zone is the part that earns its keep. A zone that suddenly reads double has a blown fitting; a zone that reads zero has a clogged filter or a valve that didn’t open. Both of those are invisible on a timer, and both of them are a dead bed by the time you notice.
Parts
Some links below are Amazon affiliate links. As an Amazon Associate I earn from qualifying purchases — at no extra cost to you. It helps keep these guides free. Outside the US, they should send you to your own Amazon store; if one doesn't, searching the part number there will find it.
This is a big build and the list is long. Nothing here is optional if you want every entity in the config; take the electronics and the zone valves and skip the fertiliser half if you only want watering.
The pump box
- ESP32 38-pin DevKit (2-pack) — the config’s
board: esp32dev - ADS1115 16-bit I2C ADC (3-pack) — pressure, thermistor and TDS all land here
- PCF8575 16-bit I2C I/O expander (4-pack) — nine relay outputs off two wires
- 16-channel relay module — sold in 5 V, 12 V and 24 V coil versions; buy the one that matches your rail
- TXS0108E 8-channel level shifters (6-pack) — ten 5 V pulse lines into a 3.3 V board
- 24 V 5 A supply — one rail for the valves
- Isolated 12–72 V to 5 V buck converter — makes the 5 V for the ESP32 and the flow meters off that rail
- Large ABS NEMA enclosure — the 16-channel relay board on its own is bigger than a typical project box
- IP65 hinged junction box with glands ×2–3 — for the flow-meter junctions out at the manifold
- 12 V 70 W COB panel — the box light, dimmable from Home Assistant
- Dual MOSFET PWM driver module — a 3.3 V pin cannot drive that panel directly
- 5.5×2.1 mm barrel jacks and pigtails
- 24 AWG silicone hookup wire, 10 colours
The manifold
- WAYNE PLS100 1 HP stainless sprinkling pump
- 1 inch motorised brass ball valve, 9–24 V AC/DC, 2-wire auto-return ×7 for the zones, plus one for the pump valve — this is the expensive part of the build
- 1/2 inch normally-closed 12 V solenoid valve — the fertiliser output valve, on a smaller line
- G3/4 hall-effect flow meter, 2–45 L/min ×10 — seven zones, the manifold, and one either side of the injector
- G1/4 pressure transducer, 0–80 psi, 0.5–4.5 V out
- 0–200 psi test gauge, 3/4 inch hose thread — you need this to calibrate the transducer
- 50–55 psi brass pressure regulator — drip tubing does not want mains pressure
- Hose-bib backflow preventer — fertiliser goes in downstream of this, and it stays that way
- Analog TDS probe — nothing in the parts bin matches, so this is a search
- 10 kΩ NTC thermistor probe, B3950 plus a 10 kΩ resistor for its divider
Plus brass to join it all: G1/2 tees, G1/2 hex nipples, NPT-to-G adapters for the transducer port, 1/4 NPT to 3/4 GHT adapters, and a short 3/4 inch rubber hose for jumpers.
Fertiliser
- EZ-FLO 2005-HB 3/4 gallon low-pressure injector — the “EZ-Flo” sensors in the config are named after this
- G1/2 venturi injector — the cheap alternative if you’d rather mix from a bucket
Out in the yard
- 1/2 inch poly supply tubing, 500 ft — you will want three rolls
- Rain Bird 1/4 inch blank distribution tubing, 250 ft
- Rain Bird pressure-compensating emitter tubing, 50 ft rolls — buy more of these than you think
- 1/2 inch barbed fittings kit, 1/2 to 1/4 inch barbed tees, reducing tees and end plugs
- Adjustable 360° emitters on 6.5 inch stakes
- Rain Bird 10-32 micro-spray nozzles
- 49 ft misting line with 15 brass nozzles — the “Misters” zone
- 3/4 GHT to 1/2 inch drip adapters
- 6 inch galvanised landscape staples, 120-pack
Getting signal and power out there
- 16/2 low-voltage landscape cable, 500 ft — one pair per valve
- 1/2 inch liquid-tight conduit and fittings kit
- Solder-seal heat-shrink butt connectors — every splice that lives outside
- IP68 3-pin inline junction connectors
- Lever-nut wire connectors — for inside the box only
Filament
Wiring
Every pin below comes out of bruh-pump.yaml. Change one and you change the
matching line in substitutions: — that is the whole point of them being there.
| Function | ESP32 pin |
|---|---|
| I2C SDA | GPIO21 |
| I2C SCL | GPIO22 |
| Manifold flow pulse | GPIO32 |
| EZ-Flo inflow pulse | GPIO33 |
| EZ-Flo outflow pulse | GPIO25 |
| Zone 1 flow pulse | GPIO16 |
| Zone 2 flow pulse | GPIO17 |
| Zone 3 flow pulse | GPIO27 |
| Zone 4 flow pulse | GPIO23 |
Zone 5 flow pulse (zone_5_pulse) | GPIO14 |
Zone 6 flow pulse (zone_6_pulse) | GPIO13 |
| Zone 7 flow pulse | GPIO26 |
| Box light PWM | GPIO18 |
Every pulse input is configured input: true, pullup: true. That is the right
setup for a hall meter with an open-drain output — the pin idles at 3.3 V and the
meter pulls it down. If yours drives its output high to its own 5 V supply
instead, it needs the level shifter or it will sit 1.7 V above what the ESP32’s
pins are rated for. Power and ground for the meters come off the buck converter.
On the I2C bus, the ADS1115 sits at 0x48 and the expander at 0x27. The
expander’s outputs are all inverted: true, which is what a low-level-trigger
relay board wants:
| Output | PCF8575 pin |
|---|---|
| Zone 1–7 | 0, 1, 2, 3, 4, 5, 6 |
| Pump water valve | 14 |
| Fertiliser output valve | 15 |
And on the ADC:
| ADS1115 channel | Reads |
|---|---|
| A0 | Manifold pressure transducer |
| A1 | TDS probe |
| A2 | Thermistor divider |
Two flow inputs are crossed in the file. The sensor named Z5 Flow reads
${zone_6_pulse} (GPIO13) and the one named Z6 Flow reads ${zone_5_pulse}
(GPIO14). Either swap the two wires at the terminal strip or swap the two
substitution references — but do it deliberately, because the zone switches
are not crossed, so as shipped, opening Zone 5 makes Zone 6’s meter spin.
The ADS1115 has to run at 5 V here. The transducer swings to 4.5 V, which is
why the config asks for gain: 6.144 — a 3.3 V reference simply cannot see the
top of that range. If your breakout’s I2C pull-ups go to VDD, the bus will then
idle at 5 V and the ESP32’s pins are in it. Pull SDA and SCL up to 3.3 V instead,
or put the level shifter on the bus as well as on the pulse lines.
Assembly
-
Plumb the manifold dry first, on the bench, with the gauge fitted. Every flow meter has an arrow on it and it is not a suggestion. The pressure transducer taps a G1/4 port; the thermistor and TDS probe want to sit in flowing water, not in a dead leg where they read yesterday’s number.
-
Fit the regulator and the backflow preventer upstream of everything, and the fertiliser injection point downstream of the backflow preventer. That order is not negotiable — this is the one part of this build that can put fertiliser into drinking water.
-
Pressure-test the manifold before a single wire goes in. Ten meters and nine valves is a lot of threaded joints, and finding the weeping one with the box wired is miserable.
-
Mount the relay board and the ESP32 in the big box, and land every valve pair on the terminal strip before you connect the relay commons. Label the pairs as you land them. Seven identical brown wires is how a zone ends up watering the wrong bed for a season.
-
Run the flow-meter signal wires back through the shifter. Ten pulse lines at 5 V is the thing most likely to kill the ESP32 in this build.
-
Power the box in stages — 24 V rail first with the valve outputs disconnected, confirm the buck is putting out 5 V, then plug in the ESP32.
-
Flash and check the I2C scan in the ESPHome log before you close the door.
scan: trueis already set; you are looking for 0x27 and 0x48.
Configuration
The config is bruh-pump.yaml, in the download section below. Copy it into your
ESPHome directory and fill in secrets.yaml — wifi_ssid, wifi_password,
ota_password, api_key, ap_password. There is a secrets.yaml.example in
the repo with every key these configs use.
Everything you’d normally change lives in substitutions: at the top — the
device name, both I2C pins, the light pin, and all ten pulse pins.
The seven zone_N_name substitutions (Garden, Blueberries, Trees, Blackberries,
Misters, Wood Hose, Front) are defined but nothing references them — the
switches and sensors are named Zone 1 and Z1 Flow literally. Rename the
entities in Home Assistant, or point the name: fields at the substitutions.
Also defined and unused: manifold_sensor_power on GPIO4, left over from
switching the analog sensors’ supply.
There is a second config, bruh-pump-s3.yaml, for an
ESP32-S3-DevKitC-1.
It is the same I2C addresses and the same nine relay outputs on different pins,
but it carries only the manifold and the two EZ-Flo meters — no per-zone flow,
no pressure, no temperature, no TDS. Build the ESP32 one unless you have a
specific reason not to.
Calibration
Nothing on this device reads correctly out of the box, and all three calibrations are two-point.
Flow. Each pulse counter divides by a constant to get L/min: 483 for the manifold, 660 for the zones, 898 for the EZ-Flo pair. Those are pulses per litre for three different meters — if all yours are the same model, they should all be the same number. Find yours by running a zone into a bucket of known volume and dividing the counted pulses by the litres that came out. Do it at a realistic flow rate; these meters are not linear near the bottom of their range.
Pressure. The config maps 0 V to 0.5 psi and 5 V to 80 psi:
filters: - calibrate_linear: - 0.0 -> 0.5 - 5 -> 80.0That is a rough fit, not the transducer’s transfer function. Put the test gauge on the manifold, run the pump, and take two real readings — one at rest and one at working pressure — then replace both points. This is what the gauge is in the parts list for.
TDS. The chain is: raw voltage → temperature compensation at 2% per °C off
25 °C → a conversion lambda → a two-point calibrate_linear (22 → 22 and
1040 → 700) → a 5-sample moving average. Calibrate it with a bottled solution of
known ppm and plain RO water, and replace both points.
The TDS conversion lambda looks like the standard cubic curve but isn’t. It reads
133.42 * V * 3 - 255.86 * V * 2 + 857.39 * V — multiplied by 3 and 2, not cubed
and squared. It collapses to a straight line, about 373 × V after the 0.5 factor.
In practice the two-point calibration downstream absorbs it and the number is
usable near where you calibrated, but it will drift at the ends of the range. If
you want the real curve, rewrite those terms with pow().
Printed parts
Two, and they do unrelated jobs.
air_injector_drill_guide_v3 is a drill guide: a 130 mm flange, 5 mm thick, with
a 70 mm tower over a 21.5 mm bore (opening to 22 mm for the lowest 20 mm). The
tower is that tall for one reason — a long bore is what stops a big bit walking
when it bites. Clamp the flange flat, go slow, and back the bit out to clear
chips rather than leaning on it. Check the bore against your actual bit before
you commit to a print; a guide that is 0.3 mm loose is not a guide.
timer_indicator_disk_v2 is a 130 mm face, 0.4 mm thick, with a 6.2 mm D-profile
centre hole (4.7 mm across the flat) and two 2.25 mm holes on a 14.5 mm bolt
circle, plus an index tab that runs out to 140 mm overall. It presses onto a
flatted shaft and pins to the two holes behind it.
Print settings
| Setting | Drill guide | Indicator disk |
|---|---|---|
| Layer height | 0.2 mm | 0.2 mm |
| Walls | 4+ | n/a — it is two layers of solid |
| Infill | 40% | 100% |
| Supports | None | None |
| Material | PETG, or PLA+ if it lives indoors | PETG |
| Orientation | Flange on the bed, as exported | Flat, as exported |
The guide wants walls, not infill — everything that matters is the bore surface, and a 20% part will flex around a bit under load. The disk is 0.4 mm total, so at 0.2 mm layers it is the first layer plus one; get your first layer right or it will curl off the plate before it finishes.
The other two CAD files, backyard_v2 and garden_sketch_v6, are layout
sketches rather than parts — the plan of the beds and the runs. There is nothing
to print in them.
Troubleshooting
A zone’s flow reads zero but water is coming out. Check the meter’s arrow first, then the signal wire. A hall meter wired backwards passes water happily and never pulses.
Every flow sensor reads a small non-zero number with the pump off. Electrical noise picked up on long pulse runs. Use one twisted pair per meter — signal and its own ground — and keep those runs out of the same conduit as the 24 V valve wiring. Switching nine inductive loads next to ten open-drain signal lines is asking for phantom pulses.
The device boots but no sensors appear. Read the I2C scan in the log. No 0x48 and no 0x27 means the bus isn’t running — usually SDA and SCL swapped, or no pull-ups on the bus at all. One address missing and the other present is a wiring fault on that one board, not a bus problem.
Manifold temperature reads a wild number or nan. The thermistor chain has
three stages, and each one publishes its own entity for exactly this reason.
Look at “Raw Manifold Temperature Voltage” first; if that is sensible, look at
“Manifold Raw Resistance”. The resistance platform is configured DOWNSTREAM
with a 10 kΩ resistor, so the thermistor goes to the supply and the fixed
resistor to ground. Wire the divider the other way round and the curve inverts.
A valve buzzes and gets hot. The 2-wire auto-return valves draw their full current the whole time they are open. That is normal for the type, but it means seven zones open at once is not something the 5 A supply will do. Stagger them in Home Assistant.
Files & downloads
Printable parts
ESPHome configuration s (2)
Copy this into your ESPHome directory and adjust the substitutions at the top.
Secrets are referenced by name — see secrets.yaml.example
.
bruh-pump.yaml
# BRUH Irrigation Pump Controller# ────────────────────────────────────────────────────────────# Complex irrigation system pump controller with multiple zones,# flow sensors, TDS/temperature monitoring, and fertilizer dosing.# Supports 7 irrigation zones with real-time flow monitoring,# manifold pressure/temperature/TDS measurement, and fertilizer# inflow/outflow tracking.## Hardware:# - Board: ESP32# - Sensors: Flow pulse counters (8 total)# - Sensors: ADS1115 ADC for pressure, temperature, TDS# - Control: PCF8574 I2C expander for 8 zone relays + 2 valves# ────────────────────────────────────────────────────────────
substitutions: device_name: "Pump Box" device_id: "pump-box" manifold_sensor_power: GPIO4 i2c_sda: GPIO21 i2c_scl: GPIO22 light_pin: GPIO18 zone_1_name: Garden zone_2_name: Blueberries zone_3_name: Trees zone_4_name: Blackberries zone_5_name: Misters zone_6_name: Wood Hose zone_7_name: Front manifold_pulse: GPIO32 fertilizer_inflow_pulse: GPIO33 fertilizer_outflow_pulse: GPIO25 zone_1_pulse: GPIO16 zone_2_pulse: GPIO17 zone_3_pulse: GPIO27 zone_4_pulse: GPIO23 zone_5_pulse: GPIO14 zone_6_pulse: GPIO13 zone_7_pulse: GPIO26
esphome: name: ${device_id} friendly_name: "${device_name}"
esp32: board: esp32dev framework: type: arduino
logger:
api: encryption: key: !secret api_key
ota: platform: esphome password: !secret ota_password
wifi: ssid: !secret wifi_ssid password: !secret wifi_password ap: ssid: "Bruh-Pump Fallback Hotspot" password: !secret ap_password
captive_portal:
i2c: sda: ${i2c_sda} scl: ${i2c_scl} scan: true id: bus_a
ads1115: - address: 0x48 i2c_id: bus_a id: ads1115_1
pcf8574: - id: 'pcf8574_hub_1' i2c_id: bus_a address: 0x27 pcf8575: true
sensor: - platform: pulse_counter name: "Manifold Flow Rate" id: manifold_flow_rate pin: number: ${manifold_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 483); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: "Manifold Total" id: manifold_total filters: - lambda: return (x / 483); unit_of_measurement: "L" device_class: water state_class: total_increasing
- platform: pulse_counter name: "EZ-Flo Inflow Rate" id: ez_flo_inflow_rate pin: number: ${fertilizer_inflow_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 898); unit_of_measurement: "L/min" state_class: measurement device_class: volume_flow_rate total: name: 'EZ-Flo Inflow Total' id: ez_flo_inflow_total filters: - lambda: return (x / 898); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: pulse_counter name: "EZ-Flo Outflow Rate" id: ez_flo_outflow_rate pin: number: ${fertilizer_outflow_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 898); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: 'EZ-Flo Outflow Total' id: ez_flow_outflow_total filters: - lambda: return (x / 898); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: pulse_counter name: "Z1 Flow" id: zone_1_flow pin: number: ${zone_1_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 660); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: "Z1 Total" id: zone_1_total filters: - lambda: return (x / 660); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: pulse_counter name: "Z2 Flow" id: zone_2_flow pin: number: ${zone_2_pulse} mode: input: true pullup: true update_interval: 20s filters: - lambda: return (x / 660); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: "Z2 Total" id: zone_2_total filters: - lambda: return (x / 660); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: pulse_counter name: "Z3 Flow" id: zone_3_flow pin: number: ${zone_3_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 660); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: "Z3 Total" id: zone_3_total filters: - lambda: return (x / 660); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: pulse_counter name: "Z4 Flow" id: zone_4_flow pin: number: ${zone_4_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 660); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: "Z4 Total" id: zone_4_total filters: - lambda: return (x / 660); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: pulse_counter name: "Z5 Flow" id: zone_5_flow pin: number: ${zone_6_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 660); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: "Z5 Total" id: zone_5_total filters: - lambda: return (x / 660); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: pulse_counter name: "Z6 Flow" id: zone_6_flow pin: number: ${zone_5_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 660); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: "Z6 Total" id: zone_6_total filters: - lambda: return (x / 660); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: pulse_counter name: "Z7 Flow" id: zone_7_flow pin: number: ${zone_7_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 660); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: "Z7 Total" id: zone_7_total filters: - lambda: return (x / 660); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: ads1115 multiplexer: 'A0_GND' ads1115_id: ads1115_1 name: "Manifold Pressure" update_interval: 5s unit_of_measurement: "psi" device_class: pressure gain: 6.144 filters: - calibrate_linear: - 0.0 -> 0.5 - 5 -> 80.0
- platform: ads1115 multiplexer: 'A2_GND' gain: 6.144 name: "Raw Manifold Temperature Voltage" id: manifold_raw_temperature_voltage update_interval: 10s unit_of_measurement: "V" accuracy_decimals: 3 internal: false
- platform: resistance id: manifold_temp_resistance sensor: manifold_raw_temperature_voltage configuration: DOWNSTREAM resistor: 10kOhm name: "Manifold Raw Resistance" internal: false
- platform: ntc sensor: manifold_temp_resistance calibration: b_constant: 3950 reference_temperature: 25°C reference_resistance: 10kOhm name: "Manifold Temperature" id: manifold_water_temperature
- platform: ads1115 multiplexer: 'A1_GND' gain: 6.144 update_interval: 10s name: "Manifold Raw TDS Voltage" ads1115_id: ads1115_1 id: manifold_raw_tds_voltage unit_of_measurement: "V" accuracy_decimals: 3 internal: false
- platform: template name: "Manifold Compensated TDS Voltage" update_interval: 10s id: manifold_compensated_tds_voltage unit_of_measurement: 'V' accuracy_decimals: 3 lambda: 'return ((id(manifold_raw_tds_voltage).state) / (1 + (0.02 * (id(manifold_water_temperature).state - 25.0))));' internal: false
- platform: template name: "Manifold Uncalibrated TDS" update_interval: 10s id: manifold_tds_uncalibrated icon: "hass:water-opacity" unit_of_measurement: 'PPM' accuracy_decimals: 0 lambda: 'return (133.42 * (id(manifold_compensated_tds_voltage).state) * 3 - 255.86 * (id(manifold_compensated_tds_voltage).state) * 2 + 857.39 * id(manifold_compensated_tds_voltage).state) * 0.5;'
- platform: template name: "Manifold Calibrated TDS" update_interval: 10s id: manifold_tds_calibrated icon: "hass:water-opacity" unit_of_measurement: 'PPM' accuracy_decimals: 0 lambda: return id(manifold_tds_uncalibrated).state; filters: - calibrate_linear: - 22 -> 22 - 1040 -> 700 - sliding_window_moving_average: window_size: 5 send_every: 1
switch: - platform: gpio name: "Zone 1" pin: pcf8574: pcf8574_hub_1 number: 0 mode: output: true inverted: true - platform: gpio name: "Zone 2" pin: pcf8574: pcf8574_hub_1 number: 1 mode: output: true inverted: true - platform: gpio name: "Zone 3" pin: pcf8574: pcf8574_hub_1 number: 2 mode: output: true inverted: true - platform: gpio name: "Zone 4" pin: pcf8574: pcf8574_hub_1 number: 3 mode: output: true inverted: true - platform: gpio name: "Zone 5" pin: pcf8574: pcf8574_hub_1 number: 4 mode: output: true inverted: true - platform: gpio name: "Zone 6" pin: pcf8574: pcf8574_hub_1 number: 5 mode: output: true inverted: true - platform: gpio name: "Zone 7" pin: pcf8574: pcf8574_hub_1 number: 6 mode: output: true inverted: true - platform: gpio name: "Pump Water Valve" pin: pcf8574: pcf8574_hub_1 number: 14 mode: output: true inverted: true - platform: gpio name: "Fertilizer Output Valve" pin: pcf8574: pcf8574_hub_1 number: 15 mode: output: true inverted: true
output: - platform: ledc pin: ${light_pin} id: light_pin frequency: "19531Hz"
light: - platform: monochromatic output: light_pin name: "Pump Box" id: cob_panel default_transition_length: 0.5s bruh-pump-s3.yaml
# BRUH Irrigation Pump Controller S3# ────────────────────────────────────────────────────────────# ESP32-S3 variant of the pump controller with similar# functionality to bruh-pump.yaml. Uses ADS1115 and PCF8574# I2C expanders for expanded I/O capacity.## Hardware:# - Board: ESP32-S3# ────────────────────────────────────────────────────────────
substitutions: device_name: "Pump Box S3" device_id: "pump-box-s3" manifold_sensor_power: GPIO38 i2c_sda: GPIO1 i2c_scl: GPIO2 light_pin: GPIO48 zone_1_name: Garden zone_2_name: Blueberries zone_3_name: Trees zone_4_name: Blackberries zone_5_name: Misters zone_6_name: Wood Hose zone_7_name: Front fertilizer_inflow_pulse: GPIO4 fertilizer_outflow_pulse: GPIO5 zone_1_pulse: GPIO6 zone_2_pulse: GPIO7 zone_3_pulse: GPIO15 zone_4_pulse: GPIO16 zone_5_pulse: GPIO17 zone_6_pulse: GPIO18 zone_7_pulse: GPIO9 manifold_pulse: GPIO10
esphome: name: ${device_id} friendly_name: "${device_name}"
esp32: board: esp32-s3-devkitc-1 framework: type: arduino
logger:
api: encryption: key: !secret api_key
ota: - platform: esphome password: !secret ota_password
wifi: ssid: !secret wifi_ssid password: !secret wifi_password ap: ssid: "Bruh-Pump-S3 Fallback Hotspot" password: !secret ap_password
captive_portal:
i2c: sda: ${i2c_sda} scl: ${i2c_scl} scan: true id: bus_a
ads1115: - address: 0x48 i2c_id: bus_a id: ads1115_1
pcf8574: - id: 'pcf8574_hub_1' i2c_id: bus_a address: 0x27 pcf8575: true
sensor: - platform: pulse_counter name: "Manifold Flow Rate" id: manifold_flow_rate pin: number: ${manifold_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 483); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: "Manifold Total" id: manifold_total filters: - lambda: return (x / 483); unit_of_measurement: "L" device_class: water state_class: total_increasing
- platform: pulse_counter name: "EZ-Flo Inflow Rate" id: ez_flo_inflow_rate pin: number: ${fertilizer_inflow_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 898); unit_of_measurement: "L/min" state_class: measurement device_class: volume_flow_rate total: name: 'EZ-Flo Inflow Total' id: ez_flo_inflow_total filters: - lambda: return (x / 898); unit_of_measurement: "L" device_class: volume state_class: total_increasing
- platform: pulse_counter name: "EZ-Flo Outflow Rate" id: ez_flo_outflow_rate pin: number: ${fertilizer_outflow_pulse} mode: input: true pullup: true update_interval: 10s filters: - lambda: return (x / 898); unit_of_measurement: "L/min" device_class: volume_flow_rate state_class: measurement total: name: 'EZ-Flo Outflow Total' id: ez_flow_outflow_total filters: - lambda: return (x / 898); unit_of_measurement: "L" device_class: volume state_class: total_increasing
switch: - platform: gpio name: "Zone 1" pin: pcf8574: pcf8574_hub_1 number: 0 mode: output: true inverted: true - platform: gpio name: "Zone 2" pin: pcf8574: pcf8574_hub_1 number: 1 mode: output: true inverted: true - platform: gpio name: "Zone 3" pin: pcf8574: pcf8574_hub_1 number: 2 mode: output: true inverted: true - platform: gpio name: "Zone 4" pin: pcf8574: pcf8574_hub_1 number: 3 mode: output: true inverted: true - platform: gpio name: "Zone 5" pin: pcf8574: pcf8574_hub_1 number: 4 mode: output: true inverted: true - platform: gpio name: "Zone 6" pin: pcf8574: pcf8574_hub_1 number: 5 mode: output: true inverted: true - platform: gpio name: "Zone 7" pin: pcf8574: pcf8574_hub_1 number: 6 mode: output: true inverted: true - platform: gpio name: "Pump Water Valve" pin: pcf8574: pcf8574_hub_1 number: 14 mode: output: true inverted: true - platform: gpio name: "Fertilizer Output Valve" pin: pcf8574: pcf8574_hub_1 number: 15 mode: output: true inverted: true
output: - platform: ledc pin: ${light_pin} id: light_pin frequency: "19531Hz"
light: - platform: monochromatic output: light_pin name: "Pump Box" id: cob_panel default_transition_length: 0.5sCAD source
The design itself, if you want to change it rather than print it. A STEP file is exact geometry and opens in almost anything; a Fusion 360 archive keeps the modelling history, so you can go back and edit the sketch that made the part.
- air_injector_drill_guide_v3.f3d Fusion 360 archive — the editable design, with its history
- air_injector_drill_guide_v3.step STEP — opens in Fusion 360, FreeCAD, Onshape, SolidWorks
- backyard_v2.f3d Fusion 360 archive — the editable design, with its history
- backyard_v2.step STEP — opens in Fusion 360, FreeCAD, Onshape, SolidWorks
- garden_sketch_v6.f3d Fusion 360 archive — the editable design, with its history
- garden_sketch_v6.step STEP — opens in Fusion 360, FreeCAD, Onshape, SolidWorks
- timer_indicator_disk_v2.f3d Fusion 360 archive — the editable design, with its history
- timer_indicator_disk_v2.step STEP — opens in Fusion 360, FreeCAD, Onshape, SolidWorks