#include "evse_meter.h" #include "meter_events.h" #include "esp_event.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include #include static const char *TAG = "evse_meter"; static SemaphoreHandle_t meter_mutex; typedef struct { uint32_t power_watts[EVSE_METER_PHASE_COUNT]; float voltage[EVSE_METER_PHASE_COUNT]; float current[EVSE_METER_PHASE_COUNT]; uint32_t energy_wh; } evse_meter_data_t; static evse_meter_data_t meter_data; static void on_meter_event_dispatcher(void *arg, esp_event_base_t base, int32_t id, void *data) { if (base == METER_EVENT && id == METER_EVENT_DATA_READY && data) { const meter_event_data_t *evt = (const meter_event_data_t *)data; if (strcmp(evt->source, "EVSE") == 0) { evse_meter_on_meter_event(arg, data); } } } void evse_meter_on_meter_event(void *arg, void *event_data) { const meter_event_data_t *evt = (const meter_event_data_t *)event_data; if (!evt) return; xSemaphoreTake(meter_mutex, portMAX_DELAY); for (int i = 0; i < EVSE_METER_PHASE_COUNT; ++i) { meter_data.power_watts[i] = evt->watt[i]; meter_data.voltage[i] = evt->vrms[i]; meter_data.current[i] = evt->irms[i]; } meter_data.energy_wh = (uint32_t)(evt->total_energy); xSemaphoreGive(meter_mutex); ESP_LOGD(TAG, "Meter updated: power[W]={%" PRIu32 ",%" PRIu32 ",%" PRIu32 "}, " "voltage[V]={%.2f,%.2f,%.2f}, " "current[A]={%.2f,%.2f,%.2f}, " "total_energy=%" PRIu32 "Wh", meter_data.power_watts[0], meter_data.power_watts[1], meter_data.power_watts[2], meter_data.voltage[0], meter_data.voltage[1], meter_data.voltage[2], meter_data.current[0], meter_data.current[1], meter_data.current[2], meter_data.energy_wh); } void evse_meter_init(void) { meter_mutex = xSemaphoreCreateMutex(); ESP_ERROR_CHECK(meter_mutex ? ESP_OK : ESP_FAIL); ESP_ERROR_CHECK(esp_event_handler_register( METER_EVENT, METER_EVENT_DATA_READY, on_meter_event_dispatcher, NULL)); memset(&meter_data, 0, sizeof(meter_data)); ESP_LOGI(TAG, "EVSE Meter listener registered."); } int evse_meter_get_instant_power(void) { xSemaphoreTake(meter_mutex, portMAX_DELAY); int sum = 0; for (int i = 0; i < EVSE_METER_PHASE_COUNT; ++i) { sum += meter_data.power_watts[i]; } xSemaphoreGive(meter_mutex); return sum; } int evse_meter_get_total_energy(void) { xSemaphoreTake(meter_mutex, portMAX_DELAY); int val = meter_data.energy_wh; xSemaphoreGive(meter_mutex); return val; } void evse_meter_get_power(int power[EVSE_METER_PHASE_COUNT]) { xSemaphoreTake(meter_mutex, portMAX_DELAY); for (int i = 0; i < EVSE_METER_PHASE_COUNT; ++i) { power[i] = meter_data.power_watts[i]; } xSemaphoreGive(meter_mutex); } void evse_meter_get_voltage(float voltage[EVSE_METER_PHASE_COUNT]) { xSemaphoreTake(meter_mutex, portMAX_DELAY); for (int i = 0; i < EVSE_METER_PHASE_COUNT; ++i) { voltage[i] = meter_data.voltage[i]; } xSemaphoreGive(meter_mutex); } void evse_meter_get_current(float current[EVSE_METER_PHASE_COUNT]) { xSemaphoreTake(meter_mutex, portMAX_DELAY); for (int i = 0; i < EVSE_METER_PHASE_COUNT; ++i) { current[i] = meter_data.current[i]; } xSemaphoreGive(meter_mutex); }