From 062d389fe394cd90cd406b44fae90e8673a07226 Mon Sep 17 00:00:00 2001 From: gregsq Date: Fri, 12 Jan 2024 00:03:33 -0800 Subject: [PATCH] Signed-off-by: gregsq Sync Operative state to connector states. Maintain Operative when made Unavailable. --- include/ocpp/v201/charge_point.hpp | 4 +++ include/ocpp/v201/connector.hpp | 1 + include/ocpp/v201/enums.hpp | 2 ++ include/ocpp/v201/evse.hpp | 5 ++++ lib/ocpp/v201/charge_point.cpp | 4 +++ lib/ocpp/v201/connector.cpp | 43 +++++++++++++++++++++++++++++- lib/ocpp/v201/enums.cpp | 8 ++++++ lib/ocpp/v201/evse.cpp | 7 +++++ 8 files changed, 73 insertions(+), 1 deletion(-) diff --git a/include/ocpp/v201/charge_point.hpp b/include/ocpp/v201/charge_point.hpp index f45c9ce27..6fff16020 100644 --- a/include/ocpp/v201/charge_point.hpp +++ b/include/ocpp/v201/charge_point.hpp @@ -591,6 +591,10 @@ class ChargePoint : ocpp::ChargingStationBase { /// becomes unavailable void on_unavailable(const int32_t evse_id, const int32_t connector_id); + /// \brief Set Unavailable on Operative conditions + /// becomes operative again + void mark_unavailable(const int32_t evse_id, const int32_t connector_id); + /// \brief Event handler that should be called when the connector on the given \p evse_id and \p connector_id /// becomes operative again void on_operative(const int32_t evse_id, const int32_t connector_id); diff --git a/include/ocpp/v201/connector.hpp b/include/ocpp/v201/connector.hpp index 697ba87a4..237e798e7 100644 --- a/include/ocpp/v201/connector.hpp +++ b/include/ocpp/v201/connector.hpp @@ -59,6 +59,7 @@ class Connector { /// \brief Get the state object /// \return ConnectorStatusEnum ConnectorStatusEnum get_state(); + void set_initial_state(const ConnectorStatusEnum new_state); /// \brief Submits the given \p event to the state machine controller /// \param event diff --git a/include/ocpp/v201/enums.hpp b/include/ocpp/v201/enums.hpp index 6babfdcdd..0bf908f8b 100644 --- a/include/ocpp/v201/enums.hpp +++ b/include/ocpp/v201/enums.hpp @@ -1781,6 +1781,7 @@ enum class ConnectorStatusEnum { Occupied, Reserved, Unavailable, + UnavailableOccupied, Faulted, }; @@ -1835,6 +1836,7 @@ enum class TriggerReasonEnum { Trigger, UnlockCommand, StopAuthorized, + EnergyTransfer, EVDeparted, EVDetected, RemoteStop, diff --git a/include/ocpp/v201/evse.hpp b/include/ocpp/v201/evse.hpp index 57f84e319..79d81549e 100644 --- a/include/ocpp/v201/evse.hpp +++ b/include/ocpp/v201/evse.hpp @@ -116,6 +116,11 @@ class Evse { /// \return ConnectorStatusEnum ConnectorStatusEnum get_state(const int32_t connector_id); + /// \brief Set the state of the connector with the given \p connector_id + /// \param connector_id id of the connector of the evse + /// \return ConnectorStatusEnum + void set_state(ConnectorStatusEnum status, const int32_t connector_id); + /// \brief Submits the given \p event to the state machine controller of the connector with the given /// \p connector_id /// \param connector_id id of the connector of the evse diff --git a/lib/ocpp/v201/charge_point.cpp b/lib/ocpp/v201/charge_point.cpp index db051b970..8fc383739 100644 --- a/lib/ocpp/v201/charge_point.cpp +++ b/lib/ocpp/v201/charge_point.cpp @@ -485,6 +485,10 @@ void ChargePoint::on_operative(const int32_t evse_id, const int32_t connector_id this->evses.at(evse_id)->submit_event(connector_id, ConnectorEvent::ReturnToOperativeState); } +void ChargePoint::mark_unavailable(const int32_t evse_id, const int32_t connector_id) { + this->evses.at(evse_id)->set_state(ConnectorStatusEnum::Unavailable, connector_id); +} + void ChargePoint::on_faulted(const int32_t evse_id, const int32_t connector_id) { this->evses.at(evse_id)->submit_event(connector_id, ConnectorEvent::Error); } diff --git a/lib/ocpp/v201/connector.cpp b/lib/ocpp/v201/connector.cpp index b70cec9a2..44aeb8f6a 100644 --- a/lib/ocpp/v201/connector.cpp +++ b/lib/ocpp/v201/connector.cpp @@ -114,6 +114,20 @@ void Connector::set_state(const ConnectorStatusEnum new_state) { this->state = new_state; } +void Connector::set_initial_state(const ConnectorStatusEnum new_state) { + std::lock_guard lg(this->state_mutex); + this->last_state = this->state; + if (new_state == ConnectorStatusEnum::Unavailable) { + if (this->state == ConnectorStatusEnum::Occupied) { + this->state = ConnectorStatusEnum::UnavailableOccupied; + } else { + this->state = ConnectorStatusEnum::Unavailable; + } + } else { + this->state = new_state; + } +} + ConnectorStatusEnum Connector::get_state() { std::lock_guard lg(this->state_mutex); return this->state; @@ -157,7 +171,7 @@ void Connector::submit_event(ConnectorEvent event) { this->set_state(ConnectorStatusEnum::Faulted); break; case ConnectorEvent::Unavailable: - this->set_state(ConnectorStatusEnum::Unavailable); + this->set_state(ConnectorStatusEnum::UnavailableOccupied); break; default: EVLOG_warning << "Invalid connector event: " << conversions::connector_event_to_string(event) @@ -216,6 +230,33 @@ void Connector::submit_event(ConnectorEvent event) { return; } break; + case ConnectorStatusEnum::UnavailableOccupied: + switch (event) { + case ConnectorEvent::UnavailableToAvailable: + [[fallthrough]]; + case ConnectorEvent::UnavailableToOccupied: + this->set_state(ConnectorStatusEnum::Occupied); + break; + case ConnectorEvent::UnavailableToReserved: + this->set_state(ConnectorStatusEnum::Reserved); + break; + case ConnectorEvent::UnavailableFaulted: + this->set_state(ConnectorStatusEnum::Faulted); + break; + case ConnectorEvent::PlugOut: + this->set_state(ConnectorStatusEnum::Unavailable); + break; + case ConnectorEvent::ReturnToOperativeState: + this->set_state(last_state); + break; + case ConnectorEvent::Unavailable: + break; + default: + EVLOG_warning << "Invalid connector event: " << conversions::connector_event_to_string(event) + << " in state UnavailableOccupied."; + return; + } + break; case ConnectorStatusEnum::Faulted: switch (event) { case ConnectorEvent::ErrorCleared: diff --git a/lib/ocpp/v201/enums.cpp b/lib/ocpp/v201/enums.cpp index 169796f63..0f34ac5c2 100644 --- a/lib/ocpp/v201/enums.cpp +++ b/lib/ocpp/v201/enums.cpp @@ -3365,6 +3365,8 @@ std::string connector_status_enum_to_string(ConnectorStatusEnum e) { return "Reserved"; case ConnectorStatusEnum::Unavailable: return "Unavailable"; + case ConnectorStatusEnum::UnavailableOccupied: + return "Occupied"; case ConnectorStatusEnum::Faulted: return "Faulted"; } @@ -3377,6 +3379,7 @@ ConnectorStatusEnum string_to_connector_status_enum(const std::string& s) { return ConnectorStatusEnum::Available; } if (s == "Occupied") { + // Either Occupied or UnavailableOccupied return ConnectorStatusEnum::Occupied; } if (s == "Reserved") { @@ -3469,6 +3472,8 @@ std::string trigger_reason_enum_to_string(TriggerReasonEnum e) { return "EVDeparted"; case TriggerReasonEnum::EVDetected: return "EVDetected"; + case TriggerReasonEnum::EnergyTransfer: + return "EnergyTransfer"; case TriggerReasonEnum::RemoteStop: return "RemoteStop"; case TriggerReasonEnum::RemoteStart: @@ -3533,6 +3538,9 @@ TriggerReasonEnum string_to_trigger_reason_enum(const std::string& s) { if (s == "EVDetected") { return TriggerReasonEnum::EVDetected; } + if (s == "EnergyTransfer") { + return TriggerReasonEnum::EnergyTransfer; + } if (s == "RemoteStop") { return TriggerReasonEnum::RemoteStop; } diff --git a/lib/ocpp/v201/evse.cpp b/lib/ocpp/v201/evse.cpp index bf46173b6..e77601040 100644 --- a/lib/ocpp/v201/evse.cpp +++ b/lib/ocpp/v201/evse.cpp @@ -198,6 +198,13 @@ ConnectorStatusEnum Evse::get_state(const int32_t connector_id) { return this->id_connector_map.at(connector_id)->get_state(); } +void Evse::set_state(ConnectorStatusEnum status, const int32_t connector_id) { + if (const auto iter = id_connector_map.find(connector_id) == id_connector_map.end()) { + EVLOG_AND_THROW(std::runtime_error("Unable to get_state for Connector")); + } + this->id_connector_map.at(connector_id)->set_initial_state(status); +} + void Evse::submit_event(const int32_t connector_id, ConnectorEvent event) { return this->id_connector_map.at(connector_id)->submit_event(event); }