This commit is contained in:
2025-08-24 11:17:48 +01:00
parent 0d0dc5b129
commit 96b2ab1f57
31 changed files with 2883 additions and 4054 deletions

View File

@@ -6,6 +6,7 @@
#include "evse_api.h"
#include "evse_meter.h"
#include "evse_session.h"
#include "evse_config.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
@@ -16,6 +17,7 @@
#include "auth_events.h"
#include "loadbalancer_events.h"
#include "ocpp_events.h"
#include "esp_event.h"
static const char *TAG = "EVSE_Manager";
@@ -23,66 +25,142 @@ static const char *TAG = "EVSE_Manager";
static SemaphoreHandle_t evse_mutex;
static bool auth_enabled = false;
#define EVSE_MANAGER_TICK_PERIOD_MS 1000 // 1 segundo
#define EVSE_MANAGER_TICK_PERIOD_MS 1000 // 1 segundo
// ===== Task de ciclo principal =====
static void evse_manager_task(void *arg) {
while (true) {
static void evse_manager_task(void *arg)
{
while (true)
{
evse_manager_tick();
vTaskDelay(pdMS_TO_TICKS(EVSE_MANAGER_TICK_PERIOD_MS));
}
}
// ===== Tratador de eventos de autenticação =====
static void on_auth_event(void* arg, esp_event_base_t base, int32_t id, void* data) {
if (base != AUTH_EVENTS || data == NULL) return;
static void on_auth_event(void *arg, esp_event_base_t base, int32_t id, void *data)
{
if (base != AUTH_EVENTS || !data)
return;
switch (id) {
case AUTH_EVENT_TAG_PROCESSED: {
auth_tag_event_data_t *evt = (auth_tag_event_data_t*)data;
ESP_LOGI("EVSE", "Tag: %s | Autorized: %s", evt->tag, evt->authorized ? "AUTHORIZED" : "DENIED");
evse_state_set_authorized(evt->authorized);
break;
auth_mode_t g_mode = AUTH_MODE_OPEN;
switch (id)
{
case AUTH_EVENT_TAG_PROCESSED:
{
const auth_tag_event_data_t *evt = (const auth_tag_event_data_t *)data;
ESP_LOGI(TAG, "Tag %s -> %s", evt->tag, evt->authorized ? "AUTHORIZED" : "DENIED");
evse_state_set_authorized(evt->authorized);
break;
}
case AUTH_EVENT_MODE_CHANGED:
case AUTH_EVENT_INIT:
{
const auth_mode_event_data_t *evt = (const auth_mode_event_data_t *)data;
g_mode = evt->mode;
ESP_LOGI(TAG, "Auth mode = %s", auth_mode_to_str(g_mode));
if (g_mode == AUTH_MODE_OPEN)
{
evse_state_set_authorized(true);
auth_enabled = false;
}
case AUTH_EVENT_ENABLED_CHANGED:
case AUTH_EVENT_INIT: {
auth_enabled_event_data_t *evt = (auth_enabled_event_data_t*)data;
auth_enabled = evt->enabled;
ESP_LOGI("EVSE", "Auth %s (%s)",
id == AUTH_EVENT_ENABLED_CHANGED ? "ficou" : "init",
evt->enabled ? "ATIVO" : "INATIVO");
if (!auth_enabled) {
evse_state_set_authorized(true);
ESP_LOGI("EVSE", "Autenticação desativada → autorização forçada.");
} else {
evse_state_set_authorized(false);
ESP_LOGI("EVSE", "Autenticação ativada → aguardando autorização por tag.");
}
break;
else
{
evse_state_set_authorized(false);
auth_enabled = true;
}
break;
}
}
}
// ===== Tratador de eventos de loadbalancer =====
static void on_loadbalancer_event(void* handler_arg, esp_event_base_t event_base,
int32_t event_id, void* event_data) {
if (event_id == LOADBALANCER_EVENT_INIT || event_id == LOADBALANCER_EVENT_STATE_CHANGED) {
const loadbalancer_state_event_t* evt = (const loadbalancer_state_event_t*) event_data;
static void on_loadbalancer_event(void *handler_arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (event_id == LOADBALANCER_EVENT_INIT || event_id == LOADBALANCER_EVENT_STATE_CHANGED)
{
const loadbalancer_state_event_t *evt = (const loadbalancer_state_event_t *)event_data;
ESP_LOGI(TAG, "Loadbalancer %s (ts: %lld)",
evt->enabled ? "ENABLED" : "DISABLED", evt->timestamp_us);
// Ações adicionais podem ser adicionadas aqui conforme necessário
} else if (event_id == LOADBALANCER_EVENT_MASTER_CURRENT_LIMIT) {
const loadbalancer_master_limit_event_t* evt = (const loadbalancer_master_limit_event_t*) event_data;
}
else if (event_id == LOADBALANCER_EVENT_MASTER_CURRENT_LIMIT)
{
const loadbalancer_master_limit_event_t *evt = (const loadbalancer_master_limit_event_t *)event_data;
ESP_LOGI(TAG, "Novo limite de corrente (master): %u A (ts: %lld)", evt->max_current, evt->timestamp_us);
evse_set_runtime_charging_current(evt->max_current);
}
}
}
static void on_ocpp_event(void *arg, esp_event_base_t base, int32_t id, void *data)
{
if (base != OCPP_EVENTS)
return;
switch (id)
{
case OCPP_EVENT_AUTHORIZED:
ESP_LOGI(TAG, "[OCPP] Authorized");
evse_state_set_authorized(true);
break;
case OCPP_EVENT_AUTH_REJECTED:
ESP_LOGW(TAG, "[OCPP] Authorization rejected");
evse_state_set_authorized(false);
break;
case OCPP_EVENT_AUTH_TIMEOUT:
ESP_LOGW(TAG, "[OCPP] Authorization timeout");
evse_state_set_authorized(false);
break;
case OCPP_EVENT_REMOTE_START:
ESP_LOGI(TAG, "[OCPP] RemoteStart");
evse_state_set_authorized(true);
break;
case OCPP_EVENT_REMOTE_STOP:
ESP_LOGI(TAG, "[OCPP] RemoteStop");
evse_state_set_authorized(false);
break;
case OCPP_EVENT_START_TX:
ESP_LOGI(TAG, "[OCPP] StartTx");
break;
case OCPP_EVENT_STOP_TX:
ESP_LOGI(TAG, "[OCPP] StopTx");
evse_state_set_authorized(false);
break;
// hegou ChangeAvailability remoto (operative/inoperative)
case OCPP_EVENT_OPERATIVE_UPDATED:
{
if (!data)
{
ESP_LOGW(TAG, "[OCPP] OperativeUpdated sem payload — ignorado");
break;
}
const ocpp_operative_event_t *ev = (const ocpp_operative_event_t *)data;
ESP_LOGI(TAG, "[OCPP] OperativeUpdated: operative=%d ts=%lld",
(int)ev->operative, (long long)ev->timestamp_us);
// Mapear operative → enabled local (persiste e emite EVSE_EVENT_ENABLE_UPDATED)
evse_config_set_enabled(ev->operative);
break;
}
default:
ESP_LOGD(TAG, "[OCPP] Unhandled event id=%" PRId32, id);
break;
}
}
// ===== Inicialização =====
void evse_manager_init(void) {
void evse_manager_init(void)
{
evse_mutex = xSemaphoreCreateMutex();
evse_config_init();
@@ -94,13 +172,15 @@ void evse_manager_init(void) {
ESP_ERROR_CHECK(esp_event_handler_register(AUTH_EVENTS, ESP_EVENT_ANY_ID, &on_auth_event, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(LOADBALANCER_EVENTS, ESP_EVENT_ANY_ID, &on_loadbalancer_event, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(OCPP_EVENTS, ESP_EVENT_ANY_ID, &on_ocpp_event, NULL)); // <— AQUI
ESP_LOGI(TAG, "EVSE Manager inicializado.");
xTaskCreate(evse_manager_task, "evse_manager_task", 4096, NULL, 5, NULL);
}
// ===== Main Tick =====
void evse_manager_tick(void) {
void evse_manager_tick(void)
{
xSemaphoreTake(evse_mutex, portMAX_DELAY);
evse_hardware_tick();
@@ -109,15 +189,20 @@ void evse_manager_tick(void) {
evse_temperature_check();
evse_session_tick();
if (auth_enabled) {
if (auth_enabled)
{
// If the car is disconnected, revoke authorization
if (evse_state_get_authorized() && evse_get_state() == EVSE_STATE_A) {
if (evse_state_get_authorized() && evse_get_state() == EVSE_STATE_A)
{
ESP_LOGI(TAG, "Vehicle disconnected → revoking authorization.");
evse_state_set_authorized(false);
}
} else {
}
else
{
// If authentication is disabled, ensure authorization is always granted
if (!evse_state_get_authorized()) {
if (!evse_state_get_authorized())
{
evse_state_set_authorized(true);
ESP_LOGI(TAG, "Authentication disabled → forced authorization.");
}