Table of Contents

Bird Feeder

1. Introduction

Bird Feeder is a project that aims to build a self-contained system which integrates a Pet Feeder manufactured by Nooie which will dispense food for birds via donations through a livestream. The Bird Feeder is projected to be placed in the bird house of Kalisto Tierpark located in Kamp-Lintfort.

The Nooie Pet Feeder features a microcontroller board manufactured by Tuya. Tuya is an IoT and cloud development service provider with a varied range of products. The pet feeder can be controlled through Tuya’s cloud development platform. While cloud development is useful, we would like to control the pet feeder locally for security and latency reasons.

To control the pet feeder locally, we will be using Home Assistant. Home Assistant is a Linux based open-source software generally used for smart home automation. We will be using a Raspberry Pi to install Home Assistant, which will be our main control hub.

Additionally, an e-paper display will be used to display last donation information to show people physically present that this service actually exists.

2. Materials

2.1 Raspberry Pi 4

   

Fig. 1: Raspberry Pi 4

2.2 Xiao Esp32S3

   

files.seeedstudio.com_wiki_seeedstudio-xiao-esp32s3_img_2.jpgFig. 2: XIAO Esp32s3 Pinout

   

Expansion BoardFig. 3: XIAO eInk Expansion Board

2.3 7.5in E-ink Display

   

e-ink displayFig. 4: 7.5" E-Ink Display

3. Home Assistant on RaPi

Home Assistant Installation

This guide was written using Home Assistant version 2024.5.x.

Raspberry Pi Setup

  1. Install Raspberry Pi imager https://www.raspberrypi.com/software/. Fig. 5: Pick the operating system you are using
  2. Insert the Micro SD card to the SD card reader.
  3. Run the application.
  4. Choose Device (Raspberry Pi 4 in this case).
  5. Choose Operating System (“Other specific-purpose OS” → “Home assistants and home automation” → “Home Assistant” → “Home Assistant OS 12.x”).
  6. Choose Storage. Fig. 6: Home Assistant Installation, In this case, Raspberry Pi 4
  7. Click “Next” → “Yes”. (Ignore Microsoft Error messages).
  8. Remove the Micro SD card.
  9. Insert the Micro SD card into the Raspberry Pi’s Micro SD card slot.
  10. Connect Raspberry Pi to power via the USB-C (or Micro-USB depending on the model) port.
  11. Connect the Raspberry Pi to your network via the ethernet port on the Pi, make sure your computer is connected to the same network as well.
  12. Home Assistant Installation happens automatically if the Micro SD card is inserted and the Raspberry Pi is powered on. This might take a few minutes. If you want to monitor the installation, connect the Raspberry Pi through its mini-HDMI port to a display.
  13. Open a web explorer, navigate to http://homeassistant.local:8123/ and hit enter.
  14. Wait for the setup to finish and click on “Create My Smart Home”.
  15. Create a user using your preferred credentials.

4. Implementation

  1. System Architecture.
  2. Connecting ESP32 to e-ink display using the extension board. (Display Component).
  3. Installing ESP-Home on HA.
  4. Connect Display Component to ESP-Home.
  5. Setting up MQTT Broker on HA.
  6. Rewriting the Display Component code from C++ to ESP-Home yaml syntax.
  7. Setting up Frontend website.
  8. Configuring website to use MQTT QoS-2.
  9. Configuring Nooie-pet feeder on HA using LocalTuya.
  10. Creating Automation function for pet feeder to trigger on MQTT Message.

4.1 System Architecture

   

amc:ss2024:bird_feeder:kalisto:sys-arch-v3.png
Diagram 1: System Architecture

4.2 Connecting ESP32 to e-ink display using the extension board.

   

display-component.jpegFig. 7: Display Component

display_code.ino
//Most Important Import
#include <SPI.h>
 
#include "Display_EPD_W21_spi.h"
#include "Display_EPD_W21.h"
#include "frame.h"
#include "GUI_Paint.h"
#include "font.h"
 
#if 1
unsigned char BlackImage[EPD_ARRAY]; //Define canvas space  
#endif
 
//Most Important Part
void setup() {
  pinMode(D5, INPUT); //BUSY
  pinMode(D0, OUTPUT); //RES 
  pinMode(D3, OUTPUT); //DC   
  pinMode(D1, OUTPUT); //CS  
 
  //SPI
  SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
  SPI.begin();
 
  Serial.begin(9600);
  Serial.print(111);
}
 
//Tips//
/*
1.Flickering is normal when EPD is performing a full screen update to clear ghosting from the previous image so to ensure better clarity and legibility for the new image.
2.There will be no flicker when EPD performs a partial refresh.
3.Please make sue that EPD enters sleep mode when refresh is completed and always leave the sleep mode command. Otherwise, this may result in a reduced lifespan of EPD.
4.Please refrain from inserting EPD to the FPC socket or unplugging it when the MCU is being powered to prevent potential damage.)
5.Re-initialization is required for every full screen update.
6.When porting the program, set the BUSY pin to input mode and other pins to output mode.
*/
 
void loop() {
  Serial.print(111);
 
  #if 1 //Partial refresh demostration.
 
  EPD_Init_Fast(); //Full screen refresh initialization.
  EPD_WhiteScreen_White(); //Clear screen function.
  EPD_DeepSleep(); //Enter the sleep mode and please do not delete it, otherwise it will reduce the lifespan of the screen.
  delay(2000); //Delay for 2s.	
  //Partial refresh demo support displaying a clock at 5 locations with 00:00.  If you need to perform partial refresh more than 5 locations, please use the feature of using partial refresh at the full screen demo.
  //After 5 partial refreshes, implement a full screen refresh to clear the ghosting caused by partial refreshes.
  //////////////////////Partial refresh time/////////////////////////////////////
  Paint_NewImage(BlackImage, EPD_WIDTH, EPD_HEIGHT, 0, WHITE); //Set canvas parameters, GUI image rotation, please change 0 to 0/90/180/270.
  Paint_SelectImage(BlackImage); //Select current settings.	
  EPD_Init(); //Full screen refresh initialization.
  Paint_Clear(WHITE); //Clear canvas.
  const char * Message = "Welcome to Kalisto";
  Paint_DrawString_EN(400 - (((strlen(Message) * 32) / 2)), 240 - (64 / 2), Message, & Font64, WHITE, BLACK);
  EPD_Display(BlackImage); //Display GUI image.
  EPD_DeepSleep(); //EPD_DeepSleep,Sleep instruction is necessary, please do not delete!!!
  delay(20000); //Delay for 2s. 		
 
  // Full screen update clear the screen.
  EPD_Init(); //Full screen refresh initialization.
  EPD_WhiteScreen_White(); //Clear screen function.
  EPD_DeepSleep(); //Enter the sleep mode and please do not delete it, otherwise it will reduce the lifespan of the screen.
  delay(2000); //Delay for 2s.	
 
  #endif
 
  delay(300000); // The program stops here   
}

4.3 Installing ESP-Home on HA.

4.4 Setting up MQTT Broker on HA.

4.5 Connect Display Component to ESP-Home.

   

esp-device-1Fig. 8

   

esp-device-2Fig. 9

   

esp-device-3Fig. 10

   

esp-device-4Fig. 11

   

esp-device-5Fig. 12

   

esp-device-6Fig. 13

   

esp-device-7Fig. 14

4.6 Rewriting the Display Component code from C++ to ESP-Home yaml syntax.

display_code.yaml
esphome:
  name: display
  friendly_name: display
  on_boot:
      priority: 200.0
      then:
        - component.update: eink_display
        - delay: 5s
        - logger.log: "Initial sensor data received: Refreshing display..."
        - script.execute: update_screen

esp32:
  board: esp32-s3-devkitc-1
  framework:
    type: arduino
 
# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "7QLJzR30itSBn30kootHbIE6FI8jmUtAl7/fcytRxis="

ota:
  platform: esphome
  password: "81ceca8aa7f29a76601df5539733d32f"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
 
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Display Fallback Hotspot"
    password: "WgV5TWXpXcpT"

captive_portal:

script:
  - id: update_screen
    then:
      - component.update: eink_display

font:
  - file: "gfonts://Roboto"
    id: roboto_64
    size: 64

spi:
  clk_pin: GPIO7
  mosi_pin: GPIO9

mqtt:
  broker: hafeeder.local
  port: 1883
  username: "mqtt"
  password: "1234"

text_sensor:
  - platform: mqtt_subscribe
    name: "Data from topic"
    id: mytext
    topic: birdfeeder  
    qos: 2
    on_value: 
      then:
        - script.execute: update_screen

display:
  - platform: waveshare_epaper
    model: 7.50in-bV3
    id: eink_display
    cs_pin: GPIO2
    dc_pin: GPIO4
    busy_pin: GPIO6
    reset_pin: GPIO1
    update_interval: never
    lambda: |-
      it.printf(400, 240, id(roboto_64), TextAlign::TOP_CENTER, id(mytext).state.c_str());

4.7 Setting up Frontend website.

   

React AppFig. 15

4.8 Configuring Nooie-pet feeder on HA using LocalTuya.

HACS Installation

Home Assistant Community Store (HACS) is a third-party download manager for Home Assistant which contains various custom integrations. We need to install LocalTuya integration through HACS to locally control the pet feeder. This guide was written using HACS version 1.34.0.

  1. Go to your user profile and enable “Advanced mode”.

   

Fig. 16: User profile is found on the bottom right.

  1. Go “Settings” → “Add-ons” → “Add-on store” → search “SSH” → Install “Terminal & SSH”.
  2. After the installation is complete, enable “Show in sidebar”

   

Fig. 17: SSH Add-on options after installation

  1. Navigate to “Terminal” on the sidebar, if it appears not to be running or if you are receiving error codes, refresh the instance.
  2. Copy and paste (CTRL+SHIFT+V to paste) the following command to the terminal and hit Enter. This will initiate the installation of HACS.
     wget -O - https://get.hacs.xyz | bash - 

   

Fig. 18: HA SSH

  1. After the installation is completed, restart the home assistant (“Settings” → three dots on the top right → “Restart Home Assistant” → “Restart Home Assistant”).
  2. Home Assistant should automatically restart, if the browser crashes, refresh the browser page to access Home Assistant again.
  3. Navigate to “Settings” → “Devices & Services” → Click “Add Integration” on the bottom right corner.
  4. Type “HACS” on the search bar, click on the result.

   

Fig. 19

  1. Check all but the last checkbox and submit.

   

Fig. 20

  1. Create a github account if you don’t have one.
  2. HACS will ask you to activate device through your github account. Follow the instructions provided and link HACS with your github account.

   

Fig. 21: Copy highlighted code and click on the github link Fig. 22: Paste the code here.

  1. Click on “Authorize” and exit github.
  2. If everything is set correctly you should have installed HACS on your Home Assistant. Do not pick an area on the pop-up and click on “finish”.
  3. Now HACS should show up on the sidebar of Home Assistant UI.

LocalTuya integration Installation

LocalTuya integration is what we need to control the pet feeder locally. This guide was written for LocalTuya version 5.2.1.

  1. On the HACS tab, click on “Integrations”.

   

Fig. 23

  1. Click on “Explore & Download Repositories” on the bottom right, on the pop-up search, type “LocalTuya”. Click on the result.

   

Fig. 24

  1. Click on “Download” on the bottom right. Click on “Download” again on the pop-up.

   

Fig. 25

Adding Pet Feeder to Home Assistant

  1. Download the “Tuya Smart” app to your smartphone (version 5.13.0 was used for this guide).
  2. Press both buttons on the pet feeder at the same time.
  3. Run the “Tuya Smart” app, press “Add Device”, the Pet feeder should appear automatically, turn on your Bluetooth if it doesn’t. Insert the wireless credentials and press login. Make sure the pet feeder and the Home Assistant are in the same network.
  4. Navigate to Tuya IoT development platform and create an account. Fig. 26
  5. Once the account is created, navigate to the developer platform on the top right corner of the page you were redirected to.
  6. Skip the tutorials, hover the cursor over “Cloud” on the sidebar and click on “Development”. Fig. 27
  7. Click on “Create Cloud Project“ on the Development page. Fill in the project details. Pick “Custom” Development method and “Central European Data Center”, pick the rest as you see fit. Fig. 28
  8. In the next step, add “Smart Home Basic Service” and ”[Deprecate]Device Log Query“ to the selected API services. Click on “Authorize”. Fig. 29
  9. Now that the project is created, let’s add the pet feeder to the project. Navigate to “Devices” → “Link Tuya App Account” → “Add App Account”. Fig. 30
  10. A QR code will appear, open the “Tuya Smart” app on your phone, press on “Me” on the bottom right and then press on the scan icon on the top right, scan the QR code.
  11. After the QR code is scanned, pick “Automatic Device Linking Method” and click on OK. Fig. 31
  12. Once the linking is complete, you should be able to see your account details on the “Link Tuya App Account” tab. Make note of the “UID”, we will use this later. Click on “Manage Devices”. Fig. 32
  13. If the Pet Feeder is shown as unlinked, check the checkbox next to the pet feeder and hit “Link Device”. Fig. 33
  14. Confirm the pet feeder exists on the “All Devices” tab, do not close this webpage. Fig. 34
  15. Navigate back to the Home Assistant UI
  16. Go to “Settings” → “Devices & Services” → “Add Integration” on the bottom right corner, Search for “LocalTuya”. Click on “LocalTuya Integration”. Fig. 35
  17. Once LocalTuya is installed, Cloud API configuration pop up will appear. Make sure API server region is EU. For the rest of the credentials, we need to navigate back to Tuya developer platform. Fig. 36
  18. On the left sidebar, hover on “Cloud” → “Development” → “Open Project”. The “Client ID” and the “Secret” can be found under the “Overview” tab of the cloud project. (not the Overview on the sidebar, the one under our project name). Fig. 37
  19. Insert the credentials back to Home Assistant. Use the previously mentioned “UID” from “Link Tuya App Account” tab and click on “Submit”.
  20. LocalTuya Integration is now linked with your Tuya Development Account. We still need to configure the pet feeder for local use.
  21. You will be redirected to LocalTuya integration page, if not, Navigate to “Settings” → “Devices & Integrations” → “LocalTuya”.
  22. Click on “Configure” on the same page → “Add a New Device” → “Pet Feeder” (which should be recognized automatically) and submit. Fig. 38 Fig. 39 Fig. 40 Fig. 41
    1. Skip to step 23 if the credentials of the Pet Feeder are configured automatically. If the Pet Feeder’s configuration is not set automatically, navigate back to the Tuya Developer Platform, hover on the “Cloud” icon on the sidebar → “API Explorer”. Fig. 42: Optional step, refer to step 22.a.
    2. On the API explorer, Navigate to “Query Devices in Project” on “Device Management”.
    3. Type “1” to “page_size” and click on “Submit Request”.
    4. The response query gives us credentials of the device. We can find the local key and device id (called “id”). Fig. 43: Optional step, refer to step 22.a.
    5. The Host address can be obtained via your router’s web interface.
  23. After you submit, you will be met with the “Entity Type Selection” pop-up. The pet feeder has different functions such as dispensing food or turning the LED on the pet feeder on and off. Each of these functions has their own “Data Point ID” to communicate with the cloud. We need to intercept these Data Points and create separate entities to control the device via the Home Assistant. Fig. 44
  24. Do not exit the Home Assistant instance and navigate back to Tuya Developer Platform. Open your project and navigate to “All Devices” tab under “Devices” and click on “Debug Device”. Fig. 45
  25. On the device debugging page, under “Standard Instructions Set” are the functions of the device we can set new values for. Under “Standard Status Set” are the previously mentioned functions and the available sensors of the device.
  26. To find out which Data Point is associated with which function of the device, navigate to “Device Logs” tab. Fig. 46
  27. Turn the developer console on of your browser (CTRL+SHIFT+I or F12 for Google Chrome). Navigate to “Network” tab on the developer console.
  28. Notice the “Select DP ID” dropdown menu on the top left side of the page.
  29. While the Developer console is on, click on the DP ID dropdown menu and select “Manual Feed”, click on “Search”.
  30. After you click on “Search”, you should see the network tab of your developer console update with several different logs. “list” is the one we are looking for. Fig. 47
  31. Click on “list”, and navigate to the “Payload” tab, “Code” is the Data Point ID we are looking for. In this case it’s 3. Fig. 48
  32. The ID is our Data Point, which is 3.
  33. Navigate back to “Device Debugging” tab, make note of the manual_feed’s type and values. It’s an integer with a minimum value of 1, maximum value of 20 and with a step of 1. Fig. 49
  34. Navigate back to Home Assistant, last time, we were at the Entity Type Selection pop-up. “Settings” → “Devices & Services” → “LocalTuya” → “Configure” → “Add a new Device” → ”Submit” → “Submit”.
  35. Let’s add the manual feed function to LocalTuya. LocalTuya includes integers in “number”, pick it from the dropdown menu and submit. Fig. 50
  36. The “ID” dropdown menu includes DP IDs of the pet feeder, we know 3 is manual feed. From the dropdown menu, pick 3. Call it Manual Feed. The minimum value is 1, maximum value is 20 and the increment between values is 1. Click “Submit’. Fig. 51
  37. On the next step, the entity type selection will appear again, for now, check the “Do not add any more entities” and click “Submit” (we can always add more later). Fig. 52
  38. Now let’s see if the manual feed entity works. Click on “1 device” below the logo of localtuya. Fig. 53
  39. Slide the Manual Feed to any value and check the Pet Feeder is dispensing food. Fig. 54
  40. Add more entities by repeating step 26 and beyond.

4.9 Creating Automation function for pet feeder to trigger on MQTT Message.

  1. This step was by far the easiest in the whole process.
  2. In the “When” section, choose MQTT and set the topic to the one we already established in the MQTT Broker.
  3. In the “Then Do” section, choose the device, in our case “Pet Feeder”. Choose the action already established in the previous step “Manual Feed” then set the value to be between 1-10.

   

tuya-automations.jpegFig. 55: Pet feeder automation configuration

5. Results and Discussion

6. Future Steps

7. Obstacles

8. Key Learnings

9. References