85 lines
2.6 KiB
C
85 lines
2.6 KiB
C
/*
|
|
* evse_session.c
|
|
* Implementation of evse_session module using instantaneous power accumulation
|
|
*/
|
|
#include <inttypes.h> // 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;
|
|
}
|