new release

This commit is contained in:
2026-05-15 12:20:47 +01:00
parent 286028b6a8
commit d0d431daf2
440 changed files with 2776 additions and 2462 deletions

View File

@@ -30,6 +30,7 @@ static SemaphoreHandle_t evse_mutex;
// ✅ Proteção para flags partilhadas (event handlers vs task)
static portMUX_TYPE s_mgr_mux = portMUX_INITIALIZER_UNLOCKED;
static bool auth_enabled = false;
static char s_pending_ocpp_tag[AUTH_TAG_MAX_LEN];
// Estado de pausa controlado pelo Load Balancer
static bool lb_paused = false;
@@ -41,6 +42,8 @@ static portMUX_TYPE s_sched_mux = portMUX_INITIALIZER_UNLOCKED;
#define EVSE_MANAGER_TICK_PERIOD_MS 1000 // 1 segundo
static uint16_t s_sched_current_a = 0;
static void lb_clear_pause_state(void)
{
portENTER_CRITICAL(&s_mgr_mux);
@@ -61,15 +64,15 @@ bool evse_sched_is_allowed(void)
static void evse_manager_handle_auth_on_tick(void)
{
bool sched_allowed = evse_sched_is_allowed();
uint32_t err_bits = evse_get_error(); // inclui holdoff interno
bool has_error = (err_bits != 0);
uint32_t err_bits = evse_get_error(); // inclui holdoff interno
bool has_error = (err_bits != 0);
bool local_auth_enabled;
bool local_lb_paused;
portENTER_CRITICAL(&s_mgr_mux);
local_auth_enabled = auth_enabled;
local_lb_paused = lb_paused;
local_lb_paused = lb_paused;
portEXIT_CRITICAL(&s_mgr_mux);
if (local_auth_enabled)
@@ -77,6 +80,7 @@ static void evse_manager_handle_auth_on_tick(void)
if (evse_state_get_authorized() && evse_get_state() == EVSE_STATE_A)
{
ESP_LOGI(TAG, "Vehicle disconnected → revoking authorization.");
evse_session_clear_authorized_tag();
evse_state_set_authorized(false);
lb_clear_pause_state();
}
@@ -86,6 +90,7 @@ static void evse_manager_handle_auth_on_tick(void)
ESP_LOGI(TAG,
"[AUTH] error active (err=0x%08" PRIx32 ") → revoking authorization.",
err_bits);
evse_session_clear_authorized_tag();
evse_state_set_authorized(false);
lb_clear_pause_state();
}
@@ -93,12 +98,13 @@ static void evse_manager_handle_auth_on_tick(void)
if (!sched_allowed && evse_state_get_authorized())
{
ESP_LOGI(TAG, "[SCHED] window closed (auth mode) → revoking authorization.");
evse_session_clear_authorized_tag();
evse_state_set_authorized(false);
}
}
else
{
bool limit_hit = evse_is_limit_reached();
bool limit_hit = evse_is_limit_reached();
bool can_operate = evse_config_is_available() && evse_config_is_enabled();
if ((has_error || limit_hit || !sched_allowed || !can_operate || local_lb_paused) &&
@@ -114,6 +120,7 @@ static void evse_manager_handle_auth_on_tick(void)
!has_error && !limit_hit &&
!evse_state_get_authorized())
{
evse_session_clear_authorized_tag();
evse_state_set_authorized(true);
ESP_LOGI(TAG, "Authentication disabled → forced authorization (schedule ok, no error/limits).");
lb_clear_pause_state();
@@ -134,7 +141,8 @@ static void evse_manager_task(void *arg)
static void on_auth_event(void *arg, esp_event_base_t base, int32_t id, void *data)
{
(void)arg;
if (base != AUTH_EVENTS || !data) return;
if (base != AUTH_EVENTS || !data)
return;
switch (id)
{
@@ -142,11 +150,30 @@ static void on_auth_event(void *arg, esp_event_base_t base, int32_t id, void *da
{
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");
if (evt->authorized)
{
evse_session_set_authorized_tag(evt->tag);
}
else
{
evse_session_clear_authorized_tag();
}
evse_state_set_authorized(evt->authorized);
lb_clear_pause_state();
break;
}
case AUTH_EVENT_TAG_VERIFY:
{
const auth_tag_verify_event_t *evt = (const auth_tag_verify_event_t *)data;
ESP_LOGI(TAG, "Tag %s -> pending remote/OCPP verification", evt->tag);
portENTER_CRITICAL(&s_mgr_mux);
strncpy(s_pending_ocpp_tag, evt->tag, AUTH_TAG_MAX_LEN - 1);
s_pending_ocpp_tag[AUTH_TAG_MAX_LEN - 1] = '\0';
portEXIT_CRITICAL(&s_mgr_mux);
break;
}
case AUTH_EVENT_MODE_CHANGED:
case AUTH_EVENT_INIT:
{
@@ -155,8 +182,10 @@ static void on_auth_event(void *arg, esp_event_base_t base, int32_t id, void *da
portENTER_CRITICAL(&s_mgr_mux);
auth_enabled = (evt->mode != AUTH_MODE_OPEN);
s_pending_ocpp_tag[0] = '\0';
portEXIT_CRITICAL(&s_mgr_mux);
evse_session_clear_authorized_tag();
evse_state_set_authorized(false);
lb_clear_pause_state();
break;
@@ -170,7 +199,8 @@ static void on_loadbalancer_event(void *handler_arg, esp_event_base_t event_base
(void)handler_arg;
(void)event_base;
if (!event_data) return;
if (!event_data)
return;
if (event_id == LOADBALANCER_EVENT_INIT || event_id == LOADBALANCER_EVENT_STATE_CHANGED)
{
@@ -211,7 +241,7 @@ static void on_loadbalancer_event(void *handler_arg, esp_event_base_t event_base
portENTER_CRITICAL(&s_mgr_mux);
was_paused = lb_paused;
prev_auth = lb_prev_authorized;
prev_auth = lb_prev_authorized;
portEXIT_CRITICAL(&s_mgr_mux);
if (was_paused)
@@ -263,27 +293,55 @@ static void on_loadbalancer_event(void *handler_arg, esp_event_base_t event_base
static void on_ocpp_event(void *arg, esp_event_base_t base, int32_t id, void *data)
{
(void)arg;
if (base != OCPP_EVENTS) return;
if (base != OCPP_EVENTS)
return;
switch (id)
{
case OCPP_EVENT_AUTHORIZED:
ESP_LOGI(TAG, "[OCPP] Authorized");
{
char tag[AUTH_TAG_MAX_LEN];
portENTER_CRITICAL(&s_mgr_mux);
strncpy(tag, s_pending_ocpp_tag, AUTH_TAG_MAX_LEN - 1);
tag[AUTH_TAG_MAX_LEN - 1] = '\0';
s_pending_ocpp_tag[0] = '\0';
portEXIT_CRITICAL(&s_mgr_mux);
if (tag[0] != '\0')
{
evse_session_set_authorized_tag(tag);
ESP_LOGI(TAG, "[OCPP] Authorized tag=%s", tag);
}
else
{
ESP_LOGI(TAG, "[OCPP] Authorized");
}
evse_state_set_authorized(true);
lb_clear_pause_state();
break;
}
case OCPP_EVENT_AUTH_REJECTED:
case OCPP_EVENT_AUTH_TIMEOUT:
case OCPP_EVENT_REMOTE_STOP:
case OCPP_EVENT_STOP_TX:
ESP_LOGW(TAG, "[OCPP] Authorization/Stop");
portENTER_CRITICAL(&s_mgr_mux);
s_pending_ocpp_tag[0] = '\0';
portEXIT_CRITICAL(&s_mgr_mux);
evse_session_clear_authorized_tag();
evse_state_set_authorized(false);
lb_clear_pause_state();
break;
case OCPP_EVENT_REMOTE_START:
ESP_LOGI(TAG, "[OCPP] RemoteStart");
portENTER_CRITICAL(&s_mgr_mux);
s_pending_ocpp_tag[0] = '\0';
portEXIT_CRITICAL(&s_mgr_mux);
evse_session_clear_authorized_tag();
evse_state_set_authorized(true);
lb_clear_pause_state();
break;
@@ -317,21 +375,31 @@ static void on_ocpp_event(void *arg, esp_event_base_t base, int32_t id, void *da
static void on_sched_event(void *arg, esp_event_base_t base, int32_t id, void *data)
{
(void)arg;
if (base != SCHED_EVENTS || data == NULL) return;
if (base != SCHED_EVENTS || data == NULL)
return;
const sched_event_state_t *ev = (const sched_event_state_t *)data;
portENTER_CRITICAL(&s_sched_mux);
s_sched_allowed = ev->allowed_now;
s_sched_current_a = ev->current_limit_a;
portEXIT_CRITICAL(&s_sched_mux);
ESP_LOGI(TAG, "[SCHED] allowed_now=%d", (int)ev->allowed_now);
ESP_LOGI(TAG, "[SCHED] allowed_now=%d current=%uA",
(int)ev->allowed_now, (unsigned)ev->current_limit_a);
if (!ev->allowed_now && evse_state_get_authorized())
{
ESP_LOGI(TAG, "[SCHED] window closed → stopping session (authorized=false)");
evse_session_clear_authorized_tag();
evse_state_set_authorized(false);
}
// ✅ aplica corrente quando permitido
if (ev->allowed_now && ev->current_limit_a > 0)
{
evse_set_runtime_charging_current(ev->current_limit_a);
}
}
void evse_manager_init(void)