Return the last numeric value for an entity

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:

Screenshot 2023-01-30 at 20-42-39 Template Number

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
1 Like