esphome: name: cold-water-to-house friendly_name: Cold Water to House esp32: board: esp32dev framework: type: esp-idf # Enable logging logger: # Enable Home Assistant API api: encryption: key: "xxxx" ota: - platform: esphome password: "xxxx" wifi: networks: - ssid: xxxx password: xxxx - ssid: xxxx password: xxxx min_auth_mode: WPA2 # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "Cold-Water-To-House" password: "xxxx" captive_portal: # esp32 pin configuration entry one_wire: - platform: gpio pin: GPIO02 globals: - id: water_impulses type: int restore_value: true # if set to false, the value will be 0 at reboot initial_value: '1443' - id: led_on type: bool restore_value: no initial_value: "false" binary_sensor: - platform: status name: "ESP32 Status" # Moisture detection - platform: template name: "Water Detected" device_class: moisture lambda: |- return id(water_raw).state > 0.8; filters: - delayed_on: 500ms - delayed_off: 5s - platform: gpio id: water_impulse internal: true pin: number: GPIO13 # Shared input with GPIO14 mode: INPUT_PULLUP inverted: true filters: - delayed_off: 0.10 s on_press: then: - lambda: id(water_impulses) += 1; # Start of Water Control inputs - platform: gpio pin: number: 23 # Valve contact - valve open mode: INPUT_PULLUP inverted: true # true = pressed = "on", released = "off" name: "Valve Indicating Open" id: valve_open on_state: then: - if: condition: binary_sensor.is_on: valve_open then: - switch.turn_on: valve_ind_open else: - switch.turn_off: valve_ind_open - platform: gpio pin: number: 22 # Valve contact - valve closed mode: INPUT_PULLUP inverted: true # true = pressed = "on", released = "off" name: "Valve Indicating Closed" id: valve_closed on_state: then: - if: condition: binary_sensor.is_on: valve_closed then: - switch.turn_on: valve_ind_closed else: - switch.turn_off: valve_ind_closed # Input pin 12v power ok - platform: gpio pin: number: GPIO21 mode: INPUT_PULLUP id: input_pin name: "Input Pin" - platform: gpio pin: number: 19 # Manual override hidden from home assistant mode: INPUT_PULLUP inverted: true # true = pressed = "on", released = "off" name: "Manual Override" internal: True id: manual_override on_state: then: - if: condition: binary_sensor.is_on: manual_override then: - switch.turn_on: manual_override_output else: - switch.turn_off: manual_override_output - platform: gpio pin: number: 18 # Close manually hidden from home assistant mode: INPUT_PULLUP inverted: true # true = pressed = "on", released = "off" name: "Manual Close" internal: True id: manual_close on_state: then: - if: condition: binary_sensor.is_on: manual_close then: - switch.turn_on: open_relay_output else: - switch.turn_off: open_relay_output switch: - platform: gpio pin: 32 # Valve open Input hidden from home assistant dashboard id: valve_ind_open name: "Valve Open" internal: True - platform: gpio pin: 33 # Valve closed Input hidden from home assistant dashboard id: valve_ind_closed name: "Valve Closed" internal: True - platform: gpio pin: 26 # Manual override id: manual_override_output name: "Manual Override" internal: False - platform: gpio pin: 27 # Relay open manually id: open_relay_output name: "Close Valve" internal: False # LED pin output: - platform: gpio pin: GPIO25 id: led_out # GPIO17 output drive pin for mositure detection - platform: gpio pin: GPIO17 id: probe_drive light: - platform: binary id: status_led output: led_out internal: true # Flash interval interval: - interval: 500ms then: - if: condition: binary_sensor.is_on: input_pin then: # GPIO21 HIGH → LED steady ON - output.turn_on: led_out - globals.set: id: led_on value: "true" else: - if: condition: wifi.connected then: # Flashing logic - if: condition: lambda: 'return id(led_on);' then: - output.turn_off: led_out - globals.set: id: led_on value: "false" else: - output.turn_on: led_out - globals.set: id: led_on value: "true" else: # Neither → LED steady ON - output.turn_on: led_out - globals.set: id: led_on value: "true" # Timer: run every 2 minutes for moisture detection - interval: 10s then: - script.execute: sample_water sensor: - platform: pulse_meter name: "Cold Mains Water" id: cold_mains_water_meter unit_of_measurement: 'm³/min' internal_filter: 0.10 s timeout: 2 min state_class: measurement device_class: water icon: mdi:meter-water #accuracy_decimals: 2 pin: number: GPIO14 # Pulse meter input, shared with GPIO13 mode: INPUT_PULLUP inverted: true filters: # 1 imp / 0.1 m³ = 10 imp / m³ (in my case); water_imp_value = 10; - lambda: return x * (1.0 / 100); - platform: template name: "Cold Mains Consumption Total" id: cold_mains_consumption_total unit_of_measurement: 'm³' icon: mdi:meter-water-outline state_class: total_increasing device_class: water accuracy_decimals: 2 lambda: return id(water_impulses) * (1.0 / 100); update_interval: 10 s - platform: dallas_temp address: 0x343c18e381021028 name: "External Meter Enclosure Temperature" - platform: wifi_signal name: "Meter Chamber WiFi Signal" update_interval: 15s filters: - sliding_window_moving_average: window_size: 15 send_every: 15 send_first_at: 15 icon: mdi:wifi # ADC input for moisture detection - platform: adc pin: GPIO34 id: water_raw name: "Water Level Raw" attenuation: 11db update_interval: never # Pulse + read script for mosture detection script: - id: sample_water then: - output.turn_on: probe_drive - delay: 10ms - component.update: water_raw - output.turn_off: probe_drive