Cover component - Custom cover?

Hi

I’ve been at this for a couple of days. I’m trying to control my mini-blinds (venetian blinds) with a servo using Esphome. I’ve done this a few times over the years with arduino but now I’d like to do it with a Wemos D1 mini and add some functionality. I’ve used MySensors and Domoticz but now I’m considering moving to Home Assistant and Esphome.

My goal:

To have a rotary encoder that gradually moves the servo to open/close the slats while the state is reported back to HA and if the state (including position, not just OPEN/CLOSED) is changed in HA, move the servo accordingly.

Where I’m now:

I have a ton of YAML (which is NOT growing on me…) which does pretty much everyhing I just described except for the position adjustment when called from Home Assistant. Open/close works even from there.

esphome:
  name: test
  platform: ESP8266
  board: d1_mini

wifi:
  ssid: xxx
  password: xxx

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Test Fallback Hotspot"
    password: ...

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

globals:
  - id: my_pos
    type: float

     
script:
  - id: move_servo
    then:
      - servo.write:
          id: my_servo
          level: !lambda "return id(my_pos);"
      - delay: 1s
      - servo.detach: my_servo
      - cover.template.publish:
          id: pub_pos
          position: !lambda "return id(my_pos) / 2 + 0.5;"
      - logger.log:
          format: "position: %.2f"
          args: ['id(my_pos)']

sensor:
  - platform: rotary_encoder
    name: "Rotary Encoder"
    id: knob
    pin_a: D8
    pin_b: D6
    min_value: -1
    max_value: 1
    on_value:
      then:
          - lambda: !lambda |-
                if (id(my_pos) > -0.9 && id(my_pos) < 0.9) {
                id(my_pos) += id(knob).state * 0.1;
                }
                else if (id(my_pos) <= -0.9 && id(knob).state == -1 && id(my_pos) > -1) {
                id(my_pos) = -1;
                }
                else if (id(my_pos) >= 0.9 && id(knob).state == 1 && id(my_pos) < 1) {
                id(my_pos) = 1;
                }
                else if (id(my_pos) == 1 && id(knob).state == -1) {
                id(my_pos) += id(knob).state * 0.1;
                }
                else if (id(my_pos) == -1 && id(knob).state == 1) {
                id(my_pos) += id(knob).state * 0.1;
                }            
          - script.execute: move_servo
          - sensor.rotary_encoder.set_value:
              id: knob
              value: 0         


binary_sensor:
  - platform: gpio
    pin:
      number: D7
      mode: INPUT_PULLUP
    id: knob_button

    
servo:
  - id: my_servo
    output: pwm_output
    
output:
  - platform: esp8266_pwm
    id: pwm_output
    pin: D5
    frequency: 50 Hz
         
cover:
  - platform: template
    name: "Blinds"
    id: pub_pos

    open_action:
      - lambda: |-
          id(my_pos) = 1;
      - script.execute: move_servo

    close_action:     
      - lambda: |-
          id(my_pos) = -1;
      - script.execute: move_servo

    stop_action:
      - servo.detach: my_servo
    
    position_action:
      - logger.log:
          format: "position_action_position: %.2f"
          args: ['id(pub_pos).position']      
      - lambda: |-
          id(my_pos) = 2 * (id(pub_pos).position) - 1.0;
      - script.execute: move_servo

The log tells me that when a position command comes in from HA id(pub_pos) is not a float but something very large and it’s not mapped to the variable (my_pos) which would drive the servo script.

This is probably some sort of a bug in Esphome but as this is a little convoluted to write in YAML, I was wondering if anyone has made a custom cover component that writes values directly to a servo? Without going through the change global variable -> script - servo component - output component hoops?

1 Like

Got this sorted by using the variable name pos instead of id(pub_pos) in the position_action. Works now but if anyone has done a custom cover with servos before, please let me know.