Skip to content

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

The manifold

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

Out in the yard

Getting signal and power out there

Filament

  • PETG for anything that lives outdoors, or PLA+ for the drill guide if it stays in the shop.

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.

FunctionESP32 pin
I2C SDAGPIO21
I2C SCLGPIO22
Manifold flow pulseGPIO32
EZ-Flo inflow pulseGPIO33
EZ-Flo outflow pulseGPIO25
Zone 1 flow pulseGPIO16
Zone 2 flow pulseGPIO17
Zone 3 flow pulseGPIO27
Zone 4 flow pulseGPIO23
Zone 5 flow pulse (zone_5_pulse)GPIO14
Zone 6 flow pulse (zone_6_pulse)GPIO13
Zone 7 flow pulseGPIO26
Box light PWMGPIO18

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:

OutputPCF8575 pin
Zone 1–70, 1, 2, 3, 4, 5, 6
Pump water valve14
Fertiliser output valve15

And on the ADC:

ADS1115 channelReads
A0Manifold pressure transducer
A1TDS probe
A2Thermistor 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

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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.

  7. Flash and check the I2C scan in the ESPHome log before you close the door. scan: true is 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.yamlwifi_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.0

That 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.

SettingDrill guideIndicator disk
Layer height0.2 mm0.2 mm
Walls4+n/a — it is two layers of solid
Infill40%100%
SupportsNoneNone
MaterialPETG, or PLA+ if it lives indoorsPETG
OrientationFlange on the bed, as exportedFlat, 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

Loading 3D model…
Drag to rotate · Scroll to zoom · Right-click to pan

Parts marked from CAD are tessellated from the STEP files below, for previewing only — approximate where the STEP is exact. Download the STEP for the real model.

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 487 lines
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

View on GitHub · Download raw

bruh-pump-s3.yaml 236 lines
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.5s

View on GitHub · Download raw

CAD 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.

Every file for this project on GitHub →