Skip to content

Instantly share code, notes, and snippets.

@rubin110
Created July 29, 2023 01:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rubin110/c078a82283a22ee05974e276ca332b8e to your computer and use it in GitHub Desktop.
Save rubin110/c078a82283a22ee05974e276ca332b8e to your computer and use it in GitHub Desktop.
ESPHome blinds with a stepper motor
# ESPHome config to control veneitan style blinds where a stepper motor has been attached to the spinning rod that lits the blinds one direction or other.
# 3D printed model by sidoh:
# https://www.printables.com/model/22186-retrofitted-motor-mount-for-blinds-automation
# Cobble a bunch of code from the designer's config:
# https://github.com/sidoh/esphome/tree/master
# This is setup to use a ULN2003 driver. Also a bit of modification because saving the end_posotion
# value didn't make sense.
#
# If it's not clear, this device is setup with 2 steppers for 2 different sets of blinds, left and right
# Please pay attention to which direction your stepper motor is turning during the intial config
# so you don't accidentally snap any wires.
#
# To configure start and stop position first begin by setting the blinds to the close posotion.
# You can do this by calling the HA servce control_stepper. You can use negative values. For my
# steppers 2048 steps is a full turn. Once at the closed position
# call the service set_closed_position to set the current step value to zero/origin.
# Use control_stepper again to get the blinds to what you would like to be as an option position.
# You can again use nagtive values if needed.
# Now use set_open_position to save to memory the numbers of steps from 0 to be decalred as fully open.
# And that should be it. Values will get saved to flash and should be restored on restart.
substitutions:
device_name: "sunroom-blinds"
friendly_name: "Sunroom Blinds"
project_name: "blinds"
device_description: "blinds"
project_version: "1.0"
relay_restore_mode: RESTORE_DEFAULT_OFF
platform_name: esp8285
board_name: esp01_1m
left_end_position: '0'
right_end_position: '0'
esp8266:
early_pin_init: false
restore_from_flash: true
packages:
device_base: !include common/device_base.yaml
interval:
- interval: 5s
then:
- logger.log:
format: "Left stepper_position: %d"
args: [ 'id(left_stepper_position)' ]
- logger.log:
format: "Left current_position : %d"
args: [ 'id(left_blinds_stepper).current_position' ]
- logger.log:
format: "Left end_position: %d"
args: [ 'id(left_end_position)' ]
- logger.log:
format: "Right stepper_position: %d"
args: [ 'id(right_stepper_position)' ]
- logger.log:
format: "Right current_position : %d"
args: [ 'id(right_blinds_stepper).current_position' ]
- logger.log:
format: "Right end_position: %d"
args: [ 'id(right_end_position)' ]
esphome:
name: $device_name
on_boot:
then:
- stepper.report_position:
id: left_blinds_stepper
position: !lambda return id(left_stepper_position);
- stepper.set_target:
id: left_blinds_stepper
target: !lambda return id(left_stepper_position);
- if:
condition:
- lambda: 'return id(left_stepper_position) == 0;'
then:
- cover.template.publish:
id: left_blinds
state: Closed
current_operation: IDLE
else:
- cover.template.publish:
id: left_blinds
state: Open
current_operation: IDLE
- stepper.report_position:
id: right_blinds_stepper
position: !lambda return id(right_stepper_position);
- stepper.set_target:
id: right_blinds_stepper
target: !lambda return id(right_stepper_position);
- if:
condition:
- lambda: 'return id(right_stepper_position) == 0;'
then:
- cover.template.publish:
id: right_blinds
state: Closed
current_operation: IDLE
else:
- cover.template.publish:
id: right_blinds
state: Open
current_operation: IDLE
preferences:
flash_write_interval: 0s
globals:
- id: left_stepper_position
type: int
restore_value: true
initial_value: '0'
- id: left_end_position
type: int
restore_value: true
initial_value: '${left_end_position}'
- id: right_stepper_position
type: int
restore_value: true
initial_value: '0'
- id: right_end_position
type: int
restore_value: true
initial_value: '${right_end_position}'
stepper:
- platform: uln2003
id: left_blinds_stepper
pin_a: 5
pin_b: 4
pin_c: 0
pin_d: 2
max_speed: 512 steps/s
# Optional:
acceleration: inf
deceleration: inf
sleep_when_done: true
- platform: uln2003
id: right_blinds_stepper
pin_a: 14
pin_b: 12
pin_c: 13
pin_d: 15
max_speed: 512 steps/s
# Optional:
acceleration: inf
deceleration: inf
sleep_when_done: true
cover:
- platform: template
id: left_blinds
device_class: blind
name: "${friendly_name} Left"
open_action:
- logger.log:
format: "Left OPEN called. Stepper position is set to: %d"
args: [ 'id(left_stepper_position)' ]
- stepper.set_target:
id: left_blinds_stepper
target: !lambda return id(left_end_position);
- globals.set:
id: left_stepper_position
value: !lambda return id(left_end_position);
close_action:
- logger.log:
format: "Left CLOSE called. Stepper position is set to: %d"
args: [ 'id(left_stepper_position)' ]
- stepper.set_target:
id: left_blinds_stepper
target: 0
- globals.set:
id: left_stepper_position
value: '0'
stop_action:
- stepper.set_target:
id: left_blinds_stepper
target: !lambda return id(left_blinds_stepper).current_position;
- globals.set:
id: left_stepper_position
value: !lambda return id(left_blinds_stepper).current_position;
optimistic: true
- platform: template
id: right_blinds
device_class: blind
name: "${friendly_name} Right"
open_action:
- logger.log:
format: "Right OPEN called. Stepper position is set to: %d"
args: [ 'id(right_stepper_position)' ]
- stepper.set_target:
id: right_blinds_stepper
target: !lambda return id(right_end_position);
- globals.set:
id: right_stepper_position
value: !lambda return id(right_end_position);
close_action:
- logger.log:
format: "Right CLOSE called. Stepper position is set to: %d"
args: [ 'id(right_stepper_position)' ]
- stepper.set_target:
id: right_blinds_stepper
target: 0
- globals.set:
id: right_stepper_position
value: '0'
stop_action:
- stepper.set_target:
id: right_blinds_stepper
target: !lambda return id(right_blinds_stepper).current_position;
- globals.set:
id: right_stepper_position
value: !lambda return id(right_blinds_stepper).current_position;
optimistic: true
api:
services:
- service: left_set_closed_position
then:
- stepper.report_position:
id: left_blinds_stepper
position: 0
- stepper.set_target:
id: left_blinds_stepper
target: 0
- globals.set:
id: left_stepper_position
value: '0'
- service: left_set_open_position
then:
- stepper.report_position:
id: left_blinds_stepper
position: !lambda return id(left_stepper_position);
- stepper.set_target:
id: left_blinds_stepper
target: !lambda return id(left_stepper_position);
- globals.set:
id: left_end_position
value: !lambda return id(left_stepper_position);
- service: left_control_stepper
variables:
target: int
then:
- stepper.set_target:
id: left_blinds_stepper
target: !lambda 'return target;'
- globals.set:
id: left_stepper_position
value: !lambda return target;
- service: right_set_closed_position
then:
- stepper.report_position:
id: right_blinds_stepper
position: 0
- stepper.set_target:
id: right_blinds_stepper
target: 0
- globals.set:
id: right_stepper_position
value: '0'
- service: right_set_open_position
then:
- stepper.report_position:
id: right_blinds_stepper
position: !lambda return id(right_stepper_position);
- stepper.set_target:
id: right_blinds_stepper
target: !lambda return id(right_stepper_position);
- globals.set:
id: right_end_position
value: !lambda return id(right_stepper_position);
- service: right_control_stepper
variables:
target: int
then:
- stepper.set_target:
id: right_blinds_stepper
target: !lambda 'return target;'
- globals.set:
id: right_stepper_position
value: !lambda return target;
button:
# - platform: template
# name: "${friendly_name} Rotate Right 0.25 turn"
# id: rotate_right_025
# on_press:
# # Move 150 steps forward
# - stepper.report_position:
# id: stepper_motor_left
# position: 0
# - stepper.set_target:
# id: stepper_motor_left
# target: -512
# - platform: template
# name: "${friendly_name} Rotate Right 0.5 turn"
# id: rotate_right_050
# on_press:
# # Move 150 steps forward
# - stepper.report_position:
# id: stepper_motor_left
# position: 0
# - stepper.set_target:
# id: stepper_motor_left
# target: -1024
# - platform: template
# name: "${friendly_name} Left 1 Turn Close"
# id: rotate_left_1_turn_right
# on_press:
# # Move 150 steps forward
# - stepper.report_position:
# id: stepper_motor_left
# position: 0
# - stepper.set_target:
# id: stepper_motor_left
# target: -2048
# - platform: template
# name: "${friendly_name} Rotate Left 0.25 turn"
# id: rotate_left_025
# on_press:
# # Move 150 steps forward
# - stepper.report_position:
# id: stepper_motor_left
# position: 0
# - stepper.set_target:
# id: stepper_motor_left
# target: 512
# - platform: template
# name: "${friendly_name} Rotate Left 0.5 turn"
# id: rotate_left_050
# on_press:
# # Move 150 steps forward
# - stepper.report_position:
# id: stepper_motor_left
# position: 0
# - stepper.set_target:
# id: stepper_motor_left
# target: 1024
# - platform: template
# name: "${friendly_name} Left 1 Turn Open"
# id: rotate_left_1_turn_left
# on_press:
# # Move 150 steps forward
# - stepper.report_position:
# id: stepper_motor_left
# position: 0
# - stepper.set_target:
# id: stepper_motor_left
# target: 2048
# - platform: template
# name: "${friendly_name} Right 1 Turn Close"
# id: other_rotate_right_1_turn_right
# on_press:
# # Move 150 steps forward
# - stepper.report_position:
# id: stepper_motor_right
# position: 0
# - stepper.set_target:
# id: stepper_motor_right
# target: -2048
# - platform: template
# name: "${friendly_name} Right 1 Turn Open"
# id: other_rotate_right_1_turn_left
# on_press:
# # Move 150 steps forward
# - stepper.report_position:
# id: stepper_motor_right
# position: 0
# - stepper.set_target:
# id: stepper_motor_right
# target: 2048
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment