new upgrade

This commit is contained in:
2025-12-21 23:28:26 +00:00
parent 82fa194bd8
commit 023644a887
99 changed files with 7457 additions and 7079 deletions

View File

@@ -10,10 +10,15 @@
#include "meter_zigbee.h"
#include "meter_ea777.h"
#include "nvs_flash.h"
#include "nvs.h"
#include <string.h>
#include "network_events.h"
#include "meter_events.h"
#include "esp_event.h"
#include "esp_timer.h"
// NEW:
#include "storage_service.h"
static const char *TAG = "meter_manager";
@@ -21,179 +26,200 @@ static const char *TAG = "meter_manager";
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"
#define STORE_NAMESPACE "meterconfig"
#define STORE_EVSE_MODEL "evse_model"
#define STORE_GRID_MODEL "grid_model"
// timeouts storage
#define STORAGE_TO pdMS_TO_TICKS(800)
// ------------------------------------------------------------------
// Helpers storage (robustos a queue cheia)
// ------------------------------------------------------------------
static esp_err_t storage_try_flush(void)
{
return storage_flush_sync(pdMS_TO_TICKS(2000));
}
static esp_err_t storage_try_set_u8(const char *ns, const char *key, uint8_t v)
{
for (int attempt = 0; attempt < 3; ++attempt)
{
esp_err_t err = storage_set_u8_async(ns, key, v);
if (err == ESP_OK)
return ESP_OK;
if (err == ESP_ERR_TIMEOUT)
{
(void)storage_try_flush();
continue;
}
return err;
}
return ESP_ERR_TIMEOUT;
}
static esp_err_t storage_get_u8_default(const char *ns, const char *key, uint8_t *out, uint8_t def)
{
if (!out)
return ESP_ERR_INVALID_ARG;
uint8_t v = def;
esp_err_t err = storage_get_u8_sync(ns, key, &v, STORAGE_TO);
if (err == ESP_OK)
{
*out = v;
return ESP_OK;
}
// se não existir / erro, devolve default
*out = def;
return err;
}
// ------------------------------------------------------------------
/*
static void meter_manager_network_event_handler(void *arg, esp_event_base_t base, int32_t event_id, void *data)
{
(void)arg;
(void)data;
if (base != NETWORK_EVENTS)
return;
switch (event_id)
{
case NETWORK_EVENT_AP_STARTED:
ESP_LOGI(TAG, "Recebido NETWORK_EVENT_AP_STARTED, parando medidor de grid");
// meter_manager_grid_stop();
ESP_LOGD(TAG, "Recebido NETWORK_EVENT_AP_STARTED, parando medidor de grid");
break;
case NETWORK_EVENT_AP_STOP:
ESP_LOGI(TAG, "Recebido NETWORK_EVENT_AP_STOP, reiniciando medidor de grid");
// meter_manager_grid_start();
ESP_LOGD(TAG, "Recebido NETWORK_EVENT_AP_STOP, reiniciando medidor de grid");
break;
case NETWORK_EVENT_STA_GOT_IP:
ESP_LOGI(TAG, "Recebido NETWORK_EVENT_STA_GOT_IP");
// opcional: reiniciar ou logar
ESP_LOGD(TAG, "Recebido NETWORK_EVENT_STA_GOT_IP");
break;
default:
break;
}
}
*/
// Função unificada para ler ou inicializar um modelo de medidor
// Função unificada para ler ou inicializar um modelo de medidor (via storage_service)
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;
}
if (!type)
return ESP_ERR_INVALID_ARG;
// tenta ler
uint8_t value = 0xFF;
esp_err_t err = storage_get_u8_sync(STORE_NAMESPACE, key, &value, STORAGE_TO);
uint8_t value = 0;
err = nvs_get_u8(handle, key, &value);
if (err == ESP_OK && value < 255)
{
*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);
ESP_LOGD(TAG, "Loaded meter type %u from storage key '%s/%s'", (unsigned)value, STORE_NAMESPACE, key);
return ESP_OK;
}
nvs_close(handle);
return ESP_OK;
// se não existir / inválido -> default NONE e grava
*type = METER_TYPE_NONE;
esp_err_t w = storage_try_set_u8(STORE_NAMESPACE, key, (uint8_t)(*type));
if (w != ESP_OK)
ESP_LOGE(TAG, "Failed to init key '%s/%s' to NONE: %s", STORE_NAMESPACE, key, esp_err_to_name(w));
(void)storage_try_flush();
ESP_LOGW(TAG, "Invalid/missing key '%s/%s' (read=%s), setting default (NONE)",
STORE_NAMESPACE, key, esp_err_to_name(err));
return ESP_OK; // seguimos com default
}
static esp_err_t write_meter_model_to_nvs(const char *key, meter_type_t meter_type)
static esp_err_t write_meter_model_to_storage(const char *key, meter_type_t meter_type)
{
nvs_handle_t handle;
esp_err_t err = nvs_open(NVS_NAMESPACE, NVS_READWRITE, &handle);
esp_err_t err = storage_try_set_u8(STORE_NAMESPACE, key, (uint8_t)meter_type);
if (err != ESP_OK)
{
ESP_LOGE(TAG, "Failed to open NVS handle for writing");
ESP_LOGE(TAG, "Failed to write meter type to storage key '%s/%s': %s",
STORE_NAMESPACE, key, esp_err_to_name(err));
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;
(void)storage_try_flush();
ESP_LOGD(TAG, "Saved meter type %d to storage key '%s/%s'", (int)meter_type, STORE_NAMESPACE, key);
return ESP_OK;
}
/**
* @brief Initializes the meter manager system.
*
* This function initializes both the EVSE and GRID meters,
* and registers the event handler to listen for NETWORK_EVENTS
* (e.g., AP started/stopped, STA got IP).
*
* @return esp_err_t ESP_OK on success, or an error code.
* @brief Inicializa o sistema de meter manager.
*/
esp_err_t meter_manager_init(void)
{
esp_err_t err;
// garantir storage pronto
esp_err_t s = storage_service_init();
if (s != ESP_OK)
ESP_LOGE(TAG, "storage_service_init failed: %s", esp_err_to_name(s));
// Initialize EVSE meter (habilite quando quiser)
// err = meter_manager_evse_init();
// if (err != ESP_OK) return err;
esp_err_t err;
// Initialize GRID meter
err = meter_manager_grid_init();
if (err != ESP_OK)
return err;
// Register handler for custom network events
ESP_LOGI(TAG, "Registering network event handler");
return esp_event_handler_register(NETWORK_EVENTS,
ESP_EVENT_ANY_ID,
meter_manager_network_event_handler,
NULL);
// Regista handler para eventos de rede
/*
ESP_LOGD(TAG, "Registering network event handler");
err = esp_event_handler_register(
NETWORK_EVENTS,
ESP_EVENT_ANY_ID,
meter_manager_network_event_handler,
NULL);
*/
if (err != ESP_OK)
return err;
// Emite um evento inicial de configuração
meter_config_event_t ev = {
.grid_type = meter_manager_grid_get_model(),
.evse_type = meter_manager_evse_get_model(),
.timestamp_us = esp_timer_get_time()};
esp_event_post(METER_EVENT,
METER_EVENT_CONFIG_UPDATED,
&ev,
sizeof(ev),
0);
return ESP_OK;
}
/**
* @brief Starts all configured meters (EVSE and GRID).
*
* This function starts the EVSE and GRID meters based on their configured types.
* It does not register event handlers — that is handled by `meter_manager_init()`.
*
* @return esp_err_t ESP_OK on success, or an error code from one of the start calls.
*/
esp_err_t meter_manager_start(void)
{
esp_err_t err;
// Start EVSE meter (habilite quando quiser)
// err = meter_manager_evse_start();
// if (err != ESP_OK) return err;
// Start GRID meter
err = meter_manager_grid_start();
if (err != ESP_OK)
return err;
return ESP_OK;
return meter_manager_grid_start();
}
/**
* @brief Stops all meters and unregisters event handlers.
*
* This function gracefully stops the EVSE and GRID meters
* and unregisters the previously registered network event handler.
*
* @return esp_err_t ESP_OK on success, or an error code.
*/
esp_err_t meter_manager_stop(void)
{
esp_err_t err;
// Stop EVSE meter
// err = meter_manager_evse_stop();
// if (err != ESP_OK) return err;
// Stop GRID meter
err = meter_manager_grid_stop();
if (err != ESP_OK)
return err;
return ESP_OK;
return meter_manager_grid_stop();
}
// ---------- EVSE ----------
esp_err_t meter_manager_evse_init()
{
esp_err_t err = load_or_init_meter_model(NVS_EVSE_MODEL, &meter_evse_type);
esp_err_t err = load_or_init_meter_model(STORE_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));
ESP_LOGD(TAG, "Initializing EVSE meter of type %s", meter_type_to_str(meter_evse_type));
switch (meter_evse_type)
{
@@ -292,13 +318,13 @@ esp_err_t meter_manager_evse_stop(void)
esp_err_t meter_manager_grid_init()
{
esp_err_t err = load_or_init_meter_model(NVS_GRID_MODEL, &meter_grid_type);
esp_err_t err = load_or_init_meter_model(STORE_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));
ESP_LOGD(TAG, "Initializing GRID meter of type %s", meter_type_to_str(meter_grid_type));
switch (meter_grid_type) // corrigido: ORNO-513 -> driver orno513
switch (meter_grid_type)
{
case METER_TYPE_NONE:
return ESP_OK;
@@ -334,7 +360,7 @@ esp_err_t meter_manager_grid_start()
case METER_TYPE_ADE7758:
return meter_ade7758_start();
case METER_TYPE_ORNO513:
return meter_orno513_start(); // corrigido
return meter_orno513_start();
case METER_TYPE_ORNO516:
return meter_orno516_start();
case METER_TYPE_ORNO526:
@@ -364,7 +390,7 @@ esp_err_t meter_manager_grid_stop(void)
meter_ade7758_stop();
break;
case METER_TYPE_ORNO513:
meter_orno513_stop(); // corrigido
meter_orno513_stop();
break;
case METER_TYPE_ORNO516:
meter_orno516_stop();
@@ -391,18 +417,64 @@ esp_err_t meter_manager_grid_stop(void)
return ESP_OK;
}
// ---------- Utilidades ----------
// ---------- Utilidades / setters com evento ----------
esp_err_t meter_manager_evse_set_model(meter_type_t meter_type)
{
esp_err_t err;
err = meter_manager_evse_stop();
if (err != ESP_OK)
ESP_LOGW(TAG, "Failed to stop EVSE meter before changing model: %s", esp_err_to_name(err));
meter_evse_type = meter_type;
return write_meter_model_to_nvs(NVS_EVSE_MODEL, meter_evse_type);
err = write_meter_model_to_storage(STORE_EVSE_MODEL, meter_evse_type);
if (err != ESP_OK)
return err;
err = meter_manager_evse_init();
if (err == ESP_OK)
err = meter_manager_evse_start();
meter_config_event_t ev = {
.grid_type = meter_manager_grid_get_model(),
.evse_type = meter_manager_evse_get_model(),
.timestamp_us = esp_timer_get_time()};
esp_err_t evt_err = esp_event_post(METER_EVENT, METER_EVENT_CONFIG_UPDATED, &ev, sizeof(ev), portMAX_DELAY);
if (evt_err != ESP_OK)
ESP_LOGW(TAG, "Failed to post METER_EVENT_CONFIG_UPDATED (EVSE): %s", esp_err_to_name(evt_err));
return err;
}
esp_err_t meter_manager_grid_set_model(meter_type_t meter_type)
{
esp_err_t err;
err = meter_manager_grid_stop();
if (err != ESP_OK)
ESP_LOGW(TAG, "Failed to stop GRID meter before changing model: %s", esp_err_to_name(err));
meter_grid_type = meter_type;
return write_meter_model_to_nvs(NVS_GRID_MODEL, meter_grid_type);
err = write_meter_model_to_storage(STORE_GRID_MODEL, meter_grid_type);
if (err != ESP_OK)
return err;
err = meter_manager_grid_init();
if (err == ESP_OK)
err = meter_manager_grid_start();
meter_config_event_t ev = {
.grid_type = meter_manager_grid_get_model(),
.evse_type = meter_manager_evse_get_model(),
.timestamp_us = esp_timer_get_time()};
esp_err_t evt_err = esp_event_post(METER_EVENT, METER_EVENT_CONFIG_UPDATED, &ev, sizeof(ev), portMAX_DELAY);
if (evt_err != ESP_OK)
ESP_LOGW(TAG, "Failed to post METER_EVENT_CONFIG_UPDATED (GRID): %s", esp_err_to_name(evt_err));
return err;
}
bool meter_manager_evse_is_enabled(void)
@@ -410,15 +482,8 @@ 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;
}
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)
{
@@ -453,6 +518,7 @@ 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)
@@ -471,5 +537,6 @@ meter_type_t string_to_meter_type(const char *str)
return METER_TYPE_TRIF_ZIGBEE;
if (strcmp(str, "EA-777") == 0)
return METER_TYPE_EA777;
return METER_TYPE_NONE;
}