Sliding Window Control with Linear Actuator [HELP]

Hi Everyone,

A few years ago I did this project to automate my backyard window so my dog can go out whenever I’m not home. this was done with ESPHOME and I compiled it to a bin file but unfortunately, I can’t find the YAML file which held all the config. At this opportunity, I wanted to make some enhancements which I realized is super important – currently, my solution doesn’t have a safety mechanism in case my dog is trying to enter or leave the house once the door is CLOSING, one time she almost got caught in the window and ever since I’m a bit traumatized (I always check the security camera before any action, but I don’t think that’s enough).

My goal now is to use a motion sensor that will constantly monitor the door to see if my dog is nearby, if the door is closing and the motion is triggered, I want the window to completely open and wait for a while until it is safe before continue to close the window.

I’m not sure how to start this as my YAML skills are not that great, I’m looking for some guidance on the logic that is required to make this happen (I believe that this can be achieved within the “cover” section?)

this is what I got so far (not tested, just want to know if I’m in the right track first and the logic makes sense):

btw: I tried to mix some information from few sources (the code for the actuator was from DrZZZ which works great, and i tried to add the motion part from kdorff/distance-sensor

##############################---NELLA DOOR OPENER---#######################################
esphome:
  name: nella_door_controller
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: !secret ssid
  password: !secret ssid_pwd

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

output:
  - platform: gpio
    id: 'win_1'
    pin: D1
  - platform: gpio
    id: 'win_2'
    pin: D2

switch:
  - platform: output
    name: "win1"
    output: 'win_1'
    id: win1
  - platform: output
    name: "win2"
    output: 'win_2'
    id: win2

cover:
  - platform: template
    name: "Nella Window Controller"
    id: win_open
    optimistic: true
    open_action:
      - switch.turn_off: win2
      - switch.turn_on: win1
      - delay: 50s
      - switch.turn_off: win1
    close_action:
      - switch.turn_off: 
      - condition: state
          entity_id: sensor.breakbeam_sensor_dist
          ### maybe we need a while loop? to constantly check if the beam is not broken while closing the window?
          state: "off"
          - switch.turn_on: win2
          - delay: 50s
          - switch.turn_off: win2
    stop_action:
      - switch.turn_off: win1
      - switch.turn_off: win2
     
binary_sensor:
  - platform: gpio
    pin: D3
    name: "Nella Window Control Button"
    filters:
      invert:
    on_press: 
      then:
        - lambda: |
            if (id(win_open).state == cover::COVER_OPEN) {
              if (id(win1).state){
                // window is opening
                id(win_open).stop();
              } else {
                // window is open and not moving
                if (id(breakbeam_sensor).state == true)
                  id(win_open).open();
                else
                  id(win_open).close();
              }
            } else {
              if (id(win2).state){
                // window is closing
                id(win_open).stop();
              } else {
                // win is closed and not moving
                id(win_open).open();
              }
            }
sensor:
  - name: "PIR Sensor"
    id: breakbeam_sensor_dist
    platform: vl53l0x
    address: 0x29
    update_interval: 0.1s
    long_range: true
    internal: true
    # Only send a value back if breakbeam_sensor changes.
    filters:
      - lambda: !lambda |-
          static double minTripDistance = 0.55;
          if (x <= minTripDistance) {
            if (id(breakbeam_sensor).state == true) {
              // Beam was already broken
              return {};
            }
            // Beam was just broken
            id(breakbeam_sensor_top).publish_state(true);
            ESP_LOGI("breakbeam_sensor_dist", "Set breakbeam_sensor to Detected");
            return {};
          }
          else {
            if (id(breakbeam_sensor_top).state == false) {
              // Beam was already un-broken
              return {};
            }
            // Beam was just un-broken
            id(breakbeam_sensor_top).publish_state(false);
            ESP_LOGI("breakbeam_sensor_dist", "Set breakbeam_sensor_top to Cleared");
            return {};
          } 

Your set-up isn’t that clear to me. Photo’s might help.

Am I reading right that the motion sensor is actually a time of flight distance sensor that is monitoring for something passing through the window?

What I’d basically be looking to do is create a binary sensor called “dog_detected” (based on the TOF sensor if need be) and then use a on_press action on that to drive some conditional actions (if closing, then open > wait > close).

Hi @Mahko_Mahko,

Thanks for the quick response.
I guess my main focus would be the cover, looking for the logic and syntax if possible for the following:

  1. if I press the close button: check that no motion before, if there is motion do nothing
  2. if I press the close button: door is closing, while constantly monitoring for motion, if there is motion, open the door completely, then wait for a while before re-attempting to close
  3. the door needs to remain close even if there is motion when no button is pressed

not sure how to address this:

cover:
  - platform: template
    name: "Nella Window Controller"
    id: win_open
    optimistic: true
    open_action:
      - switch.turn_off: win2
      - switch.turn_on: win1
      - delay: 50s
      - switch.turn_off: win1
    close_action:
      - while:
          condition: {lambda: "while (binary_sensor.pir_sensor)"}
          then:
      # - condition: state
          # entity_id: sensor.breakbeam_sensor_dist
          ### maybe we need a while loop? to constantly check if the beam is not broken while closing the window?
          # state: "off"
          - switch.turn_on: win2
          - delay: 50s
          - switch.turn_off: win2
    stop_action:
      - switch.turn_off: win1
      - switch.turn_off: win2