Add run limit feature for relay channels with NVS support

- Introduced configuration options for enabling run limits in Kconfig.
- Added APIs to get and set run limits for individual relay channels.
- Implemented run limit timer functionality to automatically stop channels.
- Updated NVS handling to store and retrieve run limit values.
- Enhanced documentation in README and code comments to reflect new feature.

Closes #1080
This commit is contained in:
2025-08-22 12:29:07 +03:00
parent 19d02836dd
commit 40633e03d8
13 changed files with 384 additions and 3 deletions

View File

@@ -10,6 +10,10 @@
#include "relay_chn_ctl.h"
#include "relay_chn_output.h"
#if RELAY_CHN_ENABLE_NVS == 1
#include "relay_chn_nvs.h"
#endif
static const char *TAG = "RELAY_CHN_CTL";
static relay_chn_ctl_t chn_ctls[RELAY_CHN_COUNT];
@@ -30,6 +34,19 @@ esp_err_t relay_chn_ctl_init(relay_chn_output_t *outputs, relay_chn_run_info_t *
chn_ctl->output = output;
chn_ctl->run_info = run_info;
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
uint16_t run_limit_sec = RELAY_CHN_RUN_LIMIT_DEFAULT_SEC;
#if RELAY_CHN_ENABLE_NVS == 1
// Load run limit value from NVS
ret = relay_chn_nvs_get_run_limit(chn_ctl->id, &run_limit_sec);
if (ret != ESP_OK && ret != ESP_ERR_NVS_NOT_FOUND) {
ESP_LOGE(TAG, "Failed to load run limit from NVS for channel %d with error: %s", i, esp_err_to_name(ret));
}
#endif
chn_ctl->run_limit_sec = run_limit_sec;
ret = relay_chn_init_run_limit_timer(chn_ctl);
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to initialize run limit timer");
#endif
ret = relay_chn_init_timer(chn_ctl); // Create direction change inertia timer
ESP_RETURN_ON_ERROR(ret, TAG, "Failed to create relay channel timer for channel %d", i);
}
@@ -44,6 +61,12 @@ void relay_chn_ctl_deinit()
esp_timer_delete(chn_ctl->inertia_timer);
chn_ctl->inertia_timer = NULL;
}
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
if (chn_ctl->run_limit_timer != NULL) {
esp_timer_delete(chn_ctl->run_limit_timer);
chn_ctl->run_limit_timer = NULL;
}
#endif
}
}
@@ -123,6 +146,37 @@ relay_chn_direction_t relay_chn_ctl_get_direction(uint8_t chn_id)
return relay_chn_output_get_direction(chn_ctl->output);
}
#if RELAY_CHN_ENABLE_RUN_LIMIT == 1
uint16_t relay_chn_ctl_get_run_limit(uint8_t chn_id)
{
if (!relay_chn_is_channel_id_valid(chn_id) || chn_id == RELAY_CHN_ID_ALL) {
ESP_LOGE(TAG, "get_run_limit: Invalid channel ID: %d", chn_id);
return 0;
}
return chn_ctls[chn_id].run_limit_sec;
}
void relay_chn_ctl_set_run_limit(uint8_t chn_id, uint16_t time_sec)
{
if (!relay_chn_is_channel_id_valid(chn_id) || chn_id == RELAY_CHN_ID_ALL) {
ESP_LOGE(TAG, "set_run_limit: Invalid channel ID: %d", chn_id);
return;
}
// Check for boundaries
if (time_sec > RELAY_CHN_RUN_LIMIT_MAX_SEC)
time_sec = RELAY_CHN_RUN_LIMIT_MAX_SEC;
else if (time_sec < RELAY_CHN_RUN_LIMIT_MIN_SEC)
time_sec = RELAY_CHN_RUN_LIMIT_MIN_SEC;
chn_ctls[chn_id].run_limit_sec = time_sec;
#if RELAY_CHN_ENABLE_NVS == 1
relay_chn_nvs_set_run_limit(chn_id, time_sec);
#endif
}
#endif
relay_chn_ctl_t *relay_chn_ctl_get(uint8_t chn_id)
{
if (!relay_chn_is_channel_id_valid(chn_id)) {