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: -100 then: - number.set: id: endstop_open value: !lambda "return id(endstop_open_global);" - number.set: id: endstop_closed value: !lambda "return id(endstop_close_global);" - number.set: id: calibration_max value: !lambda "return id(calibration_max_global);" globals: - id: hall_pos_global type: int restore_value: True initial_value: '0' - id: endstop_open_global type: int restore_value: True initial_value: '0' - id: endstop_close_global type: int restore_value: True initial_value: '0' - id: calibration_max_global type: int restore_value: True initial_value: '250' number: - platform: template id: endstop_open min_value: -50 max_value: 50 step: 1 name: endstop open optimistic: true on_value: then: - globals.set: id: endstop_open_global value: !lambda "return x;" - logger.log: "endstop open stored" - platform: template id: endstop_closed min_value: -50 max_value: 50 step: 1 name: enstop closed optimistic: true on_value: then: - globals.set: id: endstop_close_global value: !lambda "return x;" - logger.log: "endstop open stored" - platform: template id: calibration_max min_value: 0 max_value: 1000 step: 1 name: calibration max optimistic: true on_value: then: - globals.set: id: calibration_max_global value: !lambda "return x;" - logger.log: "calirbation max stored" - platform: template name: Stepper Control min_value: -100 max_value: 100 step: 1 set_action: then: - stepper.set_target: id: stepper_motor target: !lambda 'return x;' sensor: - 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 = id(hall_pos_global); 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); stepper: - platform: a4988 id: stepper_motor step_pin: ${pin_mot_stp} dir_pin: ${pin_mot_dir} max_speed: 200 sleep_pin: ${pin_mot_slp} acceleration: inf deceleration: inf button: - platform: template id: Calibrate_blinds name: Calibrate blinds on_press: # reset all params - globals.set: id: hall_pos_global value: "0" #tell stepper that he is in the middle - stepper.report_position: id: stepper_motor position: !lambda "return uint32_t(id(calibration_max));" # It's best to call set_target directly after report_position, so that the stepper doesn't move - stepper.set_target: id: stepper_motor target: !lambda "return uint32_t(id(calibration_max));" #calibrate closed_endstop - stepper.set_target: id: stepper_motor target: 0 - while: condition: lambda: 'return id(hall_pos_global) > -10;' then: - logger.log: format: "hal pos = %i; stepper pos = %i" args: [id(hall_pos_global), id(stepper_motor).current_position] # 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