# to track the states we need 3 internal binary switches:
# - door closed
# - door open
# - door shoud close
# and for the error condition an extra one:
# - counting error
switch:
  - platform: template
    name: "Door is closed"
    id: door_closed
    optimistic: true
    restore_mode: RESTORE_DEFAULT_ON
    internal: true
    on_turn_on:
    - logger.log: "Door close"
    - switch.turn_off: door_open
    - cover.close: hutch_door

  - platform: template
    name: "Door is open"
    id: door_open
    restore_mode: RESTORE_DEFAULT_OFF
    optimistic: true
    internal: true
    on_turn_on:
    - logger.log: "Door open"
    - switch.turn_off: door_closed
    - cover.open: hutch_door

  - platform: template
    name: "Door shoud close"
    id: door_should_close
    restore_mode: RESTORE_DEFAULT_OFF
    optimistic: true
    internal: true
# logic goes in here
    on_turn_on:
    - logger.log: "Door should close"
    - if:
        condition:
          and:
          - switch.is_off: counting_error
          - number.in_range:
              id: inhabitants
              above: 3.5
        then:
          - logger.log: close hutch door
          - switch.turn_on: door_closed
          - switch.turn_off: door_open

  - platform: template
    name: "counting error"
    id: counting_error
    restore_mode: RESTORE_DEFAULT_OFF
    optimistic: true
    internal: true
#
# GPIO input switches
  - platform: gpio
    name: "Hutch Door Open Switch"
    id: door_open_switch
    pin: 
      number: GPIO16
      mode:
        input: true
        pullup: true
    on_turn_on:
      - cover.open: hutch_door

  - platform: gpio
    name: "Hutch Door Close Switch"
    id: door_close_switch
    pin: 
      number: GPIO17
      mode:
        input: true
        pullup: true
    on_turn_on:
      - switch.turn_on: door_should_close
#
# GPIO outputs 
#
  - platform: gpio
    name: "Hutch Door Motor Close"
    id: motor_close
    pin:
      number: GPIO33 
      mode:
        output
    internal: true

  - platform: gpio
    name: "Hutch Door Motor Open"
    id: motor_open
    pin:
      number: GPIO32 
      mode:
        output
    internal: true

number:
  - platform: template
    id: inhabitants
    initial_value: 4
    min_value: -1
    max_value: 5
    step: 1
    optimistic: true
    on_value:
      then:
        - logger.log: value changed
        - lambda: |-
            id(rabbit_sensor).publish_state(x);
    on_value_range:
      - above: 4.5
        then:
          - switch.turn_on: counting_error
          - logger.log: Error! Manual recount necessary.
      - below: -0.5
        then:
          - switch.turn_off: counting_error
          - logger.log: Error! Manual recount necessary.

cover:
- platform: time_based
  name: "Rabbit Hutch Door"
  id: hutch_door
  open_action:
    - switch.turn_on: motor_open
    - switch.turn_off: motor_close
    - switch.turn_on: door_open
    - switch.turn_off: door_closed
  open_duration: 10s
  close_action:  # move logic out of the cover. this has no effect
    - switch.turn_on: motor_close
    - switch.turn_off: motor_open
    - switch.turn_on: door_closed
    - switch.turn_off: door_open
  close_duration: 10s
  stop_action:
      - switch.turn_off: motor_close
      - switch.turn_off: motor_open

i2c:
  sda: 21
  scl: 22
  scan: false
  id: bus_a
# frequency: 100kHz

apds9960:
  address: 0x39
  update_interval: 60s
  gesture_led_drive: 50mA

sensor:
  - platform: template
    name: "Rabbits in the Hutch"
    id: rabbit_sensor
    lambda: |-
      {return id(inhabitants).state;}

binary_sensor:
  - platform: apds9960
    # Rabbit enters the hutch
    direction: UP
    name: "Rabbit has entered the hutch"
    on_press:
      - if:
          condition:
            - switch.is_on: door_open
          then:
            - number.increment:
                id: inhabitants
                cycle: false

  - platform: apds9960
    direction: DOWN
    name: "Rabbit has left the hutch"
    on_press:
      - if:
          condition:
            - switch.is_on: door_open
          then:
            - number.decrement:
                id: inhabitants
                cycle: false
time:
  - platform: sntp
    id: sntp_time
    timezone: Europe/Sofia
    servers:
     - 0.pool.ntp.org
     - 1.pool.ntp.org
     - 2.pool.ntp.org

    on_time:
    - seconds: 0
      minutes: 30
      hours: 7
# in the monrning
      days_of_week: MON-SUN
      then:
        - switch.turn_on: door_open
        - switch.turn_off: door_closed

    - seconds: 0
      minutes: 0
      hours: 18
      days_of_week: MON-SUN
# in the evening
      then:
        - switch.turn_on: door_should_close

sun:
  latitude: 48.09009° 
  longitude: 11.96109°

  on_sunrise:
    - then:
        - switch.turn_on: door_open
        - switch.turn_off: door_closed

  on_sunset:
    - then:
        - switch.turn_on: door_should_close

