mirror of
				https://github.com/esphome/esphome.git
				synced 2025-11-04 09:01:49 +00:00 
			
		
		
		
	Correcting ESP32 flash save/load key calculation algorithm (#3416)
Co-authored-by: Otto Winter <otto@otto-winter.com> Co-authored-by: Dr. Zimmermann Zsolt <cina@storage1.cina.hu>
This commit is contained in:
		@@ -36,6 +36,7 @@ class ESP32PreferenceBackend : public ESPPreferenceBackend {
 | 
			
		||||
    save.key = key;
 | 
			
		||||
    save.data.assign(data, data + len);
 | 
			
		||||
    s_pending_save.emplace_back(save);
 | 
			
		||||
    ESP_LOGVV(TAG, "s_pending_save: key: %s, len: %d", key.c_str(), len);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  bool load(uint8_t *data, size_t len) override {
 | 
			
		||||
@@ -65,6 +66,8 @@ class ESP32PreferenceBackend : public ESPPreferenceBackend {
 | 
			
		||||
    if (err != 0) {
 | 
			
		||||
      ESP_LOGV(TAG, "nvs_get_blob('%s') failed: %s", key.c_str(), esp_err_to_name(err));
 | 
			
		||||
      return false;
 | 
			
		||||
    } else {
 | 
			
		||||
      ESP_LOGVV(TAG, "nvs_get_blob: key: %s, len: %d", key.c_str(), len);
 | 
			
		||||
    }
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
@@ -73,7 +76,6 @@ class ESP32PreferenceBackend : public ESPPreferenceBackend {
 | 
			
		||||
class ESP32Preferences : public ESPPreferences {
 | 
			
		||||
 public:
 | 
			
		||||
  uint32_t nvs_handle;
 | 
			
		||||
  uint32_t current_offset = 0;
 | 
			
		||||
 | 
			
		||||
  void open() {
 | 
			
		||||
    nvs_flash_init();
 | 
			
		||||
@@ -97,12 +99,9 @@ class ESP32Preferences : public ESPPreferences {
 | 
			
		||||
  ESPPreferenceObject make_preference(size_t length, uint32_t type) override {
 | 
			
		||||
    auto *pref = new ESP32PreferenceBackend();  // NOLINT(cppcoreguidelines-owning-memory)
 | 
			
		||||
    pref->nvs_handle = nvs_handle;
 | 
			
		||||
    current_offset += length;
 | 
			
		||||
 | 
			
		||||
    uint32_t keyval = current_offset ^ type;
 | 
			
		||||
    char keybuf[16];
 | 
			
		||||
    snprintf(keybuf, sizeof(keybuf), "%d", keyval);
 | 
			
		||||
    pref->key = keybuf;  // copied to std::string
 | 
			
		||||
    uint32_t keyval = type;
 | 
			
		||||
    pref->key = str_sprintf("%u", keyval);
 | 
			
		||||
 | 
			
		||||
    return ESPPreferenceObject(pref);
 | 
			
		||||
  }
 | 
			
		||||
@@ -121,6 +120,7 @@ class ESP32Preferences : public ESPPreferences {
 | 
			
		||||
      ESP_LOGVV(TAG, "Checking if NVS data %s has changed", save.key.c_str());
 | 
			
		||||
      if (is_changed(nvs_handle, save)) {
 | 
			
		||||
        esp_err_t err = nvs_set_blob(nvs_handle, save.key.c_str(), save.data.data(), save.data.size());
 | 
			
		||||
        ESP_LOGV(TAG, "sync: key: %s, len: %d", save.key.c_str(), save.data.size());
 | 
			
		||||
        if (err != 0) {
 | 
			
		||||
          ESP_LOGV(TAG, "nvs_set_blob('%s', len=%u) failed: %s", save.key.c_str(), save.data.size(),
 | 
			
		||||
                   esp_err_to_name(err));
 | 
			
		||||
 
 | 
			
		||||
@@ -6,8 +6,17 @@ namespace number {
 | 
			
		||||
 | 
			
		||||
static const char *const TAG = "number.automation";
 | 
			
		||||
 | 
			
		||||
union convert {
 | 
			
		||||
  float from;
 | 
			
		||||
  uint32_t to;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void ValueRangeTrigger::setup() {
 | 
			
		||||
  this->rtc_ = global_preferences->make_preference<bool>(this->parent_->get_object_id_hash());
 | 
			
		||||
  float local_min = this->min_.value(0.0);
 | 
			
		||||
  float local_max = this->max_.value(0.0);
 | 
			
		||||
  convert hash = {.from = (local_max - local_min)};
 | 
			
		||||
  uint32_t myhash = hash.to ^ this->parent_->get_object_id_hash();
 | 
			
		||||
  this->rtc_ = global_preferences->make_preference<bool>(myhash);
 | 
			
		||||
  bool initial_state;
 | 
			
		||||
  if (this->rtc_.load(&initial_state)) {
 | 
			
		||||
    this->previous_in_range_ = initial_state;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user