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.