new upgrade
This commit is contained in:
@@ -1,14 +1,12 @@
|
||||
idf_component_register(
|
||||
SRCS
|
||||
"src/protocols.c"
|
||||
"src/json.c"
|
||||
"src/mqtt.c"
|
||||
INCLUDE_DIRS
|
||||
"include"
|
||||
PRIV_INCLUDE_DIRS
|
||||
"src"
|
||||
PRIV_REQUIRES
|
||||
nvs_flash
|
||||
mqtt
|
||||
cjson
|
||||
vfs
|
||||
@@ -19,6 +17,7 @@ idf_component_register(
|
||||
config
|
||||
evse
|
||||
peripherals
|
||||
meter_manager
|
||||
ocpp
|
||||
auth
|
||||
)
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#ifndef JSON_H_
|
||||
#define JSON_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "cJSON.h"
|
||||
|
||||
/**
|
||||
* @brief Gera um objeto JSON com a configuração atual do EVSE.
|
||||
*
|
||||
* Contém parâmetros como corrente máxima, limites de tempo,
|
||||
* trava do conector, temperatura e configuração do OCPP.
|
||||
*
|
||||
* @return Ponteiro para cJSON (deve ser liberado com cJSON_Delete()).
|
||||
*/
|
||||
cJSON* json_get_evse_config(void);
|
||||
|
||||
/**
|
||||
* @brief Define a configuração do EVSE a partir de um objeto JSON.
|
||||
*
|
||||
* Aplica valores recebidos de protocolos como MQTT ou REST.
|
||||
*
|
||||
* @param root Objeto JSON com os campos válidos.
|
||||
* @return ESP_OK se todos os parâmetros foram aplicados com sucesso.
|
||||
*/
|
||||
esp_err_t json_set_evse_config(cJSON* root);
|
||||
|
||||
/**
|
||||
* @brief Retorna o estado atual do EVSE em formato JSON.
|
||||
*
|
||||
* Inclui estado de operação, erros, limites, sessão atual e medições elétricas.
|
||||
*
|
||||
* @return Ponteiro para cJSON (deve ser liberado com cJSON_Delete()).
|
||||
*/
|
||||
cJSON* json_get_state(void);
|
||||
|
||||
|
||||
#endif /* JSON_H_ */
|
||||
@@ -1,114 +1,115 @@
|
||||
#ifndef MQTT_H_
|
||||
#define MQTT_H_
|
||||
// === Início de: components/mqtt/include/mqtt.h ===
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
// Tamanhos máximos esperados pelos getters (buffers do chamador)
|
||||
#define MQTT_SERVER_MAX_LEN 64 ///< host ou URI do broker
|
||||
#define MQTT_BASE_TOPIC_MAX_LEN 64 ///< tópico base (ex: "evse")
|
||||
#define MQTT_USERNAME_MAX_LEN 32
|
||||
#define MQTT_PASSWORD_MAX_LEN 64
|
||||
|
||||
/**
|
||||
* @file mqtt.h
|
||||
* @brief MQTT configuration and control interface.
|
||||
* @brief Inicializa o módulo MQTT.
|
||||
*
|
||||
* This module provides initialization, configuration,
|
||||
* and runtime access functions for the MQTT client.
|
||||
* - Carrega configuração da NVS
|
||||
* - Regista handlers de eventos (AUTH, SCHED, LOADBALANCER, METER, EVSE, NETWORK)
|
||||
* - Cria a task de telemetria periódica
|
||||
*
|
||||
* Configuration is persisted in NVS under namespace "mqtt".
|
||||
* Não inicia a ligação ao broker imediatamente; isso acontece quando existir IP
|
||||
* (NETWORK_EVENT_STA_GOT_IP) e `enabled == true`.
|
||||
*/
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Definitions */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
#define MQTT_MAX_SERVER_LEN 64 /**< Max length for MQTT server URI */
|
||||
#define MQTT_MAX_USER_LEN 32 /**< Max length for MQTT username */
|
||||
#define MQTT_MAX_PASSWORD_LEN 64 /**< Max length for MQTT password */
|
||||
#define MQTT_MAX_BASE_TOPIC_LEN 64 /**< Max length for MQTT base topic */
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Public Functions */
|
||||
/* -------------------------------------------------------------------------- */
|
||||
esp_err_t mqtt_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize MQTT subsystem.
|
||||
* @brief Força tentativa de ligação ao broker (normalmente não é necessário chamar).
|
||||
*
|
||||
* Loads configuration from NVS and starts background publish task
|
||||
* if MQTT is enabled. Must be called once during system startup.
|
||||
* Útil apenas se quiseres forçar manualmente depois de mudares config.
|
||||
*/
|
||||
void mqtt_init(void);
|
||||
esp_err_t mqtt_start(void);
|
||||
|
||||
/**
|
||||
* @brief Restart the MQTT client safely.
|
||||
*
|
||||
* Stops the current MQTT client (if running) and starts a new one
|
||||
* with the configuration currently stored in NVS.
|
||||
*
|
||||
* Useful when changing Wi-Fi networks, credentials, or broker settings.
|
||||
*
|
||||
* @return ESP_OK on success, or an ESP_ERR_* code otherwise.
|
||||
* @brief Pára o cliente MQTT e destrói o handle.
|
||||
*/
|
||||
esp_err_t mqtt_restart(void);
|
||||
void mqtt_stop(void);
|
||||
|
||||
// =============================
|
||||
// Getters de configuração
|
||||
// =============================
|
||||
|
||||
/**
|
||||
* @brief Set and persist MQTT configuration parameters in NVS.
|
||||
*
|
||||
* Any NULL parameter will be skipped (the previous value remains stored).
|
||||
*
|
||||
* @param enabled Whether MQTT should be enabled (true/false).
|
||||
* @param server Broker URI (e.g. "mqtt://192.168.1.10").
|
||||
* @param base_topic Base topic prefix for publish/subscribe.
|
||||
* @param user MQTT username (optional).
|
||||
* @param password MQTT password (optional).
|
||||
* @param periodicity Publish interval (in seconds). Must be >0 when enabled.
|
||||
*
|
||||
* @return ESP_OK on success, or an ESP_ERR_* code otherwise.
|
||||
*/
|
||||
esp_err_t mqtt_set_config(bool enabled,
|
||||
const char *server,
|
||||
const char *base_topic,
|
||||
const char *user,
|
||||
const char *password,
|
||||
uint16_t periodicity);
|
||||
|
||||
/**
|
||||
* @brief Get whether MQTT is enabled.
|
||||
*
|
||||
* @return true if enabled, false otherwise.
|
||||
* @brief Indica se o MQTT está ativo (flag em config).
|
||||
*/
|
||||
bool mqtt_get_enabled(void);
|
||||
|
||||
/**
|
||||
* @brief Get MQTT broker URI stored in NVS.
|
||||
* @brief Obtém o servidor MQTT (host ou URI).
|
||||
*
|
||||
* @param[out] value Buffer to receive the URI (min length: MQTT_MAX_SERVER_LEN).
|
||||
* @param server buffer de saída, com pelo menos MQTT_SERVER_MAX_LEN bytes.
|
||||
*/
|
||||
void mqtt_get_server(char *value);
|
||||
void mqtt_get_server(char *server);
|
||||
|
||||
/**
|
||||
* @brief Get MQTT base topic stored in NVS.
|
||||
* @brief Obtém o tópico base (ex.: "evse").
|
||||
*
|
||||
* @param[out] value Buffer to receive the base topic (min length: MQTT_MAX_BASE_TOPIC_LEN).
|
||||
* @param base_topic buffer de saída, com pelo menos MQTT_BASE_TOPIC_MAX_LEN bytes.
|
||||
*/
|
||||
void mqtt_get_base_topic(char *value);
|
||||
void mqtt_get_base_topic(char *base_topic);
|
||||
|
||||
/**
|
||||
* @brief Get MQTT username stored in NVS.
|
||||
* @brief Obtém o username MQTT (se configurado).
|
||||
*
|
||||
* @param[out] value Buffer to receive the username (min length: MQTT_MAX_USER_LEN).
|
||||
* @param username buffer de saída, com pelo menos MQTT_USERNAME_MAX_LEN bytes.
|
||||
*/
|
||||
void mqtt_get_user(char *value);
|
||||
void mqtt_get_user(char *username);
|
||||
|
||||
/**
|
||||
* @brief Get MQTT password stored in NVS.
|
||||
* @brief Obtém a password MQTT (se configurada).
|
||||
*
|
||||
* @param[out] value Buffer to receive the password (min length: MQTT_MAX_PASSWORD_LEN).
|
||||
* @param password buffer de saída, com pelo menos MQTT_PASSWORD_MAX_LEN bytes.
|
||||
*/
|
||||
void mqtt_get_password(char *value);
|
||||
void mqtt_get_password(char *password);
|
||||
|
||||
/**
|
||||
* @brief Get MQTT publish periodicity in seconds.
|
||||
*
|
||||
* @return Publish interval in seconds (default: 30).
|
||||
* @brief Obtém a periodicidade da telemetria periódica (em segundos).
|
||||
*/
|
||||
uint16_t mqtt_get_periodicity(void);
|
||||
|
||||
#endif /* MQTT_H_ */
|
||||
// =============================
|
||||
// Setter de configuração
|
||||
// =============================
|
||||
|
||||
/**
|
||||
* @brief Atualiza a configuração MQTT (tipicamente chamado pelo endpoint REST).
|
||||
*
|
||||
* - Grava em NVS
|
||||
* - Se já existir cliente ligado, pára e recria com a nova config
|
||||
* - Se `enabled == true` e houver IP, tenta ligar ao broker
|
||||
*
|
||||
* @param enabled true para ativar MQTT
|
||||
* @param host hostname ou URI (ex: "broker.hivemq.com" ou "mqtt://x.y.z")
|
||||
* @param topic tópico base (ex: "evse")
|
||||
* @param username username MQTT (ou NULL para manter/limpar)
|
||||
* @param password password MQTT (ou NULL para manter/limpar)
|
||||
* @param periodicity período da task de telemetria em segundos (ex: 30)
|
||||
*
|
||||
* @return ESP_OK em caso de sucesso, ou erro de NVS / MQTT.
|
||||
*/
|
||||
esp_err_t mqtt_set_config(bool enabled,
|
||||
const char *host,
|
||||
const char *topic,
|
||||
const char *username,
|
||||
const char *password,
|
||||
int periodicity);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// === Fim de: components/mqtt/include/mqtt.h ===
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
// === Início de: components/protocols/src/json.c ===
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_timer.h"
|
||||
#include "esp_chip_info.h"
|
||||
#include "esp_mac.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "json.h"
|
||||
#include "mqtt.h"
|
||||
#include "network.h"
|
||||
#include "evse_error.h"
|
||||
#include "evse_api.h"
|
||||
#include "auth.h"
|
||||
#include "evse_limits.h"
|
||||
#include "evse_state.h"
|
||||
#include "evse_config.h"
|
||||
#include "ocpp.h"
|
||||
#include "board_config.h"
|
||||
#include "socket_lock.h"
|
||||
#include "proximity.h"
|
||||
#include "temp_sensor.h"
|
||||
#include "evse_meter.h"
|
||||
|
||||
static const char *TAG = "json";
|
||||
|
||||
//
|
||||
// ===== EVSE CONFIG JSON =====
|
||||
//
|
||||
cJSON *json_get_evse_config(void)
|
||||
{
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
if (!root)
|
||||
return NULL;
|
||||
|
||||
cJSON_AddNumberToObject(root, "maxChargingCurrent", evse_get_max_charging_current());
|
||||
cJSON_AddNumberToObject(root, "chargingCurrent", evse_get_charging_current());
|
||||
cJSON_AddNumberToObject(root, "defaultChargingCurrent", evse_get_default_charging_current());
|
||||
cJSON_AddBoolToObject(root, "requireAuth", auth_get_mode());
|
||||
cJSON_AddBoolToObject(root, "socketOutlet", evse_get_socket_outlet());
|
||||
cJSON_AddBoolToObject(root, "rcm", evse_is_rcm());
|
||||
cJSON_AddNumberToObject(root, "temperatureThreshold", evse_get_temp_threshold());
|
||||
cJSON_AddNumberToObject(root, "consumptionLimit", evse_get_consumption_limit());
|
||||
//cJSON_AddNumberToObject(root, "defaultConsumptionLimit", evse_get_default_consumption_limit());
|
||||
cJSON_AddNumberToObject(root, "chargingTimeLimit", evse_get_charging_time_limit());
|
||||
//cJSON_AddNumberToObject(root, "defaultChargingTimeLimit", evse_get_default_charging_time_limit());
|
||||
cJSON_AddNumberToObject(root, "underPowerLimit", evse_get_under_power_limit());
|
||||
//cJSON_AddNumberToObject(root, "defaultUnderPowerLimit", evse_get_default_under_power_limit());
|
||||
|
||||
cJSON_AddNumberToObject(root, "socketLockOperatingTime", socket_lock_get_operating_time());
|
||||
cJSON_AddNumberToObject(root, "socketLockBreakTime", socket_lock_get_break_time());
|
||||
cJSON_AddBoolToObject(root, "socketLockDetectionHigh", socket_lock_is_detection_high());
|
||||
cJSON_AddNumberToObject(root, "socketLockRetryCount", socket_lock_get_retry_count());
|
||||
|
||||
char str[64];
|
||||
cJSON_AddBoolToObject(root, "enabledocpp", ocpp_get_enabled());
|
||||
ocpp_get_server(str);
|
||||
cJSON_AddStringToObject(root, "serverocpp", str);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
//
|
||||
// ===== SET EVSE CONFIG (from MQTT or REST) =====
|
||||
//
|
||||
esp_err_t json_set_evse_config(cJSON *root)
|
||||
{
|
||||
if (!root)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
|
||||
// Alguns setters retornam esp_err_t, outros void. Para manter compatibilidade,
|
||||
// chamamos sem propagar erro (se existir, será tratado internamente).
|
||||
#define SET_NUM(key, fn) \
|
||||
do \
|
||||
{ \
|
||||
const cJSON *item = cJSON_GetObjectItem(root, key); \
|
||||
if (cJSON_IsNumber(item)) \
|
||||
{ \
|
||||
fn(item->valuedouble); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SET_BOOL(key, fn) \
|
||||
do \
|
||||
{ \
|
||||
const cJSON *item = cJSON_GetObjectItem(root, key); \
|
||||
if (cJSON_IsBool(item)) \
|
||||
{ \
|
||||
fn(cJSON_IsTrue(item)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
SET_NUM("maxChargingCurrent", evse_set_max_charging_current);
|
||||
SET_NUM("chargingCurrent", evse_set_charging_current);
|
||||
SET_NUM("defaultChargingCurrent", evse_set_default_charging_current);
|
||||
SET_BOOL("socketOutlet", evse_set_socket_outlet);
|
||||
SET_BOOL("rcm", evse_set_rcm);
|
||||
SET_NUM("temperatureThreshold", evse_set_temp_threshold);
|
||||
SET_NUM("consumptionLimit", evse_set_consumption_limit);
|
||||
//SET_NUM("defaultConsumptionLimit", evse_set_default_consumption_limit);
|
||||
SET_NUM("chargingTimeLimit", evse_set_charging_time_limit);
|
||||
//SET_NUM("defaultChargingTimeLimit", evse_set_default_charging_time_limit);
|
||||
SET_NUM("underPowerLimit", evse_set_under_power_limit);
|
||||
//SET_NUM("defaultUnderPowerLimit", evse_set_default_under_power_limit);
|
||||
SET_NUM("socketLockOperatingTime", socket_lock_set_operating_time);
|
||||
SET_NUM("socketLockBreakTime", socket_lock_set_break_time);
|
||||
|
||||
const cJSON *retry = cJSON_GetObjectItem(root, "socketLockRetryCount");
|
||||
if (cJSON_IsNumber(retry))
|
||||
socket_lock_set_retry_count(retry->valueint);
|
||||
|
||||
const cJSON *detect = cJSON_GetObjectItem(root, "socketLockDetectionHigh");
|
||||
if (cJSON_IsBool(detect))
|
||||
socket_lock_set_detection_high(cJSON_IsTrue(detect));
|
||||
|
||||
const cJSON *ocpp_enabled = cJSON_GetObjectItem(root, "enabledocpp");
|
||||
if (cJSON_IsBool(ocpp_enabled))
|
||||
ocpp_set_enabled(cJSON_IsTrue(ocpp_enabled));
|
||||
|
||||
const cJSON *ocpp_server = cJSON_GetObjectItem(root, "serverocpp");
|
||||
if (cJSON_IsString(ocpp_server))
|
||||
ocpp_set_server(cJSON_GetStringValue(ocpp_server));
|
||||
|
||||
ESP_LOGI(TAG, "EVSE configuration updated successfully");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// ===== EVSE STATE JSON =====
|
||||
//
|
||||
cJSON *json_get_state(void)
|
||||
{
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
if (!root)
|
||||
return NULL;
|
||||
|
||||
cJSON_AddStringToObject(root, "state", evse_state_to_str(evse_get_state()));
|
||||
cJSON_AddBoolToObject(root, "available", evse_config_is_available());
|
||||
cJSON_AddBoolToObject(root, "enabled", evse_config_is_enabled());
|
||||
cJSON_AddBoolToObject(root, "pendingAuth", auth_get_mode());
|
||||
cJSON_AddBoolToObject(root, "limitReached", evse_is_limit_reached());
|
||||
|
||||
// Add error list
|
||||
uint32_t error = evse_error_get_bits();
|
||||
if (error == 0)
|
||||
{
|
||||
cJSON_AddNullToObject(root, "errors");
|
||||
}
|
||||
else
|
||||
{
|
||||
cJSON *errors = cJSON_CreateArray();
|
||||
if (error & EVSE_ERR_PILOT_FAULT_BIT)
|
||||
cJSON_AddItemToArray(errors, cJSON_CreateString("pilot_fault"));
|
||||
if (error & EVSE_ERR_DIODE_SHORT_BIT)
|
||||
cJSON_AddItemToArray(errors, cJSON_CreateString("diode_short"));
|
||||
if (error & EVSE_ERR_LOCK_FAULT_BIT)
|
||||
cJSON_AddItemToArray(errors, cJSON_CreateString("lock_fault"));
|
||||
if (error & EVSE_ERR_UNLOCK_FAULT_BIT)
|
||||
cJSON_AddItemToArray(errors, cJSON_CreateString("unlock_fault"));
|
||||
if (error & EVSE_ERR_RCM_TRIGGERED_BIT)
|
||||
cJSON_AddItemToArray(errors, cJSON_CreateString("rcm_triggered"));
|
||||
if (error & EVSE_ERR_RCM_SELFTEST_FAULT_BIT)
|
||||
cJSON_AddItemToArray(errors, cJSON_CreateString("rcm_selftest_fault"));
|
||||
if (error & EVSE_ERR_TEMPERATURE_HIGH_BIT)
|
||||
cJSON_AddItemToArray(errors, cJSON_CreateString("temperature_high"));
|
||||
if (error & EVSE_ERR_TEMPERATURE_FAULT_BIT)
|
||||
cJSON_AddItemToArray(errors, cJSON_CreateString("temperature_fault"));
|
||||
cJSON_AddItemToObject(root, "errors", errors);
|
||||
}
|
||||
|
||||
// Session info
|
||||
evse_session_t sess;
|
||||
if (evse_get_session(&sess))
|
||||
{
|
||||
cJSON_AddNumberToObject(root, "sessionTime", (double)sess.start_tick);
|
||||
cJSON_AddNumberToObject(root, "chargingTime", (double)sess.duration_s);
|
||||
cJSON_AddNumberToObject(root, "consumption", (double)sess.energy_wh);
|
||||
}
|
||||
else
|
||||
{
|
||||
cJSON_AddNullToObject(root, "sessionTime");
|
||||
cJSON_AddNumberToObject(root, "chargingTime", 0);
|
||||
cJSON_AddNumberToObject(root, "consumption", 0);
|
||||
}
|
||||
|
||||
// Meter readings
|
||||
float voltage[EVSE_METER_PHASE_COUNT];
|
||||
float current[EVSE_METER_PHASE_COUNT];
|
||||
int power[EVSE_METER_PHASE_COUNT];
|
||||
|
||||
evse_meter_get_voltage(voltage);
|
||||
evse_meter_get_current(current);
|
||||
evse_meter_get_power(power);
|
||||
|
||||
cJSON_AddItemToObject(root, "power", cJSON_CreateIntArray(power, EVSE_METER_PHASE_COUNT));
|
||||
cJSON_AddItemToObject(root, "voltage", cJSON_CreateFloatArray(voltage, EVSE_METER_PHASE_COUNT));
|
||||
cJSON_AddItemToObject(root, "current", cJSON_CreateFloatArray(current, EVSE_METER_PHASE_COUNT));
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
// === Fim de: components/protocols/src/json.c ===
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user