Add NVS support for relay channel config persistence

- Introduced NVS configuration options in Kconfig.
- Implemented NVS initialization and deinitialization in relay_chn_core.
- Added functions for storing and retrieving relay channel direction and tilt sensitivity in NVS.
- Updated relay_chn_tilt and relay_chn_output to utilize NVS for state management.
- Created relay_chn_nvs.c and relay_chn_nvs.h for NVS-related functionalities.

Closes #1074.
This commit is contained in:
2025-08-19 17:33:45 +03:00
parent f04632dc77
commit b19f0c553b
8 changed files with 490 additions and 23 deletions

125
src/relay_chn_nvs.c Normal file
View File

@@ -0,0 +1,125 @@
/*
* SPDX-FileCopyrightText: 2025 Kozmotronik Tech
*
* SPDX-License-Identifier: MIT
*/
#include "esp_check.h"
#include "relay_chn_nvs.h"
#define RELAY_CHN_KEY_DIR "dir"
#ifdef RELAY_CHN_ENABLE_TILTING
#define RELAY_CHN_KEY_SENS(ch) "sens_%d"
#define RELAY_CHN_KEY_TFWD(ch) "tfwd_%d"
#define RELAY_CHN_KEY_TREV(ch) "trev_%d"
#endif
static const char *TAG = "RELAY_CHN_STORAGE_NVS";
static nvs_handle_t relay_chn_nvs;
esp_err_t relay_chn_nvs_init()
{
esp_err_t ret;
#if RELAY_CHN_NVS_CUSTOM_PARTITION == 1
ret = nvs_open_from_partition(RELAY_CHN_NVS_CUSTOM_PARTITION_NAME,
RELAY_CHN_NVS_NAMESPACE,
NVS_READWRITE,
&relay_chn_nvs);
ESP_RETURN_ON_ERROR(ret,
TAG,
"Failed to open NVS namespace '%s' from partition '%s' with error %s",
RELAY_CHN_NVS_NAMESPACE,
RELAY_CHN_NVS_CUSTOM_PARTITION_NAME,
esp_err_to_name(ret));
#else
ret = nvs_open(RELAY_CHN_NVS_NAMESPACE, NVS_READWRITE, &relay_chn_nvs);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to open NVS namespace '%s'", RELAY_CHN_NVS_NAMESPACE);
#endif // RELAY_CHN_NVS_CUSTOM_PARTITION
return ESP_OK;
}
esp_err_t relay_chn_nvs_set_direction(uint8_t ch, relay_chn_direction_t direction)
{
uint8_t direction_val;
esp_err_t ret = nvs_get_u8(relay_chn_nvs, RELAY_CHN_KEY_DIR, &direction_val);
if (ret == ESP_ERR_NVS_NOT_FOUND) {
// The key does not exist yet, set it to zero which is the default direction
direction_val = RELAY_CHN_DIRECTION_DEFAULT;
} else if (ret != ESP_OK) {
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to get direction from NVS with error: %s", esp_err_to_name(ret));
}
direction_val &= ~(1 << ch); // Clear the bit for the channel
direction_val |= (((uint8_t) direction) << ch); // Set the new direction bit
ret = nvs_set_u8(relay_chn_nvs, RELAY_CHN_KEY_DIR, direction_val);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set direction for channel %d", ch);
return nvs_commit(relay_chn_nvs);
}
esp_err_t relay_chn_nvs_get_direction(uint8_t ch, relay_chn_direction_t *direction)
{
ESP_RETURN_ON_FALSE(direction != NULL, ESP_ERR_INVALID_ARG, TAG, "Direction pointer is NULL");
uint8_t direction_val;
esp_err_t ret = nvs_get_u8(relay_chn_nvs, RELAY_CHN_KEY_DIR, &direction_val);
if (ret != ESP_OK) {
return ret; // Return error if the key does not exist
}
*direction = (relay_chn_direction_t)((direction_val >> ch) & 0x01);
return ESP_OK;
}
#ifdef RELAY_CHN_ENABLE_TILTING
esp_err_t relay_chn_nvs_set_tilt_sensitivity(uint8_t ch, uint8_t sensitivity)
{
esp_err_t ret = nvs_set_u8(relay_chn_nvs, RELAY_CHN_KEY_SENS(ch), sensitivity);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to set tilt sensitivity for channel %d", ch);
return nvs_commit(relay_chn_nvs);
}
esp_err_t relay_chn_nvs_get_tilt_sensitivity(uint8_t ch, uint8_t *sensitivity)
{
ESP_RETURN_ON_FALSE(sensitivity != NULL, ESP_ERR_INVALID_ARG, TAG, "Sensitivity pointer is NULL");
return nvs_get_u8(relay_chn_nvs, RELAY_CHN_KEY_SENS(ch), sensitivity);
}
esp_err_t relay_chn_nvs_set_tilt_count(uint8_t ch, uint32_t forward_count, uint32_t reverse_count)
{
esp_err_t ret;
ret = nvs_set_u32(relay_chn_nvs, RELAY_CHN_KEY_TFWD(ch), forward_count);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to save forward_count tilt counter");
ret = nvs_set_u32(relay_chn_nvs, RELAY_CHN_KEY_TREV(ch), reverse_count);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to save reverse_count tilt counter");
return nvs_commit(relay_chn_nvs);
}
esp_err_t relay_chn_nvs_get_tilt_count(uint8_t ch, uint32_t *forward_count, uint32_t *reverse_count)
{
ESP_RETURN_ON_FALSE(forward_count != NULL && reverse_count != NULL,
ESP_ERR_INVALID_ARG, TAG, "Counter pointers are NULL");
esp_err_t ret = nvs_get_u32(relay_chn_nvs, RELAY_CHN_KEY_TFWD(ch), forward_count);
if (ret != ESP_OK) {
return ret; // Return error if the key does not exist
}
return nvs_get_u32(relay_chn_nvs, RELAY_CHN_KEY_TREV(ch), reverse_count);
}
#endif // RELAY_CHN_ENABLE_TILTING
esp_err_t relay_chn_nvs_erase_all()
{
// Erase all key-value pairs in the relay_chn NVS namespace
esp_err_t ret = nvs_erase_all(relay_chn_nvs);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to erase all keys in NVS namespace '%s'", RELAY_CHN_NVS_NAMESPACE);
// Commit the changes
return nvs_commit(relay_chn_nvs);
}
esp_err_t relay_chn_nvs_deinit()
{
nvs_close(relay_chn_nvs);
return ESP_OK;
}