Skip to content

Suggestion for deep sleep/firmware flash/long sleep #310

@Richhoef

Description

@Richhoef

In order to flash new firmware, the device needs to stay on. I have done this with a helper switch in Home Assistant and this code:

binary_sensor:
  - platform: homeassistant
    id: stay_awake_bool
    name: Stay awake sensor
    entity_id: switch.seeedstudio_stay_awake
    on_state:
      - logger.log:
          format: "**********  stay_awake  bool turned ON/OFF  ! *****  stay_awake=%s, prevent deep_sleep "
          args: ['id(stay_awake_bool).state ? "true" : "false"']
      - if:
          condition:
            binary_sensor.is_on: stay_awake_bool
          then:
            - logger.log: "Deep Sleep PREVENTED (Sensor)"
            - deep_sleep.prevent: deep_sleep_control
          else:
            - logger.log: "Deep Sleep ALLOWED (Sensor)"
            - if:
                condition:
                  lambda: "return id(is_new_flash);"
                then:
                  - logger.log: "Deep sleep still prevented because of first startup after flash"
                else:
                  - deep_sleep.allow: deep_sleep_control
    internal: false
    entity_category: "diagnostic"

script:
  - id: enter_deep_sleep
    then:
      - logger.log: "Entering deep sleep strategy..."
      - if:
          condition:
            binary_sensor.is_off: stay_awake_bool
          then:
            - delay: 0.5s
            - logger.log: "Slaap nu"
            - deep_sleep.enter: deep_sleep_control
          else:
            - deep_sleep.prevent: deep_sleep_control
            - logger.log: "Niet slapen!"

The first time a new firmware is flashed, the device needs to be on for more than 1 minute in order to prevent a revert to the previous software version. I have done this this way:

globals:
  - id: firmware_fingerprint
    type: uint32_t
    restore_value: True
    initial_value: '0'
  - id: is_new_flash
    type: bool
    restore_value: False
    initial_value: 'false'

script:
  - id: enter_deep_sleep
    then:
      - logger.log: "Entering deep sleep strategy..."
      - if:
          condition:
            binary_sensor.is_off: stay_awake_bool
          then:
            - delay: 0.5s
            - logger.log: "Slaap nu"
            - deep_sleep.enter: deep_sleep_control
          else:
            - deep_sleep.prevent: deep_sleep_control
            - logger.log: "Niet slapen!"

  - id: manage_run_and_sleep
    mode: restart
    then:
      # Controleer of dit de eerste boot is na een flash
      - lambda: |-
          // We maken een uniek getal op basis van de compile-tijd string
          std::string version_str = __DATE__ " " __TIME__;
          uint32_t current_hash = 0;
          for (char c : version_str) {
              current_hash = ((current_hash << 5) + current_hash) + c;
          }

          if (id(firmware_fingerprint) != current_hash) {
            ESP_LOGW("CUSTOM", "Nieuwe firmware gedetecteerd! Hash: %u", current_hash);
            id(is_new_flash) = true;
            id(firmware_fingerprint) = current_hash;
          } else {
            ESP_LOGI("CUSTOM", "Firmware is ongewijzigd.");
            id(is_new_flash) = false;
          }
      - logger.log: "Waiting for sync..."

      - wait_until:
          condition:
            - and:
              - api.connected
              - lambda: 'return id(ha_time).now().is_valid() && api_is_connected();'
          timeout: 15s
      - component.update: up_time
      - wait_until:
          condition:
            lambda: |-
              return id(sensor_temp_slaapkamer_temperature).has_state() &&
                     id(weather_cond_day0).has_state() &&
                     id(weather_cond_day4).has_state() &&
                     id(weather_high_day4).has_state() &&
                     id(stay_awake_bool).has_state();
          timeout: 15s
      - delay: 3s # allow sensors time to update
      - component.update: epaper_display
      # check of het een eerste opstart is na een flash
      - if:
          condition:
            lambda: 'return id(is_new_flash);'
          then:
            - logger.log: "flash boot mode: ESP will stay on for 1.5 minutes for updates/logs."
            - deep_sleep.prevent: deep_sleep_control
            - delay: 90s
            - logger.log: "flash boot mode done, deep sleep cyclus."
            - deep_sleep.allow: deep_sleep_control
            - lambda: 'id(is_new_flash) = false;'
          else:
            - logger.log: "NORMAL MODE: short wake display update."

And for the check if it is the middle of the night and longer sleep is wished for:

      # Check of het nacht is (tussen 23:00 en 07:00)
      - if:
          condition:
            lambda: |-
              auto now = id(ha_time).now();
              return ((now.hour >= 23 || now.hour < 7) && !id(stay_awake_bool).state);
          then:
            - logger.log: "Het is nacht. Scherm wordt niet geüpdate. Slaap tot 07:00."
            - deep_sleep.enter:
                id: deep_sleep_control
                until: "07:00:00"
                time_id: ha_time
          else:
            - logger.log: "Het is dag. Normale cyclus."
            - script.execute: enter_deep_sleep

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions