diff --git a/dependencies.yaml b/dependencies.yaml index ea9bac613..3dea366cc 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -66,7 +66,7 @@ libevse-security: # OCPP libocpp: git: https://github.com/EVerest/libocpp.git - git_tag: v0.17.2 + git_tag: 5c7f10cdfd9aa70db80ccf43ace250e3322be00c cmake_condition: "EVEREST_DEPENDENCY_ENABLED_LIBOCPP" # Josev Josev: diff --git a/lib/staging/ocpp/ocpp_conversions.cpp b/lib/staging/ocpp/ocpp_conversions.cpp index c804f7e58..04af75fb6 100644 --- a/lib/staging/ocpp/ocpp_conversions.cpp +++ b/lib/staging/ocpp/ocpp_conversions.cpp @@ -1,5 +1,7 @@ #include "ocpp_conversions.hpp" +#include + #include "generated/types/display_message.hpp" namespace ocpp_conversions { @@ -185,8 +187,16 @@ ocpp::DisplayMessage to_ocpp_display_message(const types::display_message::Displ m.state = to_ocpp_201_display_message_state(display_message.state.value()); } - m.timestamp_from = display_message.timestamp_from; - m.timestamp_to = display_message.timestamp_to; + try { + if (display_message.timestamp_from.has_value()) { + m.timestamp_from = ocpp::DateTime(display_message.timestamp_from.value()); + } + if (display_message.timestamp_to.has_value()) { + m.timestamp_to = ocpp::DateTime(display_message.timestamp_to.value()); + } + } catch (const ocpp::TimePointParseException& e) { + EVLOG_warning << "Could not parse timestamp when converting DisplayMessage: " << e.what(); + } return m; } @@ -347,4 +357,14 @@ types::session_cost::SessionCost create_session_cost(const ocpp::RunningCost& ru return cost; } + +ocpp::DateTime to_ocpp_datetime_or_now(const std::string& datetime_string) { + std::optional timestamp; + try { + return ocpp::DateTime(datetime_string); + } catch (const ocpp::TimePointParseException& e) { + EVLOG_warning << "Could not parse datetime string: " << e.what() << ". Using current DateTime instead"; + } + return ocpp::DateTime(); +} } // namespace ocpp_conversions diff --git a/lib/staging/ocpp/ocpp_conversions.hpp b/lib/staging/ocpp/ocpp_conversions.hpp index 19449ae86..59d457cb3 100644 --- a/lib/staging/ocpp/ocpp_conversions.hpp +++ b/lib/staging/ocpp/ocpp_conversions.hpp @@ -44,4 +44,9 @@ create_charging_price_component(const double& price, const uint32_t& number_of_d types::session_cost::SessionCost create_session_cost(const ocpp::RunningCost& running_cost, const uint32_t number_of_decimals, std::optional currency_code); + +/// \brief Convert given \p datetime_string in RFC3339 format to a OCPP DateTime. If this is not possible return the +/// current datetime +ocpp::DateTime to_ocpp_datetime_or_now(const std::string& datetime_string); + }; // namespace ocpp_conversions diff --git a/modules/OCPP/OCPP.cpp b/modules/OCPP/OCPP.cpp index 5e8a62a45..9d032b07d 100644 --- a/modules/OCPP/OCPP.cpp +++ b/modules/OCPP/OCPP.cpp @@ -141,7 +141,7 @@ void OCPP::process_session_event(int32_t evse_id, const types::evse_manager::Ses << "Received TransactionStarted"; const auto transaction_started = session_event.transaction_started.value(); - const auto timestamp = ocpp::DateTime(session_event.timestamp); + const auto timestamp = ocpp_conversions::to_ocpp_datetime_or_now(session_event.timestamp); const auto energy_Wh_import = transaction_started.meter_value.energy_Wh_import.total; const auto session_id = session_event.uuid; const auto id_token = transaction_started.id_tag.id_token.value; @@ -177,7 +177,7 @@ void OCPP::process_session_event(int32_t evse_id, const types::evse_manager::Ses << "Received TransactionFinished"; const auto transaction_finished = session_event.transaction_finished.value(); - const auto timestamp = ocpp::DateTime(session_event.timestamp); + const auto timestamp = ocpp_conversions::to_ocpp_datetime_or_now(session_event.timestamp); const auto energy_Wh_import = transaction_finished.meter_value.energy_Wh_import.total; const auto signed_meter_value = transaction_finished.signed_meter_value; diff --git a/modules/OCPP/conversions.cpp b/modules/OCPP/conversions.cpp index 0db1927a2..afbe96af3 100644 --- a/modules/OCPP/conversions.cpp +++ b/modules/OCPP/conversions.cpp @@ -204,7 +204,7 @@ ocpp::v16::BootReasonEnum to_ocpp_boot_reason_enum(const types::system::BootReas ocpp::Powermeter to_ocpp_power_meter(const types::powermeter::Powermeter& powermeter) { ocpp::Powermeter ocpp_powermeter; - ocpp_powermeter.timestamp = powermeter.timestamp; + ocpp_powermeter.timestamp = ocpp_conversions::to_ocpp_datetime_or_now(powermeter.timestamp); ocpp_powermeter.energy_Wh_import = {powermeter.energy_Wh_import.total, powermeter.energy_Wh_import.L1, powermeter.energy_Wh_import.L2, powermeter.energy_Wh_import.L3}; diff --git a/modules/OCPP/ocpp_generic/ocppImpl.cpp b/modules/OCPP/ocpp_generic/ocppImpl.cpp index 55a5dbf80..b457c3a80 100644 --- a/modules/OCPP/ocpp_generic/ocppImpl.cpp +++ b/modules/OCPP/ocpp_generic/ocppImpl.cpp @@ -4,6 +4,8 @@ #include "ocppImpl.hpp" #include "ocpp/v16/messages/ChangeAvailability.hpp" +#include + namespace module { namespace ocpp_generic { @@ -124,11 +126,7 @@ bool ocppImpl::handle_restart() { void ocppImpl::handle_security_event(types::ocpp::SecurityEvent& event) { std::optional timestamp; if (event.timestamp.has_value()) { - try { - timestamp = ocpp::DateTime(event.timestamp.value()); - } catch (...) { - EVLOG_warning << "Timestamp in security event could not be parsed, using current datetime."; - } + timestamp = ocpp_conversions::to_ocpp_datetime_or_now(event.timestamp.value()); } this->mod->charge_point->on_security_event(event.type, event.info, event.critical, timestamp); } diff --git a/modules/OCPP201/OCPP201.cpp b/modules/OCPP201/OCPP201.cpp index 7cb0ea3e9..83f2324b2 100644 --- a/modules/OCPP201/OCPP201.cpp +++ b/modules/OCPP201/OCPP201.cpp @@ -904,7 +904,7 @@ void OCPP201::process_tx_event_effect(const int32_t evse_id, const TxEventEffect if (transaction_data == nullptr) { throw std::runtime_error("Could not start transaction because no tranasaction data is present"); } - transaction_data->timestamp = ocpp::DateTime(session_event.timestamp); + transaction_data->timestamp = ocpp_conversions::to_ocpp_datetime_or_now(session_event.timestamp); if (tx_event_effect == TxEventEffect::START_TRANSACTION) { transaction_data->started = true; @@ -959,7 +959,7 @@ void OCPP201::process_session_started(const int32_t evse_id, const int32_t conne trigger_reason = ocpp::v201::TriggerReasonEnum::RemoteStart; } } - const auto timestamp = ocpp::DateTime(session_event.timestamp); + const auto timestamp = ocpp_conversions::to_ocpp_datetime_or_now(session_event.timestamp); const auto reservation_id = session_started.reservation_id; // this is always the first transaction related interaction, so we create TransactionData here diff --git a/modules/OCPP201/conversions.cpp b/modules/OCPP201/conversions.cpp index 591511d6e..e752c0059 100644 --- a/modules/OCPP201/conversions.cpp +++ b/modules/OCPP201/conversions.cpp @@ -3,6 +3,7 @@ #include #include +#include namespace module { namespace conversions { @@ -137,7 +138,7 @@ to_ocpp_meter_value(const types::powermeter::Powermeter& power_meter, const ocpp::v201::ReadingContextEnum& reading_context, const std::optional signed_meter_value) { ocpp::v201::MeterValue meter_value; - meter_value.timestamp = ocpp::DateTime(power_meter.timestamp); + meter_value.timestamp = ocpp_conversions::to_ocpp_datetime_or_now(power_meter.timestamp); // signed_meter_value is intended for OCMF style blobs of signed meter value reports during transaction start or end // This is interpreted as Energy.Active.Import.Register diff --git a/modules/OCPP201/error_handling.hpp b/modules/OCPP201/error_handling.hpp index b5f2708a1..91226ac71 100644 --- a/modules/OCPP201/error_handling.hpp +++ b/modules/OCPP201/error_handling.hpp @@ -4,6 +4,7 @@ #define OCPP201_ERROR_HANDLING_HPP #include +#include #include #include diff --git a/modules/OCPP201/ocpp_generic/ocppImpl.cpp b/modules/OCPP201/ocpp_generic/ocppImpl.cpp index f3af1d42a..4967c2400 100644 --- a/modules/OCPP201/ocpp_generic/ocppImpl.cpp +++ b/modules/OCPP201/ocpp_generic/ocppImpl.cpp @@ -3,6 +3,7 @@ #include "ocppImpl.hpp" #include +#include namespace module { namespace ocpp_generic { @@ -26,11 +27,7 @@ bool ocppImpl::handle_restart() { void ocppImpl::handle_security_event(types::ocpp::SecurityEvent& event) { std::optional timestamp; if (event.timestamp.has_value()) { - try { - timestamp = ocpp::DateTime(event.timestamp.value()); - } catch (...) { - EVLOG_warning << "Timestamp in security event could not be parsed, using current datetime."; - } + timestamp = ocpp_conversions::to_ocpp_datetime_or_now(event.timestamp.value()); } this->mod->charge_point->on_security_event(event.type, event.info, event.critical, timestamp); }