VSON WP8621_V12 Fish Feeder

I’ve replaced the original chipset of my VSON WP8621_V12 Fish Feeder.
It’s a work in progress so bear with me and I hope some of you can help me out.
This is the top view of the device:


This is the bottom view of the device:

This is the inside view of the device:

This is the original fron of the PCB:

This is the back of the PCB:

I’ve desoldered the WIFI001_V20 chipset and replaced it with a ESP12E:

With my multimeter set to continuity test I was able to figure out the GPIO-usage.

ESP12-E Pins used
=================
GND
GPIO15 	Open/close detection
GPIO2 	N/C
GPIO0 	Button (rear)
GPIO4 	LED (blue)
GPIO5 	LED (red)
GPIO3 	RX
GPIO1 	TX

GPIO6	N/C
GPIO8	TC118S
GPIO10	TC118S
GPIO9	N/C
GPIO7	N/C
GPIO11	N/C

VCC		VCC
GPIO13	N/C
GPIO12	N/C
GPIO14	Food indicator
GPIO16	N/C
Enable	
ADC0	N/C
RST 	N/C

I’ve created the following ESPHome Configuration:

substitutions:
  name: "wp8621_fishfeeder"
  friendly_name: "WP8621_FishFeeder"

esphome:
  name: "${name}"
  friendly_name: "${friendly_name}"

esp8266:
  board: esp12e
  restore_from_flash: true

preferences:
  flash_write_interval: 0s

logger:

packages:
  api: !include ./includes/api.yaml
  ota: !include ./includes/ota.yaml
  wifi: !include ./includes/wifi.yaml
  time: !include ./includes/time.yaml
  web_server: !include ./includes/web_server.yaml
  text_sensor: !include ./includes/text_sensor.yaml
  sensor: !include ./includes/sensor.yaml
  switch: !include ./includes/switch.yaml
  binary_sensor: !include ./includes/binary_sensor.yaml

captive_portal:

output:
  - platform: gpio
    id: led_red_led
    pin: 
      number: GPIO5

light:
  - platform: binary
    name: "Red Light"
    output: led_red_led
    id: red_led

binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: true
    name: "Button"
    on_press:
      - light.turn_on:
          id: red_led
      - switch.turn_on:
          id: motor_switch
      - delay: 12.5s
      - switch.turn_off:
          id: motor_switch
      - light.turn_off:
          id: red_led

switch:
  - platform: gpio
    pin: 
      number: GPIO10
      inverted: false
    id: motor_switch
    name: "Motor Switch"

status_led:
  pin:
    number: GPIO4

I have to do some measurements on GPIO15, the open/close detection. The switch itself is a normally closed one (when the button isn’t pressed, there is a circuit made) connected to ground and this is causing an issue. GPIO15 is being used by the ESP during boot and with the open/close detection being active (button pressed because the feeding bay is retracted) the ESP12E will not boot. Is there any way to bypass this? The switch can act as a counter and it will also allow to stop the motor when the bay is finished with it’s routine.

Also there is food indicator that gave a warning when it was running out of food. This should be connected to GPIO14 and it looks like the same principle as a IR proximity sensor; an IR emmitor and an IR reciever (LED formfactor). I haven’t yet got that running.

Any help would be appreciated.

1 Like

This was an interesting project. I’ve made some adjustments:

  • The switch wired near J2 and connected to GPIO15 gives an issue with the ESP12E. The feeding bay in it’s closed state won’t allow the ESP to boot. When removed the same issue arises. I’ve resolved this issue replacing the switch with a 4,7Ohm resistor.
  • The desoldered switch has been connected to GPIO3 (RX) and ground with a pull-up (4,7Ohm resistor connected to VCC and GPIO3).

For the curious ones: I’ve bought my WB8621 at AliExpress (https://a.aliexpress.com/_EQqznvf)

The ESPHome configuration looks as follows:

substitutions:
  name: "wp8621_fishfeeder"
  friendly_name: "WP8621_FishFeeder"

esphome:
  name: "${name}"
  friendly_name: "${friendly_name}"
  on_boot:
    priority: -10
    then:
      - delay: 2s  # Give the sensor a moment to stabilize after boot
      - if:
          condition:
            binary_sensor.is_on: open_close_sensor
          then:
            - switch.turn_on: motor_switch

esp8266:
  board: esp12e
  restore_from_flash: true

preferences:
  flash_write_interval: 0s

logger:

packages:
  api: !include ./includes/api.yaml
  ota: !include ./includes/ota.yaml
  wifi: !include ./includes/wifi.yaml
  time: !include ./includes/time.yaml
  web_server: !include ./includes/web_server.yaml
  text_sensor: !include ./includes/text_sensor.yaml
  sensor: !include ./includes/sensor.yaml
  switch: !include ./includes/switch.yaml

captive_portal:

# Define the red LED as a binary output
output:
  - platform: gpio
    id: led_red_led
    pin: 
      number: GPIO5

# Control the red LED via the web interface
light:
  - platform: binary
    name: "Red Light"
    output: led_red_led
    id: red_led

# Define binary sensors (button, Open/Close sensor, and Food Level Indicator)
binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: true
    name: "Button"
    on_press:
      - switch.turn_on:
          id: motor_switch

  - platform: gpio
    pin: 
      number: GPIO3
      inverted: true
    name: "Open/Close Sensor"
    id: open_close_sensor
    on_state:
      - if:
          condition:
            binary_sensor.is_on: open_close_sensor
          then:
            - switch.turn_on: motor_switch
          else:
            - delay: 1s
            - switch.turn_off: motor_switch

  - platform: gpio
    pin: 
      number: GPIO14
      mode: INPUT_PULLUP
      inverted: false
    name: "Food Level Sensor"
    id: food_level_sensor
    device_class: "problem"  # Marks the sensor as an indicator of a problem (low food level)
    on_state:
      - if:
          condition:
            binary_sensor.is_on: food_level_sensor
          then:
            - logger.log: "Food level is low!"
          else:
            - logger.log: "Food level is sufficient."

# Define the switch for controlling the motor
switch:
  - platform: gpio
    pin: 
      number: GPIO10
      inverted: false  # Adjust this based on the TC118S control logic
    id: motor_switch
    name: "Motor Switch"
    on_turn_on:
      - light.turn_on: red_led
    on_turn_off:
      - light.turn_off: red_led

# Use the blue LED as a Wi-Fi status light
status_led:
  pin:
    number: GPIO4

This is (probably) the final configuration of the (modified) WB8621 FishFeeder:

substitutions:
  name: "wp8621_fishfeeder"
  friendly_name: "WP8621_FishFeeder"

esphome:
  name: "${name}"
  friendly_name: "${friendly_name}"
  on_boot:
    priority: -10
    then:
      - delay: 2s
      - if:
          condition:
            binary_sensor.is_on: open_close_sensor
          then:
            - switch.turn_on: motor_switch

esp8266:
  board: esp12e
  restore_from_flash: true

preferences:
  flash_write_interval: 0s

logger:
  
api:
  encryption:
    key: "{{API key}}"			# Replace with the actual API encryption key.

ota:
  - platform: esphome
    password: "{{password}}"	# Replace with the OTA update password.

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  ap:
    ssid: "WB8621 Fallback Hotspot"
    password: "{{password}}"	# Replace with a password for the fallback AP.

captive_portal:
  
time:
  - platform: homeassistant
    id: homeassistant_time		# Sync time with Home Assistant's time service.
  - platform: sntp
    id: sntp_time				# SNTP is a simpler form of NTP for syncing time with NTP servers.
    timezone: "{{timezone}}"	# Replace with your time zone (e.g., 'Europe/Amsterdam').
    servers:					# NTP servers for time synchronization.
     - "{{NTP server #1}}"		# Replace with actual NTP server.
     - "{{NTP server #2}}"
     - "{{NTP server #3}}"

sensor:
  - platform: wifi_signal
    name: "WiFi - Signal"
    update_interval: 60s
    entity_category: "diagnostic"

  - platform: uptime
    name: "System - Uptime"

output:
  - platform: gpio
    id: led_red_led
    pin: 
      number: GPIO5

light:
  - platform: binary
    name: "Red Light"
    output: led_red
    id: red_led

globals:
  - id: open_close_counter
    type: int
    restore_value: yes
    initial_value: '0'

sensor:
  - platform: template
    name: "Open/Close counter"
    id: open_close_counter_sensor
    unit_of_measurement: "times"
    accuracy_decimals: 0
    lambda: |-
      return id(open_close_counter);

binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: true
    name: "Button"
    filters:
      - delayed_on: 15ms 		# Debounce the button to avoid false triggers.
    on_press:
      - switch.turn_on:
          id: motor

  - platform: gpio
    pin: 
      number: GPIO3
      inverted: true
    name: "Open/Close sensor"
    id: open_close_sensor
    on_state:
      - if:
          condition:
            binary_sensor.is_on: open_close_sensor
          then:
            - switch.turn_on: motor
            - lambda: |-
                id(open_close_counter) += 1;
                id(open_close_counter_sensor).publish_state(id(open_close_counter));
          else:
            - delay: 1s                              # Delay for 1 second so the bay is in the feeder.
            - switch.turn_off: motor

  - platform: gpio
    pin: 
      number: GPIO14
      mode: INPUT_PULLUP
      inverted: false
    name: "Food level sensor"
    id: food_level_sensor
    device_class: "problem"            # Classify this as a problem entity in Home Assistant.
    on_state:
      - if:
          condition:
            binary_sensor.is_on: food_level_sensor
          then:
            - logger.log: "Food level is low!"
          else:
            - logger.log: "Food level is sufficient."

switch:
  - platform: gpio
    pin: 
      number: GPIO10
      inverted: false
    id: motor
    name: "Motor"
    restore_mode: ALWAYS_ON
    on_turn_on:
      - light.turn_on: red_led
    on_turn_off:
      - light.turn_off: red_led

  - platform: restart
    name: "System - Restart"

  - platform: safe_mode
    name: "System - Safe mode"

status_led:
  pin:
    number: GPIO4

I’ve created a simple automation that allows you to set the time of feeding and the amount of servings the fish need.
For this automation to work you’ll need to create two helpers within Home Assistant:

  • A Time helper (Date and/or Time → set the input to Time,
  • A Number helper (Number → set minimum to 1 and maximum to 10 or something)

You should replace input_datetime.{{fish_feedingtime}}, input_number.{{fish_meals}} and switch.{{motor fishfeeder}} with the entity ID’s applicable to your situation.

alias: Fish Feeding
description: ""
trigger:
  - platform: time
    at: input_datetime.{{fish_feedingtime}}
condition: []
action:
  - repeat:
      count: "{{ states('input_number.{{fish_meals}}') | int }}"
      sequence:
        - target:
            entity_id:
              - switch.{{motor fishfeeder}}
          action: switch.turn_on
          data: {}
        - wait_for_trigger:
            - platform: state
              entity_id: switch.{{motor fishfeeder}}
              to: "off"
mode: single

I’ve also created a Card Configuration for your dashboard based, you should have Mushroom Cards installed.
You should replace switch.{{motor fishfeeder}}, binary_sensor.{{food_level_sensor}}, input_number.{{fish_feedingtime}} and input_datetime.{{fish_meals}} with the entity ID’s applicable to your situation.

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - type: custom:mushroom-title-card
        title: WP8621 FishFeeder
        subtitle: ''
        title_tap_action:
          action: none
        subtitle_tap_action:
          action: none
  - type: horizontal-stack
    cards:
      - type: custom:mushroom-entity-card
        entity: switch.{{motor fishfeeder}}
        tap_action:
          action: toggle
        hold_action:
          action: none
        double_tap_action:
          action: none
        name: Feed fish manually
        primary_info: name
        secondary_info: none
        icon: mdi:archive
  - type: horizontal-stack
    cards:
      - type: custom:mushroom-template-card
        primary: Food level
        secondary: >-
          {% if states('binary_sensor.{{food_level_sensor}}') 
          == 'on' %} Food level is low!

          {% elif states('binary_sensor.{{food_level_sensor}}') 
          == 'off' %} Food level is sufficient.

          {% endif %}
        icon: >-
          {% if states('binary_sensor.{{food_level_sensor}}') 
          == 'on' %} mdi:alpha-l-circle-outline

          {% elif states('binary_sensor.{{food_level_sensor}}') 
          == 'off' %} mdi:alpha-f-circle

          {% endif %}
        entity: binary_sensor.{{food_level_sensor}}
  - type: horizontal-stack
    cards:
      - type: custom:mushroom-number-card
        entity: input_number.{{fish_feedingtime}}
        fill_container: false
        name: Number of servings
        display_mode: buttons
        secondary_info: none
      - type: custom:mushroom-entity-card
        entity: input_datetime.{{fish_meals}}
        name: Feeding time
3 Likes

Thanks for the detailed description modifying the VSON WP8621_V12 feeder. I have the blue tooth version and have captured most of the Bluetooth communication protocol. I was going to create an esp32 program to communicate with the feeder and send the information to home assistant via esp home or MQTT.

I like what you did much better and think I may try your modification. I have not used an ESP32E before, did you program it using USB to Serial adapter? Were there any issues connecting it to the board?

I’ve used a programmer to program the ESP32. I’ve used a solderingstation to desolder the existing print and solder the new print.

I’m very tempted to do this on mine, so can you update us with how it’s been working for you so far?

1 Like

The replacement was successful and it still functions.

substitutions:
  name: "fishfeeder-eetkamer"
  friendly_name: "FishFeeder_eetkamer"

esphome:
  name: "${name}"
  friendly_name: "${friendly_name}"
  on_boot:
    priority: -10
    then:
      - delay: 2s  # Give the sensor a moment to stabilize after boot
      - if:
          condition:
            binary_sensor.is_on: open_close_sensor
          then:
            - switch.turn_on: motor_switch

esp8266:
  board: esp12e
  restore_from_flash: true

preferences:
  flash_write_interval: 0s

logger:

api:
  encryption:
    key: !secret api_encryption_key

ota:
- platform: esphome
  password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  ap:
    password: !secret ap_password
  
time:
- platform: homeassistant
  id: homeassistant_time

- platform: sntp
  id: sntp_time
  timezone: # Your timezone
  servers:
   - pool.ntp.org
   - time.cloudflare.com

web_server:
  port: 80
  auth:
    username: !secret web_server_username
    password: !secret web_server_password
  version: 2
  local: true

text_sensor:
  - platform: wifi_info
    ip_address:
      name: WiFi - IP-address
    ssid:
      name: WiFi - Connected SSID
    bssid:
      name: WiFi - Connected BSSID
    mac_address:
      name: WiFi - MAC-address
    scan_results:
      name: WiFi - Latest Scan Results
    dns_address:
      name: WiFi - DNS Address

  - platform: version
    name: "System - ESPHome Version"

captive_portal:

# Define the red LED as a binary output
output:
  - platform: gpio
    id: led_red_led
    pin: 
      number: GPIO5

# Control the red LED via the web interface
light:
  - platform: binary
    name: "Red Light"
    output: led_red_led
    id: red_led

# Define global variable to count Open/Close Sensor triggers
globals:
  - id: open_close_counter
    type: int
    restore_value: yes
    initial_value: '0'

# Template sensor to display the Open/Close Counter value
sensor:
  - platform: template
    name: "Open/Close Counter"
    id: open_close_counter_sensor
    unit_of_measurement: "times"
    accuracy_decimals: 0
    lambda: |-
      return id(open_close_counter);
  - platform: wifi_signal
    name: "WiFi - Signal"
    update_interval: 60s
    entity_category: "diagnostic"

  - platform: uptime
    name: "System - Uptime"

# Define binary sensors (button, Open/Close sensor, and Food Level Indicator)
binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO0
      mode: INPUT_PULLUP
      inverted: true
    name: "Button"
    filters:
      - delayed_on: 15ms  # Debounce delay to avoid bouncing
    on_press:
      - switch.turn_on:
          id: motor_switch

  - platform: gpio
    pin: 
      number: GPIO3
      inverted: true
    name: "Open/Close Sensor"
    id: open_close_sensor
    on_state:
      - if:
          condition:
            binary_sensor.is_on: open_close_sensor
          then:
            - switch.turn_on: motor_switch
            - lambda: |-
                id(open_close_counter) += 1;  // Increment the counter
                id(open_close_counter_sensor).publish_state(id(open_close_counter));  // Update the sensor only when the value changes
          else:
            - delay: 1s
            - switch.turn_off: motor_switch


  - platform: gpio
    pin: 
      number: GPIO14
      mode: INPUT_PULLUP
      inverted: false
    name: "Food Level Sensor"
    id: food_level_sensor
    device_class: "problem"  # Marks the sensor as an indicator of a problem (low food level)
    on_state:
      - if:
          condition:
            binary_sensor.is_on: food_level_sensor
          then:
            - logger.log: "Food level is low!"
          else:
            - logger.log: "Food level is sufficient."

# Define the switch for controlling the motor using GPIO10 (acknowledge flash use warning)
switch:
  - platform: gpio
    pin: 
      number: GPIO10
      inverted: false  # Adjust this based on the TC118S control logic
    id: motor_switch
    name: "Motor Switch"
    restore_mode: ALWAYS_ON  # Force the state to always on during startup to avoid conflicts
    on_turn_on:
      - light.turn_on: red_led
    on_turn_off:
      - light.turn_off: red_led

  - platform: restart
    name: "System - Restart"

  - platform: safe_mode
    name: "System - Safe mode"

# Use the blue LED as a Wi-Fi status light
status_led:
  pin:
    number: GPIO4

Thank you for this. I’ll probably give it a try

I just wanted to confirm for anyone who would like to do this, that this works very well. Was an easy swap, adding 2 resistors and packing it back. Yaml works fantastically.

Thanks again

1 Like

I have also completed this mod, had a little issue getting the part off, but otherwise went well. The feed shows up in home assistant and the automation works great.
Thanks for the great mod

1 Like

Just want to say thanks! It’s working great!
I used a hacksaw blade to cut the old chip off… would not recommend. Haha but managed to get the new one on and it’s working perfectly. Can now leave for a few days without using those dissolving food things.

Hey, I have an odd problem… if home assistant is down for too long, the feeder dumps all of its food! Mine always dumps one portion of foot on first boot/power on - I’m thinking that’s the problem. But… not sure why it does this?

Any thoughts? Thanks!

Unintentional design?

GPIO 0 is not a safe pin to use, since it must be HIGH on boot.

The original design has it as a push button, which can be okay as long as you don’t push the button on boot.

The new design has it start the feeding cycle. Depending on timing this will likely cause it to dump a load of food on boot.

This might be acceptable behavior.

esphome gets nervous when HA doesn’t contact it it regularly, after some point it reboots, this is by design.

Combine the two designs and have unreliable connection to HA and you will likely get the behavior you are seeing.

You can change this behavior. Native API Component — ESPHome
reboot_timeout

Do I need to use 4.7Ohm or would 10Ohm work? Hope someone can help me out :wink: the smallest I have it’s 10 :frowning:

I think it’ll still work, you should just give it a try. For me it wasn’t an exact sience, but also more trial and error.

Thx for your work.
Because I’m not a goot to desolder, I only keep sensors and actuators. I replace the whole card with a ESP32 Wemos S2 mini.

I also add 5 feeding slots to ensure the feeding even if homeassistant crash:
On each slot you can set time and portion.

esphome:
  name: "fish-feeder"
  friendly_name: "Fish Feeder"
  on_boot:
    priority: -10
    then:
      - delay: 2s
      - if:
          condition:
            binary_sensor.is_on: open_close_sensor
          then:
            - switch.turn_on: motor_switch
      - logger.log:
          format: "Hello Fish Feeder"
      - logger.log:
          format: "Restoring feeding slots: %d [%d]"
          args: [ 'id(g_feed_time_slot_1)','id(g_food_portion_slot_1)' ]
      # SLOT 1
      - datetime.time.set:
          id: feed_slot_1
          time: !lambda |-
                 return {.second = 0, .minute = uint8_t(id(g_feed_time_slot_1)%60), .hour = uint8_t(id(g_feed_time_slot_1)/60)};
      - number.set: 
          id: food_portion_slot_1
          value: !lambda |-
                return int(id(g_food_portion_slot_1));
      # SLOT 2
      - datetime.time.set:
          id: feed_slot_2
          time: !lambda |-
                 return {.second = 0, .minute = uint8_t(id(g_feed_time_slot_2)%60), .hour = uint8_t(id(g_feed_time_slot_2)/60)};
      - number.set: 
          id: food_portion_slot_2
          value: !lambda |-
                return int(id(g_food_portion_slot_2));
      # SLOT 3
      - datetime.time.set:
          id: feed_slot_3
          time: !lambda |-
                 return {.second = 0, .minute = uint8_t(id(g_feed_time_slot_3)%60), .hour = uint8_t(id(g_feed_time_slot_3)/60)};
      - number.set: 
          id: food_portion_slot_3
          value: !lambda |-
                return int(id(g_food_portion_slot_3));
      # SLOT 4
      - datetime.time.set:
          id: feed_slot_4
          time: !lambda |-
                 return {.second = 0, .minute = uint8_t(id(g_feed_time_slot_4)%60), .hour = uint8_t(id(g_feed_time_slot_4)/60)};
      - number.set: 
          id: food_portion_slot_4
          value: !lambda |-
                return int(id(g_food_portion_slot_4));
      # SLOT 5
      - datetime.time.set:
          id: feed_slot_5
          time: !lambda |-
                 return {.second = 0, .minute = uint8_t(id(g_feed_time_slot_5)%60), .hour = uint8_t(id(g_feed_time_slot_5)/60)};
      - number.set: 
          id: food_portion_slot_5
          value: !lambda |-
                return int(id(g_food_portion_slot_5));

globals:
  # Portion counter
  - id: g_portion_count
    type: int
    restore_value: False
    initial_value: '0'
  # Portion counter
  - id: g_feeding_in_progress
    type: int
    restore_value: False
    initial_value: '0'    
  # SLOT 1
  - id: g_feed_time_slot_1
    type: int
    restore_value: true
    initial_value: '0'
  - id: g_food_portion_slot_1
    type: int
    restore_value: true
    initial_value: '0'
  # SLOT 2
  - id: g_feed_time_slot_2
    type: int
    restore_value: true
    initial_value: '0'
  - id: g_food_portion_slot_2
    type: int
    restore_value: true
    initial_value: '0'
  # SLOT 3
  - id: g_feed_time_slot_3
    type: int
    restore_value: true
    initial_value: '0'
  - id: g_food_portion_slot_3
    type: int
    restore_value: true
    initial_value: '0'
  # SLOT 4
  - id: g_feed_time_slot_4
    type: int
    restore_value: true
    initial_value: '0'
  - id: g_food_portion_slot_4
    type: int
    restore_value: true
    initial_value: '0'
  # SLOT 5
  - id: g_feed_time_slot_5
    type: int
    restore_value: true
    initial_value: '0'
  - id: g_food_portion_slot_5
    type: int
    restore_value: true
    initial_value: '0'

# Enable Home Assistant API
api:
  encryption:
    key: ""

ota:
  - platform: esphome
    password: ""

esp32:
  board: lolin_s2_mini #Pinout: https://www.wemos.cc/en/latest/s2/s2_mini.html
  framework:
    type: esp-idf
    version: recommended


preferences:
  flash_write_interval: 0s

logger:

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.0.xxx
    gateway: 192.168.0.1
    subnet: 255.255.255.0
  ap:
    ssid: "Fish Feeder Fallback Hotspot"
    password: ""
 
time:
  - platform: homeassistant
    id: homeassistant_time

  - platform: sntp
    id: sntp_time
    timezone: "Europe/Paris"
    servers:
    - pool.ntp.org
    - time.cloudflare.com


captive_portal:

# Template sensor to display the Open/Close Counter value
sensor:
  - platform: uptime
    name: "System - Uptime"

datetime:
  # SLOT 1
  - platform: template
    time_id: homeassistant_time
    name: "Slot 1"
    id: feed_slot_1
    type: TIME
    optimistic: True
    restore_value: true    
    set_action: 
      then:
        - logger.log:
            format: "Set time for slot 1:"
    on_time: 
      - if :
          condition: 
            - lambda: "return id(food_portion_slot_1).state > 0;"
            - lambda: "return id(g_feeding_in_progress) == 0;"
          then:
            - lambda: "id(g_feeding_in_progress) = 1;"
            - lambda: "id(g_portion_count)=id(g_food_portion_slot_1);"
            - while:
                condition: 
                  - lambda: "return id(g_portion_count) > 0;"
                then:
                  - lambda: "id(g_portion_count) -= 1;"
                  - logger.log:
                      format: "Portions slot 1 to give: %d"
                      args: [ 'id(g_portion_count)' ]
                  - switch.turn_on: motor_switch   
                  - delay: 30s
            - lambda: "id(g_feeding_in_progress) = 0;"
                    
    on_value: 
      then:
        - logger.log:
            format: "Set time.on_value for slot 1"
        - lambda: |-
               id(g_feed_time_slot_1) = x.hour*60+x.minute;
  # SLOT 2
  - platform: template
    time_id: homeassistant_time
    name: "Slot 2"
    id: feed_slot_2
    type: TIME
    optimistic: True
    restore_value: true    
    set_action: 
      then:
        - logger.log:
            format: "Set time for slot 2:"
    on_time: 
      - if :
          condition: 
            - lambda: "return id(food_portion_slot_2).state > 0;"
            - lambda: "return id(g_feeding_in_progress) == 0;"
          then:
            - lambda: "id(g_feeding_in_progress) = 1;"
            - lambda: "id(g_portion_count)=id(g_food_portion_slot_2);"
            - while:
                condition: 
                  - lambda: "return id(g_portion_count) > 0;"
                then:

                  - lambda: "id(g_portion_count) -= 1;"
                  - logger.log:
                      format: "Portions slot 2 to give: %d"
                      args: [ 'id(g_portion_count)' ]
                  - switch.turn_on: motor_switch   
                  - delay: 30s
            - lambda: "id(g_feeding_in_progress) = 1;"  
    on_value: 
      then:
        - logger.log:
            format: "Set time.on_value for slot 2"
        - lambda: |-
               id(g_feed_time_slot_2) = x.hour*60+x.minute;
  # SLOT 3
  - platform: template
    time_id: homeassistant_time
    name: "Slot 3"
    id: feed_slot_3
    type: TIME
    optimistic: True
    restore_value: true    
    set_action: 
      then:
        - logger.log:
            format: "Set time for slot 3:"
    on_time: 
      - if :
          condition: 
            - lambda: "return id(food_portion_slot_3).state > 0;"
            - lambda: "return id(g_feeding_in_progress) == 0;"
          then:
            - lambda: "id(g_feeding_in_progress) = 1;"
            - lambda: "id(g_portion_count)=id(g_food_portion_slot_3);"
            - while:
                condition: 
                  - lambda: "return id(g_portion_count) > 0;"
                then:

                  - lambda: "id(g_portion_count) -= 1;"
                  - logger.log:
                      format: "Portions to give: %d"
                      args: [ 'id(g_portion_count)' ]
                  - switch.turn_on: motor_switch   
                  - delay: 30s
            - lambda: "id(g_feeding_in_progress) = 0;"
    on_value: 
      then:
        - logger.log:
            format: "Set time.on_value for slot 3"
        - lambda: |-
               id(g_feed_time_slot_3) = x.hour*60+x.minute;
  # SLOT 4
  - platform: template
    time_id: homeassistant_time
    name: "Slot 4"
    id: feed_slot_4
    type: TIME
    optimistic: True
    restore_value: true    
    set_action: 
      then:
        - logger.log:
            format: "Set time for slot 4:"
    on_time: 
      - if :
          condition: 
            - lambda: "return id(food_portion_slot_4).state > 0;"
            - lambda: "return id(g_feeding_in_progress) == 0;"
          then:
            - lambda: "id(g_feeding_in_progress) = 1;"
            - lambda: "id(g_portion_count)=id(g_food_portion_slot_4);"
            - while:
                condition: 
                  - lambda: "return id(g_portion_count) > 0;"
                then:
                  - lambda: "id(g_portion_count) -= 1;"
                  - logger.log:
                      format: "Portions to give: %d"
                      args: [ 'id(g_portion_count)' ]
                  - switch.turn_on: motor_switch   
                  - delay: 30s
            - lambda: "id(g_feeding_in_progress) = 0;"
    on_value: 
      then:
        - logger.log:
            format: "Set time.on_value for slot 4"
        - lambda: |-
               id(g_feed_time_slot_4) = x.hour*60+x.minute;
  # SLOT 5
  - platform: template
    time_id: homeassistant_time
    name: "Slot 5"
    id: feed_slot_5
    type: TIME
    optimistic: True
    restore_value: true    
    set_action: 
      then:
        - logger.log:
            format: "Set time for slot 5:"
    on_time: 
      - if :
          condition: 
            - lambda: "return id(food_portion_slot_5).state > 0;"
            - lambda: "return id(g_feeding_in_progress) == 0;"
          then:
            - lambda: "id(g_feeding_in_progress) = 1;"
            - lambda: "id(g_portion_count)=id(g_food_portion_slot_5);"
            - while:
                condition: 
                  - lambda: "return id(g_portion_count) > 0;"
                then:
                  - lambda: "id(g_portion_count) -= 1;"
                  - logger.log:
                      format: "Portions to give: %d"
                      args: [ 'id(g_portion_count)' ]
                  - switch.turn_on: motor_switch   
                  - delay: 30s
            - lambda: "id(g_feeding_in_progress) = 0;"
    on_value: 
      then:
        - logger.log:
            format: "Set time.on_value for slot 5"
        - lambda: |-
               id(g_feed_time_slot_5) = x.hour*60+x.minute;


# Define binary sensors
binary_sensor:
  - platform: gpio
    pin: 
      number: GPIO4
      mode: 
        input: true
        pulldown: true
    name: "Open/Close Sensor"
    id: open_close_sensor
    device_class: door
    filters:
      - delayed_on_off: 2s
    on_state_change:
      then:
        - if :
            condition : 
              binary_sensor.is_off: open_close_sensor
            then:
              - switch.turn_off: motor_switch
  - platform: gpio
    pin: 
      number: GPIO3
      mode: INPUT_PULLUP
      inverted: False
    name: "Food Level Sensor"
    id: food_level_sensor
    device_class: problem
    icon: "mdi:alert"


number:
  # SLOT 1
  - platform: template
    id: food_portion_slot_1
    name: "Portion slot 1"
    icon: "mdi:shaker"
    step: 1
    max_value: 10
    min_value: 0
    restore_value: True
    set_action:
      then:
        - logger.log:
            format: "Number of portion set"
        - lambda: |-
               id(g_food_portion_slot_1) = x;
  # SLOT 2
  - platform: template
    id: food_portion_slot_2
    name: "Portion slot 2"
    icon: "mdi:shaker"   
    step: 1
    max_value: 10
    min_value: 0
    restore_value: True
    set_action: 
      then:
        - logger.log:
            format: "Number of portion set"
        - lambda: |-
               id(g_food_portion_slot_2) = x;
   # SLOT 3
  - platform: template
    id: food_portion_slot_3
    name: "Portion slot 3"
    icon: "mdi:shaker"    
    step: 1
    max_value: 10
    min_value: 0
    restore_value: True
    set_action: 
      then:
        - logger.log:
            format: "Number of portion set"
        - lambda: |-
               id(g_food_portion_slot_3) = x;
   # SLOT 4
  - platform: template
    id: food_portion_slot_4
    name: "Portion slot 4"
    icon: "mdi:shaker"    
    step: 1
    max_value: 10
    min_value: 0
    restore_value: True
    set_action: 
      then:
        - logger.log:
            format: "Number of portion set"
        - lambda: |-
               id(g_food_portion_slot_4) = x;
   # SLOT 5
  - platform: template
    id: food_portion_slot_5
    name: "Portion slot 5"
    icon: "mdi:shaker"    
    step: 1
    max_value: 10
    min_value: 0
    restore_value: True
    set_action: 
      then:
        - logger.log:
            format: "Number of portion set"
        - lambda: |-
               id(g_food_portion_slot_5) = x;
 

# Define the switch for controlling the motor
switch:
  - platform: gpio
    pin: 
       number: GPIO5
    id: motor_switch
    name: "Manual Feed"
    restore_mode: ALWAYS_OFF 
    icon: mdi:pinwheel

  - platform: restart
    name: "System - Restart"

  - platform: safe_mode
    name: "System - Safe mode"

Did you have to remove everything here, before soldering the ESP32 chip?

You have to remove the whole board not just the components

1 Like

Ohhhhh I just saw this is a whole tiny board attached! LOL Sorry, I didn’t see that until you said something.

Flashed the YAML just fine to the ESP, but it seems to reboot itself after 15 mins or so. Has anybody else seen this?

Logs:

Blockquote 17:05:37 [D] [sensor:135]
‘System - Uptime’: Sending state 844.85400 s with 0 decimals of accuracy
17:06:32 [E] [api:156]
No clients; rebooting
17:08:36 [D] [sensor:135]
‘System - Uptime’: Sending state 124.31000 s with 0 decimals of accuracy
17:08:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -57.00000 dBm with 0 decimals of accuracy
17:08:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:09:36 [D] [sensor:135]
‘System - Uptime’: Sending state 184.31000 s with 0 decimals of accuracy
17:09:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -60.00000 dBm with 0 decimals of accuracy
17:09:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:10:37 [D] [sensor:135]
‘System - Uptime’: Sending state 244.31400 s with 0 decimals of accuracy
17:10:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -60.00000 dBm with 0 decimals of accuracy
17:10:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:11:36 [D] [sensor:135]
‘System - Uptime’: Sending state 304.31400 s with 0 decimals of accuracy
17:11:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -58.00000 dBm with 0 decimals of accuracy
17:11:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:12:36 [D] [sensor:135]
‘System - Uptime’: Sending state 364.31400 s with 0 decimals of accuracy
17:12:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -59.00000 dBm with 0 decimals of accuracy
17:12:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:13:36 [D] [sensor:135]
‘System - Uptime’: Sending state 424.31400 s with 0 decimals of accuracy
17:13:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -59.00000 dBm with 0 decimals of accuracy
17:13:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:14:36 [D] [sensor:135]
‘System - Uptime’: Sending state 484.31500 s with 0 decimals of accuracy
17:14:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -57.00000 dBm with 0 decimals of accuracy
17:14:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:15:36 [D] [sensor:135]
‘System - Uptime’: Sending state 544.31598 s with 0 decimals of accuracy
17:15:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -59.00000 dBm with 0 decimals of accuracy
17:15:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:16:36 [D] [sensor:135]
‘System - Uptime’: Sending state 604.31598 s with 0 decimals of accuracy
17:16:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -62.00000 dBm with 0 decimals of accuracy
17:16:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:17:36 [D] [sensor:135]
‘System - Uptime’: Sending state 664.31598 s with 0 decimals of accuracy
17:17:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -61.00000 dBm with 0 decimals of accuracy
17:17:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:18:36 [D] [sensor:135]
‘System - Uptime’: Sending state 724.31598 s with 0 decimals of accuracy
17:18:38 [D] [sensor:135]
‘WiFi - Signal’: Sending state -59.00000 dBm with 0 decimals of accuracy
17:18:38 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:19:36 [D] [sensor:135]
‘System - Uptime’: Sending state 784.32098 s with 0 decimals of accuracy
17:19:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -57.00000 dBm with 0 decimals of accuracy
17:19:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:20:36 [D] [sensor:135]
‘System - Uptime’: Sending state 844.32001 s with 0 decimals of accuracy
17:20:37 [D] [sensor:135]
‘WiFi - Signal’: Sending state -59.00000 dBm with 0 decimals of accuracy
17:20:37 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:21:32 [E] [api:156]
No clients; rebooting
17:23:34 [D] [sensor:135]
‘Open/Close Counter’: Sending state 0.00000 times with 0 decimals of accuracy
17:23:34 [D] [sensor:135]
‘WiFi - Signal’: Sending state -59.00000 dBm with 0 decimals of accuracy
17:23:37 [D] [sensor:135]
‘System - Uptime’: Sending state 124.25600 s with 0 decimals of accuracy

17:06 - “No Clients Rebooting”
then again at
17:20