esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
290 stars 34 forks source link

Feedback Cover close_endstop -> off do not change cover to open #5425

Open luzik opened 7 months ago

luzik commented 7 months ago

The problem

When Feedback Cover have configured close_endstop, cover is closed and then close_endstop change it's state to OFF without opening cover with ESP (for example manual open or even bad guys brake in) - Home Assistant still reporting closed state.

Other HomeAssistant Cover backends with close_endstop sensor in this situation changes it's position to 1%. 1% is used also in other situations ex. when close_endstop is configured, we are closing but close_endstop not changing it's state to ON, so the user know that in this situation position is unknown but for sure cover is open and this is quite important information - even involving home security.

Which version of ESPHome has the issue?

2023.12.8

What type of installation are you using?

Docker

Which version of Home Assistant has the issue?

2024.1

What platform are you using?

ESP8266

Board

No response

Component causing the issue

Feedback Cover

Example YAML snippet

globals:
  - id: global_last_direction
    type: int
    restore_value: yes
    initial_value: '99'
    # 1=opened, 2=closed, 99=initial value
  - id: global_last_operation
    type: esphome::cover::CoverOperation
    restore_value: yes
    initial_value: CoverOperation::COVER_OPERATION_IDLE
    # 1= previous operation was opening, 2=closing, 0=idle

switch:
  - platform: gpio
    id: relay
    name: Relay
    disabled_by_default: true
    pin: GPIO12
    restore_mode: ALWAYS_OFF
    on_turn_on:
      - logger.log: "***********    RELAY   **************"
      - delay: 200ms
      - switch.turn_off: relay

binary_sensor:
  - platform: gpio
    id: close_endstop
    name: Close endstop
    disabled_by_default: true
    pin:
      number: GPIO13
      mode:
        input: true
        pullup: true
      inverted: true
    filters:
      - delayed_on: 20ms
    on_press:
      then:
        - logger.log: "***********    CLOSED   **************"
    on_release:
      then:
        - logger.log: "***********    NOT CLOSED   **************"
        - if:
            condition:
              and:
                - lambda: |-
                    return id(gate).current_operation == CoverOperation::COVER_OPERATION_IDLE;
                - lambda: |-
                    return id(gate).position == COVER_CLOSED;
            then:
              - cover.control:
                  id: gate
                  position: 1%
  - platform: gpio
    id: click
    name: Button Click
    disabled_by_default: true
    pin:
      number: GPIO0
      mode:
        input: true
      inverted: true
    filters:
      - delayed_on: 20ms
    on_press:
      then:
        - logger.log: "***********    BUTTON   **************"
        - cover.toggle: gate

cover:
  - platform: feedback
    name: "Brama"
    device_class: garage
    id: gate
    assumed_state: false
    has_built_in_endstop: true
    max_duration: 30s
    open_duration: 22s
    close_duration: 19s
    direction_change_wait_time: 500ms
    acceleration_wait_time: 300ms
    open_action:
      - if:
          condition:
              lambda: |-
                return id(global_last_operation) != CoverOperation::COVER_OPERATION_IDLE;
          then:
            - cover.stop: gate
      - if:
          condition:
              lambda: |-
                return id(global_last_direction) == CoverOperation::COVER_OPERATION_OPENING;
          then:
            - switch.turn_on: relay
            - delay: 400ms
            - switch.turn_on: relay
            - delay: 400ms
            - lambda: |-
                id(global_last_direction) = CoverOperation::COVER_OPERATION_CLOSING;
      - if:
          condition:
            and:
              - lambda: |-
                  return id(global_last_direction) != CoverOperation::COVER_OPERATION_OPENING;
              - lambda: |-
                  return id(global_last_operation) == CoverOperation::COVER_OPERATION_IDLE;
          then:
            - switch.turn_on: relay
            - lambda: |-
                id(global_last_direction) = CoverOperation::COVER_OPERATION_OPENING;
                id(global_last_operation) = CoverOperation::COVER_OPERATION_OPENING;
            - logger.log: "***********    OPENING   **************"
          else:
            - logger.log: "***********    OPENING ABORTED  **************"
            - lambda: |-
                ESP_LOGD("custom", "global_last_direction=%d, Idle=%d, Opening=%d, Closing=%d", id(global_last_direction), CoverOperation::COVER_OPERATION_IDLE, CoverOperation::COVER_OPERATION_OPENING, CoverOperation::COVER_OPERATION_CLOSING);
                ESP_LOGD("custom", "global_last_operation=%d, Idle=%d, Opening=%d, Closing=%d", id(global_last_operation), CoverOperation::COVER_OPERATION_IDLE, CoverOperation::COVER_OPERATION_OPENING, CoverOperation::COVER_OPERATION_CLOSING);

    on_open:
      - lambda: |-
          id(global_last_direction) = CoverOperation::COVER_OPERATION_OPENING;
          id(global_last_operation) = CoverOperation::COVER_OPERATION_IDLE;
      - logger.log: "***********    OPENED    **************"

    close_action:
      - if:
          condition:
              lambda: |-
                return id(global_last_operation) != CoverOperation::COVER_OPERATION_IDLE;
          then:
            - cover.stop: gate
      - if:
          condition:
              lambda: |-
                return id(global_last_direction) == CoverOperation::COVER_OPERATION_CLOSING;
          then:
            - switch.turn_on: relay
            - delay: 400ms
            - switch.turn_on: relay
            - delay: 400ms
            - lambda: |-
                id(global_last_direction) = CoverOperation::COVER_OPERATION_OPENING;
      - if:
          condition:
            and:
              - lambda: |-
                  return id(global_last_direction) != CoverOperation::COVER_OPERATION_CLOSING;
              - lambda: |
                  return id(global_last_operation) == CoverOperation::COVER_OPERATION_IDLE;
          then:
            - switch.turn_on: relay
            - lambda: |-
                id(global_last_direction) = CoverOperation::COVER_OPERATION_CLOSING;
                id(global_last_operation) = CoverOperation::COVER_OPERATION_CLOSING;
            - logger.log: "***********    CLOSING   **************"
          else:
            - logger.log: "***********    CLOSING ABORTED  **************"
            - lambda: |-
                ESP_LOGD("custom", "global_last_direction=%d, Idle=%d, Opening=%d, Closing=%d", id(global_last_direction), CoverOperation::COVER_OPERATION_IDLE, CoverOperation::COVER_OPERATION_OPENING, CoverOperation::COVER_OPERATION_CLOSING);
                ESP_LOGD("custom", "global_last_operation=%d, Idle=%d, Opening=%d, Closing=%d", id(global_last_operation), CoverOperation::COVER_OPERATION_IDLE, CoverOperation::COVER_OPERATION_OPENING, CoverOperation::COVER_OPERATION_CLOSING);
    close_endstop: close_endstop
    on_closed:
      - lambda: |-
          id(global_last_direction) = CoverOperation::COVER_OPERATION_CLOSING;
          id(global_last_operation) = CoverOperation::COVER_OPERATION_IDLE;
      - logger.log: "***********    CLOSED   **************"
    stop_action:
      - if:
          condition:
            lambda: |-
                  return id(global_last_operation) != CoverOperation::COVER_OPERATION_IDLE;
          then:
            - switch.turn_on: relay
            - lambda: |-
                id(global_last_operation) = CoverOperation::COVER_OPERATION_IDLE;
            - logger.log: "***********    STOPPED   **************"

          else:
            - logger.log: "***********    STOPPED ABORTED  **************"
            - lambda: |-
                ESP_LOGD("custom", "global_last_direction=%d, Idle=%d, Opening=%d, Closing=%d", id(global_last_direction), CoverOperation::COVER_OPERATION_IDLE, CoverOperation::COVER_OPERATION_OPENING, CoverOperation::COVER_OPERATION_CLOSING);
                ESP_LOGD("custom", "global_last_operation=%d, Idle=%d, Opening=%d, Closing=%d", id(global_last_operation), CoverOperation::COVER_OPERATION_IDLE, CoverOperation::COVER_OPERATION_OPENING, CoverOperation::COVER_OPERATION_CLOSING);

esp8266:
  board: esp8285

Anything in the logs that might be useful for us?

No response

Additional information

No response

Geo-Ron commented 5 months ago

I observe the same behaviour. EspHome 2024.4.0 - HomeAssistant 2024.4.3.

Is your workaround functional?

luzik commented 5 months ago

Yeah it's quite robust, but it is written for one button control

gabbiani commented 1 month ago

Same here. Feedback cover with single sensor for closed. I'm going to borrow your example and see if that works for me, but I find it odd that this basic setup doesn't work as expected.

Edit, I've been hacking away at the example for a couple of hours and I can't get it to work right. Works fine when controlled from homeassistant/esphome. But when I use the physical button the door starts opening, the reed switch opens, esp sets cover to 1% and then it fires the relay a couple of times in the opening and a stop sequence. Door stops moving an inch above closed.