Hi, I am automating my lounge curtains using a couple of stepper motors. All is going well except for the case when I remove the power from the esp32 which is the controller(using esphome). When the power is restored the stepper doesn’t remember it’s position.
I’ve worked out I can call a service and set the target value back to what it was and all is okay then.
I’m just struggling to get the last good value from history. I guess I’d like to say, get me the last 24hours history of the entity, where the value is numeric and order it by most recent first and select the top 1.
Is the best way to do this a history node and a function node, iterating through the array?
Thanks in advance.
Just restore the last state from flash in the ESP32.
Thank you for replying. I’m struggling to find the option, I can see the option if the platform was the ESP8266, but my platform is the ESP32, do you know if it is possible to do the same with this platform? Thanks
What component do you want to restore?
E.g. template number component:
https://esphome.io/components/number/template.html#configuration-variables
Thanks again for helping Tom. I thought I’d better paste in the code from my device. I have two steppers, two stepper drivers (a4988) and one esp32. I’m trying to restore each of the stepper positions.
I’ve just tried to add the number near the top to hold the rightcurtainposition which is the thing I want restoring when the power comes back on. However, the code failed to compile saying something like it was out of scope.
esphome:
name: loungecurtains
esp32:
board: esp32dev
framework:
type: arduino
number:
- platform: template
name: "rightcurtainposition"
restore_value: yes
initial_value: 0.0
step: 1
min_value: -4500
max_value: 0
optimistic: yes
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esphome-Web-0Ec490"
password: ""
captive_portal:
# Enable logging
logger:
ota:
web_server:
port: 80
# Enable Home Assistant API
api:
services:
- service: control_rightcurtain
variables:
target: int
then:
- stepper.report_position:
id: rightcurtain
position: !lambda 'return rightcurtainposition;'
- stepper.set_target:
id: rightcurtain
target: !lambda 'return rightcurtainposition;'
- sensor.template.publish:
id: rightposition
state: !lambda 'return rightcurtainposition;'
- service: control_leftcurtain
variables:
target: int
then:
- stepper.report_position:
id: leftcurtain
position: !lambda 'return target;'
- stepper.set_target:
id: leftcurtain
target: !lambda 'return target;'
- sensor.template.publish:
id: leftposition
state: !lambda 'return target;'
cover:
- platform: template
name: "My Right Curtain"
id: my_rightcurtain
device_class: curtain
has_position: true
open_action:
- stepper.set_target:
id: rightcurtain
target: 0
- sensor.template.publish:
id: rightposition
state: !lambda return id(rightcurtain).target_position;
close_action:
- stepper.set_target:
id: rightcurtain
target: -4500
- sensor.template.publish:
id: rightposition
state: !lambda return id(rightcurtain).target_position;
stop_action:
- stepper.set_target:
id: rightcurtain
target: !lambda return id(rightcurtain).current_position;
- sensor.template.publish:
id: rightposition
state: !lambda return id(rightcurtain).current_position;
optimistic: true
assumed_state: true
- platform: template
name: "My Left Curtain"
id: my_leftcurtain
device_class: curtain
has_position: true
open_action:
- stepper.set_target:
id: leftcurtain
target: 0
- sensor.template.publish:
id: leftposition
state: !lambda return id(leftcurtain).target_position;
close_action:
- stepper.set_target:
id: leftcurtain
target: -4500
- sensor.template.publish:
id: leftposition
state: !lambda return id(leftcurtain).target_position;
stop_action:
- stepper.set_target:
id: leftcurtain
target: !lambda return id(leftcurtain).current_position;
- sensor.template.publish:
id: leftposition
state: !lambda return id(leftcurtain).current_position;
optimistic: true
assumed_state: true
sensor:
- platform: template
name: "My Right Curtain Position"
id: rightposition
- platform: template
name: "My Left Curtain Position"
id: leftposition
stepper:
- platform: a4988
id: rightcurtain
step_pin: 21
dir_pin: 22
sleep_pin: 23
max_speed: 250 steps/s
- platform: a4988
id: leftcurtain
step_pin: 17
dir_pin: 18
sleep_pin: 19
max_speed: 250 steps/s
There’s an example here of saving and restoring a stepper position:
Thanks Tom I’ll take a look at that now.
Thanks again Tom for the link to the example. By following that I have managed to get it working.
Here’s my code in case anyone finds it useful
esphome:
name: loungecurtains
on_boot:
- priority: -200.0
then:
- logger.log:
format: "Calling on boot Right Position %d"
args: [ 'id(g_rightCurtainPosition)' ]
- stepper.report_position: # Set stepper to global variable
id: rightCurtainStepper
position: !lambda return id(g_rightCurtainPosition);
- stepper.set_target: # Set stepper to global variable
id: rightCurtainStepper
target: !lambda return id(g_rightCurtainPosition);
- cover.template.publish:
id: my_rightcurtain
state: !lambda return id(g_rightCurtainPosition);
esp32:
board: esp32dev
framework:
type: arduino
globals:
- id: g_rightCurtainPosition
type: int
restore_value: True
initial_value: '0'
- id: g_leftCurtainPosition
type: int
restore_value: True
initial_value: '0'
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esphome-Web-0Ec490"
password: ""
captive_portal:
# Enable logging
logger:
ota:
web_server:
port: 80
# Enable Home Assistant API
api:
services:
- service: control_rightcurtain
variables:
target: int
then:
- stepper.report_position:
id: rightCurtainStepper
position: !lambda 'return id(g_rightCurtainPosition);'
- stepper.set_target:
id: rightCurtainStepper
target: !lambda 'return id(g_rightCurtainPosition);'
- sensor.template.publish:
id: RightCurtainPosition
state: !lambda 'return id(rightCurtainStepper).current_position;'
- globals.set:
id: g_rightCurtainPosition
value: !lambda return id(rightCurtainStepper).current_position;
- service: control_leftcurtain
variables:
target: int
then:
- stepper.report_position:
id: leftCurtainStepper
position: !lambda 'return id(leftCurtainStepper).current_position;'
- stepper.set_target:
id: leftCurtainStepper
target: !lambda 'return id(g_leftCurtainPosition);'
- sensor.template.publish:
id: LeftCurtainPosition
state: !lambda 'return id(leftCurtainStepper).current_position;'
cover:
- platform: template
name: "My Right Curtain"
id: my_rightcurtain
device_class: curtain
open_action:
- logger.log: "Opening"
- stepper.set_target:
id: rightCurtainStepper
target: 0
- sensor.template.publish:
id: RightCurtainPosition
state: !lambda return id(rightCurtainStepper).target_position;
- globals.set:
id: g_rightCurtainPosition
value: !lambda return id(rightCurtainStepper).target_position;
close_action:
- stepper.set_target:
id: rightCurtainStepper
target: -4500
- sensor.template.publish:
id: RightCurtainPosition
state: !lambda return id(rightCurtainStepper).target_position;
- globals.set:
id: g_rightCurtainPosition
value: !lambda return id(rightCurtainStepper).target_position;
stop_action:
- stepper.set_target:
id: rightCurtainStepper
target: !lambda return id(rightCurtainStepper).current_position;
- sensor.template.publish:
id: RightCurtainPosition
state: !lambda return id(rightCurtainStepper).current_position;
- globals.set:
id: g_rightCurtainPosition
value: !lambda return id(rightCurtainStepper).current_position;
optimistic: true
assumed_state: true
- platform: template
name: "My Left Curtain"
id: my_leftcurtain
device_class: curtain
has_position: true
open_action:
- stepper.set_target:
id: leftCurtainStepper
target: 0
- sensor.template.publish:
id: LeftCurtainPosition
state: !lambda return id(leftCurtainStepper).target_position;
close_action:
- stepper.set_target:
id: leftCurtainStepper
target: -4500
- sensor.template.publish:
id: LeftCurtainPosition
state: !lambda return id(leftCurtainStepper).target_position;
stop_action:
- stepper.set_target:
id: leftCurtainStepper
target: !lambda return id(leftCurtainStepper).current_position;
- sensor.template.publish:
id: LeftCurtainPosition
state: !lambda return id(leftCurtainStepper).current_position;
optimistic: true
assumed_state: true
sensor:
- platform: template
name: "My Right Curtain Position"
id: RightCurtainPosition
- platform: template
name: "My Left Curtain Position"
id: LeftCurtainPosition
stepper:
- platform: a4988
id: rightCurtainStepper
step_pin: 21
dir_pin: 22
sleep_pin: 23
max_speed: 250 steps/s
- platform: a4988
id: leftCurtainStepper
step_pin: 17
dir_pin: 18
sleep_pin: 19
max_speed: 250 steps/s