122 lines
3.4 KiB
C
122 lines
3.4 KiB
C
#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 <string.h>
|
|
#include <inttypes.h>
|
|
|
|
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_LOGI(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);
|
|
}
|