substitutions: device_name: "dcds3blinds" friendly_name: "blinds" comment: "esp32-S3, motor, led" location: "speelkamer" api_password: !secret stepper_api ota_password: !secret ota_password wifi_ssid: !secret wifi_ssid wifi_password: !secret wifi_password gateway: !secret ip_gateway subnet: !secret ip_subnet ip: !secret stepper_ip update_interval: 30s pin_mot_rst: GPIO26 pin_mot_slp: GPIO33 pin_mot_dir: GPIO38 pin_mot_stp: GPIO34 pin_mot_en: GPIO21 pin_hall_dir: GPIO39 pin_hall_stp: GPIO40 pin_sda: GPIO15 pin_scl: GPIO14 pin_led1: GPIO45 num_leds: "1" chipset: ws2812 blinds_name: speelkamer packages: board: !include boards/esp32-S3a.yaml device_base: !include common/common.yaml connection: !include common/wifi.yaml logger: !include templates/logger.yaml #leds: !include templates/light_rgbw_rmt.yaml i2c: !include interfaces/i2c_a.yaml bme: !include sensors/bme280.yaml light: !include sensors/light_tsl2591.yaml api: services: - service: control_stepper variables: target: int then: - stepper.set_target: id: stepper_motor target: !lambda 'return target;' esphome: on_boot: - priority: -200.0 then: # - stepper.report_position: # Set stepper to global variable # id: stepper_motor # position: !lambda return id(stepper_motor_global); # - stepper.set_target: # Set stepper to global variable # id: stepper_motor # target: !lambda return id(stepper_motor_global); # # - sensor.template.publish: # # id: motor_hal # # state: !lambda return id(hall_pos_global); # - if: # If blind is Closed # condition: # - lambda: 'return id(stepper_motor_global) == 0;' # then: # Publish state etc. # - cover.template.publish: # id: ${blinds_name} # state: CLOSED # current_operation: IDLE # - if: # If blind is Open # condition: # - lambda: 'return id(stepper_motor_global) == id(endstop).state;' # then: # Publish state etc. # - cover.template.publish: # id: ${blinds_name} # state: OPEN # current_operation: IDLE # - if: # If blind is Neither # condition: # - lambda: 'return (id(stepper_motor_global) != 0) && (id(stepper_motor_global) != id(endstop).state);' # then: # # Publish state etc. # - cover.template.publish: # id: ${blinds_name} # position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));' # current_operation: IDLE globals: # - id: stepper_motor_global # Integer for storing the stepper position in case of reboot # type: int # restore_value: True # initial_value: '0' # - id: openclosed # Boolean to store OPEN/CLOSED state # type: bool # restore_value: True # initial_value: '0' - id: hall_pos_global type: int restore_value: True initial_value: '0' - id: hall_pos_old type: int restore_value: False initial_value: '0' sensor: # - platform: template # id: stepper_pos # name: stepper_pos - platform: template id: motor_hal name: motor_hal binary_sensor: - platform: gpio pin: number: ${pin_hall_dir} mode: input: true pullup: true # inverted: true id: halldirection name: "sensor direction" - platform: gpio pin: number: ${pin_hall_stp} mode: input: true pullup: true id: hallpulse name: "sensor pulse" on_release: - then: - lambda: |- static int motorvalue; if(id(halldirection).state){ motorvalue += 1; } else{ motorvalue -= 1; } id(motor_hal).publish_state(motorvalue); id(hall_pos_global) = motorvalue; ESP_LOGD("on sensor", "motor hall: %d", motorvalue); # number: # - platform: template # name: endstop Control # id: endstop # min_value: 0 # max_value: 2000 # step: 1 # mode: slider # unit_of_measurement: steps # restore_value: True # optimistic: True stepper: - platform: a4988 id: stepper_motor step_pin: ${pin_mot_stp} dir_pin: ${pin_mot_dir} max_speed: 200 # Optional: sleep_pin: ${pin_mot_slp} acceleration: inf deceleration: inf cover: - platform: template name: Dining Room Blinds id: ${blinds_name} open_action: then: - logger.log: "Opening" - stepper.set_target: id: stepper_motor target: 750 - while: condition: lambda: 'return id(stepper_motor).current_position < id(endstop).state;' then: - cover.template.publish: id: ${blinds_name} position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));' current_operation: OPENING - delay: 1000 ms - globals.set: # Set global to current position id: stepper_motor_global value: !lambda return id(stepper_motor).current_position; - sensor.template.publish: id: stepper_pos state: !lambda return id(stepper_motor).current_position; - globals.set: # Set toggle to OPEN (No need for 'optimistic mode') id: openclosed value: '1' - cover.template.publish: id: ${blinds_name} state: OPEN current_operation: IDLE close_action: then: - logger.log: "Closing" - stepper.set_target: # Send stepper to 0 id: stepper_motor target: '0' - while: condition: lambda: 'return id(stepper_motor).current_position > 0;' then: - cover.template.publish: id: ${blinds_name} position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));' current_operation: CLOSING - delay: 1000 ms - globals.set: # Set global to current position id: stepper_motor_global value: !lambda return id(stepper_motor).current_position; - sensor.template.publish: id: stepper_pos state: !lambda return id(stepper_motor).current_position; - globals.set: # Set toggle to CLOSED (No need for 'optimistic mode') id: openclosed value: '0' - cover.template.publish: id: ${blinds_name} state: CLOSED current_operation: IDLE position_action: then: - stepper.set_target: id: stepper_motor target: !lambda return int(id(endstop).state * pos); - while: condition: lambda: 'return id(stepper_motor).current_position != int(id(endstop).state * pos);' then: - cover.template.publish: id: ${blinds_name} position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));' - delay: 1000 ms - globals.set: # Set global to current position id: stepper_motor_global value: !lambda return id(stepper_motor).current_position; - sensor.template.publish: id: stepper_pos state: !lambda return id(stepper_motor).current_position; - cover.template.publish: id: ${blinds_name} position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));' current_operation: IDLE stop_action: then: - stepper.set_target: id: stepper_motor target: !lambda return id(stepper_motor).current_position; - globals.set: # Set global to current position id: stepper_motor_global value: !lambda return id(stepper_motor).current_position; - sensor.template.publish: id: stepper_pos state: !lambda return id(stepper_motor).current_position; - cover.template.publish: id: ${blinds_name} position: !lambda 'return (float(float(id(stepper_motor).current_position) / float(id(endstop).state)));' current_operation: IDLE has_position: true device_class: blind # switch: # - platform: template # name: Reset Blinds # id: calibrate # turn_on_action: # - lambda: |- # bool stall = false; # long steps = 40; # int oldpos = id(hall_pos_global); # while(!stall) # { # id(stepper_motor).set_target(steps); # if(oldpos != id(hall_pos_global)){ # steps+=40; # }else{ # stall = true; # ESP_LOGD("reset", "end_pos1 %d", steps); # } # oldpos = id(hall_pos_global); # } # id(calibrate).publish_state(false); # //rotate to stall # - stepper.set_target: # id: stepper_motor # target: !lambda 'return id(endstop).state * 2;' # - wait_until: # lambda: 'return id(stepper_motor).current_position == id(endstop).state*2;' # - delay: 1s # - stepper.set_target: # id: stepper_motor # target: '0' # - globals.set: # Set global to current position # id: stepper_motor_global # value: !lambda return id(stepper_motor).current_position; # - sensor.template.publish: # id: stepper_pos # state: !lambda return id(stepper_motor).current_position; # - globals.set: # Set toggle to CLOSED (No need for 'optimistic mode') # id: openclosed # value: '0' # - cover.template.publish: # id: ${blinds_name} # state: CLOSED # current_operation: IDLE # - globals.set: # id: hall_pos_global # value: '0'