Skip to content

Commit

Permalink
Update API state and error handling to new error framwork
Browse files Browse the repository at this point in the history
Signed-off-by: Cornelius Claussen <[email protected]>
  • Loading branch information
corneliusclaussen committed Jan 15, 2024
1 parent f1a0a9f commit 64d5ae3
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 63 deletions.
118 changes: 74 additions & 44 deletions modules/API/API.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace module {
static const auto NOTIFICATION_PERIOD = std::chrono::seconds(1);

SessionInfo::SessionInfo() :
state("Unknown"),
state(State::Unplugged),
start_energy_import_wh(0),
end_energy_import_wh(0),
latest_total_w(0),
Expand All @@ -19,18 +19,19 @@ SessionInfo::SessionInfo() :
this->end_time_point = this->start_time_point;
}

bool SessionInfo::is_state_charging(const std::string& current_state) {
if (current_state == "AuthRequired" || current_state == "Charging" || current_state == "ChargingPausedEV" ||
current_state == "ChargingPausedEVSE") {
bool SessionInfo::is_state_charging(const SessionInfo::State current_state) {
if (current_state == State::AuthRequired || current_state == State::Charging ||
current_state == State::ChargingPausedEV || current_state == State::ChargingPausedEVSE) {
return true;
}
return false;
}

void SessionInfo::reset() {
std::lock_guard<std::mutex> lock(this->session_info_mutex);
this->state = "Unknown";
this->state_info = "";
this->state = State::Unplugged;
this->active_permanent_faults.clear();
this->active_errors.clear();
this->start_energy_import_wh = 0;
this->end_energy_import_wh = 0;
this->start_energy_export_wh = 0;
Expand Down Expand Up @@ -65,43 +66,72 @@ types::energy::ExternalLimits get_external_limits(const std::string& data, bool
return external_limits;
}

void SessionInfo::update_state(const std::string& event, const std::string& state_info) {
void SessionInfo::update_state(const types::evse_manager::SessionEventEnum event, const std::string& error_type) {
std::lock_guard<std::mutex> lock(this->session_info_mutex);
using Event = types::evse_manager::SessionEventEnum;

if (event == Event::Enabled) {
this->state = State::Unplugged;
} else if (event == Event::Disabled) {
this->state = State::Disabled;
} else if (event == Event::SessionStarted) {
this->state = State::Preparing;
} else if (event == Event::ReservationStart) {
this->state = State::Reserved;
} else if (event == Event::ReservationEnd) {
this->state = State::Unplugged;
} else if (event == Event::AuthRequired) {
this->state = State::AuthRequired;
} else if (event == Event::WaitingForEnergy) {
this->state = State::WaitingForEnergy;
} else if (event == Event::TransactionStarted) {
this->state = State::Preparing;
} else if (event == Event::ChargingPausedEV) {
this->state = State::ChargingPausedEV;
} else if (event == Event::ChargingPausedEVSE) {
this->state = State::ChargingPausedEVSE;
} else if (event == Event::ChargingStarted) {
this->state = State::Charging;
} else if (event == Event::ChargingResumed) {
this->state = State::Charging;
} else if (event == Event::TransactionFinished) {
this->state = State::Finished;
} else if (event == Event::SessionFinished) {
this->state = State::Unplugged;
} else if (event == Event::PermanentFault) {
this->active_permanent_faults.push_back(error_type);
} else if (event == Event::Error) {
this->active_errors.push_back(error_type);
} else if (event == Event::AllErrorsCleared) {
this->active_permanent_faults.clear();
this->active_errors.clear();
}
}

this->state_info = state_info;
if (event == "Enabled") {
this->state = "Unplugged";
} else if (event == "Disabled") {
this->state = "Disabled";
} else if (event == "SessionStarted") {
this->state = "Preparing";
} else if (event == "ReservationStart") {
this->state = "Reserved";
} else if (event == "ReservationEnd") {
this->state = "Unplugged";
} else if (event == "AuthRequired") {
this->state = "AuthRequired";
} else if (event == "WaitingForEnergy") {
this->state = "WaitingForEnergy";
} else if (event == "TransactionStarted") {
this->state = "Preparing";
} else if (event == "ChargingPausedEV") {
this->state = "ChargingPausedEV";
} else if (event == "ChargingPausedEVSE") {
this->state = "ChargingPausedEVSE";
} else if (event == "ChargingStarted") {
this->state = "Charging";
} else if (event == "ChargingResumed") {
this->state = "Charging";
} else if (event == "TransactionFinished") {
this->state = "Finished";
} else if (event == "SessionFinished") {
this->state = "Unplugged";
} else if (event == "Error") {
this->state = "Error";
} else if (event == "PermanentFault") {
this->state = "PermanentFault";
std::string SessionInfo::state_to_string(SessionInfo::State s) {
switch (s) {
case SessionInfo::State::Unplugged:
return "Unplugged";
case SessionInfo::State::Disabled:
return "Disabled";
case SessionInfo::State::Preparing:
return "Preparing";
case SessionInfo::State::Reserved:
return "Reserved";
case SessionInfo::State::AuthRequired:
return "AuthRequired";
case SessionInfo::State::WaitingForEnergy:
return "WaitingForEnergy";
case SessionInfo::State::ChargingPausedEV:
return "ChargingPausedEV";
case SessionInfo::State::ChargingPausedEVSE:
return "ChargingPausedEVSE";
case SessionInfo::State::Charging:
return "Charging";
case SessionInfo::State::Finished:
return "Finished";
}
return "Unknown";
}

void SessionInfo::set_start_energy_import_wh(int32_t start_energy_import_wh) {
Expand Down Expand Up @@ -165,8 +195,9 @@ SessionInfo::operator std::string() {
auto charging_duration_s =
std::chrono::duration_cast<std::chrono::seconds>(this->end_time_point - this->start_time_point);

json session_info = json::object({{"state", this->state},
{"state_info", this->state_info},
json session_info = json::object({{"state", state_to_string(this->state)},
{"active_permanent_faults", this->active_permanent_faults},
{"active_errors", this->active_errors},
{"charged_energy_wh", charged_energy_wh},
{"discharged_energy_wh", discharged_energy_wh},
{"latest_total_w", this->latest_total_w},
Expand Down Expand Up @@ -252,12 +283,11 @@ void API::init() {

evse->subscribe_session_event(
[this, var_session_info, var_logging_path, &session_info](types::evse_manager::SessionEvent session_event) {
auto event = types::evse_manager::session_event_enum_to_string(session_event.event);
std::string state_info = "";
if (session_event.error.has_value()) {
state_info = types::evse_manager::error_enum_to_string(session_event.error.value().error_code);
}
session_info->update_state(event, state_info);
session_info->update_state(session_event.event, state_info);

if (session_event.event == types::evse_manager::SessionEventEnum::SessionStarted) {
if (session_event.session_started.has_value()) {
Expand Down
25 changes: 21 additions & 4 deletions modules/API/API.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ class SessionInfo {
private:
std::mutex session_info_mutex;

std::string state; ///< Latest state of the EVSE
std::string state_info; ///< Additional information of this state
std::vector<std::string>
active_permanent_faults; ///< Comma separated list of currently active permanent faults that prevent charging
std::vector<std::string>
active_errors; ///< Comma separated list of currently active errors that do not prevent charging

Check notice on line 43 in modules/API/API.hpp

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/API/API.hpp#L43

class member 'SessionInfo::active_errors' is never used.
int32_t start_energy_import_wh; ///< Energy reading (import) at the beginning of this charging session in Wh
int32_t end_energy_import_wh; ///< Energy reading (import) at the end of this charging session in Wh
int32_t start_energy_export_wh; ///< Energy reading (export) at the beginning of this charging session in Wh
Expand All @@ -47,7 +49,22 @@ class SessionInfo {
std::chrono::time_point<date::utc_clock> end_time_point; ///< End of the charging session
double latest_total_w; ///< Latest total power reading in W

bool is_state_charging(const std::string& current_state);
enum class State {
Unplugged,
Disabled,
Preparing,
Reserved,
AuthRequired,
WaitingForEnergy,
ChargingPausedEV,
ChargingPausedEVSE,
Charging,
Finished
} state;

bool is_state_charging(const SessionInfo::State current_state);

std::string state_to_string(State s);

public:
SessionInfo();
Expand All @@ -58,7 +75,7 @@ class SessionInfo {
false}; ///< Indicate if end export energy value (optional) has been received or not

void reset();
void update_state(const std::string& event, const std::string& state_info);
void update_state(const types::evse_manager::SessionEventEnum event, const std::string& state_info);
void set_start_energy_import_wh(int32_t start_energy_import_wh);
void set_end_energy_import_wh(int32_t end_energy_import_wh);
void set_latest_energy_import_wh(int32_t latest_energy_wh);
Expand Down
21 changes: 6 additions & 15 deletions modules/API/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ This variable is published every second and contains a json object with informat
"discharged_energy_wh": 0,
"latest_total_w": 0.0,
"state": "Unplugged",
"state_info": ""
"active_permanent_faults": "",
"active_errors": "",
}
```

Expand All @@ -64,20 +65,10 @@ This variable is published every second and contains a json object with informat
- ChargingPausedEV
- ChargingPausedEVSE
- Finished
- Error
- PermanentFault


- **state_info** contains additional information for the current state, at the moment this is only set to a meaningful value in the Error state. Here it can have the following values:
- Car
- CarDiodeFault
- Relais
- RCD
- VentilationNotAvailable
- OverCurrent
- Internal
- SLAC
- HLC

- **active_permanent_faults** array of all active errors that are permanent faults (i.e. that block charging). If anything is set here it should be shown as an error to the user instead of showing the current state.

Check warning on line 69 in modules/API/README.md

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

modules/API/README.md#L69

[list-item-indent] Incorrect list-item indent: add 2 spaces

- **active_errors** array of all active errors that do not block charging. This could be shown to the user but the current state should still be shown as it does not interfere with charging.

### everest_api/evse_manager/var/limits
This variable is published every second and contains a json object with information relating to the current limits of this EVSE.
Expand Down

0 comments on commit 64d5ae3

Please sign in to comment.