diff --git a/include/ocpp/common/incremental_counter.hpp b/include/ocpp/common/incremental_counter.hpp new file mode 100644 index 000000000..0da1e6890 --- /dev/null +++ b/include/ocpp/common/incremental_counter.hpp @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Pionix GmbH and Contributors to EVerest + +#pragma once + +#include + +namespace ocpp { +class IncrementalCounter { +public: + static int get(); + +private: + static std::atomic counter; +}; + +} // namespace ocpp diff --git a/include/ocpp/v201/charge_point.hpp b/include/ocpp/v201/charge_point.hpp index 1b7a76cdf..426af475d 100644 --- a/include/ocpp/v201/charge_point.hpp +++ b/include/ocpp/v201/charge_point.hpp @@ -488,6 +488,8 @@ class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBa void message_callback(const std::string& message); void update_aligned_data_interval(); + void notify_event_req_connector_status_update(const int32_t evse_id, const int32_t connector_id, + const ConnectorStatusEnum status); /// \brief Helper function to determine if there is any active transaction for the given \p evse /// \param evse if optional is not set, this function will check if there is any transaction active f or the whole diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index bfb7b74b8..2faa54f73 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -20,6 +20,7 @@ target_sources(ocpp PRIVATE ocpp/common/call_types.cpp ocpp/common/charging_station_base.cpp + ocpp/common/incremental_counter.cpp ocpp/common/ocpp_logging.cpp ocpp/common/schemas.cpp ocpp/common/types.cpp diff --git a/lib/ocpp/common/incremental_counter.cpp b/lib/ocpp/common/incremental_counter.cpp new file mode 100644 index 000000000..668c47d76 --- /dev/null +++ b/lib/ocpp/common/incremental_counter.cpp @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Pionix GmbH and Contributors to EVerest + +#include + +namespace ocpp { + +std::atomic IncrementalCounter::counter{0}; + +int IncrementalCounter::get() { + return ++counter; +} + +} // namespace ocpp \ No newline at end of file diff --git a/lib/ocpp/v201/charge_point.cpp b/lib/ocpp/v201/charge_point.cpp index 3a79a8506..7913b8b9e 100644 --- a/lib/ocpp/v201/charge_point.cpp +++ b/lib/ocpp/v201/charge_point.cpp @@ -2,6 +2,7 @@ // Copyright Pionix GmbH and Contributors to EVerest #include +#include #include #include #include @@ -806,6 +807,21 @@ void ChargePoint::on_reservation_status(const int32_t reservation_id, const Rese } } +void ChargePoint::notify_event_req_connector_status_update(const int32_t evse_id, const int32_t connector_id, + const ConnectorStatusEnum status) { + ocpp::v201::EventData event_data; + const auto cv = ConnectorComponentVariables::get_component_variable(evse_id, connector_id, + ConnectorComponentVariables::AvailabilityState); + event_data.eventId = ocpp::IncrementalCounter::get(); + event_data.actualValue = conversions::connector_status_enum_to_string(status); + event_data.trigger = EventTriggerEnum::Delta; + event_data.variable = cv.variable.value(); + event_data.component = cv.component; + event_data.timestamp = ocpp::DateTime(); + event_data.eventNotificationType = EventNotificationEnum::HardWiredNotification; + this->notify_event_req({event_data}); +} + void ChargePoint::initialize(const std::map& evse_connector_structure, const std::string& message_log_path) { this->device_model->check_integrity(evse_connector_structure); @@ -818,7 +834,13 @@ void ChargePoint::initialize(const std::map& evse_connector_st this->registration_status != RegistrationStatusEnum::Accepted) { return false; } else { - this->status_notification_req(evse_id, connector_id, status, initiated_by_trigger_message); + if (this->ocpp_version == OcppProtocolVersion::v201) { + // OCPP2.0.1: B01.FR.05 + this->status_notification_req(evse_id, connector_id, status, initiated_by_trigger_message); + } else { + // OCPP2.1: B01.FR.05 + this->notify_event_req_connector_status_update(evse_id, connector_id, status); + } return true; } });