new loadbalancer

This commit is contained in:
2025-06-08 14:32:21 +01:00
parent 8fe2c5e1e7
commit a57477d95b
239 changed files with 94 additions and 12 deletions

0
components/evsemeter/CMakeLists.txt Normal file → Executable file
View File

0
components/evsemeter/include/evsemeter.h Normal file → Executable file
View File

0
components/evsemeter/src/evsemeter_ade7758.c Normal file → Executable file
View File

0
components/evsemeter/src/evsemeter_events.c Normal file → Executable file
View File

0
components/evsemeter/src/evsemeter_modbus.c Normal file → Executable file
View File

0
components/gridmeter/CMakeLists.txt Normal file → Executable file
View File

0
components/gridmeter/include/gridmeter.h Normal file → Executable file
View File

0
components/gridmeter/src/gridmeter_events.c Normal file → Executable file
View File

0
components/gridmeter/src/gridmeter_modbus.c Normal file → Executable file
View File

0
components/loadbalancer/CMakeLists.txt Normal file → Executable file
View File

View File

@@ -0,0 +1,30 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
float alpha; ///< Fator de suavização (0.0 a 1.0)
float value; ///< Último valor filtrado
int initialized; ///< Flag de inicialização
} input_filter_t;
/**
* @brief Inicializa o filtro com o fator alpha desejado.
* @param filter Ponteiro para a estrutura do filtro
* @param alpha Valor entre 0.0 (mais lento) e 1.0 (sem filtro)
*/
void input_filter_init(input_filter_t *filter, float alpha);
/**
* @brief Atualiza o valor filtrado com uma nova entrada.
* @param filter Ponteiro para o filtro
* @param input Valor bruto
* @return Valor suavizado
*/
float input_filter_update(input_filter_t *filter, float input);
#ifdef __cplusplus
}
#endif

0
components/loadbalancer/include/loadbalancer.h Normal file → Executable file
View File

View File

@@ -0,0 +1,22 @@
#include "input_filter.h"
void input_filter_init(input_filter_t *filter, float alpha) {
if (filter) {
filter->alpha = alpha;
filter->value = 0.0f;
filter->initialized = 0;
}
}
float input_filter_update(input_filter_t *filter, float input) {
if (!filter) return input;
if (!filter->initialized) {
filter->value = input;
filter->initialized = 1;
} else {
filter->value = filter->alpha * input + (1.0f - filter->alpha) * filter->value;
}
return filter->value;
}

54
components/loadbalancer/src/loadbalancer.c Normal file → Executable file
View File

@@ -6,18 +6,28 @@
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "input_filter.h"
static const char *TAG = "loadbalancer";
static float grid_current = 0.0f;
static float evse_current = 0.0f;
static float max_grid_current = 32.0f; // amperes
static float max_grid_current = 32.0f; // Amperes
#define MIN_EVSE_CURRENT 6.0f
// Filtros
static input_filter_t grid_filter;
static input_filter_t evse_filter;
static void grid_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data)
{
if (id == GRIDMETER_EVENT_UPDATE && data)
{
grid_current = *(float *)data;
float raw;
memcpy(&raw, data, sizeof(float));
grid_current = input_filter_update(&grid_filter, raw);
ESP_LOGD(TAG, "Grid current (filtered): %.2f A", grid_current);
}
}
@@ -25,15 +35,29 @@ static void evse_event_handler(void *arg, esp_event_base_t base, int32_t id, voi
{
if (id == EVSEMETER_EVENT_UPDATE && data)
{
evse_current = *(float *)data;
float raw;
memcpy(&raw, data, sizeof(float));
evse_current = input_filter_update(&evse_filter, raw);
ESP_LOGD(TAG, "EVSE current (filtered): %.2f A", evse_current);
}
}
void loadbalancer_init(void)
{
ESP_LOGI(TAG, "Initializing load balancer");
esp_event_handler_register(GRIDMETER_EVENT, GRIDMETER_EVENT_UPDATE, grid_event_handler, NULL);
esp_event_handler_register(EVSEMETER_EVENT, EVSEMETER_EVENT_UPDATE, evse_event_handler, NULL);
// Inicializa filtros
input_filter_init(&grid_filter, 0.3f);
input_filter_init(&evse_filter, 0.3f);
// Registra eventos
if (esp_event_handler_register(GRIDMETER_EVENT, GRIDMETER_EVENT_UPDATE, grid_event_handler, NULL) != ESP_OK) {
ESP_LOGE(TAG, "Failed to register gridmeter event handler");
}
if (esp_event_handler_register(EVSEMETER_EVENT, EVSEMETER_EVENT_UPDATE, evse_event_handler, NULL) != ESP_OK) {
ESP_LOGE(TAG, "Failed to register evsemeter event handler");
}
}
void loadbalancer_task(void *param)
@@ -41,27 +65,33 @@ void loadbalancer_task(void *param)
while (true)
{
float available = max_grid_current - grid_current + evse_current;
if (available < 6.0f)
{
available = 6.0f;
// Aplica restrições de segurança
if (available < MIN_EVSE_CURRENT) {
available = 0.0f;
} else if (available > max_grid_current) {
available = max_grid_current;
}
ESP_LOGD(TAG, "Setting current limit: %f", available);
ESP_LOGI(TAG, "Setting EVSE current limit: %.1f A", available);
evse_set_current_limit((uint16_t)available);
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void setMaxGridCurrent(int value)
{
max_grid_current = value / 10.0f; // assume value in A*10
max_grid_current = value / 10.0f; // valor em décimos de ampere
}
void setLiveGridCurrent(int value)
{
grid_current = value / 10.0f;
float raw = value / 10.0f;
grid_current = input_filter_update(&grid_filter, raw);
}
void setLiveVolt(int value)
{
(void)value; // unused for now
(void)value; // não usado ainda
}

0
components/meter_orno_modbus/CMakeLists.txt Normal file → Executable file
View File

0
components/meter_orno_modbus/include/orno_modbus.h Normal file → Executable file
View File

0
components/meter_orno_modbus/src/orno_modbus.c Normal file → Executable file
View File