#include #include #include // <- Necessário para bool #include "freertos/FreeRTOS.h" #include "freertos/semphr.h" #include "esp_log.h" #include "esp_timer.h" #include "nvs.h" #include "energy_meter.h" #include "meter.h" #include "serial_mdb.h" #define NVS_NAMESPACE "evse_emeter" #define NVS_MODEL "model" #define NVS_STATE "state" static const char *TAG = "energy_meter"; static nvs_handle nvs; static bool state = false; static meter_model_t model = ENERGY_METER_NONE; static uint16_t power = 0; static bool has_session = false; static int64_t start_time = 0; static uint32_t charging_time = 0; // ms static uint32_t consumption = 0; // Ws static float cur[3] = {0, 0, 0}; static float vlt[3] = {0, 0, 0}; static int64_t prev_time = 0; static void set_calc_power(float p, uint32_t delta_ms) { consumption += roundf((p * delta_ms) / 1000.0f); power = roundf(p); } void energy_meter_init(void) { ESP_LOGI(TAG, "energy_meter_init"); ESP_ERROR_CHECK(nvs_open(NVS_NAMESPACE, NVS_READWRITE, &nvs)); uint8_t u8 = ENERGY_METER_NONE; nvs_get_u8(nvs, NVS_MODEL, &u8); model = u8; } bool meter_get_state(void) { return serial_mdb_get_meter_state(); } esp_err_t meter_set_state(bool _state) { state = _state; nvs_set_u8(nvs, NVS_STATE, state); nvs_commit(nvs); return ESP_OK; } meter_model_t meter_get_model(void) { return model; } esp_err_t meter_set_model(meter_model_t _model) { ESP_LOGI(TAG, "meter_set_model"); if (_model < 0 || _model > ENERGY_METER_ORNO_517) { ESP_LOGE(TAG, "Model out of range"); return ESP_ERR_INVALID_ARG; } model = _model; nvs_set_u8(nvs, NVS_MODEL, model); nvs_commit(nvs); serial_mdb_set_model(model != ENERGY_METER_NONE); return ESP_OK; } void energy_meter_start_session(void) { if (!has_session) { ESP_LOGI(TAG, "Start session"); start_time = esp_timer_get_time(); has_session = true; //meter_start(); } } void energy_meter_stop_session(void) { if (has_session) { ESP_LOGI(TAG, "Stop session"); start_time = 0; consumption = 0; charging_time = 0; has_session = false; //meter_stop(); } } void energy_meter_process(bool charging, uint16_t charging_current) { int64_t now = esp_timer_get_time(); uint32_t delta_ms = (now - prev_time) / 1000; if (charging && meter_is_running()) { MeterData data = meter_getData(); vlt[0] = data.vrmsA; vlt[1] = data.vrmsB; vlt[2] = data.vrmsC; cur[0] = data.irmsA; cur[1] = data.irmsB; cur[2] = data.irmsC; uint32_t total_power = data.wattA + data.wattB + data.wattC; set_calc_power((float)total_power, delta_ms); charging_time += delta_ms; } else { vlt[0] = vlt[1] = vlt[2] = 0; cur[0] = cur[1] = cur[2] = 0; power = 0; } prev_time = now; } uint32_t energy_meter_get_power(void) { return power; } uint32_t energy_meter_get_session_time(void) { return has_session ? (esp_timer_get_time() - start_time) / 1000000 : 0; } uint32_t energy_meter_get_charging_time(void) { return charging_time / 1000; } uint32_t energy_meter_get_consumption(void) { return consumption / 3600; } void energy_meter_get_voltage(float *voltage) { memcpy(voltage, vlt, sizeof(vlt)); } float energy_meter_get_l1_voltage(void) { return vlt[0]; } float energy_meter_get_l2_voltage(void) { return vlt[1]; } float energy_meter_get_l3_voltage(void) { return vlt[2]; } void energy_meter_get_current(float *current) { memcpy(current, cur, sizeof(cur)); } float energy_meter_get_l1_current(void) { return cur[0]; } float energy_meter_get_l2_current(void) { return cur[1]; } float energy_meter_get_l3_current(void) { return cur[2]; } const char *meter_state_to_str(bool state) { return state == true ? "CONNECTED" : "NOT CONNECTED"; } const char *meter_model_to_str(meter_model_t mode) { switch (mode) { case ENERGY_METER_NONE: return "NONE"; case ENERGY_METER_ORNO_515: return "OR-WE-515"; case ENERGY_METER_ORNO_517: return "OR-WE-517"; default: return "NONE"; } } meter_model_t meter_str_to_model(const char *str) { if (!strcmp(str, "NONE")) { return ENERGY_METER_NONE; } if (!strcmp(str, "OR-WE-515")) { return ENERGY_METER_ORNO_515; } if (!strcmp(str, "OR-WE-517")) { return ENERGY_METER_ORNO_517; } return ENERGY_METER_NONE; }