I am using one button to both start and stop a motor. If pressed when the motor is stopped, then I need it to start. But if pressed when the motor is started, then I need it to stop.
This motor controls a cover, so I’m using the Template Cover component as well.
To figure out if the motor is stopped or not, I’m using this lambda in an if statement in a binary_sensor:
lambda: 'return (id(ropener_cover).current_operation != COVER_OPERATION_IDLE);'
This should allow me to know if the motor is not idle. And if not idle, then stop. However, it does not work, it never evaluates to true and skips this step and I have no idea what I’m doing wrong. The reference I"m going off of for this is here and here.
The full YAML is below. The line above is in the binary_sensor section, about half way down. Thank you!!!
external_components:
- source: github://slimcdk/esphome-custom-components
components: [tmc2209_hub, tmc2209, stepper]
substitutions:
steps_per_revolution: "1600"
max_distance_revs: "float(231.9207)"
max_distance_steps: "${max_distance_revs}*${steps_per_revolution}"
api:
ota:
- platform: esphome
logger:
level: VERBOSE
esp32:
board: esp32-c6-devkitc-1
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
esphome:
name: glasscalibur
on_boot:
then:
- tmc2209.configure:
direction: cw
microsteps: 8
interpolation: true
- tmc2209.stallguard:
threshold: 50
- tmc2209.currents:
standstill_mode: freewheeling
irun: 26
ihold: 0
tpowerdown: 0
iholddelay: 0
- if:
condition:
binary_sensor.is_off: limit_switch_1 # Check if switch is pressed
then:
- stepper.report_position:
id: driver
position: !lambda return ${max_distance_steps};
- if:
condition:
binary_sensor.is_off: limit_switch_2 # Check if switch is pressed
then:
- stepper.report_position:
id: driver
position: 0
uart:
tx_pin: 1
rx_pin: 0
baud_rate: 500000
stepper:
- platform: tmc2209
id: driver
max_speed: 1500 steps/s
acceleration: 1000 steps/s^2
deceleration: 100000 steps/s^2
config_dump_include_registers: true
rsense: 220 mOhm
vsense: False
enn_pin: 8
index_pin: 6
diag_pin: 14
on_stall:
- stepper.stop: driver
# id(ropener_cover)->current_operation
# COVER_OPERATION_IDLE, COVER_OPERATION_OPENING, COVER_OPERATION_CLOSING
binary_sensor:
- platform: gpio
name: Button 1
id: btn1
pin:
number: 23
mode: INPUT
inverted: true
filters:
- delayed_on: 10ms
on_multi_click:
# --- Single Click ---
- timing:
- ON for at most 1.0s
- OFF for at least 0.5s
then:
- if:
condition: ## If moving, then stop
lambda: 'return (id(ropener_cover).current_operation != COVER_OPERATION_IDLE);' # Should evaluate to TRUE if moving
then:
- cover.stop: ropener_cover
else: ## If not moving, then close
- cover.close: ropener_cover
# --- Double Click ---
- timing:
- ON for at most 1.0s
- OFF for at most 0.3s
- ON for at most 1.0s
- OFF for at least 0.5s
then:
- cover.open: ropener_cover
- platform: gpio
name: Open Limit Switch
id: limit_switch_1
pin:
number: 15
mode: INPUT
inverted: true
on_press:
then:
- stepper.report_position:
id: driver
position: 0
- cover.stop: ropener_cover
- platform: gpio
name: Close Limit Switch
id: limit_switch_2
pin:
number: 3
mode: INPUT
inverted: true
on_press:
then:
- stepper.report_position:
id: driver
position: !lambda return ${max_distance_steps};
- cover.stop: ropener_cover
cover:
- platform: template
id: ropener_cover
name: Ropener
has_position: true
assumed_state: false
lambda: "return 1.0 - (id(driver)->current_position / ${max_distance_steps});"
stop_action:
- stepper.stop: driver
open_action:
- stepper.set_target:
id: driver
target: 0
close_action:
- stepper.set_target:
id: driver
target: !lambda return ${max_distance_steps};
position_action:
- stepper.set_target:
id: driver
target: !lambda return (1.0 - pos) * ${max_distance_steps};```