From f33d829ce9c03b6c1d8ba54065d178caf37646fb Mon Sep 17 00:00:00 2001 From: Javier Peletier Date: Mon, 25 Jul 2022 00:10:37 +0200 Subject: [PATCH] FIX: NVS preferences being written even if unchanged (#3647) --- esphome/components/esp32/preferences.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/esphome/components/esp32/preferences.cpp b/esphome/components/esp32/preferences.cpp index 057fefc48c..d070a20d82 100644 --- a/esphome/components/esp32/preferences.cpp +++ b/esphome/components/esp32/preferences.cpp @@ -110,9 +110,11 @@ class ESP32Preferences : public ESPPreferences { if (s_pending_save.empty()) return true; - ESP_LOGD(TAG, "Saving preferences to flash..."); + ESP_LOGD(TAG, "Saving %d preferences to flash...", s_pending_save.size()); // goal try write all pending saves even if one fails - bool any_failed = false; + int cached = 0, written = 0, failed = 0; + esp_err_t last_err = ESP_OK; + std::string last_key{}; // go through vector from back to front (makes erase easier/more efficient) for (ssize_t i = s_pending_save.size() - 1; i >= 0; i--) { @@ -124,14 +126,24 @@ class ESP32Preferences : public ESPPreferences { 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)); - any_failed = true; + failed++; + last_err = err; + last_key = save.key; continue; } + written++; } else { - ESP_LOGD(TAG, "NVS data not changed skipping %s len=%u", save.key.c_str(), save.data.size()); + ESP_LOGV(TAG, "NVS data not changed skipping %s len=%u", save.key.c_str(), save.data.size()); + cached++; } s_pending_save.erase(s_pending_save.begin() + i); } + ESP_LOGD(TAG, "Saving %d preferences to flash: %d cached, %d written, %d failed", cached + written + failed, cached, + written, failed); + if (failed > 0) { + ESP_LOGD(TAG, "Error saving %d preferences to flash. Last error=%s for key=%s", failed, esp_err_to_name(last_err), + last_key.c_str()); + } // note: commit on esp-idf currently is a no-op, nvs_set_blob always writes esp_err_t err = nvs_commit(nvs_handle); @@ -140,7 +152,7 @@ class ESP32Preferences : public ESPPreferences { return false; } - return !any_failed; + return failed == 0; } bool is_changed(const uint32_t nvs_handle, const NVSData &to_save) { NVSData stored_data{}; @@ -150,7 +162,7 @@ class ESP32Preferences : public ESPPreferences { ESP_LOGV(TAG, "nvs_get_blob('%s'): %s - the key might not be set yet", to_save.key.c_str(), esp_err_to_name(err)); return true; } - stored_data.data.reserve(actual_len); + stored_data.data.resize(actual_len); err = nvs_get_blob(nvs_handle, to_save.key.c_str(), stored_data.data.data(), &actual_len); if (err != 0) { ESP_LOGV(TAG, "nvs_get_blob('%s') failed: %s", to_save.key.c_str(), esp_err_to_name(err));