First ESP Home project - seeking code check/feedback

I’m building a “Pool Controller” on an ESP DEV kit as a 1st time real world ESP project. The device will include:

  • Tamper switch if the pool equipment panel door is opened
  • Local motion sensor
  • Pressure sensor (5v 0-30PSI connected to an ADC input) to monitor filter pressure
  • 4 on/off switches to control 4 relays (12v landscape lighting)

Future additions:

  • local weather-proof ambient temperature sensor(s)
  • piggy back the existing OmiPool flow sensor
  • local weather-proof button camera (motion triggered)

I’m super interested in how my code could be better, more efficient, more compact, etc. I realize I’m not optimizing the logger yet, and haven’t tried OTA yet. Internal ESP temp sensor was for fun and learning more than anything. I’d rather modularize things a bit and replace GPIO names with zone names. I’m working my way to getting this all to work with Konnected.io ESP YAMLS
It’s all working on the desktop, hasn’t crashed running over 24hours.

The environment is SmartThings, HomeAssistant, Konnected, ActionTiles, Hayward Omnipool (not that it matters), wifi or wired available.

substitutions:
  device_name: <REDACTED>

esphome:
  name: ${device_name}-35b730
  friendly_name: Soupasaurus

esp32:
  board: esp32doit-devkit-v1
  framework:
    type: arduino

# Enable Home Assistant API
api:
  encryption:
    key: "<REDACTED>"

# WiFi section, build connection
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "<REDACTED>"
    password: "<REDACTED>"

# additional components
captive_portal:
web_server:
  include_internal: true
logger:
ota:

text_sensor:
  # Formatted UPTIME output DD:HH:MM:SS (for fun)
  - platform: template
    name: Uptime DHMS
    update_interval: 60s
    lambda: |-
      auto s = millis() / 1000;
      return str_snprintf("%02d:%02d:%02d:%02d", 11, s / 86400, s / 3600 % 24, s / 60 % 60, s % 60);
    icon: mdi:clock-start

  - platform: wifi_info
    ip_address:
      name: IP Address
      icon: mdi:ip  
    ssid:
      name: SSID
      icon: mdi:wifi    
    mac_address:
      name: MAC Address
      icon: mdi:ip  

# BINARY SENSORS
binary_sensor:
  - platform: gpio
    id: zone_1
    name: Tamper
    device_class: tamper
    icon: mdi:alert-box-outline
    pin:
      number: GPIO4
      mode: INPUT_PULLUP
      inverted: True

  - platform: gpio
    id: zone_2
    name: Motion
    device_class: motion
    pin:
      number: GPIO2
      mode: INPUT_PULLUP
      inverted: True
    icon: mdi:motion-sensor

# REGULAR SENSORS
sensor:
  - platform: uptime
    name: Uptime
    icon: mdi:clock-start

  - platform: internal_temperature
    name: Internal temperature C
    id: int_temp_c
    unit_of_measurement: C
    icon: mdi:temperature-celcius

  - platform: template
    name: Internal temperature F
    id: int_temp_f
    lambda: return id(int_temp_c).state * 9/5 + 32;
    unit_of_measurement: F
    update_interval: 60s
    icon: mdi:temperature-fahrenheit

  - platform: adc
    name: "Filter Pressure (raw)"
    pin: GPIO35
    id: filter_pressure_sensor_volts
    update_interval: 10s
    # https://github.com/esphome/esphome/discussions/2990
    # Pressure sensor: 0 to 30 psi (more accurately, 0 to 2 bar) with an alleged 0.5-4.5V range
    # 0.5V = 0 psi / 0.00 bar / 0 kPa
    # 2.5V = 15 psi / 2.00 bar / 200 kPa
    # 4.5V = 30 psi / 4.00 bar / 400 kPa    
  
    # For the ESP, voltage is scaled by a 3.3k/1k voltage divider, so.... for a 30psi sensor
    # Min scale = 0.116V
    # Max scale = 1.047V
    # 0.116V = 0 psi / 0.00 bar / 0 kPa
    # 0.466V = 15 psi / 1.00 bar / 100 kPa
    # 1.047V = 30 psi / 2.00 bar / 200 kPa 

  - platform: copy
    source_id: filter_pressure_sensor_volts
    name: Filter Pressure (PSI)
    unit_of_measurement: 'psi'
    filters:
    - calibrate_linear:
      - 0.116 -> 0.0
      - 0.581 -> 15.0
      - 1.047 -> 30.0
    icon: mdi:gauge
        
  - platform: wifi_signal
    name: WiFi Signal RSSI
    id: wifi_signal_db
    accuracy_decimals: 1

  - platform: copy
    source_id: wifi_signal_db
    id: wifi_signal_pct
    name: WiFi Signal %
    accuracy_decimals: 1
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"

switch:
  # Used to control light relays
  - platform: gpio
    name: "Switch 1"
    pin: GPIO18
    icon: mdi:power

  - platform: gpio
    name: "Switch 2"
    pin: GPIO14
    icon: mdi:power

  - platform: gpio
    name: "Switch 3"
    pin: GPIO33
    icon: mdi:power

  - platform: gpio
    name: "Switch 4"
    pin: GPIO32
    icon: mdi:power
type or paste code here

You’ve only dedined some basic sensors wirh minimal configuration, there isnt anything to shorten or make efficient. No automations?

Packages :package:

Another way to modularize and reuse your configuration is to use packages. This feature allows you to put common pieces of configuration in separate files and keep only unique pieces of your config in the main yaml file. All definitions from packages will be merged with your main config in non-destructive way so you could always override some bits and pieces of package configuration. Substitutions in your main config will override substitutions with the same name in a package.

1 Like

All the automations will be in via HomeAssistant

Thats perfectly fine to do but, personally I think its better to put as much on the esp as you can. Any kind of HA issues, networking issues, whatever and your automations wont run. Automations on the esp will run in any of those events.

Absolutely! This is a strength of esphome which hardly can be found in any (commercially) available solution. :muscle:

For example I have a few detached lights which will fallback to trigger the locally attached relay as an fallback mechanism if HA isn’t available. This way my (locally attached lights) always trigger on a button press and the “comfort” function (trigger the whole light group in ha) is always executed when HA is available (native api connected). :bulb: :vs: :bulb::bulb::bulb:

Yep. Although my HA has been rock solid reliable for the most part, you dont have to be an engineer to see that putting automations on the esp has 1 less point of failure than if HA managed the automations.

A lot of people see it as black or white and theyre 100% HA or 95% Esphome. With a little creativity you dont have to choose 1 or the other. Lets say for example I have a light and want it to come on sunset/sunrise. Either Esphome or HA can handle that request but, people see it as a major decision and must choose!

Naw, with some simple template switches that enable or disable the automations when used in a condition like.
Condition 1. Is it sunset? True
Condition 2. Is sun automation enable switch On or Off
If On - then turn on light
else - it does nothing and that same enable switch is also your HA condition. An “enable off” in esphome then becomes “enable On” in HA and now you can simple switch which one is handling the automation by checking that condition or manually toggling it.

@Steve_Campbell , any update on your project? I am interested in monitoring my pool’s filter and 3x VSP pumps pressures… perhaps up to 4 gauges and report back to HA. Any suggestions on what hardware I need to pull that off?
Thanks!

I’ve got the prototype all done and working on the hardware bench. Let me get the real-world installation done this weekend hopefully.