new buzzer component

This commit is contained in:
2025-07-22 00:09:58 +01:00
parent 84f106eee5
commit bd587a10c0
58 changed files with 3215 additions and 6961 deletions

View File

@@ -10,18 +10,17 @@
#include <string.h>
#include "meter_events.h"
#include "evse_events.h"
#include <math.h>
static const char *TAG = "loadbalancer";
// Limites configuráveis
// Configurable limits
#define MIN_CHARGING_CURRENT_LIMIT 6 // A
#define MAX_CHARGING_CURRENT_LIMIT 32 // A
#define MIN_GRID_CURRENT_LIMIT 6 // A
#define MAX_GRID_CURRENT_LIMIT 100 // A
// Parâmetros
// Parameters
static uint8_t max_grid_current = MAX_GRID_CURRENT_LIMIT;
static bool loadbalancer_enabled = false;
@@ -34,6 +33,12 @@ static input_filter_t evse_filter;
#define NVS_MAX_GRID_CURRENT "max_grid_curr"
#define NVS_LOADBALANCER_ENABLED "enabled"
// Reset filter helper
static void input_filter_reset(input_filter_t *filter)
{
filter->value = 0.0f;
}
static void loadbalancer_meter_event_handler(void *handler_arg,
esp_event_base_t base,
int32_t id,
@@ -45,13 +50,12 @@ static void loadbalancer_meter_event_handler(void *handler_arg,
const meter_event_data_t *evt = (const meter_event_data_t *)event_data;
ESP_LOGI(TAG, "Received meter event from source: %s", evt->source);
ESP_LOGI(TAG, "Raw IRMS: [%.2f, %.2f, %.2f] A", evt->irms[0], evt->irms[1], evt->irms[2]);
ESP_LOGI(TAG, "Raw VRMS: [%.1f, %.1f, %.1f] V", evt->vrms[0], evt->vrms[1], evt->vrms[2]);
ESP_LOGI(TAG, "Raw Power: [W1=%d, W2=%d, W3=%d]", evt->watt[0], evt->watt[1], evt->watt[2]);
ESP_LOGI(TAG, "IRMS: [%.2f, %.2f, %.2f] A", evt->irms[0], evt->irms[1], evt->irms[2]);
ESP_LOGI(TAG, "VRMS: [%.1f, %.1f, %.1f] V", evt->vrms[0], evt->vrms[1], evt->vrms[2]);
ESP_LOGI(TAG, "Power: [W1=%d, W2=%d, W3=%d]", evt->watt[0], evt->watt[1], evt->watt[2]);
ESP_LOGI(TAG, "Freq: %.2f Hz | PF: %.2f | Energy: %.3f kWh",
evt->frequency, evt->power_factor, evt->total_energy);
// Calcula a corrente máxima entre as 3 fases
float max_irms = evt->irms[0];
for (int i = 1; i < 3; ++i)
{
@@ -63,13 +67,12 @@ static void loadbalancer_meter_event_handler(void *handler_arg,
ESP_LOGI(TAG, "Max IRMS detected: %.2f A", max_irms);
// Atualiza com filtro exponencial dependendo da origem
if (strncmp(evt->source, "GRID", 4) == 0)
if (evt->source && strcmp(evt->source, "GRID") == 0)
{
grid_current = input_filter_update(&grid_filter, max_irms);
ESP_LOGI(TAG, "GRID IRMS (filtered): %.2f A", grid_current);
}
else if (strncmp(evt->source, "EVSE", 4) == 0)
else if (evt->source && strcmp(evt->source, "EVSE") == 0)
{
evse_current = input_filter_update(&evse_filter, max_irms);
ESP_LOGI(TAG, "EVSE IRMS (filtered): %.2f A", evse_current);
@@ -92,27 +95,23 @@ static void loadbalancer_evse_event_handler(void *handler_arg,
switch (evt->state)
{
case EVSE_STATE_EVENT_IDLE:
// Vehicle is disconnected - current flow can be reduced or reset
ESP_LOGI(TAG, "EVSE is IDLE - possible to release current");
ESP_LOGI(TAG, "EVSE is IDLE - vehicle disconnected");
break;
case EVSE_STATE_EVENT_WAITING:
// EV is connected but not charging yet (e.g., waiting for authorization)
ESP_LOGI(TAG, "EVSE is waiting - connected but not charging");
ESP_LOGI(TAG, "EVSE is WAITING - connected but not charging");
break;
case EVSE_STATE_EVENT_CHARGING:
ESP_LOGI(TAG, "EVSE is CHARGING - resetting filters");
grid_current = 0.0f;
evse_current = 0.0f;
// Charging has started - maintain or monitor current usage
ESP_LOGI(TAG, "EVSE is charging");
input_filter_reset(&grid_filter);
input_filter_reset(&evse_filter);
break;
case EVSE_STATE_EVENT_FAULT:
// A fault has occurred - safety measures may be needed
ESP_LOGW(TAG, "EVSE is in FAULT - temporarily disabling load balancing");
// Optional: disable load balancing during fault condition
// loadbalancer_set_enabled(false);
ESP_LOGW(TAG, "EVSE is in FAULT state - consider disabling load balancing");
break;
default:
@@ -121,21 +120,19 @@ static void loadbalancer_evse_event_handler(void *handler_arg,
}
}
// Carrega configuração do NVS
static esp_err_t loadbalancer_load_config()
{
nvs_handle_t handle;
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &handle);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Failed to open NVS for load/init: %s", esp_err_to_name(err));
ESP_LOGE(TAG, "Failed to open NVS: %s", esp_err_to_name(err));
return err;
}
bool needs_commit = false;
uint8_t temp_u8;
// max_grid_current
err = nvs_get_u8(handle, NVS_MAX_GRID_CURRENT, &temp_u8);
if (err == ESP_OK && temp_u8 >= MIN_GRID_CURRENT_LIMIT && temp_u8 <= MAX_GRID_CURRENT_LIMIT)
{
@@ -145,11 +142,10 @@ static esp_err_t loadbalancer_load_config()
{
max_grid_current = MAX_GRID_CURRENT_LIMIT;
nvs_set_u8(handle, NVS_MAX_GRID_CURRENT, max_grid_current);
ESP_LOGW(TAG, "max_grid_current missing or invalid, setting default: %d", max_grid_current);
ESP_LOGW(TAG, "max_grid_current invalid or missing, set to default: %d", max_grid_current);
needs_commit = true;
}
// loadbalancer_enabled
err = nvs_get_u8(handle, NVS_LOADBALANCER_ENABLED, &temp_u8);
if (err == ESP_OK && temp_u8 <= 1)
{
@@ -159,7 +155,7 @@ static esp_err_t loadbalancer_load_config()
{
loadbalancer_enabled = false;
nvs_set_u8(handle, NVS_LOADBALANCER_ENABLED, 0);
ESP_LOGW(TAG, "loadbalancer_enabled missing or invalid, setting default: 0");
ESP_LOGW(TAG, "loadbalancer_enabled invalid or missing, set to false");
needs_commit = true;
}
@@ -172,10 +168,9 @@ static esp_err_t loadbalancer_load_config()
return ESP_OK;
}
// Salva o estado habilitado no NVS
void loadbalancer_set_enabled(bool enabled)
{
ESP_LOGI(TAG, "Setting load balancing enabled to %d", enabled);
ESP_LOGI(TAG, "Setting load balancing to %d", enabled);
nvs_handle_t handle;
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &handle);
if (err != ESP_OK)
@@ -189,7 +184,7 @@ void loadbalancer_set_enabled(bool enabled)
{
nvs_commit(handle);
loadbalancer_enabled = enabled;
ESP_LOGI(TAG, "Load balancing enabled state saved");
ESP_LOGI(TAG, "Load balancing state saved");
loadbalancer_state_event_t evt = {
.enabled = enabled,
@@ -209,7 +204,6 @@ void loadbalancer_set_enabled(bool enabled)
nvs_close(handle);
}
// Define e salva o limite de corrente da rede
esp_err_t load_balancing_set_max_grid_current(uint8_t value)
{
if (value < MIN_GRID_CURRENT_LIMIT || value > MAX_GRID_CURRENT_LIMIT)
@@ -252,20 +246,23 @@ bool loadbalancer_is_enabled(void)
return loadbalancer_enabled;
}
// Tarefa principal com eventos
void loadbalancer_task(void *param)
{
while (true)
{
if (!loadbalancer_enabled)
{
vTaskDelay(pdMS_TO_TICKS(1000));
vTaskDelay(pdMS_TO_TICKS(5000));
continue;
}
float available = max_grid_current - grid_current + evse_current;
float available = max_grid_current - grid_current;
if (available < MIN_CHARGING_CURRENT_LIMIT)
if (available < 0.0f)
{
available = 0.0f;
}
else if (available < MIN_CHARGING_CURRENT_LIMIT)
{
available = MIN_CHARGING_CURRENT_LIMIT;
}
@@ -274,7 +271,7 @@ void loadbalancer_task(void *param)
available = max_grid_current;
}
ESP_LOGD(TAG, "Setting EVSE current limit: %.1f A", available);
ESP_LOGD(TAG, "Calculated available EVSE current: %.1f A", available);
loadbalancer_charging_limit_event_t evt = {
.limit = available,
@@ -286,7 +283,7 @@ void loadbalancer_task(void *param)
sizeof(evt),
portMAX_DELAY);
vTaskDelay(pdMS_TO_TICKS(1000));
vTaskDelay(pdMS_TO_TICKS(5000));
}
}