// === Início de: components/meter_manager/driver/meter_orno/meter_orno516.c === #include "meter_orno516.h" #include "meter_events.h" #include "modbus_params.h" #include "mbcontroller.h" #include "esp_log.h" #include "driver/uart.h" #include #define TAG "serial_mdb_orno516" #define MB_PORT_NUM 2 #define MB_DEV_SPEED 9600 #define MB_UART_TXD 17 #define MB_UART_RXD 16 #define MB_UART_RTS 5 #define UPDATE_INTERVAL (5000 / portTICK_PERIOD_MS) #define POLL_INTERVAL (100 / portTICK_PERIOD_MS) #define HOLD_OFFSET(field) ((uint16_t)(offsetof(holding_reg_params_t, field) + 1)) #define STR(fieldname) ((const char *)(fieldname)) #define OPTS(min_val, max_val, step_val) {.opt1 = min_val, .opt2 = max_val, .opt3 = step_val} // Estado do driver static bool is_initialized = false; static TaskHandle_t meter_task = NULL; #define L1VOLTAGE 0x000E #define L2VOLTAGE 0x0010 #define L3VOLTAGE 0x0012 #define L1CURRENT 0x0016 #define L2CURRENT 0x0018 #define L3CURRENT 0x001A #define TOTALACTIVEPOWER 0x001C enum { CID_L1_CURRENT = 0, CID_L2_CURRENT, CID_L3_CURRENT, CID_L1_VOLTAGE, CID_L2_VOLTAGE, CID_L3_VOLTAGE, CID_TOTAL_ACTIVE_POWER }; const mb_parameter_descriptor_t device_parameters_orno516[] = { {CID_L1_CURRENT, STR("L1 Current"), STR("A"), 1, MB_PARAM_HOLDING, L1CURRENT, 2, HOLD_OFFSET(l1_current), PARAM_TYPE_FLOAT, 4, OPTS(-1000, 1000, 0.1), PAR_PERMS_READ}, {CID_L2_CURRENT, STR("L2 Current"), STR("A"), 1, MB_PARAM_HOLDING, L2CURRENT, 2, HOLD_OFFSET(l2_current), PARAM_TYPE_FLOAT, 4, OPTS(-1000, 1000, 0.1), PAR_PERMS_READ}, {CID_L3_CURRENT, STR("L3 Current"), STR("A"), 1, MB_PARAM_HOLDING, L3CURRENT, 2, HOLD_OFFSET(l3_current), PARAM_TYPE_FLOAT, 4, OPTS(-1000, 1000, 0.1), PAR_PERMS_READ}, {CID_L1_VOLTAGE, STR("L1 Voltage"), STR("V"), 1, MB_PARAM_HOLDING, L1VOLTAGE, 2, HOLD_OFFSET(l1_voltage), PARAM_TYPE_FLOAT, 4, OPTS(0, 300, 0.1), PAR_PERMS_READ}, {CID_L2_VOLTAGE, STR("L2 Voltage"), STR("V"), 1, MB_PARAM_HOLDING, L2VOLTAGE, 2, HOLD_OFFSET(l2_voltage), PARAM_TYPE_FLOAT, 4, OPTS(0, 300, 0.1), PAR_PERMS_READ}, {CID_L3_VOLTAGE, STR("L3 Voltage"), STR("V"), 1, MB_PARAM_HOLDING, L3VOLTAGE, 2, HOLD_OFFSET(l3_voltage), PARAM_TYPE_FLOAT, 4, OPTS(0, 300, 0.1), PAR_PERMS_READ}, {CID_TOTAL_ACTIVE_POWER, STR("Total Active Power"), STR("W"), 1, MB_PARAM_HOLDING, TOTALACTIVEPOWER, 2, HOLD_OFFSET(total_active_power), PARAM_TYPE_FLOAT, 4, OPTS(0, 100000, 1), PAR_PERMS_READ} }; const uint16_t num_device_parameters_orno516 = sizeof(device_parameters_orno516) / sizeof(device_parameters_orno516[0]); float ReverseFloat(const float inFloat) { float retVal; char *floatToConvert = (char *)&inFloat; char *returnFloat = (char *)&retVal; returnFloat[0] = floatToConvert[2]; returnFloat[1] = floatToConvert[3]; returnFloat[2] = floatToConvert[0]; returnFloat[3] = floatToConvert[1]; return retVal; } static void *get_param_ptr(const mb_parameter_descriptor_t *param) { if (!param || param->param_offset == 0) return NULL; return ((uint8_t *)&holding_reg_params + param->param_offset - 1); } static void meter_orno516_post_event(float *voltage, float *current, int *power) { meter_event_data_t evt = { .source = "GRID", .frequency = 0.0f, // ORNO-516 não fornece .power_factor = 0.0f, // idem .total_energy = 0.0f // idem }; memcpy(evt.vrms, voltage, sizeof(evt.vrms)); memcpy(evt.irms, current, sizeof(evt.irms)); memcpy(evt.watt, power, sizeof(evt.watt)); esp_err_t err = esp_event_post(METER_EVENT, METER_EVENT_DATA_READY, &evt, sizeof(evt), pdMS_TO_TICKS(10)); if (err != ESP_OK) { ESP_LOGW(TAG, "Falha ao emitir evento: %s", esp_err_to_name(err)); } } static void serial_mdb_task(void *param) { esp_err_t err; const mb_parameter_descriptor_t *desc = NULL; float voltage[3] = {0}, current[3] = {0}; int power[3] = {0}; while (1) { for (uint16_t cid = 0; cid < num_device_parameters_orno516; cid++) { err = mbc_master_get_cid_info(cid, &desc); if (err != ESP_OK || !desc) continue; void *data_ptr = get_param_ptr(desc); uint8_t type = 0; err = mbc_master_get_parameter(cid, (char *)desc->param_key, (uint8_t *)data_ptr, &type); if (err == ESP_OK && data_ptr) { float val = ReverseFloat(*(float *)data_ptr); ESP_LOGI(TAG, "%s: %.2f %s", desc->param_key, val, desc->param_units); switch (cid) { case CID_L1_VOLTAGE: voltage[0] = val; break; case CID_L2_VOLTAGE: voltage[1] = val; break; case CID_L3_VOLTAGE: voltage[2] = val; break; case CID_L1_CURRENT: current[0] = val; break; case CID_L2_CURRENT: current[1] = val; break; case CID_L3_CURRENT: current[2] = val; break; case CID_TOTAL_ACTIVE_POWER: power[0] = (int)(val / 3); power[1] = (int)(val / 3); power[2] = (int)(val / 3); break; default: break; } } else { ESP_LOGE(TAG, "CID %u (%s) read failed: %s", cid, desc->param_key, esp_err_to_name(err)); } vTaskDelay(POLL_INTERVAL); } meter_orno516_post_event(voltage, current, power); vTaskDelay(UPDATE_INTERVAL); } } esp_err_t meter_orno516_init(void) { if (is_initialized) { ESP_LOGW(TAG, "Already initialized"); return ESP_ERR_INVALID_STATE; } // Tenta apagar UART apenas se estiver inicializada if (uart_is_driver_installed(MB_PORT_NUM)) { uart_driver_delete(MB_PORT_NUM); ESP_LOGI(TAG, "UART driver deleted"); } mbc_master_destroy(); // OK mesmo que não esteja inicializado mb_communication_info_t comm = { .port = MB_PORT_NUM, .mode = MB_MODE_RTU, .baudrate = MB_DEV_SPEED, .parity = UART_PARITY_EVEN }; void *handler = NULL; ESP_ERROR_CHECK(mbc_master_init(MB_PORT_SERIAL_MASTER, &handler)); ESP_ERROR_CHECK(mbc_master_setup(&comm)); ESP_ERROR_CHECK(uart_set_pin(MB_PORT_NUM, MB_UART_TXD, MB_UART_RXD, MB_UART_RTS, UART_PIN_NO_CHANGE)); ESP_ERROR_CHECK(mbc_master_start()); ESP_ERROR_CHECK(uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX)); vTaskDelay(pdMS_TO_TICKS(5)); ESP_ERROR_CHECK(mbc_master_set_descriptor(device_parameters_orno516, num_device_parameters_orno516)); is_initialized = true; return ESP_OK; } esp_err_t meter_orno516_start(void) { if (!is_initialized) { ESP_LOGE(TAG, "Not initialized"); return ESP_ERR_INVALID_STATE; } if (meter_task == NULL) { xTaskCreate(serial_mdb_task, "meter_orno516_task", 4096, NULL, 3, &meter_task); ESP_LOGI(TAG, "Task started"); } return ESP_OK; } void meter_orno516_stop(void) { if (!is_initialized) { ESP_LOGW(TAG, "Not initialized, skipping stop"); return; } if (meter_task) { vTaskDelete(meter_task); meter_task = NULL; ESP_LOGI(TAG, "Task stopped"); } mbc_master_destroy(); if (uart_is_driver_installed(MB_PORT_NUM)) { uart_driver_delete(MB_PORT_NUM); ESP_LOGI(TAG, "UART driver deleted"); } is_initialized = false; ESP_LOGI(TAG, "Meter ORNO-516 cleaned up"); } // === Fim de: components/meter_manager/driver/meter_orno/meter_orno516.c === // === Início de: components/meter_manager/driver/meter_zigbee/meter_zigbee.h === #pragma once #ifdef __cplusplus extern "C" { #endif #include #include #include "esp_err.h" /** * @brief Inicializa o driver do medidor Zigbee (UART, mutex, etc.). * * @return ESP_OK se a inicialização for bem-sucedida, erro caso contrário. */ esp_err_t meter_zigbee_init(void); /** * @brief Inicia a tarefa de leitura dos dados do medidor Zigbee. * * @return ESP_OK se a tarefa for iniciada com sucesso, erro caso contrário. */ esp_err_t meter_zigbee_start(void); /** * @brief Interrompe a tarefa e limpa recursos (UART, mutex, etc.). */ void meter_zigbee_stop(void); #ifdef __cplusplus } #endif // === Fim de: components/meter_manager/driver/meter_zigbee/meter_zigbee.h === // === Início de: components/meter_manager/driver/meter_zigbee/meter_zigbee.c === #include "meter_zigbee.h" #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/semphr.h" #include "esp_log.h" #include "esp_system.h" #include "driver/uart.h" #include "driver/gpio.h" #include "meter_events.h" #define TAG "meter_zigbee" // UART config #define UART_PORT UART_NUM_1 #define TXD_PIN GPIO_NUM_17 #define RXD_PIN GPIO_NUM_16 #define UART_BUF_SIZE 128 #define RX_FRAME_SIZE 14 // Zigbee Attribute IDs #define ATTR_CURRENT_L1 0x0006 #define ATTR_CURRENT_L2 0x0007 #define ATTR_CURRENT_L3 0x0008 #define ATTR_VOLTAGE_L1 0x0266 #define ATTR_CURRENT_L1_ALT 0x0267 #define ATTR_POWER_L1 0x0268 #define ATTR_VOLTAGE_L2 0x0269 #define ATTR_CURRENT_L2_ALT 0x026A #define ATTR_POWER_L2 0x026B #define ATTR_VOLTAGE_L3 0x026C #define ATTR_CURRENT_L3_ALT 0x026D #define ATTR_POWER_L3 0x026E #define ATTR_FREQUENCY 0x0265 #define ATTR_POWER_FACTOR 0x020F #define ATTR_TOTAL_ENERGY 0x0201 #define PHASE_COUNT 3 #define PHASE_L1 0 #define PHASE_L2 1 #define PHASE_L3 2 // Internal meter state typedef struct { float vrms[PHASE_COUNT]; float irms[PHASE_COUNT]; int watt[PHASE_COUNT]; int var[PHASE_COUNT]; int va[PHASE_COUNT]; float frequency; float power_factor; float total_energy; } meter_zigbee_data_t; static bool phase_updated[PHASE_COUNT] = {false, false, false}; static meter_zigbee_data_t meter_data = {0}; static SemaphoreHandle_t meter_mutex = NULL; static TaskHandle_t meter_zigbee_task = NULL; static void meter_zigbee_post_event(void) { meter_event_data_t evt = { .source = "GRID", .frequency = meter_data.frequency, .power_factor = meter_data.power_factor, .total_energy = meter_data.total_energy }; memcpy(evt.vrms, meter_data.vrms, sizeof(evt.vrms)); memcpy(evt.irms, meter_data.irms, sizeof(evt.irms)); memcpy(evt.watt, meter_data.watt, sizeof(evt.watt)); esp_err_t err = esp_event_post(METER_EVENT, METER_EVENT_DATA_READY, &evt, sizeof(evt), pdMS_TO_TICKS(10)); if (err != ESP_OK) { ESP_LOGW(TAG, "Falha ao emitir evento: %s", esp_err_to_name(err)); } } static void handle_zigbee_frame(const uint8_t *buf, size_t len) { ESP_LOGI(TAG, "Received UART frame (%d bytes):", len); ESP_LOG_BUFFER_HEX(TAG, buf, len); if (len < RX_FRAME_SIZE) { ESP_LOGW(TAG, "Invalid frame: too short (len = %d)", len); return; } uint16_t attr = buf[2] | (buf[3] << 8); uint8_t size = buf[5]; if (size != 8) { ESP_LOGW(TAG, "Unsupported payload size: %d", size); return; } uint16_t volt_raw = (buf[6] << 8) | buf[7]; uint32_t current_raw = (buf[8] << 16) | (buf[9] << 8) | buf[10]; uint32_t power_raw = (buf[11] << 16) | (buf[12] << 8) | buf[13]; float volt = volt_raw / 10.0f; float current = current_raw / 100.0f; float power = power_raw / 1000.0f; ESP_LOGI(TAG, "Parsed Attr 0x%04X: V=%.1fV I=%.2fA P=%.1fW", attr, volt, current, power); if (xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) { switch (attr) { case ATTR_CURRENT_L1: case ATTR_CURRENT_L1_ALT: meter_data.irms[PHASE_L1] = current; meter_data.vrms[PHASE_L1] = volt; meter_data.watt[PHASE_L1] = (int)power; phase_updated[PHASE_L1] = true; break; case ATTR_CURRENT_L2: case ATTR_CURRENT_L2_ALT: meter_data.irms[PHASE_L2] = current; meter_data.vrms[PHASE_L2] = volt; meter_data.watt[PHASE_L2] = (int)power; phase_updated[PHASE_L2] = true; break; case ATTR_CURRENT_L3: case ATTR_CURRENT_L3_ALT: meter_data.irms[PHASE_L3] = current; meter_data.vrms[PHASE_L3] = volt; meter_data.watt[PHASE_L3] = (int)power; phase_updated[PHASE_L3] = true; break; case ATTR_POWER_FACTOR: meter_data.power_factor = current; break; case ATTR_FREQUENCY: meter_data.frequency = current; break; case ATTR_TOTAL_ENERGY: meter_data.total_energy = current; break; default: ESP_LOGW(TAG, "Unknown attr: 0x%04X", attr); break; } xSemaphoreGive(meter_mutex); } // Verifica se todas as 3 fases foram atualizadas if (phase_updated[PHASE_L1] && phase_updated[PHASE_L2] && phase_updated[PHASE_L3]) { meter_zigbee_post_event(); memset(phase_updated, 0, sizeof(phase_updated)); } } static void meter_zigbee_task_func(void *param) { uint8_t *buf = malloc(RX_FRAME_SIZE); if (!buf) { ESP_LOGE(TAG, "Failed to allocate buffer"); vTaskDelete(NULL); return; } ESP_LOGI(TAG, "Zigbee meter task started"); while (1) { int len = uart_read_bytes(UART_PORT, buf, RX_FRAME_SIZE, pdMS_TO_TICKS(5000)); if (len == RX_FRAME_SIZE) { handle_zigbee_frame(buf, len); } else if (len == 0) { ESP_LOGD(TAG, "UART timeout with no data"); } else { ESP_LOGW(TAG, "Incomplete frame received (%d bytes)", len); } } free(buf); vTaskDelete(NULL); } esp_err_t meter_zigbee_init(void) { ESP_LOGI(TAG, "Initializing Zigbee meter"); if (!meter_mutex) { meter_mutex = xSemaphoreCreateMutex(); if (!meter_mutex) return ESP_ERR_NO_MEM; } uart_config_t config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, .source_clk = UART_SCLK_DEFAULT }; ESP_ERROR_CHECK(uart_param_config(UART_PORT, &config)); ESP_ERROR_CHECK(uart_set_pin(UART_PORT, TXD_PIN, RXD_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE)); ESP_ERROR_CHECK(uart_driver_install(UART_PORT, UART_BUF_SIZE * 2, 0, 0, NULL, 0)); return ESP_OK; } esp_err_t meter_zigbee_start(void) { if (meter_zigbee_task) return ESP_ERR_INVALID_STATE; xTaskCreate(meter_zigbee_task_func, "meter_zigbee_task", 4096, NULL, 3, &meter_zigbee_task); return ESP_OK; } void meter_zigbee_stop(void) { if (meter_zigbee_task) { vTaskDelete(meter_zigbee_task); meter_zigbee_task = NULL; } uart_driver_delete(UART_PORT); if (meter_mutex) { vSemaphoreDelete(meter_mutex); meter_mutex = NULL; } } bool meter_zigbee_is_running(void) { return meter_zigbee_task != NULL; } // === Fim de: components/meter_manager/driver/meter_zigbee/meter_zigbee.c === // === Início de: components/meter_manager/src/meter_manager.c === #include "meter_manager.h" #include "esp_log.h" #include "meter_ade7758.h" #include "meter_orno513.h" #include "meter_orno516.h" #include "meter_zigbee.h" #include "nvs_flash.h" #include "nvs.h" #include static const char *TAG = "meter_manager"; // Tipos de medidores EVSE e GRID static meter_type_t meter_evse_type = METER_TYPE_NONE; static meter_type_t meter_grid_type = METER_TYPE_NONE; #define NVS_NAMESPACE "meterconfig" #define NVS_EVSE_MODEL "evse_model" #define NVS_GRID_MODEL "grid_model" // Função unificada para ler ou inicializar um modelo de medidor static esp_err_t load_or_init_meter_model(const char *key, meter_type_t *type) { nvs_handle_t handle; esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &handle); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to open NVS handle for %s: %s", key, esp_err_to_name(err)); return err; } uint8_t value = 0; err = nvs_get_u8(handle, key, &value); if (err == ESP_OK && value <= METER_TYPE_TRIF_ZIGBEE) { *type = (meter_type_t)value; ESP_LOGI(TAG, "Loaded meter type %d from NVS key '%s'", value, key); } else { *type = METER_TYPE_NONE; nvs_set_u8(handle, key, *type); nvs_commit(handle); ESP_LOGW(TAG, "Invalid or missing key '%s', setting default (NONE)", key); } nvs_close(handle); return ESP_OK; } static esp_err_t write_meter_model_to_nvs(const char *key, meter_type_t meter_type) { nvs_handle_t handle; esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &handle); if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to open NVS handle for writing"); return err; } err = nvs_set_u8(handle, key, (uint8_t)meter_type); if (err == ESP_OK) { err = nvs_commit(handle); ESP_LOGI(TAG, "Saved meter type %d to NVS key '%s'", meter_type, key); } else { ESP_LOGE(TAG, "Failed to write meter type to NVS key '%s'", key); } nvs_close(handle); return err; } // Função para inicializar o medidor EVSE esp_err_t meter_manager_evse_init() { esp_err_t err = load_or_init_meter_model(NVS_EVSE_MODEL, &meter_evse_type); if (err != ESP_OK) return err; ESP_LOGI(TAG, "Initializing EVSE meter of type %s", meter_type_to_str(meter_evse_type)); switch (meter_evse_type) { case METER_TYPE_NONE: return ESP_OK; case METER_TYPE_ADE7758: return meter_ade7758_init(); case METER_TYPE_ORNO513: return meter_orno513_init(); case METER_TYPE_ORNO516: return meter_orno516_init(); case METER_TYPE_MONO_ZIGBEE: case METER_TYPE_TRIF_ZIGBEE: return meter_zigbee_init(); default: return ESP_ERR_INVALID_ARG; } } esp_err_t meter_manager_grid_init() { esp_err_t err = load_or_init_meter_model(NVS_GRID_MODEL, &meter_grid_type); if (err != ESP_OK) return err; ESP_LOGI(TAG, "Initializing GRID meter of type %s", meter_type_to_str(meter_grid_type)); switch (meter_grid_type) { case METER_TYPE_NONE: return ESP_OK; case METER_TYPE_ADE7758: return meter_ade7758_init(); case METER_TYPE_ORNO513: return meter_orno513_init(); case METER_TYPE_ORNO516: return meter_orno516_init(); case METER_TYPE_MONO_ZIGBEE: case METER_TYPE_TRIF_ZIGBEE: return meter_zigbee_init(); default: return ESP_ERR_INVALID_ARG; } } esp_err_t meter_manager_grid_start() { meter_type_t type = meter_manager_grid_get_model(); switch (type) { case METER_TYPE_NONE: return ESP_OK; case METER_TYPE_ADE7758: return meter_ade7758_start(); case METER_TYPE_ORNO513: return meter_orno513_start(); case METER_TYPE_ORNO516: return meter_orno516_start(); case METER_TYPE_MONO_ZIGBEE: case METER_TYPE_TRIF_ZIGBEE: return meter_zigbee_start(); default: return ESP_ERR_INVALID_ARG; } } esp_err_t meter_manager_grid_stop(void) { meter_type_t type = meter_manager_grid_get_model(); switch (type) { case METER_TYPE_NONE: return ESP_OK; case METER_TYPE_ADE7758: meter_ade7758_stop(); break; case METER_TYPE_ORNO513: meter_orno513_stop(); break; case METER_TYPE_ORNO516: meter_orno516_stop(); break; case METER_TYPE_MONO_ZIGBEE: case METER_TYPE_TRIF_ZIGBEE: meter_zigbee_stop(); break; default: return ESP_ERR_INVALID_ARG; } return ESP_OK; } esp_err_t meter_manager_evse_set_model(meter_type_t meter_type) { meter_evse_type = meter_type; return write_meter_model_to_nvs(NVS_EVSE_MODEL, meter_evse_type); } esp_err_t meter_manager_grid_set_model(meter_type_t meter_type) { meter_grid_type = meter_type; return write_meter_model_to_nvs(NVS_GRID_MODEL, meter_grid_type); } esp_err_t meter_manager_evse_start() { meter_type_t type = meter_manager_evse_get_model(); switch (type) { case METER_TYPE_NONE: return ESP_OK; case METER_TYPE_ADE7758: return meter_ade7758_start(); case METER_TYPE_ORNO513: return meter_orno513_start(); case METER_TYPE_ORNO516: return meter_orno516_start(); case METER_TYPE_MONO_ZIGBEE: case METER_TYPE_TRIF_ZIGBEE: return meter_zigbee_start(); default: return ESP_ERR_INVALID_ARG; } } esp_err_t meter_manager_evse_stop(void) { meter_type_t type = meter_manager_evse_get_model(); switch (type) { case METER_TYPE_NONE: return ESP_OK; case METER_TYPE_ADE7758: meter_ade7758_stop(); break; case METER_TYPE_ORNO513: meter_orno513_stop(); break; case METER_TYPE_ORNO516: meter_orno516_stop(); break; case METER_TYPE_MONO_ZIGBEE: case METER_TYPE_TRIF_ZIGBEE: meter_zigbee_stop(); break; default: return ESP_ERR_INVALID_ARG; } return ESP_OK; } bool meter_manager_evse_is_enabled(void) { return meter_manager_evse_get_model() != METER_TYPE_NONE; } meter_type_t meter_manager_evse_get_model(void) { return meter_evse_type; } meter_type_t meter_manager_grid_get_model(void) { return meter_grid_type; } const char* meter_type_to_str(meter_type_t type) { switch (type) { case METER_TYPE_NONE: return "NENHUM"; case METER_TYPE_ADE7758: return "IC ADE"; case METER_TYPE_ORNO513: return "ORNO-513"; case METER_TYPE_ORNO516: return "ORNO-516"; case METER_TYPE_MONO_ZIGBEE: return "MONO-ZIGBEE"; case METER_TYPE_TRIF_ZIGBEE: return "TRIF-ZIGBEE"; default: return "NENHUM"; } } meter_type_t string_to_meter_type(const char *str) { if (!str) return METER_TYPE_NONE; if (strcmp(str, "IC ADE") == 0) return METER_TYPE_ADE7758; if (strcmp(str, "ORNO-513") == 0) return METER_TYPE_ORNO513; if (strcmp(str, "ORNO-516") == 0) return METER_TYPE_ORNO516; if (strcmp(str, "MONO-ZIGBEE") == 0) return METER_TYPE_MONO_ZIGBEE; if (strcmp(str, "TRIF-ZIGBEE") == 0) return METER_TYPE_TRIF_ZIGBEE; return METER_TYPE_NONE; } // === Fim de: components/meter_manager/src/meter_manager.c === // === Início de: components/meter_manager/src/meter_events.c === #include "meter_events.h" // Define a base de eventos ESP_EVENT_DEFINE_BASE(METER_EVENT); // === Fim de: components/meter_manager/src/meter_events.c === // === Início de: components/meter_manager/include/meter_manager.h === #ifndef METER_MANAGER_H #define METER_MANAGER_H #include "esp_err.h" #include // Para garantir que 'bool' seja reconhecido // Definindo tipos de medidores possíveis para EVSE e Grid typedef enum { METER_TYPE_NONE, // Nenhum Medidor METER_TYPE_ADE7758, // ADE7758 METER_TYPE_ORNO513, // ORNO 513 METER_TYPE_ORNO516, // ORNO 516 METER_TYPE_MONO_ZIGBEE, // Medidor Zigbee (Mono) METER_TYPE_TRIF_ZIGBEE // Medidor Zigbee (Trifásico) } meter_type_t; /** * @brief Funções para gerenciar o medidor EVSE (ex: ADE7758). */ // Inicializa o medidor EVSE com o tipo especificado (ex: ADE7758) esp_err_t meter_manager_evse_init(void); // Inicia o medidor EVSE com o tipo especificado esp_err_t meter_manager_evse_start(void); // Para o medidor EVSE esp_err_t meter_manager_evse_stop(void); // Verifica se o medidor EVSE está habilitado bool meter_manager_evse_is_enabled(void); // Define o modelo do medidor EVSE (ADE7758, etc) esp_err_t meter_manager_evse_set_model(meter_type_t meter_type); // Retorna o modelo do medidor EVSE (ADE7758, etc) meter_type_t meter_manager_evse_get_model(void); /** * @brief Funções para gerenciar o medidor Grid (ORNO 513, ORNO 516, Zigbee). */ // Inicializa o medidor Grid com o tipo especificado (ORNO 513, ORNO 516, Zigbee) esp_err_t meter_manager_grid_init(void); // Inicia o medidor Grid com o tipo especificado esp_err_t meter_manager_grid_start(void); // Para o medidor Grid esp_err_t meter_manager_grid_stop(void); // Habilita ou desabilita o medidor Grid void meter_manager_grid_set_enabled(bool value); // Define o modelo do medidor Grid (ORNO 513, ORNO 516, Zigbee) esp_err_t meter_manager_grid_set_model(meter_type_t meter_type); // Retorna o modelo do medidor Grid (ORNO 513, ORNO 516, Zigbee) meter_type_t meter_manager_grid_get_model(void); // Função auxiliar para converter o tipo de medidor em uma string const char* meter_type_to_str(meter_type_t type); meter_type_t string_to_meter_type(const char *str); #endif // METER_MANAGER_H // === Fim de: components/meter_manager/include/meter_manager.h === // === Início de: components/meter_manager/include/meter_events.h === #ifndef METER_EVENTS_H #define METER_EVENTS_H #include "esp_event.h" #include "meter_manager.h" // Para meter_type_t #ifdef __cplusplus extern "C" { #endif // Base de eventos dos medidores ESP_EVENT_DECLARE_BASE(METER_EVENT); // IDs de eventos emitidos por medidores typedef enum { METER_EVENT_DATA_READY = 0, METER_EVENT_ERROR, METER_EVENT_STARTED, METER_EVENT_STOPPED } meter_event_id_t; // Estrutura de dados enviados com METER_EVENT_DATA_READY typedef struct { const char *source; // "GRID" ou "EVSE" float vrms[3]; // Tensão por fase float irms[3]; // Corrente por fase int watt[3]; // Potência ativa por fase float frequency; // Frequência da rede (Hz) float power_factor; // Fator de potência float total_energy; // Energia acumulada (kWh) } meter_event_data_t; #ifdef __cplusplus } #endif #endif // METER_EVENTS_H // === Fim de: components/meter_manager/include/meter_events.h ===