/* * evse_session.c * Implementation of evse_session module using instantaneous power accumulation */ #include // for PRIu32 #include "evse_session.h" #include "evse_meter.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" static const char *TAG = "evse_session"; // Internal state static TickType_t session_start_tick = 0; static uint32_t watt_seconds = 0; // accumulator of W·s static evse_session_t last_session; static bool last_session_valid = false; void evse_session_init(void) { session_start_tick = 0; watt_seconds = 0; last_session_valid = false; } void evse_session_start(void) { session_start_tick = xTaskGetTickCount(); watt_seconds = 0; ESP_LOGI(TAG, "Session started at tick %u", (unsigned)session_start_tick); } void evse_session_end(void) { if (session_start_tick == 0) { ESP_LOGW(TAG, "evse_session_end called without active session"); return; } TickType_t now = xTaskGetTickCount(); uint32_t duration_s = (now - session_start_tick) / configTICK_RATE_HZ; uint32_t energy_wh = watt_seconds / 3600U; uint32_t avg_power = duration_s > 0 ? watt_seconds / duration_s : 0; last_session.start_tick = session_start_tick; last_session.duration_s = duration_s; last_session.energy_wh = energy_wh; last_session.avg_power_w = avg_power; last_session.is_current = false; last_session_valid = true; session_start_tick = 0; ESP_LOGI(TAG, "Session ended: duration=%" PRIu32 " s, energy=%" PRIu32 " Wh, avg_power=%" PRIu32 " W", (uint32_t)duration_s, (uint32_t)energy_wh, (uint32_t)avg_power); } void evse_session_tick(void) { if (session_start_tick == 0) return; // Should be called every second (or known interval) uint32_t power_w = evse_meter_get_instant_power(); watt_seconds += power_w; } bool evse_session_get(evse_session_t *out) { if (out == NULL) return false; if (session_start_tick != 0) { TickType_t now = xTaskGetTickCount(); uint32_t duration_s = (now - session_start_tick) / configTICK_RATE_HZ; uint32_t energy_wh = watt_seconds / 3600U; uint32_t avg_power = duration_s > 0 ? watt_seconds / duration_s : 0; out->start_tick = session_start_tick; out->duration_s = duration_s; out->energy_wh = energy_wh; out->avg_power_w = avg_power; out->is_current = true; return true; } if (last_session_valid) { *out = last_session; return true; } return false; }