I converted a PETKIT Fresh Element Mini dry food dispenser to run locally with ESPHome, removing the need for a cloud connection.
I was inspired by this post on the home assistant forums DIY PetKit feeder local integration to Home Assistant via ESPHome.
The project started with some open heart surgery on the feeder while the bosses watched closely.
I piggybacked onto the feeder's test points with an ESP32-S3 Supermini. This gives you access to the cap, food level and motor state, plus a feed action that runs the motor for a fixed amount of time. In my setup, 2000ms is about 4g and 4000ms is about 8g.
ESPHome YAML
substitutions:
name: feeder-1 # Do not use underscores, which are not fully compatible with mDNS
friendly_name: Dry Feeder
esp32:
board: esp32-s3-devkitc-1
framework:
type: esp-idf
esphome:
name: ${name}
logger:
level: INFO
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
power_save_mode: none
fast_connect: true
api:
actions:
- action: feed_amount
variables:
amount_g: int
then:
- script.execute:
id: petkit_feed
amount_g: !lambda "return amount_g;"
ota:
- platform: esphome
web_server:
port: 80
binary_sensor:
- platform: gpio
name: "PetKit Food level state"
device_class: problem
pin:
number: GPIO12
inverted: true
filters:
- delayed_off: 120000ms
- platform: gpio
name: "PetKit Cap state"
pin:
number: GPIO11
inverted: true
filters:
- delayed_on_off: 100ms
- delayed_off: 2000ms
- platform: gpio
name: "PetKit Motor state"
device_class: moving
pin:
number: GPIO10
inverted: true
filters:
- delayed_on_off: 100ms
- delayed_off: 2000ms
number:
- platform: template
name: "PetKit Feed Amount"
id: petkit_feed_amount
icon: "mdi:scale"
unit_of_measurement: "g"
min_value: 4
max_value: 100
step: 4
optimistic: true
restore_value: true
initial_value: 8
script:
- id: petkit_feed
mode: single
parameters:
amount_g: float
then:
- switch.turn_on: relay
# Calibration:
# 2000ms ~= 4g
# 4000ms ~= 8g
- delay: !lambda |-
return (uint32_t) (amount_g * 500);
- switch.turn_off: relay
button:
- platform: template
name: "PetKit Feed"
icon: "mdi:shaker"
on_press:
- script.execute:
id: petkit_feed
amount_g: !lambda "return id(petkit_feed_amount).state;"
switch:
- platform: gpio
pin:
number: GPIO13
# allow_other_uses: true
inverted: true
id: relay
internal: true
Original Mastodon posts: open heart surgery and ESPHome demo.