evse_link feature

This commit is contained in:
2025-08-05 16:55:11 +01:00
parent bd587a10c0
commit 0d0dc5b129
35 changed files with 4353 additions and 2257 deletions

View File

@@ -5,10 +5,9 @@
#include "driver/gpio.h"
#include "led.h"
#include "board_config.h"
#include "evse_error.h"
#include "evse_api.h"
#include "evse_events.h"
#include "evse_state.h"
#define LED_UPDATE_INTERVAL_MS 100
#define BLOCK_TIME pdMS_TO_TICKS(10)
static const char *TAG = "led";
@@ -24,32 +23,60 @@ typedef struct {
} led_t;
static led_t leds[LED_ID_MAX] = {0};
static TimerHandle_t led_update_timer = NULL;
static evse_state_t led_state = -1;
// ----------------------------
// Funções Internas
// ----------------------------
static void led_update_timer_callback(TimerHandle_t xTimer);
static void led_update(void);
static void led_apply_by_state(evse_state_t state);
static inline void led_gpio_write(gpio_num_t gpio, bool level) {
if (gpio != GPIO_NUM_NC)
gpio_set_level(gpio, level);
}
static void led_timer_callback(TimerHandle_t xTimer)
{
led_t *led = (led_t *)pvTimerGetTimerID(xTimer);
led->on = !led->on;
led_gpio_write(led->gpio, led->on);
gpio_set_level(led->gpio, led->on);
uint32_t next_time = led->on ? led->ontime : led->offtime;
xTimerChangePeriod(led->timer, pdMS_TO_TICKS(next_time), BLOCK_TIME);
}
// ----------------------------
// Event Handler: EVSE State
// ----------------------------
static void evse_led_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data) {
if (base != EVSE_EVENTS || id != EVSE_EVENT_STATE_CHANGED || data == NULL) return;
const evse_state_event_data_t *evt = (const evse_state_event_data_t *)data;
// Log do evento recebido
ESP_LOGI(TAG, "EVSE State Changed: state=%d", evt->state);
led_apply_pattern(LED_ID_STOP, LED_PATTERN_OFF);
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_OFF);
led_apply_pattern(LED_ID_ERROR, LED_PATTERN_OFF);
switch (evt->state) {
case EVSE_STATE_EVENT_IDLE:
ESP_LOGI(TAG, "EVSE_STATE_EVENT_IDLE");
led_apply_pattern(LED_ID_STOP, LED_PATTERN_ON);
break;
case EVSE_STATE_EVENT_WAITING:
ESP_LOGI(TAG, "EVSE_STATE_EVENT_WAITING");
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_ON);
break;
case EVSE_STATE_EVENT_CHARGING:
ESP_LOGI(TAG, "EVSE_STATE_EVENT_CHARGING");
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_CHARGING_EFFECT);
break;
case EVSE_STATE_EVENT_FAULT:
ESP_LOGI(TAG, "EVSE_STATE_EVENT_FAULT");
led_apply_pattern(LED_ID_ERROR, LED_PATTERN_BLINK_FAST);
break;
default:
ESP_LOGW(TAG, "Unknown state: %d", evt->state);
break;
}
}
// ----------------------------
// Inicialização
// ----------------------------
@@ -87,17 +114,20 @@ void led_init(void)
ESP_ERROR_CHECK(gpio_config(&io_conf));
}
if (!led_update_timer) {
led_update_timer = xTimerCreate("led_update_timer",
pdMS_TO_TICKS(LED_UPDATE_INTERVAL_MS),
pdTRUE, NULL,
led_update_timer_callback);
if (led_update_timer) {
xTimerStart(led_update_timer, BLOCK_TIME);
} else {
ESP_LOGE(TAG, "Failed to create LED update timer");
}
}
// Registra handler de evento EVSE
ESP_ERROR_CHECK(esp_event_handler_register(
EVSE_EVENTS,
EVSE_EVENT_STATE_CHANGED,
evse_led_event_handler,
NULL));
ESP_LOGI(TAG, "LED system initialized");
// Aplica o estado atual do EVSE aos LEDs
evse_state_event_data_t evt = {
.state = EVSE_STATE_EVENT_IDLE
};
evse_led_event_handler(NULL, EVSE_EVENTS, EVSE_EVENT_STATE_CHANGED, &evt);
}
// ----------------------------
@@ -111,7 +141,6 @@ void led_set_state(led_id_t led_id, uint16_t ontime, uint16_t offtime)
led_t *led = &leds[led_id];
if (led->gpio == GPIO_NUM_NC) return;
// Evita reconfiguração idêntica
if (led->ontime == ontime && led->offtime == offtime)
return;
@@ -124,13 +153,13 @@ void led_set_state(led_id_t led_id, uint16_t ontime, uint16_t offtime)
if (ontime == 0) {
led->on = false;
led_gpio_write(led->gpio, 0);
gpio_set_level(led->gpio, 0);
} else if (offtime == 0) {
led->on = true;
led_gpio_write(led->gpio, 1);
gpio_set_level(led->gpio, 1);
} else {
led->on = true;
led_gpio_write(led->gpio, 1);
gpio_set_level(led->gpio, 1);
if (!led->timer) {
led->timer = xTimerCreate("led_timer", pdMS_TO_TICKS(ontime),
@@ -180,66 +209,3 @@ void led_apply_pattern(led_id_t id, led_pattern_t pattern)
break;
}
}
// ----------------------------
// Controle por Estado
// ----------------------------
static void led_apply_by_state(evse_state_t state)
{
// Reset todos
led_apply_pattern(LED_ID_STOP, LED_PATTERN_OFF);
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_OFF);
led_apply_pattern(LED_ID_ERROR, LED_PATTERN_OFF);
switch (state) {
case EVSE_STATE_A:
led_apply_pattern(LED_ID_STOP, LED_PATTERN_ON);
break;
case EVSE_STATE_B1:
case EVSE_STATE_B2:
case EVSE_STATE_C1:
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_ON);
break;
case EVSE_STATE_C2:
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_CHARGING_EFFECT);
break;
case EVSE_STATE_D1:
case EVSE_STATE_D2:
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_BLINK_FAST);
break;
case EVSE_STATE_E:
case EVSE_STATE_F:
led_apply_pattern(LED_ID_ERROR, LED_PATTERN_BLINK_FAST);
break;
default:
break;
}
}
// ----------------------------
// Timer Update
// ----------------------------
static void led_update(void)
{
if (evse_error_is_active()) {
led_apply_pattern(LED_ID_ERROR, LED_PATTERN_BLINK_FAST);
led_apply_pattern(LED_ID_STOP, LED_PATTERN_OFF);
led_apply_pattern(LED_ID_CHARGING, LED_PATTERN_OFF);
return;
}
evse_state_t current = evse_get_state();
if (current != led_state) {
led_state = current;
led_apply_by_state(current);
}
}
static void led_update_timer_callback(TimerHandle_t xTimer)
{
(void)xTimer;
led_update();
}