Hi Ash,
My esphome config is a mess now. Yesterday just got my esp32-devkit-v1 burn (it was real hot on touching, suspected from shorted or overloaded onboard regulator after adding a physical button). Below is the full config, many which were copied from your code to test it. Please kindly give me some guide to improve it.
I have not yet doing the code in HA config.yaml so this is only the esphome config.
TIA.
esphome:
name: motor
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
i2c:
sda: GPIO21
scl: GPIO22
sun:
latitude: !secret latitude
longitude: !secret longitude
on_sunrise:
- then:
- binary_sensor.template.publish:
id: pot_sun_is_up
state: ON
on_sunset:
- then:
- binary_sensor.template.publish:
id: pot_sun_is_up
state: OFF
ota:
password: "eece41701fcccaad99cba87a8fbde705"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: ""
password: ""
font:
- file: "fonts/Arial.ttf"
id: arial
size: 12
captive_portal:
display:
- platform: ssd1306_i2c
model: "SSD1306 128x64"
# model: "SSD1306 128x32"
id: pot_display
rotation: 180
# reset_pin: D0
address: 0x3C
pages:
- id: pot_status
lambda: |-
it.printf(0, 00, id(arial), "System Status: %s", id(system_status).state ? "Good" : "Error");
it.printf(0, 12, id(arial), "WiFi: %s", id(wifi_connected).state ? "Connected" : "Disconnected");
it.printf(0, 24, id(arial), "API: %s", id(home_assistant_api_connected).state ? "Connected" : "Disconnected");
it.printf(0, 48, id(arial), "Motion: %s", id(motion_sensor).state ? "Detected" : "Not detected");
if (id(water_motor_running).state) {
it.printf(0, 36, id(arial), "Motor: Running %i%%", id(flow_rate_percent));
} else {
it.printf(0, 36, id(arial), "Motor: Stopped");
}
- id: watering
lambda: |-
it.printf(0, 00, id(arial), "Feeds for today: %i", id(calculated_water_per_day_variable));
it.printf(0, 12, id(arial), "Remain water: %i", id(water_left_today_variable));
it.printf(0, 24, id(arial), "Last water: %s", id(last_watering).state.c_str());
it.printf(0, 36, id(arial), "Amount: %.0fcm", id(tank_water_height).state);
it.printf(0, 48, id(arial), "Water in tank: %.0fcm", id(tank_water_height).state);
globals:
- id: last_feed_time_text
type: std::string
restore_value: no
- id: flow_rate # Rate to run feed motor. 0.2 equates to 1 rpm. From HA input_number.fish_feed_motor_feed_rate
type: float
restore_value: no
initial_value: '0.2'
- id: flow_rate_percent # feed_rate converted to percentage dor display
type: int
restore_value: no
initial_value: '20'
- id: water_left_today_variable # Used as counter for number of feeds made today. Set from calculated_feeds_per_day_variable
type: int # Decremented by dispense_food script completion
restore_value: no
initial_value: '0'
- id: calculated_water_per_day_variable # From HA sensor.calculated_feeds_per_day
type: int
restore_value: no
initial_value: '12'
- id: amount_per_dose # From HA sensor.feed_amount_per_dose
type: int
restore_value: no
initial_value: '20'
- id: post_feed_overrun_variable # From HA input_number.post_feed_overrun_HA
type: int
restore_value: no
initial_value: '5'
- id: pre_dose_height # What was the weight before feeding?
type: int
restore_value: no
initial_value: '0'
- id: post_dose_target_weight # What is the target weight after feeding finished?
type: int
restore_value: no
initial_value: '0'
- id: last_water_height_variable # What was the weight of the last feed?
type: int
restore_value: no
initial_value: '0'
- id: post_watering_tank_height_variable # Weight after last feed?
type: int
restore_value: no
initial_value: '0'
- id: disable_reset_time
type: int
restore_value: no
initial_value: '5'
time:
- platform: homeassistant
id: homeassistant_time
sensor:
#DHT11
- platform: dht
pin: 5
model: DHT22
temperature:
name: "Pot Temp"
humidity:
name: "Pot Humidity"
update_interval: 2s
# HC-SR04
- platform: ultrasonic
trigger_pin: 18
echo_pin: 19
name: "Pot water tank height"
id: tank_water_height
update_interval: 3s
filters:
# Replace the 0.42 by the height of your container. From the sensor to the bottom.
# I multiplied by 100 in order to get CM since the sensor works in meters
- lambda: return (0.12-x)*100;
unit_of_measurement: "cm"
on_value:
then:
- if: # Hopper weight is within limits
condition:
sensor.in_range:
id: tank_water_height
above: 2.0
below: 10.0
then:
- binary_sensor.template.publish:
id: tank_is_at_low_level
state: OFF
- binary_sensor.template.publish:
id: tank_is_full
state: OFF
- binary_sensor.template.publish:
id: tank_is_empty
state: OFF
- binary_sensor.template.publish:
id: tank_is_ok
state: ON
- if: # Hopper is bordering on empty
condition:
sensor.in_range:
id: tank_water_height
below: 2.0
then:
- binary_sensor.template.publish:
id: tank_is_empty
state: ON
- binary_sensor.template.publish:
id: tank_is_at_low_level
state: OFF
- binary_sensor.template.publish:
id: tank_is_full
state: OFF
- binary_sensor.template.publish:
id: tank_is_ok
state: OFF
- if: # Hopper is low level
condition:
sensor.in_range:
id: tank_water_height
above: 2.0
below: 5.0
then:
- binary_sensor.template.publish:
id: tank_is_empty
state: OFF
- binary_sensor.template.publish:
id: tank_is_at_low_level
state: ON
- binary_sensor.template.publish:
id: tank_is_full
state: OFF
- binary_sensor.template.publish:
id: tank_is_ok
state: OFF
on_value_range: # Hopper is high level
- above: 10.0
then:
- binary_sensor.template.publish:
id: tank_is_empty
state: OFF
- binary_sensor.template.publish:
id: tank_is_at_low_level
state: OFF
- binary_sensor.template.publish:
id: tank_is_full
state: ON
- binary_sensor.template.publish:
id: tank_is_ok
state: OFF
- platform: homeassistant
name: "Amount per dose"
entity_id: sensor.water_amount_per_dose #defined in homeassistant
id: water_amount_per_dose
on_value:
then:
- globals.set:
id: amount_per_dose
value: !lambda 'return x;'
- platform: homeassistant
name: "Calculated water per day"
entity_id: sensor.calculated_water_per_day #defined in homeassistant
id: feeds_per_day_from_ha
on_value:
then:
- globals.set:
id: calculated_water_per_day_variable
value: !lambda 'return x;'
#HA sensor taking data value from input_number,
# - platform: homeassistant
# name: "Water flow rate %"
# entity_id: sensor.waterflowrate
# id: waterflowrate
# unit_of_measurement: "%"
- platform: homeassistant # Set motor feed rate and intial value for motor
name: "Motor flow rate"
entity_id: input_number.pot_motor_flow_rate #defined in homeassistant
id: motor_flow_rate
on_value:
then:
- globals.set:
id: flow_rate
value: !lambda 'return x;'
- globals.set:
id: flow_rate_percent
value: !lambda 'return x * 100;'
- output.set_level:
id: pot_pump_pwm
level: !lambda 'return id(flow_rate);'
#Capacitive soil moisture sensor
#Dry 3.25 - taken from in the air, probably should do it directly in dry soil
#Wet 1.75 - taken from in a glass of water, probably should do it directly in saturated soil
- platform: adc
pin: GPIO33
id: moisture
filters:
- lambda: |-
if (x > 3.11) { // if over 3.25 volts, we are dry
return 0;
} else if (x < 1.68) { // if under 1.75 volts, we are fully saturated
return 100;
} else {
return (3.11-x) / (3.25-1.68) * 100.0; // use a linear fit for any values in between
}
name: "Pot Moisture"
unit_of_measurement: "% Moist"
icon: "mdi:water-percent"
update_interval: 2s
attenuation: 11db
on_value_range:
- below: 65.0
then:
- output.turn_on: pot_pump_pwm
- output.ledc.set_frequency:
id: pot_pump_pwm
frequency: "3Hz"
- output.set_level:
id: pot_pump_pwm
level: !lambda 'return (id(motor_flow_rate).state/100);' #return sensor value devided by 100, to make in percentage
- above: 80.0
then:
- output.turn_off: pot_pump_pwm
- platform: template # Feeds left to HA
name: "water left today"
id: water_left_today
text_sensor: # Calculated sunrise/sunset times for feeding window
- platform: sun
name: Sun Next Sunrise
type: sunrise
- platform: sun
name: Sun Next Sunset
type: sunset
- platform: template
name: "Last watering"
id: last_watering
# - platform: template
# name: "On board time"
# id: on_board_time_text
binary_sensor:
- platform: status # Availabilty for HA
name: "Pot status"
id: system_status
- platform: gpio # Motion sensor
pin: 25
name: "Pot PIR Sensor"
id: motion_sensor
device_class: motion
on_press:
then:
- light.turn_on:
id: light_status
brightness: 100%
red: 100%
green: 0%
blue: 0%
on_release:
then:
- light.turn_off:
id: light_status
- platform: gpio # Physical manual watering switch
pin:
number: 23
mode: INPUT_PULLUP
inverted: True
filters:
- delayed_on: 10ms
name: Manual watering
id: manual_plant_watering
device_class: running
on_press:
then:
- script.execute: dispense_food
- binary_sensor.template.publish:
id: watering_is_disabled
state: OFF
# - output.turn_on: pot_pump_pwm
# - output.ledc.set_frequency:
# id: pot_pump_pwm
# frequency: "3Hz"
# - output.set_level:
# id: pot_pump_pwm
# level: !lambda 'return (id(waterflowrate).state/100);'
# on_release:
# then:
# - output.turn_off: pot_pump_pwm
- platform: gpio # Physical advance display page button
pin:
number: 39
# mode: INPUT_PULLUP
inverted: True
name: "Next page"
id: next_page
on_press:
then:
- display.page.show_next: pot_display
- platform: gpio # Physical feed disable switch
pin:
number: 35
# mode: INPUT_PULLUP
name: "Disable Fish Feed"
id: disable_watering
filters:
- invert:
on_press:
then:
- if:
condition:
binary_sensor.is_on: watering_is_disabled
then:
- binary_sensor.template.publish:
id: watering_is_disabled
state: OFF
- homeassistant.service:
service: input_boolean.turn_off
data:
entity_id: input_boolean.disable_fish_feeder
else:
- homeassistant.service:
service: input_boolean.turn_on
data:
entity_id: input_boolean.disable_fish_feeder
- binary_sensor.template.publish:
id: watering_is_disabled
state: ON
- platform: template # Sun is up to HA
name: "Pot sun is up"
id: pot_sun_is_up
- platform: template # Sun is up to HA
name: "Fish feeder sun is up"
id: fish_feeder_sun_is_up
- platform: template # Hopper is full alert to HA from HX711 definition
name: "Tank is full"
id: tank_is_full
- platform: template # Hopper is low alert to HA from HX711 definition
name: "Tank is at low level"
id: tank_is_at_low_level
- platform: template # Hopper is empty alert to HA from HX711 definition
name: "Tank is empty"
id: tank_is_empty
- platform: template # Hopper is OK alert to HA from HX711 definition
name: "Tank is OK"
id: tank_is_ok
- platform: template # Hopper is blocked alert to HA from HX711 definition
name: "Discharge is blocked"
id: discharge_is_blocked
- platform: template # Hopper is over feeding alert to HA from HX711 definition
name: "Pot is over watering"
id: pot_is_over_watering
- platform: template # Hopper is over feeding alert to HA from HX711 definition
name: "Water motor running"
id: water_motor_running
- platform: template
name: "Home Assistant connected"
id: home_assistant_api_connected
- platform: template
name: "WiFi Connected"
id: wifi_connected
- platform: template
name: "Watering is disabled" # Feeding is disabled
id: watering_is_disabled
on_press:
then:
- script.execute: stop_motor
# - delay: !lambda 'return id(water_post_dispense_time_variable) * 1000;' # Continue to run water for post dispense flush period
# - switch.turn_off: feeder_water_valve_relay
- homeassistant.service:
service: input_boolean.turn_on
data:
entity_id: input_boolean.disable_fish_feeder
# - delay: !lambda 'return id(disable_reset_time) * 1000 * 60;' # Rest 'disabled' after x minutes
- binary_sensor.template.publish:
id: watering_is_disabled
state: OFF
on_release:
then:
- homeassistant.service:
service: input_boolean.turn_off
data:
entity_id: input_boolean.disable_fish_feeder
light: #led light
- platform: fastled_clockless
chipset: WS2811
id: light_status
pin: GPIO3
num_leds: 1
rgb_order: grb
name: "Pot LED"
output: #pump motor PWM pin output to IRLZ44N Gate pin
- platform: ledc
pin: 32
frequency: "3Hz"
id: pot_pump_pwm
- platform: gpio
pin: 23
id: enable_motor
fan:
- platform: speed
output: pot_pump_pwm
name: "Pot Pump PWM"
script:
- id: run_motor
then:
# - output.set_level:
# id: fish_feed_motor_pwm
# level: !lambda 'return id(feed_rate);'
- output.turn_on: enable_motor
- binary_sensor.template.publish:
id: water_motor_running
state: ON
- id: stop_motor
then:
- output.turn_off: enable_motor
- if: # When motor is stopped, check if hopper weight has reduced, if not, alert to HA
condition:
lambda: 'return id(tank_water_height).state > id(post_dose_target_weight);'
then:
- binary_sensor.template.publish:
id: discharge_is_blocked
state: ON
- if: # When motor is stopped, check if hopper weight is less than post
condition: # feed calculated weight (+ overrun allowance), if not, alert to HA
lambda: 'return id(tank_water_height).state < (id(post_dose_target_weight) + id(post_feed_overrun_variable));'
then:
- binary_sensor.template.publish:
id: pot_is_over_watering
state: ON
- binary_sensor.template.publish:
id: water_motor_running
state: OFF
- binary_sensor.template.publish:
id: manual_plant_watering
state: OFF
- text_sensor.template.publish: # Publish feed time to HA when motor stops # "%Y-%m-%d %H:%M"
id: last_watering
state: !lambda |-
char str[17];
time_t currTime = id(homeassistant_time).now().timestamp;
strftime(str, sizeof(str), "%d-%m %H:%M", localtime(&currTime));
return { str };
- id: dispense_food
then:
- binary_sensor.template.publish: # Reset blocked alert
id: discharge_is_blocked
state: OFF
- binary_sensor.template.publish: # Reset over feeding alert
id: pot_is_over_watering
state: OFF
# - globals.set: # Store hopper weight before feed
# id: pre_dose_weight
# value: !lambda 'return id(fish_food_hopper_weight).state;'
# - lambda: 'id(pre_dose_hopper_weight).publish_state(id(pre_dose_weight));' # Publish weight before feeding to HA
# - globals.set: # Store calculated hopper weight after feed
# id: post_dose_target_weight
# value: !lambda 'return id(pre_dose_weight) - id(amount_per_dose);'
# # - switch.turn_on: feeder_water_valve_relay # Open water valve for time period before food is dispensed
# - delay: !lambda 'return id(water_pre_dispense_time_variable) * 1000;'
- script.execute: run_motor # Run feed motor until hopper weight has dropped to calculated post feed weight
# - wait_until:
# condition:
# # or:
# - lambda: 'return id(fish_food_hopper_weight).state <= id(post_dose_target_weight);' # Target weight is dispensed
# # - lambda: 'return id(feed_motor).current_position >= id(feed_motor).target_position;' # Nothing is dispensed & limit of stepper reached
# - delay: !lambda 'return id(water_pre_dispense_time_variable) * 1000;' #temporary for testing
- script.execute: stop_motor # Turn off motor
# - lambda: 'id(post_dose_hopper_weight).publish_state(id(fish_food_hopper_weight).state);' # Publish weight after feeding to HA
# - lambda: 'id(weight_of_last_feed).publish_state(id(pre_dose_weight) - id(fish_food_hopper_weight).state);' # Publish weight of last feed to HA
- globals.set: # Store last feed weight
id: last_water_height_variable
value: !lambda 'return id(pre_dose_height) - id(tank_water_height).state;'
- globals.set: # Store last feed weight
id: post_watering_tank_height_variable
value: !lambda 'return id(tank_water_height).state;'
- lambda: 'id(water_left_today).publish_state(id(water_left_today_variable));' # Publish feeds left today
# - delay: !lambda 'return id(water_post_dispense_time_variable) * 1000;' # Continue to run water for post dispense flush period
# - switch.turn_off: feeder_water_valve_relay
# - homeassistant.service:
# service: input_boolean.turn_off
# data:
# entity_id: input_boolean.manually_feed_fish
- globals.set: # Decrement feeds today
id: water_left_today_variable
value: !lambda 'return id(water_left_today_variable) - 1;'
interval:
- interval: 10s
then:
- if:
condition:
wifi.connected:
then:
- binary_sensor.template.publish:
id: wifi_connected
state: ON
else:
- binary_sensor.template.publish:
id: wifi_connected
state: OFF
- if:
condition:
api.connected:
then:
- binary_sensor.template.publish:
id: home_assistant_api_connected
state: ON
else:
- binary_sensor.template.publish:
id: home_assistant_api_connected
state: OFF