fix ade7758
This commit is contained in:
@@ -31,31 +31,31 @@ static esp_err_t open_mqtt_nvs(nvs_handle_t *handle) {
|
||||
|
||||
static void subcribe_topics(void)
|
||||
{
|
||||
ESP_LOGI(TAG, "subcribe_topics");
|
||||
ESP_LOGI(TAG, "[MQTT] Subscribing to topics");
|
||||
|
||||
char base[32];
|
||||
mqtt_get_base_topic(base);
|
||||
|
||||
char topic[64];
|
||||
mqtt_get_base_topic(topic);
|
||||
|
||||
strcat(topic, "/request/#");
|
||||
snprintf(topic, sizeof(topic), "%s/request/#", base);
|
||||
esp_mqtt_client_subscribe(client, topic, 0);
|
||||
ESP_LOGI(TAG, "subscribed: %s", topic);
|
||||
ESP_LOGI(TAG, " subscribed: %s", topic);
|
||||
|
||||
mqtt_get_base_topic(topic);
|
||||
strcat(topic, "/set/config/#");
|
||||
snprintf(topic, sizeof(topic), "%s/set/config/#", base);
|
||||
esp_mqtt_client_subscribe(client, topic, 0);
|
||||
ESP_LOGI(TAG, "subscribed: %s", topic);
|
||||
ESP_LOGI(TAG, " subscribed: %s", topic);
|
||||
|
||||
mqtt_get_base_topic(topic);
|
||||
strcat(topic, "/enable");
|
||||
snprintf(topic, sizeof(topic), "%s/enable", base);
|
||||
esp_mqtt_client_subscribe(client, topic, 0);
|
||||
ESP_LOGI(TAG, "subscribed: %s", topic);
|
||||
ESP_LOGI(TAG, " subscribed: %s", topic);
|
||||
}
|
||||
|
||||
static void publish_message(const char* topic, cJSON* root)
|
||||
{
|
||||
char target_topic[64];
|
||||
mqtt_get_base_topic(target_topic);
|
||||
strcat(target_topic, topic);
|
||||
strncat(target_topic, topic, sizeof(target_topic) - strlen(target_topic) - 1);
|
||||
|
||||
const char* json = cJSON_PrintUnformatted(root);
|
||||
esp_mqtt_client_publish(client, target_topic, json, 0, 1, 0);
|
||||
@@ -67,34 +67,51 @@ static void handle_message(const char* topic, const char* data)
|
||||
char base_topic[32];
|
||||
mqtt_get_base_topic(base_topic);
|
||||
|
||||
ESP_LOGI(TAG, "[MQTT] Message received");
|
||||
ESP_LOGI(TAG, " > Topic: %s", topic);
|
||||
ESP_LOGI(TAG, " > Payload: %s", data);
|
||||
|
||||
if (strncmp(topic, base_topic, strlen(base_topic)) == 0) {
|
||||
const char* sub_topic = &topic[strlen(base_topic)];
|
||||
ESP_LOGI(TAG, " > Subtopic detected: %s", sub_topic);
|
||||
|
||||
if (strcmp(sub_topic, "/request/config/evse") == 0) {
|
||||
ESP_LOGI(TAG, " → Responding with EVSE configuration");
|
||||
cJSON* root = json_get_evse_config();
|
||||
publish_message("/response/config/evse", root);
|
||||
cJSON_Delete(root);
|
||||
} else {
|
||||
ESP_LOGW(TAG, " ! Unknown command: %s", sub_topic);
|
||||
}
|
||||
// [Outros comandos omitidos para brevidade...]
|
||||
} else {
|
||||
ESP_LOGW(TAG, " ! Topic does not match base: %s", topic);
|
||||
}
|
||||
}
|
||||
|
||||
static void event_handler(void* handler_args, esp_event_base_t base, int32_t event_id, void* event_data)
|
||||
{
|
||||
esp_mqtt_event_handle_t event = event_data;
|
||||
char topic[48], data[256];
|
||||
|
||||
switch (event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
ESP_LOGI(TAG, "MQTT conectado");
|
||||
ESP_LOGI(TAG, "[MQTT] Connected to broker");
|
||||
if (client_task) vTaskResume(client_task);
|
||||
subcribe_topics();
|
||||
break;
|
||||
case MQTT_EVENT_DATA:
|
||||
strncpy(topic, event->topic, MIN(event->topic_len, sizeof(topic)-1));
|
||||
strncpy(data, event->data, MIN(event->data_len, sizeof(data)-1));
|
||||
|
||||
case MQTT_EVENT_DATA: {
|
||||
char topic[64] = {0};
|
||||
char data[256] = {0};
|
||||
|
||||
int tlen = MIN(event->topic_len, sizeof(topic) - 1);
|
||||
int dlen = MIN(event->data_len, sizeof(data) - 1);
|
||||
|
||||
memcpy(topic, event->topic, tlen);
|
||||
memcpy(data, event->data, dlen);
|
||||
|
||||
handle_message(topic, data);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -257,4 +274,4 @@ void mqtt_get_password(char* value)
|
||||
uint16_t mqtt_get_periodicity(void)
|
||||
{
|
||||
return periodicity;
|
||||
}
|
||||
}
|
||||
@@ -1,907 +0,0 @@
|
||||
/* HTTP Restful API Server
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include "esp_http_server.h"
|
||||
#include "esp_chip_info.h"
|
||||
#include "esp_random.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_vfs.h"
|
||||
#include "cJSON.h"
|
||||
#include "rest.h"
|
||||
#include "evse_api.h"
|
||||
#include "cJSON.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_http_server.h"
|
||||
#include "auth.h"
|
||||
|
||||
static const char *REST_TAG = "esp-rest";
|
||||
#define REST_CHECK(a, str, goto_tag, ...) \
|
||||
do \
|
||||
{ \
|
||||
if (!(a)) \
|
||||
{ \
|
||||
ESP_LOGE(REST_TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
goto goto_tag; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define FILE_PATH_MAX (ESP_VFS_PATH_MAX + 128)
|
||||
#define SCRATCH_BUFSIZE (10240)
|
||||
|
||||
typedef struct rest_server_context {
|
||||
char base_path[ESP_VFS_PATH_MAX + 1];
|
||||
char scratch[SCRATCH_BUFSIZE];
|
||||
} rest_server_context_t;
|
||||
|
||||
#define CHECK_FILE_EXTENSION(filename, ext) (strcasecmp(&filename[strlen(filename) - strlen(ext)], ext) == 0)
|
||||
|
||||
// Estruturas para armazenar as configurações
|
||||
static struct {
|
||||
bool enabled;
|
||||
char ssid[128];
|
||||
char password[128];
|
||||
} wifi_config = {false, "", ""};
|
||||
|
||||
static struct {
|
||||
bool enabled;
|
||||
char host[256];
|
||||
int port;
|
||||
char username[128];
|
||||
char password[128];
|
||||
char topic[128];
|
||||
} mqtt_config = {false, "", 1883, "", "", ""};
|
||||
|
||||
// Estrutura para armazenar as configurações OCPP em memória
|
||||
static struct {
|
||||
char url[256];
|
||||
char chargeBoxId[128];
|
||||
char certificate[256];
|
||||
char privateKey[256];
|
||||
} ocpp_config = {"", "", "", ""};
|
||||
|
||||
// Estrutura para armazenar as configurações de energia
|
||||
static struct {
|
||||
int currentLimit;
|
||||
int powerLimit;
|
||||
int energyLimit;
|
||||
int chargingTimeLimit;
|
||||
int temperatureLimit;
|
||||
} settings_config = {0, 0, 0, 0, 0};
|
||||
|
||||
static struct {
|
||||
char username[128];
|
||||
} users[10] = {{"admin"}, {"user1"}};
|
||||
static int num_users = 2; // Contador de usuários cadastrados
|
||||
|
||||
|
||||
// Set HTTP response content type according to file extension
|
||||
static esp_err_t set_content_type_from_file(httpd_req_t *req, const char *filepath)
|
||||
{
|
||||
const char *type = "text/plain";
|
||||
if (CHECK_FILE_EXTENSION(filepath, ".html")) {
|
||||
type = "text/html";
|
||||
} else if (CHECK_FILE_EXTENSION(filepath, ".js")) {
|
||||
type = "application/javascript";
|
||||
} else if (CHECK_FILE_EXTENSION(filepath, ".css")) {
|
||||
type = "text/css";
|
||||
} else if (CHECK_FILE_EXTENSION(filepath, ".png")) {
|
||||
type = "image/png";
|
||||
} else if (CHECK_FILE_EXTENSION(filepath, ".ico")) {
|
||||
type = "image/x-icon";
|
||||
} else if (CHECK_FILE_EXTENSION(filepath, ".svg")) {
|
||||
type = "text/xml";
|
||||
}
|
||||
return httpd_resp_set_type(req, type);
|
||||
}
|
||||
|
||||
/* Send HTTP response with the contents of the requested file */
|
||||
static esp_err_t rest_common_get_handler(httpd_req_t *req)
|
||||
{
|
||||
char filepath[FILE_PATH_MAX];
|
||||
|
||||
rest_server_context_t *rest_context = (rest_server_context_t *)req->user_ctx;
|
||||
strlcpy(filepath, rest_context->base_path, sizeof(filepath));
|
||||
if (req->uri[strlen(req->uri) - 1] == '/') {
|
||||
strlcat(filepath, "/index.html", sizeof(filepath));
|
||||
} else {
|
||||
strlcat(filepath, req->uri, sizeof(filepath));
|
||||
}
|
||||
int fd = open(filepath, O_RDONLY, 0);
|
||||
if (fd == -1) {
|
||||
ESP_LOGW(REST_TAG, "Failed to open file : %s, redirecting to index", filepath);
|
||||
/* Try to serve index.html for SPA routing */
|
||||
strlcpy(filepath, rest_context->base_path, sizeof(filepath));
|
||||
strlcat(filepath, "/index.html", sizeof(filepath));
|
||||
fd = open(filepath, O_RDONLY, 0);
|
||||
if (fd == -1) {
|
||||
ESP_LOGE(REST_TAG, "Failed to open index file : %s", filepath);
|
||||
httpd_resp_send_err(req, HTTPD_404_NOT_FOUND, "File not found");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
set_content_type_from_file(req, filepath);
|
||||
|
||||
char *chunk = rest_context->scratch;
|
||||
ssize_t read_bytes;
|
||||
do {
|
||||
/* Read file in chunks into the scratch buffer */
|
||||
read_bytes = read(fd, chunk, SCRATCH_BUFSIZE);
|
||||
if (read_bytes == -1) {
|
||||
ESP_LOGE(REST_TAG, "Failed to read file : %s", filepath);
|
||||
} else if (read_bytes > 0) {
|
||||
/* Send the buffer contents as HTTP response chunk */
|
||||
if (httpd_resp_send_chunk(req, chunk, read_bytes) != ESP_OK) {
|
||||
close(fd);
|
||||
ESP_LOGE(REST_TAG, "File sending failed!");
|
||||
/* Abort sending file */
|
||||
httpd_resp_sendstr_chunk(req, NULL);
|
||||
/* Respond with 500 Internal Server Error */
|
||||
httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "Failed to send file");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
} while (read_bytes > 0);
|
||||
/* Close file after sending complete */
|
||||
close(fd);
|
||||
ESP_LOGI(REST_TAG, "File sending complete");
|
||||
/* Respond with an empty chunk to signal HTTP response completion */
|
||||
httpd_resp_send_chunk(req, NULL, 0);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Manipulador para o endpoint GET /api/v1/config/electrical
|
||||
static esp_err_t electrical_config_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Criar objeto JSON com as configurações de rede elétrica
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
cJSON *monitor = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(monitor, "voltage", "230");
|
||||
cJSON_AddStringToObject(monitor, "current", "10");
|
||||
cJSON_AddStringToObject(monitor, "quality", "1");
|
||||
cJSON_AddItemToObject(config, "monitor", monitor);
|
||||
cJSON_AddBoolToObject(config, "alerts", true);
|
||||
|
||||
// Adicionar mais configurações (security, loadBalancing, solar) no objeto config
|
||||
// ...
|
||||
|
||||
// Enviar a resposta
|
||||
const char *config_str = cJSON_Print(config);
|
||||
httpd_resp_sendstr(req, config_str);
|
||||
|
||||
// Liberar memória
|
||||
free((void *)config_str);
|
||||
cJSON_Delete(config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
// Manipulador para o endpoint POST /api/v1/config/electrical
|
||||
static esp_err_t electrical_config_post_handler(httpd_req_t *req)
|
||||
{
|
||||
char buf[512];
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Request body is empty");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
buf[len] = '\0'; // Garantir que a string esteja terminada
|
||||
|
||||
// Parse JSON recebido
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (json == NULL) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Processar os dados recebidos e atualizar as configurações (monitor, alerts, etc.)
|
||||
// Exemplo de configuração:
|
||||
cJSON *monitor = cJSON_GetObjectItem(json, "monitor");
|
||||
if (monitor) {
|
||||
// Atualizar configurações do monitor
|
||||
// ...
|
||||
}
|
||||
|
||||
// Atualizar outras configurações...
|
||||
|
||||
// Responder com sucesso
|
||||
httpd_resp_sendstr(req, "Configuração gravada com sucesso!");
|
||||
|
||||
cJSON_Delete(json);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
// Manipulador para o endpoint /api/v1/config/load-balancing
|
||||
static esp_err_t config_load_balancing_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Criar objeto JSON de configuração
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
|
||||
// Configuração de load balancing
|
||||
cJSON_AddBoolToObject(config, "enabled", true); // Exemplo: load balancing ativado
|
||||
cJSON_AddNumberToObject(config, "maxChargingCurrent", 32); // Exemplo: corrente máxima de 32A
|
||||
|
||||
// Lista de dispositivos disponíveis
|
||||
cJSON *devices = cJSON_CreateArray();
|
||||
cJSON_AddItemToArray(devices, cJSON_CreateString("Device 1")); // Exemplo de dispositivo
|
||||
cJSON_AddItemToArray(devices, cJSON_CreateString("Device 2")); // Outro exemplo de dispositivo
|
||||
cJSON_AddItemToObject(config, "devices", devices);
|
||||
|
||||
// Convertendo para string e enviando a resposta
|
||||
const char *config_str = cJSON_Print(config);
|
||||
httpd_resp_sendstr(req, config_str);
|
||||
|
||||
// Liberando a memória
|
||||
free((void *)config_str);
|
||||
cJSON_Delete(config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
// Manipulador para o endpoint GET /api/v1/ocpp (Status do OCPP)
|
||||
static esp_err_t ocpp_status_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Criar objeto JSON de status
|
||||
cJSON *status = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(status, "status", "connected"); // Status de exemplo, você pode adaptar conforme sua lógica
|
||||
|
||||
// Convertendo para string e enviando a resposta
|
||||
const char *status_str = cJSON_Print(status);
|
||||
httpd_resp_sendstr(req, status_str);
|
||||
|
||||
// Liberando a memória
|
||||
free((void *)status_str);
|
||||
cJSON_Delete(status);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Manipulador para o endpoint GET /api/v1/config/ocpp (Configuração OCPP)
|
||||
static esp_err_t config_ocpp_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Criar objeto JSON com as configurações do OCPP
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(config, "url", ocpp_config.url);
|
||||
cJSON_AddStringToObject(config, "chargeBoxId", ocpp_config.chargeBoxId);
|
||||
cJSON_AddStringToObject(config, "certificate", ocpp_config.certificate);
|
||||
cJSON_AddStringToObject(config, "privateKey", ocpp_config.privateKey);
|
||||
|
||||
// Convertendo para string e enviando a resposta
|
||||
const char *config_str = cJSON_Print(config);
|
||||
httpd_resp_sendstr(req, config_str);
|
||||
|
||||
// Liberando a memória
|
||||
free((void *)config_str);
|
||||
cJSON_Delete(config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Manipulador para o endpoint POST /api/v1/config/ocpp (Salvar configuração OCPP)
|
||||
static esp_err_t config_ocpp_post_handler(httpd_req_t *req)
|
||||
{
|
||||
char buf[512]; // Buffer para armazenar a requisição
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid request body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
buf[len] = '\0'; // Garantir que a string esteja terminada
|
||||
|
||||
// Parse JSON recebido
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (json == NULL) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Atualizando as configurações OCPP
|
||||
cJSON *url = cJSON_GetObjectItem(json, "url");
|
||||
if (url) strlcpy(ocpp_config.url, url->valuestring, sizeof(ocpp_config.url));
|
||||
|
||||
cJSON *chargeBoxId = cJSON_GetObjectItem(json, "chargeBoxId");
|
||||
if (chargeBoxId) strlcpy(ocpp_config.chargeBoxId, chargeBoxId->valuestring, sizeof(ocpp_config.chargeBoxId));
|
||||
|
||||
cJSON *certificate = cJSON_GetObjectItem(json, "certificate");
|
||||
if (certificate) strlcpy(ocpp_config.certificate, certificate->valuestring, sizeof(ocpp_config.certificate));
|
||||
|
||||
cJSON *privateKey = cJSON_GetObjectItem(json, "privateKey");
|
||||
if (privateKey) strlcpy(ocpp_config.privateKey, privateKey->valuestring, sizeof(ocpp_config.privateKey));
|
||||
|
||||
cJSON_Delete(json);
|
||||
|
||||
// Responder com uma mensagem de sucesso
|
||||
httpd_resp_sendstr(req, "Configuração OCPP atualizada com sucesso");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// Manipulador para o endpoint POST /api/v1/config/settings
|
||||
static esp_err_t config_settings_post_handler(httpd_req_t *req)
|
||||
{
|
||||
char buf[512]; // Buffer para armazenar a requisição
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid request body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
buf[len] = '\0'; // Garantir que a string esteja terminada
|
||||
|
||||
// Parse JSON recebido
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (json == NULL) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Atualizando as configurações
|
||||
cJSON *currentLimit = cJSON_GetObjectItem(json, "currentLimit");
|
||||
if (currentLimit)
|
||||
evse_set_max_charging_current(currentLimit->valueint);
|
||||
//settings_config.currentLimit = currentLimit->valueint;
|
||||
|
||||
cJSON *powerLimit = cJSON_GetObjectItem(json, "powerLimit");
|
||||
if (powerLimit) settings_config.powerLimit = powerLimit->valueint;
|
||||
|
||||
cJSON *energyLimit = cJSON_GetObjectItem(json, "energyLimit");
|
||||
if (energyLimit) settings_config.energyLimit = energyLimit->valueint;
|
||||
|
||||
cJSON *chargingTimeLimit = cJSON_GetObjectItem(json, "chargingTimeLimit");
|
||||
if (chargingTimeLimit) settings_config.chargingTimeLimit = chargingTimeLimit->valueint;
|
||||
|
||||
cJSON *temperatureLimit = cJSON_GetObjectItem(json, "temperatureLimit");
|
||||
if (temperatureLimit)
|
||||
evse_set_temp_threshold(temperatureLimit->valueint);
|
||||
|
||||
//settings_config.temperatureLimit = temperatureLimit->valueint;
|
||||
|
||||
cJSON_Delete(json);
|
||||
|
||||
// Responder com uma mensagem de sucesso
|
||||
httpd_resp_sendstr(req, "Configurações de energia atualizadas com sucesso");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
// Manipulador para o endpoint GET /api/v1/config/settings
|
||||
static esp_err_t config_settings_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Criar objeto JSON para enviar as configurações atuais
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
|
||||
|
||||
//cJSON_AddNumberToObject(config, "maxCurrentLimit", evse_get_max_charging_current());
|
||||
cJSON_AddNumberToObject(config, "currentLimit", evse_get_max_charging_current());
|
||||
cJSON_AddNumberToObject(config, "powerLimit", settings_config.powerLimit);
|
||||
cJSON_AddNumberToObject(config, "energyLimit", settings_config.energyLimit);
|
||||
cJSON_AddNumberToObject(config, "chargingTimeLimit", settings_config.chargingTimeLimit);
|
||||
cJSON_AddNumberToObject(config, "temperatureLimit", evse_get_temp_threshold());
|
||||
|
||||
// Convertendo para string e enviando a resposta
|
||||
const char *config_str = cJSON_Print(config);
|
||||
httpd_resp_sendstr(req, config_str);
|
||||
|
||||
// Liberando a memória
|
||||
free((void *)config_str);
|
||||
cJSON_Delete(config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
// Manipulador para o endpoint GET /api/v1/dashboard
|
||||
static esp_err_t dashboard_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Criar objeto JSON com os dados do Dashboard
|
||||
cJSON *dashboard = cJSON_CreateObject();
|
||||
|
||||
// Status do sistema
|
||||
cJSON_AddStringToObject(dashboard, "status", "Ativo");
|
||||
|
||||
// Carregadores (exemplo)
|
||||
cJSON *chargers = cJSON_CreateArray();
|
||||
cJSON *charger1 = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(charger1, "id", 1);
|
||||
cJSON_AddStringToObject(charger1, "status", "Ativo");
|
||||
cJSON_AddNumberToObject(charger1, "current", 12);
|
||||
cJSON_AddNumberToObject(charger1, "power", 2200);
|
||||
cJSON_AddItemToArray(chargers, charger1);
|
||||
|
||||
cJSON_AddItemToObject(dashboard, "chargers", chargers);
|
||||
|
||||
// Consumo de energia
|
||||
cJSON_AddNumberToObject(dashboard, "energyConsumed", 50.3);
|
||||
|
||||
// Tempo de carregamento
|
||||
cJSON_AddNumberToObject(dashboard, "chargingTime", 120);
|
||||
|
||||
// Alertas
|
||||
cJSON *alerts = cJSON_CreateArray();
|
||||
cJSON_AddItemToArray(alerts, cJSON_CreateString("Aviso: Carregador 1 está com erro."));
|
||||
cJSON_AddItemToObject(dashboard, "alerts", alerts);
|
||||
|
||||
// Convertendo para string e enviando a resposta
|
||||
const char *dashboard_str = cJSON_Print(dashboard);
|
||||
httpd_resp_sendstr(req, dashboard_str);
|
||||
|
||||
// Liberando a memória
|
||||
free((void *)dashboard_str);
|
||||
cJSON_Delete(dashboard);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t config_wifi_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Criar objeto JSON com as configurações de Wi-Fi
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
cJSON_AddBoolToObject(config, "enabled", wifi_config.enabled);
|
||||
cJSON_AddStringToObject(config, "ssid", wifi_config.ssid);
|
||||
cJSON_AddStringToObject(config, "password", wifi_config.password);
|
||||
|
||||
// Convertendo para string e enviando a resposta
|
||||
const char *config_str = cJSON_Print(config);
|
||||
httpd_resp_sendstr(req, config_str);
|
||||
|
||||
// Liberando a memória
|
||||
free((void *)config_str);
|
||||
cJSON_Delete(config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Manipulador para o endpoint POST /api/v1/config/wifi */
|
||||
static esp_err_t config_wifi_post_handler(httpd_req_t *req)
|
||||
{
|
||||
char buf[512]; // Buffer para armazenar a requisição
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid request body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
buf[len] = '\0'; // Garantir que a string esteja terminada
|
||||
|
||||
// Parse JSON recebido
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (json == NULL) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Atualizando as configurações Wi-Fi
|
||||
cJSON *enabled = cJSON_GetObjectItem(json, "enabled");
|
||||
if (enabled) wifi_config.enabled = enabled->valueint;
|
||||
|
||||
cJSON *ssid = cJSON_GetObjectItem(json, "ssid");
|
||||
if (ssid) strlcpy(wifi_config.ssid, ssid->valuestring, sizeof(wifi_config.ssid));
|
||||
|
||||
cJSON *password = cJSON_GetObjectItem(json, "password");
|
||||
if (password) strlcpy(wifi_config.password, password->valuestring, sizeof(wifi_config.password));
|
||||
|
||||
cJSON_Delete(json);
|
||||
|
||||
// Responder com uma mensagem de sucesso
|
||||
httpd_resp_sendstr(req, "Configuração Wi-Fi atualizada com sucesso");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Manipulador para o endpoint GET /api/v1/config/mqtt */
|
||||
static esp_err_t config_mqtt_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Criar objeto JSON com as configurações de MQTT
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
cJSON_AddBoolToObject(config, "enabled", mqtt_config.enabled);
|
||||
cJSON_AddStringToObject(config, "host", mqtt_config.host);
|
||||
cJSON_AddNumberToObject(config, "port", mqtt_config.port);
|
||||
cJSON_AddStringToObject(config, "username", mqtt_config.username);
|
||||
cJSON_AddStringToObject(config, "password", mqtt_config.password);
|
||||
cJSON_AddStringToObject(config, "topic", mqtt_config.topic);
|
||||
|
||||
// Convertendo para string e enviando a resposta
|
||||
const char *config_str = cJSON_Print(config);
|
||||
httpd_resp_sendstr(req, config_str);
|
||||
|
||||
// Liberando a memória
|
||||
free((void *)config_str);
|
||||
cJSON_Delete(config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Manipulador para o endpoint POST /api/v1/config/mqtt */
|
||||
static esp_err_t config_mqtt_post_handler(httpd_req_t *req)
|
||||
{
|
||||
char buf[512]; // Buffer para armazenar a requisição
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid request body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
buf[len] = '\0'; // Garantir que a string esteja terminada
|
||||
|
||||
// Parse JSON recebido
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (json == NULL) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
// Atualizando as configurações MQTT
|
||||
cJSON *enabled = cJSON_GetObjectItem(json, "enabled");
|
||||
if (enabled) mqtt_config.enabled = enabled->valueint;
|
||||
|
||||
cJSON *host = cJSON_GetObjectItem(json, "host");
|
||||
if (host) strlcpy(mqtt_config.host, host->valuestring, sizeof(mqtt_config.host));
|
||||
|
||||
cJSON *port = cJSON_GetObjectItem(json, "port");
|
||||
if (port) mqtt_config.port = port->valueint;
|
||||
|
||||
cJSON *username = cJSON_GetObjectItem(json, "username");
|
||||
if (username) strlcpy(mqtt_config.username, username->valuestring, sizeof(mqtt_config.username));
|
||||
|
||||
cJSON *password = cJSON_GetObjectItem(json, "password");
|
||||
if (password) strlcpy(mqtt_config.password, password->valuestring, sizeof(mqtt_config.password));
|
||||
|
||||
cJSON *topic = cJSON_GetObjectItem(json, "topic");
|
||||
if (topic) strlcpy(mqtt_config.topic, topic->valuestring, sizeof(mqtt_config.topic));
|
||||
|
||||
cJSON_Delete(json);
|
||||
|
||||
// Responder com uma mensagem de sucesso
|
||||
httpd_resp_sendstr(req, "Configuração MQTT atualizada com sucesso");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// GET /api/v1/config/auth-methods
|
||||
static esp_err_t config_auth_methods_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
cJSON_AddBoolToObject(config, "RFID", auth_is_enabled());
|
||||
cJSON_AddBoolToObject(config, "App", false);
|
||||
cJSON_AddBoolToObject(config, "Password", false);
|
||||
|
||||
char *config_str = cJSON_PrintUnformatted(config);
|
||||
httpd_resp_sendstr(req, config_str);
|
||||
|
||||
free(config_str);
|
||||
cJSON_Delete(config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// POST /api/v1/config/auth-methods
|
||||
static esp_err_t config_auth_methods_post_handler(httpd_req_t *req)
|
||||
{
|
||||
char buf[512];
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid request body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
|
||||
cJSON *json = cJSON_Parse(buf);
|
||||
if (!json) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid JSON");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
cJSON *RFID = cJSON_GetObjectItem(json, "RFID");
|
||||
if (cJSON_IsBool(RFID)) {
|
||||
auth_set_enabled(cJSON_IsTrue(RFID));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
cJSON *App = cJSON_GetObjectItem(json, "App");
|
||||
if (cJSON_IsBool(App)) {
|
||||
auth_methods.App = cJSON_IsTrue(App);
|
||||
}
|
||||
|
||||
cJSON *Password = cJSON_GetObjectItem(json, "Password");
|
||||
if (cJSON_IsBool(Password)) {
|
||||
auth_methods.Password = cJSON_IsTrue(Password);
|
||||
}*/
|
||||
|
||||
cJSON_Delete(json);
|
||||
|
||||
httpd_resp_sendstr(req, "Configurações de autenticação atualizadas com sucesso");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Manipulador para o endpoint GET /api/v1/config/users
|
||||
static esp_err_t config_users_get_handler(httpd_req_t *req)
|
||||
{
|
||||
httpd_resp_set_type(req, "application/json");
|
||||
|
||||
// Criar objeto JSON com a lista de usuários
|
||||
cJSON *config = cJSON_CreateObject();
|
||||
cJSON *users_list = cJSON_CreateArray();
|
||||
|
||||
for (int i = 0; i < num_users; i++) {
|
||||
cJSON *user = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(user, "username", users[i].username);
|
||||
cJSON_AddItemToArray(users_list, user);
|
||||
}
|
||||
|
||||
cJSON_AddItemToObject(config, "users", users_list);
|
||||
|
||||
// Convertendo para string e enviando a resposta
|
||||
const char *config_str = cJSON_Print(config);
|
||||
httpd_resp_sendstr(req, config_str);
|
||||
|
||||
// Liberando a memória
|
||||
free((void *)config_str);
|
||||
cJSON_Delete(config);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
// Manipulador para o endpoint POST /api/v1/config/users
|
||||
static esp_err_t config_users_post_handler(httpd_req_t *req)
|
||||
{
|
||||
char buf[128]; // Buffer para armazenar o nome do novo usuário
|
||||
int len = httpd_req_recv(req, buf, sizeof(buf) - 1);
|
||||
if (len <= 0) {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Invalid request body");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
buf[len] = '\0'; // Garantir que a string esteja terminada
|
||||
|
||||
// Adicionar o novo usuário
|
||||
if (num_users < 10) {
|
||||
strlcpy(users[num_users].username, buf, sizeof(users[num_users].username));
|
||||
num_users++;
|
||||
httpd_resp_sendstr(req, "Usuário adicionado com sucesso");
|
||||
} else {
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Máximo de usuários atingido");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
// Manipulador para o endpoint DELETE /api/v1/config/users/{username}
|
||||
static esp_err_t config_users_delete_handler(httpd_req_t *req)
|
||||
{
|
||||
char username[128]; // Nome do usuário a ser removido
|
||||
if (httpd_req_get_url_query_str(req, username, sizeof(username)) == ESP_OK) {
|
||||
// Verificar e remover o usuário
|
||||
for (int i = 0; i < num_users; i++) {
|
||||
if (strcmp(users[i].username, username) == 0) {
|
||||
// Remover o usuário
|
||||
for (int j = i; j < num_users - 1; j++) {
|
||||
users[j] = users[j + 1];
|
||||
}
|
||||
num_users--;
|
||||
httpd_resp_sendstr(req, "Usuário removido com sucesso");
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
httpd_resp_send_err(req, HTTPD_400_BAD_REQUEST, "Usuário não encontrado");
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
esp_err_t rest_init(const char *base_path)
|
||||
{
|
||||
|
||||
/*
|
||||
REST_CHECK(base_path, "wrong base path", err);
|
||||
rest_server_context_t *rest_context = calloc(1, sizeof(rest_server_context_t));
|
||||
REST_CHECK(rest_context, "No memory for rest context", err_start);
|
||||
strlcpy(rest_context->base_path, base_path, sizeof(rest_context->base_path));
|
||||
|
||||
httpd_handle_t server = NULL;
|
||||
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
|
||||
config.max_uri_handlers = 30; // Ajuste conforme necessário
|
||||
config.uri_match_fn = httpd_uri_match_wildcard;
|
||||
|
||||
ESP_LOGI(REST_TAG, "Starting HTTP Server");
|
||||
REST_CHECK(httpd_start(&server, &config) == ESP_OK, "Start server failed", err_start);
|
||||
|
||||
// Registrar manipuladores de URI para as configurações
|
||||
httpd_uri_t config_load_balancing_get_uri = {
|
||||
.uri = "/api/v1/config/load-balancing",
|
||||
.method = HTTP_GET,
|
||||
.handler = config_load_balancing_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_load_balancing_get_uri);
|
||||
|
||||
// URI handler for fetching OCPP status
|
||||
httpd_uri_t ocpp_status_get_uri = {
|
||||
.uri = "/api/v1/ocpp",
|
||||
.method = HTTP_GET,
|
||||
.handler = ocpp_status_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &ocpp_status_get_uri);
|
||||
|
||||
// URI handler for fetching OCPP config
|
||||
httpd_uri_t config_ocpp_get_uri = {
|
||||
.uri = "/api/v1/config/ocpp",
|
||||
.method = HTTP_GET,
|
||||
.handler = config_ocpp_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_ocpp_get_uri);
|
||||
|
||||
// URI handler for posting OCPP config
|
||||
httpd_uri_t config_ocpp_post_uri = {
|
||||
.uri = "/api/v1/config/ocpp",
|
||||
.method = HTTP_POST,
|
||||
.handler = config_ocpp_post_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_ocpp_post_uri);
|
||||
|
||||
// Manipulador para o endpoint POST /api/v1/config/settings
|
||||
httpd_uri_t config_settings_post_uri = {
|
||||
.uri = "/api/v1/config/settings",
|
||||
.method = HTTP_POST,
|
||||
.handler = config_settings_post_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_settings_post_uri);
|
||||
|
||||
// Manipulador para o endpoint GET /api/v1/config/settings
|
||||
httpd_uri_t config_settings_get_uri = {
|
||||
.uri = "/api/v1/config/settings",
|
||||
.method = HTTP_GET,
|
||||
.handler = config_settings_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_settings_get_uri);
|
||||
|
||||
// Manipulador para o endpoint GET /api/v1/dashboard
|
||||
httpd_uri_t dashboard_get_uri = {
|
||||
.uri = "/api/v1/dashboard",
|
||||
.method = HTTP_GET,
|
||||
.handler = dashboard_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &dashboard_get_uri);
|
||||
|
||||
// Register URI Handlers for electrical configuration
|
||||
httpd_uri_t electrical_config_get_uri = {
|
||||
.uri = "/api/v1/config/electrical",
|
||||
.method = HTTP_GET,
|
||||
.handler = electrical_config_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &electrical_config_get_uri);
|
||||
|
||||
httpd_uri_t electrical_config_post_uri = {
|
||||
.uri = "/api/v1/config/electrical",
|
||||
.method = HTTP_POST,
|
||||
.handler = electrical_config_post_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &electrical_config_post_uri);
|
||||
|
||||
// URI handler for getting Wi-Fi config
|
||||
httpd_uri_t config_wifi_get_uri = {
|
||||
.uri = "/api/v1/config/wifi",
|
||||
.method = HTTP_GET,
|
||||
.handler = config_wifi_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_wifi_get_uri);
|
||||
|
||||
// URI handler for posting Wi-Fi config
|
||||
httpd_uri_t config_wifi_post_uri = {
|
||||
.uri = "/api/v1/config/wifi",
|
||||
.method = HTTP_POST,
|
||||
.handler = config_wifi_post_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_wifi_post_uri);
|
||||
|
||||
// URI handler for getting MQTT config
|
||||
httpd_uri_t config_mqtt_get_uri = {
|
||||
.uri = "/api/v1/config/mqtt",
|
||||
.method = HTTP_GET,
|
||||
.handler = config_mqtt_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_mqtt_get_uri);
|
||||
|
||||
// URI handler for posting MQTT config
|
||||
httpd_uri_t config_mqtt_post_uri = {
|
||||
.uri = "/api/v1/config/mqtt",
|
||||
.method = HTTP_POST,
|
||||
.handler = config_mqtt_post_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_mqtt_post_uri);
|
||||
|
||||
// Registrar manipuladores para as configurações de autenticação
|
||||
httpd_uri_t config_auth_methods_get_uri = {
|
||||
.uri = "/api/v1/config/auth-methods",
|
||||
.method = HTTP_GET,
|
||||
.handler = config_auth_methods_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_auth_methods_get_uri);
|
||||
|
||||
httpd_uri_t config_auth_methods_post_uri = {
|
||||
.uri = "/api/v1/config/auth-methods",
|
||||
.method = HTTP_POST,
|
||||
.handler = config_auth_methods_post_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_auth_methods_post_uri);
|
||||
|
||||
// Registrar manipuladores para as configurações de usuários
|
||||
httpd_uri_t config_users_get_uri = {
|
||||
.uri = "/api/v1/config/users",
|
||||
.method = HTTP_GET,
|
||||
.handler = config_users_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_users_get_uri);
|
||||
|
||||
httpd_uri_t config_users_post_uri = {
|
||||
.uri = "/api/v1/config/users",
|
||||
.method = HTTP_POST,
|
||||
.handler = config_users_post_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_users_post_uri);
|
||||
|
||||
httpd_uri_t config_users_delete_uri = {
|
||||
.uri = "/api/v1/config/users",
|
||||
.method = HTTP_DELETE,
|
||||
.handler = config_users_delete_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &config_users_delete_uri);
|
||||
|
||||
// URI handler for getting web server files
|
||||
httpd_uri_t common_get_uri = {
|
||||
.uri = "/",
|
||||
.method = HTTP_GET,
|
||||
.handler = rest_common_get_handler,
|
||||
.user_ctx = rest_context
|
||||
};
|
||||
httpd_register_uri_handler(server, &common_get_uri);
|
||||
*/
|
||||
return ESP_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user