My project: Chicken coop automation

Hi folks
I thought I’d add some words about an ESPHome project I’ve had during 2021. Nothing fancy really but fun to do. We got an opportunity to “adopt” 8 chickens from a friend and while I was building the cage and chicken coop I thought to myself, this calls for some automation. I mean, manually opening and closing a chicken coop door is so 2010. :slight_smile:

As I like to fiddle with most things technical the project grew from the initial requirement of controlling the coop door to something…else. This is the result taken from the Home Assistant dashboard, pardon the Swedish labels. The whole setup is powered by a 12v 18ah AGM battery charged by a 200W solar panel.


*I had to have a camera in the coop and I had a Raspberry Zero lying around for another project. Raspberry pi zero w + camera module + protective case camera box diy kit Sale - Banggood.com completed the setup and I moved all the pieces into a dust proof case.
*I also had a spare 433mhz temperature sensor which was already set up in HA with rfxcom, only took a rename and a good location to get good data.
*Now for the fun part. It’s basically an end-stop cover setup with my complete ESPHome code below. The servo driving the coop dor is a continuous drive servo.
*Two 433mhz door sensors are used, “Hönsgården” for the cage door and “Hönshusdörr” for the entrance to the coop (for people).
*The last two switches in HA are actually helpers controlling the camera and 12v LED strip.
*I dug up a guide on how to measure battery voltage using a divider curcuit and input A0 on the Wemos, I use this to drive some automations in HA.
*Last piece are status of the actual relay switches for the camera and LED strip.

cover:
  - platform: endstop
    name: "CoopDoor"
    id: coopdoor
    #assumed_state: false
    #optimistic: false
    device_class: garage
    open_action:
      - servo.write:
          id: my_servo
          level: 60.0%
      - logger.log: "Cover opening"
      - lambda: id(coopdoor).publish_state(COVER_OPEN);
    open_duration: 10sec
    open_endstop: top_endstop

    close_action:
      - servo.write:
          id: my_servo
          level: -60.0%
      - lambda: id(coopdoor).publish_state(COVER_CLOSED);
      - logger.log: "Cover closing"
    close_duration: 10sec
    close_endstop: bottom_endstop
    stop_action:
      - delay: 100ms
      - servo.write:
          id: my_servo
          level: 0%
      - logger.log: "Motor stopped COVER"
      - servo.detach: my_servo
    max_duration: 15sec

binary_sensor:
#TopSwitch
  - platform: gpio
    name: "topStopSwitch"
    pin:
      number: D5
      inverted: true
      mode: INPUT_PULLUP
    id: top_endstop
    on_press:
      then:
        - logger.log: "Motor stopped TOP"
        - lambda: id(coopdoor).position = COVER_OPEN;
        - cover.stop: coopdoor

#BottomSwitch
  - platform: gpio
    name: "bottomStopSwitch"
    pin:
      number: D6
      mode: INPUT_PULLUP
      inverted: true
    id: bottom_endstop
    on_press:
      then:
        - logger.log: "Motor stopped Bottom"
        - lambda: id(coopdoor).position = COVER_CLOSED;
        - cover.stop: coopdoor

#Open door
  - platform: gpio
    name: "door_openButton"
    pin:
      number: D3
      inverted: true
      mode: INPUT_PULLUP
    id: coopdoor_open
    on_click:
      then:
          - logger.log: "Openbutton"
          - lambda: id(coopdoor).publish_state(COVER_OPERATION_OPENING);
          - cover.open: coopdoor
        
              
#Close door    
  - platform: gpio
    name: "door_closeButton"
    pin:
      number: D4
      mode: INPUT_PULLUP
      inverted: true
    id: coopdoor_close
    on_click:
      then:
        - logger.log: "Closebutton"
        - lambda: id(coopdoor).publish_state(COVER_OPERATION_CLOSING);
        - cover.close: coopdoor
      
servo:
  - id: my_servo
    output: pwm_output
    

output:
  - platform: esp8266_pwm
    id: pwm_output
    pin: D1
    frequency: 50 Hz
    
sensor:
#  - platform: wifi_signal
#    name: "WiFi Strength"
#    update_interval: 60s
#  - platform: uptime
#    name: "Uptime"
    
  - platform: adc
    pin: A0
    name: "VCC Voltage"
    id: VCC
    update_interval: 30 seconds

  - platform: template
    name: KalibreradVCC
    id: VCC2
    lambda: return id(VCC).state * 33.30;
    unit_of_measurement: V
    accuracy_decimals: 2


switch:
  - platform: gpio
    name: "Camera"
    pin: D8
    
  - platform: gpio
    name: "LED-strip"
    pin: D7

Below are the related automations in HA.
*To save battery I turn off the camera at night, battery drain goes from 0.4A to 0.2A

alias: CoopCameraOff
description: ''
trigger:
  - platform: time
    at: '23:00'
condition: []
action:
  - service: switch.turn_off
    target:
      entity_id: switch.camera
mode: single

*If the battery has enough volts, I turn on the camera again in the morning.

alias: CoopCameraOn
description: ''
trigger:
  - platform: time
    at: '07:00'
condition:
  - condition: numeric_state
    entity_id: sensor.kalibreradvcc
    above: '11.8'
action:
  - service: switch.turn_on
    target:
      entity_id: switch.camera
mode: single

*I want the entrance to turn on the LED strip, but only if there is enough power in the battery and turn it off again when the door is closed…but not if the LED has been commanded ON by the helper. I’m thinking the poor critters will need light during the winter. (I live in Scandinavia)

alias: CoopDoorLED
description: ''
trigger:
  - platform: state
    entity_id: binary_sensor.dorrsensor2
condition: []
action:
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.kalibreradvcc
            above: '11.7'
          - condition: state
            entity_id: binary_sensor.dorrsensor2
            state: 'on'
        sequence:
          - service: switch.turn_on
            target:
              entity_id: switch.led_strip
      - conditions:
          - condition: state
            entity_id: binary_sensor.dorrsensor2
            state: 'off'
          - condition: state
            entity_id: input_boolean.manualled_strip
            state: 'off'
        sequence:
          - delay:
              hours: 0
              minutes: 0
              seconds: 10
              milliseconds: 0
          - service: switch.turn_off
            target:
              entity_id: switch.led_strip
    default: []
mode: single

The last one is a bit of a doozy. I want some things done depending on the battery volts. Turn off the LED first, since its using the most power, and disable the input selector. Then turn off and disable the camera. Do everything in reverse when the battery has charged enough.

alias: CoopVoltageActions
description: ''
trigger:
  - platform: state
    entity_id: sensor.kalibreradvcc
condition:
  - condition: numeric_state
    entity_id: sensor.kalibreradvcc
    below: '12'
action:
  - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.kalibreradvcc
            below: '11.8'
        sequence:
          - service: switch.turn_off
            target:
              entity_id: input_boolean.manualled_strip
          - service: python_script.set_state
            data:
              data_template: null
              entity_id: input_boolean.manualled_strip
              state: unavailable
          - choose:
              - conditions:
                  - condition: numeric_state
                    entity_id: sensor.kalibreradvcc
                    below: '11.7'
                sequence:
                  - service: switch.turn_off
                    target:
                      entity_id: input_boolean.manualcamera
                  - service: python_script.set_state
                    data:
                      data_template: null
                      entity_id: input_boolean.manualcamera
                      state: unavailable
      - conditions:
          - condition: numeric_state
            entity_id: sensor.kalibreradvcc
            above: '11.8'
        sequence:
          - service: python_script.set_state
            data:
              data_template: null
              entity_id: input_boolean.manualcamera
              state: '{{states(''switch.camera'')}}'
          - choose:
              - conditions:
                  - condition: numeric_state
                    entity_id: sensor.kalibreradvcc
                    above: '11.9'
                sequence:
                  - service: python_script.set_state
                    data:
                      data_template: null
                      entity_id: input_boolean.manualled_strip
                      state: '{{states(''switch.led_strip'')}}'
            default: []
    default: []
mode: single

Some photos of the end result.

I realise there are alot more to write but this is a quick start. Expect some editing later.
Peace out and thank you for a great forum.
/Fredrik

10 Likes

I love “little” :wink: projects like this.

I have a project for my fish tank that controls the lights, heater, filter, air pump and power head flow pumps. None of those things I can’t do myself but why should I when HA makes it so easy to do it automatically!?

It’s become a pretty extensive automation package with all of the little nuances that i thought of for lighting and such. And it has notifications for any important failures in the system - heater stays on or doesn’t come on, filter stops running, things like that.

I even have a button I push when I feed the fish that turns off the filter and all the automations for 5 minutes to let then eat and then turns everything on to circulate the extra bits thru the filters. And if I haven’t fed them by 2 o’clock it reminds me.

So I get how such “simple” things turn into a huge project pretty quickly.

But it was fun. :laughing:

1 Like

Smart chickens, who’d a thought?

Cool project. What make/model of server did you use? thx

Hi Fantangelo
Thank you. I’m not sure what you mean by “server”. The ESP is a Wemos D1 mini and HA is running on a Raspberry Pi4.

/Fredrik

grrrr, sorry meant servo, not server. thx

:slight_smile:
The servo is this one. TD-8120MG Waterproof Digital Servo - 20kg - Continuous - TD-8120MG-CONT

Thanks for the info!

Hi Fredrik. This is great and looks like something I’d like to do. I don’t suppose you have schematics of your setup do you?