From 56231fa7889f5162ffbb5925f1e590da6a154417 Mon Sep 17 00:00:00 2001 From: PlxEV Date: Sun, 8 Jun 2025 14:21:10 +0100 Subject: [PATCH] Add grid and EVSE meter components with load balancer --- components/evsemeter/CMakeLists.txt | 9 +++ components/evsemeter/include/evsemeter.h | 24 +++++++ components/evsemeter/src/evsemeter_ade7758.c | 21 ++++++ components/evsemeter/src/evsemeter_events.c | 3 + components/evsemeter/src/evsemeter_modbus.c | 22 ++++++ components/gridmeter/CMakeLists.txt | 8 +++ components/gridmeter/include/gridmeter.h | 24 +++++++ components/gridmeter/src/gridmeter_events.c | 3 + components/gridmeter/src/gridmeter_modbus.c | 22 ++++++ components/loadbalancer/CMakeLists.txt | 7 ++ .../loadbalancer/include/loadbalancer.h | 20 ++++++ components/loadbalancer/src/loadbalancer.c | 67 +++++++++++++++++++ components/meter_orno_modbus/CMakeLists.txt | 6 ++ .../meter_orno_modbus/include/orno_modbus.h | 22 ++++++ .../meter_orno_modbus/src/orno_modbus.c | 21 ++++++ components/serial_mdb/CMakeLists.txt | 2 +- components/serial_mdb/src/serial_mdb copy.c | 2 +- components/serial_mdb/src/serial_mdb.c | 2 +- components/serial_mt/CMakeLists.txt | 2 +- components/serial_mt/src/serial_mt.c | 2 +- components/serial_sync/CMakeLists.txt | 2 +- components/serial_sync/src/sync_slave.c | 2 +- main/main.c | 3 + 23 files changed, 289 insertions(+), 7 deletions(-) create mode 100644 components/evsemeter/CMakeLists.txt create mode 100644 components/evsemeter/include/evsemeter.h create mode 100644 components/evsemeter/src/evsemeter_ade7758.c create mode 100644 components/evsemeter/src/evsemeter_events.c create mode 100644 components/evsemeter/src/evsemeter_modbus.c create mode 100644 components/gridmeter/CMakeLists.txt create mode 100644 components/gridmeter/include/gridmeter.h create mode 100644 components/gridmeter/src/gridmeter_events.c create mode 100644 components/gridmeter/src/gridmeter_modbus.c create mode 100644 components/loadbalancer/CMakeLists.txt create mode 100644 components/loadbalancer/include/loadbalancer.h create mode 100644 components/loadbalancer/src/loadbalancer.c create mode 100644 components/meter_orno_modbus/CMakeLists.txt create mode 100644 components/meter_orno_modbus/include/orno_modbus.h create mode 100644 components/meter_orno_modbus/src/orno_modbus.c diff --git a/components/evsemeter/CMakeLists.txt b/components/evsemeter/CMakeLists.txt new file mode 100644 index 0000000..310ee77 --- /dev/null +++ b/components/evsemeter/CMakeLists.txt @@ -0,0 +1,9 @@ +set(srcs + "src/evsemeter_modbus.c" + "src/evsemeter_ade7758.c" + "src/evsemeter_events.c" +) + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "include" + REQUIRES meter_orno_modbus) diff --git a/components/evsemeter/include/evsemeter.h b/components/evsemeter/include/evsemeter.h new file mode 100644 index 0000000..29ab5e0 --- /dev/null +++ b/components/evsemeter/include/evsemeter.h @@ -0,0 +1,24 @@ +#ifndef EVSEMETER_H_ +#define EVSEMETER_H_ + +#include "esp_err.h" +#include "esp_event_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +ESP_EVENT_DECLARE_BASE(EVSEMETER_EVENT); + +typedef enum { + EVSEMETER_EVENT_UPDATE +} evsemeter_event_id_t; + +esp_err_t evsemeter_init(void); +esp_err_t evsemeter_read_current(float *current); + +#ifdef __cplusplus +} +#endif + +#endif /* EVSEMETER_H_ */ diff --git a/components/evsemeter/src/evsemeter_ade7758.c b/components/evsemeter/src/evsemeter_ade7758.c new file mode 100644 index 0000000..7b8a248 --- /dev/null +++ b/components/evsemeter/src/evsemeter_ade7758.c @@ -0,0 +1,21 @@ +#include "evsemeter.h" +#include "esp_event.h" +#include "esp_log.h" + +static const char *TAG = "evsemeter_ade7758"; + +esp_err_t evsemeter_init(void) +{ + ESP_LOGI(TAG, "Initializing EVSE meter (ADE7758)"); + return ESP_OK; +} + +esp_err_t evsemeter_read_current(float *current) +{ + if (!current) { + return ESP_ERR_INVALID_ARG; + } + *current = 0.0f; + esp_event_post(EVSEMETER_EVENT, EVSEMETER_EVENT_UPDATE, current, sizeof(float), portMAX_DELAY); + return ESP_OK; +} diff --git a/components/evsemeter/src/evsemeter_events.c b/components/evsemeter/src/evsemeter_events.c new file mode 100644 index 0000000..d14b08a --- /dev/null +++ b/components/evsemeter/src/evsemeter_events.c @@ -0,0 +1,3 @@ +#include "evsemeter.h" + +ESP_EVENT_DEFINE_BASE(EVSEMETER_EVENT); diff --git a/components/evsemeter/src/evsemeter_modbus.c b/components/evsemeter/src/evsemeter_modbus.c new file mode 100644 index 0000000..3b5c815 --- /dev/null +++ b/components/evsemeter/src/evsemeter_modbus.c @@ -0,0 +1,22 @@ +#include "evsemeter.h" +#include "orno_modbus.h" +#include "esp_event.h" +#include "esp_log.h" + +static const char *TAG = "evsemeter_modbus"; + +esp_err_t evsemeter_init(void) +{ + ESP_LOGI(TAG, "Initializing EVSE meter (Modbus)"); + return orno_modbus_init(); +} + +esp_err_t evsemeter_read_current(float *current) +{ + esp_err_t err = orno_modbus_read_current(ORNO_METER_EVSE, current); + if (err == ESP_OK) + { + esp_event_post(EVSEMETER_EVENT, EVSEMETER_EVENT_UPDATE, current, sizeof(float), portMAX_DELAY); + } + return err; +} diff --git a/components/gridmeter/CMakeLists.txt b/components/gridmeter/CMakeLists.txt new file mode 100644 index 0000000..170af36 --- /dev/null +++ b/components/gridmeter/CMakeLists.txt @@ -0,0 +1,8 @@ +set(srcs + "src/gridmeter_modbus.c" + "src/gridmeter_events.c" +) + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "include" + REQUIRES meter_orno_modbus) diff --git a/components/gridmeter/include/gridmeter.h b/components/gridmeter/include/gridmeter.h new file mode 100644 index 0000000..849851c --- /dev/null +++ b/components/gridmeter/include/gridmeter.h @@ -0,0 +1,24 @@ +#ifndef GRIDMETER_H_ +#define GRIDMETER_H_ + +#include "esp_err.h" +#include "esp_event_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +ESP_EVENT_DECLARE_BASE(GRIDMETER_EVENT); + +typedef enum { + GRIDMETER_EVENT_UPDATE +} gridmeter_event_id_t; + +esp_err_t gridmeter_init(void); +esp_err_t gridmeter_read_current(float *current); + +#ifdef __cplusplus +} +#endif + +#endif /* GRIDMETER_H_ */ diff --git a/components/gridmeter/src/gridmeter_events.c b/components/gridmeter/src/gridmeter_events.c new file mode 100644 index 0000000..75516a2 --- /dev/null +++ b/components/gridmeter/src/gridmeter_events.c @@ -0,0 +1,3 @@ +#include "gridmeter.h" + +ESP_EVENT_DEFINE_BASE(GRIDMETER_EVENT); diff --git a/components/gridmeter/src/gridmeter_modbus.c b/components/gridmeter/src/gridmeter_modbus.c new file mode 100644 index 0000000..ed45f10 --- /dev/null +++ b/components/gridmeter/src/gridmeter_modbus.c @@ -0,0 +1,22 @@ +#include "gridmeter.h" +#include "orno_modbus.h" +#include "esp_event.h" +#include "esp_log.h" + +static const char *TAG = "gridmeter_modbus"; + +esp_err_t gridmeter_init(void) +{ + ESP_LOGI(TAG, "Initializing grid meter (Modbus)"); + return orno_modbus_init(); +} + +esp_err_t gridmeter_read_current(float *current) +{ + esp_err_t err = orno_modbus_read_current(ORNO_METER_GRID, current); + if (err == ESP_OK) + { + esp_event_post(GRIDMETER_EVENT, GRIDMETER_EVENT_UPDATE, current, sizeof(float), portMAX_DELAY); + } + return err; +} diff --git a/components/loadbalancer/CMakeLists.txt b/components/loadbalancer/CMakeLists.txt new file mode 100644 index 0000000..e1c92ec --- /dev/null +++ b/components/loadbalancer/CMakeLists.txt @@ -0,0 +1,7 @@ +set(srcs + "src/loadbalancer.c" +) + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "include" + REQUIRES gridmeter evsemeter) diff --git a/components/loadbalancer/include/loadbalancer.h b/components/loadbalancer/include/loadbalancer.h new file mode 100644 index 0000000..77562a7 --- /dev/null +++ b/components/loadbalancer/include/loadbalancer.h @@ -0,0 +1,20 @@ +#ifndef LOADBALANCER_H_ +#define LOADBALANCER_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void loadbalancer_init(void); +void loadbalancer_task(void *param); + +// Compatibility functions +void setMaxGridCurrent(int max_grid_current); +void setLiveGridCurrent(int live_grid_current); +void setLiveVolt(int live_volt); + +#ifdef __cplusplus +} +#endif + +#endif /* LOADBALANCER_H_ */ diff --git a/components/loadbalancer/src/loadbalancer.c b/components/loadbalancer/src/loadbalancer.c new file mode 100644 index 0000000..3a185b9 --- /dev/null +++ b/components/loadbalancer/src/loadbalancer.c @@ -0,0 +1,67 @@ +#include "loadbalancer.h" +#include "gridmeter.h" +#include "evsemeter.h" +#include "evse_api.h" +#include "esp_event.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +static const char *TAG = "loadbalancer"; + +static float grid_current = 0.0f; +static float evse_current = 0.0f; +static float max_grid_current = 32.0f; // amperes + +static void grid_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data) +{ + if (id == GRIDMETER_EVENT_UPDATE && data) + { + grid_current = *(float *)data; + } +} + +static void evse_event_handler(void *arg, esp_event_base_t base, int32_t id, void *data) +{ + if (id == EVSEMETER_EVENT_UPDATE && data) + { + evse_current = *(float *)data; + } +} + +void loadbalancer_init(void) +{ + ESP_LOGI(TAG, "Initializing load balancer"); + esp_event_handler_register(GRIDMETER_EVENT, GRIDMETER_EVENT_UPDATE, grid_event_handler, NULL); + esp_event_handler_register(EVSEMETER_EVENT, EVSEMETER_EVENT_UPDATE, evse_event_handler, NULL); +} + +void loadbalancer_task(void *param) +{ + while (true) + { + float available = max_grid_current - grid_current + evse_current; + if (available < 6.0f) + { + available = 6.0f; + } + ESP_LOGD(TAG, "Setting current limit: %f", available); + evse_set_current_limit((uint16_t)available); + vTaskDelay(pdMS_TO_TICKS(1000)); + } +} + +void setMaxGridCurrent(int value) +{ + max_grid_current = value / 10.0f; // assume value in A*10 +} + +void setLiveGridCurrent(int value) +{ + grid_current = value / 10.0f; +} + +void setLiveVolt(int value) +{ + (void)value; // unused for now +} diff --git a/components/meter_orno_modbus/CMakeLists.txt b/components/meter_orno_modbus/CMakeLists.txt new file mode 100644 index 0000000..c584d9e --- /dev/null +++ b/components/meter_orno_modbus/CMakeLists.txt @@ -0,0 +1,6 @@ +set(srcs + "src/orno_modbus.c" +) + +idf_component_register(SRCS "${srcs}" + INCLUDE_DIRS "include") diff --git a/components/meter_orno_modbus/include/orno_modbus.h b/components/meter_orno_modbus/include/orno_modbus.h new file mode 100644 index 0000000..84e7ce9 --- /dev/null +++ b/components/meter_orno_modbus/include/orno_modbus.h @@ -0,0 +1,22 @@ +#ifndef ORNO_MODBUS_H_ +#define ORNO_MODBUS_H_ + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + ORNO_METER_GRID, + ORNO_METER_EVSE +} orno_meter_type_t; + +esp_err_t orno_modbus_init(void); +esp_err_t orno_modbus_read_current(orno_meter_type_t type, float *current); + +#ifdef __cplusplus +} +#endif + +#endif /* ORNO_MODBUS_H_ */ diff --git a/components/meter_orno_modbus/src/orno_modbus.c b/components/meter_orno_modbus/src/orno_modbus.c new file mode 100644 index 0000000..4d7d85d --- /dev/null +++ b/components/meter_orno_modbus/src/orno_modbus.c @@ -0,0 +1,21 @@ +#include "orno_modbus.h" +#include "esp_log.h" + +static const char *TAG = "orno_modbus"; + +esp_err_t orno_modbus_init(void) +{ + ESP_LOGI(TAG, "Initializing ORNO Modbus driver"); + return ESP_OK; +} + +esp_err_t orno_modbus_read_current(orno_meter_type_t type, float *current) +{ + if (!current) { + return ESP_ERR_INVALID_ARG; + } + // Stub implementation - replace with real Modbus queries + *current = 0.0f; + ESP_LOGD(TAG, "Read current type %d -> %f", type, *current); + return ESP_OK; +} diff --git a/components/serial_mdb/CMakeLists.txt b/components/serial_mdb/CMakeLists.txt index 8bfdedc..0175e94 100755 --- a/components/serial_mdb/CMakeLists.txt +++ b/components/serial_mdb/CMakeLists.txt @@ -6,4 +6,4 @@ set(srcs idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "include" PRIV_REQUIRES nvs_flash driver - REQUIRES config evse peripherals esp-modbus currentshaper) \ No newline at end of file + REQUIRES config evse peripherals esp-modbus loadbalancer) diff --git a/components/serial_mdb/src/serial_mdb copy.c b/components/serial_mdb/src/serial_mdb copy.c index 9c7375c..b92ad88 100755 --- a/components/serial_mdb/src/serial_mdb copy.c +++ b/components/serial_mdb/src/serial_mdb copy.c @@ -6,7 +6,7 @@ #include "mbcontroller.h" #include "sdkconfig.h" #include "evse_api.h" -#include "currentshaper.h" +#include "loadbalancer.h" #include "meter.h" #define TXD_PIN (GPIO_NUM_17) diff --git a/components/serial_mdb/src/serial_mdb.c b/components/serial_mdb/src/serial_mdb.c index 9d87e59..ed11790 100755 --- a/components/serial_mdb/src/serial_mdb.c +++ b/components/serial_mdb/src/serial_mdb.c @@ -6,7 +6,7 @@ #include "mbcontroller.h" #include "sdkconfig.h" #include "evse_api.h" -#include "currentshaper.h" +#include "loadbalancer.h" #include "meter.h" #define TXD_PIN (GPIO_NUM_17) diff --git a/components/serial_mt/CMakeLists.txt b/components/serial_mt/CMakeLists.txt index ff8d5ca..2297059 100755 --- a/components/serial_mt/CMakeLists.txt +++ b/components/serial_mt/CMakeLists.txt @@ -5,4 +5,4 @@ set(srcs idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "include" PRIV_REQUIRES driver - REQUIRES config evse currentshaper serial_sync) + REQUIRES config evse loadbalancer serial_sync) diff --git a/components/serial_mt/src/serial_mt.c b/components/serial_mt/src/serial_mt.c index 82633c6..19e5750 100755 --- a/components/serial_mt/src/serial_mt.c +++ b/components/serial_mt/src/serial_mt.c @@ -8,7 +8,7 @@ #include "driver/gpio.h" #include "serial_mt.h" #include "evse_api.h" -#include "currentshaper.h" +#include "loadbalancer.h" #include "meter.h" //#include "app_main.h" //#include "sync_master.h" diff --git a/components/serial_sync/CMakeLists.txt b/components/serial_sync/CMakeLists.txt index 767673f..c2b689f 100755 --- a/components/serial_sync/CMakeLists.txt +++ b/components/serial_sync/CMakeLists.txt @@ -12,7 +12,7 @@ set(srcs idf_component_register(SRCS "${srcs}" INCLUDE_DIRS "include" "protobuf" PRIV_REQUIRES driver esp_timer - REQUIRES config evse currentshaper) + REQUIRES config evse loadbalancer) diff --git a/components/serial_sync/src/sync_slave.c b/components/serial_sync/src/sync_slave.c index 7b3a082..0161160 100755 --- a/components/serial_sync/src/sync_slave.c +++ b/components/serial_sync/src/sync_slave.c @@ -18,7 +18,7 @@ // #include "inc/version_autogen.h" #include "sync_slave.h" -#include "currentshaper.h" +#include "loadbalancer.h" #include "evse_api.h" #define VERSION_STRING "2.2" diff --git a/main/main.c b/main/main.c index e05f6ab..b4f7940 100755 --- a/main/main.c +++ b/main/main.c @@ -23,6 +23,7 @@ #include "board_config.h" #include "wifi.h" #include "logger.h" +#include "loadbalancer.h" #include "auth.h" @@ -229,6 +230,8 @@ static void init_modules(void) auth_init(); auth_set_event_queue(auth_queue); evse_manager_start(auth_queue); + loadbalancer_init(); + xTaskCreate(loadbalancer_task, "loadbalancer", 4096, NULL, 5, NULL); // Outros módulos (descomente conforme necessário)