Home Assistant - It's for the birds! [Part 1]

If you are looking for a post that is bashing home assistant, you have probably come to the wrong place. Recently I was asked to look after a flock of birds. The only trouble here was that I was away for some of the time. In order to make sure I could monitor them, I used home assistant to give me a hand.

The first thing I did was set up cameras. I had a couple of esp cameras that I wasn't using, so I got hold of my soldering octopus and used that to point the cameras in the right direction. Once set up, I set about installing the firmware.

For this, I used esphome. I have esphome installed as an addon to home assistant, but you could also use a standalone instance. Just make sure you have shared the keys for the api.

The yaml for the espcam is shown below:

esphome:
  name: espcam-01
  friendly_name: espcam-01
#  includes:
#    - ble-node.h
#  libraries:
#    - "h2zero/NimBLE-Arduino"

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "yH3WPjOoz7Yz7ZFYMFBbXxxYannu7vzH1G3uMkN3lsE="
  services:  # change camera parameters on-the-fly
  - service: camera_set_param
    variables:
      name: string
      value: int
    then:
      - lambda: |-
          bool state_return = false;
          if (("contrast" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_contrast(value); state_return = true; }
          if (("brightness" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_brightness(value); state_return = true; }
          if (("saturation" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_saturation(value); state_return = true; }
          if (("special_effect" == name) && (value >= 0U) && (value <= 6U)) { id(espcam).set_special_effect((esphome::esp32_camera::ESP32SpecialEffect)value); state_return = true; }
          if (("aec_mode" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_aec_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
          if (("aec2" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_aec2(value); state_return = true; }
          if (("ae_level" == name) && (value >= -2) && (value <= 2)) { id(espcam).set_ae_level(value); state_return = true; }
          if (("aec_value" == name) && (value >= 0U) && (value <= 1200U)) { id(espcam).set_aec_value(value); state_return = true; }
          if (("agc_mode" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_agc_mode((esphome::esp32_camera::ESP32GainControlMode)value); state_return = true; }
          if (("agc_value" == name) && (value >= 0U) && (value <= 30U)) { id(espcam).set_agc_value(value); state_return = true; }
          if (("agc_gain_ceiling" == name) && (value >= 0U) && (value <= 6U)) { id(espcam).set_agc_gain_ceiling((esphome::esp32_camera::ESP32AgcGainCeiling)value); state_return = true; }
          if (("wb_mode" == name) && (value >= 0U) && (value <= 4U)) { id(espcam).set_wb_mode((esphome::esp32_camera::ESP32WhiteBalanceMode)value); state_return = true; }
          if (("test_pattern" == name) && (value >= 0U) && (value <= 1U)) { id(espcam).set_test_pattern(value); state_return = true; }
          if (true == state_return) {
            id(espcam).update_camera_parameters();
          }
          else {
            ESP_LOGW("esp32_camera_set_param", "Error in name or data range");
          }
ota:
  - platform: esphome
    password: "8e6a10476a04b7d3634b40389e76f8f8"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Espcam-03 Fallback Hotspot"
    password: "i2kS5KXnFFnr"

captive_portal:

esp32_camera_web_server:
  - port: 8080
    mode: stream
  - port: 8081
    mode: snapshot

esp32_camera:
  id: espcam
  name: esp-cam
  external_clock:
    pin: GPIO0
    frequency: 10MHz
  i2c_pins:
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32
  resolution: 800x600
  jpeg_quality: 24  # max. 63
  max_framerate: 4.0fps
  idle_framerate: 0.2fps
  vertical_flip: true
  horizontal_mirror: false
  brightness: 2 # -2 to 2
  contrast: 1 # -2 to 2
  special_effect: none
  # exposure settings
  aec_mode: auto
  aec2: false
  ae_level: 0
  aec_value: 300
  # gain settings
  agc_mode: auto
  agc_gain_ceiling: 2x
  agc_value: 0
  # white balance setting
  wb_mode: auto
output:
# white LED
  - platform: ledc
    channel: 2
    pin: GPIO4
    id: espCamLED
# red status light
  - platform: gpio
    pin:
      number: GPIO33
      inverted: True
    id: gpio_33
light:
  - platform: monochromatic
    output: espCamLED
    name: esp-cam light
  - platform: binary
    output: gpio_33
    name: esp-cam led
switch:
  - platform: restart
    name: esp-cam restart
binary_sensor:
  - platform: status
    name: esp-cam status

sensor:
  - platform: uptime
    name: "ESP32 Camera Uptime Sensor"
    
  - platform: wifi_signal
    name: "ESP32 Camera WiFi Signal"
    update_interval: 60s   

mqtt:
  broker: !secret mqtt_serv
  username: !secret mqtt_user
  password: !secret mqtt_pass
  topic_prefix: ${name}    
  discovery: true

#custom_component:
#- lambda: |-
#    auto my_node = new BleNodeComponent("Bedroom");
#    return {my_node};

Once the yaml file was build in esphome, I flashed the device with it. I was able to do this over wifi, since I'd already flashed it for something. You may need to plug the device in to get the firmware on it.

Once complete, your devices should start to show up in home assistant. Next I used HACS to install the "Advanced Camera Card". This allowed my to configure a dashboard with the 2 cameras on it.

Lastly, I was able to set up an account for the bird's owner to view the birds remotely.

Next time, I will be setting up Music assistant to play radio to them during preset hours.

As an Amazon Associate I earn from qualifying purchases.

If you have found this post useful, please consider donating.