Skip to content

Instantly share code, notes, and snippets.

@diabl0
Created November 18, 2023 23:47
Show Gist options
  • Save diabl0/b7375d70a71848673b43ee8cb55cd536 to your computer and use it in GitHub Desktop.
Save diabl0/b7375d70a71848673b43ee8cb55cd536 to your computer and use it in GitHub Desktop.
ESPHome Blinds
substitutions:
left_start_position: '59300'
left_end_position: '61800'
right_start_position: '56350'
right_end_position: '58400'
up_speed: '350'
down_speed: '400'
esphome:
name: blinds
friendly_name: Blinds
on_boot:
then:
- output.turn_off: lm_a
- output.turn_off: lm_b
- output.turn_off: lm_c
- output.turn_off: lm_d
- output.turn_off: rm_a
- output.turn_off: rm_b
- output.turn_off: rm_c
- output.turn_off: rm_d
- stepper.report_position:
id: left_blinds_stepper
position: !lambda return id(left_stepper_position);
- stepper.report_position:
id: right_blinds_stepper
position: !lambda return id(right_stepper_position);
- stepper.set_target:
id: left_blinds_stepper
target: !lambda return id(left_stepper_position);
- stepper.set_target:
id: right_blinds_stepper
target: !lambda return id(right_stepper_position);
- cover.template.publish:
id: left_blinds
position: !lambda 'return 1.0 - (float(float(id(left_blinds_stepper).current_position) / float(id(left_end_position))));'
current_operation: IDLE
- cover.template.publish:
id: right_blinds
position: !lambda 'return 1.0 - (float(float(id(right_blinds_stepper).current_position) / float(id(right_end_position))));'
current_operation: IDLE
globals:
- id: left_stepper_position
type: int
restore_value: true
initial_value: '0'
- id: left_start_position
type: int
restore_value: true
initial_value: '${left_start_position}'
- 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_start_position
type: int
restore_value: true
initial_value: '${right_start_position}'
- id: right_end_position
type: int
restore_value: true
initial_value: '${right_end_position}'
esp32:
board: wemos_d1_mini32
framework:
type: arduino
logger:
level: DEBUG
baud_rate: 0
captive_portal:
output:
- platform: gpio
id: lm_a
pin: D5
- platform: gpio
id: lm_b
pin: D6
- platform: gpio
id: lm_c
pin: D7
- platform: gpio
id: lm_d
pin: D8
- platform: gpio
id: rm_a
pin: D1
- platform: gpio
id: rm_b
pin: D2
- platform: gpio
id: rm_c
pin: D3
- platform: gpio
id: rm_d
pin: D4
stepper:
- platform: uln2003
id: left_blinds_stepper
pin_a: D5
pin_b: D6
pin_c: D7
pin_d: D8
step_mode: FULL_STEP
max_speed: ${up_speed}
sleep_when_done: True
acceleration: 200
deceleration: inf
- platform: uln2003
id: right_blinds_stepper
pin_a: D4
pin_b: D3
pin_c: D2
pin_d: D1
step_mode: FULL_STEP
max_speed: ${up_speed}
sleep_when_done: True
acceleration: 200
deceleration: inf
cover:
- platform: template
id: left_blinds
device_class: blind
name: "Left Blinds"
open_action:
then:
- logger.log:
format: "OPEN called. Left stepper position is set to: %d"
args: [ 'id(left_stepper_position)' ]
- stepper.set_speed:
id: left_blinds_stepper
speed: ${up_speed}
- stepper.set_target: # Send stepper to endstop
id: left_blinds_stepper
target: !lambda return 0;
- if: # If continous feedback switch is on
condition:
- lambda: 'return id(left_blinds_stepper).current_position != id(left_blinds_stepper).target_position;'
then: # with continous feedback
- while:
condition:
- lambda: 'return id(left_blinds_stepper).current_position != id(left_blinds_stepper).target_position;'
then:
- cover.template.publish:
id: left_blinds
position: !lambda 'return 1 - (float(float(id(left_blinds_stepper).current_position) / float(id(left_end_position))));'
current_operation: OPENING
- delay: 1500ms
else: # without continous feedback
- wait_until: # Wait until endstop reached
lambda: 'return (id(left_blinds_stepper).current_position == id(left_end_position));'
- globals.set:
id: left_stepper_position
value: !lambda return id(left_blinds_stepper).current_position;
- cover.template.publish:
id: left_blinds
position: !lambda 'return 1 - (float(float(id(left_blinds_stepper).current_position) / float(id(left_end_position))));'
current_operation: IDLE
close_action:
then:
- logger.log:
format: "CLOSE called. Left stepper position is set to: %d"
args: [ 'id(left_stepper_position)' ]
- stepper.set_speed:
id: left_blinds_stepper
speed: ${down_speed}
- stepper.set_target: # Send stepper to 0
id: left_blinds_stepper
target: !lambda return id(left_end_position);
- if: # If continous feedback switch is on
condition:
- lambda: 'return id(left_blinds_stepper).current_position != id(left_blinds_stepper).target_position;'
then: # with continous feedback
- while:
condition:
- lambda: 'return id(left_blinds_stepper).current_position != id(left_blinds_stepper).target_position;'
then:
- cover.template.publish:
id: left_blinds
position: !lambda 'return 1 - (float(float(id(left_blinds_stepper).current_position) / float(id(left_end_position))));'
current_operation: CLOSING
- delay: 1500ms
else: # without continous feedback
- wait_until: # Wait until endstop reached
lambda: 'return id(left_blinds_stepper).current_position == id(left_end_position);'
- globals.set:
id: left_stepper_position
value: !lambda return id(left_blinds_stepper).current_position;
- cover.template.publish:
id: left_blinds
position: !lambda 'return 1 - (float(float(id(left_blinds_stepper).current_position) / float(id(left_end_position))));'
current_operation: IDLE
stop_action:
- logger.log:
format: "STOP called. Left stepper position is set to: %d"
args: [ 'id(left_stepper_position)' ]
- 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;
- cover.template.publish:
id: left_blinds
position: !lambda 'return 1 - (float(float(id(left_blinds_stepper).current_position) / float(id(left_end_position))));'
current_operation: IDLE
- stepper.set_speed:
id: left_blinds_stepper
speed: ${up_speed}
has_position: true
position_action:
then:
- logger.log:
format: "POSITION called. Left stepper position is set from: %d to %d"
args: [ 'id(left_blinds_stepper).current_position', 'int(id(left_end_position) * (1 - pos))' ]
- stepper.set_target:
id: left_blinds_stepper
target: !lambda return int(id(left_end_position) * (1 - pos));
- if:
condition:
- lambda: 'return float(id(left_blinds_stepper).current_position) < float(id(left_blinds_stepper).target_position);'
then:
- stepper.set_speed:
id: left_blinds_stepper
speed: ${up_speed}
else:
- stepper.set_speed:
id: left_blinds_stepper
speed: ${down_speed}
- if: # If continous feedback switch is on
condition:
- lambda: 'return id(left_blinds_stepper).current_position != id(left_blinds_stepper).target_position;'
then: # with continous feedback
- while:
condition:
- lambda: 'return id(left_blinds_stepper).current_position != id(left_blinds_stepper).target_position;'
then:
- cover.template.publish:
id: left_blinds
position: !lambda 'return 1 - (float(float(id(left_blinds_stepper).current_position) / float(id(left_end_position))));'
current_operation: !lambda if ( float(id(left_blinds_stepper).current_position) > float(id(left_blinds_stepper).target_position) ) return COVER_OPERATION_OPENING; else return COVER_OPERATION_CLOSING;
- delay: 1500ms
else: # without continous feedback
- wait_until: # Wait until endstop reached
lambda: 'return id(left_blinds_stepper).current_position == (int(id(left_end_position) * pos));'
- globals.set:
id: left_stepper_position
value: !lambda return id(left_blinds_stepper).current_position;
- cover.template.publish:
id: left_blinds
position: !lambda 'return 1 - (float(float(id(left_blinds_stepper).current_position) / float(id(left_end_position))));'
current_operation: IDLE
- platform: template
id: right_blinds
device_class: blind
name: "Right Blinds"
open_action:
then:
- logger.log:
format: "OPEN called. Right stepper position is set to: %d"
args: [ 'id(right_stepper_position)' ]
- stepper.set_speed:
id: right_blinds_stepper
speed: ${up_speed}
- stepper.set_target: # Send stepper to endstop
id: right_blinds_stepper
target: !lambda return 0;
- if: # If continous feedback switch is on
condition:
- lambda: 'return id(right_blinds_stepper).current_position != id(right_blinds_stepper).target_position;'
then: # with continous feedback
- while:
condition:
- lambda: 'return id(right_blinds_stepper).current_position != id(right_blinds_stepper).target_position;'
then:
- cover.template.publish:
id: right_blinds
position: !lambda 'return 1 - (float(float(id(right_blinds_stepper).current_position) / float(id(right_end_position))));'
current_operation: OPENING
- delay: 1500ms
else: # without continous feedback
- wait_until: # Wait until endstop reached
lambda: 'return (id(right_blinds_stepper).current_position == id(right_end_position));'
- globals.set:
id: right_stepper_position
value: !lambda return id(right_blinds_stepper).current_position;
- cover.template.publish:
id: right_blinds
position: !lambda 'return 1 - (float(float(id(right_blinds_stepper).current_position) / float(id(right_end_position))));'
current_operation: IDLE
close_action:
then:
- logger.log:
format: "CLOSE called. Right stepper position is set to: %d"
args: [ 'id(right_stepper_position)' ]
- stepper.set_speed:
id: right_blinds_stepper
speed: ${down_speed}
- stepper.set_target: # Send stepper to 0
id: right_blinds_stepper
target: !lambda return id(right_end_position);
- if: # If continous feedback switch is on
condition:
- lambda: 'return id(right_blinds_stepper).current_position != id(right_blinds_stepper).target_position;'
then: # with continous feedback
- while:
condition:
- lambda: 'return id(right_blinds_stepper).current_position != id(right_blinds_stepper).target_position;'
then:
- cover.template.publish:
id: right_blinds
position: !lambda 'return 1 - (float(float(id(right_blinds_stepper).current_position) / float(id(right_end_position))));'
current_operation: CLOSING
- delay: 1500ms
else: # without continous feedback
- wait_until: # Wait until endstop reached
lambda: 'return id(right_blinds_stepper).current_position == id(right_end_position);'
- globals.set:
id: right_stepper_position
value: !lambda return id(right_blinds_stepper).current_position;
- cover.template.publish:
id: right_blinds
position: !lambda 'return 1 - (float(float(id(right_blinds_stepper).current_position) / float(id(right_end_position))));'
current_operation: IDLE
stop_action:
- logger.log:
format: "STOP called. Right stepper position is set to: %d"
args: [ 'id(right_stepper_position)' ]
- 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;
- cover.template.publish:
id: right_blinds
position: !lambda 'return 1 - (float(float(id(right_blinds_stepper).current_position) / float(id(right_end_position))));'
current_operation: IDLE
- stepper.set_speed:
id: right_blinds_stepper
speed: ${up_speed}
has_position: true
position_action:
then:
- logger.log:
format: "POSITION called. Right stepper position is set from: %d to %d"
args: [ 'id(right_blinds_stepper).current_position', 'int(id(right_end_position) * (1 - pos))' ]
- stepper.set_target:
id: right_blinds_stepper
target: !lambda return int(id(right_end_position) * (1 - pos));
- if:
condition:
- lambda: 'return float(id(right_blinds_stepper).current_position) < float(id(right_blinds_stepper).target_position);'
then:
- stepper.set_speed:
id: right_blinds_stepper
speed: ${up_speed}
else:
- stepper.set_speed:
id: right_blinds_stepper
speed: ${down_speed}
- if: # If continous feedback switch is on
condition:
- lambda: 'return id(right_blinds_stepper).current_position != id(right_blinds_stepper).target_position;'
then: # with continous feedback
- while:
condition:
- lambda: 'return id(right_blinds_stepper).current_position != id(right_blinds_stepper).target_position;'
then:
- cover.template.publish:
id: right_blinds
position: !lambda 'return 1 - (float(float(id(right_blinds_stepper).current_position) / float(id(right_end_position))));'
current_operation: !lambda if ( float(id(right_blinds_stepper).current_position) > float(id(right_blinds_stepper).target_position) ) return COVER_OPERATION_OPENING; else return COVER_OPERATION_CLOSING;
- delay: 1500ms
else: # without continous feedback
- wait_until: # Wait until endstop reached
lambda: 'return id(right_blinds_stepper).current_position == (int(id(right_end_position) * pos));'
- globals.set:
id: right_stepper_position
value: !lambda return id(right_blinds_stepper).current_position;
- cover.template.publish:
id: right_blinds
position: !lambda 'return 1 - (float(float(id(right_blinds_stepper).current_position) / float(id(right_end_position))));'
current_operation: IDLE
# Enable Home Assistant API
api:
services:
- service: left_control_stepper
variables:
target: int
then:
- logger.log:
format: "MOVE called. Left stepper position is set to: %d"
args: [ 'id(left_stepper_position)' ]
- stepper.set_target:
id: left_blinds_stepper
target: !lambda 'return target;'
- globals.set:
id: left_stepper_position
value: !lambda return target;
- service: right_control_stepper
variables:
target: int
then:
- logger.log:
format: "MOVE called. Right stepper position is set to: %d"
args: [ 'id(right_stepper_position)' ]
- stepper.set_target:
id: right_blinds_stepper
target: !lambda 'return target;'
- globals.set:
id: right_stepper_position
value: !lambda return target;
- platform: template
name: Left position
lambda: !lambda "return id(left_stepper_position);"
update_interval: 1s
filters:
- or:
- throttle: 60s
- delta: 1
- platform: template
name: Right position
lambda: !lambda "return id(right_stepper_position);"
update_interval: 1s
filters:
- or:
- throttle: 60s
- delta: 1
button:
- platform: template
name: Left fully open
id: left_fully_open
icon: "mdi:blinds-open"
on_press:
- 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'
- logger.log:
format: "SET called. Left stepper position is set to: %d"
args: [ 'id(left_stepper_position)' ]
- cover.template.publish:
id: left_blinds
position: !lambda 'return 1 - (float(float(id(left_blinds_stepper).current_position) / float(id(left_end_position))));'
current_operation: IDLE
- platform: template
name: Right fully open
id: right_fully_open
icon: "mdi:blinds-open"
on_press:
- 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'
- logger.log:
format: "SET called. Right stepper position is set to: %d"
args: [ 'id(right_stepper_position)' ]
- cover.template.publish:
id: right_blinds
position: !lambda 'return 1 - (float(float(id(right_blinds_stepper).current_position) / float(id(right_end_position))));'
current_operation: IDLE
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment