new meter

This commit is contained in:
2025-06-14 10:27:29 +01:00
parent 4892718736
commit 6f95c7ba59
228 changed files with 3178 additions and 3115 deletions

View File

@@ -1,237 +1,181 @@
#include <string.h>
#include <stdbool.h>
#include <sys/param.h>
#include "sdkconfig.h"
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_ota_ops.h"
#include "esp_log.h"
#include "esp_err.h"
#include "nvs_flash.h"
#include "esp_event.h"
#include "esp_netif.h"
#include "esp_spiffs.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/gpio.h"
#include "evse_api.h"
#include "evse_manager.h"
#include "peripherals.h"
#include "led.h"
#include "api.h"
#include "protocols.h"
#include "meter_zigbee.h"
#include "board_config.h"
#include "wifi.h"
#include "board_config.h"
#include "logger.h"
#include "loadbalancer.h"
#include "rest_main.h"
#include "peripherals.h"
#include "protocols.h"
#include "evse_manager.h"
#include "evse_api.h"
#include "auth.h"
#include "loadbalancer.h"
#include "meter_manager.h"
#define EVSE_MANAGER_TICK_PERIOD_MS 1000 // 1 segundo
#define AP_CONNECTION_TIMEOUT 60000 // 60sec
#define RESET_HOLD_TIME 10000 // 10sec
#define PRESS_BIT BIT0
#define RELEASED_BIT BIT1
#define EVSE_MANAGER_TICK_PERIOD_MS 1000
#define AP_CONNECTION_TIMEOUT 120000
#define RESET_HOLD_TIME 10000
#define DEBOUNCE_TIME_MS 50
#define PRESS_BIT BIT0
#define RELEASED_BIT BIT1
static const char *TAG = "app_main";
static TaskHandle_t user_input_task;
static bool pressed = false; // Variável para verificar se o botão foi pressionado
static TickType_t press_tick = 0; // Variável para armazenar o tempo de pressionamento do botão
static TickType_t press_tick = 0;
static TickType_t last_interrupt_tick = 0;
static bool pressed = false;
static void reset_and_reboot(void)
{
ESP_LOGW(TAG, "All settings will be erased...");
ESP_ERROR_CHECK(nvs_flash_erase());
ESP_LOGW(TAG, "Rebooting...");
vTaskDelay(pdMS_TO_TICKS(500));
esp_restart();
}
static void wifi_event_task_func(void *param)
{
EventBits_t mode_bits;
while (true)
{
mode_bits = xEventGroupWaitBits(wifi_event_group, WIFI_AP_MODE_BIT | WIFI_STA_MODE_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
if (mode_bits & WIFI_AP_MODE_BIT)
{
if (xEventGroupWaitBits(wifi_event_group, WIFI_AP_CONNECTED_BIT | WIFI_STA_MODE_BIT, pdFALSE, pdFALSE, pdMS_TO_TICKS(AP_CONNECTION_TIMEOUT)) & WIFI_AP_CONNECTED_BIT)
{
do
{
} while (!(xEventGroupWaitBits(wifi_event_group, WIFI_AP_DISCONNECTED_BIT | WIFI_STA_MODE_BIT, pdFALSE, pdFALSE, portMAX_DELAY) & WIFI_AP_DISCONNECTED_BIT));
}
else
{
if (xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT)
{
wifi_ap_stop();
}
}
}
else if (mode_bits & WIFI_STA_MODE_BIT)
{
if (xEventGroupWaitBits(wifi_event_group, WIFI_STA_CONNECTED_BIT | WIFI_AP_MODE_BIT, pdFALSE, pdFALSE, portMAX_DELAY) & WIFI_STA_CONNECTED_BIT)
{
do
{
} while (!(xEventGroupWaitBits(wifi_event_group, WIFI_STA_DISCONNECTED_BIT | WIFI_AP_MODE_BIT, pdFALSE, pdFALSE, portMAX_DELAY) & WIFI_STA_DISCONNECTED_BIT));
}
}
}
}
static void handle_button_press(void)
{
if (xTaskGetTickCount() - press_tick >= pdMS_TO_TICKS(RESET_HOLD_TIME)) {
evse_set_available(false);
reset_and_reboot();
} else {
if (!(xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT)) {
wifi_ap_start();
}
}
}
static void handle_button_release(void)
{
// Lógica quando o botão for liberado
pressed = false;
}
static void user_input_task_func(void *param)
{
uint32_t notification;
while (true)
{
if (xTaskNotifyWait(0x00, 0xff, &notification, portMAX_DELAY))
{
if (notification & PRESS_BIT)
{
press_tick = xTaskGetTickCount();
pressed = true;
}
if (notification & RELEASED_BIT)
{
if (pressed)
{
handle_button_press();
}
else
{
handle_button_release();
}
}
}
}
}
static void IRAM_ATTR button_isr_handler(void *arg)
{
BaseType_t higher_task_woken = pdFALSE;
if (!gpio_get_level(board_config.button_wifi_gpio))
{
xTaskNotifyFromISR(user_input_task, RELEASED_BIT, eSetBits, &higher_task_woken);
}
else
{
xTaskNotifyFromISR(user_input_task, PRESS_BIT, eSetBits, &higher_task_woken);
}
if (higher_task_woken)
{
portYIELD_FROM_ISR();
}
}
static void button_init(void)
{
gpio_config_t conf = {
.pin_bit_mask = BIT64(board_config.button_wifi_gpio),
.mode = GPIO_MODE_INPUT,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.pull_up_en = GPIO_PULLUP_ENABLE,
.intr_type = GPIO_INTR_ANYEDGE};
ESP_ERROR_CHECK(gpio_config(&conf));
ESP_ERROR_CHECK(gpio_isr_handler_add(board_config.button_wifi_gpio, button_isr_handler, NULL));
}
static void fs_info(esp_vfs_spiffs_conf_t *conf)
{
//
// File system (SPIFFS) init and info
//
static void fs_info(esp_vfs_spiffs_conf_t *conf) {
size_t total = 0, used = 0;
esp_err_t ret = esp_spiffs_info(conf->partition_label, &total, &used);
if (ret != ESP_OK)
{
ESP_LOGE(TAG, "Failed to get partition %s information %s", conf->partition_label, esp_err_to_name(ret));
}
if (ret == ESP_OK)
ESP_LOGI(TAG, "Partition %s: total: %d, used: %d", conf->partition_label, total, used);
else
{
ESP_LOGI(TAG, "Partition %s size: total: %d, used: %d", conf->partition_label, total, used);
}
ESP_LOGE(TAG, "Failed to get SPIFFS info: %s", esp_err_to_name(ret));
}
static void fs_init(void)
{
static void fs_init(void) {
esp_vfs_spiffs_conf_t cfg_conf = {
.base_path = "/cfg",
.partition_label = "cfg",
.max_files = 1,
.format_if_mount_failed = false};
esp_err_t ret = esp_vfs_spiffs_register(&cfg_conf);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount SPIFFS partition 'cfg'. Error: %s", esp_err_to_name(ret));
return; // Ou reinicie o dispositivo dependendo do caso
}
.format_if_mount_failed = false
};
esp_vfs_spiffs_conf_t data_conf = {
.base_path = "/data",
.partition_label = "data",
.max_files = 5,
.format_if_mount_failed = true};
ret = esp_vfs_spiffs_register(&data_conf);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to mount SPIFFS partition 'data'. Error: %s", esp_err_to_name(ret));
return; // Ou reinicie o dispositivo dependendo do caso
}
.format_if_mount_failed = true
};
ESP_ERROR_CHECK(esp_vfs_spiffs_register(&cfg_conf));
ESP_ERROR_CHECK(esp_vfs_spiffs_register(&data_conf));
fs_info(&cfg_conf);
fs_info(&data_conf);
}
static bool ota_diagnostic(void)
{
// TODO diagnostic after ota
return true;
//
// Wi-Fi event monitoring task
//
static void wifi_event_task_func(void *param) {
EventBits_t mode_bits;
while (1) {
mode_bits = xEventGroupWaitBits(wifi_event_group, WIFI_AP_MODE_BIT | WIFI_STA_MODE_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
if (mode_bits & WIFI_AP_MODE_BIT) {
if (xEventGroupWaitBits(wifi_event_group, WIFI_AP_CONNECTED_BIT, pdFALSE, pdFALSE, pdMS_TO_TICKS(AP_CONNECTION_TIMEOUT)) & WIFI_AP_CONNECTED_BIT) {
xEventGroupWaitBits(wifi_event_group, WIFI_AP_DISCONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
} else {
if (xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT) {
//wifi_ap_stop();
}
}
} else if (mode_bits & WIFI_STA_MODE_BIT) {
xEventGroupWaitBits(wifi_event_group, WIFI_STA_DISCONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
}
}
}
static void init_modules(void)
{
QueueHandle_t auth_queue = xQueueCreate(10, sizeof(auth_event_t));
//
// Botão e tratamento
//
static void handle_button_press(void) {
ESP_LOGI(TAG, "Ativando modo AP");
if (!(xEventGroupGetBits(wifi_event_group) & WIFI_AP_MODE_BIT)) {
wifi_ap_start();
}
}
static void user_input_task_func(void *param) {
uint32_t notification;
while (1) {
if (xTaskNotifyWait(0x00, 0xFF, &notification, portMAX_DELAY)) {
if (notification & PRESS_BIT) {
press_tick = xTaskGetTickCount();
pressed = true;
ESP_LOGI(TAG, "Botão pressionado");
}
wifi_ini();
if (notification & RELEASED_BIT && pressed) {
pressed = false;
ESP_LOGI(TAG, "Botão liberado");
handle_button_press();
}
}
}
}
static void IRAM_ATTR button_isr_handler(void *arg) {
BaseType_t higher_task_woken = pdFALSE;
TickType_t now = xTaskGetTickCountFromISR();
if (now - last_interrupt_tick < pdMS_TO_TICKS(DEBOUNCE_TIME_MS)) return;
last_interrupt_tick = now;
if (!gpio_get_level(board_config.button_wifi_gpio)) {
xTaskNotifyFromISR(user_input_task, RELEASED_BIT, eSetBits, &higher_task_woken);
} else {
xTaskNotifyFromISR(user_input_task, PRESS_BIT, eSetBits, &higher_task_woken);
}
if (higher_task_woken) {
portYIELD_FROM_ISR();
}
}
static void button_init(void) {
gpio_config_t conf = {
.pin_bit_mask = BIT64(board_config.button_wifi_gpio),
.mode = GPIO_MODE_INPUT,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.pull_up_en = GPIO_PULLUP_ENABLE,
.intr_type = GPIO_INTR_ANYEDGE
};
ESP_ERROR_CHECK(gpio_config(&conf));
ESP_ERROR_CHECK(gpio_isr_handler_add(board_config.button_wifi_gpio, button_isr_handler, NULL));
}
//
// Inicialização dos módulos do sistema
//
static void init_modules(void) {
peripherals_init();
api_init();
//api_init();
ESP_ERROR_CHECK(rest_server_init("/data"));
protocols_init();
evse_manager_init();
evse_init(); // Cria a task para FSM
button_init();
auth_init();
auth_set_event_queue(auth_queue);
evse_manager_start(auth_queue);
loadbalancer_init();
meter_manager_grid_init();
meter_manager_grid_start();
//meter_manager_evse_init();
// Outros módulos (descomente conforme necessário)
// meter_init();
@@ -244,36 +188,18 @@ static void init_modules(void)
// slave_sync_start();
}
void app_main(void)
{
//
// Função principal do firmware
//
void app_main(void) {
logger_init();
esp_log_set_vprintf(logger_vprintf);
const esp_partition_t *running = esp_ota_get_running_partition();
ESP_LOGI(TAG, "Running partition: %s", running->label);
esp_ota_img_states_t ota_state;
if (esp_ota_get_state_partition(running, &ota_state) == ESP_OK)
{
if (ota_state == ESP_OTA_IMG_PENDING_VERIFY)
{
ESP_LOGI(TAG, "OTA pending verify");
if (ota_diagnostic())
{
ESP_LOGI(TAG, "Diagnostics completed successfully! Continuing execution ...");
esp_ota_mark_app_valid_cancel_rollback();
}
else
{
ESP_LOGE(TAG, "Diagnostics failed! Starting rollback to the previous version ...");
esp_ota_mark_app_invalid_rollback_and_reboot();
}
}
}
esp_reset_reason_t reason = esp_reset_reason();
ESP_LOGI(TAG, "Reset reason: %d", reason);
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND)
{
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGW(TAG, "Erasing NVS flash");
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
@@ -286,13 +212,10 @@ void app_main(void)
ESP_ERROR_CHECK(gpio_install_isr_service(0));
board_config_load();
wifi_ini();
//wifi_ap_start();
init_modules();
xTaskCreate(wifi_event_task_func, "wifi_event_task", 4 * 1024, NULL, 5, NULL);
xTaskCreate(user_input_task_func, "user_input_task", 4 * 1024, NULL, 5, &user_input_task);
// Loop principal não é necessário se tudo roda por tasks
xTaskCreate(wifi_event_task_func, "wifi_event_task", 8 * 1024, NULL, 3, NULL);
xTaskCreate(user_input_task_func, "user_input_task", 4 * 1024, NULL, 3, &user_input_task);
}