Add extracted tools: CitrineOS, OpenOCPP, ShapeShifter
- CitrineOS core extracted (CSMS OCPP 2.0.1) - OpenOCPP extracted (firmware OCPP 1.6J/2.0.1) - ShapeShifter library installed (pip install -e) - ShapeShifter specification extracted - EVerest extracted TODO updated with progress
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
#include <everest/timer.hpp>
|
||||
#include <ocpp/common/types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
class ClockAlignedTimer : private Everest::Timer<std::chrono::system_clock> {
|
||||
public:
|
||||
using system_time_point = std::chrono::time_point<std::chrono::system_clock>;
|
||||
|
||||
private:
|
||||
system_time_point start_point;
|
||||
std::chrono::seconds call_interval = std::chrono::seconds(0);
|
||||
|
||||
std::function<void()> callback;
|
||||
|
||||
system_time_point get_next_timepoint() {
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
auto now = std::chrono::system_clock::now();
|
||||
auto diff = now - this->start_point;
|
||||
auto time_to_next = 0s;
|
||||
// Only calculate next time if it is positive. Otherwise we would end up before the start point
|
||||
if (diff > 0s) {
|
||||
time_to_next = ((std::chrono::duration_cast<std::chrono::seconds>(diff) / this->call_interval) + 1) *
|
||||
this->call_interval;
|
||||
}
|
||||
auto next_time = this->start_point + time_to_next;
|
||||
EVLOG_debug << "Clock aligned interval every " << this->call_interval.count() << " seconds, starting at "
|
||||
<< ocpp::DateTime(date::utc_clock::from_sys(this->start_point))
|
||||
<< ". Next one at: " << ocpp::DateTime(date::utc_clock::from_sys(next_time));
|
||||
EVLOG_debug << "This amounts to "
|
||||
<< std::chrono::duration_cast<std::chrono::seconds>(std::chrono::hours(24)) / this->call_interval
|
||||
<< " samples per day";
|
||||
return next_time;
|
||||
}
|
||||
|
||||
system_time_point call_next() {
|
||||
if (this->callback == nullptr or this->call_interval.count() == 0) {
|
||||
return system_time_point{};
|
||||
}
|
||||
|
||||
auto wrapper = [this]() {
|
||||
this->callback();
|
||||
this->at(this->get_next_timepoint());
|
||||
};
|
||||
|
||||
auto next_timepoint = this->get_next_timepoint();
|
||||
this->at(wrapper, next_timepoint);
|
||||
return next_timepoint;
|
||||
}
|
||||
|
||||
public:
|
||||
ClockAlignedTimer() = default;
|
||||
|
||||
explicit ClockAlignedTimer(boost::asio::io_context* io_context) : Timer(io_context) {
|
||||
}
|
||||
|
||||
explicit ClockAlignedTimer(boost::asio::io_context* io_context, const std::function<void()>& callback) :
|
||||
Timer(io_context), callback(callback) {
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
system_time_point interval_starting_from(const std::function<void()>& callback,
|
||||
const std::chrono::duration<Rep, Period> interval,
|
||||
system_time_point start_point) {
|
||||
this->callback = callback;
|
||||
return this->interval_starting_from(interval, start_point);
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
system_time_point interval_starting_from(const std::chrono::duration<Rep, Period> interval,
|
||||
system_time_point start_point) {
|
||||
this->start_point = start_point;
|
||||
this->call_interval = interval;
|
||||
|
||||
return this->call_next();
|
||||
}
|
||||
|
||||
template <class Rep, class Period>
|
||||
system_time_point set_interval(const std::chrono::duration<Rep, Period>& interval) {
|
||||
this->call_interval = interval;
|
||||
return this->call_next();
|
||||
}
|
||||
|
||||
using Everest::Timer<std::chrono::system_clock>::stop;
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,162 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_COMMON_CALL_TYPES_HPP
|
||||
#define OCPP_COMMON_CALL_TYPES_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include <ocpp/common/cistring.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
// The locations inside the message array
|
||||
const auto MESSAGE_TYPE_ID = 0;
|
||||
const auto MESSAGE_ID = 1;
|
||||
const auto CALL_ACTION = 2;
|
||||
const auto CALL_PAYLOAD = 3;
|
||||
const auto CALLRESULT_PAYLOAD = 2;
|
||||
const auto CALLERROR_ERROR_CODE = 2;
|
||||
const auto CALLERROR_ERROR_DESCRIPTION = 3;
|
||||
const auto CALLERROR_ERROR_DETAILS = 4;
|
||||
|
||||
/// \brief Contains a MessageId implementation based on a case insensitive string with a maximum length of 36 printable
|
||||
/// ASCII characters
|
||||
class MessageId : public CiString<36> {
|
||||
using CiString::CiString;
|
||||
};
|
||||
|
||||
/// \brief Comparison operator< between two MessageId \p lhs and \p rhs
|
||||
bool operator<(const MessageId& lhs, const MessageId& rhs);
|
||||
|
||||
/// \brief Conversion from a given MessageId \p k to a given json object \p j
|
||||
void to_json(json& j, const MessageId& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given MessageId \p k
|
||||
void from_json(const json& j, MessageId& k);
|
||||
|
||||
/// \brief Contains the different message type ids
|
||||
enum class MessageTypeId {
|
||||
CALL = 2,
|
||||
CALLRESULT = 3,
|
||||
CALLERROR = 4,
|
||||
UNKNOWN = 5,
|
||||
};
|
||||
|
||||
/// \brief Creates a unique message ID
|
||||
/// \returns the unique message ID
|
||||
MessageId create_message_id();
|
||||
|
||||
/// \brief Contains a OCPP Call message
|
||||
template <class T> struct Call {
|
||||
T msg;
|
||||
MessageId uniqueId;
|
||||
|
||||
/// \brief Creates a new Call message object
|
||||
Call() = default;
|
||||
|
||||
/// \brief Creates a new Call message object with the given OCPP message \p msg
|
||||
explicit Call(T msg) : msg(msg) {
|
||||
this->uniqueId = create_message_id();
|
||||
}
|
||||
|
||||
/// \brief Creates a new Call message object with the given OCPP message \p msg and \p uniqueId
|
||||
Call(T msg, MessageId uniqueId) : msg(msg), uniqueId(uniqueId) {
|
||||
}
|
||||
|
||||
/// \brief Conversion from a given Call message \p c to a given json object \p j
|
||||
friend void to_json(json& j, const Call& c) {
|
||||
j = json::array();
|
||||
j.push_back(MessageTypeId::CALL);
|
||||
j.push_back(c.uniqueId.get());
|
||||
j.push_back(c.msg.get_type());
|
||||
j.push_back(json(c.msg));
|
||||
}
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given Call message \p c
|
||||
friend void from_json(const json& j, Call& c) {
|
||||
// the required parts of the message
|
||||
c.msg = j.at(CALL_PAYLOAD);
|
||||
c.uniqueId.set(j.at(MESSAGE_ID));
|
||||
}
|
||||
|
||||
/// \brief Writes the given case Call \p c to the given output stream \p os
|
||||
/// \returns an output stream with the Call written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const Call& c) {
|
||||
os << json(c).dump(4);
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Contains a OCPP CallResult message
|
||||
template <class T> struct CallResult {
|
||||
T msg;
|
||||
MessageId uniqueId;
|
||||
|
||||
/// \brief Creates a new CallResult message object
|
||||
CallResult() = default;
|
||||
|
||||
/// \brief Creates a new CallResult message object with the given OCPP message \p msg and \p uniqueID
|
||||
CallResult(T msg, MessageId uniqueId) : msg(msg), uniqueId(uniqueId) {
|
||||
}
|
||||
|
||||
/// \brief Conversion from a given CallResult message \p c to a given json object \p j
|
||||
friend void to_json(json& j, const CallResult& c) {
|
||||
j = json::array();
|
||||
j.push_back(MessageTypeId::CALLRESULT);
|
||||
j.push_back(c.uniqueId.get());
|
||||
j.push_back(json(c.msg));
|
||||
}
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given CallResult message \p c
|
||||
friend void from_json(const json& j, CallResult& c) {
|
||||
// the required parts of the message
|
||||
c.msg = j.at(CALLRESULT_PAYLOAD);
|
||||
c.uniqueId.set(j.at(MESSAGE_ID));
|
||||
}
|
||||
|
||||
/// \brief Writes the given case CallResult \p c to the given output stream \p os
|
||||
/// \returns an output stream with the CallResult written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const CallResult& c) {
|
||||
os << json(c).dump(4);
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Contains a OCPP CallError message
|
||||
struct CallError {
|
||||
MessageId uniqueId;
|
||||
std::string errorCode;
|
||||
std::string errorDescription;
|
||||
json errorDetails;
|
||||
|
||||
/// \brief Creates a new CallError message object
|
||||
CallError();
|
||||
|
||||
/// \brief Creates a new CallResult message object with the given \p uniqueID \p errorCode \p errorDescription and
|
||||
/// \p errorDetails
|
||||
CallError(const MessageId& uniqueId, const std::string& errorCode, const std::string& errorDescription,
|
||||
const json& errorDetails);
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given CallError message \p c to a given json object \p j
|
||||
void to_json(json& j, const CallError& c);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given CallError message \p c
|
||||
void from_json(const json& j, CallError& c);
|
||||
|
||||
/// \brief Writes the given case CallError \p c to the given output stream \p os
|
||||
/// \returns an output stream with the CallError written to
|
||||
std::ostream& operator<<(std::ostream& os, const CallError& c);
|
||||
|
||||
} // namespace ocpp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_COMMON_CHARGE_POINT_HPP
|
||||
#define OCPP_COMMON_CHARGE_POINT_HPP
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <ocpp/common/evse_security.hpp>
|
||||
#include <ocpp/common/evse_security_impl.hpp>
|
||||
#include <ocpp/common/message_queue.hpp>
|
||||
#include <ocpp/common/ocpp_logging.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
/// \brief Common base class for OCPP1.6 and OCPP2.0.1 charging stations
|
||||
class ChargingStationBase {
|
||||
|
||||
protected:
|
||||
std::shared_ptr<EvseSecurity> evse_security;
|
||||
std::shared_ptr<MessageLogging> logging;
|
||||
|
||||
boost::shared_ptr<boost::asio::executor_work_guard<boost::asio::io_context::executor_type>> work;
|
||||
boost::asio::io_context io_context;
|
||||
std::thread io_context_thread;
|
||||
|
||||
public:
|
||||
/// \brief Constructor for ChargingStationBase
|
||||
/// \param evse_security Pointer to evse_security that manages security related operations; if nullptr
|
||||
/// security_configuration must be set
|
||||
/// \param security_configuration specifies the file paths that are required to set up the internal evse_security
|
||||
/// implementation
|
||||
explicit ChargingStationBase(const std::shared_ptr<EvseSecurity>& evse_security,
|
||||
const std::optional<SecurityConfiguration>& security_configuration = std::nullopt);
|
||||
virtual ~ChargingStationBase();
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_COMMON
|
||||
@@ -0,0 +1,96 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_COMMON_CISTRING_HPP
|
||||
#define OCPP_COMMON_CISTRING_HPP
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <ocpp/common/string.hpp>
|
||||
#include <ocpp/common/utils.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
/// \brief Contains a CaseInsensitive string implementation that only allows printable ASCII characters
|
||||
template <size_t L> class CiString : public String<L> {
|
||||
|
||||
public:
|
||||
/// \brief Creates a string from the given \p data
|
||||
CiString(const std::string& data, StringTooLarge to_large = StringTooLarge::Throw) : String<L>(data, to_large) {
|
||||
}
|
||||
|
||||
CiString(const char* data, StringTooLarge to_large = StringTooLarge::Throw) : String<L>(data, to_large) {
|
||||
}
|
||||
|
||||
CiString(const CiString<L>& data) : String<L>(data.get()) {
|
||||
}
|
||||
|
||||
/// \brief Creates a string
|
||||
CiString() : String<L>() {
|
||||
}
|
||||
|
||||
CiString(CiString&&) = default;
|
||||
CiString& operator=(const CiString&) = default;
|
||||
CiString& operator=(CiString&&) = default;
|
||||
|
||||
/// \brief CaseInsensitive string implementation only allows printable ASCII characters
|
||||
bool is_valid(std::string_view data) {
|
||||
for (const char& character : data) {
|
||||
// printable ASCII starts at code 0x20 (space) and ends with code 0x7e (tilde) and 0xa (\n)
|
||||
if ((character < 0x20 || character > 0x7e) && character != 0xa) {
|
||||
throw std::runtime_error("CiString can only contain printable ASCII characters");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \brief Conversion operator to turn a String into std::string
|
||||
operator std::string() const {
|
||||
return this->get();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
template <size_t L> bool operator==(const CiString<L>& lhs, const char* rhs) {
|
||||
return iequals(lhs.get(), rhs);
|
||||
}
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
template <size_t L> bool operator==(const CiString<L>& lhs, const CiString<L>& rhs) {
|
||||
return iequals(lhs.get(), rhs.get());
|
||||
}
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
template <size_t L> bool operator!=(const CiString<L>& lhs, const char* rhs) {
|
||||
return !(lhs.get() == rhs);
|
||||
}
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
template <size_t L> bool operator!=(const CiString<L>& lhs, const CiString<L>& rhs) {
|
||||
return !(lhs.get() == rhs.get());
|
||||
}
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
template <size_t L> bool operator<(const CiString<L>& lhs, const CiString<L>& rhs) {
|
||||
return lhs.get() < rhs.get();
|
||||
}
|
||||
|
||||
/// \brief Writes the given string \p str to the given output stream \p os
|
||||
/// \returns an output stream with the case insensitive string written to
|
||||
template <size_t L> std::ostream& operator<<(std::ostream& os, const CiString<L>& str) {
|
||||
os << str.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
template <size_t L> void to_json(json& j, const CiString<L>& k) {
|
||||
j = json(k.get());
|
||||
}
|
||||
|
||||
template <size_t L> void from_json(const json& j, CiString<L>& k) {
|
||||
k.set(j);
|
||||
}
|
||||
|
||||
} // namespace ocpp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,318 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ocpp/common/websocket/websocket.hpp>
|
||||
#include <ocpp/v2/messages/SetNetworkProfile.hpp>
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
|
||||
#include <everest/util/async/monitor.hpp>
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <future>
|
||||
#include <optional>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
class DeviceModelAbstract;
|
||||
} // namespace v2
|
||||
|
||||
/// \brief The result of a configuration of a network profile.
|
||||
struct ConfigNetworkResult {
|
||||
std::optional<std::string> interface_address; ///< ip address or interface string
|
||||
bool success; ///< true if the configuration was successful
|
||||
};
|
||||
|
||||
using WebsocketConnectionCallback =
|
||||
std::function<void(int configuration_slot, const ocpp::v2::NetworkConnectionProfile& network_connection_profile,
|
||||
const OcppProtocolVersion version)>;
|
||||
using WebsocketConnectionFailedCallback = std::function<void(ConnectionFailedReason reason)>;
|
||||
using ConfigureNetworkConnectionProfileCallback = std::function<std::future<ConfigNetworkResult>(
|
||||
const std::int32_t configuration_slot, const ocpp::v2::NetworkConnectionProfile& network_connection_profile)>;
|
||||
|
||||
class ConnectivityManagerInterface {
|
||||
public:
|
||||
virtual ~ConnectivityManagerInterface() = default;
|
||||
|
||||
/// \brief Set the \p callback that is called when a message is received from the websocket
|
||||
///
|
||||
virtual void set_message_callback(const std::function<void(const std::string& message)>& callback) = 0;
|
||||
|
||||
/// \brief Set the logger \p logging
|
||||
///
|
||||
virtual void set_logging(std::shared_ptr<MessageLogging> logging) = 0;
|
||||
|
||||
/// \brief Set the websocket \p authorization_key
|
||||
///
|
||||
virtual void set_websocket_authorization_key(const std::string& authorization_key) = 0;
|
||||
|
||||
/// \brief Set the websocket \p connection_options
|
||||
///
|
||||
virtual void set_websocket_connection_options(const WebsocketConnectionOptions& connection_options) = 0;
|
||||
|
||||
/// \brief Set the websocket connection options without triggering a reconnect
|
||||
///
|
||||
virtual void set_websocket_connection_options_without_reconnect() = 0;
|
||||
|
||||
/// \brief Set the \p callback that is called when the websocket is connected.
|
||||
///
|
||||
virtual void set_websocket_connected_callback(WebsocketConnectionCallback callback) = 0;
|
||||
|
||||
/// \brief Set the \p callback that is called when the websocket is disconnected.
|
||||
///
|
||||
virtual void set_websocket_disconnected_callback(WebsocketConnectionCallback callback) = 0;
|
||||
|
||||
/// \brief Set the \p callback that is called when the websocket could not connect with a specific reason
|
||||
///
|
||||
virtual void set_websocket_connection_failed_callback(WebsocketConnectionFailedCallback callback) = 0;
|
||||
|
||||
/// \brief Set the \p callback that is called to configure a network connection profile when none is configured
|
||||
///
|
||||
virtual void
|
||||
set_configure_network_connection_profile_callback(ConfigureNetworkConnectionProfileCallback callback) = 0;
|
||||
|
||||
/// \brief Gets the cached NetworkConnectionProfile based on the given \p configuration_slot.
|
||||
/// This returns the value from the cached network connection profiles.
|
||||
/// \return Returns a profile if the slot is found
|
||||
virtual std::optional<ocpp::v2::NetworkConnectionProfile>
|
||||
get_network_connection_profile(const std::int32_t configuration_slot) const = 0;
|
||||
|
||||
/// \brief Get the priority of the given configuration slot.
|
||||
/// \param configuration_slot The configuration slot to get the priority from.
|
||||
/// \return The priority if the configuration slot exists.
|
||||
///
|
||||
virtual std::optional<std::int32_t>
|
||||
get_priority_from_configuration_slot(const std::int32_t configuration_slot) const = 0;
|
||||
|
||||
/// @brief Get a snapshot of the network connection slots sorted by priority.
|
||||
/// Each item in the vector contains the configured configuration slots, where the slot with index 0 has the highest
|
||||
/// priority. A copy is returned so callers do not observe mid-mutation state through a reference.
|
||||
/// @return The network connection slots
|
||||
///
|
||||
virtual std::vector<int> get_network_connection_slots() const = 0;
|
||||
|
||||
/// \brief Check if the websocket is connected
|
||||
/// \return True is the websocket is connected, else false
|
||||
///
|
||||
virtual bool is_websocket_connected() = 0;
|
||||
|
||||
/// @brief Get the time the websocket has been disconnected.
|
||||
/// @return The time the websocket has been disconnected
|
||||
///
|
||||
virtual std::chrono::time_point<std::chrono::steady_clock> get_time_disconnected() const = 0;
|
||||
|
||||
/// \brief Connect to the websocket
|
||||
/// \param configuration_slot Optional the network_profile_slot to connect to. std::nullopt will select the slot
|
||||
/// internally.
|
||||
///
|
||||
virtual void connect(std::optional<std::int32_t> network_profile_slot = std::nullopt) = 0;
|
||||
|
||||
/// \brief Disconnect the websocket
|
||||
///
|
||||
virtual void disconnect() = 0;
|
||||
|
||||
/// \brief send a \p message over the websocket
|
||||
/// \returns true if the message was sent successfully
|
||||
///
|
||||
virtual bool send_to_websocket(const std::string& message) = 0;
|
||||
|
||||
///
|
||||
/// \brief Can be called when a network is disconnected, for example when an ethernet cable is removed.
|
||||
///
|
||||
/// This is introduced because the websocket can take several minutes to timeout when a network interface becomes
|
||||
/// unavailable, whereas the system can detect this sooner.
|
||||
///
|
||||
/// \param ocpp_interface The interface that is disconnected.
|
||||
///
|
||||
virtual void on_network_disconnected(ocpp::v2::OCPPInterfaceEnum ocpp_interface) = 0;
|
||||
|
||||
/// \brief Called when the charging station certificate is changed
|
||||
///
|
||||
virtual void on_charging_station_certificate_changed() = 0;
|
||||
|
||||
/// \brief Confirms the connection is successful so the security profile requirements can be handled
|
||||
virtual void confirm_successful_connection() = 0;
|
||||
|
||||
/// \brief Reload network connection profiles from NetworkConfiguration DM components into the in-memory cache
|
||||
virtual void reload_network_profiles() = 0;
|
||||
|
||||
/// \brief Write a network connection profile to the device model and refresh the in-memory cache.
|
||||
/// \param slot The configuration slot to write to
|
||||
/// \param profile The profile to write
|
||||
/// \param source The source of the change (e.g. 'csms', 'internal')
|
||||
/// \return true if the profile was written successfully
|
||||
virtual bool set_network_profile(int32_t slot, const ocpp::v2::NetworkConnectionProfile& profile,
|
||||
const std::string& source) = 0;
|
||||
};
|
||||
|
||||
class ConnectivityManager : public ConnectivityManagerInterface {
|
||||
private:
|
||||
/// \brief Reference to the device model
|
||||
ocpp::v2::DeviceModelAbstract& device_model;
|
||||
/// \brief Pointer to the evse security class
|
||||
std::shared_ptr<EvseSecurity> evse_security;
|
||||
/// \brief Pointer to the logger
|
||||
std::shared_ptr<MessageLogging> logging;
|
||||
/// \brief The share path
|
||||
fs::path share_path;
|
||||
/// \brief Pointer to the websocket
|
||||
std::unique_ptr<Websocket> websocket;
|
||||
/// \brief The message callback
|
||||
std::function<void(const std::string& message)> message_callback;
|
||||
/// \brief Callback that is called when the websocket is connected successfully
|
||||
std::optional<WebsocketConnectionCallback> websocket_connected_callback;
|
||||
/// \brief Callback that is called when the websocket connection is disconnected
|
||||
std::optional<WebsocketConnectionCallback> websocket_disconnected_callback;
|
||||
/// \brief Callback that is called when the websocket could not connect with a specific reason
|
||||
std::optional<WebsocketConnectionFailedCallback> websocket_connection_failed_callback;
|
||||
/// \brief Callback that is called to configure a network connection profile when none is configured
|
||||
std::optional<ConfigureNetworkConnectionProfileCallback> configure_network_connection_profile_callback;
|
||||
|
||||
Everest::SteadyTimer websocket_timer;
|
||||
bool wants_to_be_connected;
|
||||
OcppProtocolVersion connected_ocpp_version;
|
||||
|
||||
/// @brief Mutable shared state, accessed concurrently from the OCPP message-handling thread,
|
||||
/// the websocket callback thread, and the websocket_timer thread. All access goes through the
|
||||
/// monitor handle, which acquires a recursive mutex for the handle's lifetime.
|
||||
struct NetworkProfileCacheState {
|
||||
/// Cached NetworkConnectionProfile entries reflecting the per-slot NetworkConfiguration DM variables.
|
||||
std::vector<ocpp::v2::SetNetworkProfileRequest> cached_profiles;
|
||||
/// Ordered list of configuration slots (highest priority first) derived from NetworkConfigurationPriority.
|
||||
std::vector<std::int32_t> slots;
|
||||
/// Index into \c slots of the slot currently considered active.
|
||||
std::int32_t active_priority{0};
|
||||
/// Slot currently being evaluated by \c try_connect_websocket (overrides active_priority if set).
|
||||
std::optional<std::int32_t> pending_configuration_slot;
|
||||
/// Last SecurityProfile value observed when pruning invalid profiles from the cache.
|
||||
int last_known_security_level{0};
|
||||
};
|
||||
mutable everest::lib::util::monitor<NetworkProfileCacheState, std::recursive_mutex> m_state;
|
||||
|
||||
public:
|
||||
ConnectivityManager(ocpp::v2::DeviceModelAbstract& device_model, std::shared_ptr<EvseSecurity> evse_security,
|
||||
const fs::path& share_path = {});
|
||||
|
||||
void reload_network_profiles() override;
|
||||
bool set_network_profile(int32_t slot, const ocpp::v2::NetworkConnectionProfile& profile,
|
||||
const std::string& source) override;
|
||||
|
||||
void set_message_callback(const std::function<void(const std::string& message)>& callback) override;
|
||||
void set_logging(std::shared_ptr<MessageLogging> logging) override;
|
||||
void set_websocket_authorization_key(const std::string& authorization_key) override;
|
||||
void set_websocket_connection_options(const WebsocketConnectionOptions& connection_options) override;
|
||||
void set_websocket_connection_options_without_reconnect() override;
|
||||
void set_websocket_connected_callback(WebsocketConnectionCallback callback) override;
|
||||
void set_websocket_disconnected_callback(WebsocketConnectionCallback callback) override;
|
||||
void set_websocket_connection_failed_callback(WebsocketConnectionFailedCallback callback) override;
|
||||
void set_configure_network_connection_profile_callback(ConfigureNetworkConnectionProfileCallback callback) override;
|
||||
std::optional<ocpp::v2::NetworkConnectionProfile>
|
||||
get_network_connection_profile(const std::int32_t configuration_slot) const override;
|
||||
std::optional<std::int32_t>
|
||||
get_priority_from_configuration_slot(const std::int32_t configuration_slot) const override;
|
||||
std::vector<int> get_network_connection_slots() const override;
|
||||
bool is_websocket_connected() override;
|
||||
std::chrono::time_point<std::chrono::steady_clock> get_time_disconnected() const override;
|
||||
void connect(std::optional<std::int32_t> network_profile_slot = std::nullopt) override;
|
||||
void disconnect() override;
|
||||
bool send_to_websocket(const std::string& message) override;
|
||||
void on_network_disconnected(ocpp::v2::OCPPInterfaceEnum ocpp_interface) override;
|
||||
void on_charging_station_certificate_changed() override;
|
||||
void confirm_successful_connection() override;
|
||||
|
||||
/// \brief Removes all connection profiles from the cache that have a security profile lower than the currently
|
||||
/// connected security profile
|
||||
void check_cache_for_invalid_security_profiles();
|
||||
|
||||
private:
|
||||
std::atomic<std::chrono::time_point<std::chrono::steady_clock>> time_disconnected{};
|
||||
|
||||
/// \brief Mark \c time_disconnected with steady_clock::now() iff currently unset (zero).
|
||||
/// Atomic compare-exchange so concurrent disconnect callbacks cannot overwrite the
|
||||
/// first observed disconnect time.
|
||||
void mark_disconnected_at_now();
|
||||
|
||||
/// \brief Initializes the websocket and tries to connect
|
||||
///
|
||||
void try_connect_websocket();
|
||||
|
||||
/// \brief Get the current websocket connection options
|
||||
/// \return the current websocket connection options
|
||||
///
|
||||
std::optional<WebsocketConnectionOptions> get_ws_connection_options(const std::int32_t configuration_slot);
|
||||
|
||||
/// \brief Resolve the Identity to use for the given slot. Per-slot Identity overrides
|
||||
/// SecurityCtrlr.Identity (B09.FR.16-18) when present and non-empty.
|
||||
std::string resolve_identity(std::int32_t configuration_slot) const;
|
||||
|
||||
/// \brief Resolve the BasicAuthPassword to use for the given slot. Per-slot BasicAuthPassword
|
||||
/// overrides the global SecurityCtrlr.BasicAuthPassword (B09.FR.26-28) when present
|
||||
/// and non-empty.
|
||||
std::optional<std::string> resolve_basic_auth_password(std::int32_t configuration_slot) const;
|
||||
|
||||
/// \brief Read the everest version string from the deployed version_information.txt,
|
||||
/// next to the binary. Returns nullopt if the file is missing or contains no usable line.
|
||||
std::optional<std::string> read_everest_version() const;
|
||||
|
||||
/// \brief Calls the configuration callback to get the interface to use, if there is a callback
|
||||
/// \param slot The configuration slot to get the interface for
|
||||
/// \param profile The network connection profile to get the interface for
|
||||
///
|
||||
/// \return The network configuration containing the network interface to use, nullptr if the request failed or the
|
||||
/// callback is not configured
|
||||
std::optional<ConfigNetworkResult>
|
||||
handle_configure_network_connection_profile_callback(int slot, const ocpp::v2::NetworkConnectionProfile& profile);
|
||||
|
||||
/// \brief Function invoked when the web socket connected with the \p security_profile
|
||||
///
|
||||
void on_websocket_connected(OcppProtocolVersion protocol);
|
||||
|
||||
/// \brief Function invoked when the web socket disconnected
|
||||
///
|
||||
void on_websocket_disconnected();
|
||||
|
||||
/// \brief Function invoked when the web socket stops connecting
|
||||
/// and does not re-attempt to connect again
|
||||
///
|
||||
void on_websocket_stopped_connecting(ocpp::WebsocketCloseReason reason);
|
||||
|
||||
///
|
||||
/// \brief Get the active network configuration slot in use.
|
||||
/// \return The active slot (or pending slot override) if one is available, std::nullopt if the slot
|
||||
/// list is empty or the current priority index would be out of range.
|
||||
///
|
||||
std::optional<int> get_active_network_configuration_slot() const;
|
||||
|
||||
///
|
||||
/// \brief Get the network configuration slot of the given priority.
|
||||
/// \param priority The priority to get the configuration slot.
|
||||
/// \return The configuration slot if \p priority is a valid index, std::nullopt otherwise.
|
||||
///
|
||||
std::optional<int> get_configuration_slot_from_priority(const int priority);
|
||||
|
||||
///
|
||||
/// \brief Get the next prioritized network configuration slot of the given configuration slot.
|
||||
/// \param configuration_slot The current configuration slot.
|
||||
/// \return The next prioritized configuration slot, or std::nullopt if the slot list is empty.
|
||||
///
|
||||
std::optional<int> get_next_configuration_slot(std::int32_t configuration_slot);
|
||||
|
||||
/// \brief Append the given slot to NetworkConfigurationPriority if it is not already listed.
|
||||
void append_slot_to_network_configuration_priority_if_absent(int32_t slot, const std::string& source);
|
||||
|
||||
/// \brief Cache all the network connection profiles
|
||||
void cache_network_connection_profiles();
|
||||
|
||||
/// \brief Log an error if all cached profiles have security_profile 0. Caller must hold the state lock.
|
||||
void warn_if_all_security_level_zero_locked(const NetworkProfileCacheState& state) const;
|
||||
|
||||
/// \brief Removes all NetworkConfiguration DM slots and in-memory cache entries for profiles that have a security
|
||||
/// profile lower than the currently connected security profile, and persists the updated
|
||||
/// NetworkConfigurationPriority
|
||||
void remove_network_connection_profiles_below_actual_security_profile();
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,34 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
// Time
|
||||
constexpr std::int32_t DAYS_PER_WEEK = 7;
|
||||
constexpr std::int32_t HOURS_PER_DAY = 24;
|
||||
constexpr std::int32_t SECONDS_PER_HOUR = 3600;
|
||||
constexpr std::int32_t SECONDS_PER_DAY = 86400;
|
||||
|
||||
constexpr float DEFAULT_LIMIT_AMPS = 48.0;
|
||||
constexpr float DEFAULT_LIMIT_WATTS = 33120.0;
|
||||
constexpr std::int32_t DEFAULT_AND_MAX_NUMBER_PHASES = 3;
|
||||
constexpr float LOW_VOLTAGE = 230;
|
||||
|
||||
constexpr float NO_LIMIT_SPECIFIED = -1.0;
|
||||
constexpr float NO_SETPOINT_SPECIFIED = std::numeric_limits<float>::max();
|
||||
constexpr float NO_DISCHARGE_LIMIT_SPECIFIED = -std::numeric_limits<float>::max();
|
||||
constexpr std::int32_t NO_START_PERIOD = -1;
|
||||
constexpr std::int32_t EVSEID_NOT_SET = -1;
|
||||
|
||||
constexpr std::chrono::seconds DEFAULT_WAIT_FOR_FUTURE_TIMEOUT = std::chrono::seconds(60);
|
||||
|
||||
const std::string VARIABLE_ATTRIBUTE_VALUE_SOURCE_INTERNAL = "internal";
|
||||
const std::string VARIABLE_ATTRIBUTE_VALUE_SOURCE_CSMS = "csms";
|
||||
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,97 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
// This file contains the implementation of a couple of custom iterators, enabling the iteration and abstraction of more
|
||||
// complex containers. For example we want to be able to iterate a std::vector<std::unique_ptr<T>> and get references to
|
||||
// T from the iterator
|
||||
//
|
||||
// ForwardIterator<T> implements a custom iterator for type T that does not depend on any underlying container.
|
||||
// You can add this for your type by returning ForwardIterator<T> from begin() and end()
|
||||
// ForwardIterator can only be constructed by passing a ForwardIteratorBase derived struct in a unique_ptr.
|
||||
// ForwardIteratorBase is an abstract class that allows us to implement container specific functionality.
|
||||
// VectorOfUniquePtrIterator is an implementation of the ForwardIteratorBase specifically catered to the example of
|
||||
// std::vector<std:unique_ptr<T>>
|
||||
// So to implement the begin() and end() functions for your type, you could do the following:
|
||||
// std::vector<std::unique_ptr<T>> container;
|
||||
// ForwardIterator<T> begin() {
|
||||
// return ForwardIterator<T>(std::make_unique<VectorOfUniquePtrIterator<T>>(container.begin()));
|
||||
// }
|
||||
|
||||
/// \brief Abstract struct to implement to enable the use of the ForwardIterator<T>
|
||||
template <typename T> struct ForwardIteratorBase {
|
||||
virtual ~ForwardIteratorBase() = default;
|
||||
|
||||
/// \brief Get a reference to the value pointed to by the iterator
|
||||
virtual T& deref() const = 0;
|
||||
/// \brief Increment the iterator once to the next position
|
||||
virtual void advance() = 0;
|
||||
/// \brief Check for equality between this iterator and \p other
|
||||
virtual bool not_equal(const ForwardIteratorBase& other) = 0;
|
||||
};
|
||||
|
||||
/// \brief Helper struct that allows the use of an iterator in an interface, can be implemented using any forward
|
||||
/// iterator
|
||||
template <typename T> struct ForwardIterator {
|
||||
using iterator_category = std::forward_iterator_tag;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using value_type = T;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
using base = ForwardIteratorBase<T>;
|
||||
|
||||
/// \brief Construct a new wrapper using any type that implements the abstract struct Base
|
||||
explicit ForwardIterator(std::unique_ptr<base> it) : it{std::move(it)} {
|
||||
}
|
||||
|
||||
/// \brief Get a reference to the value pointed to by the iterator
|
||||
reference operator*() const {
|
||||
return it->deref();
|
||||
};
|
||||
|
||||
/// \brief Increment the iterator once to the next position
|
||||
ForwardIterator& operator++() {
|
||||
it->advance();
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Check for inequality between this \p a and \p b
|
||||
friend bool operator!=(const ForwardIterator& a, const ForwardIterator& b) {
|
||||
return a.it->not_equal(*b.it);
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<base> it;
|
||||
};
|
||||
|
||||
/// \brief Implementation for the ForwardIteratorBase based on a vector of unique_ptr with type T
|
||||
template <typename T> struct VectorOfUniquePtrIterator : ForwardIteratorBase<T> {
|
||||
using iterator_type = typename std::vector<std::unique_ptr<T>>::iterator;
|
||||
using base = ForwardIteratorBase<T>;
|
||||
|
||||
explicit VectorOfUniquePtrIterator(iterator_type it) : it{it} {
|
||||
}
|
||||
|
||||
T& deref() const override {
|
||||
return *it->get();
|
||||
}
|
||||
|
||||
void advance() override {
|
||||
++it;
|
||||
}
|
||||
|
||||
bool not_equal(const base& other) override {
|
||||
return it != dynamic_cast<const VectorOfUniquePtrIterator&>(other).it;
|
||||
}
|
||||
|
||||
private:
|
||||
iterator_type it;
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <everest/database/exceptions.hpp>
|
||||
#include <everest/database/sqlite/connection.hpp>
|
||||
#include <ocpp/common/types.hpp>
|
||||
|
||||
namespace ocpp::common {
|
||||
|
||||
struct DBTransactionMessage {
|
||||
json json_message;
|
||||
std::string message_type;
|
||||
std::int32_t message_attempts;
|
||||
DateTime timestamp;
|
||||
std::string unique_id;
|
||||
};
|
||||
|
||||
class DatabaseHandlerCommon {
|
||||
protected:
|
||||
std::unique_ptr<everest::db::sqlite::ConnectionInterface> database;
|
||||
const fs::path sql_migration_files_path;
|
||||
const std::uint32_t target_schema_version;
|
||||
|
||||
/// \brief Perform the initialization needed to use the database. Will be called by open_connection()
|
||||
virtual void init_sql() = 0;
|
||||
|
||||
public:
|
||||
/// \brief Common database handler class
|
||||
/// Class handles some common database functionality like inserting and removing transaction messages.
|
||||
///
|
||||
/// \param database Interface for the database connection
|
||||
/// \param sql_migration_files_path Filesystem path to migration file folder
|
||||
/// \param target_schema_version The required schema version of the database
|
||||
explicit DatabaseHandlerCommon(std::unique_ptr<everest::db::sqlite::ConnectionInterface> database,
|
||||
const fs::path& sql_migration_files_path,
|
||||
std::uint32_t target_schema_version) noexcept;
|
||||
|
||||
virtual ~DatabaseHandlerCommon() = default;
|
||||
|
||||
/// \brief Opens connection to database file and performs the initialization by calling init_sql()
|
||||
void open_connection();
|
||||
|
||||
/// \brief Closes the database connection.
|
||||
void close_connection();
|
||||
|
||||
/// \brief Get messages from messages queue table specified by \p queue_type
|
||||
/// \param queue_type , defaults to QueueType::Transaction
|
||||
/// \return The transaction messages.
|
||||
virtual std::vector<DBTransactionMessage>
|
||||
get_message_queue_messages(const QueueType queue_type = QueueType::Transaction);
|
||||
|
||||
/// \brief Insert a new message into messages queue table specified by \p queue_type
|
||||
/// \param message The message to be stored.
|
||||
/// \param queue_type , defaults to QueueType::Transaction
|
||||
virtual void insert_message_queue_message(const DBTransactionMessage& message,
|
||||
const QueueType queue_type = QueueType::Transaction);
|
||||
|
||||
/// \brief Remove a message from the messages queue table specified by \p queue_type
|
||||
/// \param unique_id The unique id of the transaction message
|
||||
/// \param queue_type , defaults to QueueType::Transaction
|
||||
/// \return True on success.
|
||||
virtual void remove_message_queue_message(const std::string& unique_id,
|
||||
const QueueType queue_type = QueueType::Transaction);
|
||||
|
||||
/// \brief Deletes all entries from message queue table specified by \p queue_type
|
||||
/// \param queue_type , defaults to QueueType::Transaction
|
||||
virtual void clear_message_queue(const QueueType queue_type = QueueType::Transaction);
|
||||
};
|
||||
|
||||
} // namespace ocpp::common
|
||||
@@ -0,0 +1,166 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_COMMON_EVSE_SECURITY
|
||||
#define OCPP_COMMON_EVSE_SECURITY
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
/// \brief Handler for security related operations of the charging station
|
||||
class EvseSecurity {
|
||||
|
||||
public:
|
||||
virtual ~EvseSecurity() = default;
|
||||
|
||||
/// \brief Installs the CA \p certificate for the given \p certificate_type . This function respects the
|
||||
/// requirements of OCPP specified for the CSMS initiated message InstallCertificate.req .
|
||||
/// \param certificate PEM formatted CA certificate
|
||||
/// \param certificate_type specifies the CA certificate type
|
||||
/// \return result of the operation
|
||||
virtual InstallCertificateResult install_ca_certificate(const std::string& certificate,
|
||||
const CaCertificateType& certificate_type) = 0;
|
||||
|
||||
/// \brief Deletes the certificate specified by \p certificate_hash_data . This function respects the
|
||||
/// requirements of OCPP specified for the CSMS initiated message DeleteCertificate.req
|
||||
/// \param certificate_hash_data specifies the certificate to be deleted
|
||||
/// \return result of the operation
|
||||
virtual DeleteCertificateResult delete_certificate(const CertificateHashDataType& certificate_hash_data) = 0;
|
||||
|
||||
/// \brief Verifies the given \p certificate_chain for the given \p certificate_type using the respective CA
|
||||
/// certificates for the leaf and if valid installs the certificate. Before installing the certificate, this
|
||||
/// function checks if a private key is present for the given certificate. This function respects the
|
||||
/// requirements of OCPP specified for the CSMS initiated message CertificateSigned.req .
|
||||
/// \param certificate_chain PEM formatted certificate or certificate chain
|
||||
/// \param certificate_type type of the leaf certificate
|
||||
/// \return result of the operation
|
||||
virtual InstallCertificateResult update_leaf_certificate(const std::string& certificate_chain,
|
||||
const CertificateSigningUseEnum& certificate_type) = 0;
|
||||
|
||||
/// \brief Verifies the given \p certificate_chain for the given \p certificate_type against the respective CA
|
||||
/// certificates for the leaf according to the requirements specified in OCPP.
|
||||
/// \param certificate_chain PEM formatted certificate or certificate chain
|
||||
/// \param certificate_type type of the leaf certificate
|
||||
/// \return result of the operation
|
||||
virtual CertificateValidationResult verify_certificate(const std::string& certificate_chain,
|
||||
const LeafCertificateType& certificate_type) = 0;
|
||||
|
||||
/// \brief Verifies the given \p certificate_chain against the respective CA
|
||||
/// trust anchors (indicated by the given \p certificate_types) for the leaf.
|
||||
/// \param certificate_chain PEM formatted certificate or certificate chain
|
||||
/// \param certificate_types types of the root certificates for which the chain is verified
|
||||
/// \return result of the operation
|
||||
virtual CertificateValidationResult
|
||||
verify_certificate(const std::string& certificate_chain,
|
||||
const std::vector<LeafCertificateType>& certificate_types) = 0;
|
||||
|
||||
/// \brief Retrieves all certificates installed on the filesystem applying the \p certificate_types filter. This
|
||||
/// function respects the requirements of OCPP specified for the CSMS initiated message
|
||||
/// GetInstalledCertificateIds.req .
|
||||
/// \param certificate_types
|
||||
/// \return contains the certificate hash data chains of the requested \p certificate_types
|
||||
virtual std::vector<CertificateHashDataChain>
|
||||
get_installed_certificates(const std::vector<CertificateType>& certificate_types) = 0;
|
||||
|
||||
/// \brief Retrieves the OCSP request data of the V2G certificates (exluding the root). This function respects the
|
||||
/// requirements of OCPP specified for the CSMS initiated message GetCertificateStatus.req . \return contains OCSP
|
||||
/// request data
|
||||
virtual std::vector<OCSPRequestData> get_v2g_ocsp_request_data() = 0;
|
||||
|
||||
/// \brief Retrieves the OCSP request data of a certificate chain.
|
||||
/// \param certificate_chain PEM formatted certificate or certificate chain
|
||||
/// \param certificate_type type of the leaf certificate
|
||||
/// \return contains OCSP request data
|
||||
virtual std::vector<OCSPRequestData> get_mo_ocsp_request_data(const std::string& certificate_chain) = 0;
|
||||
|
||||
/// \brief Updates the OCSP cache for the given \p certificate_hash_data with the given \p ocsp_response
|
||||
/// \param certificate_hash_data identifies the certificate for which the \p ocsp_response is specified
|
||||
/// \param ocsp_response the actual OCSP data
|
||||
virtual void update_ocsp_cache(const CertificateHashDataType& certificate_hash_data,
|
||||
const std::string& ocsp_response) = 0;
|
||||
|
||||
/// \brief Indicates if a CA certificate for the given \p certificate_type is installed on the filesystem
|
||||
/// \param certificate_type
|
||||
/// \return true if CA certificate is present, else false
|
||||
virtual bool is_ca_certificate_installed(const CaCertificateType& certificate_type) = 0;
|
||||
|
||||
/// \brief Generates a certificate signing request for the given \p certificate_type , \p country , \p organization
|
||||
/// and \p common , uses the TPM if \p use_tpm is true
|
||||
/// \param certificate_type
|
||||
/// \param country
|
||||
/// \param organization
|
||||
/// \param common
|
||||
/// \param use_tpm If the TPM should be used for the CSR request
|
||||
/// \return the status and an optional PEM formatted certificate signing request string
|
||||
virtual GetCertificateSignRequestResult
|
||||
generate_certificate_signing_request(const CertificateSigningUseEnum& certificate_type, const std::string& country,
|
||||
const std::string& organization, const std::string& common, bool use_tpm) = 0;
|
||||
|
||||
/// \brief Searches the filesystem on the specified directories for the given \p certificate_type and retrieves the
|
||||
/// most recent certificate that is already valid and the respective key. If no certificate is present or no key is
|
||||
/// matching the certificate, this function returns a GetKeyPairStatus other than "Accepted". The function \ref
|
||||
/// update_leaf_certificate will install two files for each leaf, one containing the single leaf and one containing
|
||||
/// the leaf including any possible SUBCAs
|
||||
/// \param certificate_type type of the leaf certificate
|
||||
/// \param include_ocsp if OCSP data should be included
|
||||
/// \return contains response result, with info related to the certificate chain and response status
|
||||
virtual GetCertificateInfoResult get_leaf_certificate_info(const CertificateSigningUseEnum& certificate_type,
|
||||
bool include_ocsp = false) = 0;
|
||||
|
||||
/// \brief Updates the certificate and key links for the given \p certificate_type
|
||||
virtual bool update_certificate_links(const CertificateSigningUseEnum& certificate_type) = 0;
|
||||
|
||||
/// \brief Retrieves the PEM formatted CA bundle file for the given \p certificate_type
|
||||
/// \param certificate_type
|
||||
/// \return CA certificate file
|
||||
virtual std::string get_verify_file(const CaCertificateType& certificate_type) = 0;
|
||||
|
||||
/// \brief Retrieves the PEM formatted CA bundle location for the given \p certificate_type
|
||||
/// \param certificate_type
|
||||
/// \return CA certificate file
|
||||
virtual std::string get_verify_location(const CaCertificateType& certificate_type) = 0;
|
||||
|
||||
/// \brief Gets the expiry day count for the leaf certificate of the given \p certificate_type
|
||||
/// \param certificate_type
|
||||
/// \return day count until the leaf certificate expires
|
||||
virtual int get_leaf_expiry_days_count(const CertificateSigningUseEnum& certificate_type) = 0;
|
||||
};
|
||||
|
||||
namespace evse_security_conversions {
|
||||
|
||||
/** Conversions for Plug&Charge Data Transfer **/
|
||||
|
||||
ocpp::v2::GetCertificateIdUseEnum to_ocpp_v2(ocpp::CertificateType other);
|
||||
ocpp::v2::InstallCertificateUseEnum to_ocpp_v2(ocpp::CaCertificateType other);
|
||||
ocpp::v2::HashAlgorithmEnum to_ocpp_v2(ocpp::HashAlgorithmEnumType other);
|
||||
ocpp::v2::InstallCertificateStatusEnum to_ocpp_v2(ocpp::InstallCertificateResult other);
|
||||
ocpp::v2::DeleteCertificateStatusEnum to_ocpp_v2(ocpp::DeleteCertificateResult other);
|
||||
|
||||
ocpp::v2::CertificateHashDataType to_ocpp_v2(ocpp::CertificateHashDataType other);
|
||||
ocpp::v2::CertificateHashDataChain to_ocpp_v2(ocpp::CertificateHashDataChain other);
|
||||
ocpp::v2::OCSPRequestData to_ocpp_v2(ocpp::OCSPRequestData other);
|
||||
std::vector<ocpp::v2::OCSPRequestData> to_ocpp_v2(const std::vector<ocpp::OCSPRequestData>& ocsp_request_data);
|
||||
|
||||
ocpp::CertificateType from_ocpp_v2(ocpp::v2::GetCertificateIdUseEnum other);
|
||||
std::vector<ocpp::CertificateType> from_ocpp_v2(const std::vector<ocpp::v2::GetCertificateIdUseEnum>& other);
|
||||
ocpp::CaCertificateType from_ocpp_v2(ocpp::v2::InstallCertificateUseEnum other);
|
||||
ocpp::CertificateSigningUseEnum from_ocpp_v2(ocpp::v2::CertificateSigningUseEnum other);
|
||||
ocpp::HashAlgorithmEnumType from_ocpp_v2(ocpp::v2::HashAlgorithmEnum other);
|
||||
ocpp::InstallCertificateResult from_ocpp_v2(ocpp::v2::InstallCertificateStatusEnum other);
|
||||
ocpp::DeleteCertificateResult from_ocpp_v2(ocpp::v2::DeleteCertificateStatusEnum other);
|
||||
|
||||
ocpp::CertificateHashDataType from_ocpp_v2(ocpp::v2::CertificateHashDataType other);
|
||||
ocpp::CertificateHashDataChain from_ocpp_v2(ocpp::v2::CertificateHashDataChain other);
|
||||
ocpp::OCSPRequestData from_ocpp_v2(ocpp::v2::OCSPRequestData other);
|
||||
|
||||
} // namespace evse_security_conversions
|
||||
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_COMMON_EVSE_SECURITY
|
||||
@@ -0,0 +1,100 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_COMMON_EVSE_SECURITY_IMPL
|
||||
#define OCPP_COMMON_EVSE_SECURITY_IMPL
|
||||
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
|
||||
#include <evse_security/evse_security.hpp>
|
||||
#include <ocpp/common/evse_security.hpp>
|
||||
#include <ocpp/common/support_older_cpp_versions.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
struct SecurityConfiguration {
|
||||
fs::path csms_ca_bundle;
|
||||
fs::path mf_ca_bundle;
|
||||
fs::path mo_ca_bundle;
|
||||
fs::path v2g_ca_bundle;
|
||||
fs::path csms_leaf_cert_directory;
|
||||
fs::path csms_leaf_key_directory;
|
||||
fs::path secc_leaf_cert_directory;
|
||||
fs::path secc_leaf_key_directory;
|
||||
fs::path secc_leaf_cert_link;
|
||||
fs::path secc_leaf_key_link;
|
||||
fs::path cpo_cert_chain_link;
|
||||
std::optional<std::string> private_key_password;
|
||||
};
|
||||
|
||||
class EvseSecurityImpl : public EvseSecurity {
|
||||
|
||||
private:
|
||||
std::unique_ptr<evse_security::EvseSecurity> evse_security;
|
||||
|
||||
public:
|
||||
explicit EvseSecurityImpl(const SecurityConfiguration& security_configuration);
|
||||
InstallCertificateResult install_ca_certificate(const std::string& certificate,
|
||||
const CaCertificateType& certificate_type) override;
|
||||
DeleteCertificateResult delete_certificate(const CertificateHashDataType& certificate_hash_data) override;
|
||||
InstallCertificateResult update_leaf_certificate(const std::string& certificate_chain,
|
||||
const CertificateSigningUseEnum& certificate_type) override;
|
||||
CertificateValidationResult verify_certificate(const std::string& certificate_chain,
|
||||
const LeafCertificateType& certificate_type) override;
|
||||
CertificateValidationResult verify_certificate(const std::string& certificate_chain,
|
||||
const std::vector<LeafCertificateType>& certificate_types) override;
|
||||
std::vector<CertificateHashDataChain>
|
||||
get_installed_certificates(const std::vector<CertificateType>& certificate_types) override;
|
||||
std::vector<OCSPRequestData> get_v2g_ocsp_request_data() override;
|
||||
std::vector<OCSPRequestData> get_mo_ocsp_request_data(const std::string& certificate_chain) override;
|
||||
void update_ocsp_cache(const CertificateHashDataType& certificate_hash_data,
|
||||
const std::string& ocsp_response) override;
|
||||
bool is_ca_certificate_installed(const CaCertificateType& certificate_type) override;
|
||||
GetCertificateSignRequestResult
|
||||
generate_certificate_signing_request(const CertificateSigningUseEnum& certificate_type, const std::string& country,
|
||||
const std::string& organization, const std::string& common,
|
||||
bool use_tpm) override;
|
||||
GetCertificateInfoResult get_leaf_certificate_info(const CertificateSigningUseEnum& certificate_type,
|
||||
bool include_ocsp = false) override;
|
||||
bool update_certificate_links(const CertificateSigningUseEnum& certificate_type) override;
|
||||
std::string get_verify_file(const CaCertificateType& certificate_type) override;
|
||||
std::string get_verify_location(const CaCertificateType& certificate_type) override;
|
||||
int get_leaf_expiry_days_count(const CertificateSigningUseEnum& certificate_type) override;
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
|
||||
GetCertificateSignRequestStatus to_ocpp(evse_security::GetCertificateSignRequestStatus other);
|
||||
CaCertificateType to_ocpp(evse_security::CaCertificateType other);
|
||||
CertificateType to_ocpp(evse_security::CertificateType other);
|
||||
HashAlgorithmEnumType to_ocpp(evse_security::HashAlgorithm other);
|
||||
GetCertificateInfoStatus to_ocpp(evse_security::GetCertificateInfoStatus other);
|
||||
InstallCertificateResult to_ocpp(evse_security::InstallCertificateResult other);
|
||||
CertificateValidationResult to_ocpp(evse_security::CertificateValidationResult other);
|
||||
DeleteCertificateResult to_ocpp(evse_security::DeleteCertificateResult other);
|
||||
|
||||
CertificateHashDataType to_ocpp(evse_security::CertificateHashData other);
|
||||
CertificateHashDataChain to_ocpp(evse_security::CertificateHashDataChain other);
|
||||
OCSPRequestData to_ocpp(evse_security::OCSPRequestData other);
|
||||
CertificateOCSP to_ocpp(evse_security::CertificateOCSP other);
|
||||
CertificateInfo to_ocpp(evse_security::CertificateInfo other);
|
||||
|
||||
evse_security::CaCertificateType from_ocpp(CaCertificateType other);
|
||||
evse_security::LeafCertificateType from_ocpp(LeafCertificateType other);
|
||||
evse_security::LeafCertificateType from_ocpp(CertificateSigningUseEnum other);
|
||||
evse_security::CertificateType from_ocpp(CertificateType other);
|
||||
evse_security::HashAlgorithm from_ocpp(HashAlgorithmEnumType other);
|
||||
evse_security::InstallCertificateResult from_ocpp(InstallCertificateResult other);
|
||||
evse_security::DeleteCertificateResult from_ocpp(DeleteCertificateResult other);
|
||||
|
||||
evse_security::CertificateHashData from_ocpp(CertificateHashDataType other);
|
||||
evse_security::CertificateHashDataChain from_ocpp(CertificateHashDataChain other);
|
||||
evse_security::OCSPRequestData from_ocpp(OCSPRequestData other);
|
||||
evse_security::CertificateOCSP from_ocpp(CertificateOCSP other);
|
||||
evse_security::CertificateInfo from_ocpp(CertificateInfo other);
|
||||
|
||||
}; // namespace conversions
|
||||
|
||||
} // namespace ocpp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ocpp/common/message_queue.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
/// \brief Interface for dispatching OCPP messages that shall be send over the websocket. This interface defines
|
||||
/// dispatching of Call, CallResult and CallError messages.
|
||||
/// \tparam T Type specifies the OCPP protocol version
|
||||
template <typename T> class MessageDispatcherInterface {
|
||||
|
||||
public:
|
||||
virtual ~MessageDispatcherInterface() = default;
|
||||
|
||||
/// \brief Dispatches a Call message.
|
||||
/// \param call the OCPP Call message.
|
||||
/// \param triggered indicates if the call was triggered by a TriggerMessage. Default is false.
|
||||
virtual void dispatch_call(const json& call, bool triggered = false) = 0;
|
||||
|
||||
/// \brief Dispatches a Call message asynchronously.
|
||||
/// \param call the OCPP Call message.
|
||||
/// \param triggered indicates if the call was triggered by a TriggerMessage. Default is false.
|
||||
/// \return std::future<ocpp::EnhancedMessage<T>> Future object containing the enhanced message
|
||||
/// result of type T.
|
||||
virtual std::future<ocpp::EnhancedMessage<T>> dispatch_call_async(const json& call, bool triggered = false) = 0;
|
||||
|
||||
/// \brief Dispatches a CallResult message.
|
||||
/// \param call_result the OCPP CallResult message.
|
||||
virtual void dispatch_call_result(const json& call_result) = 0;
|
||||
|
||||
/// \brief Dispatches a CallError message.
|
||||
/// \param call_result the OCPP CallError message.
|
||||
virtual void dispatch_call_error(const json& call_error) = 0;
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,153 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_COMMON_LOGGING_HPP
|
||||
#define OCPP_COMMON_LOGGING_HPP
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <thread>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
/// Container for a formatted OCPP message with a message type
|
||||
struct FormattedMessageWithType {
|
||||
std::string message_type; ///< The message type
|
||||
std::string message; ///< The message content
|
||||
};
|
||||
|
||||
/// Configuration for log rotation
|
||||
struct LogRotationConfig {
|
||||
bool date_suffix; ///< If set to true the log rotation files use a date after the ".", if not use the traditional
|
||||
///< .0, .1 ... style
|
||||
std::uint64_t
|
||||
maximum_file_size_bytes; ///< The maximum size of the log file in bytes after which the file will be rotated
|
||||
std::uint64_t maximum_file_count; ///< The maximum number of log files to keep in rotation
|
||||
|
||||
LogRotationConfig(bool date_suffix, std::uint64_t maximum_file_size_bytes, std::uint64_t maximum_file_count) :
|
||||
date_suffix(date_suffix),
|
||||
maximum_file_size_bytes(maximum_file_size_bytes),
|
||||
maximum_file_count(maximum_file_count) {
|
||||
}
|
||||
};
|
||||
|
||||
enum class LogRotationStatus {
|
||||
NotRotated,
|
||||
Rotated,
|
||||
RotatedWithDeletion
|
||||
};
|
||||
|
||||
enum class LogType {
|
||||
ChargePoint,
|
||||
CentralSystem,
|
||||
System
|
||||
};
|
||||
|
||||
/// \brief contains a ocpp message logging abstraction
|
||||
class MessageLogging {
|
||||
private:
|
||||
bool log_messages;
|
||||
std::string message_log_path; // FIXME: use fs::path here
|
||||
std::string output_file_name;
|
||||
bool log_to_console;
|
||||
bool detailed_log_to_console;
|
||||
bool log_to_file;
|
||||
bool log_to_html;
|
||||
bool log_raw;
|
||||
bool log_security;
|
||||
bool session_logging;
|
||||
std::filesystem::path log_file;
|
||||
std::ofstream log_os;
|
||||
std::filesystem::path log_raw_file;
|
||||
std::ofstream log_raw_os;
|
||||
std::filesystem::path html_log_file;
|
||||
std::ofstream html_log_os;
|
||||
std::filesystem::path html_raw_log_file;
|
||||
std::ofstream html_raw_log_os;
|
||||
std::filesystem::path security_log_file;
|
||||
std::ofstream security_log_os;
|
||||
std::mutex output_file_mutex;
|
||||
std::function<void(const std::string& message, MessageDirection direction)> message_callback;
|
||||
std::function<void(LogRotationStatus status)> status_callback;
|
||||
std::map<std::string, std::string> lookup_map;
|
||||
std::recursive_mutex session_id_logging_mutex;
|
||||
std::map<std::string, std::shared_ptr<MessageLogging>> session_id_logging;
|
||||
bool rotate_logs;
|
||||
bool date_suffix;
|
||||
std::string logfile_basename;
|
||||
std::uint64_t maximum_file_size_bytes;
|
||||
std::uint64_t maximum_file_count;
|
||||
|
||||
/// \brief Initialize the OCPP message logging
|
||||
void initialize();
|
||||
|
||||
/// \brief Output log message to the configured targets
|
||||
void log_output(LogType typ, const std::string& message_type, const std::string& json_str, bool raw = false);
|
||||
|
||||
/// \brief Format the given \p json_str with the given \p message_type
|
||||
FormattedMessageWithType format_message(const std::string& message_type, const std::string& json_str);
|
||||
|
||||
/// \brief Rotates the log at the given file \p file_basename and remove oldest file if there are more log files
|
||||
/// than the maximum
|
||||
LogRotationStatus rotate_log(const std::string& file_basename);
|
||||
|
||||
/// \brief Rotates the log at the given \p path if needed based on the config, closing the stream \p os before
|
||||
LogRotationStatus rotate_log_if_needed(const std::filesystem::path& path, std::ofstream& os);
|
||||
|
||||
/// \brief Rotates the log at the given \p path if needed based on the config, calling \p before_close_of_os before
|
||||
/// closing the stream \p os and calling \p after_open_of_os afterwards
|
||||
LogRotationStatus rotate_log_if_needed(const std::filesystem::path& path, std::ofstream& os,
|
||||
std::function<void(std::ofstream& os)> before_close_of_os,
|
||||
std::function<void(std::ofstream& os)> after_open_of_os);
|
||||
|
||||
public:
|
||||
/// \brief Creates a new MessageLogging object with the provided configuration
|
||||
explicit MessageLogging(
|
||||
bool log_messages, const std::string& message_log_path, const std::string& output_file_name,
|
||||
bool log_to_console, bool detailed_log_to_console, bool log_to_file, bool log_to_html, bool log_raw,
|
||||
bool log_security, bool session_logging,
|
||||
std::function<void(const std::string& message, MessageDirection direction)> message_callback);
|
||||
|
||||
/// \brief Creates a new MessageLogging object with the provided configuration and enabled log rotation
|
||||
explicit MessageLogging(
|
||||
bool log_messages, const std::string& message_log_path, const std::string& output_file_name,
|
||||
bool log_to_console, bool detailed_log_to_console, bool log_to_file, bool log_to_html, bool log_raw,
|
||||
bool log_security, bool session_logging,
|
||||
std::function<void(const std::string& message, MessageDirection direction)> message_callback,
|
||||
LogRotationConfig log_rotation_config, std::function<void(LogRotationStatus status)> status_callback);
|
||||
~MessageLogging();
|
||||
|
||||
/// \brief Log a message originating from the charge point
|
||||
void charge_point(const std::string& message_type, const std::string& json_str);
|
||||
|
||||
/// \brief Log a message originating from the central system
|
||||
void central_system(const std::string& message_type, const std::string& json_str);
|
||||
|
||||
/// \brief Log a system message
|
||||
void sys(const std::string& msg);
|
||||
|
||||
/// \brief Log a security message
|
||||
void security(const std::string& msg);
|
||||
|
||||
/// \brief Log a raw OCPP message
|
||||
void raw(const std::string& msg, LogType log_type);
|
||||
|
||||
/// \brief Start session logging (without log rotation)
|
||||
void start_session_logging(const std::string& session_id, const std::string& log_path);
|
||||
|
||||
/// \brief Stop session logging
|
||||
void stop_session_logging(const std::string& session_id);
|
||||
|
||||
/// \returns The message log path
|
||||
std::string get_message_log_path();
|
||||
|
||||
/// \returns If session logging is active
|
||||
bool session_logging_active() const;
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
#endif // OCPP_COMMON_LOGGING_HPP
|
||||
@@ -0,0 +1,121 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
/// \brief Thread safe message queue. Holds a conditional variable
|
||||
/// that can be waited upon. Will take up the waiting thread on each
|
||||
/// operation of push/pop/clear
|
||||
template <typename T> class SafeQueue {
|
||||
public:
|
||||
/// \return True if the queue is empty
|
||||
bool empty() const {
|
||||
const std::lock_guard lock(mutex);
|
||||
return queue.empty();
|
||||
}
|
||||
|
||||
/// \brief We return a copy here, since while might be accessing the
|
||||
/// reference while another thread uses pop and makes the reference stale
|
||||
T front() {
|
||||
const std::lock_guard lock(mutex);
|
||||
return queue.front();
|
||||
}
|
||||
|
||||
/// \return retrieves and removes the first element in the queue. Undefined behavior if the queue is empty
|
||||
T pop() {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
|
||||
T front = std::move(queue.front());
|
||||
queue.pop();
|
||||
|
||||
// Unlock here and notify
|
||||
lock.unlock();
|
||||
|
||||
notify_waiting_thread();
|
||||
|
||||
return front;
|
||||
}
|
||||
|
||||
/// \brief Queues an element and notifies any threads waiting on the internal conditional variable
|
||||
void push(T&& value) {
|
||||
{
|
||||
const std::lock_guard<std::mutex> lock(mutex);
|
||||
queue.push(std::move(value));
|
||||
}
|
||||
|
||||
notify_waiting_thread();
|
||||
}
|
||||
|
||||
/// \brief Queues an element and notifies any threads waiting on the internal conditional variable
|
||||
void push(const T& value) {
|
||||
{
|
||||
const std::lock_guard<std::mutex> lock(mutex);
|
||||
queue.push(value);
|
||||
}
|
||||
|
||||
notify_waiting_thread();
|
||||
}
|
||||
|
||||
/// \brief Clears the queue
|
||||
void clear() {
|
||||
{
|
||||
const std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
std::queue<T> empty;
|
||||
empty.swap(queue);
|
||||
}
|
||||
|
||||
notify_waiting_thread();
|
||||
}
|
||||
|
||||
/// \brief Waits for the queue to receive an element
|
||||
/// \param timeout to wait for an element, pass in a value <= 0 to wait indefinitely
|
||||
void wait_on_queue_element(std::chrono::milliseconds timeout = std::chrono::milliseconds(0)) {
|
||||
wait_on_queue_element_or_predicate([]() { return false; }, timeout);
|
||||
}
|
||||
|
||||
/// \brief Same as 'wait_on_queue' but receives an additional predicate to wait upon
|
||||
template <class Predicate>
|
||||
void wait_on_queue_element_or_predicate(Predicate pred,
|
||||
std::chrono::milliseconds timeout = std::chrono::milliseconds(0)) {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
|
||||
if (timeout.count() > 0) {
|
||||
cv.wait_for(lock, timeout, [&]() { return (false == queue.empty()) or pred(); });
|
||||
} else {
|
||||
cv.wait(lock, [&]() { return (false == queue.empty()) or pred(); });
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Waits on the queue for a custom event
|
||||
/// \param timeout to wait for an element, pass in a value <= 0 to wait indefinitely
|
||||
template <class Predicate>
|
||||
void wait_on_custom_event(Predicate pred, std::chrono::milliseconds timeout = std::chrono::milliseconds(0)) {
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
|
||||
if (timeout.count() > 0) {
|
||||
cv.wait_for(lock, timeout, [&]() { return pred(); });
|
||||
} else {
|
||||
cv.wait(lock, [&]() { return pred(); });
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Notifies a single waiting thread to wake up
|
||||
void notify_waiting_thread() {
|
||||
cv.notify_one();
|
||||
}
|
||||
|
||||
private:
|
||||
std::queue<T> queue;
|
||||
|
||||
mutable std::mutex mutex;
|
||||
std::condition_variable cv;
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_COMMON_SCHEMAS_HPP
|
||||
#define OCPP_COMMON_SCHEMAS_HPP
|
||||
|
||||
#include <map>
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
#include <nlohmann/json-schema.hpp>
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <ocpp/common/support_older_cpp_versions.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
using json_uri = nlohmann::json_uri;
|
||||
using json_validator = nlohmann::json_schema::json_validator;
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
/// \brief Contains the json schema validation for the libocpp config
|
||||
class Schemas {
|
||||
private:
|
||||
json schema;
|
||||
std::shared_ptr<json_validator> validator;
|
||||
fs::path schemas_path;
|
||||
std::set<fs::path> available_schemas_paths;
|
||||
const static std::vector<std::string> profiles;
|
||||
const static std::regex date_time_regex;
|
||||
|
||||
/// \brief Loads the root schema "Config.json" from the schemas path
|
||||
void load_root_schema();
|
||||
|
||||
/// \brief A custom json schema loader that loads \p schema files relative to the provided \p uri
|
||||
void loader(const json_uri& uri, json& schema);
|
||||
|
||||
public:
|
||||
/// \brief Creates a new Schemas object looking for the root schema file in relation to the provided \p main_dir
|
||||
explicit Schemas(fs::path schemas_path);
|
||||
/// \brief Creates a new Schemas object using the supplied JSON schema
|
||||
explicit Schemas(const json& schema_in);
|
||||
/// \brief Creates a new Schemas object using the supplied JSON schema
|
||||
explicit Schemas(json&& schema_in);
|
||||
|
||||
/// \brief Provides the config schema
|
||||
/// \returns the config schema as as json object
|
||||
json get_schema();
|
||||
|
||||
/// \brief Provides the config schema validator
|
||||
/// \returns a json_validator for the config
|
||||
std::shared_ptr<json_validator> get_validator();
|
||||
|
||||
/// \brief Provides a format checker for the given \p format and \p value
|
||||
static void format_checker(const std::string& format, const std::string& value);
|
||||
};
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_COMMON_SCHEMAS_HPP
|
||||
@@ -0,0 +1,109 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_COMMON_STRING_HPP
|
||||
#define OCPP_COMMON_STRING_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
class StringConversionException : public std::runtime_error {
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
enum class StringTooLarge {
|
||||
Throw,
|
||||
Truncate
|
||||
};
|
||||
|
||||
/// \brief Contains a String impementation with a maximum length
|
||||
template <size_t L> class String {
|
||||
private:
|
||||
std::string data;
|
||||
static constexpr size_t length = L;
|
||||
|
||||
public:
|
||||
/// \brief Creates a string from the given \p data
|
||||
explicit String(const std::string& data, StringTooLarge to_large = StringTooLarge::Throw) {
|
||||
this->set(data, to_large);
|
||||
}
|
||||
|
||||
explicit String(const char* data, StringTooLarge to_large = StringTooLarge::Throw) {
|
||||
this->set(data, to_large);
|
||||
}
|
||||
|
||||
/// \brief Creates a string
|
||||
String() = default;
|
||||
|
||||
/// \brief Provides a std::string representation of the string
|
||||
/// \returns a std::string
|
||||
std::string get() const {
|
||||
return data;
|
||||
}
|
||||
|
||||
/// \brief Sets the content of the string to the given \p data
|
||||
void set(const std::string& data, StringTooLarge to_large = StringTooLarge::Throw) {
|
||||
std::string_view view = data;
|
||||
if (view.length() > String<L>::length) {
|
||||
if (to_large == StringTooLarge::Throw) {
|
||||
throw StringConversionException("String length (" + std::to_string(view.length()) +
|
||||
") exceeds permitted length (" + std::to_string(String<L>::length) +
|
||||
")");
|
||||
}
|
||||
// Truncate
|
||||
view = view.substr(0, length);
|
||||
}
|
||||
|
||||
if (this->is_valid(view)) {
|
||||
this->data = view;
|
||||
} else {
|
||||
throw StringConversionException("String has invalid format");
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Override this to check for a specific format
|
||||
bool is_valid(std::string_view data) {
|
||||
(void)data; // not needed here
|
||||
return true;
|
||||
}
|
||||
|
||||
/// \brief Conversion operator to turn a String into std::string
|
||||
operator std::string() {
|
||||
return this->get();
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
template <size_t L> bool operator==(const String<L>& lhs, const char* rhs) {
|
||||
return lhs.get() == rhs;
|
||||
}
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
template <size_t L> bool operator==(const String<L>& lhs, const String<L>& rhs) {
|
||||
return lhs.get() == rhs.get();
|
||||
}
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
template <size_t L> bool operator!=(const String<L>& lhs, const char* rhs) {
|
||||
return !(lhs.get() == rhs);
|
||||
}
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
template <size_t L> bool operator!=(const String<L>& lhs, const String<L>& rhs) {
|
||||
return !(lhs.get() == rhs.get());
|
||||
}
|
||||
|
||||
/// \brief Writes the given string \p str to the given output stream \p os
|
||||
/// \returns an output stream with the case insensitive string written to
|
||||
template <size_t L> std::ostream& operator<<(std::ostream& os, const String<L>& str) {
|
||||
os << str.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
} // namespace ocpp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef OCPP_COMMON_SUPPORT_OLDER_CPP_VERSIONS_HPP_
|
||||
#define OCPP_COMMON_SUPPORT_OLDER_CPP_VERSIONS_HPP_
|
||||
|
||||
#ifndef LIBOCPP_USE_BOOST_FILESYSTEM
|
||||
#include <filesystem>
|
||||
#else
|
||||
#include <boost/filesystem.hpp>
|
||||
#endif
|
||||
|
||||
#ifndef LIBOCPP_USE_BOOST_FILESYSTEM
|
||||
namespace fs = std::filesystem;
|
||||
namespace fsstd = std;
|
||||
#else
|
||||
namespace fs = boost::filesystem;
|
||||
namespace fsstd = boost::filesystem;
|
||||
#endif
|
||||
|
||||
#endif /* OCPP_COMMON_SUPPORT_OLDER_CPP_VERSIONS_HPP_ */
|
||||
@@ -0,0 +1,866 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef OCPP_COMMON_TYPES_HPP
|
||||
#define OCPP_COMMON_TYPES_HPP
|
||||
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <date/date.h>
|
||||
#include <date/tz.h>
|
||||
|
||||
#include <ocpp/common/cistring.hpp>
|
||||
#include <ocpp/common/support_older_cpp_versions.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v2/ocpp_enums.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
/// \brief Parent structure for all OCPP messages supported by this implementation
|
||||
struct Message {
|
||||
/// \brief Provides the type of the message
|
||||
/// \returns the message type as a string
|
||||
virtual std::string get_type() const = 0;
|
||||
virtual ~Message() = default;
|
||||
};
|
||||
|
||||
/// \brief Exception used when DateTime class is initialized by invalid timepoint string.
|
||||
class TimePointParseException : public std::exception {
|
||||
public:
|
||||
explicit TimePointParseException(const std::string& timepoint_str) :
|
||||
msg{"Timepoint string parsing failed. Could not convert: \"" + timepoint_str + "\" into DateTime."} {
|
||||
}
|
||||
|
||||
const char* what() const noexcept override {
|
||||
return msg.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
/// \brief Contains a DateTime implementation that can parse and create RFC 3339 compatible strings
|
||||
class DateTimeImpl {
|
||||
private:
|
||||
std::chrono::time_point<date::utc_clock> timepoint;
|
||||
|
||||
public:
|
||||
/// \brief Creates a new DateTimeImpl object with the current utc time
|
||||
DateTimeImpl();
|
||||
|
||||
~DateTimeImpl() = default;
|
||||
|
||||
/// \brief Creates a new DateTimeImpl object from the given \p timepoint
|
||||
explicit DateTimeImpl(std::chrono::time_point<date::utc_clock> timepoint);
|
||||
|
||||
/// \brief Creates a new DateTimeImpl object from the given \p timepoint_str
|
||||
explicit DateTimeImpl(const std::string& timepoint_str);
|
||||
|
||||
/// \brief Converts this DateTimeImpl to a RFC 3339 compatible string
|
||||
/// \returns a RFC 3339 compatible string representation of the stored DateTime
|
||||
std::string to_rfc3339() const;
|
||||
|
||||
/// \brief Sets the timepoint of this DateTimeImpl to the given \p timepoint_str
|
||||
void from_rfc3339(const std::string& timepoint_str);
|
||||
|
||||
/// \brief Converts this DateTimeImpl to a std::chrono::time_point
|
||||
/// \returns a std::chrono::time_point
|
||||
std::chrono::time_point<date::utc_clock> to_time_point() const;
|
||||
|
||||
/// \brief Assignment operator= to assign another DateTimeImpl \p dt to this DateTimeImpl
|
||||
DateTimeImpl& operator=(const DateTimeImpl& dt);
|
||||
|
||||
/// \brief Conversion operatpr std::string returns a RFC 3339 compatible string representation of the stored
|
||||
/// DateTime
|
||||
operator std::string() const {
|
||||
return this->to_rfc3339();
|
||||
}
|
||||
|
||||
/// \brief Writes the given DateTimeImpl \p dt to the given output stream \p os as a RFC 3339 compatible string
|
||||
/// \returns an output stream with the DateTimeImpl as a RFC 3339 compatible string written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const DateTimeImpl& dt);
|
||||
|
||||
/// \brief Comparison operator> between two DateTimeImpl \p lhs and \p rhs
|
||||
friend bool operator>(const DateTimeImpl& lhs, const DateTimeImpl& rhs);
|
||||
|
||||
/// \brief Comparison operator>= between two DateTimeImpl \p lhs and \p rhs
|
||||
friend bool operator>=(const DateTimeImpl& lhs, const DateTimeImpl& rhs);
|
||||
|
||||
/// \brief Comparison operator< between two DateTimeImpl \p lhs and \p rhs
|
||||
friend bool operator<(const DateTimeImpl& lhs, const DateTimeImpl& rhs);
|
||||
|
||||
/// \brief Comparison operator<= between two DateTimeImpl \p lhs and \p rhs
|
||||
friend bool operator<=(const DateTimeImpl& lhs, const DateTimeImpl& rhs);
|
||||
|
||||
/// \brief Comparison operator== between two DateTimeImpl \p lhs and \p rhs
|
||||
friend bool operator==(const DateTimeImpl& lhs, const DateTimeImpl& rhs);
|
||||
};
|
||||
|
||||
/// \brief Contains a DateTime implementation that can parse and create RFC 3339 compatible strings
|
||||
class DateTime : public DateTimeImpl {
|
||||
public:
|
||||
/// \brief Creates a new DateTime object with the current system time
|
||||
DateTime();
|
||||
|
||||
~DateTime() = default;
|
||||
|
||||
/// \brief Creates a new DateTime object from the given \p timepoint
|
||||
explicit DateTime(std::chrono::time_point<date::utc_clock> timepoint);
|
||||
|
||||
/// \brief Creates a new DateTime object from the given \p timepoint_str
|
||||
explicit DateTime(const std::string& timepoint_str);
|
||||
};
|
||||
|
||||
/// \brief Base exception for when a conversion from string to enum or vice versa fails
|
||||
class EnumConversionException : public std::out_of_range {
|
||||
public:
|
||||
using std::out_of_range::out_of_range;
|
||||
};
|
||||
|
||||
/// \brief Exception used when conversion from enum to string fails
|
||||
class EnumToStringException : public EnumConversionException {
|
||||
public:
|
||||
/// \brief Creates a new StringToEnumException
|
||||
/// \param enumValue value of enum that failed to convert
|
||||
/// \param type name of the enum trying to convert from
|
||||
template <typename T>
|
||||
explicit EnumToStringException(T enumValue, std::string_view type) :
|
||||
EnumConversionException{std::string{"No known conversion from value '"} +
|
||||
std::to_string(static_cast<int>(enumValue)) + "' to " + type.data()} {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Exception used when conversion from string to enum fails
|
||||
class StringToEnumException : public EnumConversionException {
|
||||
public:
|
||||
/// \brief Creates a new StringToEnumException
|
||||
/// \param str input string that failed to convert
|
||||
/// \param type name of the enum trying to convert to
|
||||
StringToEnumException(std::string_view str, std::string_view type) :
|
||||
EnumConversionException{std::string{"Provided string '"} + str.data() + "' could not be converted to " +
|
||||
type.data()} {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Contains the different connection states of the charge point
|
||||
enum class SessionStartedReason {
|
||||
EVConnected,
|
||||
Authorized
|
||||
};
|
||||
namespace conversions {
|
||||
/// \brief Converts the given SessionStartedReason \p e to std::string
|
||||
/// \returns a string representation of the SessionStartedReason
|
||||
std::string session_started_reason_to_string(SessionStartedReason e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to SessionStartedReason
|
||||
/// \returns a SessionStartedReason from a string representation
|
||||
SessionStartedReason string_to_session_started_reason(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given \p session_started_reason
|
||||
/// to the given output stream \p os \returns an output stream with the SessionStartedReason written to
|
||||
std::ostream& operator<<(std::ostream& os, const SessionStartedReason& session_started_reason);
|
||||
|
||||
struct Current {
|
||||
std::optional<float> DC; ///< DC current
|
||||
std::optional<float> L1; ///< AC L1 value only
|
||||
std::optional<float> L2; ///< AC L2 value only
|
||||
std::optional<float> L3; ///< AC L3 value only
|
||||
std::optional<float> N; ///< AC Neutral value only
|
||||
|
||||
/// \brief Conversion from a given Current \p k to a given json object \p j
|
||||
friend void to_json(json& j, const Current& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given Current \p k
|
||||
friend void from_json(const json& j, Current& k);
|
||||
|
||||
// \brief Writes the string representation of the given Current \p k to the given output stream \p os
|
||||
/// \returns an output stream with the Current written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const Current& k);
|
||||
};
|
||||
struct Voltage {
|
||||
std::optional<float> DC; ///< DC voltage
|
||||
std::optional<float> L1; ///< AC L1 value only
|
||||
std::optional<float> L2; ///< AC L2 value only
|
||||
std::optional<float> L3; ///< AC L3 value only
|
||||
|
||||
/// \brief Conversion from a given Voltage \p k to a given json object \p j
|
||||
friend void to_json(json& j, const Voltage& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given Voltage \p k
|
||||
friend void from_json(const json& j, Voltage& k);
|
||||
|
||||
// \brief Writes the string representation of the given Voltage \p k to the given output stream \p os
|
||||
/// \returns an output stream with the Voltage written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const Voltage& k);
|
||||
};
|
||||
struct Frequency {
|
||||
float L1; ///< AC L1 value
|
||||
std::optional<float> L2; ///< AC L2 value
|
||||
std::optional<float> L3; ///< AC L3 value
|
||||
|
||||
/// \brief Conversion from a given Frequency \p k to a given json object \p j
|
||||
friend void to_json(json& j, const Frequency& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given Frequency \p k
|
||||
friend void from_json(const json& j, Frequency& k);
|
||||
|
||||
// \brief Writes the string representation of the given Frequency \p k to the given output stream \p os
|
||||
/// \returns an output stream with the Frequency written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const Frequency& k);
|
||||
};
|
||||
struct Power {
|
||||
float total; ///< DC / AC Sum value
|
||||
std::optional<float> L1; ///< AC L1 value only
|
||||
std::optional<float> L2; ///< AC L2 value only
|
||||
std::optional<float> L3; ///< AC L3 value only
|
||||
|
||||
/// \brief Conversion from a given Power \p k to a given json object \p j
|
||||
friend void to_json(json& j, const Power& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given Power \p k
|
||||
friend void from_json(const json& j, Power& k);
|
||||
|
||||
// \brief Writes the string representation of the given Power \p k to the given output stream \p os
|
||||
/// \returns an output stream with the Power written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const Power& k);
|
||||
};
|
||||
struct Energy {
|
||||
float total; ///< DC / AC Sum value (which is relevant for billing)
|
||||
std::optional<float> L1; ///< AC L1 value only
|
||||
std::optional<float> L2; ///< AC L2 value only
|
||||
std::optional<float> L3; ///< AC L3 value only
|
||||
|
||||
/// \brief Conversion from a given Energy \p k to a given json object \p j
|
||||
friend void to_json(json& j, const Energy& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given Energy \p k
|
||||
friend void from_json(const json& j, Energy& k);
|
||||
|
||||
// \brief Writes the string representation of the given Energy \p k to the given output stream \p os
|
||||
/// \returns an output stream with the Energy written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const Energy& k);
|
||||
};
|
||||
struct ReactivePower {
|
||||
float total; ///< VAR total
|
||||
std::optional<float> VARphA; ///< VAR phase A
|
||||
std::optional<float> VARphB; ///< VAR phase B
|
||||
std::optional<float> VARphC; ///< VAR phase C
|
||||
|
||||
/// \brief Conversion from a given ReactivePower \p k to a given json object \p j
|
||||
friend void to_json(json& j, const ReactivePower& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ReactivePower \p k
|
||||
friend void from_json(const json& j, ReactivePower& k);
|
||||
|
||||
// \brief Writes the string representation of the given ReactivePower \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ReactivePower written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const ReactivePower& k);
|
||||
};
|
||||
|
||||
struct Powermeter {
|
||||
std::string timestamp; ///< Timestamp of measurement
|
||||
Energy energy_Wh_import; ///< Imported energy in Wh (from grid)
|
||||
std::optional<std::string> meter_id; ///< A (user defined) meter if (e.g. id printed on the case)
|
||||
std::optional<bool> phase_seq_error; ///< AC only: true for 3 phase rotation error (ccw)
|
||||
std::optional<Energy> energy_Wh_export; ///< Exported energy in Wh (to grid)
|
||||
std::optional<Power>
|
||||
power_W; ///< Instantaneous power in Watt. Negative values are exported, positive values imported Energy.
|
||||
std::optional<Voltage> voltage_V; ///< Voltage in Volts
|
||||
std::optional<ReactivePower> VAR; ///< Reactive power VAR
|
||||
std::optional<Current> current_A; ///< Current in ampere
|
||||
std::optional<Frequency> frequency_Hz; ///< Grid frequency in Hertz
|
||||
|
||||
/// \brief Conversion from a given Powermeter \p k to a given json object \p j
|
||||
friend void to_json(json& j, const Powermeter& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given Powermeter \p k
|
||||
friend void from_json(const json& j, Powermeter& k);
|
||||
|
||||
// \brief Writes the string representation of the given Powermeter \p k to the given output stream \p os
|
||||
/// \returns an output stream with the Powermeter written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const Powermeter& k);
|
||||
};
|
||||
|
||||
struct StateOfCharge {
|
||||
float value = 0; ///< State of Charge in percent
|
||||
std::optional<std::string> location; ///< Location of the State of Charge measurement
|
||||
|
||||
/// \brief Conversion from a given StateOfCharge \p k to a given json object \p j
|
||||
friend void to_json(json& j, const StateOfCharge& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given StateOfCharge \p k
|
||||
friend void from_json(const json& j, StateOfCharge& k);
|
||||
|
||||
// \brief Writes the string representation of the given StateOfCharge \p k to the given output stream \p os
|
||||
/// \returns an output stream with the StateOfCharge written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const StateOfCharge& k);
|
||||
};
|
||||
|
||||
struct Temperature {
|
||||
float value = 0; ///< Temperature in degree Celsius
|
||||
std::optional<std::string> location; ///< Location of the Temperature measurement
|
||||
|
||||
/// \brief Conversion from a given Temperature \p k to a given json object \p j
|
||||
friend void to_json(json& j, const Temperature& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given Temperature \p k
|
||||
friend void from_json(const json& j, Temperature& k);
|
||||
|
||||
// \brief Writes the string representation of the given Temperature \p k to the given output stream \p os
|
||||
/// \returns an output stream with the Temperature written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const Temperature& k);
|
||||
};
|
||||
|
||||
struct RPM {
|
||||
float value = 0; ///< RPM
|
||||
std::optional<std::string> location; ///< Location of the RPM measurement
|
||||
|
||||
/// \brief Conversion from a given RPM \p k to a given json object \p j
|
||||
friend void to_json(json& j, const RPM& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given RPM \p k
|
||||
friend void from_json(const json& j, RPM& k);
|
||||
|
||||
// \brief Writes the string representation of the given RPM \p k to the given output stream \p os
|
||||
/// \returns an output stream with the RPM written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const RPM& k);
|
||||
};
|
||||
|
||||
struct Measurement {
|
||||
Powermeter power_meter; ///< Powermeter data
|
||||
std::optional<StateOfCharge> soc_Percent; ///< State of Charge in percent
|
||||
std::vector<Temperature> temperature_C; ///< Temperature in degree Celsius
|
||||
std::optional<RPM> rpm; ///< RPM
|
||||
|
||||
/// \brief Conversion from a given Measurement \p k to a given json object \p j
|
||||
friend void to_json(json& j, const Measurement& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given Measurement \p k
|
||||
friend void from_json(const json& j, Measurement& k);
|
||||
|
||||
// \brief Writes the string representation of the given Measurement \p k to the given output stream \p os
|
||||
/// \returns an output stream with the Measurement written to
|
||||
friend std::ostream& operator<<(std::ostream& os, const Measurement& k);
|
||||
};
|
||||
|
||||
struct DisplayMessageContent {
|
||||
std::string message;
|
||||
std::optional<std::string> language;
|
||||
std::optional<v2::MessageFormatEnum> message_format;
|
||||
|
||||
friend void from_json(const json& j, DisplayMessageContent& m);
|
||||
friend void to_json(json& j, const DisplayMessageContent& m);
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Type of an identifier string.
|
||||
///
|
||||
enum class IdentifierType {
|
||||
SessionId, ///< \brief Identifier is the session id.
|
||||
IdToken, ///< \brief Identifier is the id token.
|
||||
TransactionId ///< \brief Identifier is the transaction id.
|
||||
};
|
||||
|
||||
struct TariffMessage {
|
||||
std::optional<std::string> ocpp_transaction_id;
|
||||
std::optional<std::string> identifier_id;
|
||||
std::optional<IdentifierType> identifier_type;
|
||||
std::vector<DisplayMessageContent> message;
|
||||
};
|
||||
|
||||
struct DisplayMessage {
|
||||
std::optional<std::int32_t> id;
|
||||
std::optional<v2::MessagePriorityEnum> priority;
|
||||
std::optional<v2::MessageStateEnum> state;
|
||||
std::optional<DateTime> timestamp_from;
|
||||
std::optional<DateTime> timestamp_to;
|
||||
std::optional<std::string> identifier_id;
|
||||
std::optional<IdentifierType> identifier_type;
|
||||
DisplayMessageContent message;
|
||||
std::optional<std::string> qr_code;
|
||||
};
|
||||
|
||||
struct RunningCostChargingPrice {
|
||||
std::optional<double> kWh_price;
|
||||
std::optional<double> hour_price;
|
||||
std::optional<double> flat_fee;
|
||||
|
||||
friend void from_json(const json& j, RunningCostChargingPrice& c);
|
||||
friend void to_json(json& j, const RunningCostChargingPrice& c);
|
||||
};
|
||||
|
||||
struct RunningCostIdlePrice {
|
||||
std::optional<std::uint32_t> idle_grace_minutes;
|
||||
std::optional<double> idle_hour_price;
|
||||
|
||||
friend void from_json(const json& j, RunningCostIdlePrice& c);
|
||||
friend void to_json(json& j, const RunningCostIdlePrice& c);
|
||||
};
|
||||
|
||||
enum class RunningCostState {
|
||||
Charging,
|
||||
Idle,
|
||||
Finished
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
RunningCostState string_to_running_cost_state(const std::string& state);
|
||||
std::string running_cost_state_to_string(const RunningCostState& state);
|
||||
} // namespace conversions
|
||||
|
||||
struct RunningCost {
|
||||
std::string transaction_id;
|
||||
std::optional<DateTime> timestamp;
|
||||
std::optional<std::uint32_t> meter_value;
|
||||
double cost;
|
||||
// Running cost state: "Charging" or "Idle". When this is the final price, state will be "Finished".
|
||||
RunningCostState state;
|
||||
std::optional<RunningCostChargingPrice> charging_price;
|
||||
std::optional<RunningCostIdlePrice> idle_price;
|
||||
std::optional<DateTime> next_period_at_time;
|
||||
std::optional<RunningCostChargingPrice> next_period_charging_price;
|
||||
std::optional<RunningCostIdlePrice> next_period_idle_price;
|
||||
std::optional<std::vector<DisplayMessageContent>> cost_messages;
|
||||
std::optional<std::string> qr_code_text;
|
||||
|
||||
friend void from_json(const json& j, RunningCost& c);
|
||||
};
|
||||
|
||||
struct TriggerMeterValue {
|
||||
std::optional<DateTime> at_time;
|
||||
std::optional<int> at_energy_kwh;
|
||||
std::optional<int> at_power_kw;
|
||||
std::vector<v16::ChargePointStatus> at_chargepoint_status;
|
||||
|
||||
friend void from_json(const json& j, TriggerMeterValue& t);
|
||||
};
|
||||
|
||||
enum class CaCertificateType {
|
||||
V2G,
|
||||
MO,
|
||||
CSMS,
|
||||
MF,
|
||||
OEM
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given CaCertificateType \p e to human readable string
|
||||
/// \returns a string representation of the CaCertificateType
|
||||
std::string ca_certificate_type_to_string(CaCertificateType e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to CaCertificateType
|
||||
/// \returns a CaCertificateType from a string representation
|
||||
CaCertificateType string_to_ca_certificate_type(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given CaCertificateType
|
||||
/// \param ca_certificate_type to the given output stream
|
||||
/// \param os
|
||||
/// \returns an output stream with the CaCertificateType written to
|
||||
std::ostream& operator<<(std::ostream& os, const CaCertificateType& ca_certificate_type);
|
||||
|
||||
enum class CertificateValidationResult {
|
||||
Valid,
|
||||
Expired,
|
||||
InvalidSignature,
|
||||
IssuerNotFound,
|
||||
InvalidLeafSignature,
|
||||
InvalidChain,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given InstallCertificateResult \p e to human readable string
|
||||
/// \returns a string representation of the InstallCertificateResult
|
||||
std::string certificate_validation_result_to_string(CertificateValidationResult e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to InstallCertificateResult
|
||||
/// \returns a InstallCertificateResult from a string representation
|
||||
CertificateValidationResult string_to_certificate_validation_result(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given InstallCertificateResult \p
|
||||
/// install_certificate_result to the given output stream \p os \returns an output stream with the
|
||||
/// InstallCertificateResult written to
|
||||
std::ostream& operator<<(std::ostream& os, const CertificateValidationResult& certificate_validation_result);
|
||||
|
||||
enum class InstallCertificateResult {
|
||||
InvalidSignature,
|
||||
InvalidCertificateChain,
|
||||
InvalidFormat,
|
||||
InvalidCommonName,
|
||||
NoRootCertificateInstalled,
|
||||
Expired,
|
||||
CertificateStoreMaxLengthExceeded,
|
||||
WriteError,
|
||||
Accepted
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given InstallCertificateResult \p e to human readable string
|
||||
/// \returns a string representation of the InstallCertificateResult
|
||||
std::string install_certificate_result_to_string(InstallCertificateResult e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to InstallCertificateResult
|
||||
/// \returns a InstallCertificateResult from a string representation
|
||||
InstallCertificateResult string_to_install_certificate_result(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given InstallCertificateResult \p
|
||||
/// install_certificate_result to the given output stream \p os \returns an output stream with the
|
||||
/// InstallCertificateResult written to
|
||||
std::ostream& operator<<(std::ostream& os, const InstallCertificateResult& install_certificate_result);
|
||||
|
||||
enum class DeleteCertificateResult {
|
||||
Accepted,
|
||||
Failed,
|
||||
NotFound,
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given DeleteCertificateResult \p e to human readable string
|
||||
/// \returns a string representation of the DeleteCertificateResult
|
||||
std::string delete_certificate_result_to_string(DeleteCertificateResult e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to DeleteCertificateResult
|
||||
/// \returns a DeleteCertificateResult from a string representation
|
||||
DeleteCertificateResult string_to_delete_certificate_result(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given DeleteCertificateResult \p
|
||||
/// delete_certificate_result to the given output stream \p os \returns an output stream with the
|
||||
/// DeleteCertificateResult written to
|
||||
std::ostream& operator<<(std::ostream& os, const DeleteCertificateResult& delete_certificate_result);
|
||||
|
||||
// from: GetInstalledCertificateIdsResponse
|
||||
enum class HashAlgorithmEnumType {
|
||||
SHA256,
|
||||
SHA384,
|
||||
SHA512,
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given HashAlgorithmEnumType \p e to human readable string
|
||||
/// \returns a string representation of the HashAlgorithmEnumType
|
||||
std::string hash_algorithm_enum_type_to_string(HashAlgorithmEnumType e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to HashAlgorithmEnumType
|
||||
/// \returns a HashAlgorithmEnumType from a string representation
|
||||
HashAlgorithmEnumType string_to_hash_algorithm_enum_type(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given HashAlgorithmEnumType \p hash_algorithm_enum_type to the given
|
||||
/// output stream \p os \returns an output stream with the HashAlgorithmEnumType written to
|
||||
std::ostream& operator<<(std::ostream& os, const HashAlgorithmEnumType& hash_algorithm_enum_type);
|
||||
|
||||
struct CertificateHashDataType {
|
||||
HashAlgorithmEnumType hashAlgorithm;
|
||||
CiString<128> issuerNameHash;
|
||||
CiString<128> issuerKeyHash;
|
||||
CiString<40> serialNumber;
|
||||
};
|
||||
/// \brief Conversion from a given CertificateHashDataType \p k to a given json object \p j
|
||||
void to_json(json& j, const CertificateHashDataType& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given CertificateHashDataType \p k
|
||||
void from_json(const json& j, CertificateHashDataType& k);
|
||||
|
||||
// \brief Writes the string representation of the given CertificateHashDataType \p k to the given output stream \p os
|
||||
/// \returns an output stream with the CertificateHashDataType written to
|
||||
std::ostream& operator<<(std::ostream& os, const CertificateHashDataType& k);
|
||||
|
||||
enum class CertificateType {
|
||||
V2GRootCertificate,
|
||||
MORootCertificate,
|
||||
CSMSRootCertificate,
|
||||
V2GCertificateChain,
|
||||
MFRootCertificate,
|
||||
OEMRootCertificate,
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given CertificateType \p e to human readable string
|
||||
/// \returns a string representation of the CertificateType
|
||||
std::string certificate_type_to_string(CertificateType e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to CertificateType
|
||||
/// \returns a CertificateType from a string representation
|
||||
CertificateType string_to_certificate_type(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given CertificateType \p certificate_type to
|
||||
/// the given output stream \p os \returns an output stream with the CertificateType written to
|
||||
std::ostream& operator<<(std::ostream& os, const CertificateType& certificate_type);
|
||||
|
||||
struct CertificateHashDataChain {
|
||||
CertificateHashDataType certificateHashData;
|
||||
CertificateType certificateType;
|
||||
std::optional<std::vector<CertificateHashDataType>> childCertificateHashData;
|
||||
};
|
||||
/// \brief Conversion from a given CertificateHashDataChain \p k to a given json object \p j
|
||||
void to_json(json& j, const CertificateHashDataChain& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given CertificateHashDataChain \p k
|
||||
void from_json(const json& j, CertificateHashDataChain& k);
|
||||
|
||||
// \brief Writes the string representation of the given CertificateHashDataChain \p k to the given output stream \p os
|
||||
/// \returns an output stream with the CertificateHashDataChain written to
|
||||
std::ostream& operator<<(std::ostream& os, const CertificateHashDataChain& k);
|
||||
|
||||
enum class OcppProtocolVersion {
|
||||
v16,
|
||||
v201,
|
||||
v21,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given OcppProtocolVersion \p e to human readable string
|
||||
/// \returns a string representation of the OcppProtocolVersion
|
||||
std::string ocpp_protocol_version_to_string(OcppProtocolVersion e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to OcppProtocolVersion
|
||||
/// \returns a OcppProtocolVersion from a string representation
|
||||
OcppProtocolVersion string_to_ocpp_protocol_version(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given OcppProtocolVersion \p
|
||||
/// ocpp_protocol_version to the given output stream \p os \returns an output stream with the
|
||||
/// OcppProtocolVersion written to
|
||||
std::ostream& operator<<(std::ostream& os, const OcppProtocolVersion& ocpp_protocol_version);
|
||||
|
||||
enum class CertificateSigningUseEnum {
|
||||
ChargingStationCertificate,
|
||||
V2GCertificate,
|
||||
ManufacturerCertificate,
|
||||
V2G20Certificate
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given CertificateSigningUseEnum \p e to human readable string
|
||||
/// \returns a string representation of the CertificateSigningUseEnum
|
||||
std::string certificate_signing_use_enum_to_string(CertificateSigningUseEnum e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to CertificateSigningUseEnum
|
||||
/// \returns a CertificateSigningUseEnum from a string representation
|
||||
CertificateSigningUseEnum string_to_certificate_signing_use_enum(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given CertificateSigningUseEnum \p certificate_signing_use_enum to
|
||||
/// the given output stream \p os \returns an output stream with the CertificateSigningUseEnum written to
|
||||
std::ostream& operator<<(std::ostream& os, const CertificateSigningUseEnum& certificate_signing_use_enum);
|
||||
|
||||
/// \brief Struct for OCSPRequestData
|
||||
struct OCSPRequestData {
|
||||
HashAlgorithmEnumType hashAlgorithm;
|
||||
std::string issuerNameHash;
|
||||
std::string issuerKeyHash;
|
||||
std::string serialNumber;
|
||||
std::string responderUrl;
|
||||
};
|
||||
|
||||
enum class GetCertificateSignRequestStatus {
|
||||
Accepted,
|
||||
InvalidRequestedType, ///< Requested a CSR for non CSMS/V2G leafs
|
||||
KeyGenError, ///< The key could not be generated with the requested/default parameters
|
||||
GenerationError, ///< Any other error when creating the CSR
|
||||
};
|
||||
|
||||
enum class GetCertificateInfoStatus {
|
||||
Accepted,
|
||||
Rejected,
|
||||
NotFound,
|
||||
NotFoundValid,
|
||||
PrivateKeyNotFound,
|
||||
};
|
||||
|
||||
struct GetCertificateSignRequestResult {
|
||||
GetCertificateSignRequestStatus status;
|
||||
std::optional<std::string> csr;
|
||||
};
|
||||
|
||||
struct CertificateOCSP {
|
||||
CertificateHashDataType hash;
|
||||
std::optional<fs::path> ocsp_path;
|
||||
};
|
||||
|
||||
struct CertificateInfo {
|
||||
std::optional<fs::path> certificate_path; // path to the full certificate chain
|
||||
std::optional<fs::path> certificate_single_path; // path to the single leaf certificate
|
||||
int certificate_count; // count of certs in the chain
|
||||
fs::path key_path; // path to private key of the leaf certificate
|
||||
std::optional<std::string> password; // optional password for the private key
|
||||
std::vector<CertificateOCSP> ocsp; // OCSP data if requested
|
||||
};
|
||||
|
||||
struct GetCertificateInfoResult {
|
||||
GetCertificateInfoStatus status = GetCertificateInfoStatus::Rejected;
|
||||
std::optional<CertificateInfo> info;
|
||||
};
|
||||
|
||||
enum class LeafCertificateType {
|
||||
CSMS, // Charging Station Management System
|
||||
V2G, // Vehicle to grid
|
||||
MF, // Manufacturer
|
||||
MO // Mobility Operator
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given bool \p b to a string representation of "true" or "false"
|
||||
/// \returns a string representation of the given bool
|
||||
std::string bool_to_string(bool b);
|
||||
|
||||
/// \brief Converts the given string \p s to a bool value. "true" is converted into true, anything else to false
|
||||
/// \returns a bool from the given string representation
|
||||
bool string_to_bool(const std::string& s);
|
||||
|
||||
/// \brief Converts the given double \p d to a string representation with the given \p precision
|
||||
/// \returns a string representation of the given double using the given precision
|
||||
std::string double_to_string(double d, int precision);
|
||||
|
||||
/// \brief Converts the given double \p d to a string representation with a fixed precision of 2
|
||||
/// \returns a string representation of the given double using a fixed precision of 2
|
||||
std::string double_to_string(double d);
|
||||
} // namespace conversions
|
||||
|
||||
enum class FirmwareStatusNotification {
|
||||
Downloaded,
|
||||
DownloadFailed,
|
||||
Downloading,
|
||||
DownloadScheduled,
|
||||
DownloadPaused,
|
||||
Idle,
|
||||
InstallationFailed,
|
||||
Installing,
|
||||
Installed,
|
||||
InstallRebooting,
|
||||
InstallScheduled,
|
||||
InstallVerificationFailed,
|
||||
InvalidSignature,
|
||||
SignatureVerified
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts GetCertificateSignRequestStatus to string
|
||||
std::string generate_certificate_signing_request_status_to_string(const GetCertificateSignRequestStatus status);
|
||||
} // namespace conversions
|
||||
|
||||
namespace conversions {
|
||||
|
||||
/// \brief Converts ocpp::FirmwareStatusNotification to v16::FirmwareStatus
|
||||
v16::FirmwareStatus firmware_status_notification_to_firmware_status(const FirmwareStatusNotification status);
|
||||
|
||||
/// \brief Converts ocpp::FirmwareStatusNotification to v16::FirmwareStatusEnumType
|
||||
v16::FirmwareStatusEnumType
|
||||
firmware_status_notification_to_firmware_status_enum_type(const FirmwareStatusNotification status);
|
||||
|
||||
} // namespace conversions
|
||||
|
||||
namespace security {
|
||||
// The security profiles defined in OCPP 2.0.1 resp. in the OCPP 1.6 security-whitepaper.
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class): used in implicit `switch`-comparisons to `int security_profile`
|
||||
enum SecurityProfile {
|
||||
OCPP_1_6_ONLY_UNSECURED_TRANSPORT_WITHOUT_BASIC_AUTHENTICATION = 0,
|
||||
UNSECURED_TRANSPORT_WITH_BASIC_AUTHENTICATION = 1,
|
||||
TLS_WITH_BASIC_AUTHENTICATION = 2,
|
||||
TLS_WITH_CLIENT_SIDE_CERTIFICATES = 3,
|
||||
};
|
||||
} // namespace security
|
||||
|
||||
namespace security_events {
|
||||
|
||||
// This is the list of security events defined in OCPP 2.0.1 (and the 1.6 security whitepper).
|
||||
// Security events that are marked critical should be pushed to the CSMS.
|
||||
// This is a non-exhaustive list of security events, when a security event matches the description in the OCPP
|
||||
// specification of one of the Security Events in this list, for interoperability reasons, the Security Event from this
|
||||
// list shall be used, instead of adding a new (proprietary) Security Event.
|
||||
|
||||
inline const std::string FIRMWARE_UPDATED = "FirmwareUpdated"; // CRITICAL
|
||||
inline const std::string FAILEDTOAUTHENTICATEATCSMS = "FailedToAuthenticateAtCsms";
|
||||
inline const std::string CSMSFAILEDTOAUTHENTICATE = "CsmsFailedToAuthenticate";
|
||||
inline const std::string CSRGENERATIONFAILED = "CSRGenerationFailed";
|
||||
inline const std::string SETTINGSYSTEMTIME = "SettingSystemTime"; // CRITICAL
|
||||
inline const std::string RESET_OR_REBOOT = "ResetOrReboot"; // CRITICAL
|
||||
inline const std::string STARTUP_OF_THE_DEVICE = "StartupOfTheDevice"; // CRITICAL
|
||||
inline const std::string SECURITYLOGWASCLEARED = "SecurityLogWasCleared"; // CRITICAL
|
||||
inline const std::string RECONFIGURATIONOFSECURITYPARAMETERS = "ReconfigurationOfSecurityParameters";
|
||||
inline const std::string MEMORYEXHAUSTION = "MemoryExhaustion"; // CRITICAL
|
||||
inline const std::string INVALIDMESSAGES = "InvalidMessages";
|
||||
inline const std::string ATTEMPTEDREPLAYATTACKS = "AttemptedReplayAttacks";
|
||||
inline const std::string TAMPERDETECTIONACTIVATED = "TamperDetectionActivated"; // CRITICAL
|
||||
inline const std::string INVALIDFIRMWARESIGNATURE = "InvalidFirmwareSignature";
|
||||
inline const std::string INVALIDFIRMWARESIGNINGCERTIFICATE = "InvalidFirmwareSigningCertificate";
|
||||
inline const std::string INVALIDCSMSCERTIFICATE = "InvalidCsmsCertificate";
|
||||
inline const std::string INVALIDCENTRALSYSTEMCERTIFICATE = "InvalidCentralSystemCertificate";
|
||||
inline const std::string INVALIDCHARGINGSTATIONCERTIFICATE = "InvalidChargingStationCertificate";
|
||||
inline const std::string INVALIDCHARGEPOINTCERTIFICATE = "InvalidChargePointCertificate"; // for OCPP1.6
|
||||
inline const std::string INVALIDTLSVERSION = "InvalidTLSVersion";
|
||||
inline const std::string INVALIDTLSCIPHERSUITE = "InvalidTLSCipherSuite";
|
||||
inline const std::string MAINTENANCELOGINACCEPTED = "MaintenanceLoginAccepted";
|
||||
inline const std::string MAINTENANCELOGINFAILED = "MaintenanceLoginFailed";
|
||||
} // namespace security_events
|
||||
|
||||
enum class MessageDirection {
|
||||
CSMSToChargingStation,
|
||||
ChargingStationToCSMS
|
||||
};
|
||||
|
||||
enum class ConnectionFailedReason {
|
||||
InvalidCSMSCertificate = 0,
|
||||
FailedToAuthenticateAtCsms
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Reason why a websocket closes its connection
|
||||
///
|
||||
enum class WebsocketCloseReason : uint8_t {
|
||||
/// Normal closure
|
||||
Normal = 1,
|
||||
ForceTcpDrop,
|
||||
GoingAway,
|
||||
AbnormalClose,
|
||||
ServiceRestart
|
||||
};
|
||||
|
||||
/// \brief This can be used to distinguish the different queue types
|
||||
enum class QueueType {
|
||||
Normal,
|
||||
Transaction,
|
||||
None,
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts GetCertificateSignRequestStatus to string
|
||||
std::string queue_type_to_string(const QueueType queue_type);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Struct containing default limits for amps, watts and number of phases
|
||||
struct CompositeScheduleDefaultLimits {
|
||||
std::int32_t amps;
|
||||
std::int32_t watts;
|
||||
std::int32_t number_phases;
|
||||
};
|
||||
|
||||
/// \brief Status of a reservation check.
|
||||
enum class ReservationCheckStatus {
|
||||
NotReserved, ///< @brief No reservation of this evse and / or id token
|
||||
ReservedForToken, ///< @brief Reservation for this token.
|
||||
ReservedForOtherToken, ///< @brief Reserved for other token and reservation has no parent token or parent token does
|
||||
///< not match.
|
||||
ReservedForOtherTokenAndHasParentToken, ///< @brief Reserved for other token but reservation has a parent token.
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_COMMON_UTILS_HPP
|
||||
#define OCPP_COMMON_UTILS_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
/// \brief Case insensitive compare for a case insensitive (Ci)String
|
||||
bool iequals(const std::string& lhs, const std::string rhs);
|
||||
|
||||
bool is_integer(const std::string& value);
|
||||
std::tuple<bool, int> is_positive_integer(const std::string& value);
|
||||
bool is_decimal_number(const std::string& value);
|
||||
|
||||
bool is_rfc3339_datetime(const std::string& value);
|
||||
bool is_boolean(const std::string& value);
|
||||
|
||||
bool is_equal(const float& value1, const float& value2, const double& epsilon = std::numeric_limits<double>::epsilon());
|
||||
bool is_equal(const double& value1, const double& value2,
|
||||
const double& epsilon = std::numeric_limits<double>::epsilon());
|
||||
|
||||
/// \brief True if \p v is empty, or holds a value that is not NaN and not +/-Inf.
|
||||
bool is_finite_or_unset(const std::optional<float>& v);
|
||||
|
||||
///
|
||||
/// \brief Split string on a given character.
|
||||
/// \param string_to_split The string to split.
|
||||
/// \param c The character to split the string on.
|
||||
/// \param trim True if all strings must be trimmed as well. Defaults to 'false'.
|
||||
/// \return A vector with the string 'segments'.
|
||||
///
|
||||
std::vector<std::string> split_string(const std::string& string_to_split, const char c, const bool trim = false);
|
||||
|
||||
///
|
||||
/// \brief Trim string, removing leading and trailing white spaces.
|
||||
/// \param string_to_trim The string to trim.
|
||||
/// \return The trimmed string.
|
||||
///
|
||||
std::string trim_string(const std::string& string_to_trim);
|
||||
|
||||
///
|
||||
/// \brief Clamp the value to the maximum value of the given type
|
||||
/// \param len The value to clamp
|
||||
/// \return The clamped value
|
||||
template <typename T, typename U> T constexpr clamp_to(U len) {
|
||||
return (len <= std::numeric_limits<T>::max()) ? static_cast<T>(len) : std::numeric_limits<T>::max();
|
||||
}
|
||||
|
||||
std::size_t convert_to_positive_size_t(float value);
|
||||
} // namespace ocpp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_WEBSOCKET_HPP
|
||||
#define OCPP_WEBSOCKET_HPP
|
||||
|
||||
#include <ocpp/common/evse_security.hpp>
|
||||
#include <ocpp/common/ocpp_logging.hpp>
|
||||
|
||||
#include <ocpp/common/websocket/websocket_base.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
///
|
||||
/// \brief contains a websocket abstraction that can connect to TLS and non-TLS websocket endpoints
|
||||
///
|
||||
class Websocket {
|
||||
private:
|
||||
// unique_ptr holds address of base - requires WebSocketBase to have a virtual destructor
|
||||
std::unique_ptr<WebsocketBase> websocket;
|
||||
std::function<void(OcppProtocolVersion protocol)> connected_callback;
|
||||
std::function<void()> disconnected_callback;
|
||||
std::function<void(const WebsocketCloseReason reason)> stopped_connecting_callback;
|
||||
std::function<void(const std::string& message)> message_callback;
|
||||
std::shared_ptr<MessageLogging> logging;
|
||||
|
||||
public:
|
||||
/// \brief Creates a new Websocket object with the provided \p connection_options
|
||||
explicit Websocket(const WebsocketConnectionOptions& connection_options,
|
||||
std::shared_ptr<EvseSecurity> evse_security, std::shared_ptr<MessageLogging> logging);
|
||||
~Websocket() = default;
|
||||
|
||||
/// \brief Starts the connection attempts. It will init the websocket processing thread
|
||||
/// \returns true if the websocket is successfully initialized, false otherwise. Does
|
||||
/// not wait for a successful connection
|
||||
bool start_connecting();
|
||||
|
||||
void set_connection_options(const WebsocketConnectionOptions& connection_options);
|
||||
|
||||
/// \brief disconnect the websocket
|
||||
void disconnect(const WebsocketCloseReason code);
|
||||
|
||||
// \brief reconnects the websocket after the delay
|
||||
void reconnect(long delay);
|
||||
|
||||
/// \brief indicates if the websocket is connected
|
||||
bool is_connected();
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket is connected successfully
|
||||
void register_connected_callback(const std::function<void(OcppProtocolVersion protocol)>& callback);
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket connection is disconnected
|
||||
void register_disconnected_callback(const std::function<void()>& callback);
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket connection has been stopped and will not attempt
|
||||
/// to reconnect
|
||||
void register_stopped_connecting_callback(const std::function<void(const WebsocketCloseReason)>& callback);
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket receives a message
|
||||
void register_message_callback(const std::function<void(const std::string& message)>& callback);
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket could not connect with a specific reason
|
||||
void register_connection_failed_callback(const std::function<void(ConnectionFailedReason)>& callback);
|
||||
|
||||
/// \brief send a \p message over the websocket
|
||||
/// \returns true if the message was sent successfully
|
||||
bool send(const std::string& message);
|
||||
|
||||
/// \brief set the websocket ping interval \p ping_interval_s in seconds and pong timeout \p pong_interval_s in
|
||||
/// seconds
|
||||
void set_websocket_ping_interval(std::int32_t ping_interval_s, std::int32_t pong_interval_s);
|
||||
|
||||
/// \brief set the \p authorization_key of the connection_options
|
||||
void set_authorization_key(const std::string& authorization_key);
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
#endif // OCPP_WEBSOCKET_HPP
|
||||
@@ -0,0 +1,148 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_WEBSOCKET_BASE_HPP
|
||||
#define OCPP_WEBSOCKET_BASE_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
|
||||
#include <everest/timer.hpp>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/common/websocket/websocket_uri.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
struct WebsocketConnectionOptions {
|
||||
std::vector<OcppProtocolVersion> ocpp_versions; // List of allowed protocols ordered by preference
|
||||
Uri csms_uri; // the URI of the CSMS
|
||||
int security_profile; // FIXME: change type to `SecurityProfile`
|
||||
std::optional<std::string> authorization_key;
|
||||
std::chrono::milliseconds message_timeout;
|
||||
int retry_backoff_random_range_s;
|
||||
int retry_backoff_repeat_times;
|
||||
int retry_backoff_wait_minimum_s;
|
||||
int max_connection_attempts;
|
||||
std::string supported_ciphers_12;
|
||||
std::string supported_ciphers_13;
|
||||
int ping_interval_s;
|
||||
std::string ping_payload;
|
||||
int pong_timeout_s;
|
||||
bool use_ssl_default_verify_paths;
|
||||
std::optional<bool> additional_root_certificate_check;
|
||||
std::optional<std::string> hostName;
|
||||
bool verify_csms_common_name;
|
||||
bool use_tpm_tls;
|
||||
bool verify_csms_allow_wildcards;
|
||||
std::optional<std::string> iface; // Optional interface where the socket is created. Only usable for libwebsocket
|
||||
bool enable_tls_keylog = false; ///< If set to true enables logging of TLS secrets to the keylog_file
|
||||
std::optional<std::filesystem::path> keylog_file; ///< Optional path to a keylog file
|
||||
std::optional<std::string> everest_version;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief contains a websocket abstraction
|
||||
///
|
||||
class WebsocketBase {
|
||||
protected:
|
||||
std::atomic_bool m_is_connected;
|
||||
WebsocketConnectionOptions connection_options;
|
||||
std::function<void(OcppProtocolVersion protocol)> connected_callback;
|
||||
std::function<void()> disconnected_callback;
|
||||
std::function<void(const WebsocketCloseReason reason)> stopped_connecting_callback;
|
||||
std::function<void(const std::string& message)> message_callback;
|
||||
std::function<void(ConnectionFailedReason)> connection_failed_callback;
|
||||
std::shared_ptr<boost::asio::steady_timer> reconnect_timer;
|
||||
std::unique_ptr<Everest::SteadyTimer> ping_timer;
|
||||
std::atomic_bool ping_cleared;
|
||||
std::int32_t ping_elapsed_s;
|
||||
std::int32_t pong_elapsed_s;
|
||||
std::mutex reconnect_mutex;
|
||||
std::mutex connection_mutex;
|
||||
std::atomic_int reconnect_backoff_ms;
|
||||
std::atomic_int connection_attempts;
|
||||
std::atomic_bool shutting_down;
|
||||
|
||||
/// \brief Indicates if the required callbacks are registered
|
||||
/// \returns true if the websocket is properly initialized
|
||||
bool initialized();
|
||||
|
||||
/// \brief getter for authorization header for connection with basic authentication
|
||||
std::optional<std::string> getAuthorizationHeader();
|
||||
|
||||
/// \brief Logs websocket connection error
|
||||
static void log_on_fail(const std::error_code& ec, const boost::system::error_code& transport_ec,
|
||||
const int http_status);
|
||||
|
||||
/// \brief Calculates and returns the reconnect interval based on int retry_backoff_random_range_s,
|
||||
/// retry_backoff_repeat_times, int retry_backoff_wait_minimum_s of the WebsocketConnectionOptions
|
||||
long get_reconnect_interval();
|
||||
|
||||
// \brief cancels the reconnect timer
|
||||
void cancel_reconnect_timer();
|
||||
|
||||
/// \brief send a websocket ping
|
||||
virtual void ping() = 0;
|
||||
|
||||
/// \brief Called when a websocket pong timeout is received
|
||||
void on_pong_timeout(std::string msg);
|
||||
|
||||
public:
|
||||
/// \brief Creates a new WebsocketBase object. The `connection_options` must be initialised with
|
||||
/// `set_connection_options()`
|
||||
explicit WebsocketBase();
|
||||
virtual ~WebsocketBase();
|
||||
|
||||
/// \brief Starts the connection attempts. It will init the websocket processing thread
|
||||
/// \returns true if the websocket is successfully initialized, false otherwise. Does
|
||||
/// not wait for a successful connection
|
||||
virtual bool start_connecting() = 0;
|
||||
|
||||
/// \brief sets this connection_options to the given \p connection_options and resets the connection_attempts
|
||||
virtual void set_connection_options(const WebsocketConnectionOptions& connection_options) = 0;
|
||||
void set_connection_options_base(const WebsocketConnectionOptions& connection_options);
|
||||
|
||||
/// \brief reconnect the websocket after the delay
|
||||
virtual void reconnect(long delay) = 0;
|
||||
|
||||
/// \brief disconnect the websocket
|
||||
void disconnect(const WebsocketCloseReason code);
|
||||
|
||||
/// \brief indicates if the websocket is connected
|
||||
bool is_connected();
|
||||
|
||||
/// \brief closes the websocket
|
||||
virtual void close(const WebsocketCloseReason code, const std::string& reason) = 0;
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket is connected successfully
|
||||
void register_connected_callback(const std::function<void(OcppProtocolVersion protocol)>& callback);
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket connection is disconnected
|
||||
void register_disconnected_callback(const std::function<void()>& callback);
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket connection has been closed and will not attempt
|
||||
/// to reconnect
|
||||
void register_stopped_connecting_callback(const std::function<void(const WebsocketCloseReason reason)>& callback);
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket receives a message
|
||||
void register_message_callback(const std::function<void(const std::string& message)>& callback);
|
||||
|
||||
/// \brief register a \p callback that is called when the websocket could not connect with a specific reason
|
||||
void register_connection_failed_callback(const std::function<void(ConnectionFailedReason)>& callback);
|
||||
|
||||
/// \brief send a \p message over the websocket
|
||||
/// \returns true if the message was sent successfully
|
||||
virtual bool send(const std::string& message) = 0;
|
||||
|
||||
/// \brief starts a timer that sends a websocket ping at the given \p ping_interval_s and
|
||||
/// waits for a pong response in \p pong_timeout_s
|
||||
void set_websocket_ping_interval(std::int32_t ping_interval_s, std::int32_t pong_timeout_s);
|
||||
|
||||
/// \brief set the \p authorization_key of the connection_options
|
||||
void set_authorization_key(const std::string& authorization_key);
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
#endif // OCPP_WEBSOCKET_BASE_HPP
|
||||
@@ -0,0 +1,121 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_WEBSOCKET_TLS_TPM_HPP
|
||||
#define OCPP_WEBSOCKET_TLS_TPM_HPP
|
||||
|
||||
#include <ocpp/common/evse_security.hpp>
|
||||
#include <ocpp/common/safe_queue.hpp>
|
||||
#include <ocpp/common/websocket/websocket_base.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
struct ssl_ctx_st;
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
struct ConnectionData;
|
||||
struct WebsocketMessage;
|
||||
|
||||
/// \brief Experimental libwebsockets TLS connection
|
||||
class WebsocketLibwebsockets final : public WebsocketBase {
|
||||
public:
|
||||
/// \brief Creates a new Websocket object with the providede \p connection_options
|
||||
explicit WebsocketLibwebsockets(const WebsocketConnectionOptions& connection_options,
|
||||
std::shared_ptr<EvseSecurity> evse_security);
|
||||
|
||||
~WebsocketLibwebsockets() override;
|
||||
|
||||
void set_connection_options(const WebsocketConnectionOptions& connection_options) override;
|
||||
|
||||
bool start_connecting() override;
|
||||
|
||||
void reconnect(long delay) override;
|
||||
|
||||
void close(const WebsocketCloseReason code, const std::string& reason) override;
|
||||
|
||||
bool send(const std::string& message) override;
|
||||
|
||||
void ping() override;
|
||||
|
||||
/// \brief Indicates if the websocket has a valid connection data and is trying to
|
||||
/// connect/reconnect internally even if for the moment it might not be connected
|
||||
/// \return True if the websocket is connected or trying to connect, false otherwise
|
||||
bool is_trying_to_connect();
|
||||
|
||||
int process_callback(void* wsi_ptr, int callback_reason, void* user, void* in, size_t len);
|
||||
|
||||
private:
|
||||
bool is_trying_to_connect_internal();
|
||||
void close_internal(const WebsocketCloseReason code, const std::string& reason);
|
||||
|
||||
/// \brief Initializes the connection options, including the security info
|
||||
/// \return True if it was successful, false otherwise
|
||||
bool initialize_connection_options(std::shared_ptr<ConnectionData>& new_connection_data);
|
||||
|
||||
bool tls_init(struct ssl_ctx_st* ctx, const std::string& path_chain, const std::string& path_key,
|
||||
std::optional<std::string>& password);
|
||||
|
||||
/// \brief Websocket processing thread loop
|
||||
void thread_websocket_client_loop(std::shared_ptr<ConnectionData> local_data);
|
||||
|
||||
/// \brief Function to handle received messages. Required since from the received message
|
||||
/// callback we also send messages that must block and wait on the client thread
|
||||
void thread_websocket_message_recv_loop(std::shared_ptr<ConnectionData> local_data);
|
||||
|
||||
/// \brief Function to handle the deferred callbacks
|
||||
void thread_deferred_callback_queue();
|
||||
|
||||
/// \brief Called when a TLS websocket connection is established, calls the connected callback
|
||||
void on_conn_connected(ConnectionData* conn_data);
|
||||
|
||||
/// \brief Called when a TLS websocket connection is closed
|
||||
void on_conn_close(ConnectionData* conn_data);
|
||||
|
||||
/// \brief Called when a TLS websocket connection fails to be established
|
||||
void on_conn_fail(ConnectionData* conn_data);
|
||||
|
||||
/// \brief When the connection can send data
|
||||
void on_conn_writable();
|
||||
|
||||
/// \brief Called when a message is received over the TLS websocket, calls the message callback
|
||||
void on_conn_message(std::string&& message);
|
||||
|
||||
/// \brief Requests a message write, awakes the websocket loop from 'poll'
|
||||
void request_write();
|
||||
|
||||
void poll_message(const std::shared_ptr<WebsocketMessage>& msg);
|
||||
|
||||
/// \brief Add a callback to the queue of callbacks to be executed. All will be executed from a single thread
|
||||
void push_deferred_callback(const std::function<void()>& callback);
|
||||
|
||||
// \brief Safely closes the already running connection threads
|
||||
void safe_close_threads();
|
||||
|
||||
/// \brief Clears all messages and message queues both incoming and outgoing
|
||||
void clear_all_queues();
|
||||
|
||||
std::shared_ptr<EvseSecurity> evse_security;
|
||||
|
||||
// Connection related data
|
||||
Everest::SteadyTimer reconnect_timer_tpm;
|
||||
std::unique_ptr<std::thread> websocket_thread;
|
||||
std::shared_ptr<ConnectionData> conn_data;
|
||||
|
||||
// Queue of outgoing messages, notify thread only when we remove messages
|
||||
SafeQueue<std::shared_ptr<WebsocketMessage>> message_queue;
|
||||
|
||||
std::unique_ptr<std::thread> recv_message_thread;
|
||||
SafeQueue<std::string> recv_message_queue;
|
||||
std::string recv_buffered_message;
|
||||
|
||||
std::unique_ptr<std::thread> deferred_callback_thread;
|
||||
SafeQueue<std::function<void()>> deferred_callback_queue;
|
||||
std::atomic_bool stop_deferred_handler;
|
||||
|
||||
OcppProtocolVersion connected_ocpp_version;
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
#endif // OCPP_WEBSOCKET_HPP
|
||||
@@ -0,0 +1,83 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_WEBSOCKET_URI_HPP
|
||||
#define OCPP_WEBSOCKET_URI_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include <websocketpp_utils/uri.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
using ev_uri = ocpp::uri;
|
||||
class Uri {
|
||||
public:
|
||||
Uri() = default;
|
||||
|
||||
// clang-format off
|
||||
/// \brief parse_and_validate parses the \p uri and checks
|
||||
/// 1. the general validity of it and
|
||||
/// 2. if optional scheme fits to given \p security_profile
|
||||
///
|
||||
/// \param uri The whole URI with optional scheme and \p chargepoint_id as last segment (as backward-compatibility).
|
||||
/// \param chargepoint_id The identifier unique to the CSMS.
|
||||
/// \param security_profile The security-profile.
|
||||
/// \returns Uri
|
||||
/// \throws std::invalid_argument for several checks
|
||||
// clang-format on
|
||||
static Uri parse_and_validate(std::string uri, std::string chargepoint_id, int security_profile);
|
||||
|
||||
/// \brief set_secure defines if the connection is done via TLS
|
||||
///
|
||||
/// \param secure true: connect via TLS; false: connect as plaintext
|
||||
void set_secure(bool secure) {
|
||||
this->secure = secure;
|
||||
}
|
||||
|
||||
std::string get_hostname() {
|
||||
return this->host;
|
||||
}
|
||||
std::string get_chargepoint_id() {
|
||||
return this->chargepoint_id;
|
||||
}
|
||||
|
||||
std::string get_path() {
|
||||
return this->path_without_chargepoint_id;
|
||||
}
|
||||
|
||||
uint16_t get_port() const {
|
||||
return this->port;
|
||||
}
|
||||
|
||||
std::string string() {
|
||||
auto uri = get_websocketpp_uri();
|
||||
return uri.str();
|
||||
}
|
||||
|
||||
ev_uri get_websocketpp_uri() { // FIXME: wrap needed `websocketpp:uri` functionality inside `Uri`
|
||||
return ev_uri(this->secure, this->host, this->port,
|
||||
this->path_without_chargepoint_id /* is normalized with ending slash */ + this->chargepoint_id);
|
||||
}
|
||||
|
||||
private:
|
||||
Uri(bool secure, const std::string& host, uint16_t port, const std::string& path_without_chargepoint_id,
|
||||
const std::string& chargepoint_id) :
|
||||
secure(secure),
|
||||
host(host),
|
||||
port(port),
|
||||
path_without_chargepoint_id(path_without_chargepoint_id),
|
||||
chargepoint_id(chargepoint_id) {
|
||||
}
|
||||
|
||||
bool secure = false;
|
||||
std::string host;
|
||||
uint16_t port = 0;
|
||||
std::string path_without_chargepoint_id;
|
||||
std::string chargepoint_id;
|
||||
};
|
||||
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_WEBSOCKET_URI_HPP */
|
||||
@@ -0,0 +1,663 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2026 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_V16_CHARGE_POINT_HPP
|
||||
#define OCPP_V16_CHARGE_POINT_HPP
|
||||
|
||||
#include <ocpp/common/cistring.hpp>
|
||||
#include <ocpp/common/evse_security.hpp>
|
||||
#include <ocpp/common/evse_security_impl.hpp>
|
||||
#include <ocpp/common/support_older_cpp_versions.hpp>
|
||||
#include <ocpp/v16/charge_point_configuration_interface.hpp>
|
||||
#include <ocpp/v16/charge_point_state_machine.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
#include <ocpp/v16/smart_charging.hpp>
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
#include <ocpp/v16/messages/BootNotification.hpp>
|
||||
#include <ocpp/v16/messages/DataTransfer.hpp>
|
||||
#include <ocpp/v16/messages/GetConfiguration.hpp>
|
||||
#include <ocpp/v16/messages/GetDiagnostics.hpp>
|
||||
#include <ocpp/v16/messages/GetLog.hpp>
|
||||
#include <ocpp/v16/messages/SignedUpdateFirmware.hpp>
|
||||
#include <ocpp/v16/messages/UpdateFirmware.hpp>
|
||||
|
||||
// for OCPP1.6 PnC
|
||||
#include "ocpp/v16/messages/ChangeAvailability.hpp"
|
||||
#include <ocpp/v2/messages/Authorize.hpp>
|
||||
#include <ocpp/v2/messages/CertificateSigned.hpp>
|
||||
#include <ocpp/v2/messages/DeleteCertificate.hpp>
|
||||
#include <ocpp/v2/messages/Get15118EVCertificate.hpp>
|
||||
#include <ocpp/v2/messages/GetCertificateStatus.hpp>
|
||||
#include <ocpp/v2/messages/GetInstalledCertificateIds.hpp>
|
||||
#include <ocpp/v2/messages/InstallCertificate.hpp>
|
||||
#include <ocpp/v2/messages/SignCertificate.hpp>
|
||||
#include <ocpp/v2/messages/TriggerMessage.hpp>
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
class ChargePointImpl;
|
||||
|
||||
/// \brief Contains a ChargePoint implementation compatible with OCPP-J 1.6
|
||||
class ChargePoint {
|
||||
private:
|
||||
std::unique_ptr<ChargePointImpl> charge_point;
|
||||
|
||||
/// \addtogroup chargepoint_constructors Chargepoint constructors
|
||||
/// Constructors for chargepoint, 1.6 and 2.0.1
|
||||
/// @{
|
||||
|
||||
/// @name Constructors for 1.6
|
||||
/// @{
|
||||
|
||||
public:
|
||||
/// \brief The main entrypoint for libOCPP for OCPP 1.6
|
||||
/// \param cfg a reference to the configuration provider
|
||||
/// \param share_path This path contains the following files and directories and is installed by the libocpp install
|
||||
/// target
|
||||
/// \param database_path this points to the location of the sqlite database that libocpp uses to keep track of
|
||||
/// connector availability, the authorization cache and auth list, charging profiles and transaction data
|
||||
/// \param sql_init_path this points to the init.sql file which contains the database schema used by libocpp for its
|
||||
/// sqlite database
|
||||
/// \param message_log_path this points to the directory in which libocpp can put OCPP communication logfiles for
|
||||
/// debugging purposes. This behavior can be controlled by the "LogMessages" (set to true by default) and
|
||||
/// "LogMessagesFormat" (set to ["log", "html", "session_logging"] by default, "console" and "console_detailed" are
|
||||
/// also available) configuration keys in the "Internal" section of the config file. Please note that this is
|
||||
/// intended for debugging purposes only as it logs all communication, including authentication messages.
|
||||
/// \param evse_security Pointer to evse_security that manages security related operations; if nullptr
|
||||
/// security_configuration must be set
|
||||
/// \param security_configuration specifies the file paths that are required to set up the internal evse_security
|
||||
/// implementation
|
||||
/// \param message_callback A callback that will get all OCPP messages sent or received to/from the CSMS
|
||||
explicit ChargePoint(
|
||||
ChargePointConfigurationInterface& cfg, const fs::path& share_path, const fs::path& database_path,
|
||||
const fs::path& sql_init_path, const fs::path& message_log_path,
|
||||
const std::shared_ptr<EvseSecurity> evse_security,
|
||||
const std::optional<SecurityConfiguration> security_configuration = std::nullopt,
|
||||
const std::function<void(const std::string& message, MessageDirection direction)>& message_callback = nullptr);
|
||||
|
||||
virtual ~ChargePoint();
|
||||
|
||||
/// @} // End constructors 1.6 group
|
||||
/// @} // End chargepoint constructors topic
|
||||
|
||||
/// \brief Allow to update the ChargePoint core information which will be sent in BootNotification.req
|
||||
/// While `vendor` and `model` strings are both required, all other values are optional.
|
||||
/// Passing `std::nullopt` keeps the current existing value, i.e. does not touch the current
|
||||
/// value at all, other strings replace the corresponding current value.
|
||||
void update_chargepoint_information(const std::string& vendor, const std::string& model,
|
||||
const std::optional<std::string>& serialnumber,
|
||||
const std::optional<std::string>& chargebox_serialnumber,
|
||||
const std::optional<std::string>& firmware_version);
|
||||
|
||||
/// \brief Allow to update the ChargePoint's modem information which will be sent in BootNotification.req
|
||||
/// Passing `std::nullopt` keeps the current existing value, i.e. does not touch the current value at all.
|
||||
/// Passing other strings replace the corresponding current value.
|
||||
void update_modem_information(const std::optional<std::string>& iccid, const std::optional<std::string>& imsi);
|
||||
|
||||
/// \brief Allow to update the ChargePoint's meter information which will be sent in BootNotification.req
|
||||
/// Passing `std::nullopt` keeps the current existing value, i.e. does not touch the current value at all,
|
||||
/// other strings replace the corresponding current value.
|
||||
void update_meter_information(const std::optional<std::string>& meter_serialnumber,
|
||||
const std::optional<std::string>& meter_type);
|
||||
|
||||
/// \brief Initializes the ChargePoint and all of it's connectors, the state machine and message queue. This method
|
||||
/// should be called if a more granular start of the process is necessary. Notably if it is necessary for the state
|
||||
/// machine and the connectors (and their statuses) need to be updated prior to initiating connection with the CSMS.
|
||||
/// \param connector_status_map initial state of connectors including connector 0 with reduced set of states
|
||||
/// (Available, Unavailable, Faulted)
|
||||
/// \param resuming_session_ids can optionally contain active session ids from previous executions. If empty and
|
||||
/// libocpp has transactions in its internal database that have not been stopped yet, calling this function will
|
||||
/// initiate a StopTransaction.req for those transactions. If this vector contains session_ids this function will
|
||||
/// not stop transactions with this session_id even in case it has an internal database entry for this session and
|
||||
/// it hasnt been stopped yet. Its ignored if this vector contains session_ids that are unknown to libocpp.
|
||||
/// \return
|
||||
bool init(const std::map<int, ChargePointStatus>& connector_status_map = {},
|
||||
const std::set<std::string>& resuming_session_ids = {});
|
||||
|
||||
/// \brief Starts the ChargePoint, initializes and connects to the Websocket endpoint and initializes a
|
||||
/// BootNotification.req
|
||||
/// \param connector_status_map initial state of connectors including connector 0 with reduced set of states
|
||||
/// (Available, Unavailable, Faulted). connector_status_map is empty, last availability states from the persistant
|
||||
/// storage will be used
|
||||
/// \param bootreason reason for calling the start function
|
||||
/// \param resuming_session_ids can optionally contain active session ids from previous executions. If empty and
|
||||
/// libocpp has transactions in its internal database that have not been stopped yet, calling this function will
|
||||
/// initiate a StopTransaction.req for those transactions. If this vector contains session_ids this function will
|
||||
/// not stop transactions with this session_id even in case it has an internal database entry for this session and
|
||||
/// it hasnt been stopped yet. Its ignored if this vector contains session_ids that are unknown to libocpp.
|
||||
/// \return
|
||||
bool start(const std::map<int, ChargePointStatus>& connector_status_map = {},
|
||||
BootReasonEnum bootreason = BootReasonEnum::PowerUp,
|
||||
const std::set<std::string>& resuming_session_ids = {});
|
||||
|
||||
/// \brief Restarts the ChargePoint if it has been stopped before. The ChargePoint is reinitialized, connects to the
|
||||
/// websocket and starts to communicate OCPP messages again
|
||||
/// \param connector_status_map initial state of connectors including connector 0 with reduced set of states
|
||||
/// (Available, Unavailable, Faulted). connector_status_map is empty, last availability states from the persistant
|
||||
/// storage will be used
|
||||
/// \param bootreason reason for calling the start function
|
||||
bool restart(const std::map<int, ChargePointStatus>& connector_status_map = {},
|
||||
BootReasonEnum bootreason = BootReasonEnum::ApplicationReset);
|
||||
|
||||
// \brief Resets the internal state machine for the connectors using the given \p connector_status_map
|
||||
/// \param connector_status_map state of connectors including connector 0 with reduced set of states (Available,
|
||||
/// Unavailable, Faulted)
|
||||
void reset_state_machine(const std::map<int, ChargePointStatus>& connector_status_map);
|
||||
|
||||
/// \brief Stops the ChargePoint, stops timers, transactions and the message queue and disconnects from the
|
||||
/// websocket
|
||||
bool stop();
|
||||
|
||||
/// \brief Initializes the websocket and connects to CSMS if it is not yet connected
|
||||
void connect_websocket();
|
||||
|
||||
/// \brief Disconnects the the websocket connection to the CSMS if it is connected
|
||||
void disconnect_websocket();
|
||||
|
||||
/// \brief Calls the set_connection_timeout_callback that can be registered. This function is used to notify an
|
||||
/// Authorization mechanism about a changed ConnectionTimeout configuration key.
|
||||
void call_set_connection_timeout();
|
||||
|
||||
// public API for Core profile
|
||||
|
||||
/// \brief Authorizes the provided \p id_token against the central system, LocalAuthorizationList or
|
||||
/// AuthorizationCache depending on the values of the ConfigurationKeys LocalPreAuthorize, LocalAuthorizeOffline,
|
||||
/// LocalAuthListEnabled and AuthorizationCacheEnabled
|
||||
/// \returns the EnhancedIdTagInfo that contains the result of the authorization and an optional tarriff message
|
||||
EnhancedIdTagInfo authorize_id_token(CiString<20> id_token);
|
||||
|
||||
// for plug&charge 1.6 whitepaper
|
||||
|
||||
/// \brief Uses data_transfer mechanism to authorize given \p emaid , \p certificate and
|
||||
/// \p iso15118_certificate_hash_data locally or by requesting authorzation at CSMS. This function can be called
|
||||
/// when the authorization mechanism Plug&Charge is specified as part of the ISO15118 PaymentDetailsRequest
|
||||
/// \param emaid
|
||||
/// \param certificate contract certificate that the EVCC provides
|
||||
/// \param iso15118_certificate_hash_data
|
||||
/// \return
|
||||
ocpp::v2::AuthorizeResponse data_transfer_pnc_authorize(
|
||||
const std::string& emaid, const std::optional<std::string>& certificate,
|
||||
const std::optional<std::vector<ocpp::v2::OCSPRequestData>>& iso15118_certificate_hash_data);
|
||||
|
||||
/// \brief Uses data transfer mechanism to get 15118 ev certificate from CSMS. This function can be called when the
|
||||
/// EVCC requests the update or installation of a contract certificate as part of the ISO15118
|
||||
/// CertificateInstallRequest or CertificateUpdateRequest
|
||||
/// \param connector_id
|
||||
/// \param exi_request provided by the EVCC
|
||||
/// \param iso15118_schema_version provided by the EVCC
|
||||
/// \param certificate_action Install or Update
|
||||
void data_transfer_pnc_get_15118_ev_certificate(const std::int32_t connector_id, const std::string& exi_request,
|
||||
const std::string& iso15118_schema_version,
|
||||
const ocpp::v2::CertificateActionEnum& certificate_action);
|
||||
|
||||
/// \brief Allows the exchange of arbitrary \p data identified by a \p vendorId and \p messageId with a central
|
||||
/// system \returns the DataTransferResponse
|
||||
/// \param vendorId
|
||||
/// \param messageId
|
||||
/// \param data
|
||||
/// \return the DataTransferResponse from the CSMS. In case no response is received from the CSMS because the
|
||||
/// message timed out or the charging station is offline, std::nullopt is returned
|
||||
std::optional<DataTransferResponse> data_transfer(const CiString<255>& vendorId,
|
||||
const std::optional<CiString<50>>& messageId,
|
||||
const std::optional<std::string>& data);
|
||||
|
||||
/// \brief Calculates ChargingProfiles configured by the CSMS of all connectors from now until now + given \p
|
||||
/// duration_s and the given \p unit
|
||||
/// \param duration_s
|
||||
/// \param unit defaults to A
|
||||
/// \return ChargingSchedules of all connectors
|
||||
std::map<std::int32_t, ChargingSchedule>
|
||||
get_all_composite_charging_schedules(const std::int32_t duration_s,
|
||||
const ChargingRateUnit unit = ChargingRateUnit::A);
|
||||
|
||||
/// \brief Calculates EnhancedChargingSchedule(s) configured by the CSMS of all connectors from now until now +
|
||||
/// given \p duration_s and the given \p unit . EnhancedChargingSchedules contain EnhancedChargingSchedulePeriod(s)
|
||||
/// that are enhanced by the stackLevel that was provided for the ChargingProfile
|
||||
/// \param duration_s
|
||||
/// \param unit defaults to A
|
||||
/// \return ChargingSchedules of all connectors
|
||||
std::map<std::int32_t, EnhancedChargingSchedule>
|
||||
get_all_enhanced_composite_charging_schedules(const std::int32_t duration_s,
|
||||
const ChargingRateUnit unit = ChargingRateUnit::A);
|
||||
|
||||
/// \addtogroup ocpp16_handlers OCPP 1.6 handlers
|
||||
/// Handlers that can be called from the implementing class.
|
||||
/// @{
|
||||
|
||||
/// @name Handlers
|
||||
/// The handlers
|
||||
/// @{
|
||||
|
||||
/// \brief Stores the given \p powermeter values for the given \p connector . This function can be called when a new
|
||||
/// meter value is present.
|
||||
/// \param connector
|
||||
/// \param measurement structure that can contain all kinds of measurands
|
||||
void on_meter_values(std::int32_t connector, const Measurement& measurement);
|
||||
|
||||
/// \brief Stores the given \p max_current for the given \p connector offered to the EV. This function can be called
|
||||
/// when the value for the maximum current for the connector changes. It will be used to report the Measurand
|
||||
/// Current_Offered if it is configured
|
||||
/// \param connector
|
||||
/// \param max_current in Amps
|
||||
void on_max_current_offered(std::int32_t connector, std::int32_t max_current);
|
||||
|
||||
/// \brief Stores the given \p max_power for the given \p connector offered to the EV. This function can be called
|
||||
/// when the value for the maximum power for the connector changes. It will be used to report the Measurand
|
||||
/// Power_Offered if it is configured
|
||||
/// \param connector
|
||||
/// \param max_power in Watts
|
||||
void on_max_power_offered(std::int32_t connector, std::int32_t max_power);
|
||||
|
||||
/// \brief Notifies chargepoint that a new session with the given \p session_id has been started at the given \p
|
||||
/// connector with the given \p reason . The logs of the session will be written into \p session_logging_path if
|
||||
/// present. This function must be called when first interaction with user or EV occurs. This can be a valid
|
||||
/// authorization or the connection of cable and/or EV to the given \p connector
|
||||
/// \param connector
|
||||
/// \param session_id unique id of the session
|
||||
/// \param reason for the initiation of the session
|
||||
/// \param session_logging_path optional filesystem path to where the session log should be written
|
||||
void on_session_started(std::int32_t connector, const std::string& session_id, const SessionStartedReason reason,
|
||||
const std::optional<std::string>& session_logging_path);
|
||||
|
||||
/// \brief Notifies chargepoint that a session has been stopped at the given \p connector. This function must be
|
||||
/// called when the EV disconnects from the given \p connector .
|
||||
/// \param connector
|
||||
/// \param session_id
|
||||
void on_session_stopped(std::int32_t connector, const std::string& session_id);
|
||||
|
||||
/// \brief Notifies chargepoint that a transaction at the given \p connector with the given parameters has been
|
||||
/// started. This function must be called at the point that all conditions for charging are met, for instance, EV is
|
||||
/// connected to Charge Point and user has been authorized.
|
||||
/// \param connector
|
||||
/// \param session_id
|
||||
/// \param id_token that has been used to authorize the transaction
|
||||
/// \param meter_start start meter value in Wh
|
||||
/// \param reservation_id
|
||||
/// \param timestamp of the start of transaction
|
||||
/// \param signed_meter_value e.g. in OCMF format
|
||||
void on_transaction_started(const std::int32_t& connector, const std::string& session_id,
|
||||
const std::string& id_token, const double meter_start,
|
||||
std::optional<std::int32_t> reservation_id, const ocpp::DateTime& timestamp,
|
||||
std::optional<std::string> signed_meter_value);
|
||||
|
||||
/// \brief Notifies chargepoint that the transaction on the given \p connector with the given \p reason has been
|
||||
/// stopped. This function must be called at the point where one of the preconditions for charging irrevocably
|
||||
/// becomes false, for instance when a user swipes to stop the transaction and the stop is authorized or if the EV
|
||||
/// disconnects.
|
||||
/// \param connector
|
||||
/// \param session_id
|
||||
/// \param reason
|
||||
/// \param timestamp of the end of transaction
|
||||
/// \param energy_wh_import stop meter value in Wh
|
||||
/// \param id_tag_end
|
||||
/// \param signed_meter_value e.g. in OCMF format
|
||||
void on_transaction_stopped(const std::int32_t connector, const std::string& session_id, const Reason& reason,
|
||||
ocpp::DateTime timestamp, float energy_wh_import,
|
||||
std::optional<CiString<20>> id_tag_end, std::optional<std::string> signed_meter_value);
|
||||
|
||||
/// \brief This function should be called when EV indicates that it suspends charging on the given \p connector
|
||||
/// \param connector
|
||||
/// \param reason
|
||||
void on_suspend_charging_ev(std::int32_t connector, const std::optional<CiString<50>> info = std::nullopt);
|
||||
|
||||
/// \brief This function should be called when EVSE indicates that it suspends charging on the given \p connector
|
||||
/// \param connector
|
||||
/// \param reason
|
||||
void on_suspend_charging_evse(std::int32_t connector, const std::optional<CiString<50>> info = std::nullopt);
|
||||
|
||||
/// \brief This function should be called when charging resumes on the given \p connector
|
||||
/// \param connector
|
||||
void on_resume_charging(std::int32_t connector);
|
||||
|
||||
/// \brief This function should be called if an error with the given \p error_info is present. This function will
|
||||
/// trigger a StatusNotification.req containing the given \p error_info . It will change the present state of
|
||||
/// the state machine to faulted, in case the corresponding flag is set in the given \p error_info. This function
|
||||
/// can be called multiple times for different errors. Errors reported using this function stay active as long as
|
||||
/// they are cleared by \ref on_error_cleared().
|
||||
/// \param connector
|
||||
/// \param error_info Additional information related to
|
||||
/// the error
|
||||
void on_error(std::int32_t connector, const ErrorInfo& error_info);
|
||||
|
||||
/// \brief This function should be called if an error with the given \p uuid has been cleared. If this leads to the
|
||||
/// fact that no other error is active anymore, this function will initiate a StatusNotification.req that reports
|
||||
/// the current state and no error
|
||||
/// \param connector
|
||||
/// \param uuid of a previously reported error. If uuid is not
|
||||
/// known, the event will be ignored
|
||||
void on_error_cleared(std::int32_t connector, const std::string uuid);
|
||||
|
||||
/// \brief Clears all previously reported errors at the same time for the given \p connector . This will
|
||||
/// clear a previously reported "Faulted" state if present
|
||||
/// \param connector
|
||||
void on_all_errors_cleared(std::int32_t connector);
|
||||
|
||||
/// \brief Chargepoint notifies about new log status \p log_status . This function should be called during a
|
||||
/// Diagnostics / Log upload to indicate the current \p log_status .
|
||||
/// \param request_id A \p request_id of -1 indicates a DiagnosticsStatusNotification.req, else a
|
||||
/// LogStatusNotification.req.
|
||||
/// \param log_status The \p log_status should be either be convertable to the
|
||||
/// ocpp::v16::UploadLogStatusEnumType enum or ocpp::v16::DiagnosticsStatus enum depending on the previous request,
|
||||
/// which could have been a DiagnosticsUpload.req or a GetLog.req (Security Whitepaper)
|
||||
void on_log_status_notification(std::int32_t request_id, std::string log_status);
|
||||
|
||||
/// \brief Chargepoint notifies about new firmware update status \p firmware_update_status . This function should be
|
||||
/// called during a Firmware Update to indicate the current \p firmware_update_status .
|
||||
/// \param request_id A \p request_id of -1 indicates a FirmwareStatusNotification.req, else a
|
||||
/// SignedFirmwareUpdateStatusNotification.req .
|
||||
/// \param firmware_update_status The \p firmware_update_status
|
||||
void on_firmware_update_status_notification(std::int32_t request_id,
|
||||
const ocpp::FirmwareStatusNotification firmware_update_status);
|
||||
|
||||
/// \brief This function must be called when a reservation is started at the given \p connector .
|
||||
/// \param connector
|
||||
void on_reservation_start(std::int32_t connector);
|
||||
|
||||
/// \brief This function must be called when a reservation ends at the given \p connector
|
||||
/// \param connector
|
||||
void on_reservation_end(std::int32_t connector);
|
||||
|
||||
/// \brief Notifies chargepoint that the \p connector is enabled . This function should be called when the \p
|
||||
/// connector becomes functional and operational
|
||||
/// \param connector
|
||||
void on_enabled(std::int32_t connector);
|
||||
|
||||
/// \brief Notifies chargepoint that the \p connector is disabled . This function should be called when the \p
|
||||
/// connector becomes inoperative
|
||||
/// \param connector
|
||||
void on_disabled(std::int32_t connector);
|
||||
|
||||
/// \brief Notifies chargepoint that a ConnectionTimeout occured for the given \p connector . This function should
|
||||
/// be called when an EV is plugged in but the authorization is present within the specified ConnectionTimeout
|
||||
void on_plugin_timeout(std::int32_t connector);
|
||||
|
||||
/// \brief Notifies chargepoint that a SecurityEvent occurs. This will send a SecurityEventNotification.req to the
|
||||
/// CSMS
|
||||
/// \param event_type type of the security event
|
||||
/// \param tech_info additional info of the security event
|
||||
/// \param critical if set this overwrites the default criticality recommended in the OCPP 1.6 security whitepaper.
|
||||
/// A critical security event is transmitted as a message to the CSMS, a non-critical one is just written to the
|
||||
/// security log
|
||||
/// \param timestamp when this security event occured, if absent the current datetime is assumed
|
||||
void on_security_event(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
|
||||
const std::optional<bool>& critical = std::nullopt,
|
||||
const std::optional<DateTime>& timestamp = std::nullopt);
|
||||
|
||||
/// \brief Handles an internal ChangeAvailabilityRequest (in the same way as if it was emitted by the CSMS).
|
||||
/// \param request
|
||||
ChangeAvailabilityResponse on_change_availability(const ChangeAvailabilityRequest& request);
|
||||
|
||||
/// @} // End handlers group
|
||||
|
||||
/// @}
|
||||
|
||||
/// @addtogroup ocpp16_callbacks OCPP 1.6 callbacks
|
||||
/// Callbacks will call be called when necessary and must be implemented by the calling class.
|
||||
/// @{
|
||||
|
||||
/// @name Callbacks
|
||||
/// Callbacks
|
||||
/// @{
|
||||
|
||||
/// registers a \p callback function that can be used to receive a arbitrary data transfer for the given \p
|
||||
/// vendorId and \p messageId
|
||||
/// \param vendorId
|
||||
/// \param messageId
|
||||
/// \param callback
|
||||
void register_data_transfer_callback(
|
||||
const CiString<255>& vendorId, const CiString<50>& messageId,
|
||||
const std::function<DataTransferResponse(const std::optional<std::string>& msg)>& callback);
|
||||
|
||||
/// registers a \p callback function that can be used to handle arbitrary data transfers for all vendorId an
|
||||
/// messageId
|
||||
/// \param callback
|
||||
void register_data_transfer_callback(
|
||||
const std::function<DataTransferResponse(const DataTransferRequest& request)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to enable the evse. The enable_evse_callback is called
|
||||
/// when a ChangeAvailaibility.req is received.
|
||||
/// \param callback
|
||||
void register_enable_evse_callback(const std::function<bool(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to disable the evse. The disable_evse_callback is
|
||||
/// called when a ChangeAvailaibility.req is received.
|
||||
/// \param callback
|
||||
void register_disable_evse_callback(const std::function<bool(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to pause charging. The pause_charging_callback is
|
||||
/// called when the idTagInfo.status of a StartTransaction.conf is not Accepted
|
||||
/// \param callback
|
||||
void register_pause_charging_callback(const std::function<bool(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to resume charging
|
||||
/// \param callback
|
||||
void register_resume_charging_callback(const std::function<bool(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to provide an \p id_token for the given \p
|
||||
/// referenced_connectors to an authorization handler. \p prevalidated signals to the authorization handler that no
|
||||
/// further authorization is necessary. The provide_token_callback is called when a RemoteStartTransaction.req is
|
||||
/// received.
|
||||
/// \param callback
|
||||
void register_provide_token_callback(
|
||||
const std::function<void(const std::string& id_token, std::vector<std::int32_t> referenced_connectors,
|
||||
bool prevalidated)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to stop a transaction. Ths stop_transaction_callback is
|
||||
/// called
|
||||
/// - when the idTagInfo.status of a StartTransaction.conf is not Accepted
|
||||
/// - when a RemoteStopTransaction.req is received
|
||||
/// - when a UnlockConnector.req is received
|
||||
/// \param callback
|
||||
void register_stop_transaction_callback(const std::function<bool(std::int32_t connector, Reason reason)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to reserve a connector for a idTag until a timeout
|
||||
/// is reached. The reserve_now_callback is called when a ReserveNow.req is received.
|
||||
/// \param callback
|
||||
void register_reserve_now_callback(
|
||||
const std::function<ReservationStatus(std::int32_t reservation_id, std::int32_t connector,
|
||||
ocpp::DateTime expiryDate, CiString<20> idTag,
|
||||
std::optional<CiString<20>> parent_id)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to cancel a reservation on a connector. Callback
|
||||
/// function should return false if the reservation could not be cancelled, else true . The
|
||||
/// cancel_reservation_callback is called when a CancelReservation.req is received
|
||||
/// \param callback
|
||||
void register_cancel_reservation_callback(const std::function<bool(std::int32_t reservation_id)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to unlock the connector. In case a transaction is
|
||||
// active at the specified connector, the \p callback shall stop the transaction before unlocking the connector. The
|
||||
// unlock_connector_callback is called:
|
||||
/// - when receiving a UnlockConnector.req and
|
||||
/// - when a transaction has on_transaction_stopped is called and the configuration key
|
||||
/// UnlockConnectorOnEVSideDisconnect is true
|
||||
/// \param callback
|
||||
void register_unlock_connector_callback(const std::function<UnlockStatus(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to trigger an upload of diagnostics. This callback
|
||||
/// should trigger a process of a diagnostics upload using the given parameters of the request. This process should
|
||||
/// call the on_log_status_notification handler in order to update the status of the file upload. The
|
||||
/// upload_diagnostics_callback is called when a GetDiagnostics.req is received
|
||||
/// \param callback
|
||||
void register_upload_diagnostics_callback(
|
||||
const std::function<GetLogResponse(const GetDiagnosticsRequest& request)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to trigger a firmware update. This callback
|
||||
/// should trigger a process of a firmware update using the given parameters of the request. This process should
|
||||
/// call the on_firmware_update_status_notification handler in order to update the status of the update. The
|
||||
/// update_firmware_callback is called when a FirmwareUpdate.req is received
|
||||
/// \param callback
|
||||
void register_update_firmware_callback(const std::function<void(const UpdateFirmwareRequest msg)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to trigger a signed firmware update. This callback
|
||||
/// should trigger a process of a signed firmware update using the given parameters of the request. This process
|
||||
/// should call the on_firmware_update_status_notification handler in order to update the status of the signed
|
||||
/// firmware update. The signed_update_firmware_callback is called when a SignedUpdateFirmware.req is received.
|
||||
/// \param callback
|
||||
void register_signed_update_firmware_callback(
|
||||
const std::function<UpdateFirmwareStatusEnumType(const SignedUpdateFirmwareRequest msg)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that is called when all connectors are set to unavailable.
|
||||
/// This can be used to then trigger the installation of the firmware update
|
||||
void register_all_connectors_unavailable_callback(const std::function<void()>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to upload logfiles. This callback
|
||||
/// should trigger a process of a log upload using the given parameters of the request. This process should
|
||||
/// call the on_log_status_notification handler in order to update the status of the file upload. The
|
||||
/// upload_logs_callback is called when a GetLog.req is received
|
||||
/// \param callback
|
||||
void register_upload_logs_callback(const std::function<GetLogResponse(GetLogRequest req)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to set the authorization or plug in connection timeout.
|
||||
/// The set_connection_timeout_callback is called when the configuration key ConnectionTimeout has been changed by
|
||||
/// the CSMS.
|
||||
/// \param callback
|
||||
void register_set_connection_timeout_callback(const std::function<void(std::int32_t connection_timeout)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to check if a reset is allowed . The
|
||||
/// is_reset_allowed_callback is called when a Reset.req is received.
|
||||
/// \param callback
|
||||
void register_is_reset_allowed_callback(const std::function<bool(const ResetType& reset_type)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to trigger a reset of the chargepoint. The
|
||||
/// reset_callback is called when a Reset.req is received and a previous execution of the is_reset_allowed_callback
|
||||
/// returned true
|
||||
/// \param callback
|
||||
void register_reset_callback(const std::function<void(const ResetType& reset_type)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to set the system time.
|
||||
/// \param callback
|
||||
void register_set_system_time_callback(const std::function<void(const std::string& system_time)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used receive the BootNotificationResponse
|
||||
/// \param callback
|
||||
void register_boot_notification_response_callback(
|
||||
const std::function<void(const BootNotificationResponse& boot_notification_response)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to signal that the chargepoint received a
|
||||
/// SetChargingProfile.req . The set_charging_profiles_callback is called when a SetChargingProfile.req is received
|
||||
/// and was accepted. The registered callback could make use of the get_all_composite_charging_schedules in order to
|
||||
/// retrieve the ChargingProfiles that have been set by the CSMS.
|
||||
/// \param callback
|
||||
void register_signal_set_charging_profiles_callback(const std::function<void()>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used when the connection state to CSMS changes. The
|
||||
/// connection_state_changed_callback is called when chargepoint has connected to or disconnected from the CSMS.
|
||||
/// \param callback
|
||||
void register_connection_state_changed_callback(const std::function<void(bool is_connected)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to publish the response to a Get15118Certificate.req
|
||||
/// wrapped in a DataTransfer.req . The get_15118_ev_certificate_response_callback is called after the response to a
|
||||
/// DataTransfer.req(Get15118EVCertificate) has been accepted.
|
||||
/// \param callback
|
||||
void register_get_15118_ev_certificate_response_callback(
|
||||
const std::function<void(const std::int32_t connector,
|
||||
const ocpp::v2::Get15118EVCertificateResponse& certificate_response,
|
||||
const ocpp::v2::CertificateActionEnum& certificate_action)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that is called when a StartTransaction.req message is sent by the
|
||||
/// chargepoint
|
||||
/// \param callback
|
||||
void register_transaction_started_callback(
|
||||
const std::function<void(const std::int32_t connector, const std::string& session_id)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that is called when a StopTransaction.req message is sent by the
|
||||
/// chargepoint
|
||||
/// \param callback
|
||||
void register_transaction_stopped_callback(
|
||||
const std::function<void(const std::int32_t connector, const std::string& session_id,
|
||||
const std::int32_t transaction_id)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that is called when a StartTransaction.conf message is received by the
|
||||
/// CSMS. This includes the transactionId.
|
||||
/// \param callback
|
||||
void register_transaction_updated_callback(
|
||||
const std::function<void(const std::int32_t connector, const std::string& session_id,
|
||||
const std::int32_t transaction_id, const IdTagInfo& id_tag_info)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to react on changed configuration keys. This
|
||||
/// callback is called when a configuration key has been successfully changed by the CSMS or internally using the
|
||||
/// set_custom_configuration_key function
|
||||
/// \param key the configuration key for which the callback is registered
|
||||
/// \param callback executed when this configuration key changed
|
||||
void register_configuration_key_changed_callback(const CiString<50>& key,
|
||||
const std::function<void(const KeyValue& key_value)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to react on changed configuration key and value. This
|
||||
/// callback is called when a configuration key has been changed by the CSMS, where no key based callback is
|
||||
/// assigned
|
||||
/// \param callback executed when this configuration key and its value changed
|
||||
void
|
||||
register_generic_configuration_key_changed_callback(const std::function<void(const KeyValue& key_value)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to react to a security event callback. This callback is
|
||||
/// called only if the SecurityEvent occured internally within libocpp
|
||||
void register_security_event_callback(
|
||||
const std::function<void(const std::string& type, const std::string& tech_info)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to check, if the \p connector is reserved for the given
|
||||
/// \p id_token. The is_token_reserved_for_connector_callback is called when a RemoteStartTransaction.req is
|
||||
/// received.
|
||||
/// \param callback
|
||||
/// \ingroup ocpp16_callbacks
|
||||
void register_is_token_reserved_for_connector_callback(
|
||||
const std::function<ReservationCheckStatus(const std::int32_t connector, const std::string& id_token)>&
|
||||
callback);
|
||||
|
||||
/// \brief Registers a callback function for the session cost datatransfer message (California Pricing Requirements)
|
||||
/// \param session_cost_callback The callback.
|
||||
/// \ingroup ocpp16_callbacks
|
||||
void register_session_cost_callback(
|
||||
const std::function<DataTransferResponse(const RunningCost& session_cost,
|
||||
const std::uint32_t number_of_decimals)>& session_cost_callback);
|
||||
|
||||
/// \brief Registers a callback function for the tariff text message (California Pricing Requirements). The
|
||||
/// callback is executed when the CSMS sends a DataTransfer.req(SetUserPrice). The callback should return a
|
||||
/// DataTransferResponse with the response to the CSMS.
|
||||
/// \param tariff_message_callback The callback
|
||||
/// \ingroup ocpp16_callbacks
|
||||
void register_tariff_message_callback(
|
||||
const std::function<DataTransferResponse(const TariffMessage& message)>& tariff_message_callback);
|
||||
|
||||
/// \brief Registers a callback function for the default price. The callback is called on startup and whenever the
|
||||
/// applicable default price changes (e.g. after a connectivity state change or a configuration update).
|
||||
/// \param callback Called with the currently applicable default price text.
|
||||
/// \ingroup ocpp16_callbacks
|
||||
void register_default_price_callback(const std::function<void(const TariffMessage& message)>& callback);
|
||||
|
||||
/// \brief Register a callback function for display messages (used in California Pricing Requirements)
|
||||
/// \param set_display_message_callback The callback.
|
||||
/// \ingroup ocpp16_callbacks
|
||||
void register_set_display_message_callback(
|
||||
const std::function<DataTransferResponse(const std::vector<DisplayMessage>&)> set_display_message_callback);
|
||||
|
||||
/// @} // End ocpp 16 callbacks group / topic
|
||||
|
||||
/// @} // End group
|
||||
|
||||
/// \brief Gets the configured configuration key requested in the given \p request
|
||||
/// \param request specifies the keys that should be returned. If empty or not set, all keys will be reported
|
||||
/// \return a response containing the requested key(s) including the values and unkown keys if present
|
||||
GetConfigurationResponse get_configuration_key(const GetConfigurationRequest& request);
|
||||
|
||||
/// \brief Sets a configuration key
|
||||
/// \param key
|
||||
/// \param value
|
||||
/// \return Indicates the result of the operation
|
||||
ConfigurationStatus set_configuration_key(CiString<50> key, CiString<500> value);
|
||||
|
||||
/// \brief Delay draining the message queue after reconnecting, so the CSMS can perform post-reconnect checks first
|
||||
/// \param delay The delay period (seconds)
|
||||
void set_message_queue_resume_delay(std::chrono::seconds delay);
|
||||
|
||||
/// \brief Sets the public key of the powermeter for the given connector
|
||||
/// \param connector The connector for which the public key is set
|
||||
/// \param public_key_pem The public key in PEM format
|
||||
/// \return true if the public key was set successfully, false otherwise
|
||||
bool set_powermeter_public_key(const int32_t connector, const std::string& public_key_pem);
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
#endif
|
||||
@@ -0,0 +1,542 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_V16_CHARGE_POINT_CONFIGURATION_HPP
|
||||
#define OCPP_V16_CHARGE_POINT_CONFIGURATION_HPP
|
||||
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
#include <ocpp/common/support_older_cpp_versions.hpp>
|
||||
#include <ocpp/v16/charge_point_configuration_base.hpp>
|
||||
#include <ocpp/v16/charge_point_configuration_interface.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief contains the configuration of the charge point
|
||||
class ChargePointConfiguration : private ChargePointConfigurationBase, public ChargePointConfigurationInterface {
|
||||
private:
|
||||
json config;
|
||||
json custom_schema;
|
||||
json internal_schema;
|
||||
bool core_schema_unlock_connector_on_ev_side_disconnect_ro_value;
|
||||
fs::path user_config_path;
|
||||
|
||||
std::recursive_mutex configuration_mutex;
|
||||
|
||||
bool validate_measurands(const json& config);
|
||||
json get_user_config();
|
||||
void setInUserConfig(const std::string& profile, const std::string& key, json value);
|
||||
|
||||
void setChargepointInformationProperty(json& user_config, const std::string& key,
|
||||
const std::optional<std::string>& value);
|
||||
|
||||
public:
|
||||
ChargePointConfiguration(const std::string& config, const fs::path& ocpp_main_path,
|
||||
const fs::path& user_config_path);
|
||||
ChargePointConfiguration() = delete;
|
||||
ChargePointConfiguration(const ChargePointConfiguration&) = delete;
|
||||
ChargePointConfiguration(ChargePointConfiguration&&) = delete;
|
||||
ChargePointConfiguration& operator=(const ChargePointConfiguration&) = delete;
|
||||
ChargePointConfiguration& operator=(ChargePointConfiguration&&) = delete;
|
||||
virtual ~ChargePointConfiguration() = default;
|
||||
|
||||
void setChargepointInformation(const std::string& chargePointVendor, const std::string& chargePointModel,
|
||||
const std::optional<std::string>& chargePointSerialNumber,
|
||||
const std::optional<std::string>& chargeBoxSerialNumber,
|
||||
const std::optional<std::string>& firmwareVersion) override;
|
||||
void setChargepointModemInformation(const std::optional<std::string>& ICCID,
|
||||
const std::optional<std::string>& IMSI) override;
|
||||
void setChargepointMeterInformation(const std::optional<std::string>& meterSerialNumber,
|
||||
const std::optional<std::string>& meterType) override;
|
||||
// Internal config options
|
||||
std::string getChargePointId() override;
|
||||
KeyValue getChargePointIdKeyValue() override;
|
||||
std::string getCentralSystemURI() override;
|
||||
void setCentralSystemURI(const std::string& ocpp_uri) override;
|
||||
KeyValue getCentralSystemURIKeyValue() override;
|
||||
std::string getChargeBoxSerialNumber() override;
|
||||
KeyValue getChargeBoxSerialNumberKeyValue() override;
|
||||
CiString<20> getChargePointModel() override;
|
||||
KeyValue getChargePointModelKeyValue() override;
|
||||
std::optional<CiString<25>> getChargePointSerialNumber() override;
|
||||
std::optional<KeyValue> getChargePointSerialNumberKeyValue() override;
|
||||
CiString<20> getChargePointVendor() override;
|
||||
KeyValue getChargePointVendorKeyValue() override;
|
||||
CiString<50> getFirmwareVersion() override;
|
||||
KeyValue getFirmwareVersionKeyValue() override;
|
||||
std::optional<CiString<20>> getICCID() override;
|
||||
std::optional<KeyValue> getICCIDKeyValue() override;
|
||||
std::optional<CiString<20>> getIMSI() override;
|
||||
std::optional<KeyValue> getIMSIKeyValue() override;
|
||||
std::optional<CiString<25>> getMeterSerialNumber() override;
|
||||
std::optional<KeyValue> getMeterSerialNumberKeyValue() override;
|
||||
std::optional<CiString<25>> getMeterType() override;
|
||||
std::optional<KeyValue> getMeterTypeKeyValue() override;
|
||||
bool getAuthorizeConnectorZeroOnConnectorOne() override;
|
||||
KeyValue getAuthorizeConnectorZeroOnConnectorOneKeyValue() override;
|
||||
bool getLogMessages() override;
|
||||
KeyValue getLogMessagesKeyValue() override;
|
||||
bool getLogMessagesRaw() override;
|
||||
KeyValue getLogMessagesRawKeyValue() override;
|
||||
std::vector<std::string> getLogMessagesFormat() override;
|
||||
KeyValue getLogMessagesFormatKeyValue() override;
|
||||
bool getLogRotation() override;
|
||||
KeyValue getLogRotationKeyValue() override;
|
||||
bool getLogRotationDateSuffix() override;
|
||||
KeyValue getLogRotationDateSuffixKeyValue() override;
|
||||
uint64_t getLogRotationMaximumFileSize() override;
|
||||
KeyValue getLogRotationMaximumFileSizeKeyValue() override;
|
||||
uint64_t getLogRotationMaximumFileCount() override;
|
||||
KeyValue getLogRotationMaximumFileCountKeyValue() override;
|
||||
std::vector<ChargingProfilePurposeType> getSupportedChargingProfilePurposeTypes() override;
|
||||
KeyValue getSupportedChargingProfilePurposeTypesKeyValue() override;
|
||||
std::vector<ChargingProfilePurposeType> getIgnoredProfilePurposesOffline() override;
|
||||
std::optional<KeyValue> getIgnoredProfilePurposesOfflineKeyValue() override;
|
||||
bool setIgnoredProfilePurposesOffline(const std::string& ignored_profile_purposes_offline) override;
|
||||
std::int32_t getMaxCompositeScheduleDuration() override;
|
||||
KeyValue getMaxCompositeScheduleDurationKeyValue() override;
|
||||
std::optional<std::int32_t> getCompositeScheduleDefaultLimitAmps() override;
|
||||
std::optional<KeyValue> getCompositeScheduleDefaultLimitAmpsKeyValue() override;
|
||||
void setCompositeScheduleDefaultLimitAmps(std::int32_t limit_amps) override;
|
||||
std::optional<std::int32_t> getCompositeScheduleDefaultLimitWatts() override;
|
||||
std::optional<KeyValue> getCompositeScheduleDefaultLimitWattsKeyValue() override;
|
||||
void setCompositeScheduleDefaultLimitWatts(std::int32_t limit_watts) override;
|
||||
std::optional<std::int32_t> getCompositeScheduleDefaultNumberPhases() override;
|
||||
std::optional<KeyValue> getCompositeScheduleDefaultNumberPhasesKeyValue() override;
|
||||
void setCompositeScheduleDefaultNumberPhases(std::int32_t number_phases) override;
|
||||
std::optional<std::int32_t> getSupplyVoltage() override;
|
||||
std::optional<KeyValue> getSupplyVoltageKeyValue() override;
|
||||
void setSupplyVoltage(std::int32_t supply_voltage) override;
|
||||
std::string getSupportedCiphers12() override;
|
||||
KeyValue getSupportedCiphers12KeyValue() override;
|
||||
std::string getSupportedCiphers13() override;
|
||||
KeyValue getSupportedCiphers13KeyValue() override;
|
||||
bool getUseSslDefaultVerifyPaths() override;
|
||||
KeyValue getUseSslDefaultVerifyPathsKeyValue() override;
|
||||
bool getVerifyCsmsCommonName() override;
|
||||
KeyValue getVerifyCsmsCommonNameKeyValue() override;
|
||||
bool getVerifyCsmsAllowWildcards() override;
|
||||
void setVerifyCsmsAllowWildcards(bool verify_csms_allow_wildcards) override;
|
||||
KeyValue getVerifyCsmsAllowWildcardsKeyValue() override;
|
||||
bool getUseTPM() override;
|
||||
KeyValue getUseTPMKeyValue() override;
|
||||
bool getUseTPMSeccLeafCertificate() override;
|
||||
KeyValue getUseTPMSeccLeafCertificateKeyValue() override;
|
||||
|
||||
std::string getSupportedMeasurands() override;
|
||||
KeyValue getSupportedMeasurandsKeyValue() override;
|
||||
int getMaxMessageSize() override;
|
||||
KeyValue getMaxMessageSizeKeyValue() override;
|
||||
|
||||
bool getEnableTLSKeylog() override;
|
||||
KeyValue getEnableTLSKeylogKeyValue() override;
|
||||
std::string getTLSKeylogFile() override;
|
||||
KeyValue getTLSKeylogFileKeyValue() override;
|
||||
|
||||
bool getStopTransactionIfUnlockNotSupported() override;
|
||||
void setStopTransactionIfUnlockNotSupported(bool stop_transaction_if_unlock_not_supported) override;
|
||||
KeyValue getStopTransactionIfUnlockNotSupportedKeyValue() override;
|
||||
|
||||
std::int32_t getRetryBackoffRandomRange() override;
|
||||
void setRetryBackoffRandomRange(std::int32_t retry_backoff_random_range) override;
|
||||
KeyValue getRetryBackoffRandomRangeKeyValue() override;
|
||||
|
||||
std::int32_t getRetryBackoffRepeatTimes() override;
|
||||
void setRetryBackoffRepeatTimes(std::int32_t retry_backoff_repeat_times) override;
|
||||
KeyValue getRetryBackoffRepeatTimesKeyValue() override;
|
||||
|
||||
std::int32_t getRetryBackoffWaitMinimum() override;
|
||||
void setRetryBackoffWaitMinimum(std::int32_t retry_backoff_wait_minimum) override;
|
||||
KeyValue getRetryBackoffWaitMinimumKeyValue() override;
|
||||
|
||||
std::set<MessageType> getSupportedMessageTypesSending() override;
|
||||
std::set<MessageType> getSupportedMessageTypesReceiving() override;
|
||||
|
||||
std::string getWebsocketPingPayload() override;
|
||||
KeyValue getWebsocketPingPayloadKeyValue() override;
|
||||
|
||||
std::int32_t getWebsocketPongTimeout() override;
|
||||
KeyValue getWebsocketPongTimeoutKeyValue() override;
|
||||
|
||||
std::optional<std::string> getHostName() override;
|
||||
std::optional<KeyValue> getHostNameKeyValue() override;
|
||||
|
||||
std::optional<std::string> getIFace() override;
|
||||
std::optional<KeyValue> getIFaceKeyValue() override;
|
||||
|
||||
std::optional<bool> getQueueAllMessages() override;
|
||||
std::optional<KeyValue> getQueueAllMessagesKeyValue() override;
|
||||
|
||||
std::optional<std::string> getMessageTypesDiscardForQueueing() override;
|
||||
std::optional<KeyValue> getMessageTypesDiscardForQueueingKeyValue() override;
|
||||
|
||||
std::optional<int> getMessageQueueSizeThreshold() override;
|
||||
std::optional<KeyValue> getMessageQueueSizeThresholdKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<bool> getAllowOfflineTxForUnknownId() override;
|
||||
void setAllowOfflineTxForUnknownId(bool enabled) override;
|
||||
std::optional<KeyValue> getAllowOfflineTxForUnknownIdKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<bool> getAuthorizationCacheEnabled() override;
|
||||
void setAuthorizationCacheEnabled(bool enabled) override;
|
||||
std::optional<KeyValue> getAuthorizationCacheEnabledKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
bool getAuthorizeRemoteTxRequests() override;
|
||||
void setAuthorizeRemoteTxRequests(bool enabled) override;
|
||||
KeyValue getAuthorizeRemoteTxRequestsKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getBlinkRepeat() override;
|
||||
void setBlinkRepeat(std::int32_t blink_repeat) override;
|
||||
std::optional<KeyValue> getBlinkRepeatKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::int32_t getClockAlignedDataInterval() override;
|
||||
void setClockAlignedDataInterval(std::int32_t interval) override;
|
||||
KeyValue getClockAlignedDataIntervalKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::int32_t getConnectionTimeOut() override;
|
||||
void setConnectionTimeOut(std::int32_t timeout) override;
|
||||
KeyValue getConnectionTimeOutKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::string getConnectorPhaseRotation() override;
|
||||
void setConnectorPhaseRotation(const std::string& connector_phase_rotation) override;
|
||||
KeyValue getConnectorPhaseRotationKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getConnectorPhaseRotationMaxLength() override;
|
||||
std::optional<KeyValue> getConnectorPhaseRotationMaxLengthKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::int32_t getGetConfigurationMaxKeys() override;
|
||||
KeyValue getGetConfigurationMaxKeysKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::int32_t getHeartbeatInterval() override;
|
||||
void setHeartbeatInterval(std::int32_t interval) override;
|
||||
KeyValue getHeartbeatIntervalKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getLightIntensity() override;
|
||||
void setLightIntensity(std::int32_t light_intensity) override;
|
||||
std::optional<KeyValue> getLightIntensityKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
bool getLocalAuthorizeOffline() override;
|
||||
void setLocalAuthorizeOffline(bool local_authorize_offline) override;
|
||||
KeyValue getLocalAuthorizeOfflineKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
bool getLocalPreAuthorize() override;
|
||||
void setLocalPreAuthorize(bool local_pre_authorize) override;
|
||||
KeyValue getLocalPreAuthorizeKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getMaxEnergyOnInvalidId() override;
|
||||
void setMaxEnergyOnInvalidId(std::int32_t max_energy) override;
|
||||
std::optional<KeyValue> getMaxEnergyOnInvalidIdKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::string getMeterValuesAlignedData() override;
|
||||
bool setMeterValuesAlignedData(const std::string& meter_values_aligned_data) override;
|
||||
KeyValue getMeterValuesAlignedDataKeyValue() override;
|
||||
std::vector<MeasurandWithPhase> getMeterValuesAlignedDataVector() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getMeterValuesAlignedDataMaxLength() override;
|
||||
std::optional<KeyValue> getMeterValuesAlignedDataMaxLengthKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::string getMeterValuesSampledData() override;
|
||||
bool setMeterValuesSampledData(const std::string& meter_values_sampled_data) override;
|
||||
KeyValue getMeterValuesSampledDataKeyValue() override;
|
||||
std::vector<MeasurandWithPhase> getMeterValuesSampledDataVector() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getMeterValuesSampledDataMaxLength() override;
|
||||
std::optional<KeyValue> getMeterValuesSampledDataMaxLengthKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::int32_t getMeterValueSampleInterval() override;
|
||||
void setMeterValueSampleInterval(std::int32_t interval) override;
|
||||
KeyValue getMeterValueSampleIntervalKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getMinimumStatusDuration() override;
|
||||
void setMinimumStatusDuration(std::int32_t minimum_status_duration) override;
|
||||
std::optional<KeyValue> getMinimumStatusDurationKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::int32_t getNumberOfConnectors() override;
|
||||
KeyValue getNumberOfConnectorsKeyValue() override;
|
||||
|
||||
// Reservation Profile
|
||||
std::optional<bool> getReserveConnectorZeroSupported() override;
|
||||
std::optional<KeyValue> getReserveConnectorZeroSupportedKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::int32_t getResetRetries() override;
|
||||
void setResetRetries(std::int32_t retries) override;
|
||||
KeyValue getResetRetriesKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<bool> getStopTransactionOnEVSideDisconnect() override;
|
||||
std::optional<KeyValue> getStopTransactionOnEVSideDisconnectKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
bool getStopTransactionOnInvalidId() override;
|
||||
void setStopTransactionOnInvalidId(bool stop_transaction_on_invalid_id) override;
|
||||
KeyValue getStopTransactionOnInvalidIdKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::string getStopTxnAlignedData() override;
|
||||
bool setStopTxnAlignedData(const std::string& stop_txn_aligned_data) override;
|
||||
KeyValue getStopTxnAlignedDataKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getStopTxnAlignedDataMaxLength() override;
|
||||
std::optional<KeyValue> getStopTxnAlignedDataMaxLengthKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::string getStopTxnSampledData() override;
|
||||
bool setStopTxnSampledData(const std::string& stop_txn_sampled_data) override;
|
||||
KeyValue getStopTxnSampledDataKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getStopTxnSampledDataMaxLength() override;
|
||||
std::optional<KeyValue> getStopTxnSampledDataMaxLengthKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::string getSupportedFeatureProfiles() override;
|
||||
KeyValue getSupportedFeatureProfilesKeyValue() override;
|
||||
std::set<SupportedFeatureProfiles> getSupportedFeatureProfilesSet() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getSupportedFeatureProfilesMaxLength() override;
|
||||
std::optional<KeyValue> getSupportedFeatureProfilesMaxLengthKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::int32_t getTransactionMessageAttempts() override;
|
||||
void setTransactionMessageAttempts(std::int32_t attempts) override;
|
||||
KeyValue getTransactionMessageAttemptsKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
std::int32_t getTransactionMessageRetryInterval() override;
|
||||
void setTransactionMessageRetryInterval(std::int32_t retry_interval) override;
|
||||
KeyValue getTransactionMessageRetryIntervalKeyValue() override;
|
||||
|
||||
// Core Profile
|
||||
bool getUnlockConnectorOnEVSideDisconnect() override;
|
||||
void setUnlockConnectorOnEVSideDisconnect(bool unlock_connector_on_ev_side_disconnect) override;
|
||||
KeyValue getUnlockConnectorOnEVSideDisconnectKeyValue() override;
|
||||
|
||||
// Core Profile - optional
|
||||
std::optional<std::int32_t> getWebsocketPingInterval() override;
|
||||
void setWebsocketPingInterval(std::int32_t websocket_ping_interval) override;
|
||||
std::optional<KeyValue> getWebsocketPingIntervalKeyValue() override;
|
||||
|
||||
// Core Profile end
|
||||
|
||||
// Firmware Management Profile
|
||||
|
||||
std::optional<std::string> getSupportedFileTransferProtocols() override;
|
||||
std::optional<KeyValue> getSupportedFileTransferProtocolsKeyValue() override;
|
||||
|
||||
// SmartCharging Profile
|
||||
std::int32_t getChargeProfileMaxStackLevel() override;
|
||||
KeyValue getChargeProfileMaxStackLevelKeyValue() override;
|
||||
|
||||
// SmartCharging Profile
|
||||
std::string getChargingScheduleAllowedChargingRateUnit() override;
|
||||
KeyValue getChargingScheduleAllowedChargingRateUnitKeyValue() override;
|
||||
std::vector<ChargingRateUnit> getChargingScheduleAllowedChargingRateUnitVector() override;
|
||||
|
||||
// SmartCharging Profile
|
||||
std::int32_t getChargingScheduleMaxPeriods() override;
|
||||
KeyValue getChargingScheduleMaxPeriodsKeyValue() override;
|
||||
|
||||
// SmartCharging Profile - optional
|
||||
std::optional<bool> getConnectorSwitch3to1PhaseSupported() override;
|
||||
std::optional<KeyValue> getConnectorSwitch3to1PhaseSupportedKeyValue() override;
|
||||
|
||||
// SmartCharging Profile
|
||||
std::int32_t getMaxChargingProfilesInstalled() override;
|
||||
KeyValue getMaxChargingProfilesInstalledKeyValue() override;
|
||||
|
||||
// SmartCharging Profile end
|
||||
|
||||
// Security profile - optional
|
||||
std::optional<bool> getAdditionalRootCertificateCheck() override;
|
||||
std::optional<KeyValue> getAdditionalRootCertificateCheckKeyValue() override;
|
||||
|
||||
// Security profile - optional
|
||||
std::optional<std::string> getAuthorizationKey() override;
|
||||
void setAuthorizationKey(const std::string& authorization_key) override;
|
||||
std::optional<KeyValue> getAuthorizationKeyKeyValue() override;
|
||||
|
||||
// Security profile - optional
|
||||
std::optional<std::int32_t> getCertificateSignedMaxChainSize() override;
|
||||
std::optional<KeyValue> getCertificateSignedMaxChainSizeKeyValue() override;
|
||||
|
||||
// Security profile - optional
|
||||
std::optional<std::int32_t> getCertificateStoreMaxLength() override;
|
||||
std::optional<KeyValue> getCertificateStoreMaxLengthKeyValue() override;
|
||||
|
||||
// Security profile - optional
|
||||
std::optional<std::string> getCpoName() override;
|
||||
void setCpoName(const std::string& cpo_name) override;
|
||||
std::optional<KeyValue> getCpoNameKeyValue() override;
|
||||
|
||||
// // Security profile - optional in ocpp but mandatory websocket connection
|
||||
std::int32_t getSecurityProfile() override;
|
||||
void setSecurityProfile(std::int32_t security_profile) override;
|
||||
KeyValue getSecurityProfileKeyValue() override;
|
||||
|
||||
// // Security profile - optional with default
|
||||
bool getDisableSecurityEventNotifications() override;
|
||||
void setDisableSecurityEventNotifications(bool disable_security_event_notifications) override;
|
||||
KeyValue getDisableSecurityEventNotificationsKeyValue() override;
|
||||
|
||||
// Local Auth List Management Profile
|
||||
bool getLocalAuthListEnabled() override;
|
||||
void setLocalAuthListEnabled(bool local_auth_list_enabled) override;
|
||||
KeyValue getLocalAuthListEnabledKeyValue() override;
|
||||
|
||||
// Local Auth List Management Profile
|
||||
std::int32_t getLocalAuthListMaxLength() override;
|
||||
KeyValue getLocalAuthListMaxLengthKeyValue() override;
|
||||
|
||||
// Local Auth List Management Profile
|
||||
std::int32_t getSendLocalListMaxLength() override;
|
||||
KeyValue getSendLocalListMaxLengthKeyValue() override;
|
||||
|
||||
// PnC
|
||||
bool getISO15118CertificateManagementEnabled() override;
|
||||
void setISO15118CertificateManagementEnabled(bool iso15118_certificate_management_enabled) override;
|
||||
KeyValue getISO15118CertificateManagementEnabledKeyValue() override;
|
||||
|
||||
bool getISO15118PnCEnabled() override;
|
||||
void setISO15118PnCEnabled(bool iso15118_pnc_enabled) override;
|
||||
KeyValue getISO15118PnCEnabledKeyValue() override;
|
||||
|
||||
std::optional<bool> getCentralContractValidationAllowed() override;
|
||||
void setCentralContractValidationAllowed(bool central_contract_validation_allowed) override;
|
||||
std::optional<KeyValue> getCentralContractValidationAllowedKeyValue() override;
|
||||
|
||||
std::optional<std::int32_t> getCertSigningWaitMinimum() override;
|
||||
void setCertSigningWaitMinimum(std::int32_t cert_signing_wait_minimum) override;
|
||||
std::optional<KeyValue> getCertSigningWaitMinimumKeyValue() override;
|
||||
|
||||
std::optional<std::int32_t> getCertSigningRepeatTimes() override;
|
||||
void setCertSigningRepeatTimes(std::int32_t cert_signing_repeat_times) override;
|
||||
std::optional<KeyValue> getCertSigningRepeatTimesKeyValue() override;
|
||||
|
||||
bool getContractValidationOffline() override;
|
||||
void setContractValidationOffline(bool contract_validation_offline) override;
|
||||
KeyValue getContractValidationOfflineKeyValue() override;
|
||||
|
||||
std::int32_t getOcspRequestInterval() override;
|
||||
void setOcspRequestInterval(std::int32_t ocsp_request_interval) override;
|
||||
KeyValue getOcspRequestIntervalKeyValue() override;
|
||||
|
||||
std::optional<std::string> getSeccLeafSubjectCommonName() override;
|
||||
void setSeccLeafSubjectCommonName(const std::string& secc_leaf_subject_common_name) override;
|
||||
std::optional<KeyValue> getSeccLeafSubjectCommonNameKeyValue() override;
|
||||
|
||||
std::optional<std::string> getSeccLeafSubjectCountry() override;
|
||||
void setSeccLeafSubjectCountry(const std::string& secc_leaf_subject_country) override;
|
||||
std::optional<KeyValue> getSeccLeafSubjectCountryKeyValue() override;
|
||||
|
||||
std::optional<std::string> getSeccLeafSubjectOrganization() override;
|
||||
void setSeccLeafSubjectOrganization(const std::string& secc_leaf_subject_organization) override;
|
||||
std::optional<KeyValue> getSeccLeafSubjectOrganizationKeyValue() override;
|
||||
|
||||
std::optional<std::string> getConnectorEvseIds() override;
|
||||
void setConnectorEvseIds(const std::string& connector_evse_ids) override;
|
||||
std::optional<KeyValue> getConnectorEvseIdsKeyValue() override;
|
||||
|
||||
std::optional<bool> getAllowChargingProfileWithoutStartSchedule() override;
|
||||
void setAllowChargingProfileWithoutStartSchedule(bool allow) override;
|
||||
std::optional<KeyValue> getAllowChargingProfileWithoutStartScheduleKeyValue() override;
|
||||
|
||||
std::int32_t getWaitForStopTransactionsOnResetTimeout() override;
|
||||
void setWaitForStopTransactionsOnResetTimeout(std::int32_t wait_for_stop_transactions_on_reset_timeout) override;
|
||||
KeyValue getWaitForStopTransactionsOnResetTimeoutKeyValue() override;
|
||||
|
||||
// California Pricing Requirements
|
||||
bool getCustomDisplayCostAndPriceEnabled() override;
|
||||
KeyValue getCustomDisplayCostAndPriceEnabledKeyValue() override;
|
||||
|
||||
std::optional<std::uint32_t> getPriceNumberOfDecimalsForCostValues() override;
|
||||
std::optional<KeyValue> getPriceNumberOfDecimalsForCostValuesKeyValue() override;
|
||||
|
||||
std::optional<std::string> getDefaultPriceText(const std::string& language) override;
|
||||
TariffMessage getDefaultTariffMessage(bool offline) override;
|
||||
ConfigurationStatus setDefaultPriceText(const CiString<50>& key, const CiString<500>& value) override;
|
||||
KeyValue getDefaultPriceTextKeyValue(const std::string& language) override;
|
||||
std::optional<std::vector<KeyValue>> getAllDefaultPriceTextKeyValues() override;
|
||||
|
||||
std::optional<std::string> getDefaultPrice() override;
|
||||
ConfigurationStatus setDefaultPrice(const std::string& value) override;
|
||||
std::optional<KeyValue> getDefaultPriceKeyValue() override;
|
||||
|
||||
std::optional<std::string> getDisplayTimeOffset() override;
|
||||
ConfigurationStatus setDisplayTimeOffset(const std::string& offset) override;
|
||||
std::optional<KeyValue> getDisplayTimeOffsetKeyValue() override;
|
||||
|
||||
std::optional<std::string> getNextTimeOffsetTransitionDateTime() override;
|
||||
ConfigurationStatus setNextTimeOffsetTransitionDateTime(const std::string& date_time) override;
|
||||
std::optional<KeyValue> getNextTimeOffsetTransitionDateTimeKeyValue() override;
|
||||
|
||||
std::optional<std::string> getTimeOffsetNextTransition() override;
|
||||
ConfigurationStatus setTimeOffsetNextTransition(const std::string& offset) override;
|
||||
std::optional<KeyValue> getTimeOffsetNextTransitionKeyValue() override;
|
||||
|
||||
std::optional<bool> getCustomIdleFeeAfterStop() override;
|
||||
void setCustomIdleFeeAfterStop(bool value) override;
|
||||
std::optional<KeyValue> getCustomIdleFeeAfterStopKeyValue() override;
|
||||
|
||||
std::optional<bool> getCustomMultiLanguageMessagesEnabled() override;
|
||||
std::optional<KeyValue> getCustomMultiLanguageMessagesEnabledKeyValue() override;
|
||||
|
||||
std::optional<std::string> getMultiLanguageSupportedLanguages() override;
|
||||
std::optional<KeyValue> getMultiLanguageSupportedLanguagesKeyValue() override;
|
||||
|
||||
std::optional<std::string> getLanguage() override;
|
||||
void setLanguage(const std::string& language) override;
|
||||
std::optional<KeyValue> getLanguageKeyValue() override;
|
||||
|
||||
std::optional<std::int32_t> getWaitForSetUserPriceTimeout() override;
|
||||
void setWaitForSetUserPriceTimeout(std::int32_t wait_for_set_user_price_timeout) override;
|
||||
std::optional<KeyValue> getWaitForSetUserPriceTimeoutKeyValue() override;
|
||||
|
||||
// Signed Meter Values
|
||||
std::optional<KeyValue> getPublicKeyKeyValue(std::uint32_t connector_id) override;
|
||||
std::optional<std::vector<KeyValue>> getAllMeterPublicKeyKeyValues() override;
|
||||
bool setMeterPublicKey(std::int32_t connector_id, const std::string& public_key_pem) override;
|
||||
|
||||
// custom
|
||||
std::optional<KeyValue> getCustomKeyValue(const CiString<50>& key) override;
|
||||
ConfigurationStatus setCustomKey(const CiString<50>& key, const CiString<500>& value, bool force) override;
|
||||
|
||||
std::optional<KeyValue> get(const CiString<50>& key) override;
|
||||
|
||||
std::vector<KeyValue> get_all_key_value() override;
|
||||
|
||||
std::optional<ConfigurationStatus> set(const CiString<50>& key, const CiString<500>& value) override;
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_CHARGE_POINT_CONFIGURATION_HPP
|
||||
@@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2026 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef OCPP_V16_CHARGE_POINT_CONFIGURATION_BASE_HPP
|
||||
#define OCPP_V16_CHARGE_POINT_CONFIGURATION_BASE_HPP
|
||||
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string_view>
|
||||
|
||||
namespace ocpp::v16 {
|
||||
|
||||
constexpr std::size_t AUTHORIZATION_KEY_MIN_LENGTH = 8;
|
||||
constexpr std::size_t OCSP_REQUEST_INTERVAL_MIN = 86400;
|
||||
constexpr std::size_t SECC_LEAF_SUBJECT_COMMON_NAME_MIN_LENGTH = 7;
|
||||
constexpr std::size_t SECC_LEAF_SUBJECT_COMMON_NAME_MAX_LENGTH = 64;
|
||||
constexpr std::size_t SECC_LEAF_SUBJECT_COUNTRY_LENGTH = 2;
|
||||
constexpr std::size_t SECC_LEAF_SUBJECT_ORGANIZATION_MAX_LENGTH = 64;
|
||||
constexpr std::size_t CONNECTOR_EVSE_IDS_MAX_LENGTH = 1000;
|
||||
constexpr std::int32_t MAX_WAIT_FOR_SET_USER_PRICE_TIMEOUT_MS = 30000;
|
||||
|
||||
/// \brief contains the configuration of the charge point
|
||||
class ChargePointConfigurationBase {
|
||||
public:
|
||||
using MessagesSet = std::set<MessageType>;
|
||||
using ProfilesSet = std::set<SupportedFeatureProfiles>;
|
||||
using FeaturesMap = std::map<SupportedFeatureProfiles, MessagesSet>;
|
||||
using MeasurandsMap = std::map<Measurand, std::vector<Phase>>;
|
||||
using MeasurandWithPhaseList = std::vector<MeasurandWithPhase>;
|
||||
|
||||
protected:
|
||||
static const FeaturesMap supported_message_types_from_charge_point;
|
||||
static const FeaturesMap supported_message_types_from_central_system;
|
||||
|
||||
MessagesSet supported_message_types_receiving;
|
||||
MessagesSet supported_message_types_sending;
|
||||
ProfilesSet supported_feature_profiles;
|
||||
MeasurandsMap supported_measurands;
|
||||
std::filesystem::path ocpp_main_path;
|
||||
|
||||
void initialise(const ProfilesSet& initial_set, const std::optional<std::string>& supported_profiles_csl,
|
||||
const std::optional<std::string>& supported_measurands_csl);
|
||||
|
||||
public:
|
||||
ChargePointConfigurationBase(const std::string_view& ocpp_main_path) : ocpp_main_path(ocpp_main_path) {
|
||||
}
|
||||
ChargePointConfigurationBase(const std::filesystem::path& ocpp_main_path) : ocpp_main_path(ocpp_main_path) {
|
||||
}
|
||||
ChargePointConfigurationBase() = delete;
|
||||
ChargePointConfigurationBase(const ChargePointConfigurationBase&) = delete;
|
||||
ChargePointConfigurationBase(ChargePointConfigurationBase&&) = delete;
|
||||
ChargePointConfigurationBase& operator=(const ChargePointConfigurationBase&) = delete;
|
||||
ChargePointConfigurationBase& operator=(ChargePointConfigurationBase&&) = delete;
|
||||
|
||||
virtual ~ChargePointConfigurationBase() = default;
|
||||
|
||||
bool validate(const std::string_view& schema_file, const json& object) const;
|
||||
|
||||
bool isValidSupportedMeasurands(const std::string& csl) const;
|
||||
std::optional<MeasurandWithPhaseList> csvToMeasurandWithPhaseVector(const std::string& csl) const;
|
||||
|
||||
static std::optional<std::uint32_t> extractConnectorIdFromMeterPublicKey(const std::string& str);
|
||||
static std::string meterPublicKeyString(std::uint32_t connector_id);
|
||||
|
||||
static bool toBool(const std::string& value);
|
||||
static bool isBool(const std::string& str);
|
||||
static bool isPositiveInteger(const std::string& str);
|
||||
static bool isConnectorPhaseRotationValid(std::int32_t num_connectors, const std::string& value);
|
||||
static bool isTimeOffset(const std::string& offset);
|
||||
static bool areValidEvseIds(const std::string& value);
|
||||
static std::string hexToString(const std::string& s);
|
||||
static bool isHexNotation(const std::string& s);
|
||||
};
|
||||
|
||||
} // namespace ocpp::v16
|
||||
|
||||
#endif // OCPP_V16_CHARGE_POINT_CONFIGURATION_BASE_HPP
|
||||
@@ -0,0 +1,504 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2026 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef OCPP_V16_CHARGE_POINT_CONFIGURATION_DEVICEMODEL_HPP
|
||||
#define OCPP_V16_CHARGE_POINT_CONFIGURATION_DEVICEMODEL_HPP
|
||||
|
||||
#include <ocpp/v16/charge_point_configuration_base.hpp>
|
||||
#include <ocpp/v16/charge_point_configuration_interface.hpp>
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
class DeviceModelInterface;
|
||||
}
|
||||
namespace v16 {
|
||||
|
||||
/// \brief contains the configuration of the charge point
|
||||
class ChargePointConfigurationDeviceModel : private ChargePointConfigurationBase,
|
||||
public ChargePointConfigurationInterface {
|
||||
public:
|
||||
using SetResult = v2::SetVariableStatusEnum;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<v2::DeviceModelInterface> storage;
|
||||
|
||||
SetResult setInternalAllowChargingProfileWithoutStartSchedule(const std::string& value);
|
||||
SetResult setInternalCentralSystemURI(const std::string& value);
|
||||
SetResult setInternalCompositeScheduleDefaultLimitAmps(const std::string& value);
|
||||
SetResult setInternalCompositeScheduleDefaultLimitWatts(const std::string& value);
|
||||
SetResult setInternalCompositeScheduleDefaultNumberPhases(const std::string& value);
|
||||
SetResult setInternalConnectorEvseIds(const std::string& value);
|
||||
SetResult setInternalIgnoredProfilePurposesOffline(const std::string& value);
|
||||
SetResult setInternalOcspRequestInterval(const std::string& value);
|
||||
SetResult setInternalRetryBackoffRandomRange(const std::string& value);
|
||||
SetResult setInternalRetryBackoffRepeatTimes(const std::string& value);
|
||||
SetResult setInternalRetryBackoffWaitMinimum(const std::string& value);
|
||||
SetResult setInternalSeccLeafSubjectCommonName(const std::string& value);
|
||||
SetResult setInternalSeccLeafSubjectCountry(const std::string& value);
|
||||
SetResult setInternalSeccLeafSubjectOrganization(const std::string& value);
|
||||
SetResult setInternalStopTransactionIfUnlockNotSupported(const std::string& value);
|
||||
SetResult setInternalSupplyVoltage(const std::string& value);
|
||||
SetResult setInternalVerifyCsmsAllowWildcards(const std::string& value);
|
||||
SetResult setInternalWaitForStopTransactionsOnResetTimeout(const std::string& value);
|
||||
|
||||
SetResult setInternalAllowOfflineTxForUnknownId(const std::string& value);
|
||||
SetResult setInternalAuthorizationCacheEnabled(const std::string& value);
|
||||
SetResult setInternalAuthorizeRemoteTxRequests(const std::string& value);
|
||||
SetResult setInternalBlinkRepeat(const std::string& value);
|
||||
SetResult setInternalClockAlignedDataInterval(const std::string& value);
|
||||
SetResult setInternalConnectionTimeOut(const std::string& value);
|
||||
SetResult setInternalConnectorPhaseRotation(const std::string& value);
|
||||
SetResult setInternalHeartbeatInterval(const std::string& value);
|
||||
SetResult setInternalLightIntensity(const std::string& value);
|
||||
SetResult setInternalLocalAuthorizeOffline(const std::string& value);
|
||||
SetResult setInternalLocalPreAuthorize(const std::string& value);
|
||||
SetResult setInternalMaxEnergyOnInvalidId(const std::string& value);
|
||||
SetResult setInternalMeterValuesAlignedData(const std::string& value);
|
||||
SetResult setInternalMeterValuesSampledData(const std::string& value);
|
||||
SetResult setInternalMeterValueSampleInterval(const std::string& value);
|
||||
SetResult setInternalMinimumStatusDuration(const std::string& value);
|
||||
SetResult setInternalResetRetries(const std::string& value);
|
||||
SetResult setInternalStopTransactionOnInvalidId(const std::string& value);
|
||||
SetResult setInternalStopTxnAlignedData(const std::string& value);
|
||||
SetResult setInternalStopTxnSampledData(const std::string& value);
|
||||
SetResult setInternalTransactionMessageAttempts(const std::string& value);
|
||||
SetResult setInternalTransactionMessageRetryInterval(const std::string& value);
|
||||
SetResult setInternalUnlockConnectorOnEVSideDisconnect(const std::string& value);
|
||||
SetResult setInternalWebsocketPingInterval(const std::string& value);
|
||||
|
||||
SetResult setInternalAuthorizationKey(const std::string& value);
|
||||
SetResult setInternalCpoName(const std::string& value);
|
||||
SetResult setInternalDisableSecurityEventNotifications(const std::string& value);
|
||||
SetResult setInternalSecurityProfile(const std::string& value);
|
||||
|
||||
SetResult setInternalISO15118CertificateManagementEnabled(const std::string& value);
|
||||
SetResult setInternalLocalAuthListEnabled(const std::string& value);
|
||||
|
||||
SetResult setInternalContractValidationOffline(const std::string& value);
|
||||
SetResult setInternalCentralContractValidationAllowed(const std::string& value);
|
||||
SetResult setInternalCertSigningRepeatTimes(const std::string& value);
|
||||
SetResult setInternalCertSigningWaitMinimum(const std::string& value);
|
||||
SetResult setInternalISO15118PnCEnabled(const std::string& value);
|
||||
|
||||
SetResult setInternalCustomIdleFeeAfterStop(const std::string& value);
|
||||
SetResult setInternalDefaultPrice(const std::string& value);
|
||||
SetResult setInternalDefaultPriceText(const std::string& key, const std::string& value);
|
||||
SetResult setInternalDisplayTimeOffset(const std::string& value);
|
||||
SetResult setInternalLanguage(const std::string& value);
|
||||
SetResult setInternalNextTimeOffsetTransitionDateTime(const std::string& value);
|
||||
SetResult setInternalTimeOffsetNextTransition(const std::string& value);
|
||||
SetResult setInternalWaitForSetUserPriceTimeout(const std::string& value);
|
||||
|
||||
std::optional<std::string> calculateEvseIds();
|
||||
std::string calculateSupportedMeasurands();
|
||||
|
||||
public:
|
||||
explicit ChargePointConfigurationDeviceModel(const std::string_view& ocpp_main_path,
|
||||
std::unique_ptr<v2::DeviceModelInterface> device_model_interface);
|
||||
virtual ~ChargePointConfigurationDeviceModel() = default;
|
||||
|
||||
// UserConfig and Internal
|
||||
std::string getChargeBoxSerialNumber() override;
|
||||
std::optional<CiString<25>> getChargePointSerialNumber() override;
|
||||
CiString<50> getFirmwareVersion() override;
|
||||
std::optional<CiString<20>> getICCID() override;
|
||||
std::optional<CiString<20>> getIMSI() override;
|
||||
std::optional<CiString<25>> getMeterSerialNumber() override;
|
||||
std::optional<CiString<25>> getMeterType() override;
|
||||
|
||||
KeyValue getChargeBoxSerialNumberKeyValue() override;
|
||||
KeyValue getFirmwareVersionKeyValue() override;
|
||||
|
||||
std::optional<KeyValue> getChargePointSerialNumberKeyValue() override;
|
||||
std::optional<KeyValue> getICCIDKeyValue() override;
|
||||
std::optional<KeyValue> getIMSIKeyValue() override;
|
||||
std::optional<KeyValue> getMeterSerialNumberKeyValue() override;
|
||||
std::optional<KeyValue> getMeterTypeKeyValue() override;
|
||||
|
||||
void setChargepointInformation(const std::string& chargePointVendor, const std::string& chargePointModel,
|
||||
const std::optional<std::string>& chargePointSerialNumber,
|
||||
const std::optional<std::string>& chargeBoxSerialNumber,
|
||||
const std::optional<std::string>& firmwareVersion) override;
|
||||
void setChargepointMeterInformation(const std::optional<std::string>& meterSerialNumber,
|
||||
const std::optional<std::string>& meterType) override;
|
||||
void setChargepointModemInformation(const std::optional<std::string>& ICCID,
|
||||
const std::optional<std::string>& IMSI) override;
|
||||
|
||||
// Internal
|
||||
std::string getCentralSystemURI() override;
|
||||
std::string getChargePointId() override;
|
||||
std::string getSupportedCiphers12() override;
|
||||
std::string getSupportedCiphers13() override;
|
||||
std::string getSupportedMeasurands() override;
|
||||
std::string getTLSKeylogFile() override;
|
||||
std::string getWebsocketPingPayload() override;
|
||||
|
||||
CiString<20> getChargePointModel() override;
|
||||
CiString<20> getChargePointVendor() override;
|
||||
|
||||
bool getAuthorizeConnectorZeroOnConnectorOne() override;
|
||||
bool getEnableTLSKeylog() override;
|
||||
bool getLogMessages() override;
|
||||
bool getLogMessagesRaw() override;
|
||||
bool getLogRotation() override;
|
||||
bool getLogRotationDateSuffix() override;
|
||||
bool getStopTransactionIfUnlockNotSupported() override;
|
||||
bool getUseSslDefaultVerifyPaths() override;
|
||||
bool getUseTPM() override;
|
||||
bool getUseTPMSeccLeafCertificate() override;
|
||||
bool getVerifyCsmsAllowWildcards() override;
|
||||
bool getVerifyCsmsCommonName() override;
|
||||
|
||||
int getMaxMessageSize() override;
|
||||
|
||||
std::int32_t getMaxCompositeScheduleDuration() override;
|
||||
std::int32_t getOcspRequestInterval() override;
|
||||
std::int32_t getRetryBackoffRandomRange() override;
|
||||
std::int32_t getRetryBackoffRepeatTimes() override;
|
||||
std::int32_t getRetryBackoffWaitMinimum() override;
|
||||
std::int32_t getWaitForStopTransactionsOnResetTimeout() override;
|
||||
std::int32_t getWebsocketPongTimeout() override;
|
||||
|
||||
std::uint64_t getLogRotationMaximumFileCount() override;
|
||||
std::uint64_t getLogRotationMaximumFileSize() override;
|
||||
|
||||
std::vector<std::string> getLogMessagesFormat() override;
|
||||
std::vector<ChargingProfilePurposeType> getIgnoredProfilePurposesOffline() override;
|
||||
std::vector<ChargingProfilePurposeType> getSupportedChargingProfilePurposeTypes() override;
|
||||
|
||||
std::optional<std::string> getConnectorEvseIds() override;
|
||||
std::optional<std::string> getHostName() override;
|
||||
std::optional<std::string> getIFace() override;
|
||||
std::optional<std::string> getMessageTypesDiscardForQueueing() override;
|
||||
std::optional<std::string> getSeccLeafSubjectCommonName() override;
|
||||
std::optional<std::string> getSeccLeafSubjectCountry() override;
|
||||
std::optional<std::string> getSeccLeafSubjectOrganization() override;
|
||||
std::optional<bool> getAllowChargingProfileWithoutStartSchedule() override;
|
||||
std::optional<bool> getQueueAllMessages() override;
|
||||
std::optional<int> getMessageQueueSizeThreshold() override;
|
||||
std::optional<std::int32_t> getCompositeScheduleDefaultLimitAmps() override;
|
||||
std::optional<std::int32_t> getCompositeScheduleDefaultLimitWatts() override;
|
||||
std::optional<std::int32_t> getCompositeScheduleDefaultNumberPhases() override;
|
||||
std::optional<std::int32_t> getSupplyVoltage() override;
|
||||
std::optional<std::vector<KeyValue>> getAllMeterPublicKeyKeyValues() override;
|
||||
|
||||
std::set<MessageType> getSupportedMessageTypesSending() override;
|
||||
std::set<MessageType> getSupportedMessageTypesReceiving() override;
|
||||
|
||||
KeyValue getAuthorizeConnectorZeroOnConnectorOneKeyValue() override;
|
||||
KeyValue getCentralSystemURIKeyValue() override;
|
||||
KeyValue getChargePointIdKeyValue() override;
|
||||
KeyValue getChargePointModelKeyValue() override;
|
||||
KeyValue getChargePointVendorKeyValue() override;
|
||||
KeyValue getEnableTLSKeylogKeyValue() override;
|
||||
KeyValue getLogMessagesFormatKeyValue() override;
|
||||
KeyValue getLogMessagesKeyValue() override;
|
||||
KeyValue getLogMessagesRawKeyValue() override;
|
||||
KeyValue getLogRotationDateSuffixKeyValue() override;
|
||||
KeyValue getLogRotationKeyValue() override;
|
||||
KeyValue getLogRotationMaximumFileCountKeyValue() override;
|
||||
KeyValue getLogRotationMaximumFileSizeKeyValue() override;
|
||||
KeyValue getMaxCompositeScheduleDurationKeyValue() override;
|
||||
KeyValue getMaxMessageSizeKeyValue() override;
|
||||
KeyValue getOcspRequestIntervalKeyValue() override;
|
||||
KeyValue getRetryBackoffRandomRangeKeyValue() override;
|
||||
KeyValue getRetryBackoffRepeatTimesKeyValue() override;
|
||||
KeyValue getRetryBackoffWaitMinimumKeyValue() override;
|
||||
KeyValue getStopTransactionIfUnlockNotSupportedKeyValue() override;
|
||||
KeyValue getSupportedChargingProfilePurposeTypesKeyValue() override;
|
||||
KeyValue getSupportedCiphers12KeyValue() override;
|
||||
KeyValue getSupportedCiphers13KeyValue() override;
|
||||
KeyValue getSupportedMeasurandsKeyValue() override;
|
||||
KeyValue getTLSKeylogFileKeyValue() override;
|
||||
KeyValue getUseSslDefaultVerifyPathsKeyValue() override;
|
||||
KeyValue getUseTPMKeyValue() override;
|
||||
KeyValue getUseTPMSeccLeafCertificateKeyValue() override;
|
||||
KeyValue getVerifyCsmsAllowWildcardsKeyValue() override;
|
||||
KeyValue getVerifyCsmsCommonNameKeyValue() override;
|
||||
KeyValue getWaitForStopTransactionsOnResetTimeoutKeyValue() override;
|
||||
KeyValue getWebsocketPingPayloadKeyValue() override;
|
||||
KeyValue getWebsocketPongTimeoutKeyValue() override;
|
||||
|
||||
std::optional<KeyValue> getAllowChargingProfileWithoutStartScheduleKeyValue() override;
|
||||
std::optional<KeyValue> getCompositeScheduleDefaultLimitAmpsKeyValue() override;
|
||||
std::optional<KeyValue> getCompositeScheduleDefaultLimitWattsKeyValue() override;
|
||||
std::optional<KeyValue> getCompositeScheduleDefaultNumberPhasesKeyValue() override;
|
||||
std::optional<KeyValue> getConnectorEvseIdsKeyValue() override;
|
||||
std::optional<KeyValue> getHostNameKeyValue() override;
|
||||
std::optional<KeyValue> getIFaceKeyValue() override;
|
||||
std::optional<KeyValue> getIgnoredProfilePurposesOfflineKeyValue() override;
|
||||
std::optional<KeyValue> getMessageTypesDiscardForQueueingKeyValue() override;
|
||||
std::optional<KeyValue> getMessageQueueSizeThresholdKeyValue() override;
|
||||
std::optional<KeyValue> getPublicKeyKeyValue(std::uint32_t connector_id) override;
|
||||
std::optional<KeyValue> getQueueAllMessagesKeyValue() override;
|
||||
std::optional<KeyValue> getSeccLeafSubjectCommonNameKeyValue() override;
|
||||
std::optional<KeyValue> getSeccLeafSubjectCountryKeyValue() override;
|
||||
std::optional<KeyValue> getSeccLeafSubjectOrganizationKeyValue() override;
|
||||
std::optional<KeyValue> getSupplyVoltageKeyValue() override;
|
||||
|
||||
void setAllowChargingProfileWithoutStartSchedule(bool allow) override;
|
||||
void setCentralSystemURI(const std::string& ocpp_uri) override;
|
||||
void setCompositeScheduleDefaultLimitAmps(std::int32_t limit_amps) override;
|
||||
void setCompositeScheduleDefaultLimitWatts(std::int32_t limit_watts) override;
|
||||
void setCompositeScheduleDefaultNumberPhases(std::int32_t number_phases) override;
|
||||
void setConnectorEvseIds(const std::string& connector_evse_ids) override;
|
||||
bool setIgnoredProfilePurposesOffline(const std::string& ignored_profile_purposes_offline) override;
|
||||
bool setMeterPublicKey(std::int32_t connector_id, const std::string& public_key_pem) override;
|
||||
void setOcspRequestInterval(std::int32_t ocsp_request_interval) override;
|
||||
void setRetryBackoffRandomRange(std::int32_t retry_backoff_random_range) override;
|
||||
void setRetryBackoffRepeatTimes(std::int32_t retry_backoff_repeat_times) override;
|
||||
void setRetryBackoffWaitMinimum(std::int32_t retry_backoff_wait_minimum) override;
|
||||
void setSeccLeafSubjectCommonName(const std::string& secc_leaf_subject_common_name) override;
|
||||
void setSeccLeafSubjectCountry(const std::string& secc_leaf_subject_country) override;
|
||||
void setSeccLeafSubjectOrganization(const std::string& secc_leaf_subject_organization) override;
|
||||
void setStopTransactionIfUnlockNotSupported(bool stop_transaction_if_unlock_not_supported) override;
|
||||
void setSupplyVoltage(std::int32_t supply_voltage) override;
|
||||
void setVerifyCsmsAllowWildcards(bool verify_csms_allow_wildcards) override;
|
||||
void setWaitForStopTransactionsOnResetTimeout(std::int32_t wait_for_stop_transactions_on_reset_timeout) override;
|
||||
|
||||
// Core Profile
|
||||
std::string getConnectorPhaseRotation() override;
|
||||
std::string getMeterValuesAlignedData() override;
|
||||
std::string getMeterValuesSampledData() override;
|
||||
std::string getStopTxnAlignedData() override;
|
||||
std::string getStopTxnSampledData() override;
|
||||
std::string getSupportedFeatureProfiles() override;
|
||||
|
||||
bool getAuthorizeRemoteTxRequests() override;
|
||||
bool getLocalAuthorizeOffline() override;
|
||||
bool getLocalPreAuthorize() override;
|
||||
bool getStopTransactionOnInvalidId() override;
|
||||
bool getUnlockConnectorOnEVSideDisconnect() override;
|
||||
|
||||
std::int32_t getClockAlignedDataInterval() override;
|
||||
std::int32_t getConnectionTimeOut() override;
|
||||
std::int32_t getGetConfigurationMaxKeys() override;
|
||||
std::int32_t getHeartbeatInterval() override;
|
||||
std::int32_t getMeterValueSampleInterval() override;
|
||||
std::int32_t getNumberOfConnectors() override;
|
||||
std::int32_t getResetRetries() override;
|
||||
std::int32_t getTransactionMessageAttempts() override;
|
||||
std::int32_t getTransactionMessageRetryInterval() override;
|
||||
|
||||
std::vector<MeasurandWithPhase> getMeterValuesAlignedDataVector() override;
|
||||
std::vector<MeasurandWithPhase> getMeterValuesSampledDataVector() override;
|
||||
|
||||
std::optional<bool> getAllowOfflineTxForUnknownId() override;
|
||||
std::optional<bool> getAuthorizationCacheEnabled() override;
|
||||
std::optional<bool> getReserveConnectorZeroSupported() override;
|
||||
std::optional<bool> getStopTransactionOnEVSideDisconnect() override;
|
||||
std::optional<std::int32_t> getBlinkRepeat() override;
|
||||
std::optional<std::int32_t> getConnectorPhaseRotationMaxLength() override;
|
||||
std::optional<std::int32_t> getLightIntensity() override;
|
||||
std::optional<std::int32_t> getMaxEnergyOnInvalidId() override;
|
||||
std::optional<std::int32_t> getMeterValuesAlignedDataMaxLength() override;
|
||||
std::optional<std::int32_t> getMeterValuesSampledDataMaxLength() override;
|
||||
std::optional<std::int32_t> getMinimumStatusDuration() override;
|
||||
std::optional<std::int32_t> getStopTxnAlignedDataMaxLength() override;
|
||||
std::optional<std::int32_t> getStopTxnSampledDataMaxLength() override;
|
||||
std::optional<std::int32_t> getSupportedFeatureProfilesMaxLength() override;
|
||||
std::optional<std::int32_t> getWebsocketPingInterval() override;
|
||||
|
||||
std::set<SupportedFeatureProfiles> getSupportedFeatureProfilesSet() override;
|
||||
|
||||
KeyValue getAuthorizeRemoteTxRequestsKeyValue() override;
|
||||
KeyValue getClockAlignedDataIntervalKeyValue() override;
|
||||
KeyValue getConnectionTimeOutKeyValue() override;
|
||||
KeyValue getConnectorPhaseRotationKeyValue() override;
|
||||
KeyValue getGetConfigurationMaxKeysKeyValue() override;
|
||||
KeyValue getHeartbeatIntervalKeyValue() override;
|
||||
KeyValue getLocalAuthorizeOfflineKeyValue() override;
|
||||
KeyValue getLocalPreAuthorizeKeyValue() override;
|
||||
KeyValue getMeterValuesAlignedDataKeyValue() override;
|
||||
KeyValue getMeterValueSampleIntervalKeyValue() override;
|
||||
KeyValue getMeterValuesSampledDataKeyValue() override;
|
||||
KeyValue getNumberOfConnectorsKeyValue() override;
|
||||
KeyValue getResetRetriesKeyValue() override;
|
||||
KeyValue getStopTransactionOnInvalidIdKeyValue() override;
|
||||
KeyValue getStopTxnAlignedDataKeyValue() override;
|
||||
KeyValue getStopTxnSampledDataKeyValue() override;
|
||||
KeyValue getSupportedFeatureProfilesKeyValue() override;
|
||||
KeyValue getTransactionMessageAttemptsKeyValue() override;
|
||||
KeyValue getTransactionMessageRetryIntervalKeyValue() override;
|
||||
KeyValue getUnlockConnectorOnEVSideDisconnectKeyValue() override;
|
||||
|
||||
std::optional<KeyValue> getAllowOfflineTxForUnknownIdKeyValue() override;
|
||||
std::optional<KeyValue> getAuthorizationCacheEnabledKeyValue() override;
|
||||
std::optional<KeyValue> getBlinkRepeatKeyValue() override;
|
||||
std::optional<KeyValue> getConnectorPhaseRotationMaxLengthKeyValue() override;
|
||||
std::optional<KeyValue> getLightIntensityKeyValue() override;
|
||||
std::optional<KeyValue> getMaxEnergyOnInvalidIdKeyValue() override;
|
||||
std::optional<KeyValue> getMeterValuesAlignedDataMaxLengthKeyValue() override;
|
||||
std::optional<KeyValue> getMeterValuesSampledDataMaxLengthKeyValue() override;
|
||||
std::optional<KeyValue> getMinimumStatusDurationKeyValue() override;
|
||||
std::optional<KeyValue> getReserveConnectorZeroSupportedKeyValue() override;
|
||||
std::optional<KeyValue> getStopTransactionOnEVSideDisconnectKeyValue() override;
|
||||
std::optional<KeyValue> getStopTxnAlignedDataMaxLengthKeyValue() override;
|
||||
std::optional<KeyValue> getStopTxnSampledDataMaxLengthKeyValue() override;
|
||||
std::optional<KeyValue> getSupportedFeatureProfilesMaxLengthKeyValue() override;
|
||||
std::optional<KeyValue> getWebsocketPingIntervalKeyValue() override;
|
||||
|
||||
void setAllowOfflineTxForUnknownId(bool enabled) override;
|
||||
void setAuthorizationCacheEnabled(bool enabled) override;
|
||||
void setAuthorizeRemoteTxRequests(bool enabled) override;
|
||||
void setBlinkRepeat(std::int32_t blink_repeat) override;
|
||||
void setClockAlignedDataInterval(std::int32_t interval) override;
|
||||
void setConnectionTimeOut(std::int32_t timeout) override;
|
||||
void setConnectorPhaseRotation(const std::string& connector_phase_rotation) override;
|
||||
void setHeartbeatInterval(std::int32_t interval) override;
|
||||
void setLightIntensity(std::int32_t light_intensity) override;
|
||||
void setLocalAuthorizeOffline(bool local_authorize_offline) override;
|
||||
void setLocalPreAuthorize(bool local_pre_authorize) override;
|
||||
void setMaxEnergyOnInvalidId(std::int32_t max_energy) override;
|
||||
bool setMeterValuesAlignedData(const std::string& meter_values_aligned_data) override;
|
||||
bool setMeterValuesSampledData(const std::string& meter_values_sampled_data) override;
|
||||
void setMeterValueSampleInterval(std::int32_t interval) override;
|
||||
void setMinimumStatusDuration(std::int32_t minimum_status_duration) override;
|
||||
void setResetRetries(std::int32_t retries) override;
|
||||
void setStopTransactionOnInvalidId(bool stop_transaction_on_invalid_id) override;
|
||||
bool setStopTxnAlignedData(const std::string& stop_txn_aligned_data) override;
|
||||
bool setStopTxnSampledData(const std::string& stop_txn_sampled_data) override;
|
||||
void setTransactionMessageAttempts(std::int32_t attempts) override;
|
||||
void setTransactionMessageRetryInterval(std::int32_t retry_interval) override;
|
||||
void setUnlockConnectorOnEVSideDisconnect(bool unlock_connector_on_ev_side_disconnect) override;
|
||||
void setWebsocketPingInterval(std::int32_t websocket_ping_interval) override;
|
||||
|
||||
// Firmware Management Profile
|
||||
std::optional<std::string> getSupportedFileTransferProtocols() override;
|
||||
std::optional<KeyValue> getSupportedFileTransferProtocolsKeyValue() override;
|
||||
|
||||
// Smart Charging Profile
|
||||
std::string getChargingScheduleAllowedChargingRateUnit() override;
|
||||
std::int32_t getChargeProfileMaxStackLevel() override;
|
||||
std::int32_t getChargingScheduleMaxPeriods() override;
|
||||
std::int32_t getMaxChargingProfilesInstalled() override;
|
||||
|
||||
std::optional<bool> getConnectorSwitch3to1PhaseSupported() override;
|
||||
|
||||
std::vector<ChargingRateUnit> getChargingScheduleAllowedChargingRateUnitVector() override;
|
||||
|
||||
KeyValue getChargeProfileMaxStackLevelKeyValue() override;
|
||||
KeyValue getChargingScheduleAllowedChargingRateUnitKeyValue() override;
|
||||
KeyValue getChargingScheduleMaxPeriodsKeyValue() override;
|
||||
KeyValue getMaxChargingProfilesInstalledKeyValue() override;
|
||||
|
||||
std::optional<KeyValue> getConnectorSwitch3to1PhaseSupportedKeyValue() override;
|
||||
|
||||
// Security Profile
|
||||
bool getDisableSecurityEventNotifications() override;
|
||||
std::int32_t getSecurityProfile() override;
|
||||
|
||||
std::optional<std::string> getAuthorizationKey() override;
|
||||
std::optional<std::string> getCpoName() override;
|
||||
std::optional<bool> getAdditionalRootCertificateCheck() override;
|
||||
std::optional<std::int32_t> getCertificateSignedMaxChainSize() override;
|
||||
std::optional<std::int32_t> getCertificateStoreMaxLength() override;
|
||||
|
||||
KeyValue getDisableSecurityEventNotificationsKeyValue() override;
|
||||
KeyValue getSecurityProfileKeyValue() override;
|
||||
|
||||
std::optional<KeyValue> getAdditionalRootCertificateCheckKeyValue() override;
|
||||
std::optional<KeyValue> getAuthorizationKeyKeyValue() override;
|
||||
std::optional<KeyValue> getCertificateSignedMaxChainSizeKeyValue() override;
|
||||
std::optional<KeyValue> getCertificateStoreMaxLengthKeyValue() override;
|
||||
std::optional<KeyValue> getCpoNameKeyValue() override;
|
||||
|
||||
void setAuthorizationKey(const std::string& authorization_key) override;
|
||||
void setCpoName(const std::string& cpo_name) override;
|
||||
void setDisableSecurityEventNotifications(bool disable_security_event_notifications) override;
|
||||
void setSecurityProfile(std::int32_t security_profile) override;
|
||||
|
||||
// Local Auth List Management Profile
|
||||
bool getLocalAuthListEnabled() override;
|
||||
std::int32_t getLocalAuthListMaxLength() override;
|
||||
std::int32_t getSendLocalListMaxLength() override;
|
||||
|
||||
KeyValue getLocalAuthListEnabledKeyValue() override;
|
||||
KeyValue getLocalAuthListMaxLengthKeyValue() override;
|
||||
KeyValue getSendLocalListMaxLengthKeyValue() override;
|
||||
|
||||
void setLocalAuthListEnabled(bool local_auth_list_enabled) override;
|
||||
|
||||
// PnC
|
||||
bool getContractValidationOffline() override;
|
||||
bool getISO15118CertificateManagementEnabled() override;
|
||||
bool getISO15118PnCEnabled() override;
|
||||
|
||||
std::optional<bool> getCentralContractValidationAllowed() override;
|
||||
std::optional<std::int32_t> getCertSigningRepeatTimes() override;
|
||||
std::optional<std::int32_t> getCertSigningWaitMinimum() override;
|
||||
|
||||
KeyValue getContractValidationOfflineKeyValue() override;
|
||||
KeyValue getISO15118CertificateManagementEnabledKeyValue() override;
|
||||
KeyValue getISO15118PnCEnabledKeyValue() override;
|
||||
|
||||
std::optional<KeyValue> getCentralContractValidationAllowedKeyValue() override;
|
||||
std::optional<KeyValue> getCertSigningRepeatTimesKeyValue() override;
|
||||
std::optional<KeyValue> getCertSigningWaitMinimumKeyValue() override;
|
||||
|
||||
void setContractValidationOffline(bool contract_validation_offline) override;
|
||||
void setCentralContractValidationAllowed(bool central_contract_validation_allowed) override;
|
||||
void setCertSigningRepeatTimes(std::int32_t cert_signing_repeat_times) override;
|
||||
void setCertSigningWaitMinimum(std::int32_t cert_signing_wait_minimum) override;
|
||||
void setISO15118CertificateManagementEnabled(bool iso15118_certificate_management_enabled) override;
|
||||
void setISO15118PnCEnabled(bool iso15118_pnc_enabled) override;
|
||||
|
||||
// California Pricing Requirements
|
||||
bool getCustomDisplayCostAndPriceEnabled() override;
|
||||
|
||||
TariffMessage getDefaultTariffMessage(bool offline) override;
|
||||
|
||||
std::optional<std::string> getDefaultPrice() override;
|
||||
std::optional<std::string> getDefaultPriceText(const std::string& language) override;
|
||||
std::optional<std::string> getDisplayTimeOffset() override;
|
||||
std::optional<std::string> getLanguage() override;
|
||||
std::optional<std::string> getMultiLanguageSupportedLanguages() override;
|
||||
std::optional<std::string> getNextTimeOffsetTransitionDateTime() override;
|
||||
std::optional<std::string> getTimeOffsetNextTransition() override;
|
||||
std::optional<bool> getCustomIdleFeeAfterStop() override;
|
||||
std::optional<bool> getCustomMultiLanguageMessagesEnabled() override;
|
||||
std::optional<std::int32_t> getWaitForSetUserPriceTimeout() override;
|
||||
std::optional<std::uint32_t> getPriceNumberOfDecimalsForCostValues() override;
|
||||
|
||||
KeyValue getCustomDisplayCostAndPriceEnabledKeyValue() override;
|
||||
KeyValue getDefaultPriceTextKeyValue(const std::string& language) override;
|
||||
|
||||
std::optional<KeyValue> getCustomIdleFeeAfterStopKeyValue() override;
|
||||
std::optional<KeyValue> getCustomMultiLanguageMessagesEnabledKeyValue() override;
|
||||
std::optional<KeyValue> getDefaultPriceKeyValue() override;
|
||||
std::optional<KeyValue> getDisplayTimeOffsetKeyValue() override;
|
||||
std::optional<KeyValue> getLanguageKeyValue() override;
|
||||
std::optional<KeyValue> getMultiLanguageSupportedLanguagesKeyValue() override;
|
||||
std::optional<KeyValue> getNextTimeOffsetTransitionDateTimeKeyValue() override;
|
||||
std::optional<KeyValue> getPriceNumberOfDecimalsForCostValuesKeyValue() override;
|
||||
std::optional<KeyValue> getTimeOffsetNextTransitionKeyValue() override;
|
||||
std::optional<KeyValue> getWaitForSetUserPriceTimeoutKeyValue() override;
|
||||
|
||||
std::optional<std::vector<KeyValue>> getAllDefaultPriceTextKeyValues() override;
|
||||
|
||||
void setCustomIdleFeeAfterStop(bool value) override;
|
||||
ConfigurationStatus setDefaultPrice(const std::string& value) override;
|
||||
ConfigurationStatus setDefaultPriceText(const CiString<50>& key, const CiString<500>& value) override;
|
||||
ConfigurationStatus setDisplayTimeOffset(const std::string& offset) override;
|
||||
void setLanguage(const std::string& language) override;
|
||||
ConfigurationStatus setNextTimeOffsetTransitionDateTime(const std::string& date_time) override;
|
||||
ConfigurationStatus setTimeOffsetNextTransition(const std::string& offset) override;
|
||||
void setWaitForSetUserPriceTimeout(std::int32_t wait_for_set_user_price_timeout) override;
|
||||
|
||||
// Custom
|
||||
std::optional<KeyValue> getCustomKeyValue(const CiString<50>& key) override;
|
||||
std::optional<KeyValue> get(const CiString<50>& key) override;
|
||||
std::vector<KeyValue> get_all_key_value() override;
|
||||
|
||||
ConfigurationStatus setCustomKey(const CiString<50>& key, const CiString<500>& value, bool force) override;
|
||||
std::optional<ConfigurationStatus> set(const CiString<50>& key, const CiString<500>& value) override;
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_CHARGE_POINT_CONFIGURATION_DEVICEMODEL_HPP
|
||||
@@ -0,0 +1,425 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2026 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_V16_CHARGE_POINT_CONFIGURATION_INTERFACE_HPP
|
||||
#define OCPP_V16_CHARGE_POINT_CONFIGURATION_INTERFACE_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <ocpp/common/cistring.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
namespace ocpp::v16 {
|
||||
|
||||
struct KeyValue;
|
||||
|
||||
/// \brief contains the configuration of the charge point
|
||||
class ChargePointConfigurationInterface {
|
||||
public:
|
||||
virtual ~ChargePointConfigurationInterface() = default;
|
||||
// UserConfig and Internal
|
||||
virtual std::string getChargeBoxSerialNumber() = 0;
|
||||
virtual std::optional<CiString<25>> getChargePointSerialNumber() = 0;
|
||||
virtual CiString<50> getFirmwareVersion() = 0;
|
||||
virtual std::optional<CiString<20>> getICCID() = 0;
|
||||
virtual std::optional<CiString<20>> getIMSI() = 0;
|
||||
virtual std::optional<CiString<25>> getMeterSerialNumber() = 0;
|
||||
virtual std::optional<CiString<25>> getMeterType() = 0;
|
||||
|
||||
virtual KeyValue getChargeBoxSerialNumberKeyValue() = 0;
|
||||
virtual KeyValue getFirmwareVersionKeyValue() = 0;
|
||||
|
||||
virtual std::optional<KeyValue> getChargePointSerialNumberKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getICCIDKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getIMSIKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getMeterSerialNumberKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getMeterTypeKeyValue() = 0;
|
||||
|
||||
virtual void setChargepointInformation(const std::string& chargePointVendor, const std::string& chargePointModel,
|
||||
const std::optional<std::string>& chargePointSerialNumber,
|
||||
const std::optional<std::string>& chargeBoxSerialNumber,
|
||||
const std::optional<std::string>& firmwareVersion) = 0;
|
||||
virtual void setChargepointMeterInformation(const std::optional<std::string>& meterSerialNumber,
|
||||
const std::optional<std::string>& meterType) = 0;
|
||||
virtual void setChargepointModemInformation(const std::optional<std::string>& ICCID,
|
||||
const std::optional<std::string>& IMSI) = 0;
|
||||
|
||||
// Internal
|
||||
virtual std::string getCentralSystemURI() = 0;
|
||||
virtual std::string getChargePointId() = 0;
|
||||
virtual std::string getSupportedCiphers12() = 0;
|
||||
virtual std::string getSupportedCiphers13() = 0;
|
||||
virtual std::string getSupportedMeasurands() = 0;
|
||||
virtual std::string getTLSKeylogFile() = 0;
|
||||
virtual std::string getWebsocketPingPayload() = 0;
|
||||
|
||||
virtual CiString<20> getChargePointModel() = 0;
|
||||
virtual CiString<20> getChargePointVendor() = 0;
|
||||
|
||||
virtual bool getAuthorizeConnectorZeroOnConnectorOne() = 0;
|
||||
virtual bool getEnableTLSKeylog() = 0;
|
||||
virtual bool getLogMessages() = 0;
|
||||
virtual bool getLogMessagesRaw() = 0;
|
||||
virtual bool getLogRotation() = 0;
|
||||
virtual bool getLogRotationDateSuffix() = 0;
|
||||
virtual bool getStopTransactionIfUnlockNotSupported() = 0;
|
||||
virtual bool getUseSslDefaultVerifyPaths() = 0;
|
||||
virtual bool getUseTPM() = 0;
|
||||
virtual bool getUseTPMSeccLeafCertificate() = 0;
|
||||
virtual bool getVerifyCsmsAllowWildcards() = 0;
|
||||
virtual bool getVerifyCsmsCommonName() = 0;
|
||||
|
||||
virtual int getMaxMessageSize() = 0;
|
||||
|
||||
virtual std::int32_t getMaxCompositeScheduleDuration() = 0;
|
||||
virtual std::int32_t getOcspRequestInterval() = 0;
|
||||
virtual std::int32_t getRetryBackoffRandomRange() = 0;
|
||||
virtual std::int32_t getRetryBackoffRepeatTimes() = 0;
|
||||
virtual std::int32_t getRetryBackoffWaitMinimum() = 0;
|
||||
virtual std::int32_t getWaitForStopTransactionsOnResetTimeout() = 0;
|
||||
virtual std::int32_t getWebsocketPongTimeout() = 0;
|
||||
|
||||
virtual std::uint64_t getLogRotationMaximumFileCount() = 0;
|
||||
virtual std::uint64_t getLogRotationMaximumFileSize() = 0;
|
||||
|
||||
virtual std::vector<std::string> getLogMessagesFormat() = 0;
|
||||
virtual std::vector<ChargingProfilePurposeType> getIgnoredProfilePurposesOffline() = 0;
|
||||
virtual std::vector<ChargingProfilePurposeType> getSupportedChargingProfilePurposeTypes() = 0;
|
||||
|
||||
virtual std::optional<std::string> getConnectorEvseIds() = 0;
|
||||
virtual std::optional<std::string> getHostName() = 0;
|
||||
virtual std::optional<std::string> getIFace() = 0;
|
||||
virtual std::optional<std::string> getMessageTypesDiscardForQueueing() = 0;
|
||||
virtual std::optional<std::string> getSeccLeafSubjectCommonName() = 0;
|
||||
virtual std::optional<std::string> getSeccLeafSubjectCountry() = 0;
|
||||
virtual std::optional<std::string> getSeccLeafSubjectOrganization() = 0;
|
||||
virtual std::optional<bool> getAllowChargingProfileWithoutStartSchedule() = 0;
|
||||
virtual std::optional<bool> getQueueAllMessages() = 0;
|
||||
virtual std::optional<int> getMessageQueueSizeThreshold() = 0;
|
||||
virtual std::optional<std::int32_t> getCompositeScheduleDefaultLimitAmps() = 0;
|
||||
virtual std::optional<std::int32_t> getCompositeScheduleDefaultLimitWatts() = 0;
|
||||
virtual std::optional<std::int32_t> getCompositeScheduleDefaultNumberPhases() = 0;
|
||||
virtual std::optional<std::int32_t> getSupplyVoltage() = 0;
|
||||
virtual std::optional<std::vector<KeyValue>> getAllMeterPublicKeyKeyValues() = 0;
|
||||
|
||||
virtual std::set<MessageType> getSupportedMessageTypesSending() = 0;
|
||||
virtual std::set<MessageType> getSupportedMessageTypesReceiving() = 0;
|
||||
|
||||
virtual KeyValue getAuthorizeConnectorZeroOnConnectorOneKeyValue() = 0;
|
||||
virtual KeyValue getCentralSystemURIKeyValue() = 0;
|
||||
virtual KeyValue getChargePointIdKeyValue() = 0;
|
||||
virtual KeyValue getChargePointModelKeyValue() = 0;
|
||||
virtual KeyValue getChargePointVendorKeyValue() = 0;
|
||||
virtual KeyValue getEnableTLSKeylogKeyValue() = 0;
|
||||
virtual KeyValue getLogMessagesFormatKeyValue() = 0;
|
||||
virtual KeyValue getLogMessagesKeyValue() = 0;
|
||||
virtual KeyValue getLogMessagesRawKeyValue() = 0;
|
||||
virtual KeyValue getLogRotationDateSuffixKeyValue() = 0;
|
||||
virtual KeyValue getLogRotationKeyValue() = 0;
|
||||
virtual KeyValue getLogRotationMaximumFileCountKeyValue() = 0;
|
||||
virtual KeyValue getLogRotationMaximumFileSizeKeyValue() = 0;
|
||||
virtual KeyValue getMaxCompositeScheduleDurationKeyValue() = 0;
|
||||
virtual KeyValue getMaxMessageSizeKeyValue() = 0;
|
||||
virtual KeyValue getOcspRequestIntervalKeyValue() = 0;
|
||||
virtual KeyValue getRetryBackoffRandomRangeKeyValue() = 0;
|
||||
virtual KeyValue getRetryBackoffRepeatTimesKeyValue() = 0;
|
||||
virtual KeyValue getRetryBackoffWaitMinimumKeyValue() = 0;
|
||||
virtual KeyValue getStopTransactionIfUnlockNotSupportedKeyValue() = 0;
|
||||
virtual KeyValue getSupportedChargingProfilePurposeTypesKeyValue() = 0;
|
||||
virtual KeyValue getSupportedCiphers12KeyValue() = 0;
|
||||
virtual KeyValue getSupportedCiphers13KeyValue() = 0;
|
||||
virtual KeyValue getSupportedMeasurandsKeyValue() = 0;
|
||||
virtual KeyValue getTLSKeylogFileKeyValue() = 0;
|
||||
virtual KeyValue getUseSslDefaultVerifyPathsKeyValue() = 0;
|
||||
virtual KeyValue getUseTPMKeyValue() = 0;
|
||||
virtual KeyValue getUseTPMSeccLeafCertificateKeyValue() = 0;
|
||||
virtual KeyValue getVerifyCsmsAllowWildcardsKeyValue() = 0;
|
||||
virtual KeyValue getVerifyCsmsCommonNameKeyValue() = 0;
|
||||
virtual KeyValue getWaitForStopTransactionsOnResetTimeoutKeyValue() = 0;
|
||||
virtual KeyValue getWebsocketPingPayloadKeyValue() = 0;
|
||||
virtual KeyValue getWebsocketPongTimeoutKeyValue() = 0;
|
||||
|
||||
virtual std::optional<KeyValue> getAllowChargingProfileWithoutStartScheduleKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getCompositeScheduleDefaultLimitAmpsKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getCompositeScheduleDefaultLimitWattsKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getCompositeScheduleDefaultNumberPhasesKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getConnectorEvseIdsKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getHostNameKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getIFaceKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getIgnoredProfilePurposesOfflineKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getMessageTypesDiscardForQueueingKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getMessageQueueSizeThresholdKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getPublicKeyKeyValue(std::uint32_t connector_id) = 0;
|
||||
virtual std::optional<KeyValue> getQueueAllMessagesKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getSeccLeafSubjectCommonNameKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getSeccLeafSubjectCountryKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getSeccLeafSubjectOrganizationKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getSupplyVoltageKeyValue() = 0;
|
||||
|
||||
virtual void setAllowChargingProfileWithoutStartSchedule(bool allow) = 0;
|
||||
virtual void setCentralSystemURI(const std::string& ocpp_uri) = 0;
|
||||
virtual void setCompositeScheduleDefaultLimitAmps(std::int32_t limit_amps) = 0;
|
||||
virtual void setCompositeScheduleDefaultLimitWatts(std::int32_t limit_watts) = 0;
|
||||
virtual void setCompositeScheduleDefaultNumberPhases(std::int32_t number_phases) = 0;
|
||||
virtual void setConnectorEvseIds(const std::string& connector_evse_ids) = 0;
|
||||
virtual bool setIgnoredProfilePurposesOffline(const std::string& ignored_profile_purposes_offline) = 0;
|
||||
virtual bool setMeterPublicKey(std::int32_t connector_id, const std::string& public_key_pem) = 0;
|
||||
virtual void setOcspRequestInterval(std::int32_t ocsp_request_interval) = 0;
|
||||
virtual void setRetryBackoffRandomRange(std::int32_t retry_backoff_random_range) = 0;
|
||||
virtual void setRetryBackoffRepeatTimes(std::int32_t retry_backoff_repeat_times) = 0;
|
||||
virtual void setRetryBackoffWaitMinimum(std::int32_t retry_backoff_wait_minimum) = 0;
|
||||
virtual void setSeccLeafSubjectCommonName(const std::string& secc_leaf_subject_common_name) = 0;
|
||||
virtual void setSeccLeafSubjectCountry(const std::string& secc_leaf_subject_country) = 0;
|
||||
virtual void setSeccLeafSubjectOrganization(const std::string& secc_leaf_subject_organization) = 0;
|
||||
virtual void setStopTransactionIfUnlockNotSupported(bool stop_transaction_if_unlock_not_supported) = 0;
|
||||
virtual void setSupplyVoltage(std::int32_t supply_voltage) = 0;
|
||||
virtual void setVerifyCsmsAllowWildcards(bool verify_csms_allow_wildcards) = 0;
|
||||
virtual void setWaitForStopTransactionsOnResetTimeout(std::int32_t wait_for_stop_transactions_on_reset_timeout) = 0;
|
||||
|
||||
// Core Profile
|
||||
virtual std::string getConnectorPhaseRotation() = 0;
|
||||
virtual std::string getMeterValuesAlignedData() = 0;
|
||||
virtual std::string getMeterValuesSampledData() = 0;
|
||||
virtual std::string getStopTxnAlignedData() = 0;
|
||||
virtual std::string getStopTxnSampledData() = 0;
|
||||
virtual std::string getSupportedFeatureProfiles() = 0;
|
||||
|
||||
virtual bool getAuthorizeRemoteTxRequests() = 0;
|
||||
virtual bool getLocalAuthorizeOffline() = 0;
|
||||
virtual bool getLocalPreAuthorize() = 0;
|
||||
virtual bool getStopTransactionOnInvalidId() = 0;
|
||||
virtual bool getUnlockConnectorOnEVSideDisconnect() = 0;
|
||||
|
||||
virtual std::int32_t getClockAlignedDataInterval() = 0;
|
||||
virtual std::int32_t getConnectionTimeOut() = 0;
|
||||
virtual std::int32_t getGetConfigurationMaxKeys() = 0;
|
||||
virtual std::int32_t getHeartbeatInterval() = 0;
|
||||
virtual std::int32_t getMeterValueSampleInterval() = 0;
|
||||
virtual std::int32_t getNumberOfConnectors() = 0;
|
||||
virtual std::int32_t getResetRetries() = 0;
|
||||
virtual std::int32_t getTransactionMessageAttempts() = 0;
|
||||
virtual std::int32_t getTransactionMessageRetryInterval() = 0;
|
||||
|
||||
virtual std::vector<MeasurandWithPhase> getMeterValuesAlignedDataVector() = 0;
|
||||
virtual std::vector<MeasurandWithPhase> getMeterValuesSampledDataVector() = 0;
|
||||
|
||||
virtual std::optional<bool> getAllowOfflineTxForUnknownId() = 0;
|
||||
virtual std::optional<bool> getAuthorizationCacheEnabled() = 0;
|
||||
virtual std::optional<bool> getReserveConnectorZeroSupported() = 0;
|
||||
virtual std::optional<bool> getStopTransactionOnEVSideDisconnect() = 0;
|
||||
virtual std::optional<std::int32_t> getBlinkRepeat() = 0;
|
||||
virtual std::optional<std::int32_t> getConnectorPhaseRotationMaxLength() = 0;
|
||||
virtual std::optional<std::int32_t> getLightIntensity() = 0;
|
||||
virtual std::optional<std::int32_t> getMaxEnergyOnInvalidId() = 0;
|
||||
virtual std::optional<std::int32_t> getMeterValuesAlignedDataMaxLength() = 0;
|
||||
virtual std::optional<std::int32_t> getMeterValuesSampledDataMaxLength() = 0;
|
||||
virtual std::optional<std::int32_t> getMinimumStatusDuration() = 0;
|
||||
virtual std::optional<std::int32_t> getStopTxnAlignedDataMaxLength() = 0;
|
||||
virtual std::optional<std::int32_t> getStopTxnSampledDataMaxLength() = 0;
|
||||
virtual std::optional<std::int32_t> getSupportedFeatureProfilesMaxLength() = 0;
|
||||
virtual std::optional<std::int32_t> getWebsocketPingInterval() = 0;
|
||||
|
||||
virtual std::set<SupportedFeatureProfiles> getSupportedFeatureProfilesSet() = 0;
|
||||
|
||||
virtual KeyValue getAuthorizeRemoteTxRequestsKeyValue() = 0;
|
||||
virtual KeyValue getClockAlignedDataIntervalKeyValue() = 0;
|
||||
virtual KeyValue getConnectionTimeOutKeyValue() = 0;
|
||||
virtual KeyValue getConnectorPhaseRotationKeyValue() = 0;
|
||||
virtual KeyValue getGetConfigurationMaxKeysKeyValue() = 0;
|
||||
virtual KeyValue getHeartbeatIntervalKeyValue() = 0;
|
||||
virtual KeyValue getLocalAuthorizeOfflineKeyValue() = 0;
|
||||
virtual KeyValue getLocalPreAuthorizeKeyValue() = 0;
|
||||
virtual KeyValue getMeterValuesAlignedDataKeyValue() = 0;
|
||||
virtual KeyValue getMeterValueSampleIntervalKeyValue() = 0;
|
||||
virtual KeyValue getMeterValuesSampledDataKeyValue() = 0;
|
||||
virtual KeyValue getNumberOfConnectorsKeyValue() = 0;
|
||||
virtual KeyValue getResetRetriesKeyValue() = 0;
|
||||
virtual KeyValue getStopTransactionOnInvalidIdKeyValue() = 0;
|
||||
virtual KeyValue getStopTxnAlignedDataKeyValue() = 0;
|
||||
virtual KeyValue getStopTxnSampledDataKeyValue() = 0;
|
||||
virtual KeyValue getSupportedFeatureProfilesKeyValue() = 0;
|
||||
virtual KeyValue getTransactionMessageAttemptsKeyValue() = 0;
|
||||
virtual KeyValue getTransactionMessageRetryIntervalKeyValue() = 0;
|
||||
virtual KeyValue getUnlockConnectorOnEVSideDisconnectKeyValue() = 0;
|
||||
|
||||
virtual std::optional<KeyValue> getAllowOfflineTxForUnknownIdKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getAuthorizationCacheEnabledKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getBlinkRepeatKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getConnectorPhaseRotationMaxLengthKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getLightIntensityKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getMaxEnergyOnInvalidIdKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getMeterValuesAlignedDataMaxLengthKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getMeterValuesSampledDataMaxLengthKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getMinimumStatusDurationKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getReserveConnectorZeroSupportedKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getStopTransactionOnEVSideDisconnectKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getStopTxnAlignedDataMaxLengthKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getStopTxnSampledDataMaxLengthKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getSupportedFeatureProfilesMaxLengthKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getWebsocketPingIntervalKeyValue() = 0;
|
||||
|
||||
virtual void setAllowOfflineTxForUnknownId(bool enabled) = 0;
|
||||
virtual void setAuthorizationCacheEnabled(bool enabled) = 0;
|
||||
virtual void setAuthorizeRemoteTxRequests(bool enabled) = 0;
|
||||
virtual void setBlinkRepeat(std::int32_t blink_repeat) = 0;
|
||||
virtual void setClockAlignedDataInterval(std::int32_t interval) = 0;
|
||||
virtual void setConnectionTimeOut(std::int32_t timeout) = 0;
|
||||
virtual void setConnectorPhaseRotation(const std::string& connector_phase_rotation) = 0;
|
||||
virtual void setHeartbeatInterval(std::int32_t interval) = 0;
|
||||
virtual void setLightIntensity(std::int32_t light_intensity) = 0;
|
||||
virtual void setLocalAuthorizeOffline(bool local_authorize_offline) = 0;
|
||||
virtual void setLocalPreAuthorize(bool local_pre_authorize) = 0;
|
||||
virtual void setMaxEnergyOnInvalidId(std::int32_t max_energy) = 0;
|
||||
virtual bool setMeterValuesAlignedData(const std::string& meter_values_aligned_data) = 0;
|
||||
virtual bool setMeterValuesSampledData(const std::string& meter_values_sampled_data) = 0;
|
||||
virtual void setMeterValueSampleInterval(std::int32_t interval) = 0;
|
||||
virtual void setMinimumStatusDuration(std::int32_t minimum_status_duration) = 0;
|
||||
virtual void setResetRetries(std::int32_t retries) = 0;
|
||||
virtual void setStopTransactionOnInvalidId(bool stop_transaction_on_invalid_id) = 0;
|
||||
virtual bool setStopTxnAlignedData(const std::string& stop_txn_aligned_data) = 0;
|
||||
virtual bool setStopTxnSampledData(const std::string& stop_txn_sampled_data) = 0;
|
||||
virtual void setTransactionMessageAttempts(std::int32_t attempts) = 0;
|
||||
virtual void setTransactionMessageRetryInterval(std::int32_t retry_interval) = 0;
|
||||
virtual void setUnlockConnectorOnEVSideDisconnect(bool unlock_connector_on_ev_side_disconnect) = 0;
|
||||
virtual void setWebsocketPingInterval(std::int32_t websocket_ping_interval) = 0;
|
||||
|
||||
// Firmware Management Profile
|
||||
virtual std::optional<std::string> getSupportedFileTransferProtocols() = 0;
|
||||
virtual std::optional<KeyValue> getSupportedFileTransferProtocolsKeyValue() = 0;
|
||||
|
||||
// Smart Charging Profile
|
||||
virtual std::string getChargingScheduleAllowedChargingRateUnit() = 0;
|
||||
virtual std::int32_t getChargeProfileMaxStackLevel() = 0;
|
||||
virtual std::int32_t getChargingScheduleMaxPeriods() = 0;
|
||||
virtual std::int32_t getMaxChargingProfilesInstalled() = 0;
|
||||
|
||||
virtual std::optional<bool> getConnectorSwitch3to1PhaseSupported() = 0;
|
||||
|
||||
virtual std::vector<ChargingRateUnit> getChargingScheduleAllowedChargingRateUnitVector() = 0;
|
||||
|
||||
virtual KeyValue getChargeProfileMaxStackLevelKeyValue() = 0;
|
||||
virtual KeyValue getChargingScheduleAllowedChargingRateUnitKeyValue() = 0;
|
||||
virtual KeyValue getChargingScheduleMaxPeriodsKeyValue() = 0;
|
||||
virtual KeyValue getMaxChargingProfilesInstalledKeyValue() = 0;
|
||||
|
||||
virtual std::optional<KeyValue> getConnectorSwitch3to1PhaseSupportedKeyValue() = 0;
|
||||
|
||||
// Security Profile
|
||||
virtual bool getDisableSecurityEventNotifications() = 0;
|
||||
virtual std::int32_t getSecurityProfile() = 0;
|
||||
|
||||
virtual std::optional<std::string> getAuthorizationKey() = 0;
|
||||
virtual std::optional<std::string> getCpoName() = 0;
|
||||
virtual std::optional<bool> getAdditionalRootCertificateCheck() = 0;
|
||||
virtual std::optional<std::int32_t> getCertificateSignedMaxChainSize() = 0;
|
||||
virtual std::optional<std::int32_t> getCertificateStoreMaxLength() = 0;
|
||||
|
||||
virtual KeyValue getDisableSecurityEventNotificationsKeyValue() = 0;
|
||||
virtual KeyValue getSecurityProfileKeyValue() = 0;
|
||||
|
||||
virtual std::optional<KeyValue> getAdditionalRootCertificateCheckKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getAuthorizationKeyKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getCertificateSignedMaxChainSizeKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getCertificateStoreMaxLengthKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getCpoNameKeyValue() = 0;
|
||||
|
||||
virtual void setAuthorizationKey(const std::string& authorization_key) = 0;
|
||||
virtual void setCpoName(const std::string& cpo_name) = 0;
|
||||
virtual void setDisableSecurityEventNotifications(bool disable_security_event_notifications) = 0;
|
||||
virtual void setSecurityProfile(std::int32_t security_profile) = 0;
|
||||
|
||||
// Local Auth List Management Profile
|
||||
virtual bool getLocalAuthListEnabled() = 0;
|
||||
virtual std::int32_t getLocalAuthListMaxLength() = 0;
|
||||
virtual std::int32_t getSendLocalListMaxLength() = 0;
|
||||
|
||||
virtual KeyValue getLocalAuthListEnabledKeyValue() = 0;
|
||||
virtual KeyValue getLocalAuthListMaxLengthKeyValue() = 0;
|
||||
virtual KeyValue getSendLocalListMaxLengthKeyValue() = 0;
|
||||
|
||||
virtual void setLocalAuthListEnabled(bool local_auth_list_enabled) = 0;
|
||||
|
||||
// PnC
|
||||
virtual bool getContractValidationOffline() = 0;
|
||||
virtual bool getISO15118CertificateManagementEnabled() = 0;
|
||||
virtual bool getISO15118PnCEnabled() = 0;
|
||||
|
||||
virtual std::optional<bool> getCentralContractValidationAllowed() = 0;
|
||||
virtual std::optional<std::int32_t> getCertSigningRepeatTimes() = 0;
|
||||
virtual std::optional<std::int32_t> getCertSigningWaitMinimum() = 0;
|
||||
|
||||
virtual KeyValue getContractValidationOfflineKeyValue() = 0;
|
||||
virtual KeyValue getISO15118CertificateManagementEnabledKeyValue() = 0;
|
||||
virtual KeyValue getISO15118PnCEnabledKeyValue() = 0;
|
||||
|
||||
virtual std::optional<KeyValue> getCentralContractValidationAllowedKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getCertSigningRepeatTimesKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getCertSigningWaitMinimumKeyValue() = 0;
|
||||
|
||||
virtual void setContractValidationOffline(bool contract_validation_offline) = 0;
|
||||
virtual void setCentralContractValidationAllowed(bool central_contract_validation_allowed) = 0;
|
||||
virtual void setCertSigningRepeatTimes(std::int32_t cert_signing_repeat_times) = 0;
|
||||
virtual void setCertSigningWaitMinimum(std::int32_t cert_signing_wait_minimum) = 0;
|
||||
virtual void setISO15118CertificateManagementEnabled(bool iso15118_certificate_management_enabled) = 0;
|
||||
virtual void setISO15118PnCEnabled(bool iso15118_pnc_enabled) = 0;
|
||||
|
||||
// California Pricing Requirements
|
||||
virtual bool getCustomDisplayCostAndPriceEnabled() = 0;
|
||||
|
||||
virtual TariffMessage getDefaultTariffMessage(bool offline) = 0;
|
||||
|
||||
virtual std::optional<std::string> getDefaultPrice() = 0;
|
||||
virtual std::optional<std::string> getDefaultPriceText(const std::string& language) = 0;
|
||||
virtual std::optional<std::string> getDisplayTimeOffset() = 0;
|
||||
virtual std::optional<std::string> getLanguage() = 0;
|
||||
virtual std::optional<std::string> getMultiLanguageSupportedLanguages() = 0;
|
||||
virtual std::optional<std::string> getNextTimeOffsetTransitionDateTime() = 0;
|
||||
virtual std::optional<std::string> getTimeOffsetNextTransition() = 0;
|
||||
virtual std::optional<bool> getCustomIdleFeeAfterStop() = 0;
|
||||
virtual std::optional<bool> getCustomMultiLanguageMessagesEnabled() = 0;
|
||||
virtual std::optional<std::int32_t> getWaitForSetUserPriceTimeout() = 0;
|
||||
virtual std::optional<std::uint32_t> getPriceNumberOfDecimalsForCostValues() = 0;
|
||||
|
||||
virtual KeyValue getCustomDisplayCostAndPriceEnabledKeyValue() = 0;
|
||||
virtual KeyValue getDefaultPriceTextKeyValue(const std::string& language) = 0;
|
||||
|
||||
virtual std::optional<KeyValue> getCustomIdleFeeAfterStopKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getCustomMultiLanguageMessagesEnabledKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getDefaultPriceKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getDisplayTimeOffsetKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getLanguageKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getMultiLanguageSupportedLanguagesKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getNextTimeOffsetTransitionDateTimeKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getPriceNumberOfDecimalsForCostValuesKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getTimeOffsetNextTransitionKeyValue() = 0;
|
||||
virtual std::optional<KeyValue> getWaitForSetUserPriceTimeoutKeyValue() = 0;
|
||||
|
||||
virtual std::optional<std::vector<KeyValue>> getAllDefaultPriceTextKeyValues() = 0;
|
||||
|
||||
virtual void setCustomIdleFeeAfterStop(bool value) = 0;
|
||||
virtual ConfigurationStatus setDefaultPrice(const std::string& value) = 0;
|
||||
virtual ConfigurationStatus setDefaultPriceText(const CiString<50>& key, const CiString<500>& value) = 0;
|
||||
virtual ConfigurationStatus setDisplayTimeOffset(const std::string& offset) = 0;
|
||||
virtual void setLanguage(const std::string& language) = 0;
|
||||
virtual ConfigurationStatus setNextTimeOffsetTransitionDateTime(const std::string& date_time) = 0;
|
||||
virtual ConfigurationStatus setTimeOffsetNextTransition(const std::string& offset) = 0;
|
||||
virtual void setWaitForSetUserPriceTimeout(std::int32_t wait_for_set_user_price_timeout) = 0;
|
||||
|
||||
// Signed Meter Values
|
||||
|
||||
// Custom
|
||||
virtual std::optional<KeyValue> getCustomKeyValue(const CiString<50>& key) = 0;
|
||||
virtual std::optional<KeyValue> get(const CiString<50>& key) = 0;
|
||||
virtual std::vector<KeyValue> get_all_key_value() = 0;
|
||||
|
||||
virtual ConfigurationStatus setCustomKey(const CiString<50>& key, const CiString<500>& value, bool force) = 0;
|
||||
virtual std::optional<ConfigurationStatus> set(const CiString<50>& key, const CiString<500>& value) = 0;
|
||||
};
|
||||
|
||||
} // namespace ocpp::v16
|
||||
|
||||
#endif // OCPP_V16_CHARGE_POINT_CONFIGURATION_INTERFACE_HPP
|
||||
@@ -0,0 +1,958 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2026 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_V16_CHARGE_POINT_IMPL_HPP
|
||||
#define OCPP_V16_CHARGE_POINT_IMPL_HPP
|
||||
#include "ocpp/v16/ocpp_enums.hpp"
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <date/date.h>
|
||||
#include <date/tz.h>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <ocpp/common/support_older_cpp_versions.hpp>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
#include <everest/timer.hpp>
|
||||
|
||||
#include <ocpp/common/aligned_timer.hpp>
|
||||
#include <ocpp/common/charging_station_base.hpp>
|
||||
#include <ocpp/common/message_dispatcher.hpp>
|
||||
#include <ocpp/common/message_queue.hpp>
|
||||
#include <ocpp/common/schemas.hpp>
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/common/websocket/websocket.hpp>
|
||||
#include <ocpp/v16/charge_point_configuration_interface.hpp>
|
||||
#include <ocpp/v16/connector.hpp>
|
||||
#include <ocpp/v16/database_handler.hpp>
|
||||
#include <ocpp/v16/message_dispatcher.hpp>
|
||||
#include <ocpp/v16/messages/Authorize.hpp>
|
||||
#include <ocpp/v16/messages/BootNotification.hpp>
|
||||
#include <ocpp/v16/messages/CancelReservation.hpp>
|
||||
#include <ocpp/v16/messages/CertificateSigned.hpp>
|
||||
#include <ocpp/v16/messages/ChangeAvailability.hpp>
|
||||
#include <ocpp/v16/messages/ChangeConfiguration.hpp>
|
||||
#include <ocpp/v16/messages/ClearCache.hpp>
|
||||
#include <ocpp/v16/messages/ClearChargingProfile.hpp>
|
||||
#include <ocpp/v16/messages/DataTransfer.hpp>
|
||||
#include <ocpp/v16/messages/DeleteCertificate.hpp>
|
||||
#include <ocpp/v16/messages/DiagnosticsStatusNotification.hpp>
|
||||
#include <ocpp/v16/messages/ExtendedTriggerMessage.hpp>
|
||||
#include <ocpp/v16/messages/FirmwareStatusNotification.hpp>
|
||||
#include <ocpp/v16/messages/GetCompositeSchedule.hpp>
|
||||
#include <ocpp/v16/messages/GetConfiguration.hpp>
|
||||
#include <ocpp/v16/messages/GetDiagnostics.hpp>
|
||||
#include <ocpp/v16/messages/GetInstalledCertificateIds.hpp>
|
||||
#include <ocpp/v16/messages/GetLocalListVersion.hpp>
|
||||
#include <ocpp/v16/messages/GetLog.hpp>
|
||||
#include <ocpp/v16/messages/Heartbeat.hpp>
|
||||
#include <ocpp/v16/messages/InstallCertificate.hpp>
|
||||
#include <ocpp/v16/messages/LogStatusNotification.hpp>
|
||||
#include <ocpp/v16/messages/MeterValues.hpp>
|
||||
#include <ocpp/v16/messages/RemoteStartTransaction.hpp>
|
||||
#include <ocpp/v16/messages/RemoteStopTransaction.hpp>
|
||||
#include <ocpp/v16/messages/ReserveNow.hpp>
|
||||
#include <ocpp/v16/messages/Reset.hpp>
|
||||
#include <ocpp/v16/messages/SecurityEventNotification.hpp>
|
||||
#include <ocpp/v16/messages/SendLocalList.hpp>
|
||||
#include <ocpp/v16/messages/SetChargingProfile.hpp>
|
||||
#include <ocpp/v16/messages/SignCertificate.hpp>
|
||||
#include <ocpp/v16/messages/SignedFirmwareStatusNotification.hpp>
|
||||
#include <ocpp/v16/messages/SignedUpdateFirmware.hpp>
|
||||
#include <ocpp/v16/messages/StartTransaction.hpp>
|
||||
#include <ocpp/v16/messages/StatusNotification.hpp>
|
||||
#include <ocpp/v16/messages/StopTransaction.hpp>
|
||||
#include <ocpp/v16/messages/TriggerMessage.hpp>
|
||||
#include <ocpp/v16/messages/UnlockConnector.hpp>
|
||||
#include <ocpp/v16/messages/UpdateFirmware.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
#include <ocpp/v16/smart_charging.hpp>
|
||||
#include <ocpp/v16/transaction.hpp>
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
// for OCPP1.6 PnC
|
||||
#include <ocpp/v2/messages/Authorize.hpp>
|
||||
#include <ocpp/v2/messages/CertificateSigned.hpp>
|
||||
#include <ocpp/v2/messages/DeleteCertificate.hpp>
|
||||
#include <ocpp/v2/messages/Get15118EVCertificate.hpp>
|
||||
#include <ocpp/v2/messages/GetCertificateStatus.hpp>
|
||||
#include <ocpp/v2/messages/GetInstalledCertificateIds.hpp>
|
||||
#include <ocpp/v2/messages/InstallCertificate.hpp>
|
||||
#include <ocpp/v2/messages/SignCertificate.hpp>
|
||||
#include <ocpp/v2/messages/TriggerMessage.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a ChargePoint implementation compatible with OCPP-J 1.6
|
||||
class ChargePointImpl : ocpp::ChargingStationBase {
|
||||
private:
|
||||
ChargePointConfigurationInterface& configuration;
|
||||
BootReasonEnum bootreason{BootReasonEnum::PowerUp};
|
||||
bool initialized{false};
|
||||
bool InvalidCSMSCertificate_logged{false};
|
||||
bool wants_to_be_connected{false};
|
||||
ChargePointConnectionState connection_state{ChargePointConnectionState::Disconnected};
|
||||
std::atomic<RegistrationStatus> registration_status{RegistrationStatus::Pending};
|
||||
DiagnosticsStatus diagnostics_status{DiagnosticsStatus::Idle};
|
||||
FirmwareStatus firmware_status{FirmwareStatus::Idle};
|
||||
UploadLogStatusEnumType log_status{UploadLogStatusEnumType::Idle};
|
||||
|
||||
std::string message_log_path;
|
||||
fs::path share_path;
|
||||
|
||||
bool boot_notification_callerror;
|
||||
bool firmware_update_is_pending = false;
|
||||
|
||||
std::unique_ptr<Websocket> websocket;
|
||||
std::unique_ptr<ocpp::MessageDispatcherInterface<MessageType>> message_dispatcher;
|
||||
Everest::SteadyTimer websocket_timer;
|
||||
std::unique_ptr<MessageQueue<v16::MessageType>> message_queue;
|
||||
std::map<std::int32_t, std::shared_ptr<Connector>> connectors;
|
||||
std::unique_ptr<SmartChargingHandler> smart_charging_handler;
|
||||
std::int32_t heartbeat_interval;
|
||||
bool stopped;
|
||||
std::chrono::time_point<date::utc_clock> boot_time;
|
||||
std::set<MessageType> allowed_message_types;
|
||||
std::mutex allowed_message_types_mutex;
|
||||
std::unique_ptr<ChargePointStates> status;
|
||||
std::shared_ptr<ocpp::v16::DatabaseHandler> database_handler;
|
||||
std::unique_ptr<Everest::SteadyTimer> boot_notification_timer;
|
||||
std::unique_ptr<Everest::SteadyTimer> heartbeat_timer;
|
||||
std::unique_ptr<ClockAlignedTimer> clock_aligned_meter_values_timer;
|
||||
std::vector<std::unique_ptr<Everest::SteadyTimer>> status_notification_timers;
|
||||
std::unique_ptr<Everest::SteadyTimer> ocsp_request_timer;
|
||||
std::unique_ptr<Everest::SteadyTimer> client_certificate_timer;
|
||||
std::unique_ptr<Everest::SteadyTimer> v2g_certificate_timer;
|
||||
std::unique_ptr<Everest::SystemTimer> change_time_offset_timer;
|
||||
std::chrono::time_point<date::utc_clock> clock_aligned_meter_values_time_point;
|
||||
std::mutex meter_values_mutex;
|
||||
std::mutex measurement_mutex;
|
||||
std::map<std::int32_t, AvailabilityChange> change_availability_queue; // TODO: move to Connectors
|
||||
std::mutex change_availability_mutex; // TODO: move to Connectors
|
||||
std::unique_ptr<TransactionHandler> transaction_handler;
|
||||
std::vector<v16::MessageType> external_notify;
|
||||
|
||||
std::map<std::string,
|
||||
std::map<std::string, std::function<DataTransferResponse(const std::optional<std::string>& msg)>>>
|
||||
data_transfer_callbacks;
|
||||
std::function<DataTransferResponse(const DataTransferRequest& request)> data_transfer_callback;
|
||||
std::map<std::string, std::function<void(Call<DataTransferRequest> call)>> data_transfer_pnc_callbacks;
|
||||
std::mutex data_transfer_callbacks_mutex;
|
||||
std::map<CiString<50>, std::function<void(const KeyValue& key_value)>> configuration_key_changed_callbacks;
|
||||
std::function<void(const KeyValue& key_value)> generic_configuration_key_changed_callback;
|
||||
|
||||
std::mutex stop_transaction_mutex;
|
||||
std::condition_variable stop_transaction_cv;
|
||||
|
||||
std::mutex user_price_map_mutex;
|
||||
std::map<std::string, std::condition_variable> user_price_cvs;
|
||||
std::map<std::string, TariffMessage> tariff_messages_by_id_token;
|
||||
|
||||
std::thread reset_thread;
|
||||
|
||||
int log_status_request_id;
|
||||
|
||||
FirmwareStatusEnumType signed_firmware_status;
|
||||
int signed_firmware_status_request_id;
|
||||
|
||||
/// \brief optional delay to resumption of message queue after reconnecting to the CSMS
|
||||
std::chrono::seconds message_queue_resume_delay = std::chrono::seconds(0);
|
||||
|
||||
// callbacks
|
||||
std::function<bool(std::int32_t connector)> enable_evse_callback;
|
||||
std::function<bool(std::int32_t connector)> disable_evse_callback;
|
||||
std::function<bool(std::int32_t connector)> pause_charging_callback;
|
||||
std::function<bool(std::int32_t connector)> resume_charging_callback;
|
||||
std::function<void(const std::string& id_token, std::vector<std::int32_t> referenced_connectors, bool prevalidated)>
|
||||
provide_token_callback;
|
||||
std::function<bool(std::int32_t connector, Reason reason)> stop_transaction_callback;
|
||||
std::function<UnlockStatus(std::int32_t connector)> unlock_connector_callback;
|
||||
std::function<bool(std::int32_t connector, std::int32_t max_current)> set_max_current_callback;
|
||||
std::function<bool(const ResetType& reset_type)> is_reset_allowed_callback;
|
||||
std::function<void(const ResetType& reset_type)> reset_callback;
|
||||
std::function<void(const std::string& system_time)> set_system_time_callback;
|
||||
std::function<void(const BootNotificationResponse& boot_notification_response)> boot_notification_response_callback;
|
||||
std::function<void()> signal_set_charging_profiles_callback;
|
||||
std::function<void(bool is_connected)> connection_state_changed_callback;
|
||||
|
||||
std::function<GetLogResponse(const GetDiagnosticsRequest& request)> upload_diagnostics_callback;
|
||||
std::function<void(const UpdateFirmwareRequest msg)> update_firmware_callback;
|
||||
|
||||
std::function<UpdateFirmwareStatusEnumType(const SignedUpdateFirmwareRequest msg)> signed_update_firmware_callback;
|
||||
std::function<void(const std::string& type, const std::string& tech_info)> security_event_callback;
|
||||
|
||||
std::function<void()> all_connectors_unavailable_callback;
|
||||
|
||||
std::function<ReservationStatus(std::int32_t reservation_id, std::int32_t connector, ocpp::DateTime expiryDate,
|
||||
CiString<20> idTag, std::optional<CiString<20>> parent_id)>
|
||||
reserve_now_callback;
|
||||
std::function<bool(std::int32_t reservation_id)> cancel_reservation_callback;
|
||||
std::function<void()> switch_security_profile_callback;
|
||||
std::function<GetLogResponse(GetLogRequest msg)> upload_logs_callback;
|
||||
std::function<void(std::int32_t connection_timeout)> set_connection_timeout_callback;
|
||||
|
||||
std::function<void(const std::int32_t connector, const std::string& session_id)> transaction_started_callback;
|
||||
std::function<void(const std::int32_t connector, const std::string& session_id, const std::int32_t transaction_id,
|
||||
const IdTagInfo& id_tag_info)>
|
||||
transaction_updated_callback;
|
||||
std::function<void(const std::int32_t connector, const std::string& session_id, const std::int32_t transaction_id)>
|
||||
transaction_stopped_callback;
|
||||
std::function<ocpp::ReservationCheckStatus(const std::int32_t connector, const std::string& id_token)>
|
||||
is_token_reserved_for_connector_callback;
|
||||
|
||||
// iso15118 callback
|
||||
std::function<void(const std::int32_t connector,
|
||||
const ocpp::v2::Get15118EVCertificateResponse& certificate_response,
|
||||
const ocpp::v2::CertificateActionEnum& certificate_action)>
|
||||
get_15118_ev_certificate_response_callback;
|
||||
|
||||
// tariff and cost callback
|
||||
std::function<DataTransferResponse(const RunningCost& running_cost, const std::uint32_t number_of_decimals)>
|
||||
session_cost_callback;
|
||||
std::function<DataTransferResponse(const std::vector<DisplayMessage>& display_message)>
|
||||
set_display_message_callback;
|
||||
std::function<DataTransferResponse(const TariffMessage& message)> tariff_message_callback;
|
||||
std::function<void(const TariffMessage& message)> default_price_callback;
|
||||
|
||||
/// \brief This function is called after a successful connection to the Websocket
|
||||
void connected_callback();
|
||||
void init_websocket();
|
||||
void init_state_machine(const std::map<int, ChargePointStatus>& connector_status_map);
|
||||
WebsocketConnectionOptions get_ws_connection_options();
|
||||
std::unique_ptr<ocpp::MessageQueue<v16::MessageType>> create_message_queue();
|
||||
void message_callback(const std::string& message);
|
||||
void handle_message(const EnhancedMessage<v16::MessageType>& message);
|
||||
void heartbeat(bool initiated_by_trigger_message = false);
|
||||
void boot_notification(bool initiated_by_trigger_message = false);
|
||||
void clock_aligned_meter_values_sample();
|
||||
void update_heartbeat_interval();
|
||||
void update_meter_values_sample_interval();
|
||||
void update_clock_aligned_meter_values_interval();
|
||||
std::optional<MeterValue> get_latest_meter_value(std::int32_t connector,
|
||||
std::vector<MeasurandWithPhase> values_of_interest,
|
||||
ReadingContext context);
|
||||
void send_meter_value(std::int32_t connector, MeterValue meter_value, bool initiated_by_trigger_message = false);
|
||||
void send_meter_value_on_pricing_trigger(const std::int32_t connector_number, std::shared_ptr<Connector> connector,
|
||||
const Measurement& measurement);
|
||||
void reset_pricing_triggers(const std::int32_t connector_number);
|
||||
void status_notification(const std::int32_t connector, const ChargePointErrorCode errorCode,
|
||||
const ChargePointStatus status, const ocpp::DateTime& timestamp,
|
||||
const std::optional<CiString<50>>& info = std::nullopt,
|
||||
const std::optional<CiString<255>>& vendor_id = std::nullopt,
|
||||
const std::optional<CiString<50>>& vendor_error_code = std::nullopt,
|
||||
bool initiated_by_trigger_message = false);
|
||||
void diagnostic_status_notification(DiagnosticsStatus status, bool initiated_by_trigger_message = false);
|
||||
void firmware_status_notification(FirmwareStatus status, bool initiated_by_trigger_message = false);
|
||||
void log_status_notification(UploadLogStatusEnumType status, int requestId,
|
||||
bool initiated_by_trigger_message = false);
|
||||
void signed_firmware_update_status_notification(FirmwareStatusEnumType status, int requestId,
|
||||
bool initiated_by_trigger_message = false);
|
||||
|
||||
/// \brief Changes all unoccupied connectors to unavailable. If a transaction is running schedule an availabilty
|
||||
/// change. If all connectors are unavailable signal to the firmware updater that installation of the firmware
|
||||
/// update can proceed
|
||||
void change_all_connectors_to_unavailable_for_firmware_update();
|
||||
|
||||
/// \brief Tries to resume the transactions given by \p resuming_session_ids . This function retrieves open
|
||||
/// transactions from the internal database (e.g. because of power loss). In case the \p
|
||||
/// resuming_session_ids contain the internal session_id, this function attempts to resume the transaction by
|
||||
/// initializing it and adding it to the \ref transaction_handler. If the session_id is not part of \p
|
||||
/// resuming_session_ids a StopTransaction.req is initiated to properly close the transaction.
|
||||
void try_resume_transactions(const std::set<std::string>& resuming_session_ids);
|
||||
void stop_all_transactions();
|
||||
void stop_all_transactions(Reason reason);
|
||||
bool validate_against_cache_entries(CiString<20> id_tag);
|
||||
|
||||
// new transaction handling:
|
||||
void start_transaction(std::shared_ptr<Transaction> transaction);
|
||||
|
||||
void stop_transaction(std::int32_t connector, Reason reason, std::optional<CiString<20>> id_tag_end);
|
||||
|
||||
/// \brief Returns transaction data that can be used to set the transactionData field in StopTransaction.req.
|
||||
/// Filters the meter values of the transaction according to the values set within StopTxnAlignedData and
|
||||
/// StopTxnSampledData
|
||||
std::vector<TransactionData> get_filtered_transaction_data(const std::shared_ptr<Transaction>& transaction);
|
||||
|
||||
/// \brief Load charging profiles if present in database
|
||||
void load_charging_profiles();
|
||||
|
||||
// security
|
||||
/// \brief Creates a new public/private key pair and sends a certificate signing request to the central system for
|
||||
/// the given \p certificate_signing_use
|
||||
void sign_certificate(const ocpp::CertificateSigningUseEnum& certificate_signing_use,
|
||||
bool initiated_by_trigger_message = false);
|
||||
|
||||
/// \brief Checks if OCSP cache needs to be updated and executes update if necessary by using
|
||||
/// DataTransfer(GetCertificateStatus.req)
|
||||
void update_ocsp_cache();
|
||||
|
||||
// core profile
|
||||
void handleBootNotificationResponse(
|
||||
CallResult<BootNotificationResponse> call_result); // TODO(kai):: async/promise based version?
|
||||
void handleChangeAvailabilityRequest(Call<ChangeAvailabilityRequest> call);
|
||||
void handleChangeConfigurationRequest(Call<ChangeConfigurationRequest> call);
|
||||
void handleClearCacheRequest(Call<ClearCacheRequest> call);
|
||||
void handleDataTransferRequest(Call<DataTransferRequest> call);
|
||||
void handleGetConfigurationRequest(Call<GetConfigurationRequest> call);
|
||||
void handleRemoteStartTransactionRequest(Call<RemoteStartTransactionRequest> call);
|
||||
void handleRemoteStopTransactionRequest(Call<RemoteStopTransactionRequest> call);
|
||||
void handleResetRequest(Call<ResetRequest> call);
|
||||
void handleStartTransactionResponse(CallResult<StartTransactionResponse> call_result);
|
||||
void handleStopTransactionResponse(const EnhancedMessage<v16::MessageType>& message);
|
||||
void handleUnlockConnectorRequest(Call<UnlockConnectorRequest> call);
|
||||
void handleHeartbeatResponse(CallResult<HeartbeatResponse> call_result);
|
||||
|
||||
// smart charging profile
|
||||
void handleSetChargingProfileRequest(Call<SetChargingProfileRequest> call);
|
||||
void handleGetCompositeScheduleRequest(Call<GetCompositeScheduleRequest> call);
|
||||
void handleClearChargingProfileRequest(Call<ClearChargingProfileRequest> call);
|
||||
|
||||
// plug&charge for 1.6 whitepaper
|
||||
bool is_iso15118_certificate_management_enabled();
|
||||
bool is_pnc_enabled();
|
||||
void data_transfer_pnc_sign_certificate();
|
||||
void data_transfer_pnc_get_certificate_status(const ocpp::v2::OCSPRequestData& ocsp_request_data);
|
||||
|
||||
void handle_data_transfer_pnc_trigger_message(Call<DataTransferRequest> call);
|
||||
void handle_data_transfer_pnc_certificate_signed(Call<DataTransferRequest> call);
|
||||
void handle_data_transfer_pnc_get_installed_certificates(Call<DataTransferRequest> call);
|
||||
void handle_data_transfer_delete_certificate(Call<DataTransferRequest> call);
|
||||
void handle_data_transfer_install_certificate(Call<DataTransferRequest> call);
|
||||
|
||||
/// \brief ReserveNow.req(connectorId, expiryDate, idTag, reservationId, [parentIdTag]): tries to perform the
|
||||
/// reservation and sends a reservation response. The reservation response: ReserveNow::Status
|
||||
void handleReserveNowRequest(Call<ReserveNowRequest> call);
|
||||
|
||||
/// \brief Receives CancelReservation.req(reservationId)
|
||||
/// The reservation response: CancelReservationStatus: `Accepted` if the reservationId was found, else
|
||||
/// `Rejected`
|
||||
void handleCancelReservationRequest(Call<CancelReservationRequest> call);
|
||||
|
||||
// RemoteTrigger profile
|
||||
void handleTriggerMessageRequest(Call<TriggerMessageRequest> call);
|
||||
|
||||
// FirmwareManagement profile
|
||||
void handleGetDiagnosticsRequest(Call<GetDiagnosticsRequest> call);
|
||||
void handleUpdateFirmwareRequest(Call<UpdateFirmwareRequest> call);
|
||||
|
||||
// Security profile
|
||||
void handleExtendedTriggerMessageRequest(Call<ExtendedTriggerMessageRequest> call);
|
||||
void handleCertificateSignedRequest(Call<CertificateSignedRequest> call);
|
||||
void handleGetInstalledCertificateIdsRequest(Call<GetInstalledCertificateIdsRequest> call);
|
||||
void handleDeleteCertificateRequest(Call<DeleteCertificateRequest> call);
|
||||
void handleInstallCertificateRequest(Call<InstallCertificateRequest> call);
|
||||
void handleGetLogRequest(Call<GetLogRequest> call);
|
||||
void handleSignedUpdateFirmware(Call<SignedUpdateFirmwareRequest> call);
|
||||
void securityEventNotification(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
|
||||
const bool triggered_internally, const std::optional<bool>& critical = std::nullopt,
|
||||
const std::optional<DateTime>& timestamp = std::nullopt);
|
||||
void switchSecurityProfile(std::int32_t new_security_profile, std::int32_t max_connection_attempts);
|
||||
// Local Authorization List profile
|
||||
void handleSendLocalListRequest(Call<SendLocalListRequest> call);
|
||||
void handleGetLocalListVersionRequest(Call<GetLocalListVersionRequest> call);
|
||||
|
||||
// California Pricing
|
||||
DataTransferResponse handle_set_user_price(const std::optional<std::string>& msg);
|
||||
DataTransferResponse handle_set_session_cost(const RunningCostState& type,
|
||||
const std::optional<std::string>& message);
|
||||
///
|
||||
/// \brief Set timer to trigger sending a metervalue at a specific time.
|
||||
/// \param date_time The date/time to send the metervalue.
|
||||
/// \param connector The connector to set the timer for.
|
||||
///
|
||||
void set_connector_trigger_metervalue_timer(const DateTime& date_time, std::shared_ptr<Connector> connector);
|
||||
|
||||
///
|
||||
/// \brief Set offset timer to change the 'timezone' (time offset) at the given time.
|
||||
/// \param date_time The date / time to change the time offset.
|
||||
///
|
||||
void set_time_offset_timer(const std::string& date_time);
|
||||
|
||||
/// \brief Preprocess a ChangeAvailabilityRequest: Determine response;
|
||||
/// - if connector is 0, availability change is also propagated for all connectors
|
||||
/// - for each connector (except "0"), if transaction is ongoing the change is scheduled,
|
||||
/// otherwise the OCPP connector id is appended to the `accepted_connector_availability_changes` vector
|
||||
void preprocess_change_availability_request(const ChangeAvailabilityRequest& request,
|
||||
ChangeAvailabilityResponse& response,
|
||||
std::vector<std::int32_t>& accepted_connector_availability_changes);
|
||||
|
||||
/// \brief Executes availability change for the provided connectors:
|
||||
/// - if persist == true: store availability in database
|
||||
/// - submit state event (for the whole ChargePoint if "0" in set of connectors; otherwise for each connector
|
||||
/// individually)
|
||||
/// - call according EVSE enable or disable callback, respectively
|
||||
/// \param changed_connectors list of OCPP connector ids (and 0 for whole chargepoint)
|
||||
/// \param availability new availabillity
|
||||
/// \param persist if true, persists availability in database
|
||||
void execute_connectors_availability_change(const std::vector<std::int32_t>& changed_connectors,
|
||||
const ocpp::v16::AvailabilityType availability, bool persist);
|
||||
|
||||
/// \brief Checks scheduled availability queue and exeuctues availability change if required
|
||||
/// \param connector for which availability change shall be checked and executed
|
||||
void execute_queued_availability_change(const std::int32_t connector);
|
||||
|
||||
/// \brief Sets a configuration key (internal implementation)
|
||||
/// \param key
|
||||
/// \param value
|
||||
/// \param uniqueId used when an OCPP response is sent
|
||||
/// \return Indicates the result of the operation with an optional response message
|
||||
/// \note the optional response message will be nullopt when a response has
|
||||
/// been sent by this method
|
||||
std::pair<ConfigurationStatus, std::optional<ChangeConfigurationResponse>>
|
||||
set_configuration_key_internal(CiString<50> key, CiString<500> value, std::optional<MessageId> uniqueId);
|
||||
|
||||
public:
|
||||
/// \brief The main entrypoint for libOCPP for OCPP 1.6
|
||||
/// \param cfg a reference to the configuration provider
|
||||
/// \param database_path this points to the location of the sqlite database that libocpp uses to keep track of
|
||||
/// \param share_path This path contains the following files and directories and is installed by the libocpp install
|
||||
/// target
|
||||
/// connector availability, the authorization cache and auth list, charging profiles and transaction
|
||||
/// data \param sql_init_path this points to the init.sql file which contains the database schema used by libocpp
|
||||
/// for its sqlite database \param message_log_path this points to the directory in which libocpp can put OCPP
|
||||
/// communication logfiles for debugging purposes. This behavior can be controlled by the "LogMessages" (set to true
|
||||
/// by default) and "LogMessagesFormat" (set to ["log", "html", "session_logging"] by default, "console" and
|
||||
/// "console_detailed" are also available) configuration keys in the "Internal" section of the config file. Please
|
||||
/// note that this is intended for debugging purposes only as it logs all communication, including authentication
|
||||
/// messages. \param evse_security Pointer to evse_security that manages security related operations
|
||||
/// \param message_callback A callback that will get all OCPP messages sent or received to/from the CSMS
|
||||
explicit ChargePointImpl(
|
||||
ChargePointConfigurationInterface& cfg, const fs::path& share_path, const fs::path& database_path,
|
||||
const fs::path& sql_init_path, const fs::path& message_log_path,
|
||||
const std::shared_ptr<EvseSecurity>& evse_security,
|
||||
const std::optional<SecurityConfiguration>& security_configuration,
|
||||
const std::function<void(const std::string& message, MessageDirection direction)>& message_callback);
|
||||
|
||||
virtual ~ChargePointImpl() override = default;
|
||||
|
||||
/// \brief Allow to update the ChargePoint core information which will be sent in BootNotification.req
|
||||
void update_chargepoint_information(const std::string& vendor, const std::string& model,
|
||||
const std::optional<std::string>& serialnumber,
|
||||
const std::optional<std::string>& chargebox_serialnumber,
|
||||
const std::optional<std::string>& firmware_version);
|
||||
|
||||
/// \brief Allow to update the ChargePoint modem information
|
||||
void update_modem_information(const std::optional<std::string>& iccid, const std::optional<std::string>& imsi);
|
||||
|
||||
/// \brief Allow to update the ChargePoint meter information
|
||||
void update_meter_information(const std::optional<std::string>& meter_serialnumber,
|
||||
const std::optional<std::string>& meter_type);
|
||||
|
||||
/// \brief Initializes the ChargePoint and all of it's connectors, the state machine and message queue. This method
|
||||
/// should be called if a more granular start of the process is necessary. Notably if it is necessary for the state
|
||||
/// machine and the connectors (and their statuses) need to be updated prior to initiating connection with the CSMS.
|
||||
/// \param connector_status_map initial state of connectors including connector 0 with reduced set of states
|
||||
/// (Available, Unavailable, Faulted)
|
||||
/// \param resuming_session_ids can optionally contain active session ids from previous executions. If empty and
|
||||
/// libocpp has transactions in its internal database that have not been stopped yet, calling this function will
|
||||
/// initiate a StopTransaction.req for those transactions. If this vector contains session_ids this function will
|
||||
/// not stop transactions with this session_id even in case it has an internal database entry for this session and
|
||||
/// it hasnt been stopped yet. Its ignored if this vector contains session_ids that are unknown to libocpp.
|
||||
/// \return
|
||||
bool init(const std::map<int, ChargePointStatus>& connector_status_map,
|
||||
const std::set<std::string>& resuming_session_ids);
|
||||
|
||||
/// \brief Starts the ChargePoint, initializes (if and only if init was not called previously) and connects to the
|
||||
/// Websocket endpoint and initializes a BootNotification.req
|
||||
/// \param connector_status_map initial state of connectors including connector 0 with reduced set of states
|
||||
/// (Available, Unavailable, Faulted)
|
||||
/// \param bootreason reason for calling the start function
|
||||
/// \param resuming_session_ids can optionally contain active session ids from previous executions. If empty and
|
||||
/// libocpp has transactions in its internal database that have not been stopped yet, calling this function will
|
||||
/// initiate a StopTransaction.req for those transactions. If this vector contains session_ids this function will
|
||||
/// not stop transactions with this session_id even in case it has an internal database entry for this session and
|
||||
/// it hasnt been stopped yet. Its ignored if this vector contains session_ids that are unknown to libocpp.
|
||||
/// \return
|
||||
bool start(const std::map<int, ChargePointStatus>& connector_status_map, BootReasonEnum bootreason,
|
||||
const std::set<std::string>& resuming_session_ids);
|
||||
|
||||
/// \brief Restarts the ChargePoint if it has been stopped before. The ChargePoint is reinitialized, connects to the
|
||||
/// websocket and starts to communicate OCPP messages again
|
||||
/// \param connector_status_map initial state of connectors including connector 0 with reduced set of states
|
||||
/// (Available, Unavailable, Faulted). connector_status_map is empty, last availability states from the persistant
|
||||
/// storage will be used
|
||||
/// \param bootreason reason for calling the restart function
|
||||
bool restart(const std::map<int, ChargePointStatus>& connector_status_map, BootReasonEnum bootreason);
|
||||
|
||||
/// \brief Resets the internal state machine for the connectors using the given \p connector_status_map
|
||||
/// \param connector_status_map state of connectors including connector 0 with reduced set of states (Available,
|
||||
/// Unavailable, Faulted)
|
||||
void reset_state_machine(const std::map<int, ChargePointStatus>& connector_status_map);
|
||||
|
||||
/// \brief Stops the ChargePoint, stops timers, transactions and the message queue and disconnects from the
|
||||
/// websocket
|
||||
bool stop();
|
||||
|
||||
/// \brief Initializes the websocket and connects to CSMS if it is not yet connected
|
||||
void connect_websocket();
|
||||
|
||||
/// \brief Disconnects the the websocket connection to the CSMS if it is connected
|
||||
void disconnect_websocket();
|
||||
|
||||
/// \brief Calls the set_connection_timeout_callback that can be registered. This function is used to notify an
|
||||
/// Authorization mechanism about a changed ConnectionTimeout configuration key.
|
||||
void call_set_connection_timeout();
|
||||
|
||||
// public API for Core profile
|
||||
|
||||
/// \brief Authorizes the provided \p id_token against the central system, LocalAuthorizationList or
|
||||
/// AuthorizationCache depending on the values of the ConfigurationKeys LocalPreAuthorize, LocalAuthorizeOffline,
|
||||
/// LocalAuthListEnabled and AuthorizationCacheEnabled. If \p authorize_only_locally is true, no Authorize.req will
|
||||
/// be sent to the CSMS but only LocalAuthorizationList and LocalAuthorizationCache will be used for the validation
|
||||
/// \returns the EnhancedIdTagInfo that contains the result of the authorization and an optional tarriff message
|
||||
EnhancedIdTagInfo authorize_id_token(CiString<20> id_token, const bool authorize_only_locally = false);
|
||||
|
||||
// for plug&charge 1.6 whitepaper
|
||||
|
||||
/// \brief Uses data_transfer mechanism to authorize given \p emaid , \p certificate and
|
||||
/// \p iso15118_certificate_hash_data locally or by requesting authorzation at CSMS. This function can be called
|
||||
/// when the authorization mechanism Plug&Charge is specified as part of the ISO15118 PaymentDetailsRequest
|
||||
/// \param emaid
|
||||
/// \param certificate contract certificate that the EVCC provides
|
||||
/// \param iso15118_certificate_hash_data
|
||||
/// \return
|
||||
ocpp::v2::AuthorizeResponse data_transfer_pnc_authorize(
|
||||
const std::string& emaid, const std::optional<std::string>& certificate,
|
||||
const std::optional<std::vector<ocpp::v2::OCSPRequestData>>& iso15118_certificate_hash_data);
|
||||
|
||||
/// \brief Uses data transfer mechanism to get 15118 ev certificate from CSMS. This function can be called when the
|
||||
/// EVCC requests the update or installation of a contract certificate as part of the ISO15118
|
||||
/// CertificateInstallRequest or CertificateUpdateRequest
|
||||
/// \param connector_id
|
||||
/// \param exi_request provided by the EVCC
|
||||
/// \param iso15118_schema_version provided by the EVCC
|
||||
/// \param certificate_action Install or Update
|
||||
void data_transfer_pnc_get_15118_ev_certificate(const std::int32_t connector_id, const std::string& exi_request,
|
||||
const std::string& iso15118_schema_version,
|
||||
const ocpp::v2::CertificateActionEnum& certificate_action);
|
||||
|
||||
/// \brief Allows the exchange of arbitrary \p data identified by a \p vendorId and \p messageId with a central
|
||||
/// system \returns the DataTransferResponse
|
||||
/// \param vendorId
|
||||
/// \param messageId
|
||||
/// \param data
|
||||
/// \return the DataTransferResponse from the CSMS. In case no response is received from the CSMS because the
|
||||
/// message timed out or the charging station is offline, std::nullopt is returned
|
||||
std::optional<DataTransferResponse> data_transfer(const CiString<255>& vendorId,
|
||||
const std::optional<CiString<50>>& messageId,
|
||||
const std::optional<std::string>& data);
|
||||
|
||||
/// \brief Calculates ChargingProfiles configured by the CSMS of all connectors from now until now + given \p
|
||||
/// duration_s and the given \p unit
|
||||
/// \param duration_s
|
||||
/// \param unit defaults to A
|
||||
/// \return ChargingSchedules of all connectors
|
||||
std::map<std::int32_t, ChargingSchedule>
|
||||
get_all_composite_charging_schedules(const std::int32_t duration_s,
|
||||
const ChargingRateUnit unit = ChargingRateUnit::A);
|
||||
|
||||
/// \brief Calculates EnhancedChargingSchedule(s) configured by the CSMS of all connectors from now until now +
|
||||
/// given \p duration_s and the given \p unit . EnhancedChargingSchedules contain EnhancedChargingSchedulePeriod(s)
|
||||
/// that are enhanced by the stackLevel that was provided for the ChargingProfile
|
||||
/// \param duration_s
|
||||
/// \param unit
|
||||
/// defaults to A \return ChargingSchedules of all connectors
|
||||
std::map<std::int32_t, EnhancedChargingSchedule>
|
||||
get_all_enhanced_composite_charging_schedules(const std::int32_t duration_s,
|
||||
const ChargingRateUnit unit = ChargingRateUnit::A);
|
||||
|
||||
/// \brief Stores the given \p powermeter values for the given \p connector . This function can be called when a new
|
||||
/// meter value is present.
|
||||
/// \param connector
|
||||
/// \param measurement structure that can contain all kinds of measurands
|
||||
void on_meter_values(std::int32_t connector, const Measurement& measurement);
|
||||
|
||||
/// \brief Stores the given \p max_current for the given \p connector offered to the EV. This function can be called
|
||||
/// when the value for the maximum current for the connector changes. It will be used to report the Measurand
|
||||
/// Current_Offered if it is configured
|
||||
/// \param connector
|
||||
/// \param max_current in Amps
|
||||
void on_max_current_offered(std::int32_t connector, std::int32_t max_current);
|
||||
|
||||
/// \brief Stores the given \p max_power for the given \p connector offered to the EV. This function can be called
|
||||
/// when the value for the maximum power for the connector changes. It will be used to report the Measurand
|
||||
/// Power_Offered if it is configured
|
||||
/// \param connector
|
||||
/// \param max_power in Watts
|
||||
void on_max_power_offered(std::int32_t connector, std::int32_t max_power);
|
||||
|
||||
/// \brief Notifies chargepoint that a new session with the given \p session_id has been started at the given \p
|
||||
/// connector with the given \p reason . The logs of the session will be written into \p session_logging_path if
|
||||
/// present. This function must be called when first interaction with user or EV occurs. This can be a valid
|
||||
/// authorization or the connection of cable and/or EV to the given \p connector
|
||||
/// \param connector
|
||||
/// \param session_id unique id of the session
|
||||
/// \param reason for the initiation of the session
|
||||
/// \param session_logging_path optional filesystem path to where the session log should be written
|
||||
void on_session_started(std::int32_t connector, const std::string& session_id, const SessionStartedReason reason,
|
||||
const std::optional<std::string>& session_logging_path);
|
||||
|
||||
/// \brief Notifies chargepoint that a session has been stopped at the given \p connector. This function must be
|
||||
/// called when the EV disconnects from the given \p connector .
|
||||
/// \param connector
|
||||
/// \param session_id
|
||||
void on_session_stopped(std::int32_t connector, const std::string& session_id);
|
||||
|
||||
/// \brief Notifies chargepoint that a transaction at the given \p connector with the given parameters has been
|
||||
/// started. This function must be called at the point that all conditions for charging are met, for instance, EV is
|
||||
/// connected to Charge Point and user has been authorized.
|
||||
/// \param connector
|
||||
/// \param session_id
|
||||
/// \param id_token that has been used to authorize the transaction
|
||||
/// \param meter_start start meter value in Wh
|
||||
/// \param reservation_id
|
||||
/// \param timestamp of the start of transaction
|
||||
/// \param signed_meter_value e.g. in OCMF format
|
||||
void on_transaction_started(const std::int32_t& connector, const std::string& session_id,
|
||||
const std::string& id_token, const double meter_start,
|
||||
std::optional<std::int32_t> reservation_id, const ocpp::DateTime& timestamp,
|
||||
std::optional<std::string> signed_meter_value);
|
||||
|
||||
/// \brief Notifies chargepoint that the transaction on the given \p connector with the given \p reason has been
|
||||
/// stopped. This function must be called at the point where one of the preconditions for charging irrevocably
|
||||
/// becomes false, for instance when a user swipes to stop the transaction and the stop is authorized or if the EV
|
||||
/// disconnects.
|
||||
/// \param connector
|
||||
/// \param session_id
|
||||
/// \param reason
|
||||
/// \param timestamp of the end of transaction
|
||||
/// \param energy_wh_import stop meter value in Wh
|
||||
/// \param id_tag_end
|
||||
/// \param signed_meter_value e.g. in OCMF format
|
||||
void on_transaction_stopped(const std::int32_t connector, const std::string& session_id, const Reason& reason,
|
||||
ocpp::DateTime timestamp, float energy_wh_import,
|
||||
std::optional<CiString<20>> id_tag_end, std::optional<std::string> signed_meter_value);
|
||||
|
||||
/// \brief This function should be called when EV indicates that it suspends charging on the given \p connector
|
||||
/// \param connector
|
||||
/// \param info
|
||||
void on_suspend_charging_ev(std::int32_t connector, const std::optional<CiString<50>> info = std::nullopt);
|
||||
|
||||
/// \brief This function should be called when EVSE indicates that it suspends charging on the given \p connector
|
||||
/// \param connector
|
||||
/// \param info
|
||||
void on_suspend_charging_evse(std::int32_t connector, const std::optional<CiString<50>> info = std::nullopt);
|
||||
|
||||
/// \brief This function should be called when charging resumes on the given \p connector
|
||||
/// \param connector
|
||||
void on_resume_charging(std::int32_t connector);
|
||||
|
||||
/// \brief This function should be called if an error with the given \p error_info is present. This function will
|
||||
/// trigger a StatusNotification.req containing the given \p error_info . It will change the present state of
|
||||
/// the state machine to faulted, in case the corresponding flag is set in the given \p error_info. This function
|
||||
/// can be called multiple times for different errors. Errors reported using this function stay active as long as
|
||||
/// they are cleared by \ref on_error_cleared().
|
||||
/// \param connector
|
||||
/// \param error_info Additional information related to the error
|
||||
void on_error(std::int32_t connector, const ErrorInfo& error_info);
|
||||
|
||||
/// \brief This function should be called if an error with the given \p uuid has been cleared. If this leads to the
|
||||
/// fact that no other error is active anymore, this function will initiate a StatusNotification.req that reports
|
||||
/// the current state and no error
|
||||
/// \param connector
|
||||
/// \param uuid of a previously reported error. If uuid is not
|
||||
/// known, the event will be ignored
|
||||
void on_error_cleared(std::int32_t connector, const std::string uuid);
|
||||
|
||||
/// \brief Clears all previously reported errors at the same time for the given \p connector . This will
|
||||
/// clear a previously reported "Faulted" state if present
|
||||
/// \param connector
|
||||
void on_all_errors_cleared(std::int32_t connector);
|
||||
|
||||
/// \brief Chargepoint notifies about new log status \p log_status . This function should be called during a
|
||||
/// Diagnostics / Log upload to indicate the current \p log_status .
|
||||
/// \param request_id A \p request_id of -1 indicates a DiagnosticsStatusNotification.req, else a
|
||||
/// LogStatusNotification.req.
|
||||
/// \param log_status The \p log_status should be either be convertable to the
|
||||
/// ocpp::v16::UploadLogStatusEnumType enum or ocpp::v16::DiagnosticsStatus enum depending on the previous request,
|
||||
/// which could have been a DiagnosticsUpload.req or a GetLog.req (Security Whitepaper)
|
||||
void on_log_status_notification(std::int32_t request_id, std::string log_status);
|
||||
|
||||
/// \brief Chargepoint notifies about new firmware update status \p firmware_update_status . This function should be
|
||||
/// called during a Firmware Update to indicate the current \p firmware_update_status .
|
||||
/// \param request_id A \p request_id of -1 indicates a FirmwareStatusNotification.req, else a
|
||||
/// SignedFirmwareUpdateStatusNotification.req .
|
||||
/// \param firmware_update_status The \p firmware_update_status
|
||||
void on_firmware_update_status_notification(std::int32_t request_id,
|
||||
const ocpp::FirmwareStatusNotification firmware_update_status);
|
||||
|
||||
/// \brief This function must be called when a reservation is started at the given \p connector .
|
||||
/// \param connector
|
||||
void on_reservation_start(std::int32_t connector);
|
||||
|
||||
/// \brief This function must be called when a reservation ends at the given \p connector
|
||||
/// \param connector
|
||||
void on_reservation_end(std::int32_t connector);
|
||||
|
||||
/// \brief Notifies chargepoint that the \p connector is enabled . This function should be called when the \p
|
||||
/// connector becomes functional and operational
|
||||
/// \param connector
|
||||
void on_enabled(std::int32_t connector);
|
||||
|
||||
/// \brief Notifies chargepoint that the \p connector is disabled . This function should be called when the \p
|
||||
/// connector becomes inoperative
|
||||
/// \param connector
|
||||
void on_disabled(std::int32_t connector);
|
||||
|
||||
/// \brief Notifies chargepoint that a ConnectionTimeout occured for the given \p connector . This function should
|
||||
/// be called when an EV is plugged in but the authorization is not present within the specified ConnectionTimeout
|
||||
void on_plugin_timeout(std::int32_t connector);
|
||||
|
||||
/// \brief Notifies chargepoint that a SecurityEvent occurs. This will send a SecurityEventNotification.req to the
|
||||
/// CSMS
|
||||
/// \param event_type type of the security event
|
||||
/// \param tech_info additional info of the security event
|
||||
/// \param critical if set this overwrites the default criticality recommended in the OCPP 1.6 security whitepaper.
|
||||
/// A critical security event is transmitted as a message to the CSMS, a non-critical one is just written to the
|
||||
/// security log
|
||||
/// \param timestamp when this security event occured, if absent the current datetime is assumed
|
||||
void on_security_event(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
|
||||
const std::optional<bool>& critical = std::nullopt,
|
||||
const std::optional<DateTime>& timestamp = std::nullopt);
|
||||
|
||||
/// \brief Handles an internal ChangeAvailabilityRequest (in the same way as if it was emitted by the CSMS).
|
||||
/// \param request
|
||||
ChangeAvailabilityResponse on_change_availability(const ChangeAvailabilityRequest& request);
|
||||
|
||||
/// registers a \p callback function that can be used to receive a arbitrary data transfer for the given \p
|
||||
/// vendorId and \p messageId
|
||||
/// \param vendorId
|
||||
/// \param messageId
|
||||
/// \param callback
|
||||
void register_data_transfer_callback(
|
||||
const CiString<255>& vendorId, const CiString<50>& messageId,
|
||||
const std::function<DataTransferResponse(const std::optional<std::string>& msg)>& callback);
|
||||
|
||||
/// registers a \p callback function that can be used to handle arbitrary data transfers for all vendorId an
|
||||
/// messageId
|
||||
/// \param callback
|
||||
void register_data_transfer_callback(
|
||||
const std::function<DataTransferResponse(const DataTransferRequest& request)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to enable the evse. The enable_evse_callback is called
|
||||
/// when a ChangeAvailaibility.req is received.
|
||||
/// \param callback
|
||||
void register_enable_evse_callback(const std::function<bool(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to disable the evse. The disable_evse_callback is
|
||||
/// called when a ChangeAvailaibility.req is received.
|
||||
/// \param callback
|
||||
void register_disable_evse_callback(const std::function<bool(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to pause charging. The pause_charging_callback is
|
||||
/// called when the idTagInfo.status of a StartTransaction.conf is not Accepted
|
||||
/// \param callback
|
||||
void register_pause_charging_callback(const std::function<bool(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to resume charging
|
||||
/// \param callback
|
||||
void register_resume_charging_callback(const std::function<bool(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to provide an \p id_token for the given \p
|
||||
/// referenced_connectors to an authorization handler. \p prevalidated signals to the authorization handler that no
|
||||
/// further authorization is necessary. The provide_token_callback is called when a RemoteStartTransaction.req is
|
||||
/// received.
|
||||
/// \param callback
|
||||
void register_provide_token_callback(
|
||||
const std::function<void(const std::string& id_token, std::vector<std::int32_t> referenced_connectors,
|
||||
bool prevalidated)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to stop a transaction. Ths stop_transaction_callback is
|
||||
/// called
|
||||
/// - when the idTagInfo.status of a StartTransaction.conf is not Accepted
|
||||
/// - when a RemoteStopTransaction.req is received
|
||||
/// - when a UnlockConnector.req is received
|
||||
/// \param callback
|
||||
void register_stop_transaction_callback(const std::function<bool(std::int32_t connector, Reason reason)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to reserve a connector for a idTag until a timeout
|
||||
/// is reached. The reserve_now_callback is called when a ReserveNow.req is received.
|
||||
/// \param callback
|
||||
void register_reserve_now_callback(
|
||||
const std::function<ReservationStatus(std::int32_t reservation_id, std::int32_t connector,
|
||||
ocpp::DateTime expiryDate, CiString<20> idTag,
|
||||
std::optional<CiString<20>> parent_id)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to cancel a reservation on a connector. Callback
|
||||
/// function should return false if the reservation could not be cancelled, else true . The
|
||||
/// cancel_reservation_callback is called when a CancelReservation.req is received
|
||||
/// \param callback
|
||||
void register_cancel_reservation_callback(const std::function<bool(std::int32_t reservation_id)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to unlock the connector. In case a transaction is
|
||||
// active at the specified connector, the \p callback shall stop the transaction before unlocking the connector. The
|
||||
// unlock_connector_callback is called:
|
||||
/// - when receiving a UnlockConnector.req and
|
||||
/// - when a transaction has on_transaction_stopped is called and the configuration key
|
||||
/// UnlockConnectorOnEVSideDisconnect is true
|
||||
/// \param callback
|
||||
void register_unlock_connector_callback(const std::function<UnlockStatus(std::int32_t connector)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to trigger an upload of diagnostics. This callback
|
||||
/// should trigger a process of a diagnostics upload using the given parameters of the request. This process should
|
||||
/// call the on_log_status_notification handler in order to update the status of the file upload. The
|
||||
/// upload_diagnostics_callback is called when a GetDiagnostics.req is received
|
||||
/// \param callback
|
||||
void register_upload_diagnostics_callback(
|
||||
const std::function<GetLogResponse(const GetDiagnosticsRequest& request)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to trigger a firmware update. This callback
|
||||
/// should trigger a process of a firmware update using the given parameters of the request. This process should
|
||||
/// call the on_firmware_update_status_notification handler in order to update the status of the update. The
|
||||
/// update_firmware_callback is called when a FirmwareUpdate.req is received
|
||||
/// \param callback
|
||||
void register_update_firmware_callback(const std::function<void(const UpdateFirmwareRequest msg)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to trigger a signed firmware update. This callback
|
||||
/// should trigger a process of a signed firmware update using the given parameters of the request. This process
|
||||
/// should call the on_firmware_update_status_notification handler in order to update the status of the signed
|
||||
/// firmware update. The signed_update_firmware_callback is called when a SignedUpdateFirmware.req is received.
|
||||
/// \param callback
|
||||
void register_signed_update_firmware_callback(
|
||||
const std::function<UpdateFirmwareStatusEnumType(const SignedUpdateFirmwareRequest msg)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that is called when all connectors are set to unavailable.
|
||||
/// This can be used to then trigger the installation of the firmware update
|
||||
void register_all_connectors_unavailable_callback(const std::function<void()>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to upload logfiles. This callback
|
||||
/// should trigger a process of a log upload using the given parameters of the request. This process should
|
||||
/// call the on_log_status_notification handler in order to update the status of the file upload. The
|
||||
/// upload_logs_callback is called when a GetLog.req is received
|
||||
/// \param callback
|
||||
void register_upload_logs_callback(const std::function<GetLogResponse(GetLogRequest req)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to set the authorization or plug in connection timeout.
|
||||
/// The set_connection_timeout_callback is called when the configuration key ConnectionTimeout has been changed by
|
||||
/// the CSMS.
|
||||
/// \param callback
|
||||
void register_set_connection_timeout_callback(const std::function<void(std::int32_t connection_timeout)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to check if a reset is allowed . The
|
||||
/// is_reset_allowed_callback is called when a Reset.req is received.
|
||||
/// \param callback
|
||||
void register_is_reset_allowed_callback(const std::function<bool(const ResetType& reset_type)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to trigger a reset of the chargepoint. The
|
||||
/// reset_callback is called when a Reset.req is received and a previous execution of the is_reset_allowed_callback
|
||||
/// returned true
|
||||
/// \param callback
|
||||
void register_reset_callback(const std::function<void(const ResetType& reset_type)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to set the system time.
|
||||
/// \param callback
|
||||
void register_set_system_time_callback(const std::function<void(const std::string& system_time)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used receive the BootNotificationResponse
|
||||
/// \param callback
|
||||
void register_boot_notification_response_callback(
|
||||
const std::function<void(const BootNotificationResponse& boot_notification_response)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to signal that the chargepoint received a
|
||||
/// SetChargingProfile.req . The set_charging_profiles_callback is called when a SetChargingProfile.req is received
|
||||
/// and was accepted. The registered callback could make use of the get_all_composite_charging_schedules in order to
|
||||
/// retrieve the ChargingProfiles that have been set by the CSMS.
|
||||
/// \param callback
|
||||
void register_signal_set_charging_profiles_callback(const std::function<void()>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used when the connection state to CSMS changes. The
|
||||
/// connection_state_changed_callback is called when chargepoint has connected to or disconnected from the CSMS.
|
||||
/// \param callback
|
||||
void register_connection_state_changed_callback(const std::function<void(bool is_connected)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to publish the response to a Get15118Certificate.req
|
||||
/// wrapped in a DataTransfer.req . The get_15118_ev_certificate_response_callback is called after the response to a
|
||||
/// DataTransfer.req(Get15118EVCertificate) has been accepted.
|
||||
/// \param callback
|
||||
void register_get_15118_ev_certificate_response_callback(
|
||||
const std::function<void(const std::int32_t connector,
|
||||
const ocpp::v2::Get15118EVCertificateResponse& certificate_response,
|
||||
const ocpp::v2::CertificateActionEnum& certificate_action)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that is called when a StartTransaction.req message is sent by the
|
||||
/// chargepoint
|
||||
/// \param callback
|
||||
void register_transaction_started_callback(
|
||||
const std::function<void(const std::int32_t connector, const std::string& session_id)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that is called when a StopTransaction.req message is sent by the
|
||||
/// chargepoint
|
||||
/// \param callback
|
||||
void register_transaction_stopped_callback(
|
||||
const std::function<void(const std::int32_t connector, const std::string& session_id,
|
||||
const std::int32_t transaction_id)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that is called when a StartTransaction.conf message is received by the
|
||||
/// CSMS. This includes the transactionId.
|
||||
/// \param callback
|
||||
void register_transaction_updated_callback(
|
||||
const std::function<void(const std::int32_t connector, const std::string& session_id,
|
||||
const std::int32_t transaction_id, const IdTagInfo& id_tag_info)>
|
||||
callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to react on changed configuration keys. This
|
||||
/// callback is called when a configuration key has been changed by the CSMS
|
||||
/// \param key the configuration key for which the callback is registered
|
||||
/// \param callback executed when this configuration key changed
|
||||
void register_configuration_key_changed_callback(const CiString<50>& key,
|
||||
const std::function<void(const KeyValue& key_value)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to react on changed configuration key. This
|
||||
/// callback is called when a configuration key and value has been changed by the CSMS, where no key based callback
|
||||
/// is assigned
|
||||
/// \param callback executed when this configuration key changed
|
||||
void
|
||||
register_generic_configuration_key_changed_callback(const std::function<void(const KeyValue& key_value)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to react to a security event callback. This callback is
|
||||
/// called only if the SecurityEvent occured internally within libocpp
|
||||
void register_security_event_callback(
|
||||
const std::function<void(const std::string& type, const std::string& tech_info)>& callback);
|
||||
|
||||
/// \brief registers a \p callback function that can be used to check, if the \p connector is reserved for the given
|
||||
/// \p id_token. The is_token_reserved_for_connector_callback is called when a RemoteStartTransaction.req is
|
||||
/// received.
|
||||
/// \param callback
|
||||
void register_is_token_reserved_for_connector_callback(
|
||||
const std::function<ReservationCheckStatus(const std::int32_t connector, const std::string& id_token)>&
|
||||
callback);
|
||||
|
||||
void register_session_cost_callback(
|
||||
const std::function<DataTransferResponse(const RunningCost& running_cost,
|
||||
const std::uint32_t number_of_decimals)>& session_cost_callback);
|
||||
void register_tariff_message_callback(
|
||||
const std::function<DataTransferResponse(const TariffMessage& message)>& tariff_message_callback);
|
||||
void register_default_price_callback(const std::function<void(const TariffMessage& message)>& callback);
|
||||
void publish_default_price(bool is_offline);
|
||||
void register_set_display_message_callback(
|
||||
const std::function<DataTransferResponse(const std::vector<DisplayMessage>&)> set_display_message_callback);
|
||||
|
||||
/// \brief Gets the configured configuration key requested in the given \p request
|
||||
/// \param request specifies the keys that should be returned. If empty or not set, all keys will be reported
|
||||
/// \return a response containing the requested key(s) including the values and unkown keys if present
|
||||
GetConfigurationResponse get_configuration_key(const GetConfigurationRequest& request);
|
||||
|
||||
/// \brief Sets a configuration key
|
||||
/// \param key
|
||||
/// \param value
|
||||
/// \return Indicates the result of the operation
|
||||
ConfigurationStatus set_configuration_key(CiString<50> key, CiString<500> value);
|
||||
|
||||
/// \brief Delay draining the message queue after reconnecting, so the CSMS can perform post-reconnect checks first
|
||||
/// \param delay The delay period (seconds)
|
||||
void set_message_queue_resume_delay(std::chrono::seconds delay) {
|
||||
this->message_queue_resume_delay = delay;
|
||||
}
|
||||
|
||||
/// \brief Sets the public key of the powermeter for the given connector
|
||||
/// \param connector The connector for which the public key is set
|
||||
/// \param public_key_pem The public key in PEM format
|
||||
/// \return true if the public key was set successfully, false otherwise
|
||||
bool set_powermeter_public_key(const int32_t connector, const std::string& public_key_pem);
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
#endif
|
||||
@@ -0,0 +1,125 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_V16_CHARGE_POINT_STATE_MACHINE_HPP
|
||||
#define OCPP_V16_CHARGE_POINT_STATE_MACHINE_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
enum class FSMEvent {
|
||||
BecomeAvailable,
|
||||
UsageInitiated,
|
||||
StartCharging,
|
||||
PauseChargingEV,
|
||||
PauseChargingEVSE,
|
||||
ReserveConnector,
|
||||
TransactionStoppedAndUserActionRequired,
|
||||
ChangeAvailabilityToUnavailable,
|
||||
ReservationEnd,
|
||||
// FaultDetected - note: this event is handled via a separate function
|
||||
I1_ReturnToAvailable,
|
||||
I2_ReturnToPreparing,
|
||||
I3_ReturnToCharging,
|
||||
I4_ReturnToSuspendedEV,
|
||||
I5_ReturnToSuspendedEVSE,
|
||||
I6_ReturnToFinishing,
|
||||
I7_ReturnToReserved,
|
||||
I8_ReturnToUnavailable,
|
||||
};
|
||||
|
||||
/// \brief Contains all relevant information to handle errros in OCPP1.6
|
||||
struct ErrorInfo {
|
||||
std::string uuid; // uuid
|
||||
ChargePointErrorCode error_code; /// defined by OCPP1.6
|
||||
bool is_fault; /// indicates if state should change to "Faulted", if not set, state will not change and error is
|
||||
/// only informational
|
||||
std::optional<CiString<50>> info; /// defined by OCPP1.6
|
||||
std::optional<CiString<255>> vendor_id; /// defined by OCPP1.6
|
||||
std::optional<CiString<50>> vendor_error_code; /// defined by OCPP1.6
|
||||
DateTime timestamp; // timestamp
|
||||
|
||||
ErrorInfo(const std::string uuid, const ChargePointErrorCode error_code, const bool is_fault);
|
||||
ErrorInfo(const std::string uuid, const ChargePointErrorCode error_code, const bool is_fault,
|
||||
const std::optional<std::string> info);
|
||||
ErrorInfo(const std::string uuid, const ChargePointErrorCode error_code, const bool is_fault,
|
||||
const std::optional<std::string> info, const std::optional<std::string> vendor_id);
|
||||
ErrorInfo(const std::string uuid, const ChargePointErrorCode error_code, const bool is_fault,
|
||||
const std::optional<std::string> info, const std::optional<std::string> vendor_id,
|
||||
const std::optional<std::string> vendor_error_code);
|
||||
};
|
||||
|
||||
using FSMState = ChargePointStatus;
|
||||
|
||||
using FSMStateTransitions = std::map<FSMEvent, FSMState>;
|
||||
|
||||
using FSMDefinition = std::map<FSMState, FSMStateTransitions>;
|
||||
|
||||
class ChargePointFSM {
|
||||
public:
|
||||
using StatusNotificationCallback = std::function<void(
|
||||
const ChargePointStatus status, const ChargePointErrorCode error_code, const ocpp::DateTime& timestamp,
|
||||
const std::optional<CiString<50>>& info, const std::optional<CiString<255>>& vendor_id,
|
||||
const std::optional<CiString<50>>& vendor_error_code)>;
|
||||
explicit ChargePointFSM(const StatusNotificationCallback& status_notification_callback, FSMState initial_state);
|
||||
|
||||
bool handle_event(FSMEvent event, const ocpp::DateTime timestamp, const std::optional<CiString<50>>& info);
|
||||
bool handle_error(const ErrorInfo& error_info);
|
||||
bool handle_error_cleared(const std::string uuid);
|
||||
bool handle_all_errors_cleared();
|
||||
void trigger_status_notification();
|
||||
|
||||
FSMState get_state();
|
||||
std::optional<ErrorInfo> get_latest_error();
|
||||
|
||||
private:
|
||||
StatusNotificationCallback status_notification_callback;
|
||||
// track current state
|
||||
|
||||
FSMState state;
|
||||
std::unordered_map<std::string, ErrorInfo> active_errors;
|
||||
|
||||
bool is_faulted();
|
||||
};
|
||||
|
||||
class ChargePointStates {
|
||||
public:
|
||||
using ConnectorStatusCallback = std::function<void(
|
||||
const int connector_id, const ChargePointErrorCode errorCode, const ChargePointStatus status,
|
||||
const ocpp::DateTime& timestamp, const std::optional<CiString<50>>& info,
|
||||
const std::optional<CiString<255>>& vendor_id, const std::optional<CiString<50>>& vendor_error_code)>;
|
||||
ChargePointStates(const ConnectorStatusCallback& connector_status_callback);
|
||||
void reset(std::map<int, ChargePointStatus> connector_status_map);
|
||||
|
||||
void submit_event(const int connector_id, FSMEvent event, const ocpp::DateTime& timestamp,
|
||||
const std::optional<CiString<50>>& info = std::nullopt);
|
||||
void submit_error(const int connector_id, const ErrorInfo& error_info);
|
||||
void submit_error_cleared(const int connector_id, const std::string uuid);
|
||||
void submit_all_errors_cleared(const std::int32_t connector_id);
|
||||
void trigger_status_notification(const int connector_id);
|
||||
void trigger_status_notifications();
|
||||
|
||||
ChargePointStatus get_state(int connector_id);
|
||||
std::optional<ErrorInfo> get_latest_error(int connector_id);
|
||||
|
||||
private:
|
||||
ConnectorStatusCallback connector_status_callback;
|
||||
|
||||
std::unique_ptr<ChargePointFSM> state_machine_connector_zero;
|
||||
std::vector<ChargePointFSM> state_machines;
|
||||
std::mutex state_machines_mutex;
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_CHARGE_POINT_STATE_MACHINE_HPP
|
||||
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef OCPP_V16_CONNECTOR_HPP
|
||||
#define OCPP_V16_CONNECTOR_HPP
|
||||
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
#include <ocpp/v16/transaction.hpp>
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
struct Connector {
|
||||
std::int32_t id;
|
||||
std::optional<Measurement> measurement;
|
||||
double max_current_offered = 0;
|
||||
double max_power_offered = 0;
|
||||
std::shared_ptr<Transaction> transaction = nullptr;
|
||||
std::map<int, ChargingProfile> stack_level_tx_default_profiles_map;
|
||||
std::map<int, ChargingProfile> stack_level_tx_profiles_map;
|
||||
std::optional<std::vector<ChargePointStatus>> trigger_metervalue_on_status;
|
||||
std::optional<double> trigger_metervalue_on_power_kw;
|
||||
std::optional<double> trigger_metervalue_on_energy_kwh;
|
||||
std::unique_ptr<Everest::SystemTimer> trigger_metervalue_at_time_timer;
|
||||
std::optional<ChargePointStatus> previous_status;
|
||||
std::optional<double> last_triggered_metervalue_power_kw;
|
||||
|
||||
explicit Connector(const int id) : id(id) {
|
||||
}
|
||||
~Connector() = default;
|
||||
Connector& operator=(const Connector&) = delete;
|
||||
Connector(const Connector&) = delete;
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,173 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_V16_DATABASE_HANDLER_HPP
|
||||
#define OCPP_V16_DATABASE_HANDLER_HPP
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <ocpp/common/database/database_handler_common.hpp>
|
||||
#include <ocpp/common/schemas.hpp>
|
||||
#include <ocpp/common/support_older_cpp_versions.hpp>
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Struct that contains all attributes of a transaction entry in the database
|
||||
struct TransactionEntry {
|
||||
std::string session_id;
|
||||
std::int32_t connector;
|
||||
std::string id_tag_start;
|
||||
std::string time_start;
|
||||
std::int32_t meter_start;
|
||||
std::int32_t transaction_id;
|
||||
bool csms_ack;
|
||||
std::int32_t meter_last;
|
||||
std::string meter_last_time;
|
||||
std::string last_update;
|
||||
std::string start_transaction_message_id;
|
||||
std::optional<std::string> stop_transaction_message_id;
|
||||
std::optional<std::int32_t> reservation_id = std::nullopt;
|
||||
std::optional<std::string> parent_id_tag = std::nullopt;
|
||||
std::optional<std::int32_t> meter_stop = std::nullopt;
|
||||
std::optional<std::string> time_end = std::nullopt;
|
||||
std::optional<std::string> id_tag_end = std::nullopt;
|
||||
std::optional<std::string> stop_reason = std::nullopt;
|
||||
};
|
||||
|
||||
/// \brief This class handles the connection and operations of the SQLite database
|
||||
class DatabaseHandler : public ocpp::common::DatabaseHandlerCommon {
|
||||
private:
|
||||
const std::int32_t number_of_connectors;
|
||||
|
||||
// Runs initialization script and initializes the CONNECTORS and AUTH_LIST_VERSION table.
|
||||
void init_sql() override;
|
||||
void init_connector_table();
|
||||
|
||||
public:
|
||||
DatabaseHandler(std::unique_ptr<everest::db::sqlite::ConnectionInterface> database,
|
||||
const fs::path& sql_migration_files_path, std::int32_t number_of_connectors);
|
||||
|
||||
// transactions
|
||||
/// \brief Inserts a transaction with the given parameter to the TRANSACTIONS table.
|
||||
void insert_transaction(const std::string& session_id, const std::int32_t transaction_id,
|
||||
const std::int32_t connector, const std::string& id_tag_start,
|
||||
const std::string& time_start, const std::int32_t meter_start, const bool csms_ack,
|
||||
const std::optional<std::int32_t> reservation_id,
|
||||
const std::string& start_transaction_message_id);
|
||||
|
||||
/// \brief Updates the given parameters for the transaction with the given \p session_id in the TRANSACTIONS table.
|
||||
void update_transaction(const std::string& session_id, std::int32_t transaction_id,
|
||||
std::optional<CiString<20>> parent_id_tag = std::nullopt);
|
||||
|
||||
/// \brief Updates the given parameters for the transaction with the given \p session_id in the TRANSACTIONS table.
|
||||
void update_transaction(const std::string& session_id, std::int32_t meter_stop, const std::string& time_end,
|
||||
std::optional<CiString<20>> id_tag_end, std::optional<v16::Reason> stop_reason,
|
||||
const std::string& stop_transaction_message_id);
|
||||
|
||||
/// \brief Updates the CSMS_ACK column for the transaction with the given \p transaction_id in the TRANSACTIONS
|
||||
/// table
|
||||
void update_transaction_csms_ack(const std::int32_t transaction_id);
|
||||
|
||||
/// \brief Returns the TransactionEntry for the given \p transaction_id, or std::nullopt if not found.
|
||||
std::optional<TransactionEntry> get_transaction(const std::int32_t transaction_id);
|
||||
|
||||
/// \brief Updates the START_TRANSACTION_MESSAGE_ID column for the transaction with the given \p session_id in the
|
||||
/// TRANSACTIONS table
|
||||
void update_start_transaction_message_id(const std::string& session_id,
|
||||
const std::string& start_transaction_message_id);
|
||||
|
||||
/// \brief Updates the METER_LAST and METER_LAST_TIME column for the transaction with the given \p session_id in the
|
||||
/// TRANSACTIONS table
|
||||
void update_transaction_meter_value(const std::string& session_id, const std::int32_t value,
|
||||
const std::string& last_meter_time);
|
||||
|
||||
/// \brief Returns a list of all transactions in the database. If \p filter_complete is true, only incomplete
|
||||
/// transactions will be return. If \p filter_complete is false, all transactions will be returned
|
||||
std::vector<TransactionEntry> get_transactions(bool filter_incomplete = false);
|
||||
|
||||
// authorization cache
|
||||
/// \brief Inserts or updates an authorization cache entry to the AUTH_CACHE table.
|
||||
void insert_or_update_authorization_cache_entry(const CiString<20>& id_tag, const v16::IdTagInfo& id_tag_info);
|
||||
|
||||
/// \brief Returns the IdTagInfo of the given \p id_tag if it exists in the AUTH_CACHE table, else std::nullopt.
|
||||
std::optional<v16::IdTagInfo> get_authorization_cache_entry(const CiString<20>& id_tag);
|
||||
|
||||
/// \brief Deletes all entries of the AUTH_CACHE table.
|
||||
void clear_authorization_cache();
|
||||
|
||||
// connector availability
|
||||
/// \brief Inserts or updates the given \p availability_type of the given \p connector to the CONNECTORS table.
|
||||
void insert_or_update_connector_availability(std::int32_t connector,
|
||||
const v16::AvailabilityType& availability_type);
|
||||
|
||||
/// \brief Inserts or updates the given \p availability_type of the given \p connectors to the CONNECTORS table.
|
||||
void insert_or_update_connector_availability(const std::vector<std::int32_t>& connectors,
|
||||
const v16::AvailabilityType& availability_type);
|
||||
|
||||
/// \brief Returns the AvailabilityType of the given \p connector of the CONNECTORS table.
|
||||
v16::AvailabilityType get_connector_availability(std::int32_t connector);
|
||||
|
||||
/// \brief Returns a map of all connectors and its AvailabilityTypes of the CONNECTORS table.
|
||||
std::map<std::int32_t, v16::AvailabilityType> get_connector_availability();
|
||||
|
||||
// local auth list management
|
||||
|
||||
/// \brief Inserts or ignores the given \p version in the AUTH_LIST_VERSION table.
|
||||
void insert_or_ignore_local_list_version(std::int32_t version);
|
||||
|
||||
/// \brief Inserts or updates the given \p version in the AUTH_LIST_VERSION table.
|
||||
void insert_or_update_local_list_version(std::int32_t version);
|
||||
|
||||
/// \brief Returns the version in the AUTH_LIST_VERSION table.
|
||||
std::int32_t get_local_list_version();
|
||||
|
||||
/// \brief Inserts or updates a local authorization list entry to the AUTH_LIST table.
|
||||
void insert_or_update_local_authorization_list_entry(const CiString<20>& id_tag, const v16::IdTagInfo& id_tag_info);
|
||||
|
||||
/// \brief Inserts or updates a local authorization list entries \p local_authorization_list to the AUTH_LIST table.
|
||||
void insert_or_update_local_authorization_list(std::vector<v16::LocalAuthorizationList> local_authorization_list);
|
||||
|
||||
/// \brief Deletes the authorization list entry with the given \p id_tag
|
||||
void delete_local_authorization_list_entry(const std::string& id_tag);
|
||||
|
||||
/// \brief Returns the IdTagInfo of the given \p id_tag if it exists in the AUTH_LIST table, else std::nullopt.
|
||||
std::optional<v16::IdTagInfo> get_local_authorization_list_entry(const CiString<20>& id_tag);
|
||||
|
||||
/// \brief Deletes all entries of the AUTH_LIST table.
|
||||
void clear_local_authorization_list();
|
||||
|
||||
/// \brief Get the number of entries currently in the authorization list
|
||||
std::int32_t get_local_authorization_list_number_of_entries();
|
||||
|
||||
/// \brief Inserts or updates the given \p profile to CHARGING_PROFILES table
|
||||
virtual void insert_or_update_charging_profile(const int connector_id, const v16::ChargingProfile& profile);
|
||||
|
||||
/// \brief Deletes the profile with the given \p profile_id
|
||||
virtual void delete_charging_profile(const int profile_id);
|
||||
|
||||
/// \brief Deletes all profiles from table CHARGING_PROFILES
|
||||
void delete_charging_profiles();
|
||||
|
||||
/// \brief Returns a list of all charging profiles in the CHARGING_PROFILES table
|
||||
std::vector<v16::ChargingProfile> get_charging_profiles();
|
||||
|
||||
/// \brief Returns the connector_id of the given \p profile_id
|
||||
int get_connector_id(const int profile_id);
|
||||
|
||||
/// \brief Returns the ids of all charging profiles stored against the given \p connector_id
|
||||
///
|
||||
/// Used to discover profiles whose install-time connector was 0 (i.e. ChargePointMaxProfile
|
||||
/// and TxDefaultProfile installed at the charge-point level) so that ClearChargingProfile
|
||||
/// with connectorId=0 can remove them along with their in-memory fan-out copies.
|
||||
virtual std::vector<int32_t> get_charging_profile_ids_by_connector_id(const int connector_id);
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_COMMON_DATABASE_HANDLER_HPP
|
||||
@@ -0,0 +1,394 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2026 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef OCPP_V16_KNOWN_KEYS_HPP
|
||||
#define OCPP_V16_KNOWN_KEYS_HPP
|
||||
|
||||
#include "ocpp/v16/types.hpp"
|
||||
#include "ocpp/v2/ctrlr_component_variables.hpp"
|
||||
#include "ocpp/v2/ocpp_enums.hpp"
|
||||
#include "ocpp/v2/ocpp_types.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <tuple>
|
||||
|
||||
namespace ocpp::v16::keys {
|
||||
|
||||
// clang-format off
|
||||
// ============================================================================
|
||||
// Standard OCPP 1.6 keys
|
||||
// ============================================================================
|
||||
|
||||
// SupportedMeasurands is collected from the following valuesList elements
|
||||
// - AlignedDataMeasurands
|
||||
// - AlignedDataTxEndedMeasurands
|
||||
// - SampledDataTxEndedMeasurands
|
||||
// - SampledDataTxStartedMeasurands
|
||||
// - SampledDataTxUpdatedMeasurands
|
||||
|
||||
#define MAPPING_STANDARD(mapping) \
|
||||
mapping(AllowOfflineTxForUnknownId, OfflineTxForUnknownIdEnabled, Actual) \
|
||||
mapping(AuthorizationCacheEnabled, AuthCacheCtrlrEnabled, Actual) \
|
||||
mapping(AuthorizeRemoteTxRequests, AuthorizeRemoteStart, Actual) \
|
||||
mapping(ClockAlignedDataInterval, AlignedDataInterval, Actual) \
|
||||
mapping(ConnectionTimeOut, EVConnectionTimeOut, Actual) \
|
||||
mapping(HeartbeatInterval, HeartbeatInterval, Actual) \
|
||||
mapping(LocalAuthorizeOffline, LocalAuthorizeOffline, Actual) \
|
||||
mapping(LocalPreAuthorize, LocalPreAuthorize, Actual) \
|
||||
mapping(MaxEnergyOnInvalidId, MaxEnergyOnInvalidId, Actual) \
|
||||
mapping(MeterValuesAlignedData, AlignedDataMeasurands, Actual) \
|
||||
mapping(MeterValuesSampledData, SampledDataTxUpdatedMeasurands, Actual) \
|
||||
mapping(MeterValueSampleInterval, SampledDataTxUpdatedInterval, Actual) \
|
||||
mapping(ResetRetries, ResetRetries, Actual) \
|
||||
mapping(StopTransactionOnInvalidId, StopTxOnInvalidId, Actual) \
|
||||
mapping(StopTxnAlignedData, AlignedDataTxEndedMeasurands, Actual) \
|
||||
mapping(StopTxnSampledData, SampledDataTxEndedMeasurands, Actual) \
|
||||
mapping(TransactionMessageAttempts, MessageAttempts, Actual) \
|
||||
mapping(TransactionMessageRetryInterval, MessageAttemptInterval, Actual) \
|
||||
mapping(WebSocketPingInterval, WebSocketPingInterval, Actual) \
|
||||
mapping(LocalAuthListEnabled, LocalAuthListCtrlrEnabled, Actual) \
|
||||
mapping(ChargeProfileMaxStackLevel, ChargingProfileMaxStackLevel, Actual) \
|
||||
mapping(ChargingScheduleAllowedChargingRateUnit, ChargingScheduleChargingRateUnit, Actual) \
|
||||
mapping(ChargingScheduleMaxPeriods, PeriodsPerSchedule, Actual) \
|
||||
mapping(ConnectorSwitch3to1PhaseSupported, Phases3to1, Actual) \
|
||||
mapping(SupportedFileTransferProtocols, FileTransferProtocols, Actual)
|
||||
|
||||
// ============================================================================
|
||||
// Internal configuration keys
|
||||
// ============================================================================
|
||||
|
||||
#define MAPPING_INTERNAL(mapping) \
|
||||
mapping(ChargePointId, ChargePointId, Actual) \
|
||||
mapping(ChargeBoxSerialNumber, ChargeBoxSerialNumber, Actual) \
|
||||
mapping(ChargePointModel, ChargePointModel, Actual) \
|
||||
mapping(ChargePointSerialNumber, ChargePointSerialNumber, Actual) \
|
||||
mapping(ChargePointVendor, ChargePointVendor, Actual) \
|
||||
mapping(FirmwareVersion, FirmwareVersion, Actual) \
|
||||
mapping(ICCID, ICCID, Actual) \
|
||||
mapping(IFace, IFace, Actual) \
|
||||
mapping(IMSI, IMSI, Actual) \
|
||||
mapping(MeterSerialNumber, MeterSerialNumber, Actual) \
|
||||
mapping(MeterType, MeterType, Actual) \
|
||||
mapping(SupportedCiphers12, SupportedCiphers12, Actual) \
|
||||
mapping(SupportedCiphers13, SupportedCiphers13, Actual) \
|
||||
mapping(UseTPM, UseTPM, Actual) \
|
||||
mapping(UseTPMSeccLeafCertificate, UseTPMSeccLeafCertificate, Actual) \
|
||||
mapping(RetryBackoffRandomRange, RetryBackOffRandomRange, Actual) \
|
||||
mapping(RetryBackoffRepeatTimes, RetryBackOffRepeatTimes, Actual) \
|
||||
mapping(AuthorizeConnectorZeroOnConnectorOne,AuthorizeConnectorZeroOnConnectorOne, Actual) \
|
||||
mapping(LogMessages, LogMessages, Actual) \
|
||||
mapping(LogMessagesRaw, LogMessagesRaw, Actual) \
|
||||
mapping(LogMessagesFormat, LogMessagesFormat, Actual) \
|
||||
mapping(LogRotation, LogRotation, Actual) \
|
||||
mapping(LogRotationDateSuffix, LogRotationDateSuffix, Actual) \
|
||||
mapping(LogRotationMaximumFileSize, LogRotationMaximumFileSize, Actual) \
|
||||
mapping(LogRotationMaximumFileCount, LogRotationMaximumFileCount, Actual) \
|
||||
mapping(SupportedChargingProfilePurposeTypes,SupportedChargingProfilePurposeTypes, Actual) \
|
||||
mapping(IgnoredProfilePurposesOffline, IgnoredProfilePurposesOffline, Actual) \
|
||||
mapping(MaxCompositeScheduleDuration, MaxCompositeScheduleDuration, Actual) \
|
||||
mapping(CompositeScheduleDefaultLimitAmps, CompositeScheduleDefaultLimitAmps, Actual) \
|
||||
mapping(CompositeScheduleDefaultLimitWatts, CompositeScheduleDefaultLimitWatts, Actual) \
|
||||
mapping(CompositeScheduleDefaultNumberPhases, CompositeScheduleDefaultNumberPhases, Actual) \
|
||||
mapping(SupplyVoltage, SupplyVoltage, Actual) \
|
||||
mapping(WebsocketPingPayload, WebsocketPingPayload, Actual) \
|
||||
mapping(WebsocketPongTimeout, WebsocketPongTimeout, Actual) \
|
||||
mapping(UseSslDefaultVerifyPaths, UseSslDefaultVerifyPaths, Actual) \
|
||||
mapping(VerifyCsmsCommonName, VerifyCsmsCommonName, Actual) \
|
||||
mapping(VerifyCsmsAllowWildcards, VerifyCsmsAllowWildcards, Actual) \
|
||||
mapping(OcspRequestInterval, OcspRequestInterval, Actual) \
|
||||
mapping(SeccLeafSubjectCommonName, ISO15118CtrlrSeccId, Actual) \
|
||||
mapping(SeccLeafSubjectCountry, ISO15118CtrlrCountryName, Actual) \
|
||||
mapping(SeccLeafSubjectOrganization, ISO15118CtrlrOrganizationName, Actual) \
|
||||
mapping(QueueAllMessages, QueueAllMessages, Actual) \
|
||||
mapping(MessageTypesDiscardForQueueing, MessageTypesDiscardForQueueing, Actual) \
|
||||
mapping(MessageQueueSizeThreshold, MessageQueueSizeThreshold, Actual) \
|
||||
mapping(MaxMessageSize, MaxMessageSize, Actual) \
|
||||
mapping(TLSKeylogFile, TLSKeylogFile, Actual) \
|
||||
mapping(EnableTLSKeylog, EnableTLSKeylog, Actual) \
|
||||
mapping(NumberOfConnectors, NumberOfConnectors, Actual) \
|
||||
mapping(RetryBackoffWaitMinimum, RetryBackOffWaitMinimum, Actual)
|
||||
|
||||
// ============================================================================
|
||||
// VariableCharacteristics.maxLimit mappings
|
||||
// These OCPP 1.6 read-only length/limit keys map to VariableCharacteristics.maxLimit
|
||||
// in OCPP 2.x
|
||||
// ============================================================================
|
||||
|
||||
#define MAPPING_MAX_LIMIT(mapping) \
|
||||
mapping(MeterValuesAlignedDataMaxLength, AlignedDataMeasurands) \
|
||||
mapping(MeterValuesSampledDataMaxLength, SampledDataTxUpdatedMeasurands) \
|
||||
mapping(StopTxnAlignedDataMaxLength, AlignedDataTxEndedMeasurands) \
|
||||
mapping(StopTxnSampledDataMaxLength, SampledDataTxEndedMeasurands) \
|
||||
mapping(LocalAuthListMaxLength, LocalAuthListCtrlrEntries) \
|
||||
mapping(SendLocalListMaxLength, ItemsPerMessageSendLocalList) \
|
||||
mapping(MaxChargingProfilesInstalled, EntriesChargingProfiles)
|
||||
|
||||
// ============================================================================
|
||||
// Security Section
|
||||
// ============================================================================
|
||||
|
||||
#define MAPPING_SECURITY(mapping) \
|
||||
mapping(AdditionalRootCertificateCheck, AdditionalRootCertificateCheck, Actual) \
|
||||
mapping(CertificateSignedMaxChainSize, MaxCertificateChainSize, Actual) \
|
||||
mapping(CpoName, OrganizationName, Actual) \
|
||||
mapping(CertSigningWaitMinimum, CertSigningWaitMinimum, Actual) \
|
||||
mapping(CertSigningRepeatTimes, CertSigningRepeatTimes, Actual) \
|
||||
mapping(CertificateStoreMaxLength, CertificateEntries, Actual)
|
||||
|
||||
// ============================================================================
|
||||
// PnC Section
|
||||
// ============================================================================
|
||||
|
||||
#define MAPPING_PNC(mapping) \
|
||||
mapping(ISO15118PnCEnabled, PnCEnabled, Actual) \
|
||||
mapping(CentralContractValidationAllowed, CentralContractValidationAllowed, Actual) \
|
||||
mapping(ContractValidationOffline, ContractValidationOffline, Actual)
|
||||
|
||||
// ============================================================================
|
||||
// CostAndPrice Section
|
||||
// ============================================================================
|
||||
|
||||
#define MAPPING_COST(mapping) \
|
||||
mapping(NumberOfDecimalsForCostValues, NumberOfDecimalsForCostValues, Actual) \
|
||||
mapping(TimeOffset, TimeOffset, Actual) \
|
||||
mapping(NextTimeOffsetTransitionDateTime, NextTimeOffsetTransitionDateTime, Actual) \
|
||||
mapping(TimeOffsetNextTransition, TimeOffsetNextTransition, Actual)
|
||||
|
||||
// ============================================================================
|
||||
// Mavericks Section - OCPP 1.6 keys without direct OCPP 2.x equivalents
|
||||
// ============================================================================
|
||||
|
||||
#define MAPPING_MISC(mapping) \
|
||||
mapping(BlinkRepeat, BlinkRepeat, Actual) \
|
||||
mapping(ConnectorPhaseRotation, ConnectorPhaseRotation, Actual) \
|
||||
mapping(ConnectorPhaseRotationMaxLength, ConnectorPhaseRotationMaxLength, Actual) \
|
||||
mapping(GetConfigurationMaxKeys, GetConfigurationMaxKeys, Actual) \
|
||||
mapping(LightIntensity, LightIntensity, Actual) \
|
||||
mapping(MinimumStatusDuration, MinimumStatusDuration, Actual) \
|
||||
mapping(StopTransactionOnEVSideDisconnect, StopTransactionOnEVSideDisconnect, Actual) \
|
||||
mapping(SupportedFeatureProfiles, SupportedFeatureProfiles, Actual) \
|
||||
mapping(SupportedFeatureProfilesMaxLength, SupportedFeatureProfilesMaxLength, Actual) \
|
||||
mapping(UnlockConnectorOnEVSideDisconnect, UnlockConnectorOnEVSideDisconnect, Actual) \
|
||||
mapping(ReserveConnectorZeroSupported, ReserveConnectorZeroSupported, Actual) \
|
||||
mapping(HostName, HostName, Actual) \
|
||||
mapping(AllowChargingProfileWithoutStartSchedule, AllowChargingProfileWithoutStartSchedule, Actual) \
|
||||
mapping(WaitForStopTransactionsOnResetTimeout, WaitForStopTransactionsOnResetTimeout, Actual) \
|
||||
mapping(StopTransactionIfUnlockNotSupported, StopTransactionIfUnlockNotSupported, Actual) \
|
||||
mapping(MeterPublicKeys, MeterPublicKeys, Actual) \
|
||||
mapping(DisableSecurityEventNotifications, DisableSecurityEventNotifications, Actual) \
|
||||
mapping(ISO15118CertificateManagementEnabled, ISO15118CertificateManagementEnabled, Actual) \
|
||||
mapping(CustomDisplayCostAndPrice, CustomDisplayCostAndPrice, Actual) \
|
||||
mapping(DefaultPrice, DefaultPrice, Actual) \
|
||||
mapping(DefaultPriceText, DefaultPriceText, Actual) \
|
||||
mapping(CustomIdleFeeAfterStop, CustomIdleFeeAfterStop, Actual) \
|
||||
mapping(SupportedLanguages, SupportedLanguages, Actual) \
|
||||
mapping(CustomMultiLanguageMessages, CustomMultiLanguageMessages, Actual) \
|
||||
mapping(Language, Language, Actual) \
|
||||
mapping(WaitForSetUserPriceTimeout, WaitForSetUserPriceTimeout, Actual)
|
||||
|
||||
// ============================================================================
|
||||
// Mavericks Section - OCPP 1.6 keys where OCPP 2.x mapping is problematic
|
||||
// ============================================================================
|
||||
|
||||
#define MAPPING_MISC_ADDITIONAL(mapping) \
|
||||
mapping(AuthorizationKey, AuthorizationKey16, Actual) \
|
||||
mapping(CentralSystemURI, CentralSystemURI16, Actual) \
|
||||
mapping(SecurityProfile, SecurityProfile16, Actual)
|
||||
|
||||
#define MAPPING_ALL(mapping) \
|
||||
MAPPING_MISC_ADDITIONAL(mapping) \
|
||||
MAPPING_MISC(mapping) \
|
||||
MAPPING_STANDARD(mapping) \
|
||||
MAPPING_INTERNAL(mapping) \
|
||||
MAPPING_SECURITY(mapping) \
|
||||
MAPPING_PNC(mapping) \
|
||||
MAPPING_COST(mapping)
|
||||
|
||||
#define FOR_ALL_MAPPED_KEYS(key) \
|
||||
key(Core, AllowOfflineTxForUnknownId) \
|
||||
key(Core, AuthorizationCacheEnabled) \
|
||||
key(Core, AuthorizeRemoteTxRequests) \
|
||||
key(Core, BlinkRepeat) \
|
||||
key(Core, ClockAlignedDataInterval) \
|
||||
key(Core, ConnectionTimeOut) \
|
||||
key(Core, ConnectorPhaseRotation) \
|
||||
key(Core, ConnectorPhaseRotationMaxLength) \
|
||||
key(Core, GetConfigurationMaxKeys) \
|
||||
key(Core, HeartbeatInterval) \
|
||||
key(Core, LightIntensity) \
|
||||
key(Core, LocalAuthorizeOffline) \
|
||||
key(Core, LocalPreAuthorize) \
|
||||
key(Core, MaxEnergyOnInvalidId) \
|
||||
key(Core, MeterValuesAlignedData) \
|
||||
key(Core, MeterValuesAlignedDataMaxLength) \
|
||||
key(Core, MeterValueSampleInterval) \
|
||||
key(Core, MeterValuesSampledData) \
|
||||
key(Core, MeterValuesSampledDataMaxLength) \
|
||||
key(Core, MinimumStatusDuration) \
|
||||
key(Core, NumberOfConnectors) \
|
||||
key(Core, ResetRetries) \
|
||||
key(Core, StopTransactionOnEVSideDisconnect) \
|
||||
key(Core, StopTransactionOnInvalidId) \
|
||||
key(Core, StopTxnAlignedData) \
|
||||
key(Core, StopTxnAlignedDataMaxLength) \
|
||||
key(Core, StopTxnSampledData) \
|
||||
key(Core, StopTxnSampledDataMaxLength) \
|
||||
key(Core, SupportedFeatureProfiles) \
|
||||
key(Core, SupportedFeatureProfilesMaxLength) \
|
||||
key(Core, TransactionMessageAttempts) \
|
||||
key(Core, TransactionMessageRetryInterval) \
|
||||
key(Core, UnlockConnectorOnEVSideDisconnect) \
|
||||
key(Core, WebSocketPingInterval) \
|
||||
key(CostAndPrice, CustomDisplayCostAndPrice) \
|
||||
key(CostAndPrice, CustomIdleFeeAfterStop) \
|
||||
key(CostAndPrice, CustomMultiLanguageMessages) \
|
||||
key(CostAndPrice, DefaultPrice) \
|
||||
key(CostAndPrice, DefaultPriceText) \
|
||||
key(CostAndPrice, Language) \
|
||||
key(CostAndPrice, NextTimeOffsetTransitionDateTime) \
|
||||
key(CostAndPrice, NumberOfDecimalsForCostValues) \
|
||||
key(CostAndPrice, SupportedLanguages) \
|
||||
key(CostAndPrice, TimeOffset) \
|
||||
key(CostAndPrice, TimeOffsetNextTransition) \
|
||||
key(CostAndPrice, WaitForSetUserPriceTimeout) \
|
||||
key(FirmwareManagement, SupportedFileTransferProtocols) \
|
||||
key(Internal, AllowChargingProfileWithoutStartSchedule) \
|
||||
key(Internal, AuthorizeConnectorZeroOnConnectorOne) \
|
||||
key(Internal, CentralSystemURI) \
|
||||
key(Internal, ChargeBoxSerialNumber) \
|
||||
key(Internal, ChargePointId) \
|
||||
key(Internal, ChargePointModel) \
|
||||
key(Internal, ChargePointSerialNumber) \
|
||||
key(Internal, ChargePointVendor) \
|
||||
key(Internal, CompositeScheduleDefaultLimitAmps) \
|
||||
key(Internal, CompositeScheduleDefaultLimitWatts) \
|
||||
key(Internal, CompositeScheduleDefaultNumberPhases) \
|
||||
key(Internal, EnableTLSKeylog) \
|
||||
key(Internal, FirmwareVersion) \
|
||||
key(Internal, HostName) \
|
||||
key(Internal, ICCID) \
|
||||
key(Internal, IFace) \
|
||||
key(Internal, IgnoredProfilePurposesOffline) \
|
||||
key(Internal, IMSI) \
|
||||
key(Internal, LogMessages) \
|
||||
key(Internal, LogMessagesFormat) \
|
||||
key(Internal, LogMessagesRaw) \
|
||||
key(Internal, LogRotation) \
|
||||
key(Internal, LogRotationDateSuffix) \
|
||||
key(Internal, LogRotationMaximumFileCount) \
|
||||
key(Internal, LogRotationMaximumFileSize) \
|
||||
key(Internal, MaxCompositeScheduleDuration) \
|
||||
key(Internal, MaxMessageSize) \
|
||||
key(Internal, MessageQueueSizeThreshold) \
|
||||
key(Internal, MessageTypesDiscardForQueueing) \
|
||||
key(Internal, MeterPublicKeys) \
|
||||
key(Internal, MeterSerialNumber) \
|
||||
key(Internal, MeterType) \
|
||||
key(Internal, OcspRequestInterval) \
|
||||
key(Internal, QueueAllMessages) \
|
||||
key(Internal, RetryBackoffRandomRange) \
|
||||
key(Internal, RetryBackoffRepeatTimes) \
|
||||
key(Internal, RetryBackoffWaitMinimum) \
|
||||
key(Internal, SeccLeafSubjectCommonName) \
|
||||
key(Internal, SeccLeafSubjectCountry) \
|
||||
key(Internal, SeccLeafSubjectOrganization) \
|
||||
key(Internal, StopTransactionIfUnlockNotSupported) \
|
||||
key(Internal, SupplyVoltage) \
|
||||
key(Internal, SupportedChargingProfilePurposeTypes) \
|
||||
key(Internal, SupportedCiphers12) \
|
||||
key(Internal, SupportedCiphers13) \
|
||||
key(Internal, TLSKeylogFile) \
|
||||
key(Internal, UseSslDefaultVerifyPaths) \
|
||||
key(Internal, UseTPM) \
|
||||
key(Internal, UseTPMSeccLeafCertificate) \
|
||||
key(Internal, VerifyCsmsAllowWildcards) \
|
||||
key(Internal, VerifyCsmsCommonName) \
|
||||
key(Internal, WaitForStopTransactionsOnResetTimeout) \
|
||||
key(Internal, WebsocketPingPayload) \
|
||||
key(Internal, WebsocketPongTimeout) \
|
||||
key(LocalAuthListManagement, LocalAuthListEnabled) \
|
||||
key(LocalAuthListManagement, LocalAuthListMaxLength) \
|
||||
key(LocalAuthListManagement, SendLocalListMaxLength) \
|
||||
key(PnC, CentralContractValidationAllowed) \
|
||||
key(PnC, CertSigningRepeatTimes) \
|
||||
key(PnC, CertSigningWaitMinimum) \
|
||||
key(PnC, ContractValidationOffline) \
|
||||
key(PnC, ISO15118CertificateManagementEnabled) \
|
||||
key(PnC, ISO15118PnCEnabled) \
|
||||
key(Reservation, ReserveConnectorZeroSupported) \
|
||||
key(Security, AdditionalRootCertificateCheck) \
|
||||
key(Security, AuthorizationKey) \
|
||||
key(Security, CertificateSignedMaxChainSize) \
|
||||
key(Security, CertificateStoreMaxLength) \
|
||||
key(Security, CpoName) \
|
||||
key(Security, DisableSecurityEventNotifications) \
|
||||
key(Security, SecurityProfile) \
|
||||
key(SmartCharging, ChargeProfileMaxStackLevel) \
|
||||
key(SmartCharging, ChargingScheduleAllowedChargingRateUnit) \
|
||||
key(SmartCharging, ChargingScheduleMaxPeriods) \
|
||||
key(SmartCharging, ConnectorSwitch3to1PhaseSupported) \
|
||||
key(SmartCharging, MaxChargingProfilesInstalled)
|
||||
|
||||
// these have special handling
|
||||
#define FOR_ALL_UNMAPPED_KEYS(key) \
|
||||
key(Internal, ConnectorEvseIds) \
|
||||
key(Internal, SupportedMeasurands)
|
||||
|
||||
#define FOR_ALL_KEYS(key) \
|
||||
FOR_ALL_MAPPED_KEYS(key) \
|
||||
FOR_ALL_UNMAPPED_KEYS(key)
|
||||
// clang-format on
|
||||
|
||||
#define VALUE(a, b) b,
|
||||
|
||||
enum class valid_keys : std::uint8_t {
|
||||
FOR_ALL_KEYS(VALUE)
|
||||
};
|
||||
|
||||
enum class sections : std::uint8_t {
|
||||
Core,
|
||||
CostAndPrice,
|
||||
FirmwareManagement,
|
||||
Internal,
|
||||
LocalAuthListManagement,
|
||||
PnC,
|
||||
Reservation,
|
||||
Security,
|
||||
SmartCharging,
|
||||
Custom,
|
||||
};
|
||||
|
||||
#undef VALUE
|
||||
|
||||
#define MAX_LIMIT_ENTRY(a, b) {valid_keys::a, &ocpp::v2::ControllerComponentVariables::b},
|
||||
using MaxLimitEntry = std::pair<valid_keys, const ocpp::v2::ComponentVariable*>;
|
||||
inline const MaxLimitEntry max_limit_entries[] = {MAPPING_MAX_LIMIT(MAX_LIMIT_ENTRY)};
|
||||
#undef MAX_LIMIT_ENTRY
|
||||
|
||||
std::optional<valid_keys> convert(const std::string_view& str);
|
||||
std::string_view convert(valid_keys key);
|
||||
sections to_section(valid_keys key);
|
||||
std::string_view to_section_string_view(valid_keys key);
|
||||
bool is_readonly(valid_keys key);
|
||||
inline bool is_in_section(sections section, valid_keys key) {
|
||||
return to_section(key) == section;
|
||||
}
|
||||
bool is_hidden(valid_keys key);
|
||||
std::optional<ocpp::v16::SupportedFeatureProfiles> get_profile(valid_keys key);
|
||||
|
||||
using DeviceModel_CV = std::optional<std::tuple<ocpp::v2::Component, ocpp::v2::Variable, ocpp::v2::AttributeEnum>>;
|
||||
DeviceModel_CV convert_v2(const std::string_view& str);
|
||||
DeviceModel_CV convert_v2(valid_keys key);
|
||||
std::optional<std::string> convert_v2(const ocpp::v2::Component& component, const ocpp::v2::Variable& variable,
|
||||
ocpp::v2::AttributeEnum attribute);
|
||||
|
||||
/// Returns the (Component, Variable) pair for keys that map to VariableCharacteristics.maxLimit,
|
||||
/// or std::nullopt if the key uses a regular VariableAttribute mapping.
|
||||
using DeviceModel_MaxLimitCV = std::optional<std::pair<ocpp::v2::Component, ocpp::v2::Variable>>;
|
||||
DeviceModel_MaxLimitCV convert_v2_max_limit(valid_keys key);
|
||||
|
||||
} // namespace ocpp::v16::keys
|
||||
|
||||
#endif // OCPP_V16_KNOWN_KEYS_HPP
|
||||
@@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ocpp/common/message_dispatcher.hpp>
|
||||
#include <ocpp/v16/charge_point_configuration_interface.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
class MessageDispatcher : public MessageDispatcherInterface<MessageType> {
|
||||
|
||||
public:
|
||||
MessageDispatcher(ocpp::MessageQueue<MessageType>& message_queue, ChargePointConfigurationInterface& configuration,
|
||||
std::atomic<RegistrationStatus>& registration_status) :
|
||||
message_queue(message_queue), configuration(configuration), registration_status(registration_status){};
|
||||
void dispatch_call(const json& call, bool triggered = false) override;
|
||||
std::future<ocpp::EnhancedMessage<MessageType>> dispatch_call_async(const json& call, bool triggered) override;
|
||||
void dispatch_call_result(const json& call_result) override;
|
||||
void dispatch_call_error(const json& call_error) override;
|
||||
|
||||
private:
|
||||
ocpp::MessageQueue<MessageType>& message_queue;
|
||||
ChargePointConfigurationInterface& configuration;
|
||||
std::atomic<RegistrationStatus>& registration_status;
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_AUTHORIZE_HPP
|
||||
#define OCPP_V16_AUTHORIZE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP Authorize message
|
||||
struct AuthorizeRequest : public ocpp::Message {
|
||||
CiString<20> idTag;
|
||||
|
||||
/// \brief Provides the type of this Authorize message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given AuthorizeRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const AuthorizeRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given AuthorizeRequest \p k
|
||||
void from_json(const json& j, AuthorizeRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given AuthorizeRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the AuthorizeRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const AuthorizeRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP AuthorizeResponse message
|
||||
struct AuthorizeResponse : public ocpp::Message {
|
||||
IdTagInfo idTagInfo;
|
||||
|
||||
/// \brief Provides the type of this AuthorizeResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given AuthorizeResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const AuthorizeResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given AuthorizeResponse \p k
|
||||
void from_json(const json& j, AuthorizeResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given AuthorizeResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the AuthorizeResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const AuthorizeResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_AUTHORIZE_HPP
|
||||
@@ -0,0 +1,69 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_BOOTNOTIFICATION_HPP
|
||||
#define OCPP_V16_BOOTNOTIFICATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP BootNotification message
|
||||
struct BootNotificationRequest : public ocpp::Message {
|
||||
CiString<20> chargePointVendor;
|
||||
CiString<20> chargePointModel;
|
||||
std::optional<CiString<25>> chargePointSerialNumber;
|
||||
std::optional<CiString<25>> chargeBoxSerialNumber;
|
||||
std::optional<CiString<50>> firmwareVersion;
|
||||
std::optional<CiString<20>> iccid;
|
||||
std::optional<CiString<20>> imsi;
|
||||
std::optional<CiString<25>> meterType;
|
||||
std::optional<CiString<25>> meterSerialNumber;
|
||||
|
||||
/// \brief Provides the type of this BootNotification message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given BootNotificationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const BootNotificationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given BootNotificationRequest \p k
|
||||
void from_json(const json& j, BootNotificationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given BootNotificationRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the BootNotificationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const BootNotificationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP BootNotificationResponse message
|
||||
struct BootNotificationResponse : public ocpp::Message {
|
||||
RegistrationStatus status;
|
||||
ocpp::DateTime currentTime;
|
||||
std::int32_t interval;
|
||||
|
||||
/// \brief Provides the type of this BootNotificationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given BootNotificationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const BootNotificationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given BootNotificationResponse \p k
|
||||
void from_json(const json& j, BootNotificationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given BootNotificationResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the BootNotificationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const BootNotificationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_BOOTNOTIFICATION_HPP
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_CANCELRESERVATION_HPP
|
||||
#define OCPP_V16_CANCELRESERVATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP CancelReservation message
|
||||
struct CancelReservationRequest : public ocpp::Message {
|
||||
std::int32_t reservationId;
|
||||
|
||||
/// \brief Provides the type of this CancelReservation message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given CancelReservationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const CancelReservationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given CancelReservationRequest \p k
|
||||
void from_json(const json& j, CancelReservationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given CancelReservationRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the CancelReservationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const CancelReservationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP CancelReservationResponse message
|
||||
struct CancelReservationResponse : public ocpp::Message {
|
||||
CancelReservationStatus status;
|
||||
|
||||
/// \brief Provides the type of this CancelReservationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given CancelReservationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const CancelReservationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given CancelReservationResponse \p k
|
||||
void from_json(const json& j, CancelReservationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given CancelReservationResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the CancelReservationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const CancelReservationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_CANCELRESERVATION_HPP
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_CERTIFICATESIGNED_HPP
|
||||
#define OCPP_V16_CERTIFICATESIGNED_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP CertificateSigned message
|
||||
struct CertificateSignedRequest : public ocpp::Message {
|
||||
CiString<10000> certificateChain;
|
||||
|
||||
/// \brief Provides the type of this CertificateSigned message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given CertificateSignedRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const CertificateSignedRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given CertificateSignedRequest \p k
|
||||
void from_json(const json& j, CertificateSignedRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given CertificateSignedRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the CertificateSignedRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const CertificateSignedRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP CertificateSignedResponse message
|
||||
struct CertificateSignedResponse : public ocpp::Message {
|
||||
CertificateSignedStatusEnumType status;
|
||||
|
||||
/// \brief Provides the type of this CertificateSignedResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given CertificateSignedResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const CertificateSignedResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given CertificateSignedResponse \p k
|
||||
void from_json(const json& j, CertificateSignedResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given CertificateSignedResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the CertificateSignedResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const CertificateSignedResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_CERTIFICATESIGNED_HPP
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_CHANGEAVAILABILITY_HPP
|
||||
#define OCPP_V16_CHANGEAVAILABILITY_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP ChangeAvailability message
|
||||
struct ChangeAvailabilityRequest : public ocpp::Message {
|
||||
std::int32_t connectorId;
|
||||
AvailabilityType type;
|
||||
|
||||
/// \brief Provides the type of this ChangeAvailability message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ChangeAvailabilityRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const ChangeAvailabilityRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ChangeAvailabilityRequest \p k
|
||||
void from_json(const json& j, ChangeAvailabilityRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ChangeAvailabilityRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ChangeAvailabilityRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const ChangeAvailabilityRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP ChangeAvailabilityResponse message
|
||||
struct ChangeAvailabilityResponse : public ocpp::Message {
|
||||
AvailabilityStatus status;
|
||||
|
||||
/// \brief Provides the type of this ChangeAvailabilityResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ChangeAvailabilityResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const ChangeAvailabilityResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ChangeAvailabilityResponse \p k
|
||||
void from_json(const json& j, ChangeAvailabilityResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ChangeAvailabilityResponse \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the ChangeAvailabilityResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const ChangeAvailabilityResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_CHANGEAVAILABILITY_HPP
|
||||
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_CHANGECONFIGURATION_HPP
|
||||
#define OCPP_V16_CHANGECONFIGURATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP ChangeConfiguration message
|
||||
struct ChangeConfigurationRequest : public ocpp::Message {
|
||||
CiString<50> key;
|
||||
CiString<500> value;
|
||||
|
||||
/// \brief Provides the type of this ChangeConfiguration message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ChangeConfigurationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const ChangeConfigurationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ChangeConfigurationRequest \p k
|
||||
void from_json(const json& j, ChangeConfigurationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ChangeConfigurationRequest \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the ChangeConfigurationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const ChangeConfigurationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP ChangeConfigurationResponse message
|
||||
struct ChangeConfigurationResponse : public ocpp::Message {
|
||||
ConfigurationStatus status;
|
||||
|
||||
/// \brief Provides the type of this ChangeConfigurationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ChangeConfigurationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const ChangeConfigurationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ChangeConfigurationResponse \p k
|
||||
void from_json(const json& j, ChangeConfigurationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ChangeConfigurationResponse \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the ChangeConfigurationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const ChangeConfigurationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_CHANGECONFIGURATION_HPP
|
||||
@@ -0,0 +1,56 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_CLEARCACHE_HPP
|
||||
#define OCPP_V16_CLEARCACHE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP ClearCache message
|
||||
struct ClearCacheRequest : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this ClearCache message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ClearCacheRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const ClearCacheRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ClearCacheRequest \p k
|
||||
void from_json(const json& j, ClearCacheRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ClearCacheRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ClearCacheRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const ClearCacheRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP ClearCacheResponse message
|
||||
struct ClearCacheResponse : public ocpp::Message {
|
||||
ClearCacheStatus status;
|
||||
|
||||
/// \brief Provides the type of this ClearCacheResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ClearCacheResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const ClearCacheResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ClearCacheResponse \p k
|
||||
void from_json(const json& j, ClearCacheResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ClearCacheResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ClearCacheResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const ClearCacheResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_CLEARCACHE_HPP
|
||||
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_CLEARCHARGINGPROFILE_HPP
|
||||
#define OCPP_V16_CLEARCHARGINGPROFILE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP ClearChargingProfile message
|
||||
struct ClearChargingProfileRequest : public ocpp::Message {
|
||||
std::optional<std::int32_t> id;
|
||||
std::optional<std::int32_t> connectorId;
|
||||
std::optional<ChargingProfilePurposeType> chargingProfilePurpose;
|
||||
std::optional<std::int32_t> stackLevel;
|
||||
|
||||
/// \brief Provides the type of this ClearChargingProfile message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ClearChargingProfileRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const ClearChargingProfileRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ClearChargingProfileRequest \p k
|
||||
void from_json(const json& j, ClearChargingProfileRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ClearChargingProfileRequest \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the ClearChargingProfileRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const ClearChargingProfileRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP ClearChargingProfileResponse message
|
||||
struct ClearChargingProfileResponse : public ocpp::Message {
|
||||
ClearChargingProfileStatus status;
|
||||
|
||||
/// \brief Provides the type of this ClearChargingProfileResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ClearChargingProfileResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const ClearChargingProfileResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ClearChargingProfileResponse \p k
|
||||
void from_json(const json& j, ClearChargingProfileResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ClearChargingProfileResponse \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the ClearChargingProfileResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const ClearChargingProfileResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_CLEARCHARGINGPROFILE_HPP
|
||||
@@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_DATATRANSFER_HPP
|
||||
#define OCPP_V16_DATATRANSFER_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP DataTransfer message
|
||||
struct DataTransferRequest : public ocpp::Message {
|
||||
CiString<255> vendorId;
|
||||
std::optional<CiString<50>> messageId;
|
||||
std::optional<std::string> data;
|
||||
|
||||
/// \brief Provides the type of this DataTransfer message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given DataTransferRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const DataTransferRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given DataTransferRequest \p k
|
||||
void from_json(const json& j, DataTransferRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given DataTransferRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the DataTransferRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const DataTransferRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP DataTransferResponse message
|
||||
struct DataTransferResponse : public ocpp::Message {
|
||||
DataTransferStatus status;
|
||||
std::optional<std::string> data;
|
||||
|
||||
/// \brief Provides the type of this DataTransferResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given DataTransferResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const DataTransferResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given DataTransferResponse \p k
|
||||
void from_json(const json& j, DataTransferResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given DataTransferResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the DataTransferResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const DataTransferResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_DATATRANSFER_HPP
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_DELETECERTIFICATE_HPP
|
||||
#define OCPP_V16_DELETECERTIFICATE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP DeleteCertificate message
|
||||
struct DeleteCertificateRequest : public ocpp::Message {
|
||||
CertificateHashDataType certificateHashData;
|
||||
|
||||
/// \brief Provides the type of this DeleteCertificate message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given DeleteCertificateRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const DeleteCertificateRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given DeleteCertificateRequest \p k
|
||||
void from_json(const json& j, DeleteCertificateRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given DeleteCertificateRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the DeleteCertificateRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const DeleteCertificateRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP DeleteCertificateResponse message
|
||||
struct DeleteCertificateResponse : public ocpp::Message {
|
||||
DeleteCertificateStatusEnumType status;
|
||||
|
||||
/// \brief Provides the type of this DeleteCertificateResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given DeleteCertificateResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const DeleteCertificateResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given DeleteCertificateResponse \p k
|
||||
void from_json(const json& j, DeleteCertificateResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given DeleteCertificateResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the DeleteCertificateResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const DeleteCertificateResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_DELETECERTIFICATE_HPP
|
||||
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_DIAGNOSTICSSTATUSNOTIFICATION_HPP
|
||||
#define OCPP_V16_DIAGNOSTICSSTATUSNOTIFICATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP DiagnosticsStatusNotification message
|
||||
struct DiagnosticsStatusNotificationRequest : public ocpp::Message {
|
||||
DiagnosticsStatus status;
|
||||
|
||||
/// \brief Provides the type of this DiagnosticsStatusNotification message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given DiagnosticsStatusNotificationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const DiagnosticsStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given DiagnosticsStatusNotificationRequest \p k
|
||||
void from_json(const json& j, DiagnosticsStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given DiagnosticsStatusNotificationRequest \p k to the given output
|
||||
/// stream \p os
|
||||
/// \returns an output stream with the DiagnosticsStatusNotificationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const DiagnosticsStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP DiagnosticsStatusNotificationResponse message
|
||||
struct DiagnosticsStatusNotificationResponse : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this DiagnosticsStatusNotificationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given DiagnosticsStatusNotificationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const DiagnosticsStatusNotificationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given DiagnosticsStatusNotificationResponse \p k
|
||||
void from_json(const json& j, DiagnosticsStatusNotificationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given DiagnosticsStatusNotificationResponse \p k to the given output
|
||||
/// stream \p os
|
||||
/// \returns an output stream with the DiagnosticsStatusNotificationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const DiagnosticsStatusNotificationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_DIAGNOSTICSSTATUSNOTIFICATION_HPP
|
||||
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_EXTENDEDTRIGGERMESSAGE_HPP
|
||||
#define OCPP_V16_EXTENDEDTRIGGERMESSAGE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP ExtendedTriggerMessage message
|
||||
struct ExtendedTriggerMessageRequest : public ocpp::Message {
|
||||
MessageTriggerEnumType requestedMessage;
|
||||
std::optional<std::int32_t> connectorId;
|
||||
|
||||
/// \brief Provides the type of this ExtendedTriggerMessage message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ExtendedTriggerMessageRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const ExtendedTriggerMessageRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ExtendedTriggerMessageRequest \p k
|
||||
void from_json(const json& j, ExtendedTriggerMessageRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ExtendedTriggerMessageRequest \p k to the given output stream
|
||||
/// \p os
|
||||
/// \returns an output stream with the ExtendedTriggerMessageRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const ExtendedTriggerMessageRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP ExtendedTriggerMessageResponse message
|
||||
struct ExtendedTriggerMessageResponse : public ocpp::Message {
|
||||
TriggerMessageStatusEnumType status;
|
||||
|
||||
/// \brief Provides the type of this ExtendedTriggerMessageResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ExtendedTriggerMessageResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const ExtendedTriggerMessageResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ExtendedTriggerMessageResponse \p k
|
||||
void from_json(const json& j, ExtendedTriggerMessageResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ExtendedTriggerMessageResponse \p k to the given output stream
|
||||
/// \p os
|
||||
/// \returns an output stream with the ExtendedTriggerMessageResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const ExtendedTriggerMessageResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_EXTENDEDTRIGGERMESSAGE_HPP
|
||||
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_FIRMWARESTATUSNOTIFICATION_HPP
|
||||
#define OCPP_V16_FIRMWARESTATUSNOTIFICATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP FirmwareStatusNotification message
|
||||
struct FirmwareStatusNotificationRequest : public ocpp::Message {
|
||||
FirmwareStatus status;
|
||||
|
||||
/// \brief Provides the type of this FirmwareStatusNotification message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given FirmwareStatusNotificationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const FirmwareStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given FirmwareStatusNotificationRequest \p k
|
||||
void from_json(const json& j, FirmwareStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given FirmwareStatusNotificationRequest \p k to the given output
|
||||
/// stream \p os
|
||||
/// \returns an output stream with the FirmwareStatusNotificationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const FirmwareStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP FirmwareStatusNotificationResponse message
|
||||
struct FirmwareStatusNotificationResponse : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this FirmwareStatusNotificationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given FirmwareStatusNotificationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const FirmwareStatusNotificationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given FirmwareStatusNotificationResponse \p k
|
||||
void from_json(const json& j, FirmwareStatusNotificationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given FirmwareStatusNotificationResponse \p k to the given output
|
||||
/// stream \p os
|
||||
/// \returns an output stream with the FirmwareStatusNotificationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const FirmwareStatusNotificationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_FIRMWARESTATUSNOTIFICATION_HPP
|
||||
@@ -0,0 +1,65 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_GETCOMPOSITESCHEDULE_HPP
|
||||
#define OCPP_V16_GETCOMPOSITESCHEDULE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP GetCompositeSchedule message
|
||||
struct GetCompositeScheduleRequest : public ocpp::Message {
|
||||
std::int32_t connectorId;
|
||||
std::int32_t duration;
|
||||
std::optional<ChargingRateUnit> chargingRateUnit;
|
||||
|
||||
/// \brief Provides the type of this GetCompositeSchedule message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetCompositeScheduleRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const GetCompositeScheduleRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetCompositeScheduleRequest \p k
|
||||
void from_json(const json& j, GetCompositeScheduleRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetCompositeScheduleRequest \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the GetCompositeScheduleRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetCompositeScheduleRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP GetCompositeScheduleResponse message
|
||||
struct GetCompositeScheduleResponse : public ocpp::Message {
|
||||
GetCompositeScheduleStatus status;
|
||||
std::optional<std::int32_t> connectorId;
|
||||
std::optional<ocpp::DateTime> scheduleStart;
|
||||
std::optional<ChargingSchedule> chargingSchedule;
|
||||
|
||||
/// \brief Provides the type of this GetCompositeScheduleResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetCompositeScheduleResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const GetCompositeScheduleResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetCompositeScheduleResponse \p k
|
||||
void from_json(const json& j, GetCompositeScheduleResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetCompositeScheduleResponse \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the GetCompositeScheduleResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetCompositeScheduleResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_GETCOMPOSITESCHEDULE_HPP
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_GETCONFIGURATION_HPP
|
||||
#define OCPP_V16_GETCONFIGURATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP GetConfiguration message
|
||||
struct GetConfigurationRequest : public ocpp::Message {
|
||||
std::optional<std::vector<CiString<50>>> key;
|
||||
|
||||
/// \brief Provides the type of this GetConfiguration message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetConfigurationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const GetConfigurationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetConfigurationRequest \p k
|
||||
void from_json(const json& j, GetConfigurationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetConfigurationRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the GetConfigurationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetConfigurationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP GetConfigurationResponse message
|
||||
struct GetConfigurationResponse : public ocpp::Message {
|
||||
std::optional<std::vector<KeyValue>> configurationKey;
|
||||
std::optional<std::vector<CiString<50>>> unknownKey;
|
||||
|
||||
/// \brief Provides the type of this GetConfigurationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetConfigurationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const GetConfigurationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetConfigurationResponse \p k
|
||||
void from_json(const json& j, GetConfigurationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetConfigurationResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the GetConfigurationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetConfigurationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_GETCONFIGURATION_HPP
|
||||
@@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_GETDIAGNOSTICS_HPP
|
||||
#define OCPP_V16_GETDIAGNOSTICS_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP GetDiagnostics message
|
||||
struct GetDiagnosticsRequest : public ocpp::Message {
|
||||
std::string location;
|
||||
std::optional<std::int32_t> retries;
|
||||
std::optional<std::int32_t> retryInterval;
|
||||
std::optional<ocpp::DateTime> startTime;
|
||||
std::optional<ocpp::DateTime> stopTime;
|
||||
|
||||
/// \brief Provides the type of this GetDiagnostics message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetDiagnosticsRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const GetDiagnosticsRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetDiagnosticsRequest \p k
|
||||
void from_json(const json& j, GetDiagnosticsRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetDiagnosticsRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the GetDiagnosticsRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetDiagnosticsRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP GetDiagnosticsResponse message
|
||||
struct GetDiagnosticsResponse : public ocpp::Message {
|
||||
std::optional<CiString<255>> fileName;
|
||||
|
||||
/// \brief Provides the type of this GetDiagnosticsResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetDiagnosticsResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const GetDiagnosticsResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetDiagnosticsResponse \p k
|
||||
void from_json(const json& j, GetDiagnosticsResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetDiagnosticsResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the GetDiagnosticsResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetDiagnosticsResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_GETDIAGNOSTICS_HPP
|
||||
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_GETINSTALLEDCERTIFICATEIDS_HPP
|
||||
#define OCPP_V16_GETINSTALLEDCERTIFICATEIDS_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP GetInstalledCertificateIds message
|
||||
struct GetInstalledCertificateIdsRequest : public ocpp::Message {
|
||||
CertificateUseEnumType certificateType;
|
||||
|
||||
/// \brief Provides the type of this GetInstalledCertificateIds message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetInstalledCertificateIdsRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const GetInstalledCertificateIdsRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetInstalledCertificateIdsRequest \p k
|
||||
void from_json(const json& j, GetInstalledCertificateIdsRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetInstalledCertificateIdsRequest \p k to the given output
|
||||
/// stream \p os
|
||||
/// \returns an output stream with the GetInstalledCertificateIdsRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetInstalledCertificateIdsRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP GetInstalledCertificateIdsResponse message
|
||||
struct GetInstalledCertificateIdsResponse : public ocpp::Message {
|
||||
GetInstalledCertificateStatusEnumType status;
|
||||
std::optional<std::vector<CertificateHashDataType>> certificateHashData;
|
||||
|
||||
/// \brief Provides the type of this GetInstalledCertificateIdsResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetInstalledCertificateIdsResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const GetInstalledCertificateIdsResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetInstalledCertificateIdsResponse \p k
|
||||
void from_json(const json& j, GetInstalledCertificateIdsResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetInstalledCertificateIdsResponse \p k to the given output
|
||||
/// stream \p os
|
||||
/// \returns an output stream with the GetInstalledCertificateIdsResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetInstalledCertificateIdsResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_GETINSTALLEDCERTIFICATEIDS_HPP
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_GETLOCALLISTVERSION_HPP
|
||||
#define OCPP_V16_GETLOCALLISTVERSION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP GetLocalListVersion message
|
||||
struct GetLocalListVersionRequest : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this GetLocalListVersion message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetLocalListVersionRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const GetLocalListVersionRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetLocalListVersionRequest \p k
|
||||
void from_json(const json& j, GetLocalListVersionRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetLocalListVersionRequest \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the GetLocalListVersionRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetLocalListVersionRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP GetLocalListVersionResponse message
|
||||
struct GetLocalListVersionResponse : public ocpp::Message {
|
||||
std::int32_t listVersion;
|
||||
|
||||
/// \brief Provides the type of this GetLocalListVersionResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetLocalListVersionResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const GetLocalListVersionResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetLocalListVersionResponse \p k
|
||||
void from_json(const json& j, GetLocalListVersionResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetLocalListVersionResponse \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the GetLocalListVersionResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetLocalListVersionResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_GETLOCALLISTVERSION_HPP
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_GETLOG_HPP
|
||||
#define OCPP_V16_GETLOG_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP GetLog message
|
||||
struct GetLogRequest : public ocpp::Message {
|
||||
LogParametersType log;
|
||||
LogEnumType logType;
|
||||
std::int32_t requestId;
|
||||
std::optional<std::int32_t> retries;
|
||||
std::optional<std::int32_t> retryInterval;
|
||||
|
||||
/// \brief Provides the type of this GetLog message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetLogRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const GetLogRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetLogRequest \p k
|
||||
void from_json(const json& j, GetLogRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetLogRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the GetLogRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetLogRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP GetLogResponse message
|
||||
struct GetLogResponse : public ocpp::Message {
|
||||
LogStatusEnumType status;
|
||||
std::optional<CiString<255>> filename;
|
||||
|
||||
/// \brief Provides the type of this GetLogResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given GetLogResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const GetLogResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given GetLogResponse \p k
|
||||
void from_json(const json& j, GetLogResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given GetLogResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the GetLogResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const GetLogResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_GETLOG_HPP
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_HEARTBEAT_HPP
|
||||
#define OCPP_V16_HEARTBEAT_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP Heartbeat message
|
||||
struct HeartbeatRequest : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this Heartbeat message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given HeartbeatRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const HeartbeatRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given HeartbeatRequest \p k
|
||||
void from_json(const json& j, HeartbeatRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given HeartbeatRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the HeartbeatRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const HeartbeatRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP HeartbeatResponse message
|
||||
struct HeartbeatResponse : public ocpp::Message {
|
||||
ocpp::DateTime currentTime;
|
||||
|
||||
/// \brief Provides the type of this HeartbeatResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given HeartbeatResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const HeartbeatResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given HeartbeatResponse \p k
|
||||
void from_json(const json& j, HeartbeatResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given HeartbeatResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the HeartbeatResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const HeartbeatResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_HEARTBEAT_HPP
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_INSTALLCERTIFICATE_HPP
|
||||
#define OCPP_V16_INSTALLCERTIFICATE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP InstallCertificate message
|
||||
struct InstallCertificateRequest : public ocpp::Message {
|
||||
CertificateUseEnumType certificateType;
|
||||
CiString<5500> certificate;
|
||||
|
||||
/// \brief Provides the type of this InstallCertificate message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given InstallCertificateRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const InstallCertificateRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given InstallCertificateRequest \p k
|
||||
void from_json(const json& j, InstallCertificateRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given InstallCertificateRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the InstallCertificateRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const InstallCertificateRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP InstallCertificateResponse message
|
||||
struct InstallCertificateResponse : public ocpp::Message {
|
||||
InstallCertificateStatusEnumType status;
|
||||
|
||||
/// \brief Provides the type of this InstallCertificateResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given InstallCertificateResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const InstallCertificateResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given InstallCertificateResponse \p k
|
||||
void from_json(const json& j, InstallCertificateResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given InstallCertificateResponse \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the InstallCertificateResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const InstallCertificateResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_INSTALLCERTIFICATE_HPP
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_LOGSTATUSNOTIFICATION_HPP
|
||||
#define OCPP_V16_LOGSTATUSNOTIFICATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP LogStatusNotification message
|
||||
struct LogStatusNotificationRequest : public ocpp::Message {
|
||||
UploadLogStatusEnumType status;
|
||||
std::optional<std::int32_t> requestId;
|
||||
|
||||
/// \brief Provides the type of this LogStatusNotification message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given LogStatusNotificationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const LogStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given LogStatusNotificationRequest \p k
|
||||
void from_json(const json& j, LogStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given LogStatusNotificationRequest \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the LogStatusNotificationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const LogStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP LogStatusNotificationResponse message
|
||||
struct LogStatusNotificationResponse : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this LogStatusNotificationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given LogStatusNotificationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const LogStatusNotificationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given LogStatusNotificationResponse \p k
|
||||
void from_json(const json& j, LogStatusNotificationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given LogStatusNotificationResponse \p k to the given output stream
|
||||
/// \p os
|
||||
/// \returns an output stream with the LogStatusNotificationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const LogStatusNotificationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_LOGSTATUSNOTIFICATION_HPP
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_METERVALUES_HPP
|
||||
#define OCPP_V16_METERVALUES_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP MeterValues message
|
||||
struct MeterValuesRequest : public ocpp::Message {
|
||||
std::int32_t connectorId;
|
||||
std::vector<MeterValue> meterValue;
|
||||
std::optional<std::int32_t> transactionId;
|
||||
|
||||
/// \brief Provides the type of this MeterValues message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given MeterValuesRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const MeterValuesRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given MeterValuesRequest \p k
|
||||
void from_json(const json& j, MeterValuesRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given MeterValuesRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the MeterValuesRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const MeterValuesRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP MeterValuesResponse message
|
||||
struct MeterValuesResponse : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this MeterValuesResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given MeterValuesResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const MeterValuesResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given MeterValuesResponse \p k
|
||||
void from_json(const json& j, MeterValuesResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given MeterValuesResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the MeterValuesResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const MeterValuesResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_METERVALUES_HPP
|
||||
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_REMOTESTARTTRANSACTION_HPP
|
||||
#define OCPP_V16_REMOTESTARTTRANSACTION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP RemoteStartTransaction message
|
||||
struct RemoteStartTransactionRequest : public ocpp::Message {
|
||||
CiString<20> idTag;
|
||||
std::optional<std::int32_t> connectorId;
|
||||
std::optional<ChargingProfile> chargingProfile;
|
||||
|
||||
/// \brief Provides the type of this RemoteStartTransaction message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given RemoteStartTransactionRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const RemoteStartTransactionRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given RemoteStartTransactionRequest \p k
|
||||
void from_json(const json& j, RemoteStartTransactionRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given RemoteStartTransactionRequest \p k to the given output stream
|
||||
/// \p os
|
||||
/// \returns an output stream with the RemoteStartTransactionRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const RemoteStartTransactionRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP RemoteStartTransactionResponse message
|
||||
struct RemoteStartTransactionResponse : public ocpp::Message {
|
||||
RemoteStartStopStatus status;
|
||||
|
||||
/// \brief Provides the type of this RemoteStartTransactionResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given RemoteStartTransactionResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const RemoteStartTransactionResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given RemoteStartTransactionResponse \p k
|
||||
void from_json(const json& j, RemoteStartTransactionResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given RemoteStartTransactionResponse \p k to the given output stream
|
||||
/// \p os
|
||||
/// \returns an output stream with the RemoteStartTransactionResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const RemoteStartTransactionResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_REMOTESTARTTRANSACTION_HPP
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_REMOTESTOPTRANSACTION_HPP
|
||||
#define OCPP_V16_REMOTESTOPTRANSACTION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP RemoteStopTransaction message
|
||||
struct RemoteStopTransactionRequest : public ocpp::Message {
|
||||
std::int32_t transactionId;
|
||||
|
||||
/// \brief Provides the type of this RemoteStopTransaction message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given RemoteStopTransactionRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const RemoteStopTransactionRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given RemoteStopTransactionRequest \p k
|
||||
void from_json(const json& j, RemoteStopTransactionRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given RemoteStopTransactionRequest \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the RemoteStopTransactionRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const RemoteStopTransactionRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP RemoteStopTransactionResponse message
|
||||
struct RemoteStopTransactionResponse : public ocpp::Message {
|
||||
RemoteStartStopStatus status;
|
||||
|
||||
/// \brief Provides the type of this RemoteStopTransactionResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given RemoteStopTransactionResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const RemoteStopTransactionResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given RemoteStopTransactionResponse \p k
|
||||
void from_json(const json& j, RemoteStopTransactionResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given RemoteStopTransactionResponse \p k to the given output stream
|
||||
/// \p os
|
||||
/// \returns an output stream with the RemoteStopTransactionResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const RemoteStopTransactionResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_REMOTESTOPTRANSACTION_HPP
|
||||
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_RESERVENOW_HPP
|
||||
#define OCPP_V16_RESERVENOW_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP ReserveNow message
|
||||
struct ReserveNowRequest : public ocpp::Message {
|
||||
std::int32_t connectorId;
|
||||
ocpp::DateTime expiryDate;
|
||||
CiString<20> idTag;
|
||||
std::int32_t reservationId;
|
||||
std::optional<CiString<20>> parentIdTag;
|
||||
|
||||
/// \brief Provides the type of this ReserveNow message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ReserveNowRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const ReserveNowRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ReserveNowRequest \p k
|
||||
void from_json(const json& j, ReserveNowRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ReserveNowRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ReserveNowRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const ReserveNowRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP ReserveNowResponse message
|
||||
struct ReserveNowResponse : public ocpp::Message {
|
||||
ReservationStatus status;
|
||||
|
||||
/// \brief Provides the type of this ReserveNowResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ReserveNowResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const ReserveNowResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ReserveNowResponse \p k
|
||||
void from_json(const json& j, ReserveNowResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ReserveNowResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ReserveNowResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const ReserveNowResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_RESERVENOW_HPP
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_RESET_HPP
|
||||
#define OCPP_V16_RESET_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP Reset message
|
||||
struct ResetRequest : public ocpp::Message {
|
||||
ResetType type;
|
||||
|
||||
/// \brief Provides the type of this Reset message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ResetRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const ResetRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ResetRequest \p k
|
||||
void from_json(const json& j, ResetRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ResetRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ResetRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const ResetRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP ResetResponse message
|
||||
struct ResetResponse : public ocpp::Message {
|
||||
ResetStatus status;
|
||||
|
||||
/// \brief Provides the type of this ResetResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given ResetResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const ResetResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ResetResponse \p k
|
||||
void from_json(const json& j, ResetResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ResetResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ResetResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const ResetResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_RESET_HPP
|
||||
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_SECURITYEVENTNOTIFICATION_HPP
|
||||
#define OCPP_V16_SECURITYEVENTNOTIFICATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP SecurityEventNotification message
|
||||
struct SecurityEventNotificationRequest : public ocpp::Message {
|
||||
CiString<50> type;
|
||||
ocpp::DateTime timestamp;
|
||||
std::optional<CiString<255>> techInfo;
|
||||
|
||||
/// \brief Provides the type of this SecurityEventNotification message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SecurityEventNotificationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const SecurityEventNotificationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SecurityEventNotificationRequest \p k
|
||||
void from_json(const json& j, SecurityEventNotificationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SecurityEventNotificationRequest \p k to the given output
|
||||
/// stream \p os
|
||||
/// \returns an output stream with the SecurityEventNotificationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const SecurityEventNotificationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP SecurityEventNotificationResponse message
|
||||
struct SecurityEventNotificationResponse : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this SecurityEventNotificationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SecurityEventNotificationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const SecurityEventNotificationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SecurityEventNotificationResponse \p k
|
||||
void from_json(const json& j, SecurityEventNotificationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SecurityEventNotificationResponse \p k to the given output
|
||||
/// stream \p os
|
||||
/// \returns an output stream with the SecurityEventNotificationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const SecurityEventNotificationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_SECURITYEVENTNOTIFICATION_HPP
|
||||
@@ -0,0 +1,61 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_SENDLOCALLIST_HPP
|
||||
#define OCPP_V16_SENDLOCALLIST_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP SendLocalList message
|
||||
struct SendLocalListRequest : public ocpp::Message {
|
||||
std::int32_t listVersion;
|
||||
UpdateType updateType;
|
||||
std::optional<std::vector<LocalAuthorizationList>> localAuthorizationList;
|
||||
|
||||
/// \brief Provides the type of this SendLocalList message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SendLocalListRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const SendLocalListRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SendLocalListRequest \p k
|
||||
void from_json(const json& j, SendLocalListRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SendLocalListRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the SendLocalListRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const SendLocalListRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP SendLocalListResponse message
|
||||
struct SendLocalListResponse : public ocpp::Message {
|
||||
UpdateStatus status;
|
||||
|
||||
/// \brief Provides the type of this SendLocalListResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SendLocalListResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const SendLocalListResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SendLocalListResponse \p k
|
||||
void from_json(const json& j, SendLocalListResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SendLocalListResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the SendLocalListResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const SendLocalListResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_SENDLOCALLIST_HPP
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_SETCHARGINGPROFILE_HPP
|
||||
#define OCPP_V16_SETCHARGINGPROFILE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP SetChargingProfile message
|
||||
struct SetChargingProfileRequest : public ocpp::Message {
|
||||
std::int32_t connectorId;
|
||||
ChargingProfile csChargingProfiles;
|
||||
|
||||
/// \brief Provides the type of this SetChargingProfile message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SetChargingProfileRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const SetChargingProfileRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SetChargingProfileRequest \p k
|
||||
void from_json(const json& j, SetChargingProfileRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SetChargingProfileRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the SetChargingProfileRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const SetChargingProfileRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP SetChargingProfileResponse message
|
||||
struct SetChargingProfileResponse : public ocpp::Message {
|
||||
ChargingProfileStatus status;
|
||||
|
||||
/// \brief Provides the type of this SetChargingProfileResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SetChargingProfileResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const SetChargingProfileResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SetChargingProfileResponse \p k
|
||||
void from_json(const json& j, SetChargingProfileResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SetChargingProfileResponse \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the SetChargingProfileResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const SetChargingProfileResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_SETCHARGINGPROFILE_HPP
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_SIGNCERTIFICATE_HPP
|
||||
#define OCPP_V16_SIGNCERTIFICATE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP SignCertificate message
|
||||
struct SignCertificateRequest : public ocpp::Message {
|
||||
CiString<5500> csr;
|
||||
|
||||
/// \brief Provides the type of this SignCertificate message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SignCertificateRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const SignCertificateRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SignCertificateRequest \p k
|
||||
void from_json(const json& j, SignCertificateRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SignCertificateRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the SignCertificateRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const SignCertificateRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP SignCertificateResponse message
|
||||
struct SignCertificateResponse : public ocpp::Message {
|
||||
GenericStatusEnumType status;
|
||||
|
||||
/// \brief Provides the type of this SignCertificateResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SignCertificateResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const SignCertificateResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SignCertificateResponse \p k
|
||||
void from_json(const json& j, SignCertificateResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SignCertificateResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the SignCertificateResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const SignCertificateResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_SIGNCERTIFICATE_HPP
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_SIGNEDFIRMWARESTATUSNOTIFICATION_HPP
|
||||
#define OCPP_V16_SIGNEDFIRMWARESTATUSNOTIFICATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP SignedFirmwareStatusNotification message
|
||||
struct SignedFirmwareStatusNotificationRequest : public ocpp::Message {
|
||||
FirmwareStatusEnumType status;
|
||||
std::optional<std::int32_t> requestId;
|
||||
|
||||
/// \brief Provides the type of this SignedFirmwareStatusNotification message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SignedFirmwareStatusNotificationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const SignedFirmwareStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SignedFirmwareStatusNotificationRequest \p k
|
||||
void from_json(const json& j, SignedFirmwareStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SignedFirmwareStatusNotificationRequest \p k to the given
|
||||
/// output stream \p os
|
||||
/// \returns an output stream with the SignedFirmwareStatusNotificationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const SignedFirmwareStatusNotificationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP SignedFirmwareStatusNotificationResponse message
|
||||
struct SignedFirmwareStatusNotificationResponse : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this SignedFirmwareStatusNotificationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SignedFirmwareStatusNotificationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const SignedFirmwareStatusNotificationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SignedFirmwareStatusNotificationResponse \p k
|
||||
void from_json(const json& j, SignedFirmwareStatusNotificationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SignedFirmwareStatusNotificationResponse \p k to the given
|
||||
/// output stream \p os
|
||||
/// \returns an output stream with the SignedFirmwareStatusNotificationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const SignedFirmwareStatusNotificationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_SIGNEDFIRMWARESTATUSNOTIFICATION_HPP
|
||||
@@ -0,0 +1,63 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_SIGNEDUPDATEFIRMWARE_HPP
|
||||
#define OCPP_V16_SIGNEDUPDATEFIRMWARE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP SignedUpdateFirmware message
|
||||
struct SignedUpdateFirmwareRequest : public ocpp::Message {
|
||||
std::int32_t requestId;
|
||||
FirmwareType firmware;
|
||||
std::optional<std::int32_t> retries;
|
||||
std::optional<std::int32_t> retryInterval;
|
||||
|
||||
/// \brief Provides the type of this SignedUpdateFirmware message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SignedUpdateFirmwareRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const SignedUpdateFirmwareRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SignedUpdateFirmwareRequest \p k
|
||||
void from_json(const json& j, SignedUpdateFirmwareRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SignedUpdateFirmwareRequest \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the SignedUpdateFirmwareRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const SignedUpdateFirmwareRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP SignedUpdateFirmwareResponse message
|
||||
struct SignedUpdateFirmwareResponse : public ocpp::Message {
|
||||
UpdateFirmwareStatusEnumType status;
|
||||
|
||||
/// \brief Provides the type of this SignedUpdateFirmwareResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given SignedUpdateFirmwareResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const SignedUpdateFirmwareResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SignedUpdateFirmwareResponse \p k
|
||||
void from_json(const json& j, SignedUpdateFirmwareResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SignedUpdateFirmwareResponse \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the SignedUpdateFirmwareResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const SignedUpdateFirmwareResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_SIGNEDUPDATEFIRMWARE_HPP
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_STARTTRANSACTION_HPP
|
||||
#define OCPP_V16_STARTTRANSACTION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP StartTransaction message
|
||||
struct StartTransactionRequest : public ocpp::Message {
|
||||
std::int32_t connectorId;
|
||||
CiString<20> idTag;
|
||||
std::int32_t meterStart;
|
||||
ocpp::DateTime timestamp;
|
||||
std::optional<std::int32_t> reservationId;
|
||||
|
||||
/// \brief Provides the type of this StartTransaction message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given StartTransactionRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const StartTransactionRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given StartTransactionRequest \p k
|
||||
void from_json(const json& j, StartTransactionRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given StartTransactionRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the StartTransactionRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const StartTransactionRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP StartTransactionResponse message
|
||||
struct StartTransactionResponse : public ocpp::Message {
|
||||
IdTagInfo idTagInfo;
|
||||
std::int32_t transactionId;
|
||||
|
||||
/// \brief Provides the type of this StartTransactionResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given StartTransactionResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const StartTransactionResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given StartTransactionResponse \p k
|
||||
void from_json(const json& j, StartTransactionResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given StartTransactionResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the StartTransactionResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const StartTransactionResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_STARTTRANSACTION_HPP
|
||||
@@ -0,0 +1,65 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_STATUSNOTIFICATION_HPP
|
||||
#define OCPP_V16_STATUSNOTIFICATION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP StatusNotification message
|
||||
struct StatusNotificationRequest : public ocpp::Message {
|
||||
std::int32_t connectorId;
|
||||
ChargePointErrorCode errorCode;
|
||||
ChargePointStatus status;
|
||||
std::optional<CiString<50>> info;
|
||||
std::optional<ocpp::DateTime> timestamp;
|
||||
std::optional<CiString<255>> vendorId;
|
||||
std::optional<CiString<50>> vendorErrorCode;
|
||||
|
||||
/// \brief Provides the type of this StatusNotification message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given StatusNotificationRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const StatusNotificationRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given StatusNotificationRequest \p k
|
||||
void from_json(const json& j, StatusNotificationRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given StatusNotificationRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the StatusNotificationRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const StatusNotificationRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP StatusNotificationResponse message
|
||||
struct StatusNotificationResponse : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this StatusNotificationResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given StatusNotificationResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const StatusNotificationResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given StatusNotificationResponse \p k
|
||||
void from_json(const json& j, StatusNotificationResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given StatusNotificationResponse \p k to the given output stream \p
|
||||
/// os
|
||||
/// \returns an output stream with the StatusNotificationResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const StatusNotificationResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_STATUSNOTIFICATION_HPP
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_STOPTRANSACTION_HPP
|
||||
#define OCPP_V16_STOPTRANSACTION_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP StopTransaction message
|
||||
struct StopTransactionRequest : public ocpp::Message {
|
||||
std::int32_t meterStop;
|
||||
ocpp::DateTime timestamp;
|
||||
std::int32_t transactionId;
|
||||
std::optional<CiString<20>> idTag;
|
||||
std::optional<Reason> reason;
|
||||
std::optional<std::vector<TransactionData>> transactionData;
|
||||
|
||||
/// \brief Provides the type of this StopTransaction message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given StopTransactionRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const StopTransactionRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given StopTransactionRequest \p k
|
||||
void from_json(const json& j, StopTransactionRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given StopTransactionRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the StopTransactionRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const StopTransactionRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP StopTransactionResponse message
|
||||
struct StopTransactionResponse : public ocpp::Message {
|
||||
std::optional<IdTagInfo> idTagInfo;
|
||||
|
||||
/// \brief Provides the type of this StopTransactionResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given StopTransactionResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const StopTransactionResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given StopTransactionResponse \p k
|
||||
void from_json(const json& j, StopTransactionResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given StopTransactionResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the StopTransactionResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const StopTransactionResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_STOPTRANSACTION_HPP
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_TRIGGERMESSAGE_HPP
|
||||
#define OCPP_V16_TRIGGERMESSAGE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP TriggerMessage message
|
||||
struct TriggerMessageRequest : public ocpp::Message {
|
||||
MessageTrigger requestedMessage;
|
||||
std::optional<std::int32_t> connectorId;
|
||||
|
||||
/// \brief Provides the type of this TriggerMessage message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given TriggerMessageRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const TriggerMessageRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given TriggerMessageRequest \p k
|
||||
void from_json(const json& j, TriggerMessageRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given TriggerMessageRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the TriggerMessageRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const TriggerMessageRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP TriggerMessageResponse message
|
||||
struct TriggerMessageResponse : public ocpp::Message {
|
||||
TriggerMessageStatus status;
|
||||
|
||||
/// \brief Provides the type of this TriggerMessageResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given TriggerMessageResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const TriggerMessageResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given TriggerMessageResponse \p k
|
||||
void from_json(const json& j, TriggerMessageResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given TriggerMessageResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the TriggerMessageResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const TriggerMessageResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_TRIGGERMESSAGE_HPP
|
||||
@@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_UNLOCKCONNECTOR_HPP
|
||||
#define OCPP_V16_UNLOCKCONNECTOR_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP UnlockConnector message
|
||||
struct UnlockConnectorRequest : public ocpp::Message {
|
||||
std::int32_t connectorId;
|
||||
|
||||
/// \brief Provides the type of this UnlockConnector message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given UnlockConnectorRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const UnlockConnectorRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given UnlockConnectorRequest \p k
|
||||
void from_json(const json& j, UnlockConnectorRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given UnlockConnectorRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the UnlockConnectorRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const UnlockConnectorRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP UnlockConnectorResponse message
|
||||
struct UnlockConnectorResponse : public ocpp::Message {
|
||||
UnlockStatus status;
|
||||
|
||||
/// \brief Provides the type of this UnlockConnectorResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given UnlockConnectorResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const UnlockConnectorResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given UnlockConnectorResponse \p k
|
||||
void from_json(const json& j, UnlockConnectorResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given UnlockConnectorResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the UnlockConnectorResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const UnlockConnectorResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_UNLOCKCONNECTOR_HPP
|
||||
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_UPDATEFIRMWARE_HPP
|
||||
#define OCPP_V16_UPDATEFIRMWARE_HPP
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains a OCPP UpdateFirmware message
|
||||
struct UpdateFirmwareRequest : public ocpp::Message {
|
||||
std::string location;
|
||||
ocpp::DateTime retrieveDate;
|
||||
std::optional<std::int32_t> retries;
|
||||
std::optional<std::int32_t> retryInterval;
|
||||
|
||||
/// \brief Provides the type of this UpdateFirmware message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given UpdateFirmwareRequest \p k to a given json object \p j
|
||||
void to_json(json& j, const UpdateFirmwareRequest& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given UpdateFirmwareRequest \p k
|
||||
void from_json(const json& j, UpdateFirmwareRequest& k);
|
||||
|
||||
/// \brief Writes the string representation of the given UpdateFirmwareRequest \p k to the given output stream \p os
|
||||
/// \returns an output stream with the UpdateFirmwareRequest written to
|
||||
std::ostream& operator<<(std::ostream& os, const UpdateFirmwareRequest& k);
|
||||
|
||||
/// \brief Contains a OCPP UpdateFirmwareResponse message
|
||||
struct UpdateFirmwareResponse : public ocpp::Message {
|
||||
|
||||
/// \brief Provides the type of this UpdateFirmwareResponse message as a human readable string
|
||||
/// \returns the message type as a human readable string
|
||||
std::string get_type() const override;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given UpdateFirmwareResponse \p k to a given json object \p j
|
||||
void to_json(json& j, const UpdateFirmwareResponse& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given UpdateFirmwareResponse \p k
|
||||
void from_json(const json& j, UpdateFirmwareResponse& k);
|
||||
|
||||
/// \brief Writes the string representation of the given UpdateFirmwareResponse \p k to the given output stream \p os
|
||||
/// \returns an output stream with the UpdateFirmwareResponse written to
|
||||
std::ostream& operator<<(std::ostream& os, const UpdateFirmwareResponse& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_UPDATEFIRMWARE_HPP
|
||||
1179
tools/EVerest-main/lib/everest/ocpp/include/ocpp/v16/ocpp_enums.hpp
Normal file
1179
tools/EVerest-main/lib/everest/ocpp/include/ocpp/v16/ocpp_enums.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,214 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// This code is generated using the generator in 'src/code_generator/common`, please do not edit manually
|
||||
|
||||
#ifndef OCPP_V16_OCPP_TYPES_HPP
|
||||
#define OCPP_V16_OCPP_TYPES_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
struct IdTagInfo {
|
||||
AuthorizationStatus status;
|
||||
std::optional<ocpp::DateTime> expiryDate;
|
||||
std::optional<CiString<20>> parentIdTag;
|
||||
};
|
||||
/// \brief Conversion from a given IdTagInfo \p k to a given json object \p j
|
||||
void to_json(json& j, const IdTagInfo& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given IdTagInfo \p k
|
||||
void from_json(const json& j, IdTagInfo& k);
|
||||
|
||||
/// \brief Writes the string representation of the given IdTagInfo \p k to the given output stream \p os
|
||||
/// \returns an output stream with the IdTagInfo written to
|
||||
std::ostream& operator<<(std::ostream& os, const IdTagInfo& k);
|
||||
|
||||
struct CertificateHashDataType {
|
||||
HashAlgorithmEnumType hashAlgorithm;
|
||||
CiString<128> issuerNameHash;
|
||||
CiString<128> issuerKeyHash;
|
||||
CiString<40> serialNumber;
|
||||
};
|
||||
/// \brief Conversion from a given CertificateHashDataType \p k to a given json object \p j
|
||||
void to_json(json& j, const CertificateHashDataType& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given CertificateHashDataType \p k
|
||||
void from_json(const json& j, CertificateHashDataType& k);
|
||||
|
||||
/// \brief Writes the string representation of the given CertificateHashDataType \p k to the given output stream \p os
|
||||
/// \returns an output stream with the CertificateHashDataType written to
|
||||
std::ostream& operator<<(std::ostream& os, const CertificateHashDataType& k);
|
||||
|
||||
struct ChargingSchedulePeriod {
|
||||
std::int32_t startPeriod;
|
||||
float limit;
|
||||
std::optional<std::int32_t> numberPhases;
|
||||
};
|
||||
/// \brief Conversion from a given ChargingSchedulePeriod \p k to a given json object \p j
|
||||
void to_json(json& j, const ChargingSchedulePeriod& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ChargingSchedulePeriod \p k
|
||||
void from_json(const json& j, ChargingSchedulePeriod& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ChargingSchedulePeriod \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ChargingSchedulePeriod written to
|
||||
std::ostream& operator<<(std::ostream& os, const ChargingSchedulePeriod& k);
|
||||
|
||||
struct ChargingSchedule {
|
||||
ChargingRateUnit chargingRateUnit;
|
||||
std::vector<ChargingSchedulePeriod> chargingSchedulePeriod;
|
||||
std::optional<std::int32_t> duration;
|
||||
std::optional<ocpp::DateTime> startSchedule;
|
||||
std::optional<float> minChargingRate;
|
||||
};
|
||||
/// \brief Conversion from a given ChargingSchedule \p k to a given json object \p j
|
||||
void to_json(json& j, const ChargingSchedule& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ChargingSchedule \p k
|
||||
void from_json(const json& j, ChargingSchedule& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ChargingSchedule \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ChargingSchedule written to
|
||||
std::ostream& operator<<(std::ostream& os, const ChargingSchedule& k);
|
||||
|
||||
struct KeyValue {
|
||||
CiString<50> key;
|
||||
bool readonly;
|
||||
std::optional<CiString<500>> value;
|
||||
};
|
||||
/// \brief Conversion from a given KeyValue \p k to a given json object \p j
|
||||
void to_json(json& j, const KeyValue& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given KeyValue \p k
|
||||
void from_json(const json& j, KeyValue& k);
|
||||
|
||||
/// \brief Writes the string representation of the given KeyValue \p k to the given output stream \p os
|
||||
/// \returns an output stream with the KeyValue written to
|
||||
std::ostream& operator<<(std::ostream& os, const KeyValue& k);
|
||||
|
||||
struct LogParametersType {
|
||||
CiString<512> remoteLocation;
|
||||
std::optional<ocpp::DateTime> oldestTimestamp;
|
||||
std::optional<ocpp::DateTime> latestTimestamp;
|
||||
};
|
||||
/// \brief Conversion from a given LogParametersType \p k to a given json object \p j
|
||||
void to_json(json& j, const LogParametersType& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given LogParametersType \p k
|
||||
void from_json(const json& j, LogParametersType& k);
|
||||
|
||||
/// \brief Writes the string representation of the given LogParametersType \p k to the given output stream \p os
|
||||
/// \returns an output stream with the LogParametersType written to
|
||||
std::ostream& operator<<(std::ostream& os, const LogParametersType& k);
|
||||
|
||||
struct SampledValue {
|
||||
std::string value;
|
||||
std::optional<ReadingContext> context;
|
||||
std::optional<ValueFormat> format;
|
||||
std::optional<Measurand> measurand;
|
||||
std::optional<Phase> phase;
|
||||
std::optional<Location> location;
|
||||
std::optional<UnitOfMeasure> unit;
|
||||
};
|
||||
/// \brief Conversion from a given SampledValue \p k to a given json object \p j
|
||||
void to_json(json& j, const SampledValue& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given SampledValue \p k
|
||||
void from_json(const json& j, SampledValue& k);
|
||||
|
||||
/// \brief Writes the string representation of the given SampledValue \p k to the given output stream \p os
|
||||
/// \returns an output stream with the SampledValue written to
|
||||
std::ostream& operator<<(std::ostream& os, const SampledValue& k);
|
||||
|
||||
struct MeterValue {
|
||||
ocpp::DateTime timestamp;
|
||||
std::vector<SampledValue> sampledValue;
|
||||
};
|
||||
/// \brief Conversion from a given MeterValue \p k to a given json object \p j
|
||||
void to_json(json& j, const MeterValue& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given MeterValue \p k
|
||||
void from_json(const json& j, MeterValue& k);
|
||||
|
||||
/// \brief Writes the string representation of the given MeterValue \p k to the given output stream \p os
|
||||
/// \returns an output stream with the MeterValue written to
|
||||
std::ostream& operator<<(std::ostream& os, const MeterValue& k);
|
||||
|
||||
struct ChargingProfile {
|
||||
std::int32_t chargingProfileId;
|
||||
std::int32_t stackLevel;
|
||||
ChargingProfilePurposeType chargingProfilePurpose;
|
||||
ChargingProfileKindType chargingProfileKind;
|
||||
ChargingSchedule chargingSchedule;
|
||||
std::optional<std::int32_t> transactionId;
|
||||
std::optional<RecurrencyKindType> recurrencyKind;
|
||||
std::optional<ocpp::DateTime> validFrom;
|
||||
std::optional<ocpp::DateTime> validTo;
|
||||
};
|
||||
/// \brief Conversion from a given ChargingProfile \p k to a given json object \p j
|
||||
void to_json(json& j, const ChargingProfile& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given ChargingProfile \p k
|
||||
void from_json(const json& j, ChargingProfile& k);
|
||||
|
||||
/// \brief Writes the string representation of the given ChargingProfile \p k to the given output stream \p os
|
||||
/// \returns an output stream with the ChargingProfile written to
|
||||
std::ostream& operator<<(std::ostream& os, const ChargingProfile& k);
|
||||
|
||||
struct LocalAuthorizationList {
|
||||
CiString<20> idTag;
|
||||
std::optional<IdTagInfo> idTagInfo;
|
||||
};
|
||||
/// \brief Conversion from a given LocalAuthorizationList \p k to a given json object \p j
|
||||
void to_json(json& j, const LocalAuthorizationList& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given LocalAuthorizationList \p k
|
||||
void from_json(const json& j, LocalAuthorizationList& k);
|
||||
|
||||
/// \brief Writes the string representation of the given LocalAuthorizationList \p k to the given output stream \p os
|
||||
/// \returns an output stream with the LocalAuthorizationList written to
|
||||
std::ostream& operator<<(std::ostream& os, const LocalAuthorizationList& k);
|
||||
|
||||
struct FirmwareType {
|
||||
CiString<512> location;
|
||||
ocpp::DateTime retrieveDateTime;
|
||||
CiString<5500> signingCertificate;
|
||||
CiString<800> signature;
|
||||
std::optional<ocpp::DateTime> installDateTime;
|
||||
};
|
||||
/// \brief Conversion from a given FirmwareType \p k to a given json object \p j
|
||||
void to_json(json& j, const FirmwareType& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given FirmwareType \p k
|
||||
void from_json(const json& j, FirmwareType& k);
|
||||
|
||||
/// \brief Writes the string representation of the given FirmwareType \p k to the given output stream \p os
|
||||
/// \returns an output stream with the FirmwareType written to
|
||||
std::ostream& operator<<(std::ostream& os, const FirmwareType& k);
|
||||
|
||||
struct TransactionData {
|
||||
ocpp::DateTime timestamp;
|
||||
std::vector<SampledValue> sampledValue;
|
||||
};
|
||||
/// \brief Conversion from a given TransactionData \p k to a given json object \p j
|
||||
void to_json(json& j, const TransactionData& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given TransactionData \p k
|
||||
void from_json(const json& j, TransactionData& k);
|
||||
|
||||
/// \brief Writes the string representation of the given TransactionData \p k to the given output stream \p os
|
||||
/// \returns an output stream with the TransactionData written to
|
||||
std::ostream& operator<<(std::ostream& os, const TransactionData& k);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_OCPP_TYPES_HPP
|
||||
108
tools/EVerest-main/lib/everest/ocpp/include/ocpp/v16/profile.hpp
Normal file
108
tools/EVerest-main/lib/everest/ocpp/include/ocpp/v16/profile.hpp
Normal file
@@ -0,0 +1,108 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef PROFILE_H
|
||||
#define PROFILE_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
|
||||
namespace ocpp::v16 {
|
||||
class ChargingProfile;
|
||||
class EnhancedChargingSchedulePeriod;
|
||||
class ChargingSchedulePeriod;
|
||||
|
||||
constexpr float no_limit_specified = -1.0;
|
||||
|
||||
using ocpp::DateTime;
|
||||
|
||||
struct IntermediatePeriod {
|
||||
std::int32_t startPeriod;
|
||||
float current_limit;
|
||||
float power_limit;
|
||||
std::int32_t stack_level_current;
|
||||
std::int32_t stack_level_power;
|
||||
std::optional<std::int32_t> numberPhases;
|
||||
std::optional<std::int32_t> phaseToUse;
|
||||
};
|
||||
|
||||
using IntermediateProfile = std::vector<IntermediatePeriod>;
|
||||
|
||||
struct period_entry_t {
|
||||
void init(const DateTime& in_start, int in_duration, const ChargingSchedulePeriod& in_period,
|
||||
const ChargingProfile& in_profile);
|
||||
bool validate(const ChargingProfile& profile, const DateTime& now);
|
||||
|
||||
DateTime start;
|
||||
DateTime end;
|
||||
float limit;
|
||||
std::optional<std::int32_t> number_phases;
|
||||
std::int32_t stack_level;
|
||||
ChargingRateUnit charging_rate_unit;
|
||||
std::optional<float> min_charging_rate;
|
||||
};
|
||||
|
||||
/// \brief Calculate the number of seconds elapsed between \param to and \param from
|
||||
std::int32_t elapsed_seconds(const ocpp::DateTime& to, const ocpp::DateTime& from);
|
||||
|
||||
/// \brief Rounds down the \param dt to the nearest second
|
||||
ocpp::DateTime floor_seconds(const ocpp::DateTime& dt);
|
||||
|
||||
std::vector<DateTime> calculate_start(const DateTime& now, const DateTime& end,
|
||||
const std::optional<DateTime>& session_start, const ChargingProfile& profile);
|
||||
std::vector<period_entry_t> calculate_profile_entry(const DateTime& now, const DateTime& end,
|
||||
const std::optional<DateTime>& session_start,
|
||||
const ChargingProfile& profile, std::size_t period_index);
|
||||
std::vector<period_entry_t> calculate_profile(const DateTime& now, const DateTime& end,
|
||||
const std::optional<DateTime>& session_start,
|
||||
const ChargingProfile& profile);
|
||||
|
||||
/// \brief generate an ordered list of valid schedule periods for the profiles
|
||||
/// \param now the current date and time
|
||||
/// \param end ignore entries beyond this date and time (i.e. that start after end)
|
||||
/// \param session_start optional when the charging session started
|
||||
/// \param profiles A vector of charging profiles
|
||||
/// \param purpose The purpose to generate the list for. Only profiles with this purpose are included.
|
||||
/// \return a list of profile periods with calculated date & time start and end times
|
||||
/// \note it is valid for there to be gaps (for recurring profiles)
|
||||
std::vector<period_entry_t> calculate_all_profiles(const DateTime& now, const DateTime& end,
|
||||
const std::optional<DateTime>& session_start,
|
||||
const std::vector<ChargingProfile>& profiles,
|
||||
ChargingProfilePurposeType purpose);
|
||||
|
||||
/// \brief generates an IntermediateProfile by sorting and processing a list of period_entry_t intervals within a given
|
||||
/// time range, resolving overlaps based on stack priority and filling any time gaps with default values.
|
||||
/// \param periods the list of periods to build into the profile
|
||||
/// \param now the start of the composite schedule
|
||||
/// \param end the end (i.e. duration) of the composite schedule \return a list of profile periods with calculated date
|
||||
/// & time start and end times
|
||||
IntermediateProfile generate_profile_from_periods(std::vector<period_entry_t>& periods, const DateTime& now,
|
||||
const DateTime& end);
|
||||
|
||||
/// \brief Generates a new profile by combining a \param tx_profile and a \param tx_default_profile.
|
||||
/// The tx_profile will be preferred over the tx_default_profile whenever it has a value
|
||||
/// \return A combined profile
|
||||
IntermediateProfile merge_tx_profile_with_tx_default_profile(const IntermediateProfile& tx_profile,
|
||||
const IntermediateProfile& tx_default_profile);
|
||||
|
||||
/// \brief Generates a new profile by taking the lowest limit of all the provided \param profiles
|
||||
IntermediateProfile merge_profiles_by_lowest_limit(const std::vector<IntermediateProfile>& profiles);
|
||||
|
||||
/// \brief Generates a new profile by summing the limits of all the provided \param profiles, filling in defaults
|
||||
/// wherever a profile has no limit
|
||||
IntermediateProfile merge_profiles_by_summing_limits(const std::vector<IntermediateProfile>& profiles,
|
||||
float current_default, float power_default);
|
||||
|
||||
/// \brief Convert an intermediate profile into a final charging schedule.
|
||||
/// This will fill in defaults and convert merge the current and power limits into the final \p charging_rate_unit based
|
||||
/// limit
|
||||
std::vector<EnhancedChargingSchedulePeriod>
|
||||
convert_intermediate_into_schedule(const IntermediateProfile& profile, ChargingRateUnit charging_rate_unit,
|
||||
float default_limit, std::int32_t default_number_phases, float supply_voltage);
|
||||
|
||||
} // namespace ocpp::v16
|
||||
|
||||
#endif // PROFILE_H
|
||||
@@ -0,0 +1,130 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef OCPP_V16_SMART_CHARGING_HPP
|
||||
#define OCPP_V16_SMART_CHARGING_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
|
||||
#include <ocpp/v16/charge_point_configuration_interface.hpp>
|
||||
#include <ocpp/v16/connector.hpp>
|
||||
#include <ocpp/v16/database_handler.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
#include <ocpp/v16/transaction.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
const int DEFAULT_AND_MAX_NUMBER_PHASES = 3;
|
||||
const int HOURS_PER_DAY = 24;
|
||||
const int SECONDS_PER_HOUR = 3600;
|
||||
const int SECONDS_PER_DAY = 86400;
|
||||
const int DAYS_PER_WEEK = 7;
|
||||
|
||||
/// \brief Helper struct to calculate Composite Schedule
|
||||
struct LimitStackLevelPair {
|
||||
int limit;
|
||||
int stack_level;
|
||||
};
|
||||
|
||||
/// \brief Helper struct to calculate Composite Schedule
|
||||
struct PeriodDateTimePair {
|
||||
std::optional<ChargingSchedulePeriod> period;
|
||||
ocpp::DateTime end_time;
|
||||
};
|
||||
|
||||
/// \brief This class handles and maintains incoming ChargingProfiles and contains the logic
|
||||
/// to calculate the composite schedules
|
||||
class SmartChargingHandler {
|
||||
private:
|
||||
std::map<std::int32_t, std::shared_ptr<Connector>> connectors;
|
||||
std::shared_ptr<ocpp::v16::DatabaseHandler> database_handler;
|
||||
ChargePointConfigurationInterface& configuration;
|
||||
std::map<int, ChargingProfile> stack_level_charge_point_max_profiles_map;
|
||||
std::mutex charge_point_max_profiles_map_mutex;
|
||||
std::mutex tx_default_profiles_map_mutex;
|
||||
std::mutex tx_profiles_map_mutex;
|
||||
|
||||
std::unique_ptr<Everest::SteadyTimer> clear_profiles_timer;
|
||||
|
||||
bool clear_profiles(std::map<std::int32_t, ChargingProfile>& stack_level_profiles_map,
|
||||
std::optional<int> profile_id_opt, std::optional<int> connector_id_opt, const int connector_id,
|
||||
std::optional<int> stack_level_opt,
|
||||
std::optional<ChargingProfilePurposeType> charging_profile_purpose_opt, bool check_id_only);
|
||||
|
||||
protected:
|
||||
int get_number_installed_profiles();
|
||||
void clear_expired_profiles(const date::utc_clock::time_point& now);
|
||||
|
||||
public:
|
||||
SmartChargingHandler(std::map<std::int32_t, std::shared_ptr<Connector>>& connectors,
|
||||
std::shared_ptr<DatabaseHandler> database_handler,
|
||||
ChargePointConfigurationInterface& configuration);
|
||||
|
||||
///
|
||||
/// \brief validates the given \p profile according to the specification
|
||||
///
|
||||
bool validate_profile(ChargingProfile& profile, const int connector_id, bool ignore_no_transaction,
|
||||
const int profile_max_stack_level, const int max_charging_profiles_installed,
|
||||
const int charging_schedule_max_periods,
|
||||
const std::vector<ChargingRateUnit>& charging_schedule_allowed_charging_rate_units);
|
||||
|
||||
///
|
||||
/// \brief Adds the given \p profile to the collection of stack_level_charge_point_max_profiles_map
|
||||
///
|
||||
void add_charge_point_max_profile(const ChargingProfile& profile);
|
||||
|
||||
///
|
||||
/// \brief Adds the given \p profile to the collection of stack_level_tx_default_profiles_map of the respective
|
||||
/// connector or to all connectors if \p connector_id is 0
|
||||
///
|
||||
void add_tx_default_profile(const ChargingProfile& profile, const int connector_id);
|
||||
|
||||
///
|
||||
/// \brief Adds the given \p profile to the collection of stack_level_tx_profiles_map of the respective
|
||||
/// connector
|
||||
///
|
||||
void add_tx_profile(const ChargingProfile& profile, const int connector_id);
|
||||
|
||||
///
|
||||
/// \brief Clears all charging profiles using optional filters
|
||||
///
|
||||
bool clear_all_profiles_with_filter(std::optional<int> profile_id, std::optional<int> connector_id,
|
||||
std::optional<int> stack_level,
|
||||
std::optional<ChargingProfilePurposeType> charging_profile_purpose,
|
||||
bool check_id_only);
|
||||
|
||||
///
|
||||
/// \brief Clears all present profiles from all collections
|
||||
///
|
||||
void clear_all_profiles();
|
||||
|
||||
///
|
||||
/// \brief Gets all valid profiles within the given absoulte \p start_time and absolute \p end_time for the given
|
||||
/// \p connector_id . Only profiles that are not contained in \p purposes_to_ignore are included in the response.
|
||||
///
|
||||
std::vector<ChargingProfile>
|
||||
get_valid_profiles(const ocpp::DateTime& start_time, const ocpp::DateTime& end_time, const int connector_id,
|
||||
const std::set<ChargingProfilePurposeType>& purposes_to_ignore = {});
|
||||
///
|
||||
/// \brief Calculates the enhanced composite schedule for the given \p valid_profiles and the given \p connector_id
|
||||
///
|
||||
EnhancedChargingSchedule calculate_enhanced_composite_schedule(const ocpp::DateTime& start_time,
|
||||
const ocpp::DateTime& end_time,
|
||||
const std::int32_t evse_id,
|
||||
ChargingRateUnit charging_rate_unit, bool is_offline,
|
||||
bool simulate_transaction_active);
|
||||
|
||||
ChargingSchedule calculate_composite_schedule(const ocpp::DateTime& start_time, const ocpp::DateTime& end_time,
|
||||
const std::int32_t evse_id, ChargingRateUnit charging_rate_unit,
|
||||
bool is_offline, bool simulate_transaction_active);
|
||||
};
|
||||
|
||||
bool validate_schedule(const ChargingSchedule& schedule, const int charging_schedule_max_periods,
|
||||
const std::vector<ChargingRateUnit>& charging_schedule_allowed_charging_rate_units);
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_SMART_CHARGING_HPP
|
||||
@@ -0,0 +1,218 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_V16_TRANSACTION_HPP
|
||||
#define OCPP_V16_TRANSACTION_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
#include <everest/timer.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief A structure that contains a energy value in Wh that can be used for start/stop energy values and a
|
||||
/// corresponding timestamp
|
||||
struct StampedEnergyWh {
|
||||
ocpp::DateTime timestamp; ///< A timestamp associated with the energy value
|
||||
double energy_Wh; ///< The energy value in Wh
|
||||
StampedEnergyWh(ocpp::DateTime timestamp, double energy_Wh) : timestamp(timestamp), energy_Wh(energy_Wh) {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Contains all transaction related data, such as the ID and power meter values
|
||||
class Transaction {
|
||||
private:
|
||||
std::optional<std::int32_t> transaction_id;
|
||||
std::int32_t internal_transaction_id;
|
||||
std::int32_t connector;
|
||||
std::string session_id;
|
||||
CiString<20> id_token;
|
||||
std::shared_ptr<StampedEnergyWh> start_energy_wh;
|
||||
std::optional<std::int32_t> reservation_id;
|
||||
bool active;
|
||||
bool finished;
|
||||
bool has_signed_meter_values;
|
||||
std::unique_ptr<Everest::SteadyTimer> meter_values_sample_timer;
|
||||
std::string start_transaction_message_id;
|
||||
std::string stop_transaction_message_id;
|
||||
std::shared_ptr<StampedEnergyWh> stop_energy_wh;
|
||||
std::mutex meter_values_mutex;
|
||||
std::vector<MeterValue> meter_values;
|
||||
|
||||
public:
|
||||
/// \brief Creates a new Transaction object, taking ownership of the provided \p meter_values_sample_timer
|
||||
/// on the provided \p connector
|
||||
Transaction(const std::int32_t transaction_id, const std::int32_t& connector, const std::string& session_id,
|
||||
const CiString<20>& id_token, const double meter_start, std::optional<std::int32_t> reservation_id,
|
||||
const ocpp::DateTime& timestamp, std::unique_ptr<Everest::SteadyTimer> meter_values_sample_timer);
|
||||
|
||||
/// \brief Provides the energy in Wh at the start of the transaction
|
||||
/// \returns the energy in Wh combined with a timestamp
|
||||
std::shared_ptr<StampedEnergyWh> get_start_energy_wh();
|
||||
|
||||
/// \brief Adds the energy in Wh \p stop_energy_wh to the transaction. This also
|
||||
/// stops the collection of further meter values.
|
||||
void add_stop_energy_wh(std::shared_ptr<StampedEnergyWh> stop_energy_wh);
|
||||
|
||||
/// \brief Provides the energy in Wh at the end of the transaction
|
||||
/// \returns the energy in Wh combined with a timestamp
|
||||
std::shared_ptr<StampedEnergyWh> get_stop_energy_wh();
|
||||
|
||||
/// \brief Provides the reservation id of the transaction if present
|
||||
/// \returns the reservation id
|
||||
std::optional<std::int32_t> get_reservation_id();
|
||||
|
||||
/// \brief Provides the connector of this transaction
|
||||
/// \returns the connector
|
||||
std::int32_t get_connector() const;
|
||||
|
||||
/// \brief Provides the authorized id tag of this Transaction
|
||||
/// \returns the authorized id tag
|
||||
CiString<20> get_id_tag();
|
||||
|
||||
/// \brief Adds the provided \p meter_value to a chronological list of powermeter values
|
||||
void add_meter_value(MeterValue meter_value);
|
||||
|
||||
/// \brief Provides all recorded powermeter values
|
||||
/// \returns a vector of powermeter values
|
||||
std::vector<MeterValue> get_meter_values();
|
||||
|
||||
/// \brief Changes the sample \p interval of the powermeter values sampling timer
|
||||
/// \returns true if successful
|
||||
bool change_meter_values_sample_interval(std::int32_t interval);
|
||||
|
||||
/// \brief Adds the provided \p meter_value to a chronological list of clock aligned powermeter values
|
||||
void add_clock_aligned_meter_value(MeterValue meter_value);
|
||||
|
||||
/// \brief Provides the id of this transaction
|
||||
/// \returns the transaction id
|
||||
std::optional<std::int32_t> get_transaction_id();
|
||||
|
||||
/// \brief Returns the internal transaction id
|
||||
std::int32_t get_internal_transaction_id() const;
|
||||
|
||||
/// \brief Provides the id of this session
|
||||
/// \returns the session_id
|
||||
std::string get_session_id();
|
||||
|
||||
/// \brief Sets the start transaction message id using the provides \p message_id
|
||||
void set_start_transaction_message_id(const std::string& message_id);
|
||||
|
||||
/// \brief Provides the start transaction message id
|
||||
std::string get_start_transaction_message_id();
|
||||
|
||||
/// \brief Sets the stop transaction message id using the provides \p message_id
|
||||
void set_stop_transaction_message_id(const std::string& message_id);
|
||||
|
||||
/// \brief Provides the stop transaction message id
|
||||
std::string get_stop_transaction_message_id();
|
||||
|
||||
/// \brief Sets the transaction id
|
||||
void set_transaction_id(std::int32_t transaction_id);
|
||||
|
||||
/// \brief Provides all recorded sampled and clock aligned powermeter values
|
||||
/// \returns a vector of sampled and clock aligned powermeter values packaged into a TransactionData object
|
||||
std::vector<TransactionData> get_transaction_data();
|
||||
|
||||
/// \brief Marks the transaction as stopped/inactive
|
||||
void stop();
|
||||
|
||||
/// \brief Indicates if the transaction is active. Active means that the transaction for this session is not null
|
||||
/// and no StopTransaction.req has been pushed to the message queue yet
|
||||
bool is_active() const;
|
||||
|
||||
/// \brief Indicates if a StopTransaction.req for this transaction has already been pushed to the message queue
|
||||
bool is_finished() const;
|
||||
|
||||
/// \brief Sets the finished flag for this transaction. This is done when a StopTransaction.req has been pushed to
|
||||
/// the message queue
|
||||
void set_finished();
|
||||
|
||||
/// \brief Sets the has_signed_meter_value flag for this transaction, this function is called
|
||||
/// from \p on_transaction_started and \p on_transaction_stopped
|
||||
void set_has_signed_meter_values();
|
||||
|
||||
/// \brief Indicates if this transaction has signed meter values or not, this function is called
|
||||
/// from \p on_transaction_started and \p on_transaction_stopped
|
||||
/// \returns a boolean value indicating if this transaction has signed meter values or not
|
||||
bool get_has_signed_meter_values();
|
||||
};
|
||||
|
||||
/// \brief Contains transactions for all available connectors and manages access to these transactions
|
||||
class TransactionHandler {
|
||||
private:
|
||||
std::mutex active_transactions_mutex;
|
||||
// size is equal to the number of connectors
|
||||
std::int32_t number_of_connectors;
|
||||
|
||||
std::vector<std::shared_ptr<Transaction>> active_transactions;
|
||||
// size does not depend on the number of connectors
|
||||
std::vector<std::shared_ptr<Transaction>> stopped_transactions;
|
||||
|
||||
std::mt19937 gen;
|
||||
std::uniform_int_distribution<std::int32_t> distr;
|
||||
|
||||
public:
|
||||
/// \brief Creates and manages transactions for the provided \p number_of_connectors
|
||||
explicit TransactionHandler(std::int32_t number_of_connectors);
|
||||
|
||||
/// \brief Returns a negative random transaction_id
|
||||
std::int32_t get_negative_random_transaction_id();
|
||||
|
||||
/// \brief Adds the given \p transaction the vector of transactions
|
||||
void add_transaction(std::shared_ptr<Transaction> transaction);
|
||||
|
||||
/// \brief Adds the transaction at the \p connector to the vector of stopped transactions
|
||||
void add_stopped_transaction(std::int32_t connector);
|
||||
|
||||
/// \brief Removes a transaction from the provided \p connector
|
||||
/// \returns true if successful
|
||||
bool remove_active_transaction(std::int32_t connector);
|
||||
|
||||
/// \brief Erases a transaction with the provided \p stop_transaction_message_id
|
||||
void erase_stopped_transaction(std::string stop_transaction_message_id);
|
||||
|
||||
/// \brief Returns the transaction associated with the transaction at the provided \p connector
|
||||
/// \returns The associated transaction if available or nullptr if not
|
||||
std::shared_ptr<Transaction> get_transaction(std::int32_t connector);
|
||||
|
||||
/// \brief Returns the transaction associated with the transaction with the provided
|
||||
/// \p start_transaction_message_id
|
||||
/// \returns The associated transaction if available or nullptr if not
|
||||
std::shared_ptr<Transaction> get_transaction(const std::string& start_transaction_message_id);
|
||||
|
||||
///
|
||||
/// \brief Returns the transaction associated with the given id tag.
|
||||
/// \param id_tag The id tag.
|
||||
/// \return The associated transaction if available.
|
||||
///
|
||||
std::shared_ptr<Transaction> get_transaction_from_id_tag(const std::string& id_tag);
|
||||
|
||||
/// \brief Provides the connector on which a transaction with the given \p transaction_id is running
|
||||
/// \returns The connector or -1 if the transaction_id is unknown
|
||||
std::int32_t get_connector_from_transaction_id(std::int32_t transaction_id);
|
||||
|
||||
/// \brief Adds a clock aligned \p meter_value to the transaction on the provided \p connector
|
||||
void add_meter_value(std::int32_t connector, const MeterValue& meter_value);
|
||||
|
||||
/// \brief Modifies the sample interval of the meter values sample timer on all connectors. The
|
||||
/// provided \p interval is expected to be given in seconds.
|
||||
void change_meter_values_sample_intervals(std::int32_t interval);
|
||||
|
||||
// \brief Provides the IdTag that was associated with the transaction with the provided
|
||||
/// \p stop_transaction_message_id
|
||||
/// \returns the IdTag if it is available, std::nullopt otherwise
|
||||
std::optional<CiString<20>> get_authorized_id_tag(const std::string& stop_transaction_message_id);
|
||||
|
||||
/// \brief Indicates if there is an active transaction at the proveded \p connector
|
||||
/// \returns true if a transaction exists
|
||||
bool transaction_active(std::int32_t connector);
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_TRANSACTION_HPP
|
||||
245
tools/EVerest-main/lib/everest/ocpp/include/ocpp/v16/types.hpp
Normal file
245
tools/EVerest-main/lib/everest/ocpp/include/ocpp/v16/types.hpp
Normal file
@@ -0,0 +1,245 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_V16_TYPES_HPP
|
||||
#define OCPP_V16_TYPES_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string_view>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v16/ocpp_enums.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
namespace ocpp {
|
||||
namespace v16 {
|
||||
|
||||
/// \brief Contains all supported OCPP 1.6 message types
|
||||
enum class MessageType {
|
||||
Authorize,
|
||||
AuthorizeResponse,
|
||||
BootNotification,
|
||||
BootNotificationResponse,
|
||||
CancelReservation,
|
||||
CancelReservationResponse,
|
||||
CertificateSigned,
|
||||
CertificateSignedResponse,
|
||||
ChangeAvailability,
|
||||
ChangeAvailabilityResponse,
|
||||
ChangeConfiguration,
|
||||
ChangeConfigurationResponse,
|
||||
ClearCache,
|
||||
ClearCacheResponse,
|
||||
ClearChargingProfile,
|
||||
ClearChargingProfileResponse,
|
||||
DataTransfer,
|
||||
DataTransferResponse,
|
||||
DeleteCertificate,
|
||||
DeleteCertificateResponse,
|
||||
DiagnosticsStatusNotification,
|
||||
DiagnosticsStatusNotificationResponse,
|
||||
ExtendedTriggerMessage,
|
||||
ExtendedTriggerMessageResponse,
|
||||
FirmwareStatusNotification,
|
||||
FirmwareStatusNotificationResponse,
|
||||
GetCompositeSchedule,
|
||||
GetCompositeScheduleResponse,
|
||||
GetConfiguration,
|
||||
GetConfigurationResponse,
|
||||
GetDiagnostics,
|
||||
GetDiagnosticsResponse,
|
||||
GetInstalledCertificateIds,
|
||||
GetInstalledCertificateIdsResponse,
|
||||
GetLocalListVersion,
|
||||
GetLocalListVersionResponse,
|
||||
GetLog,
|
||||
GetLogResponse,
|
||||
Heartbeat,
|
||||
HeartbeatResponse,
|
||||
InstallCertificate,
|
||||
InstallCertificateResponse,
|
||||
LogStatusNotification,
|
||||
LogStatusNotificationResponse,
|
||||
MeterValues,
|
||||
MeterValuesResponse,
|
||||
RemoteStartTransaction,
|
||||
RemoteStartTransactionResponse,
|
||||
RemoteStopTransaction,
|
||||
RemoteStopTransactionResponse,
|
||||
ReserveNow,
|
||||
ReserveNowResponse,
|
||||
Reset,
|
||||
ResetResponse,
|
||||
SecurityEventNotification,
|
||||
SecurityEventNotificationResponse,
|
||||
SendLocalList,
|
||||
SendLocalListResponse,
|
||||
SetChargingProfile,
|
||||
SetChargingProfileResponse,
|
||||
SignCertificate,
|
||||
SignCertificateResponse,
|
||||
SignedFirmwareStatusNotification,
|
||||
SignedFirmwareStatusNotificationResponse,
|
||||
SignedUpdateFirmware,
|
||||
SignedUpdateFirmwareResponse,
|
||||
StartTransaction,
|
||||
StartTransactionResponse,
|
||||
StatusNotification,
|
||||
StatusNotificationResponse,
|
||||
StopTransaction,
|
||||
StopTransactionResponse,
|
||||
TriggerMessage,
|
||||
TriggerMessageResponse,
|
||||
UnlockConnector,
|
||||
UnlockConnectorResponse,
|
||||
UpdateFirmware,
|
||||
UpdateFirmwareResponse,
|
||||
InternalError, // not in spec, for internal use
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given MessageType \p m to std::string
|
||||
/// \returns a string representation of the MessageType
|
||||
std::string messagetype_to_string(MessageType m);
|
||||
|
||||
/// \brief Converts the given std::string \p s to MessageType
|
||||
/// \returns a MessageType from a string representation
|
||||
MessageType string_to_messagetype(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given \p message_type to the given output stream \p os
|
||||
/// \returns an output stream with the MessageType written to
|
||||
std::ostream& operator<<(std::ostream& os, const MessageType& message_type);
|
||||
|
||||
/// \brief Contains the supported OCPP 1.6 feature profiles
|
||||
enum class SupportedFeatureProfiles {
|
||||
Internal,
|
||||
Core,
|
||||
CostAndPrice,
|
||||
FirmwareManagement,
|
||||
LocalAuthListManagement,
|
||||
Reservation,
|
||||
SmartCharging,
|
||||
RemoteTrigger,
|
||||
Security,
|
||||
PnC,
|
||||
Custom
|
||||
};
|
||||
namespace conversions {
|
||||
/// \brief Converts the given SupportedFeatureProfiles \p e to std::string
|
||||
/// \returns a string representation of the SupportedFeatureProfiles
|
||||
std::string supported_feature_profiles_to_string(SupportedFeatureProfiles e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to SupportedFeatureProfiles
|
||||
/// \returns a SupportedFeatureProfiles from a string representation
|
||||
SupportedFeatureProfiles string_to_supported_feature_profiles(const std::string_view& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given \p supported_feature_profiles to the given output stream \p os
|
||||
/// \returns an output stream with the SupportedFeatureProfiles written to
|
||||
std::ostream& operator<<(std::ostream& os, const SupportedFeatureProfiles& supported_feature_profiles);
|
||||
|
||||
/// \brief Contains the different connection states of the charge point
|
||||
enum class ChargePointConnectionState {
|
||||
Disconnected, // state when disconnected
|
||||
Connected, // state when ws is connected
|
||||
Booted, // state when ws is connected and BootNotifcation had been Accepted
|
||||
Pending, // state when ws is connected and state when BootNotifcation is Pending
|
||||
Rejected, // state when ws is connected and state when BootNotifcation had been Rejected
|
||||
};
|
||||
namespace conversions {
|
||||
/// \brief Converts the given ChargePointConnectionState \p e to std::string
|
||||
/// \returns a string representation of the ChargePointConnectionState
|
||||
std::string charge_point_connection_state_to_string(ChargePointConnectionState e);
|
||||
|
||||
/// \brief Converts the given std::string \p s to ChargePointConnectionState
|
||||
/// \returns a ChargePointConnectionState from a string representation
|
||||
ChargePointConnectionState string_to_charge_point_connection_state(const std::string& s);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Writes the string representation of the given \p charge_point_connection_state
|
||||
/// to the given output stream \p os \returns an output stream with the ChargePointConnectionState written to
|
||||
std::ostream& operator<<(std::ostream& os, const ChargePointConnectionState& charge_point_connection_state);
|
||||
|
||||
/// \brief Combines a Measurand with an optional Phase
|
||||
struct MeasurandWithPhase {
|
||||
Measurand measurand; ///< A OCPP Measurand
|
||||
std::optional<Phase> phase; ///< If applicable and available a Phase
|
||||
|
||||
/// \brief Comparison operator== between this MeasurandWithPhase and the given \p measurand_with_phase
|
||||
/// \returns true when measurand and phase are equal
|
||||
bool operator==(MeasurandWithPhase measurand_with_phase);
|
||||
};
|
||||
|
||||
/// \brief Combines a Measurand with a list of Phases
|
||||
struct MeasurandWithPhases {
|
||||
Measurand measurand; ///< A OCPP Measurand
|
||||
std::vector<Phase> phases; ///< A list of Phases
|
||||
};
|
||||
|
||||
/// \brief Combines AvailabilityType with persist flag for scheduled Availability changes
|
||||
struct AvailabilityChange {
|
||||
AvailabilityType availability;
|
||||
bool persist;
|
||||
};
|
||||
|
||||
/// \brief BootReasonEnum contains the different boot reasons of the charge point (copied from OCPP2.0.1 definition)
|
||||
enum class BootReasonEnum {
|
||||
ApplicationReset,
|
||||
FirmwareUpdate,
|
||||
LocalReset,
|
||||
PowerUp,
|
||||
RemoteReset,
|
||||
ScheduledReset,
|
||||
Triggered,
|
||||
Unknown,
|
||||
Watchdog
|
||||
};
|
||||
|
||||
/// \brief Enhances ChargingSchedulePeriod with stackLevel
|
||||
struct EnhancedChargingSchedulePeriod {
|
||||
std::int32_t startPeriod;
|
||||
float limit;
|
||||
std::optional<std::int32_t> numberPhases;
|
||||
std::int32_t stackLevel;
|
||||
bool periodTransformed = false; // indicates that a period was transformed from chargingRateUnit
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given EnhancedChargingSchedulePeriod \p k to a given json object \p j
|
||||
void to_json(json& j, const EnhancedChargingSchedulePeriod& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given EnhancedChargingSchedulePeriod \p k
|
||||
void from_json(const json& j, EnhancedChargingSchedulePeriod& k);
|
||||
|
||||
/// \brief Enhances ChargingSchedule by containing std::vector<EnhancedChargingSchedulePeriods> instead of
|
||||
/// std::vector<ChargingSchedulePeriod>
|
||||
struct EnhancedChargingSchedule {
|
||||
ChargingRateUnit chargingRateUnit;
|
||||
std::vector<EnhancedChargingSchedulePeriod> chargingSchedulePeriod;
|
||||
std::optional<std::int32_t> duration;
|
||||
std::optional<ocpp::DateTime> startSchedule;
|
||||
std::optional<float> minChargingRate;
|
||||
};
|
||||
|
||||
/// \brief Conversion from a given EnhancedChargingSchedule \p k to a given json object \p j
|
||||
void to_json(json& j, const EnhancedChargingSchedule& k);
|
||||
|
||||
/// \brief Conversion from a given json object \p j to a given EnhancedChargingSchedule \p k
|
||||
void from_json(const json& j, EnhancedChargingSchedule& k);
|
||||
|
||||
/// \brief Extends the IdTagInfo with an optional TariffMessage for california pricing
|
||||
struct EnhancedIdTagInfo {
|
||||
IdTagInfo id_tag_info;
|
||||
std::optional<TariffMessage> tariff_message;
|
||||
};
|
||||
|
||||
} // namespace v16
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V16_TYPES_HPP
|
||||
@@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef V16_UTILS_HPP
|
||||
#define V16_UTILS_HPP
|
||||
|
||||
#include <ocpp/common/call_types.hpp>
|
||||
#include <ocpp/v16/messages/StopTransaction.hpp>
|
||||
#include <ocpp/v16/ocpp_types.hpp>
|
||||
#include <ocpp/v16/types.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ocpp::v16::utils {
|
||||
|
||||
size_t get_message_size(const ocpp::Call<StopTransactionRequest>& call);
|
||||
|
||||
/// \brief Drops every second entry from transactionData as long as the message size of the \p call is greater than the
|
||||
/// \p max_message_size
|
||||
void drop_transaction_data(size_t max_message_size, ocpp::Call<StopTransactionRequest>& call);
|
||||
|
||||
/// \brief Determines if a given \p security_event is critical as defined in the OCPP 1.6 security whitepaper
|
||||
bool is_critical(const std::string& security_event);
|
||||
|
||||
/// \brief split a string into a vector of strings
|
||||
/// \note will contain empty strings where a separator is repeated
|
||||
std::vector<std::string> split_string(char separator, const std::string& csl);
|
||||
|
||||
/// \brief convert a vector into a comma separated list in a string
|
||||
std::string to_csl(const std::vector<std::string>& vec);
|
||||
/// \brief convert a comma separated list in a string to a vector of strings
|
||||
/// \note will not contain empty strings when a comma is repeated
|
||||
std::vector<std::string> from_csl(const std::string& csl);
|
||||
|
||||
/// \brief List that maintains insertion order and prevents duplicates
|
||||
class OrderedUniqueStringList {
|
||||
private:
|
||||
using Store = std::map<std::string, std::size_t>;
|
||||
std::size_t count{0};
|
||||
Store list{};
|
||||
|
||||
void do_insert(std::string&& s);
|
||||
|
||||
public:
|
||||
/// \brief Add to list assuming not a duplicate
|
||||
/// \param s - the string to add
|
||||
void insert(const std::string& s) {
|
||||
do_insert(std::string{s});
|
||||
}
|
||||
/// \brief Add to list assuming not a duplicate
|
||||
/// \param s - the string to add
|
||||
void insert(std::string&& s) {
|
||||
do_insert(std::move(s));
|
||||
}
|
||||
|
||||
/// \brief Clear the list
|
||||
void clear() {
|
||||
count = 0;
|
||||
list.clear();
|
||||
}
|
||||
|
||||
/// \brief obtain an ordered vector of the unique strings
|
||||
std::vector<std::string> get() const;
|
||||
|
||||
/// \brief is the list empty
|
||||
/// \returns true when empty
|
||||
bool empty() const {
|
||||
return list.empty();
|
||||
}
|
||||
|
||||
/// \brief how many strings are in the list
|
||||
/// \returns the size of the list
|
||||
auto size() const {
|
||||
return list.size();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ocpp::v16::utils
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
#include <everest/timer.hpp>
|
||||
#include <ocpp/common/types.hpp>
|
||||
#include <ocpp/v2/ocpp_enums.hpp>
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
#include <ocpp/v2/types.hpp>
|
||||
#include <ocpp/v2/utils.hpp>
|
||||
#include <vector>
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
class AverageMeterValues {
|
||||
|
||||
public:
|
||||
AverageMeterValues() = default;
|
||||
/// @brief Set the meter values into the local object for processing
|
||||
/// @param meter_value MeterValue
|
||||
void set_values(const MeterValue& meter_value);
|
||||
/// @brief retrive the processed values
|
||||
/// @return MeterValue type
|
||||
MeterValue retrieve_processed_values();
|
||||
/// @brief Manually clear the local object meter values
|
||||
void clear_values();
|
||||
|
||||
private:
|
||||
struct MeterValueCalc {
|
||||
double sum;
|
||||
int num_elements;
|
||||
};
|
||||
struct MeterValueMeasurands {
|
||||
MeasurandEnum measurand;
|
||||
std::optional<PhaseEnum> phase; // measurand may or may not have a phase field
|
||||
std::optional<LocationEnum> location; // measurand may or may not have location field
|
||||
|
||||
// Define a comparison operator for the struct
|
||||
bool operator<(const MeterValueMeasurands& other) const {
|
||||
// Using tie here to compare the two lexicographically instead of writing it all out
|
||||
return std::tie(measurand, location, phase) < std::tie(other.measurand, other.location, other.phase);
|
||||
}
|
||||
};
|
||||
|
||||
MeterValue averaged_meter_values;
|
||||
std::mutex avg_meter_value_mutex;
|
||||
std::map<MeterValueMeasurands, MeterValueCalc> aligned_meter_values;
|
||||
void average_meter_value();
|
||||
};
|
||||
} // namespace v2
|
||||
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,709 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <future>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include <ocpp/common/message_dispatcher.hpp>
|
||||
|
||||
#include <ocpp/common/charging_station_base.hpp>
|
||||
|
||||
#include <ocpp/v2/average_meter_values.hpp>
|
||||
#include <ocpp/v2/charge_point_callbacks.hpp>
|
||||
#include <ocpp/v2/ocpp_enums.hpp>
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
#include <ocpp/v2/ocsp_updater.hpp>
|
||||
#include <ocpp/v2/types.hpp>
|
||||
#include <ocpp/v2/utils.hpp>
|
||||
|
||||
#include <ocpp/v2/messages/Authorize.hpp>
|
||||
#include <ocpp/v2/messages/ChangeAvailability.hpp>
|
||||
#include <ocpp/v2/messages/DataTransfer.hpp>
|
||||
#include <ocpp/v2/messages/Get15118EVCertificate.hpp>
|
||||
#include <ocpp/v2/messages/GetCompositeSchedule.hpp>
|
||||
#include <ocpp/v2/messages/NotifyEVChargingNeeds.hpp>
|
||||
|
||||
#include "component_state_manager.hpp"
|
||||
|
||||
namespace ocpp {
|
||||
|
||||
namespace v21 {
|
||||
class DERControlInterface;
|
||||
} // namespace v21
|
||||
|
||||
namespace v2 {
|
||||
|
||||
class AuthorizationInterface;
|
||||
class AvailabilityInterface;
|
||||
class DataTransferInterface;
|
||||
class DiagnosticsInterface;
|
||||
class DisplayMessageInterface;
|
||||
class FirmwareUpdateInterface;
|
||||
class MeterValuesInterface;
|
||||
class ProvisioningInterface;
|
||||
class RemoteTransactionControlInterface;
|
||||
class ReservationInterface;
|
||||
class SecurityInterface;
|
||||
class SmartChargingInterface;
|
||||
class TariffAndCostInterface;
|
||||
class TransactionInterface;
|
||||
class BidirectionalInterface;
|
||||
|
||||
class DatabaseHandler;
|
||||
class DeviceModelAbstract;
|
||||
class DeviceModelStorageInterface;
|
||||
class EvseManager;
|
||||
|
||||
struct FunctionalBlockContext;
|
||||
|
||||
class UnexpectedMessageTypeFromCSMS : public std::runtime_error {
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
/// \brief Interface class for OCPP2.0.1 Charging Station
|
||||
class ChargePointInterface {
|
||||
public:
|
||||
virtual ~ChargePointInterface() = default;
|
||||
|
||||
/// \brief Starts the ChargePoint, initializes and connects to the Websocket endpoint
|
||||
/// \param bootreason Optional bootreason (default: PowerUp).
|
||||
/// \param start_connecting Optional, set to false to initialize but not start connecting. Otherwise will connect to
|
||||
/// the first network profile. (default: true)
|
||||
virtual void start(BootReasonEnum bootreason = BootReasonEnum::PowerUp, bool start_connecting = true) = 0;
|
||||
|
||||
/// \brief Stops the ChargePoint. Disconnects the websocket connection and stops MessageQueue and all timers
|
||||
virtual void stop() = 0;
|
||||
|
||||
/// \brief Initializes the websocket and connects to a CSMS. Provide a network_profile_slot to connect to that
|
||||
/// specific slot.
|
||||
///
|
||||
/// \param network_profile_slot Optional slot to use when connecting. std::nullopt means the slot will be determined
|
||||
/// automatically.
|
||||
virtual void connect_websocket(std::optional<std::int32_t> network_profile_slot = std::nullopt) = 0;
|
||||
|
||||
/// \brief Disconnects the the websocket connection to the CSMS if it is connected
|
||||
virtual void disconnect_websocket() = 0;
|
||||
|
||||
/// \addtogroup ocpp201_handlers OCPP 2.0.1 handlers
|
||||
/// Handlers that can be called from the implementing class
|
||||
/// @{
|
||||
|
||||
/// @name Handlers
|
||||
/// The handlers
|
||||
/// @{
|
||||
|
||||
///
|
||||
/// \brief Shall be called when a websocket connection has been established in case the connectivity_handler is
|
||||
/// provided exernally.
|
||||
/// \param configuration_slot The network profile slot used for the connection.
|
||||
/// \param network_connection_profile The network connection profile used for the connection.
|
||||
virtual void on_websocket_connected(const int configuration_slot,
|
||||
const NetworkConnectionProfile& network_connection_profile,
|
||||
const OcppProtocolVersion ocpp_version) = 0;
|
||||
|
||||
///
|
||||
/// \brief Shall be called when a websocket connection has been disconnected in case the connectivity_handler is
|
||||
/// provided externally.
|
||||
/// \param configuration_slot The network profile slot used for the connection.
|
||||
/// \param network_connection_profile The network connection profile used for the connection.
|
||||
virtual void on_websocket_disconnected(const int configuration_slot,
|
||||
const NetworkConnectionProfile& network_connection_profile) = 0;
|
||||
|
||||
/// \brief Shall be called when a websocket connection attempt has failed in case the connectivity_handler is
|
||||
/// provided externally.
|
||||
/// \param reason The reason why the connection failed.
|
||||
virtual void on_websocket_connection_failed(ConnectionFailedReason reason) = 0;
|
||||
|
||||
///
|
||||
/// \brief Can be called when a network is disconnected, for example when an ethernet cable is removed.
|
||||
///
|
||||
/// This is introduced because the websocket can take several minutes to timeout when a network interface becomes
|
||||
/// unavailable, whereas the system can detect this sooner.
|
||||
///
|
||||
/// \param ocpp_interface The interface that is disconnected.
|
||||
///
|
||||
virtual void on_network_disconnected(OCPPInterfaceEnum ocpp_interface) = 0;
|
||||
|
||||
/// \brief Chargepoint notifies about new firmware update status firmware_update_status. This function should be
|
||||
/// called during a Firmware Update to indicate the current firmware_update_status.
|
||||
/// \param request_id The request_id. When it is -1, it will not be included in the request.
|
||||
/// \param firmware_update_status The firmware_update_status
|
||||
virtual void on_firmware_update_status_notification(std::int32_t request_id,
|
||||
const FirmwareStatusEnum& firmware_update_status) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when a session has started
|
||||
/// \param evse_id
|
||||
/// \param connector_id
|
||||
virtual void on_session_started(const std::int32_t evse_id, const std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when the EV sends a certificate request (for update or installation)
|
||||
/// \param request
|
||||
virtual Get15118EVCertificateResponse
|
||||
on_get_15118_ev_certificate_request(const Get15118EVCertificateRequest& request) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when a transaction has started
|
||||
/// \param evse_id
|
||||
/// \param connector_id
|
||||
/// \param session_id
|
||||
/// \param timestamp
|
||||
/// \param trigger_reason
|
||||
/// \param meter_start
|
||||
/// \param id_token
|
||||
/// \param group_id_token Optional group id token
|
||||
/// \param reservation_id
|
||||
/// \param remote_start_id
|
||||
/// \param charging_state The new charging state
|
||||
virtual void on_transaction_started(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const std::string& session_id, const DateTime& timestamp,
|
||||
const TriggerReasonEnum trigger_reason, const MeterValue& meter_start,
|
||||
const std::optional<IdToken>& id_token,
|
||||
const std::optional<IdToken>& group_id_token,
|
||||
const std::optional<std::int32_t>& reservation_id,
|
||||
const std::optional<std::int32_t>& remote_start_id,
|
||||
const ChargingStateEnum charging_state) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when a transaction has finished
|
||||
/// \param evse_id
|
||||
/// \param timestamp
|
||||
/// \param meter_stop
|
||||
/// \param reason
|
||||
/// \param id_token
|
||||
/// \param signed_meter_value
|
||||
/// \param charging_state
|
||||
virtual void on_transaction_finished(const std::int32_t evse_id, const DateTime& timestamp,
|
||||
const MeterValue& meter_stop, const ReasonEnum reason,
|
||||
const TriggerReasonEnum trigger_reason, const std::optional<IdToken>& id_token,
|
||||
const std::optional<std::string>& signed_meter_value,
|
||||
const ChargingStateEnum charging_state) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when a session has finished
|
||||
/// \param evse_id
|
||||
/// \param connector_id
|
||||
virtual void on_session_finished(const std::int32_t evse_id, const std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when the given \p id_token is authorized
|
||||
virtual void on_authorized(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const IdToken& id_token) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when a new meter value is present
|
||||
/// \param evse_id
|
||||
/// \param meter_value
|
||||
virtual void on_meter_value(const std::int32_t evse_id, const MeterValue& meter_value) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when the connector on the given \p evse_id and \p connector_id
|
||||
/// becomes unavailable
|
||||
virtual void on_unavailable(const std::int32_t evse_id, const std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when the connector returns from unavailable on the given \p evse_id
|
||||
/// and \p connector_id .
|
||||
virtual void on_enabled(const std::int32_t evse_id, const std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when the connector on the given evse_id and connector_id is faulted.
|
||||
/// \param evse_id Faulted EVSE id
|
||||
/// \param connector_id Faulted connector id
|
||||
virtual void on_faulted(const std::int32_t evse_id, const std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when the fault on the connector on the given evse_id is cleared.
|
||||
/// \param evse_id EVSE id where fault was cleared
|
||||
/// \param connector_id Connector id where fault was cleared
|
||||
virtual void on_fault_cleared(const std::int32_t evse_id, const std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when the connector on the given evse_id and connector_id is reserved.
|
||||
/// \param evse_id Reserved EVSE id
|
||||
/// \param connector_id Reserved connector id
|
||||
virtual void on_reserved(const std::int32_t evse_id, const std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when the reservation of the connector is cleared.
|
||||
/// \param evse_id Cleared EVSE id
|
||||
/// \param connector_id Cleared connector id.
|
||||
virtual void on_reservation_cleared(const std::int32_t evse_id, const std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Event handler that will update the charging state internally when it has been changed.
|
||||
/// \param evse_id The evse id of which the charging state has changed.
|
||||
/// \param charging_state The new charging state.
|
||||
/// \param trigger_reason The trigger reason of the event. Defaults to ChargingStateChanged
|
||||
/// \return True on success. False if evse id does not exist.
|
||||
virtual bool
|
||||
on_charging_state_changed(const std::uint32_t evse_id, const ChargingStateEnum charging_state,
|
||||
const TriggerReasonEnum trigger_reason = TriggerReasonEnum::ChargingStateChanged) = 0;
|
||||
|
||||
/// \brief Event handler that will update the charging station availability
|
||||
/// \param request The request
|
||||
/// \return returns a ChangeAvailabilityResponse
|
||||
virtual ChangeAvailabilityResponse on_change_availability(const ChangeAvailabilityRequest& request) = 0;
|
||||
|
||||
/// \brief Gets the transaction id for a certain \p evse_id if there is an active transaction
|
||||
/// \param evse_id The evse to get the transaction for
|
||||
/// \return The transaction id if a transaction is active, otherwise nullopt
|
||||
virtual std::optional<std::string> get_evse_transaction_id(std::int32_t evse_id) = 0;
|
||||
|
||||
/// \brief Event handler that can be called to trigger a NotifyEvent.req with the given \p events
|
||||
/// \param events
|
||||
virtual void on_event(const std::vector<EventData>& events) = 0;
|
||||
|
||||
///
|
||||
/// \brief Event handler that can be called to notify about the log status.
|
||||
///
|
||||
/// This function should be called curing a Diagnostics / Log upload to indicate the current log status.
|
||||
///
|
||||
/// \param status Log status.
|
||||
/// \param requestId Request id that was provided in GetLogRequest.
|
||||
///
|
||||
virtual void on_log_status_notification(UploadLogStatusEnum status, std::int32_t requestId) = 0;
|
||||
|
||||
// \brief Notifies chargepoint that a SecurityEvent has occured. This will send a SecurityEventNotification.req to
|
||||
// the
|
||||
/// CSMS
|
||||
/// \param type type of the security event
|
||||
/// \param tech_info additional info of the security event
|
||||
/// \param critical if set this overwrites the default criticality recommended in the OCPP 2.0.1 appendix. A
|
||||
/// critical security event is transmitted as a message to the CSMS, a non-critical one is just written to the
|
||||
/// security log
|
||||
/// \param timestamp when this security event occured, if absent the current datetime is assumed
|
||||
virtual void on_security_event(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
|
||||
const std::optional<bool>& critical = std::nullopt,
|
||||
const std::optional<DateTime>& timestamp = std::nullopt) = 0;
|
||||
|
||||
/// \brief Event handler that will update the variable internally when it has been changed on the fly.
|
||||
/// \param set_variable_data contains data of the variable to set
|
||||
///
|
||||
virtual void on_variable_changed(const SetVariableData& set_variable_data) = 0;
|
||||
|
||||
/// \brief Event handler that will send a ReservationStatusUpdate request.
|
||||
/// \param reservation_id The reservation id.
|
||||
/// \param status The status.
|
||||
virtual void on_reservation_status(const std::int32_t reservation_id, const ReservationUpdateStatusEnum status) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when the charging station receives a ChargeParameterDiscoveryReq from
|
||||
/// the CSMS \param request specifies the parameters sent from the EV to the charging station
|
||||
virtual void on_ev_charging_needs(const NotifyEVChargingNeedsRequest& request) = 0;
|
||||
|
||||
/// @} // End handlers group
|
||||
|
||||
/// @}
|
||||
|
||||
/// \brief Validates provided \p id_token \p certificate and \p ocsp_request_data using CSMS, AuthCache or AuthList
|
||||
/// \param id_token
|
||||
/// \param certificate
|
||||
/// \param ocsp_request_data
|
||||
/// \return AuthorizeResponse containing the result of the validation
|
||||
virtual AuthorizeResponse validate_token(const IdToken id_token, const std::optional<CiString<10000>>& certificate,
|
||||
const std::optional<std::vector<OCSPRequestData>>& ocsp_request_data) = 0;
|
||||
|
||||
/// \brief Data transfer mechanism initiated by charger
|
||||
/// \param vendorId
|
||||
/// \param messageId
|
||||
/// \param data
|
||||
/// \return DataTransferResponse containing the result from CSMS
|
||||
virtual std::optional<DataTransferResponse> data_transfer_req(const CiString<255>& vendorId,
|
||||
const std::optional<CiString<50>>& messageId,
|
||||
const std::optional<json>& data) = 0;
|
||||
|
||||
/// \brief Data transfer mechanism initiated by charger
|
||||
/// \param request
|
||||
/// \return DataTransferResponse containing the result from CSMS. In case no response is received from the CSMS
|
||||
/// because the message timed out or the charging station is offline, std::nullopt is returned
|
||||
virtual std::optional<DataTransferResponse> data_transfer_req(const DataTransferRequest& request) = 0;
|
||||
|
||||
/// \brief Delay draining the message queue after reconnecting, so the CSMS can perform post-reconnect checks first
|
||||
/// \param delay The delay period (seconds)
|
||||
virtual void set_message_queue_resume_delay(std::chrono::seconds delay) = 0;
|
||||
|
||||
/// \brief Gets variables specified within \p get_variable_data_vector from the device model and returns the result.
|
||||
/// This function is used internally in order to handle GetVariables.req messages and it can be used to get
|
||||
/// variables externally.
|
||||
/// \param get_variable_data_vector contains data of the variables to get
|
||||
/// \return Vector containing a result for each requested variable
|
||||
virtual std::vector<GetVariableResult>
|
||||
get_variables(const std::vector<GetVariableData>& get_variable_data_vector) = 0;
|
||||
|
||||
/// \brief Sets variables specified within \p set_variable_data_vector in the device model and returns the result.
|
||||
/// \param set_variable_data_vector contains data of the variables to set
|
||||
/// \return Map containing the SetVariableData as a key and the SetVariableResult as a value for each requested
|
||||
/// change
|
||||
virtual std::map<SetVariableData, SetVariableResult>
|
||||
set_variables(const std::vector<SetVariableData>& set_variable_data_vector, const std::string& source) = 0;
|
||||
|
||||
/// \brief Registers a listener for variable changes
|
||||
/// \param listener The listener function to register
|
||||
virtual void register_variable_listener(
|
||||
std::function<void(const std::unordered_map<std::int64_t, VariableMonitoringMeta>& monitors,
|
||||
const Component& component, const Variable& variable,
|
||||
const VariableCharacteristics& characteristics, const VariableAttribute& attribute,
|
||||
const std::string& value_previous, const std::string& value_current)>&& listener) = 0;
|
||||
|
||||
/// \brief Gets a composite schedule based on the given \p request
|
||||
/// \param request specifies different options for the request
|
||||
/// \return EnhancedCompositeScheduleResponse containing the status of the operation and the composite schedule if
|
||||
/// the operation was successful
|
||||
virtual EnhancedCompositeScheduleResponse get_composite_schedule(const GetCompositeScheduleRequest& request) = 0;
|
||||
|
||||
/// \brief Gets a composite schedule based on the given parameters.
|
||||
/// \note This will ignore TxDefaultProfiles and TxProfiles if no transaction is active on \p evse_id
|
||||
/// \param evse_id Evse to get the schedule for
|
||||
/// \param duration How long the schedule should be
|
||||
/// \param unit ChargingRateUnit to thet the schedule for
|
||||
/// \return the composite schedule if the operation was successful, otherwise nullopt
|
||||
virtual std::optional<EnhancedCompositeSchedule>
|
||||
get_composite_schedule(std::int32_t evse_id, std::chrono::seconds duration, ChargingRateUnitEnum unit) = 0;
|
||||
|
||||
/// \brief Gets composite schedules for all evse_ids (including 0) for the given \p duration and \p unit . If no
|
||||
/// valid profiles are given for an evse for the specified period, the composite schedule will be empty for this
|
||||
/// evse.
|
||||
/// \param duration of the request from. Composite schedules will be retrieved from now to (now + duration)
|
||||
/// \param unit of the period entries of the composite schedules
|
||||
/// \return vector of composite schedules, one for each evse_id including 0.
|
||||
virtual std::vector<EnhancedCompositeSchedule> get_all_composite_schedules(const std::int32_t duration,
|
||||
const ChargingRateUnitEnum& unit) = 0;
|
||||
|
||||
/// \brief Gets the configured NetworkConnectionProfile based on the given \p configuration_slot . The
|
||||
/// central system uri of the connection options will not contain ws:// or wss:// because this method removes it if
|
||||
/// present. This returns the value from the cached network connection profiles. \param
|
||||
/// network_configuration_priority \return
|
||||
virtual std::optional<NetworkConnectionProfile>
|
||||
get_network_connection_profile(const std::int32_t configuration_slot) const = 0;
|
||||
|
||||
/// \brief Get the priority of the given configuration slot.
|
||||
/// \param configuration_slot The configuration slot to get the priority from.
|
||||
/// \return The priority if the configuration slot exists.
|
||||
///
|
||||
virtual std::optional<int> get_priority_from_configuration_slot(const int configuration_slot) const = 0;
|
||||
|
||||
/// @brief Get a snapshot of the network connection slots sorted by priority.
|
||||
/// Each item in the vector contains the configured configuration slots, where the slot with index 0 has the highest
|
||||
/// priority. A copy is returned (rather than a const reference) so callers do not observe mid-mutation state once
|
||||
/// the underlying ConnectivityManager monitor handle has been released.
|
||||
/// @return The network connection slots
|
||||
///
|
||||
virtual std::vector<int> get_network_connection_slots() const = 0;
|
||||
};
|
||||
|
||||
/// \brief Class implements OCPP2.0.1 Charging Station
|
||||
class ChargePoint : public ChargePointInterface, private ocpp::ChargingStationBase {
|
||||
|
||||
private:
|
||||
std::shared_ptr<DeviceModelAbstract> device_model;
|
||||
std::unique_ptr<EvseManager> evse_manager;
|
||||
std::shared_ptr<ConnectivityManagerInterface> connectivity_manager;
|
||||
|
||||
std::unique_ptr<MessageDispatcherInterface<MessageType>> message_dispatcher;
|
||||
|
||||
// Functional blocks
|
||||
std::unique_ptr<FunctionalBlockContext> functional_block_context;
|
||||
std::unique_ptr<DataTransferInterface> data_transfer;
|
||||
std::unique_ptr<ReservationInterface> reservation;
|
||||
std::unique_ptr<AvailabilityInterface> availability;
|
||||
std::unique_ptr<AuthorizationInterface> authorization;
|
||||
std::unique_ptr<DiagnosticsInterface> diagnostics;
|
||||
std::unique_ptr<SecurityInterface> security;
|
||||
std::unique_ptr<DisplayMessageInterface> display_message;
|
||||
std::unique_ptr<FirmwareUpdateInterface> firmware_update;
|
||||
std::unique_ptr<MeterValuesInterface> meter_values;
|
||||
std::unique_ptr<SmartChargingInterface> smart_charging;
|
||||
std::unique_ptr<TariffAndCostInterface> tariff_and_cost;
|
||||
std::unique_ptr<TransactionInterface> transaction;
|
||||
std::unique_ptr<ProvisioningInterface> provisioning;
|
||||
std::unique_ptr<RemoteTransactionControlInterface> remote_transaction_control;
|
||||
std::unique_ptr<BidirectionalInterface> bidirectional;
|
||||
std::unique_ptr<v21::DERControlInterface> der_control;
|
||||
|
||||
// utility
|
||||
std::shared_ptr<MessageQueue<v2::MessageType>> message_queue;
|
||||
std::shared_ptr<DatabaseHandler> database_handler;
|
||||
fs::path share_path;
|
||||
|
||||
// states
|
||||
std::atomic<RegistrationStatusEnum> registration_status{RegistrationStatusEnum::Rejected};
|
||||
std::atomic<OcppProtocolVersion> ocpp_version{
|
||||
OcppProtocolVersion::Unknown}; // version that is currently in use, selected by CSMS in websocket handshake
|
||||
std::atomic<UploadLogStatusEnum> upload_log_status{UploadLogStatusEnum::Idle};
|
||||
std::atomic<std::int32_t> upload_log_status_id;
|
||||
BootReasonEnum bootreason{BootReasonEnum::PowerUp};
|
||||
bool skip_invalid_csms_certificate_notifications{false};
|
||||
|
||||
/// \brief Component responsible for maintaining and persisting the operational status of CS, EVSEs, and connectors.
|
||||
std::shared_ptr<ComponentStateManagerInterface> component_state_manager;
|
||||
|
||||
// store the connector status
|
||||
struct EvseConnectorPair {
|
||||
std::int32_t evse_id;
|
||||
std::int32_t connector_id;
|
||||
|
||||
// Define a comparison operator for the struct
|
||||
bool operator<(const EvseConnectorPair& other) const {
|
||||
// Compare based on name, then age
|
||||
if (evse_id != other.evse_id) {
|
||||
return evse_id < other.evse_id;
|
||||
}
|
||||
return connector_id < other.connector_id;
|
||||
}
|
||||
};
|
||||
|
||||
// callback struct
|
||||
Callbacks callbacks;
|
||||
|
||||
/// \brief Handler for automatic or explicit OCSP cache updates
|
||||
OcspUpdater ocsp_updater;
|
||||
|
||||
/// \brief optional delay to resumption of message queue after reconnecting to the CSMS
|
||||
std::chrono::seconds message_queue_resume_delay = std::chrono::seconds(0);
|
||||
|
||||
// internal helper functions
|
||||
void initialize(const std::map<std::int32_t, std::int32_t>& evse_connector_structure,
|
||||
const std::string& message_log_path);
|
||||
OcspUpdater make_ocsp_updater();
|
||||
void update_dm_availability_state(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const ConnectorStatusEnum status);
|
||||
|
||||
void message_callback(const std::string& message);
|
||||
|
||||
/// \brief Get the value optional offline flag
|
||||
/// \return true if the charge point is offline. std::nullopt if it is online;
|
||||
bool is_offline();
|
||||
|
||||
/// @brief Configure the message logging callback with device model parameters
|
||||
/// @param message_log_path path to file logging
|
||||
void configure_message_logging_format(const std::string& message_log_path);
|
||||
|
||||
/* OCPP message requests */
|
||||
|
||||
/* OCPP message handlers */
|
||||
|
||||
// Generates async sending callbacks
|
||||
template <class RequestType, class ResponseType>
|
||||
std::function<ResponseType(RequestType)> send_callback(MessageType expected_response_message_type) {
|
||||
return [this, expected_response_message_type](auto request) {
|
||||
const auto enhanced_response =
|
||||
this->message_dispatcher->dispatch_call_async(ocpp::Call<RequestType>(request)).get();
|
||||
if (enhanced_response.messageType != expected_response_message_type) {
|
||||
throw UnexpectedMessageTypeFromCSMS(
|
||||
std::string("Got unexpected message type from CSMS, expected: ") +
|
||||
conversions::messagetype_to_string(expected_response_message_type) +
|
||||
", got: " + conversions::messagetype_to_string(enhanced_response.messageType));
|
||||
}
|
||||
const ocpp::CallResult<ResponseType> call_result = enhanced_response.message;
|
||||
return call_result.msg;
|
||||
};
|
||||
}
|
||||
|
||||
protected:
|
||||
void handle_message(const EnhancedMessage<v2::MessageType>& message);
|
||||
void clear_invalid_charging_profiles();
|
||||
|
||||
public:
|
||||
/// \addtogroup chargepoint_constructors
|
||||
/// @{
|
||||
|
||||
/// @name Constructors for 2.0.1
|
||||
/// @{
|
||||
|
||||
/// \brief Construct a new ChargePoint object
|
||||
/// \param evse_connector_structure Map that defines the structure of EVSE and connectors of the chargepoint. The
|
||||
/// key represents the id of the EVSE and the value represents the number of connectors for this EVSE. The ids of
|
||||
/// the EVSEs have to increment starting with 1.
|
||||
/// \param device_model device model instance
|
||||
/// \param database_handler database handler instance
|
||||
/// \param evse_security Pointer to evse_security that manages security related operations
|
||||
/// \param connectivity_manager connectivity manager instance
|
||||
/// \param message_log_path Path to where logfiles are written to
|
||||
/// \param callbacks Callbacks that will be registered for ChargePoint
|
||||
ChargePoint(const std::map<int32_t, int32_t>& evse_connector_structure,
|
||||
const std::shared_ptr<DeviceModelAbstract> device_model,
|
||||
const std::shared_ptr<DatabaseHandler> database_handler,
|
||||
const std::shared_ptr<EvseSecurity> evse_security,
|
||||
const std::shared_ptr<ConnectivityManagerInterface> connectivity_manager,
|
||||
const std::string& message_log_path, const Callbacks& callbacks);
|
||||
|
||||
/// \brief Construct a new ChargePoint object
|
||||
/// \param evse_connector_structure Map that defines the structure of EVSE and connectors of the chargepoint. The
|
||||
/// key represents the id of the EVSE and the value represents the number of connectors for this EVSE. The ids of
|
||||
/// the EVSEs have to increment starting with 1.
|
||||
/// \param device_model device model instance
|
||||
/// \param database_handler database handler instance
|
||||
/// \param message_queue message queue instance
|
||||
/// \param message_log_path Path to where logfiles are written to
|
||||
/// \param evse_security Pointer to evse_security that manages security related operations
|
||||
/// \param callbacks Callbacks that will be registered for ChargePoint
|
||||
/// \param share_path Path where utility files for OCPP are read and written to
|
||||
ChargePoint(const std::map<std::int32_t, std::int32_t>& evse_connector_structure,
|
||||
std::shared_ptr<DeviceModelAbstract> device_model, std::shared_ptr<DatabaseHandler> database_handler,
|
||||
std::shared_ptr<MessageQueue<v2::MessageType>> message_queue, const std::string& message_log_path,
|
||||
const std::shared_ptr<EvseSecurity> evse_security, const Callbacks& callbacks,
|
||||
const fs::path& share_path = {});
|
||||
|
||||
/// \brief Construct a new ChargePoint object
|
||||
/// \param evse_connector_structure Map that defines the structure of EVSE and connectors of the chargepoint. The
|
||||
/// key represents the id of the EVSE and the value represents the number of connectors for this EVSE. The ids of
|
||||
/// the EVSEs have to increment starting with 1.
|
||||
/// \param device_model_storage_interface device model interface instance
|
||||
/// \param ocpp_main_path Path where utility files for OCPP are read and written to
|
||||
/// \param core_database_path Path to directory where core database is located
|
||||
/// \param message_log_path Path to where logfiles are written to
|
||||
/// \param evse_security Pointer to evse_security that manages security related operations
|
||||
/// \param callbacks Callbacks that will be registered for ChargePoint
|
||||
ChargePoint(const std::map<std::int32_t, std::int32_t>& evse_connector_structure,
|
||||
std::unique_ptr<DeviceModelStorageInterface> device_model_storage_interface,
|
||||
const std::string& ocpp_main_path, const std::string& core_database_path,
|
||||
const std::string& sql_init_path, const std::string& message_log_path,
|
||||
const std::shared_ptr<EvseSecurity> evse_security, const Callbacks& callbacks);
|
||||
|
||||
/// \brief Construct a new ChargePoint object
|
||||
/// \param evse_connector_structure Map that defines the structure of EVSE and connectors of the chargepoint. The
|
||||
/// key represents the id of the EVSE and the value represents the number of connectors for this EVSE. The ids of
|
||||
/// the EVSEs have to increment starting with 1.
|
||||
/// \param device_model_storage_address address to device model storage (e.g. location of SQLite database)
|
||||
/// \param device_model_migration_path Path to the device model database migration files
|
||||
/// \param device_model_config_path Path to the device model config
|
||||
/// \param ocpp_main_path Path where utility files for OCPP are read and written to
|
||||
/// \param core_database_path Path to directory where core database is located
|
||||
/// \param message_log_path Path to where logfiles are written to
|
||||
/// \param evse_security Pointer to evse_security that manages security related operations; if nullptr
|
||||
/// security_configuration must be set
|
||||
/// \param callbacks Callbacks that will be registered for ChargePoint
|
||||
ChargePoint(const std::map<std::int32_t, std::int32_t>& evse_connector_structure,
|
||||
const std::string& device_model_storage_address, const std::string& device_model_migration_path,
|
||||
const std::string& device_model_config_path, const std::string& ocpp_main_path,
|
||||
const std::string& core_database_path, const std::string& sql_init_path,
|
||||
const std::string& message_log_path, const std::shared_ptr<EvseSecurity> evse_security,
|
||||
const Callbacks& callbacks);
|
||||
|
||||
/// @} // End chargepoint 2.0.1 member group
|
||||
|
||||
/// @} // End chargepoint 2.0.1 topic
|
||||
|
||||
~ChargePoint() override;
|
||||
|
||||
void start(BootReasonEnum bootreason = BootReasonEnum::PowerUp, bool start_connecting = true) override;
|
||||
|
||||
void stop() override;
|
||||
|
||||
void connect_websocket(std::optional<std::int32_t> network_profile_slot = std::nullopt) override;
|
||||
void disconnect_websocket() override;
|
||||
|
||||
void on_websocket_connected(const int configuration_slot,
|
||||
const NetworkConnectionProfile& network_connection_profile,
|
||||
const OcppProtocolVersion ocpp_version) override;
|
||||
void on_websocket_disconnected(const int configuration_slot,
|
||||
const NetworkConnectionProfile& network_connection_profile) override;
|
||||
void on_websocket_connection_failed(ConnectionFailedReason reason) override;
|
||||
void on_network_disconnected(OCPPInterfaceEnum ocpp_interface) override;
|
||||
|
||||
void on_firmware_update_status_notification(std::int32_t request_id,
|
||||
const FirmwareStatusEnum& firmware_update_status) override;
|
||||
|
||||
void on_session_started(const std::int32_t evse_id, const std::int32_t connector_id) override;
|
||||
|
||||
Get15118EVCertificateResponse
|
||||
on_get_15118_ev_certificate_request(const Get15118EVCertificateRequest& request) override;
|
||||
|
||||
void on_transaction_started(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const std::string& session_id, const DateTime& timestamp,
|
||||
const TriggerReasonEnum trigger_reason, const MeterValue& meter_start,
|
||||
const std::optional<IdToken>& id_token, const std::optional<IdToken>& group_id_token,
|
||||
const std::optional<std::int32_t>& reservation_id,
|
||||
const std::optional<std::int32_t>& remote_start_id,
|
||||
const ChargingStateEnum charging_state) override;
|
||||
|
||||
void on_transaction_finished(const std::int32_t evse_id, const DateTime& timestamp, const MeterValue& meter_stop,
|
||||
const ReasonEnum reason, const TriggerReasonEnum trigger_reason,
|
||||
const std::optional<IdToken>& id_token,
|
||||
const std::optional<std::string>& signed_meter_value,
|
||||
const ChargingStateEnum charging_state) override;
|
||||
|
||||
void on_session_finished(const std::int32_t evse_id, const std::int32_t connector_id) override;
|
||||
|
||||
void on_authorized(const std::int32_t evse_id, const std::int32_t connector_id, const IdToken& id_token) override;
|
||||
|
||||
void on_meter_value(const std::int32_t evse_id, const MeterValue& meter_value) override;
|
||||
|
||||
void on_unavailable(const std::int32_t evse_id, const std::int32_t connector_id) override;
|
||||
|
||||
void on_enabled(const std::int32_t evse_id, const std::int32_t connector_id) override;
|
||||
|
||||
void on_faulted(const std::int32_t evse_id, const std::int32_t connector_id) override;
|
||||
|
||||
void on_fault_cleared(const std::int32_t evse_id, const std::int32_t connector_id) override;
|
||||
|
||||
void on_reserved(const std::int32_t evse_id, const std::int32_t connector_id) override;
|
||||
|
||||
void on_reservation_cleared(const std::int32_t evse_id, const std::int32_t connector_id) override;
|
||||
|
||||
bool on_charging_state_changed(
|
||||
const std::uint32_t evse_id, const ChargingStateEnum charging_state,
|
||||
const TriggerReasonEnum trigger_reason = TriggerReasonEnum::ChargingStateChanged) override;
|
||||
|
||||
ChangeAvailabilityResponse on_change_availability(const ChangeAvailabilityRequest& request) override;
|
||||
|
||||
std::optional<std::string> get_evse_transaction_id(std::int32_t evse_id) override;
|
||||
|
||||
AuthorizeResponse validate_token(const IdToken id_token, const std::optional<CiString<10000>>& certificate,
|
||||
const std::optional<std::vector<OCSPRequestData>>& ocsp_request_data) override;
|
||||
|
||||
void on_event(const std::vector<EventData>& events) override;
|
||||
|
||||
void on_log_status_notification(UploadLogStatusEnum status, std::int32_t requestId) override;
|
||||
|
||||
void on_security_event(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info,
|
||||
const std::optional<bool>& critical = std::nullopt,
|
||||
const std::optional<DateTime>& timestamp = std::nullopt) override;
|
||||
|
||||
void on_variable_changed(const SetVariableData& set_variable_data) override;
|
||||
|
||||
void on_reservation_status(const std::int32_t reservation_id, const ReservationUpdateStatusEnum status) override;
|
||||
|
||||
void on_ev_charging_needs(const NotifyEVChargingNeedsRequest& request) override;
|
||||
|
||||
std::optional<DataTransferResponse> data_transfer_req(const CiString<255>& vendorId,
|
||||
const std::optional<CiString<50>>& messageId,
|
||||
const std::optional<json>& data) override;
|
||||
|
||||
std::optional<DataTransferResponse> data_transfer_req(const DataTransferRequest& request) override;
|
||||
|
||||
void set_message_queue_resume_delay(std::chrono::seconds delay) override {
|
||||
this->message_queue_resume_delay = delay;
|
||||
}
|
||||
|
||||
std::vector<GetVariableResult> get_variables(const std::vector<GetVariableData>& get_variable_data_vector) override;
|
||||
|
||||
std::map<SetVariableData, SetVariableResult>
|
||||
set_variables(const std::vector<SetVariableData>& set_variable_data_vector, const std::string& source) override;
|
||||
void register_variable_listener(
|
||||
std::function<void(const std::unordered_map<std::int64_t, VariableMonitoringMeta>& monitors,
|
||||
const Component& component, const Variable& variable,
|
||||
const VariableCharacteristics& characteristics, const VariableAttribute& attribute,
|
||||
const std::string& value_previous, const std::string& value_current)>&& listener) override;
|
||||
EnhancedCompositeScheduleResponse get_composite_schedule(const GetCompositeScheduleRequest& request) override;
|
||||
std::optional<EnhancedCompositeSchedule> get_composite_schedule(std::int32_t evse_id, std::chrono::seconds duration,
|
||||
ChargingRateUnitEnum unit) override;
|
||||
std::vector<EnhancedCompositeSchedule> get_all_composite_schedules(const std::int32_t duration,
|
||||
const ChargingRateUnitEnum& unit) override;
|
||||
|
||||
std::optional<NetworkConnectionProfile>
|
||||
get_network_connection_profile(const std::int32_t configuration_slot) const override;
|
||||
|
||||
std::optional<int> get_priority_from_configuration_slot(const int configuration_slot) const override;
|
||||
|
||||
std::vector<int> get_network_connection_slots() const override;
|
||||
|
||||
void send_not_implemented_error(const MessageId unique_message_id, const MessageTypeId message_type_id);
|
||||
|
||||
/// \brief Requests a value of a VariableAttribute specified by combination of \p component_id and \p variable_id
|
||||
/// from the device model
|
||||
/// \tparam T datatype of the value that is requested
|
||||
/// \param component_id
|
||||
/// \param variable_id
|
||||
/// \param attribute_enum
|
||||
/// \return Response to request that contains status of the request and the requested value as std::optional<T> .
|
||||
/// The value is present if the status is GetVariableStatusEnum::Accepted
|
||||
template <typename T>
|
||||
RequestDeviceModelResponse<T> request_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum) {
|
||||
return this->device_model->request_value<T>(component_id, variable_id, attribute_enum);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,194 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include <ocpp/common/connectivity_manager.hpp>
|
||||
#include <ocpp/v2/device_model.hpp>
|
||||
|
||||
#include <ocpp/v2/messages/BootNotification.hpp>
|
||||
#include <ocpp/v2/messages/ClearDisplayMessage.hpp>
|
||||
#include <ocpp/v2/messages/DataTransfer.hpp>
|
||||
#include <ocpp/v2/messages/GetDisplayMessages.hpp>
|
||||
#include <ocpp/v2/messages/GetLog.hpp>
|
||||
#include <ocpp/v2/messages/RequestStartTransaction.hpp>
|
||||
#include <ocpp/v2/messages/ReserveNow.hpp>
|
||||
#include <ocpp/v2/messages/SetDisplayMessage.hpp>
|
||||
#include <ocpp/v2/messages/TransactionEvent.hpp>
|
||||
#include <ocpp/v2/messages/UnlockConnector.hpp>
|
||||
#include <ocpp/v2/messages/UpdateFirmware.hpp>
|
||||
|
||||
namespace ocpp::v2 {
|
||||
struct Callbacks {
|
||||
/// @addtogroup ocpp201_callbacks OCPP 2.0.1 callbacks
|
||||
/// Callbacks will call be called when necessary and must be implemented by the calling class.
|
||||
/// @{
|
||||
|
||||
/// @name Callbacks
|
||||
/// Callbacks
|
||||
/// @{
|
||||
|
||||
/// \brief Function to check if the callback struct is completely filled. All std::functions should hold a function,
|
||||
/// all std::optional<std::functions> should either be empty or hold a function.
|
||||
/// \param device_model The device model, to check if certain modules are enabled / available.
|
||||
/// \param evse_connector_structure The evse_connector_structure is used to check variables for specific evse and/or
|
||||
/// connector
|
||||
///
|
||||
/// \retval false if any of the normal callbacks are nullptr or any of the optional ones are filled with a nullptr
|
||||
/// true otherwise
|
||||
bool all_callbacks_valid(std::shared_ptr<DeviceModelAbstract> device_model,
|
||||
const std::map<std::int32_t, std::int32_t>& evse_connector_structure) const;
|
||||
|
||||
///
|
||||
/// \brief Callback if reset is allowed. If evse_id has a value, reset only applies to the given evse id. If it has
|
||||
/// no value, applies to complete charging station.
|
||||
///
|
||||
std::function<bool(const std::optional<const std::int32_t> evse_id, const ResetEnum& reset_type)>
|
||||
is_reset_allowed_callback;
|
||||
std::function<void(const std::optional<const std::int32_t> evse_id, const ResetEnum& reset_type)> reset_callback;
|
||||
std::function<RequestStartStopStatusEnum(const std::int32_t evse_id, const ReasonEnum& stop_reason)>
|
||||
stop_transaction_callback;
|
||||
std::function<void(const std::int32_t evse_id)> pause_charging_callback;
|
||||
|
||||
/// \brief Used to notify the user of libocpp that the Operative/Inoperative state of the charging station changed
|
||||
/// If as a result the state of EVSEs or connectors changed as well, libocpp will additionally call the
|
||||
/// evse_effective_operative_status_changed_callback once for each EVSE whose status changed, and
|
||||
/// connector_effective_operative_status_changed_callback once for each connector whose status changed.
|
||||
/// If left empty, the callback is ignored.
|
||||
/// \param new_status The operational status the CS switched to
|
||||
std::optional<std::function<void(const OperationalStatusEnum new_status)>>
|
||||
cs_effective_operative_status_changed_callback;
|
||||
|
||||
/// \brief Used to notify the user of libocpp that the Operative/Inoperative state of an EVSE changed
|
||||
/// If as a result the state of connectors changed as well, libocpp will additionally call the
|
||||
/// connector_effective_operative_status_changed_callback once for each connector whose status changed.
|
||||
/// If left empty, the callback is ignored.
|
||||
/// \param evse_id The id of the EVSE
|
||||
/// \param new_status The operational status the EVSE switched to
|
||||
std::optional<std::function<void(const std::int32_t evse_id, const OperationalStatusEnum new_status)>>
|
||||
evse_effective_operative_status_changed_callback;
|
||||
|
||||
/// \brief Used to notify the user of libocpp that the Operative/Inoperative state of a connector changed.
|
||||
/// \param evse_id The id of the EVSE
|
||||
/// \param connector_id The ID of the connector within the EVSE
|
||||
/// \param new_status The operational status the connector switched to
|
||||
std::function<void(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const OperationalStatusEnum new_status)>
|
||||
connector_effective_operative_status_changed_callback;
|
||||
|
||||
std::function<GetLogResponse(const GetLogRequest& request)> get_log_request_callback;
|
||||
std::function<UnlockConnectorResponse(const std::int32_t evse_id, const std::int32_t connecor_id)>
|
||||
unlock_connector_callback;
|
||||
// callback to be called when the request can be accepted. authorize_remote_start indicates if Authorize.req needs
|
||||
// to follow or not
|
||||
std::function<RequestStartStopStatusEnum(const RequestStartTransactionRequest& request,
|
||||
const bool authorize_remote_start)>
|
||||
remote_start_transaction_callback;
|
||||
|
||||
///
|
||||
/// \brief Check if the current reservation for the given evse id is made for the id token / group id token.
|
||||
/// \return The reservation check status of this evse / id token.
|
||||
///
|
||||
std::function<ocpp::ReservationCheckStatus(const std::int32_t evse_id, const CiString<255> idToken,
|
||||
const std::optional<CiString<255>> groupIdToken)>
|
||||
is_reservation_for_token_callback;
|
||||
std::function<UpdateFirmwareResponse(const UpdateFirmwareRequest& request)> update_firmware_request_callback;
|
||||
// callback to be called when a variable has been changed by the CSMS
|
||||
std::optional<std::function<void(const SetVariableData& set_variable_data)>> variable_changed_callback;
|
||||
// callback is called when receiving a SetNetworkProfile.req from the CSMS
|
||||
std::optional<std::function<SetNetworkProfileStatusEnum(
|
||||
const std::int32_t configuration_slot, const NetworkConnectionProfile& network_connection_profile)>>
|
||||
validate_network_profile_callback;
|
||||
std::optional<ConfigureNetworkConnectionProfileCallback> configure_network_connection_profile_callback;
|
||||
std::optional<std::function<void(const ocpp::DateTime& currentTime)>> time_sync_callback;
|
||||
|
||||
/// \brief Callback function is called when a OCPP message is sent or received
|
||||
std::optional<std::function<void(const std::string& message, MessageDirection direction)>> ocpp_messages_callback;
|
||||
|
||||
///
|
||||
/// \brief callback function that can be used to react to a security event callback. This callback is
|
||||
/// called only if the SecurityEvent occured internally within libocpp
|
||||
/// Typically this callback is used to log security events in the security log
|
||||
///
|
||||
std::function<void(const CiString<50>& event_type, const std::optional<CiString<255>>& tech_info)>
|
||||
security_event_callback;
|
||||
|
||||
/// \brief Callback for indicating when a charging profile is received and was accepted.
|
||||
std::function<void()> set_charging_profiles_callback;
|
||||
|
||||
/// \brief Callback for when a bootnotification response is received
|
||||
std::optional<std::function<void(const ocpp::v2::BootNotificationResponse& boot_notification_response)>>
|
||||
boot_notification_callback;
|
||||
|
||||
/// \brief Callback function that can be used to get (human readable) customer information based on the given
|
||||
/// arguments
|
||||
std::optional<std::function<std::string(const std::optional<CertificateHashDataType> customer_certificate,
|
||||
const std::optional<IdToken> id_token,
|
||||
const std::optional<CiString<64>> customer_identifier)>>
|
||||
get_customer_information_callback;
|
||||
|
||||
/// \brief Callback function that can be called to clear customer information based on the given arguments
|
||||
std::optional<std::function<void(const std::optional<CertificateHashDataType> customer_certificate,
|
||||
const std::optional<IdToken> id_token,
|
||||
const std::optional<CiString<64>> customer_identifier)>>
|
||||
clear_customer_information_callback;
|
||||
|
||||
/// \brief Callback function that can be called when all connectors are unavailable
|
||||
std::optional<std::function<void()>> all_connectors_unavailable_callback;
|
||||
|
||||
/// \brief Callback function that can be used to handle arbitrary data transfers for all vendorId and
|
||||
/// messageId
|
||||
std::optional<std::function<DataTransferResponse(const DataTransferRequest& request)>> data_transfer_callback;
|
||||
|
||||
/// \brief Callback function that is called when a transaction_event was sent to the CSMS
|
||||
std::optional<std::function<void(const TransactionEventRequest& transaction_event)>> transaction_event_callback;
|
||||
|
||||
/// \brief Callback function that is called when a transaction_event_response was received from the CSMS
|
||||
std::optional<std::function<void(const TransactionEventRequest& transaction_event,
|
||||
const TransactionEventResponse& transaction_event_response)>>
|
||||
transaction_event_response_callback;
|
||||
|
||||
/// \brief Callback function is called when the websocket connection status changes
|
||||
std::optional<std::function<void(const bool is_connected, const int configuration_slot,
|
||||
const NetworkConnectionProfile& network_connection_profile,
|
||||
const OcppProtocolVersion ocpp_version)>>
|
||||
connection_state_changed_callback;
|
||||
|
||||
/// \brief Callback functions called for get / set / clear display messages
|
||||
std::optional<std::function<std::vector<DisplayMessage>(const GetDisplayMessagesRequest& request)>>
|
||||
get_display_message_callback;
|
||||
std::optional<std::function<SetDisplayMessageResponse(const std::vector<DisplayMessage>& display_messages)>>
|
||||
set_display_message_callback;
|
||||
std::optional<std::function<ClearDisplayMessageResponse(const ClearDisplayMessageRequest& request)>>
|
||||
clear_display_message_callback;
|
||||
|
||||
/// \brief Callback function is called when running cost is set.
|
||||
std::optional<std::function<void(const RunningCost& running_cost, const std::uint32_t number_of_decimals,
|
||||
std::optional<std::string> currency_code)>>
|
||||
set_running_cost_callback;
|
||||
|
||||
/// \brief Callback function is called when a TransactionEventResponse message from the CSMS is received that
|
||||
/// contains tariff and cost information.
|
||||
std::optional<std::function<void(const TariffMessage& message)>> tariff_message_callback;
|
||||
|
||||
/// \brief Callback function is called on startup and whenever the applicable default price changes (e.g. after a
|
||||
/// connectivity state change or a configuration update that affects the fallback price variables). The argument
|
||||
/// contains the price text in one or more languages; the first entry uses the configured default language.
|
||||
std::optional<std::function<void(const std::vector<DisplayMessageContent>& messages)>> default_price_callback;
|
||||
|
||||
/// \brief Callback function is called when a reservation request is received from the CSMS
|
||||
std::optional<std::function<ReserveNowStatusEnum(const ReserveNowRequest& request)>> reserve_now_callback;
|
||||
/// \brief Callback function is called when a cancel reservation request is received from the CSMS
|
||||
std::optional<std::function<bool(const std::int32_t reservationId)>> cancel_reservation_callback;
|
||||
|
||||
/// @} // End ocpp 201 callbacks group / topic
|
||||
|
||||
/// \brief Callback function is called when an update to the allowed energy transfer modes has been received,
|
||||
/// OCPP 2.1
|
||||
std::optional<std::function<bool(const std::vector<ocpp::v2::EnergyTransferModeEnum> allowed_energy_transfer_modes,
|
||||
const CiString<36> transaction_id)>>
|
||||
update_allowed_energy_transfer_modes_callback;
|
||||
|
||||
/// @} // End group
|
||||
};
|
||||
} // namespace ocpp::v2
|
||||
@@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
inline bool operator==(const EVSE& lhs, const EVSE& rhs) {
|
||||
return lhs.id == rhs.id and lhs.connectorId == rhs.connectorId;
|
||||
};
|
||||
|
||||
inline bool operator<(const EVSE& lhs, const EVSE& rhs) {
|
||||
if (lhs.id != rhs.id) {
|
||||
return lhs.id < rhs.id;
|
||||
}
|
||||
return lhs.connectorId < rhs.connectorId;
|
||||
}
|
||||
|
||||
inline bool operator==(const Component& lhs, const Component& rhs) {
|
||||
return lhs.name.get() == rhs.name.get() and lhs.instance == rhs.instance and lhs.evse == rhs.evse;
|
||||
};
|
||||
|
||||
inline bool operator<(const Component& lhs, const Component& rhs) {
|
||||
if (lhs.name != rhs.name) {
|
||||
return lhs.name < rhs.name;
|
||||
}
|
||||
if (lhs.instance != rhs.instance) {
|
||||
return lhs.instance < rhs.instance;
|
||||
}
|
||||
return lhs.evse < rhs.evse;
|
||||
};
|
||||
|
||||
inline bool operator==(const Variable& lhs, const Variable& rhs) {
|
||||
return lhs.name.get() == rhs.name.get() and lhs.instance == rhs.instance;
|
||||
};
|
||||
|
||||
inline bool operator<(const Variable& lhs, const Variable& rhs) {
|
||||
if (lhs.name != rhs.name) {
|
||||
return lhs.name < rhs.name;
|
||||
}
|
||||
return lhs.instance < rhs.instance;
|
||||
};
|
||||
|
||||
inline bool operator==(const ComponentVariable& lhs, const ComponentVariable& rhs) {
|
||||
return lhs.component == rhs.component and lhs.variable == rhs.variable;
|
||||
}
|
||||
|
||||
inline bool operator<(const ComponentVariable& lhs, const ComponentVariable& rhs) {
|
||||
if (lhs.component == rhs.component) {
|
||||
return lhs.variable < rhs.variable;
|
||||
}
|
||||
return lhs.component < rhs.component;
|
||||
}
|
||||
|
||||
inline bool operator==(const SetVariableData& lhs, const SetVariableData& rhs) {
|
||||
return lhs.component == rhs.component and lhs.variable == rhs.variable and
|
||||
lhs.attributeValue.get() == rhs.attributeValue.get() and lhs.attributeType == rhs.attributeType;
|
||||
}
|
||||
|
||||
inline bool operator<(const SetVariableData& lhs, const SetVariableData& rhs) {
|
||||
if (lhs.component == rhs.component) {
|
||||
return lhs.variable < rhs.variable;
|
||||
}
|
||||
return lhs.component < rhs.component;
|
||||
}
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,343 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "database_handler.hpp"
|
||||
#include <ocpp/v2/ocpp_enums.hpp>
|
||||
|
||||
namespace ocpp::v2 {
|
||||
|
||||
/// \brief Exception used when an evse that does not exist is accessed.
|
||||
class EvseOutOfRangeException : public std::exception {
|
||||
public:
|
||||
explicit EvseOutOfRangeException(std::int32_t id) : msg{"Evse with id " + std::to_string(id) + " does not exist"} {
|
||||
}
|
||||
|
||||
~EvseOutOfRangeException() noexcept override = default;
|
||||
|
||||
const char* what() const noexcept override {
|
||||
return msg.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
/// \brief Exception used when an connector_id that does not exist is accessed.
|
||||
class ConnectorOutOfRangeException : public std::exception {
|
||||
public:
|
||||
explicit ConnectorOutOfRangeException(std::int32_t connector_id, std::int32_t evse_id) :
|
||||
msg{"Connector with id " + std::to_string(connector_id) + " does not exist for evse with id " +
|
||||
std::to_string(evse_id)} {
|
||||
}
|
||||
|
||||
~ConnectorOutOfRangeException() noexcept override = default;
|
||||
|
||||
const char* what() const noexcept override {
|
||||
return msg.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string msg;
|
||||
};
|
||||
|
||||
/// \brief Describes the individual state of a single connector
|
||||
struct FullConnectorStatus {
|
||||
/// \brief Operative/Inoperative status, usually set by the CSMS
|
||||
OperationalStatusEnum individual_operational_status;
|
||||
/// \brief True if the connector has an active (uncleared) error, assumed false on boot
|
||||
bool faulted;
|
||||
/// \brief True if the connector has an active reservation, assumed false on boot
|
||||
bool reserved;
|
||||
/// \brief True if the connector has a cable plugged in, assumed false on boot
|
||||
bool occupied;
|
||||
/// \brief True if the connector is explicitly set to unavailable
|
||||
bool unavailable;
|
||||
|
||||
/// \brief Translates the individual state to an Available/Unavailable/Occupied/Reserved/Faulted state
|
||||
/// This does NOT take into account the state of the EVSE or CS,
|
||||
/// and is intended to be used internally by the ComponentStateManagerInterface.
|
||||
ConnectorStatusEnum to_connector_status() const;
|
||||
};
|
||||
|
||||
class ComponentStateManagerInterface {
|
||||
public:
|
||||
virtual ~ComponentStateManagerInterface();
|
||||
|
||||
/// \brief Set a callback to be called when the effective Operative/Inoperative state of the CS changes.
|
||||
virtual void set_cs_effective_availability_changed_callback(
|
||||
const std::function<void(const OperationalStatusEnum new_status)>& callback) = 0;
|
||||
|
||||
/// \brief Set a callback to be called when the effective Operative/Inoperative state of an EVSE changes.
|
||||
virtual void set_evse_effective_availability_changed_callback(
|
||||
const std::function<void(const std::int32_t evse_id, const OperationalStatusEnum new_status)>& callback) = 0;
|
||||
|
||||
/// \brief Set a callback to be called when the effective Operative/Inoperative state of a connector changes.
|
||||
virtual void set_connector_effective_availability_changed_callback(
|
||||
const std::function<void(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const OperationalStatusEnum new_status)>& callback) = 0;
|
||||
|
||||
/// \brief Get the individual status (Operative/Inoperative) of the CS, as set by the CSMS
|
||||
virtual OperationalStatusEnum get_cs_individual_operational_status() = 0;
|
||||
|
||||
/// \brief Get the individual status (Operative/Inoperative) of an EVSE, as set by the CSMS
|
||||
/// Note: This is not the same as the effective status.
|
||||
/// The EVSE might be effectively Inoperative if the CS is Inoperative.
|
||||
virtual OperationalStatusEnum get_evse_individual_operational_status(std::int32_t evse_id) = 0;
|
||||
|
||||
/// \brief Get the individual status (Operative/Inoperative) of a connector, as set by the CSMS
|
||||
/// Note: This is not the same as the effective status.
|
||||
/// The connector might be effectively Inoperative if its EVSE or the CS is Inoperative.
|
||||
virtual OperationalStatusEnum get_connector_individual_operational_status(std::int32_t evse_id,
|
||||
std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Get the individual status (Operative/Inoperative) of the CS, as persisted in the database
|
||||
/// This status is restored after reboot, and differs from the individual status if non-persistent
|
||||
/// status changes were made.
|
||||
virtual OperationalStatusEnum get_cs_persisted_operational_status() = 0;
|
||||
|
||||
/// \brief Get the individual status (Operative/Inoperative) of an EVSE, as persisted in the database
|
||||
/// This status is restored after reboot, and differs from the individual status if non-persistent
|
||||
/// status changes were made.
|
||||
virtual OperationalStatusEnum get_evse_persisted_operational_status(std::int32_t evse_id) = 0;
|
||||
|
||||
/// \brief Get the individual status (Operative/Inoperative) of a connector, as persisted in the database
|
||||
/// This status is restored after reboot, and differs from the individual status if non-persistent
|
||||
/// status changes were made.
|
||||
virtual OperationalStatusEnum get_connector_persisted_operational_status(std::int32_t evse_id,
|
||||
std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Set the individual status (Operative/Inoperative) of the CS
|
||||
virtual void set_cs_individual_operational_status(OperationalStatusEnum new_status, bool persist) = 0;
|
||||
|
||||
/// \brief Set the individual status (Operative/Inoperative) of an EVSE
|
||||
/// Note: This is not the same as the effective status.
|
||||
/// The EVSE might be effectively Inoperative if the CS is Inoperative.
|
||||
virtual void set_evse_individual_operational_status(std::int32_t evse_id, OperationalStatusEnum new_status,
|
||||
bool persist) = 0;
|
||||
|
||||
/// \brief Set the individual status (Operative/Inoperative) of a connector
|
||||
/// Note: This is not the same as the effective status.
|
||||
/// The connector might be effectively Inoperative if its EVSE or the CS is Inoperative.
|
||||
virtual void set_connector_individual_operational_status(std::int32_t evse_id, std::int32_t connector_id,
|
||||
OperationalStatusEnum new_status, bool persist) = 0;
|
||||
|
||||
/// \brief Get the effective Operative/Inoperative status of an EVSE
|
||||
/// This is computed from the EVSE's and the CS's individual statuses.
|
||||
virtual OperationalStatusEnum get_evse_effective_operational_status(std::int32_t evse_id) = 0;
|
||||
|
||||
/// \brief Get the effective Operative/Inoperative status of a connector.
|
||||
/// This is computed from the connector's, the EVSE's, and the CS's individual statuses.
|
||||
virtual OperationalStatusEnum get_connector_effective_operational_status(std::int32_t evse_id,
|
||||
std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Get the effective Available/Unavailable/Occupied/Faulted/Reserved status of a connector.
|
||||
/// If the EVSE or the CS is Inoperative, the connector will be effectively Unavailable.
|
||||
virtual ConnectorStatusEnum get_connector_effective_status(std::int32_t evse_id, std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Update the state of the connector when plugged in or out
|
||||
virtual void set_connector_occupied(std::int32_t evse_id, std::int32_t connector_id, bool is_occupied) = 0;
|
||||
|
||||
/// \brief Update the state of the connector when reservations are made or expire
|
||||
virtual void set_connector_reserved(std::int32_t evse_id, std::int32_t connector_id, bool is_reserved) = 0;
|
||||
|
||||
/// \brief Update the state of the connector when errors are raised and cleared
|
||||
virtual void set_connector_faulted(std::int32_t evse_id, std::int32_t connector_id, bool is_faulted) = 0;
|
||||
|
||||
/// \brief Update the state of the connector when unavailable or enabled
|
||||
virtual void set_connector_unavailable(std::int32_t evse_id, std::int32_t connector_id, bool is_unavailable) = 0;
|
||||
|
||||
/// \brief Call the {cs, evse, connector}_effective_availability_changed_callback callback once for every component.
|
||||
/// This is usually only done once on boot to notify the rest of the system what the state manager expects the
|
||||
/// operative state (Operative/Inoperative) of the CS, EVSEs, and connectors to be.
|
||||
virtual void trigger_all_effective_availability_changed_callbacks() = 0;
|
||||
|
||||
/// \brief Call the send_connector_status_notification_callback once for every connector.
|
||||
/// This is usually done on boot, and on reconnect after the station has been offline for a long time.
|
||||
virtual void send_status_notification_all_connectors() = 0;
|
||||
|
||||
/// \brief Call the send_connector_status_notification_callback once for every connector whose state has changed
|
||||
/// since it was last reported with a successful send_connector_status_notification_callback. This is usually done
|
||||
/// when the station has been offline for short time and comes back online.
|
||||
virtual void send_status_notification_changed_connectors() = 0;
|
||||
|
||||
/// \brief Call the send_connector_status_notification_callback for a single connector.
|
||||
/// This is usually done when the CSMS explicitly sends a TriggerMessage to send a StatusNotification.
|
||||
virtual void send_status_notification_single_connector(std::int32_t evse_id, std::int32_t connector_id) = 0;
|
||||
};
|
||||
|
||||
/// \brief Stores and monitors operational/effective states of the CS, EVSEs, and connectors
|
||||
class ComponentStateManager : public ComponentStateManagerInterface {
|
||||
private:
|
||||
std::shared_ptr<DatabaseHandler> database;
|
||||
|
||||
/// Current individual Operative/Inoperative state of the CS
|
||||
OperationalStatusEnum cs_individual_status;
|
||||
/// Current individual Operative/Inoperative state of EVSEs, plus individual state of connectors.
|
||||
std::vector<std::pair<OperationalStatusEnum, std::vector<FullConnectorStatus>>>
|
||||
evse_and_connector_individual_statuses;
|
||||
|
||||
/// Last Operative/Inoperative status of the CS that was reported to the user of libocpp via callbacks
|
||||
OperationalStatusEnum last_cs_effective_operational_status;
|
||||
/// Last Operative/Inoperative status of EVSEs and connectors that was reported to the user of libocpp via callbacks
|
||||
std::vector<std::pair<OperationalStatusEnum, std::vector<OperationalStatusEnum>>>
|
||||
last_evse_and_connector_effective_operational_statuses;
|
||||
|
||||
/// Last connector status for each connector that was reported with a successful
|
||||
/// send_connector_status_notification_callback
|
||||
// We need to track this separately because the send_connector_status_notification_callback can fail
|
||||
std::vector<std::vector<ConnectorStatusEnum>> last_connector_reported_statuses;
|
||||
|
||||
/// \brief Callback triggered by the library when the effective status of the charging station changes
|
||||
/// \param new_status The effective status after the change
|
||||
std::optional<std::function<void(const OperationalStatusEnum new_status)>>
|
||||
cs_effective_availability_changed_callback = std::nullopt;
|
||||
|
||||
/// \brief Callback triggered by the library when the effective status of an EVSE changes
|
||||
/// \param evse_id The ID of the EVSE whose status changed
|
||||
/// \param new_status The effective status after the change
|
||||
std::optional<std::function<void(const std::int32_t evse_id, const OperationalStatusEnum new_status)>>
|
||||
evse_effective_availability_changed_callback = std::nullopt;
|
||||
|
||||
/// \brief Callback triggered by the library when the effective status of a connector changes
|
||||
/// \param evse_id The ID of the EVSE whose status changed
|
||||
/// \param connector_id The ID of the connector within the EVSE whose status changed
|
||||
/// \param new_status The effective status after the change
|
||||
std::optional<std::function<void(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const OperationalStatusEnum new_status)>>
|
||||
connector_effective_availability_changed_callback = std::nullopt;
|
||||
|
||||
/// \brief Callback used by the library to trigger a StatusUpdateRequest for a connector
|
||||
/// \param evse_id The ID of the EVSE
|
||||
/// \param connector_id The ID of the connector
|
||||
/// \param new_status The connector status
|
||||
/// \param initiated_by_trigger_message Indicates if the StatusNotification was initiated by a TriggerMessage.req
|
||||
/// \return true if the status notification was successfully sent, false otherwise (usually it fails when offline)
|
||||
std::function<bool(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const ConnectorStatusEnum new_status, bool initiated_by_trigger_message)>
|
||||
send_connector_status_notification_callback;
|
||||
|
||||
/// \brief Internal convenience function - returns the number of EVSEs
|
||||
std::int32_t num_evses();
|
||||
/// \brief Internal convenience function - returns the number of connectors in an EVSE
|
||||
std::int32_t num_connectors(std::int32_t evse_id);
|
||||
|
||||
/// \brief Throws a std::out_of_range if \param evse_id is out of bounds
|
||||
void check_evse_id(std::int32_t evse_id);
|
||||
/// \brief Throws a std::out_of_range if \param evse_id or \param connector_id is out of bounds
|
||||
void check_evse_and_connector_id(std::int32_t evse_id, std::int32_t connector_id);
|
||||
|
||||
/// \brief Convenience function, returns a (writeable) reference to the individual status of an EVSE
|
||||
OperationalStatusEnum& individual_evse_status(std::int32_t evse_id);
|
||||
/// \brief Convenience function, returns a (writeable) reference to the individual status of a connector
|
||||
FullConnectorStatus& individual_connector_status(std::int32_t evse_id, std::int32_t connector_id);
|
||||
|
||||
/// \brief Convenience function, returns a (writeable) reference to last Operative/Inoperative status of an EVSE
|
||||
/// that was reported to the user of libocpp via callbacks.
|
||||
OperationalStatusEnum& last_evse_effective_status(std::int32_t evse_id);
|
||||
/// \brief Convenience function, returns a (writeable) reference to last Operative/Inoperative status of a connector
|
||||
/// that was reported to the user of libocpp via callbacks.
|
||||
OperationalStatusEnum& last_connector_effective_status(std::int32_t evse_id, std::int32_t connector_id);
|
||||
/// \brief Convenience function, returns a (writeable) reference to last connector status that was successfully
|
||||
/// reported via send_connector_status_notification_callback
|
||||
ConnectorStatusEnum& last_connector_reported_status(std::int32_t evse_id, std::int32_t connector_id);
|
||||
|
||||
/// \brief Internal helper function, triggers {cs, evse, connector}_effective_availability_changed_callback calls
|
||||
/// for the CS and all sub-components.
|
||||
/// \param only_if_state_changed If set to true, callbacks are only triggered for components whose state
|
||||
/// has changed since it was last reported via callbacks
|
||||
void trigger_callbacks_cs(bool only_if_state_changed);
|
||||
/// \brief Internal helper function, triggers {evse, connector}_effective_availability_changed_callback calls
|
||||
/// for an EVSE and its connectors
|
||||
/// \param only_if_state_changed If set to true, callbacks are only triggered for components whose state
|
||||
/// has changed since it was last reported via callbacks
|
||||
void trigger_callbacks_evse(std::int32_t evse_id, bool only_if_state_changed);
|
||||
/// \brief Internal helper function, triggers connector_effective_availability_changed_callback calls
|
||||
/// for a connector
|
||||
/// \param only_if_state_changed If set to true, callbacks are only triggered for components whose state
|
||||
/// has changed since it was last reported via callbacks
|
||||
void trigger_callbacks_connector(std::int32_t evse_id, std::int32_t connector_id, bool only_if_state_changed);
|
||||
|
||||
/// \brief Internal helper function, calls send_connector_status_notification_callback for a single connector
|
||||
/// \param only_if_changed If set to true, the callback will only be triggered if the connector state has changed
|
||||
/// since it was last reported with a successful send_connector_status_notification_callback
|
||||
/// \param intiated_by_trigger_message Indicates if the StatusNotification was initiated by a TriggerMessage.req
|
||||
void send_status_notification_single_connector_internal(std::int32_t evse_id, std::int32_t connector_id,
|
||||
bool only_if_changed,
|
||||
bool intiated_by_trigger_message = false);
|
||||
|
||||
/// \brief Initializes *_individual_status(es) from the values stored in the DB.
|
||||
/// Inserts Operative if values are missing.
|
||||
void
|
||||
read_all_states_from_database_or_set_defaults(const std::map<std::int32_t, std::int32_t>& evse_connector_structure);
|
||||
|
||||
/// \brief Initializes last_*_operational_status(es) and last_connector_reported_statuses
|
||||
/// with the current effective statuses of all components
|
||||
void initialize_reported_state_cache();
|
||||
|
||||
public:
|
||||
/// \brief At construction time, the state of each component (CS, EVSEs, and connectors) is retrieved from the
|
||||
/// database. No callbacks are triggered at this stage.
|
||||
/// When the status of components is updated, corresponding callbacks are triggered to notify the user of libocpp.
|
||||
/// Additionally, the ComponentStateManager sends StatusNotifications to the CSMS when connector statuses change.
|
||||
/// Note: It is expected that ComponentStateManagerInterface::trigger_all_effective_availability_changed_callbacks
|
||||
/// is called on boot, and ComponentStateManagerInterface::send_status_notification_all_connectors is called when
|
||||
/// first connected to the CSMS.
|
||||
/// \param evse_connector_structure Maps each EVSE ID to the number of connectors the EVSE has
|
||||
/// \param db_handler A shared reference to the persistent database
|
||||
/// \param send_connector_status_notification_callback The callback through which to send StatusNotifications to the
|
||||
/// CSMS \param initiated_by_trigger_message Indicates if the StatusNotification was initiated by a
|
||||
/// TriggerMessage.req
|
||||
explicit ComponentStateManager(
|
||||
const std::map<std::int32_t, std::int32_t>& evse_connector_structure,
|
||||
std::shared_ptr<DatabaseHandler> db_handler,
|
||||
std::function<bool(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const ConnectorStatusEnum new_status, const bool initiated_by_trigger_message)>
|
||||
send_connector_status_notification_callback);
|
||||
|
||||
void set_cs_effective_availability_changed_callback(
|
||||
const std::function<void(const OperationalStatusEnum new_status)>& callback) override;
|
||||
|
||||
void set_evse_effective_availability_changed_callback(
|
||||
const std::function<void(const std::int32_t evse_id, const OperationalStatusEnum new_status)>& callback)
|
||||
override;
|
||||
|
||||
void set_connector_effective_availability_changed_callback(
|
||||
const std::function<void(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const OperationalStatusEnum new_status)>& callback) override;
|
||||
|
||||
OperationalStatusEnum get_cs_individual_operational_status() override;
|
||||
OperationalStatusEnum get_evse_individual_operational_status(std::int32_t evse_id) override;
|
||||
OperationalStatusEnum get_connector_individual_operational_status(std::int32_t evse_id,
|
||||
std::int32_t connector_id) override;
|
||||
|
||||
OperationalStatusEnum get_cs_persisted_operational_status() override;
|
||||
OperationalStatusEnum get_evse_persisted_operational_status(std::int32_t evse_id) override;
|
||||
OperationalStatusEnum get_connector_persisted_operational_status(std::int32_t evse_id,
|
||||
std::int32_t connector_id) override;
|
||||
|
||||
void set_cs_individual_operational_status(OperationalStatusEnum new_status, bool persist) override;
|
||||
void set_evse_individual_operational_status(std::int32_t evse_id, OperationalStatusEnum new_status,
|
||||
bool persist) override;
|
||||
void set_connector_individual_operational_status(std::int32_t evse_id, std::int32_t connector_id,
|
||||
OperationalStatusEnum new_status, bool persist) override;
|
||||
|
||||
OperationalStatusEnum get_evse_effective_operational_status(std::int32_t evse_id) override;
|
||||
OperationalStatusEnum get_connector_effective_operational_status(std::int32_t evse_id,
|
||||
std::int32_t connector_id) override;
|
||||
ConnectorStatusEnum get_connector_effective_status(std::int32_t evse_id, std::int32_t connector_id) override;
|
||||
|
||||
void set_connector_occupied(std::int32_t evse_id, std::int32_t connector_id, bool is_occupied) override;
|
||||
void set_connector_reserved(std::int32_t evse_id, std::int32_t connector_id, bool is_reserved) override;
|
||||
void set_connector_faulted(std::int32_t evse_id, std::int32_t connector_id, bool is_faulted) override;
|
||||
void set_connector_unavailable(std::int32_t evse_id, std::int32_t connector_id, bool is_unavailable) override;
|
||||
|
||||
void trigger_all_effective_availability_changed_callbacks() override;
|
||||
|
||||
void send_status_notification_all_connectors() override;
|
||||
void send_status_notification_changed_connectors() override;
|
||||
void send_status_notification_single_connector(std::int32_t evse_id, std::int32_t connector_id) override;
|
||||
};
|
||||
|
||||
} // namespace ocpp::v2
|
||||
@@ -0,0 +1,78 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
|
||||
#include "component_state_manager.hpp"
|
||||
#include "database_handler.hpp"
|
||||
#include <ocpp/v2/ocpp_enums.hpp>
|
||||
#include <optional>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
/// \brief Enum for ConnectorEvents
|
||||
enum class ConnectorEvent {
|
||||
PlugIn,
|
||||
PlugOut,
|
||||
Reserve,
|
||||
ReservationCleared,
|
||||
Error,
|
||||
ErrorCleared,
|
||||
Unavailable,
|
||||
UnavailableCleared
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given ConnectorEvent \p e to human readable string
|
||||
/// \returns a string representation of the ConnectorEvent
|
||||
std::string connector_event_to_string(ConnectorEvent e);
|
||||
} // namespace conversions
|
||||
|
||||
/// \brief Represents a Connector, thus electrical outlet on a Charging Station. Single physical Connector.
|
||||
class Connector {
|
||||
private:
|
||||
/// \brief ID of the EVSE this connector belongs to (>0)
|
||||
// cppcheck-suppress unusedStructMember
|
||||
std::int32_t evse_id;
|
||||
/// \brief ID of the connector itself (>0)
|
||||
std::int32_t connector_id;
|
||||
|
||||
/// \brief Component responsible for maintaining and monitoring the operational status of CS, EVSEs, and connectors.
|
||||
std::shared_ptr<ComponentStateManagerInterface> component_state_manager;
|
||||
|
||||
/// \brief status mutex to protect the status of the connector against concurrent updates
|
||||
std::mutex status_mutex;
|
||||
|
||||
public:
|
||||
/// \brief Construct a new Connector object
|
||||
/// \param evse_id id of the EVSE the connector is ap art of
|
||||
/// \param connector_id id of the connector
|
||||
/// \param component_state_manager A shared reference to the component state manager
|
||||
Connector(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
std::shared_ptr<ComponentStateManagerInterface> component_state_manager);
|
||||
|
||||
/// \brief Gets the effective Operative/Inoperative status of this connector
|
||||
OperationalStatusEnum get_effective_operational_status();
|
||||
/// \brief Gets the effective Available/Unavailable/Faulted/Reserved/Occupied status of this connector
|
||||
ConnectorStatusEnum get_effective_connector_status();
|
||||
|
||||
/// \brief Adjust the state of the connector according to the \p event that was submitted.
|
||||
/// \param event
|
||||
void submit_event(ConnectorEvent event);
|
||||
|
||||
/// \brief Switches the operative status of the connector and recomputes its effective status
|
||||
/// \param new_status: The operative status to switch to
|
||||
/// \param persist: True if the updated operative status setting should be persisted
|
||||
void set_connector_operative_status(OperationalStatusEnum new_status, bool persist);
|
||||
|
||||
/// \brief Restores the operative status of the connector to the persisted status and recomputes its effective
|
||||
/// status
|
||||
void restore_connector_operative_status();
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
/// \brief OCPP 2.0.1 defines this as 5600 but it can be set to a higher value, which we do here, if it's reported via
|
||||
/// the device model, which we do as well
|
||||
/// 17000 is the minimum value from OCPP 2.1
|
||||
constexpr std::size_t ISO15118_GET_EV_CERTIFICATE_EXI_RESPONSE_SIZE = 17000;
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,464 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef OCPP_V2_CTRLR_COMPONENT_VARIABLES
|
||||
#define OCPP_V2_CTRLR_COMPONENT_VARIABLES
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
class DeviceModelInterface;
|
||||
|
||||
///
|
||||
/// \brief Required ComponentVariable.
|
||||
///
|
||||
struct RequiredComponentVariable : ComponentVariable {
|
||||
/// \brief Constructor
|
||||
RequiredComponentVariable() : required_for({OcppProtocolVersion::v201, OcppProtocolVersion::v21}){};
|
||||
|
||||
///
|
||||
/// \brief RequiredComponentVariable
|
||||
/// \param component Component
|
||||
/// \param variable Variable
|
||||
/// \param custom_data Custom data (default nullopt)
|
||||
/// \param required_for Required for which version. Multiple versions can be given.
|
||||
///
|
||||
RequiredComponentVariable(const Component component, const std::optional<Variable> variable,
|
||||
const std::optional<CustomData> custom_data = std::nullopt,
|
||||
const std::set<OcppProtocolVersion>& required_for = {OcppProtocolVersion::v201,
|
||||
OcppProtocolVersion::v21}) :
|
||||
ComponentVariable(), required_for(required_for) {
|
||||
this->component = component;
|
||||
this->variable = variable;
|
||||
this->customData = custom_data;
|
||||
};
|
||||
|
||||
/// \brief For which ocpp protocol version(s) this component variable is required.
|
||||
std::set<OcppProtocolVersion> required_for;
|
||||
};
|
||||
|
||||
///
|
||||
/// \brief Required variables per component.
|
||||
///
|
||||
/// First value is the 'available' variable from the specific component. Second value is a set of required variables.
|
||||
/// This makes it possible to check only for the required variables if a component is available.
|
||||
///
|
||||
extern const std::vector<std::pair<ComponentVariable, std::vector<RequiredComponentVariable>>>
|
||||
required_component_available_variables;
|
||||
|
||||
///
|
||||
/// \brief Required variables that should always exist, regardless of any available or not available controller.
|
||||
///
|
||||
extern const std::vector<RequiredComponentVariable> required_variables;
|
||||
|
||||
///
|
||||
/// \brief Required variables of an EVSE.
|
||||
///
|
||||
extern const std::vector<Variable> required_evse_variables;
|
||||
|
||||
///
|
||||
/// \brief Required variables of a connector.
|
||||
///
|
||||
extern const std::vector<Variable> required_connector_variables;
|
||||
|
||||
///
|
||||
/// \brief Required variables of a V2X component.
|
||||
///
|
||||
extern const std::vector<Variable> required_v2x_variables;
|
||||
|
||||
namespace ControllerComponents {
|
||||
extern const Component InternalCtrlr;
|
||||
extern const Component AlignedDataCtrlr;
|
||||
extern const Component AuthCacheCtrlr;
|
||||
extern const Component AuthCtrlr;
|
||||
extern const Component ChargingStation;
|
||||
extern const Component ClockCtrlr;
|
||||
extern const Component ConnectedEV;
|
||||
extern const Component CustomizationCtrlr;
|
||||
extern const Component DeviceDataCtrlr;
|
||||
extern const Component DisplayMessageCtrlr;
|
||||
extern const Component ISO15118Ctrlr;
|
||||
extern const Component LocalAuthListCtrlr;
|
||||
extern const Component MonitoringCtrlr;
|
||||
extern const Component OCPPCommCtrlr;
|
||||
extern const Component ReservationCtrlr;
|
||||
extern const Component SampledDataCtrlr;
|
||||
extern const Component SecurityCtrlr;
|
||||
extern const Component SmartChargingCtrlr;
|
||||
extern const Component TariffCostCtrlr;
|
||||
extern const Component TxCtrlr;
|
||||
// following controllers contains OCPP1.6 configuration keys without a clear mapping to OCPP2.x.
|
||||
extern const Component OCPP16LegacyCtrlr;
|
||||
extern const Component CustomLegacyController;
|
||||
} // namespace ControllerComponents
|
||||
|
||||
namespace StandardizedVariables {
|
||||
extern const Variable Problem;
|
||||
extern const Variable Tripped;
|
||||
extern const Variable Overload;
|
||||
extern const Variable Fallback;
|
||||
}; // namespace StandardizedVariables
|
||||
|
||||
// Provides access to standardized variables of OCPP2.0.1 spec
|
||||
namespace ControllerComponentVariables {
|
||||
extern const ComponentVariable InternalCtrlrEnabled;
|
||||
extern const RequiredComponentVariable ChargePointId;
|
||||
extern const RequiredComponentVariable NetworkConnectionProfiles;
|
||||
extern const RequiredComponentVariable ChargeBoxSerialNumber;
|
||||
extern const RequiredComponentVariable ChargePointModel;
|
||||
extern const ComponentVariable ChargePointSerialNumber;
|
||||
extern const RequiredComponentVariable ChargePointVendor;
|
||||
extern const RequiredComponentVariable FirmwareVersion;
|
||||
extern const ComponentVariable ICCID;
|
||||
extern const ComponentVariable IMSI;
|
||||
extern const ComponentVariable MeterSerialNumber;
|
||||
extern const ComponentVariable MeterType;
|
||||
extern const RequiredComponentVariable SupportedCiphers12;
|
||||
extern const RequiredComponentVariable SupportedCiphers13;
|
||||
extern const ComponentVariable AuthorizeConnectorZeroOnConnectorOne;
|
||||
extern const ComponentVariable LogMessages;
|
||||
extern const ComponentVariable LogMessagesRaw;
|
||||
extern const RequiredComponentVariable LogMessagesFormat;
|
||||
extern const ComponentVariable LogRotation;
|
||||
extern const ComponentVariable LogRotationDateSuffix;
|
||||
extern const ComponentVariable LogRotationMaximumFileSize;
|
||||
extern const ComponentVariable LogRotationMaximumFileCount;
|
||||
extern const ComponentVariable SupportedChargingProfilePurposeTypes;
|
||||
extern const ComponentVariable SupportedCriteria;
|
||||
extern const ComponentVariable RoundClockAlignedTimestamps;
|
||||
extern const ComponentVariable NetworkConfigTimeout;
|
||||
extern const ComponentVariable MaxCompositeScheduleDuration;
|
||||
extern const RequiredComponentVariable NumberOfConnectors;
|
||||
extern const ComponentVariable UseSslDefaultVerifyPaths;
|
||||
extern const ComponentVariable VerifyCsmsCommonName;
|
||||
extern const ComponentVariable UseTPM;
|
||||
extern const ComponentVariable UseTPMSeccLeafCertificate;
|
||||
extern const ComponentVariable VerifyCsmsAllowWildcards;
|
||||
extern const ComponentVariable IFace;
|
||||
extern const ComponentVariable EnableTLSKeylog;
|
||||
extern const ComponentVariable TLSKeylogFile;
|
||||
extern const ComponentVariable OcspRequestInterval;
|
||||
extern const ComponentVariable WebsocketPingPayload;
|
||||
extern const ComponentVariable WebsocketPongTimeout;
|
||||
extern const ComponentVariable MonitorsProcessingInterval;
|
||||
extern const ComponentVariable MaxCustomerInformationDataLength;
|
||||
extern const ComponentVariable V2GCertificateExpireCheckInitialDelaySeconds;
|
||||
extern const ComponentVariable V2GCertificateExpireCheckIntervalSeconds;
|
||||
extern const ComponentVariable ClientCertificateExpireCheckInitialDelaySeconds;
|
||||
extern const ComponentVariable ClientCertificateExpireCheckIntervalSeconds;
|
||||
extern const ComponentVariable MessageQueueSizeThreshold;
|
||||
extern const ComponentVariable MaxMessageSize;
|
||||
extern const ComponentVariable ResumeTransactionsOnBoot;
|
||||
extern const ComponentVariable AllowSecurityLevelZeroConnections;
|
||||
extern const RequiredComponentVariable SupportedOcppVersions;
|
||||
extern const ComponentVariable AlignedDataCtrlrEnabled;
|
||||
extern const ComponentVariable AlignedDataCtrlrAvailable;
|
||||
extern const RequiredComponentVariable AlignedDataInterval;
|
||||
extern const RequiredComponentVariable AlignedDataMeasurands;
|
||||
extern const ComponentVariable AlignedDataSendDuringIdle;
|
||||
extern const ComponentVariable AlignedDataSignReadings;
|
||||
extern const RequiredComponentVariable AlignedDataTxEndedInterval;
|
||||
extern const RequiredComponentVariable AlignedDataTxEndedMeasurands;
|
||||
extern const ComponentVariable AuthCacheCtrlrAvailable;
|
||||
extern const ComponentVariable AuthCacheCtrlrEnabled;
|
||||
extern const ComponentVariable AuthCacheDisablePostAuthorize;
|
||||
extern const ComponentVariable AuthCacheLifeTime;
|
||||
extern const ComponentVariable AuthCachePolicy;
|
||||
extern const ComponentVariable AuthCacheStorage;
|
||||
extern const ComponentVariable AuthCtrlrEnabled;
|
||||
extern const ComponentVariable AdditionalInfoItemsPerMessage;
|
||||
extern const RequiredComponentVariable AuthorizeRemoteStart;
|
||||
extern const RequiredComponentVariable LocalAuthorizeOffline;
|
||||
extern const RequiredComponentVariable LocalPreAuthorize;
|
||||
extern const ComponentVariable DisableRemoteAuthorization;
|
||||
extern const ComponentVariable MasterPassGroupId;
|
||||
extern const ComponentVariable OfflineTxForUnknownIdEnabled;
|
||||
extern const ComponentVariable AllowNewSessionsPendingFirmwareUpdate;
|
||||
extern const RequiredComponentVariable ChargingStationAvailabilityState;
|
||||
extern const RequiredComponentVariable ChargingStationAvailable;
|
||||
extern const RequiredComponentVariable ChargingStationSupplyPhases;
|
||||
extern const RequiredComponentVariable ClockCtrlrDateTime;
|
||||
extern const ComponentVariable NextTimeOffsetTransitionDateTime;
|
||||
extern const ComponentVariable NtpServerUri;
|
||||
extern const ComponentVariable NtpSource;
|
||||
extern const ComponentVariable TimeAdjustmentReportingThreshold;
|
||||
extern const ComponentVariable TimeOffset;
|
||||
extern const ComponentVariable TimeOffsetNextTransition;
|
||||
extern const RequiredComponentVariable TimeSource;
|
||||
extern const ComponentVariable TimeZone;
|
||||
extern const ComponentVariable CustomImplementationEnabled;
|
||||
extern const ComponentVariable CustomImplementationCaliforniaPricingEnabled;
|
||||
extern const ComponentVariable CustomImplementationMultiLanguageEnabled;
|
||||
extern const RequiredComponentVariable BytesPerMessageGetReport;
|
||||
extern const RequiredComponentVariable BytesPerMessageGetVariables;
|
||||
extern const RequiredComponentVariable BytesPerMessageSetVariables;
|
||||
extern const ComponentVariable ConfigurationValueSize;
|
||||
extern const RequiredComponentVariable ItemsPerMessageGetReport;
|
||||
extern const RequiredComponentVariable ItemsPerMessageGetVariables;
|
||||
extern const RequiredComponentVariable ItemsPerMessageSetVariables;
|
||||
extern const ComponentVariable ReportingValueSize;
|
||||
extern const ComponentVariable DisplayMessageCtrlrAvailable;
|
||||
extern const RequiredComponentVariable NumberOfDisplayMessages;
|
||||
extern const RequiredComponentVariable DisplayMessageSupportedFormats;
|
||||
extern const RequiredComponentVariable DisplayMessageSupportedPriorities;
|
||||
extern const ComponentVariable DisplayMessageSupportedStates;
|
||||
extern const ComponentVariable DisplayMessageQRCodeDisplayCapable;
|
||||
extern const ComponentVariable DisplayMessageLanguage;
|
||||
extern const ComponentVariable CentralContractValidationAllowed;
|
||||
extern const RequiredComponentVariable ContractValidationOffline;
|
||||
extern const ComponentVariable RequestMeteringReceipt;
|
||||
extern const ComponentVariable ISO15118CtrlrSeccId;
|
||||
extern const ComponentVariable ISO15118CtrlrCountryName;
|
||||
extern const ComponentVariable ISO15118CtrlrOrganizationName;
|
||||
extern const ComponentVariable PnCEnabled;
|
||||
extern const ComponentVariable V2GCertificateInstallationEnabled;
|
||||
extern const ComponentVariable ContractCertificateInstallationEnabled;
|
||||
extern const ComponentVariable LocalAuthListCtrlrAvailable;
|
||||
extern const RequiredComponentVariable BytesPerMessageSendLocalList;
|
||||
extern const ComponentVariable LocalAuthListCtrlrEnabled;
|
||||
extern const RequiredComponentVariable LocalAuthListCtrlrEntries;
|
||||
extern const RequiredComponentVariable ItemsPerMessageSendLocalList;
|
||||
extern const ComponentVariable LocalAuthListCtrlrStorage;
|
||||
extern const ComponentVariable LocalAuthListDisablePostAuthorize;
|
||||
extern const ComponentVariable MonitoringCtrlrAvailable;
|
||||
extern const ComponentVariable BytesPerMessageClearVariableMonitoring;
|
||||
extern const RequiredComponentVariable BytesPerMessageSetVariableMonitoring;
|
||||
extern const ComponentVariable MonitoringCtrlrEnabled;
|
||||
extern const ComponentVariable ActiveMonitoringBase;
|
||||
extern const ComponentVariable ActiveMonitoringLevel;
|
||||
extern const ComponentVariable ItemsPerMessageClearVariableMonitoring;
|
||||
extern const RequiredComponentVariable ItemsPerMessageSetVariableMonitoring;
|
||||
extern const ComponentVariable OfflineQueuingSeverity;
|
||||
extern const ComponentVariable ActiveNetworkProfile;
|
||||
extern const RequiredComponentVariable FileTransferProtocols;
|
||||
extern const ComponentVariable HeartbeatInterval;
|
||||
extern const RequiredComponentVariable MessageTimeout;
|
||||
extern const RequiredComponentVariable MessageAttemptInterval;
|
||||
extern const RequiredComponentVariable MessageAttempts;
|
||||
extern const RequiredComponentVariable NetworkConfigurationPriority;
|
||||
extern const RequiredComponentVariable NetworkProfileConnectionAttempts;
|
||||
extern const RequiredComponentVariable OfflineThreshold;
|
||||
extern const ComponentVariable QueueAllMessages;
|
||||
extern const ComponentVariable MessageTypesDiscardForQueueing;
|
||||
extern const RequiredComponentVariable ResetRetries;
|
||||
extern const RequiredComponentVariable RetryBackOffRandomRange;
|
||||
extern const RequiredComponentVariable RetryBackOffRepeatTimes;
|
||||
extern const RequiredComponentVariable RetryBackOffWaitMinimum;
|
||||
extern const RequiredComponentVariable UnlockOnEVSideDisconnect;
|
||||
extern const RequiredComponentVariable WebSocketPingInterval;
|
||||
extern const ComponentVariable ReservationCtrlrAvailable;
|
||||
extern const ComponentVariable ReservationCtrlrEnabled;
|
||||
extern const ComponentVariable ReservationCtrlrNonEvseSpecific;
|
||||
extern const ComponentVariable SampledDataCtrlrAvailable;
|
||||
extern const ComponentVariable SampledDataCtrlrEnabled;
|
||||
extern const ComponentVariable SampledDataSignReadings;
|
||||
extern const RequiredComponentVariable SampledDataTxEndedInterval;
|
||||
extern const RequiredComponentVariable SampledDataTxEndedMeasurands;
|
||||
extern const RequiredComponentVariable SampledDataTxStartedMeasurands;
|
||||
extern const RequiredComponentVariable SampledDataTxUpdatedInterval;
|
||||
extern const RequiredComponentVariable SampledDataTxUpdatedMeasurands;
|
||||
extern const ComponentVariable AdditionalRootCertificateCheck;
|
||||
extern const ComponentVariable BasicAuthPassword;
|
||||
extern const RequiredComponentVariable CertificateEntries;
|
||||
extern const ComponentVariable CertSigningRepeatTimes;
|
||||
extern const ComponentVariable CertSigningWaitMinimum;
|
||||
extern const RequiredComponentVariable SecurityCtrlrIdentity;
|
||||
extern const ComponentVariable MaxCertificateChainSize;
|
||||
extern const ComponentVariable UpdateCertificateSymlinks;
|
||||
extern const RequiredComponentVariable OrganizationName;
|
||||
extern const RequiredComponentVariable SecurityProfile;
|
||||
extern const ComponentVariable AllowCSMSRootCertInstallWithUnsecureConnection;
|
||||
extern const ComponentVariable AllowMFRootCertInstallWithUnsecureConnection;
|
||||
extern const ComponentVariable ACPhaseSwitchingSupported;
|
||||
extern const ComponentVariable SmartChargingCtrlrAvailable;
|
||||
extern const ComponentVariable SmartChargingCtrlrEnabled;
|
||||
extern const RequiredComponentVariable EntriesChargingProfiles;
|
||||
extern const ComponentVariable ExternalControlSignalsEnabled;
|
||||
extern const RequiredComponentVariable LimitChangeSignificance;
|
||||
extern const ComponentVariable NotifyChargingLimitWithSchedules;
|
||||
extern const RequiredComponentVariable PeriodsPerSchedule;
|
||||
extern const RequiredComponentVariable CompositeScheduleDefaultLimitAmps;
|
||||
extern const RequiredComponentVariable CompositeScheduleDefaultLimitWatts;
|
||||
extern const RequiredComponentVariable CompositeScheduleDefaultNumberPhases;
|
||||
extern const RequiredComponentVariable SupplyVoltage;
|
||||
extern const ComponentVariable Phases3to1;
|
||||
extern const RequiredComponentVariable ChargingProfileMaxStackLevel;
|
||||
extern const RequiredComponentVariable ChargingScheduleChargingRateUnit;
|
||||
extern const ComponentVariable IgnoredProfilePurposesOffline;
|
||||
extern const ComponentVariable ChargingProfilePersistenceTxProfile;
|
||||
extern const ComponentVariable ChargingProfilePersistenceChargingStationExternalConstraints;
|
||||
extern const ComponentVariable ChargingProfilePersistenceLocalGeneration;
|
||||
extern const ComponentVariable ChargingProfileUpdateRateLimit;
|
||||
extern const ComponentVariable MaxExternalConstraintsId;
|
||||
extern const ComponentVariable SupportedAdditionalPurposes;
|
||||
extern const ComponentVariable SupportsDynamicProfiles;
|
||||
extern const ComponentVariable SupportsUseLocalTime;
|
||||
extern const ComponentVariable SupportsRandomizedDelay;
|
||||
extern const ComponentVariable SupportsLimitAtSoC;
|
||||
extern const ComponentVariable SupportsEvseSleep;
|
||||
extern const ComponentVariable TariffCostCtrlrAvailableTariff;
|
||||
extern const ComponentVariable TariffCostCtrlrAvailableCost;
|
||||
extern const RequiredComponentVariable TariffCostCtrlrCurrency;
|
||||
extern const ComponentVariable TariffCostCtrlrEnabledTariff;
|
||||
extern const ComponentVariable TariffCostCtrlrEnabledCost;
|
||||
extern const RequiredComponentVariable TariffFallbackMessage;
|
||||
extern const ComponentVariable OfflineTariffFallbackMessage;
|
||||
extern const RequiredComponentVariable TotalCostFallbackMessage;
|
||||
extern const ComponentVariable NumberOfDecimalsForCostValues;
|
||||
extern const RequiredComponentVariable EVConnectionTimeOut;
|
||||
extern const ComponentVariable MaxEnergyOnInvalidId;
|
||||
extern const RequiredComponentVariable StopTxOnEVSideDisconnect;
|
||||
extern const RequiredComponentVariable StopTxOnInvalidId;
|
||||
extern const ComponentVariable TxBeforeAcceptedEnabled;
|
||||
extern const RequiredComponentVariable TxStartPoint;
|
||||
extern const RequiredComponentVariable TxStopPoint;
|
||||
extern const ComponentVariable ISO15118CtrlrAvailable;
|
||||
|
||||
// OCPP1.6 mavericks: The following ComponentVariable definitions are required because some OCPP1.6 configuration keys
|
||||
// do not map to any existing component variable combination in OCPP2.x. The following definitions only control the
|
||||
// OCPP1.6 implementation
|
||||
extern const ComponentVariable BlinkRepeat;
|
||||
extern const ComponentVariable ConnectorPhaseRotation;
|
||||
extern const ComponentVariable ConnectorPhaseRotationMaxLength;
|
||||
extern const RequiredComponentVariable GetConfigurationMaxKeys;
|
||||
extern const ComponentVariable LightIntensity;
|
||||
extern const ComponentVariable MinimumStatusDuration;
|
||||
extern const ComponentVariable StopTransactionOnEVSideDisconnect;
|
||||
extern const RequiredComponentVariable SupportedFeatureProfiles;
|
||||
extern const ComponentVariable SupportedFeatureProfilesMaxLength;
|
||||
extern const RequiredComponentVariable UnlockConnectorOnEVSideDisconnect;
|
||||
extern const ComponentVariable ReserveConnectorZeroSupported;
|
||||
extern const ComponentVariable HostName;
|
||||
extern const ComponentVariable AllowChargingProfileWithoutStartSchedule;
|
||||
extern const ComponentVariable WaitForStopTransactionsOnResetTimeout;
|
||||
extern const ComponentVariable StopTransactionIfUnlockNotSupported;
|
||||
extern const ComponentVariable MeterPublicKeys;
|
||||
extern const ComponentVariable DisableSecurityEventNotifications;
|
||||
extern const ComponentVariable ISO15118CertificateManagementEnabled;
|
||||
extern const ComponentVariable CustomDisplayCostAndPrice; // Required only if CaliforniaPricing enabled
|
||||
extern const ComponentVariable DefaultPrice;
|
||||
extern const ComponentVariable DefaultPriceText;
|
||||
extern const ComponentVariable CustomIdleFeeAfterStop;
|
||||
extern const ComponentVariable SupportedLanguages;
|
||||
extern const ComponentVariable CustomMultiLanguageMessages;
|
||||
extern const ComponentVariable Language;
|
||||
extern const ComponentVariable WaitForSetUserPriceTimeout;
|
||||
extern const ComponentVariable AuthorizationKey16;
|
||||
extern const RequiredComponentVariable CentralSystemURI16;
|
||||
extern const RequiredComponentVariable SecurityProfile16;
|
||||
} // namespace ControllerComponentVariables
|
||||
|
||||
namespace EvseComponentVariables {
|
||||
extern const Variable Available;
|
||||
extern const Variable AvailabilityState;
|
||||
extern const Variable SupplyPhases;
|
||||
extern const Variable AllowReset;
|
||||
extern const Variable Power;
|
||||
extern const Variable DCInputPhaseControl;
|
||||
extern const Variable ISO15118EvseId;
|
||||
ComponentVariable get_component_variable(const std::int32_t evse_id, const Variable& variable);
|
||||
} // namespace EvseComponentVariables
|
||||
|
||||
namespace ConnectorComponentVariables {
|
||||
extern const Variable Available;
|
||||
extern const Variable AvailabilityState;
|
||||
extern const Variable Type;
|
||||
extern const Variable SupplyPhases;
|
||||
ComponentVariable get_component_variable(const std::int32_t evse_id, const std::int32_t connector_id,
|
||||
const Variable& variable);
|
||||
} // namespace ConnectorComponentVariables
|
||||
|
||||
namespace V2xComponentVariables {
|
||||
extern const Variable Available;
|
||||
extern const Variable Enabled;
|
||||
extern const Variable SupportedEnergyTransferModes;
|
||||
extern const Variable SupportedOperationModes;
|
||||
extern const Variable TxStartedMeasurands;
|
||||
extern const Variable TxEndedMeasurands;
|
||||
extern const Variable TxEndedInterval;
|
||||
extern const Variable TxUpdatedMeasurands;
|
||||
extern const Variable TxUpdatedInterval;
|
||||
Variable get_v2x_tx_started_measurands(const OperationModeEnum& mode);
|
||||
Variable get_v2x_tx_ended_measurands(const OperationModeEnum& mode);
|
||||
Variable get_v2x_tx_ended_interval(const OperationModeEnum& mode);
|
||||
Variable get_v2x_tx_updated_measurands(const OperationModeEnum& mode);
|
||||
Variable get_v2x_tx_updated_interval(const OperationModeEnum& mode);
|
||||
ComponentVariable get_component_variable(const std::int32_t evse_id, const Variable& variable);
|
||||
} // namespace V2xComponentVariables
|
||||
|
||||
namespace ISO15118ComponentVariables {
|
||||
extern const Variable Enabled;
|
||||
extern const Variable ServiceRenegotiationSupport;
|
||||
extern const Variable ProtocolSupported;
|
||||
// These variables are defined again here as it is possible to have either a global variable or evse specific
|
||||
extern const Variable SeccId;
|
||||
extern const Variable CountryName;
|
||||
extern const Variable OrganizationName;
|
||||
ComponentVariable get_component_variable(const std::int32_t evse_id, const Variable& variable);
|
||||
} // namespace ISO15118ComponentVariables
|
||||
|
||||
namespace ConnectedEvComponentVariables {
|
||||
extern const Variable Available;
|
||||
extern const Variable VehicleId;
|
||||
extern const Variable ProtocolAgreed;
|
||||
extern const Variable VehicleCertificateLeaf;
|
||||
extern const Variable VehicleCertificateSubCa1;
|
||||
extern const Variable VehicleCertificateSubCa2;
|
||||
extern const Variable VehicleCertificateRoot;
|
||||
Variable get_protocol_supported_by_ev(const std::int32_t priority);
|
||||
ComponentVariable get_component_variable(const std::int32_t evse_id, const Variable& variable);
|
||||
} // namespace ConnectedEvComponentVariables
|
||||
|
||||
namespace NetworkConfigurationComponentVariables {
|
||||
extern const Variable OcppCsmsUrl;
|
||||
extern const Variable SecurityProfile;
|
||||
extern const Variable OcppInterface;
|
||||
extern const Variable OcppTransport;
|
||||
extern const Variable MessageTimeout;
|
||||
extern const Variable Identity;
|
||||
extern const Variable BasicAuthPassword;
|
||||
extern const Variable ApnEnabled;
|
||||
extern const Variable VpnEnabled;
|
||||
extern const Variable Apn;
|
||||
extern const Variable ApnUserName;
|
||||
extern const Variable ApnPassword;
|
||||
extern const Variable SimPin;
|
||||
extern const Variable PreferredNetwork;
|
||||
extern const Variable UseOnlyPreferredNetwork;
|
||||
extern const Variable ApnAuthentication;
|
||||
extern const Variable VpnServer;
|
||||
extern const Variable VpnUser;
|
||||
extern const Variable VpnPassword;
|
||||
extern const Variable VpnKey;
|
||||
extern const Variable VpnType;
|
||||
extern const Variable VpnGroup;
|
||||
extern const Variable OcppVersion;
|
||||
extern const Variable CsmsRootCertificateHashAlgorithm;
|
||||
extern const Variable CsmsRootCertificateIssuerKeyHash;
|
||||
extern const Variable CsmsRootCertificateIssuerNameHash;
|
||||
extern const Variable CsmsRootCertificateSerialNumber;
|
||||
ComponentVariable get_component_variable(const std::int32_t slot, const Variable& variable);
|
||||
std::optional<NetworkConnectionProfile> read_profile_from_device_model(DeviceModelInterface& dm, int32_t slot);
|
||||
bool write_profile_to_device_model(DeviceModelInterface& dm, int32_t slot, const NetworkConnectionProfile& profile,
|
||||
const std::string& source);
|
||||
void migrate_from_blob_if_needed(DeviceModelInterface& dm);
|
||||
void clear_slot_in_device_model(DeviceModelInterface& dm, int32_t slot);
|
||||
} // namespace NetworkConfigurationComponentVariables
|
||||
|
||||
namespace DERComponentVariables {
|
||||
extern const Variable Available;
|
||||
extern const Variable ModesSupported;
|
||||
ComponentVariable get_dc_component_variable(const std::int32_t evse_id, const Variable& variable);
|
||||
ComponentVariable get_ac_component_variable(const std::int32_t evse_id, const Variable& variable);
|
||||
} // namespace DERComponentVariables
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V2_CTRLR_COMPONENT_VARIABLES
|
||||
@@ -0,0 +1,400 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
#ifndef OCPP_V2_DATABASE_HANDLER_HPP
|
||||
#define OCPP_V2_DATABASE_HANDLER_HPP
|
||||
|
||||
#include "ocpp/v2/types.hpp"
|
||||
#include "sqlite3.h"
|
||||
#include <memory>
|
||||
#include <ocpp/common/support_older_cpp_versions.hpp>
|
||||
|
||||
#include <everest/database/sqlite/connection.hpp>
|
||||
#include <ocpp/common/database/database_handler_common.hpp>
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
#include <ocpp/v2/transaction.hpp>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
/// \brief Helper class for retrieving authorization cache entries from the database
|
||||
struct AuthorizationCacheEntry {
|
||||
IdTokenInfo id_token_info;
|
||||
DateTime last_used;
|
||||
};
|
||||
|
||||
class DatabaseHandlerInterface {
|
||||
public:
|
||||
virtual ~DatabaseHandlerInterface() = default;
|
||||
|
||||
// Authorization cache management
|
||||
|
||||
/// \brief Inserts cache entry
|
||||
/// \param id_token_hash
|
||||
/// \param id_token_info
|
||||
virtual void authorization_cache_insert_entry(const std::string& id_token_hash,
|
||||
const IdTokenInfo& id_token_info) = 0;
|
||||
|
||||
/// \brief Updates the last_used field in the entry
|
||||
///
|
||||
/// \param id_token_hash
|
||||
/// \retval true if entry was updated
|
||||
virtual void authorization_cache_update_last_used(const std::string& id_token_hash) = 0;
|
||||
|
||||
/// \brief Gets cache entry for given \p id_token_hash if present
|
||||
/// \param id_token_hash
|
||||
/// \return
|
||||
virtual std::optional<AuthorizationCacheEntry> authorization_cache_get_entry(const std::string& id_token_hash) = 0;
|
||||
|
||||
/// \brief Deletes the cache entry for the given \p id_token_hash
|
||||
/// \param id_token_hash
|
||||
virtual void authorization_cache_delete_entry(const std::string& id_token_hash) = 0;
|
||||
|
||||
/// \brief Removes up to \p nr_to_remove items from the cache starting from the least recently used
|
||||
///
|
||||
/// \param nr_to_remove Number of items to remove from the database
|
||||
/// \retval True if succeeded
|
||||
virtual void authorization_cache_delete_nr_of_oldest_entries(size_t nr_to_remove) = 0;
|
||||
|
||||
/// \brief Removes all entries from the cache that have passed their expiry date or auth cache lifetime
|
||||
///
|
||||
/// \param auth_cache_lifetime The maximum time tokens can stay in the cache without being used
|
||||
/// \retval True if succeeded
|
||||
virtual void
|
||||
authorization_cache_delete_expired_entries(std::optional<std::chrono::seconds> auth_cache_lifetime) = 0;
|
||||
|
||||
/// \brief Deletes all entries of the AUTH_CACHE table. Returns true if the operation was successful, else false
|
||||
virtual void authorization_cache_clear() = 0;
|
||||
|
||||
/// \brief Get the binary size of the authorization cache table
|
||||
///
|
||||
/// \retval The size of the authorization cache table in bytes
|
||||
virtual size_t authorization_cache_get_binary_size() = 0;
|
||||
|
||||
// Availability
|
||||
|
||||
/// \brief Persist operational settings for the charging station
|
||||
virtual void insert_cs_availability(OperationalStatusEnum operational_status, bool replace) = 0;
|
||||
/// \brief Retrieve persisted operational settings for the charging station
|
||||
virtual OperationalStatusEnum get_cs_availability() = 0;
|
||||
|
||||
/// \brief Persist operational settings for an EVSE
|
||||
virtual void insert_evse_availability(std::int32_t evse_id, OperationalStatusEnum operational_status,
|
||||
bool replace) = 0;
|
||||
/// \brief Retrieve persisted operational settings for an EVSE
|
||||
virtual OperationalStatusEnum get_evse_availability(std::int32_t evse_id) = 0;
|
||||
|
||||
/// \brief Persist operational settings for a connector
|
||||
virtual void insert_connector_availability(std::int32_t evse_id, std::int32_t connector_id,
|
||||
OperationalStatusEnum operational_status, bool replace) = 0;
|
||||
/// \brief Retrieve persisted operational settings for a connector
|
||||
virtual OperationalStatusEnum get_connector_availability(std::int32_t evse_id, std::int32_t connector_id) = 0;
|
||||
|
||||
// Local authorization list management
|
||||
|
||||
/// \brief Inserts or updates the given \p version in the AUTH_LIST_VERSION table.
|
||||
virtual void insert_or_update_local_authorization_list_version(std::int32_t version) = 0;
|
||||
|
||||
/// \brief Returns the version in the AUTH_LIST_VERSION table.
|
||||
virtual std::int32_t get_local_authorization_list_version() = 0;
|
||||
|
||||
/// \brief Inserts or updates a local authorization list entry to the AUTH_LIST table.
|
||||
virtual void insert_or_update_local_authorization_list_entry(const IdToken& id_token,
|
||||
const IdTokenInfo& id_token_info) = 0;
|
||||
|
||||
/// \brief Inserts or updates a local authorization list entries \p local_authorization_list to the AUTH_LIST table.
|
||||
virtual void
|
||||
insert_or_update_local_authorization_list(const std::vector<v2::AuthorizationData>& local_authorization_list) = 0;
|
||||
|
||||
/// \brief Deletes the authorization list entry with the given \p id_tag
|
||||
virtual void delete_local_authorization_list_entry(const IdToken& id_token) = 0;
|
||||
|
||||
/// \brief Returns the IdTagInfo of the given \p id_tag if it exists in the AUTH_LIST table, else std::nullopt.
|
||||
virtual std::optional<v2::IdTokenInfo> get_local_authorization_list_entry(const IdToken& id_token) = 0;
|
||||
|
||||
/// \brief Deletes all entries of the AUTH_LIST table.
|
||||
virtual void clear_local_authorization_list() = 0;
|
||||
|
||||
/// \brief Get the number of entries currently in the authorization list
|
||||
virtual std::int32_t get_local_authorization_list_number_of_entries() = 0;
|
||||
|
||||
// Transaction metervalues
|
||||
|
||||
/// \brief Inserts a \p meter_value to the database linked to transaction with id \p transaction_id
|
||||
virtual void transaction_metervalues_insert(const std::string& transaction_id, const MeterValue& meter_value) = 0;
|
||||
|
||||
/// \brief Get all metervalues linked to transaction with id \p transaction_id
|
||||
virtual std::vector<MeterValue> transaction_metervalues_get_all(const std::string& transaction_id) = 0;
|
||||
|
||||
/// \brief Remove all metervalue entries linked to transaction with id \p transaction_id
|
||||
virtual void transaction_metervalues_clear(const std::string& transaction_id) = 0;
|
||||
|
||||
// transactions
|
||||
|
||||
/// \brief Inserts a transaction with the given parameters to the TRANSACTIONS table
|
||||
/// \param transaction
|
||||
/// \param evse_id
|
||||
virtual void transaction_insert(const EnhancedTransaction& transaction, std::int32_t evse_id) = 0;
|
||||
|
||||
/// \brief Gets a transaction from the database if one can be found using \p evse_id
|
||||
/// \param evse_id The evse id to get the transaction for
|
||||
/// \return nullptr if not found, otherwise an enhanced transaction object.
|
||||
virtual std::unique_ptr<EnhancedTransaction> transaction_get(const std::int32_t evse_id) = 0;
|
||||
|
||||
/// \brief Update the sequence number of the given transaction id in the database.
|
||||
/// \param transaction_id
|
||||
/// \param seq_no
|
||||
virtual void transaction_update_seq_no(const std::string& transaction_id, std::int32_t seq_no) = 0;
|
||||
|
||||
/// \brief Update the charging state of the given transaction id in the database.
|
||||
/// \param transaction_id
|
||||
/// \param charging_state
|
||||
virtual void transaction_update_charging_state(const std::string& transaction_id,
|
||||
const ChargingStateEnum charging_state) = 0;
|
||||
|
||||
/// \brief Update the id_token_sent of the given transaction id in the database.
|
||||
/// \param transaction_id
|
||||
/// \param id_token_sent
|
||||
virtual void transaction_update_id_token_sent(const std::string& transaction_id, bool id_token_sent) = 0;
|
||||
|
||||
/// \brief Clear all the transactions from the TRANSACTIONS table.
|
||||
/// \param transaction_id transaction id of the transaction to clear from.
|
||||
/// \return true if succeeded
|
||||
virtual void transaction_delete(const std::string& transaction_id) = 0;
|
||||
|
||||
/// charging profiles
|
||||
|
||||
/// \brief Inserts or updates the given \p profile to CHARGING_PROFILES table
|
||||
virtual void insert_or_update_charging_profile(
|
||||
const int evse_id, const v2::ChargingProfile& profile,
|
||||
const CiString<20> charging_limit_source = ChargingLimitSourceEnumStringType::CSO) = 0;
|
||||
|
||||
/// \brief Deletes the profile with the given \p profile_id
|
||||
virtual bool delete_charging_profile(const int profile_id) = 0;
|
||||
|
||||
/// \brief Deletes the profiles with the given \p transaction_id
|
||||
virtual void delete_charging_profile_by_transaction_id(const std::string& transaction_id) = 0;
|
||||
|
||||
/// \brief Deletes all profiles from table CHARGING_PROFILES
|
||||
virtual bool clear_charging_profiles() = 0;
|
||||
|
||||
/// \brief Deletes all profiles from table CHARGING_PROFILES matching \p profile_id or \p criteria.
|
||||
/// \return the ids of the rows actually deleted (empty when nothing matched).
|
||||
virtual std::vector<std::int32_t>
|
||||
clear_charging_profiles_matching_criteria(const std::optional<std::int32_t> profile_id,
|
||||
const std::optional<ClearChargingProfile>& criteria) = 0;
|
||||
|
||||
/// \brief Get all profiles from table CHARGING_PROFILES matching \p profile_id or \p criteria
|
||||
virtual std::vector<ReportedChargingProfile>
|
||||
get_charging_profiles_matching_criteria(const std::optional<std::int32_t> evse_id,
|
||||
const ChargingProfileCriterion& criteria) = 0;
|
||||
|
||||
/// \brief Retrieves the charging profiles stored on \p evse_id
|
||||
virtual std::vector<v2::ChargingProfile> get_charging_profiles_for_evse(const int evse_id) = 0;
|
||||
|
||||
/// \brief Retrieves all ChargingProfiles
|
||||
virtual std::vector<v2::ChargingProfile> get_all_charging_profiles() = 0;
|
||||
|
||||
/// \brief Retrieves all ChargingProfiles grouped by EVSE ID
|
||||
virtual std::map<std::int32_t, std::vector<v2::ChargingProfile>> get_all_charging_profiles_group_by_evse() = 0;
|
||||
|
||||
virtual CiString<20> get_charging_limit_source_for_profile(const int profile_id) = 0;
|
||||
|
||||
// DER Control persistence (OCPP 2.1 R04)
|
||||
|
||||
/// \brief Inserts or updates a DER control in DER_CONTROLS table
|
||||
virtual void insert_or_update_der_control(const std::string& control_id, bool is_default,
|
||||
const std::string& control_type, bool is_superseded, int32_t priority,
|
||||
const std::optional<std::string>& start_time,
|
||||
const std::optional<float>& duration,
|
||||
const std::string& control_json) = 0;
|
||||
|
||||
/// \brief Retrieves a single DER control by control_id
|
||||
virtual std::optional<std::string> get_der_control(const std::string& control_id) = 0;
|
||||
|
||||
/// \brief Total number of rows currently in DER_CONTROLS. Used by the DER control
|
||||
/// handler to cap the table so a CSMS cannot grow the DB unbounded by issuing
|
||||
/// SetDERControl with ever-unique controlIds.
|
||||
virtual std::size_t count_der_controls() = 0;
|
||||
|
||||
/// \brief Retrieves DER controls matching optional filter criteria
|
||||
virtual std::vector<std::string>
|
||||
get_der_controls_matching_criteria(const std::optional<bool>& is_default,
|
||||
const std::optional<std::string>& control_type,
|
||||
const std::optional<std::string>& control_id) = 0;
|
||||
|
||||
/// \brief Deletes a DER control by control_id. Returns true if a row was deleted.
|
||||
virtual bool delete_der_control(const std::string& control_id) = 0;
|
||||
|
||||
/// \brief Deletes a DER control whose CONTROL_ID AND IS_DEFAULT both match.
|
||||
/// Returns true if a row was deleted. Needed for R04.FR.42 so ClearDERControl
|
||||
/// scoped by isDefault won't accidentally delete a row of the opposite kind.
|
||||
virtual bool delete_der_control_by_id_and_default(const std::string& control_id, bool is_default) = 0;
|
||||
|
||||
/// \brief Deletes DER controls matching is_default and optional control_type. Returns number of rows deleted.
|
||||
virtual int delete_der_controls_matching_criteria(bool is_default,
|
||||
const std::optional<std::string>& control_type) = 0;
|
||||
|
||||
/// \brief Updates the is_superseded flag for a DER control
|
||||
virtual void update_der_control_superseded(const std::string& control_id, bool is_superseded) = 0;
|
||||
|
||||
/// \brief Append \p displaced_id to the \p control_id row's CONTROL_JSON.displacedIds
|
||||
/// array. Creates the array if it does not yet exist. Used at deferred-supersede
|
||||
/// activation so the row records the controlId it ended up displacing; the expiry
|
||||
/// handler reads this back to populate FR.22 NotifyDERStartStop.supersededIds.
|
||||
virtual void append_der_control_displaced_id(const std::string& control_id, const std::string& displaced_id) = 0;
|
||||
|
||||
/// \brief R04.FR.07: record that \p new_control_id, once activated, will supersede
|
||||
/// \p existing_control_id. The flip is performed later by a scheduled-check pass.
|
||||
virtual void set_der_control_pending_supersede(const std::string& new_control_id,
|
||||
const std::string& existing_control_id) = 0;
|
||||
|
||||
/// \brief R04.FR.07: clear the pending-supersede pointer for \p control_id after
|
||||
/// the deferred supersede has been performed.
|
||||
virtual void clear_der_control_pending_supersede(const std::string& control_id) = 0;
|
||||
|
||||
/// \brief A pending-supersede activation: when \p new_id 's start time has arrived,
|
||||
/// \p existing_id should be flipped to isSuperseded=true and \p new_id started.
|
||||
struct PendingSupersedeActivation {
|
||||
std::string new_id;
|
||||
std::string existing_id;
|
||||
};
|
||||
|
||||
/// \brief R04.FR.07: return all rows whose PENDING_SUPERSEDE_ID is set and whose
|
||||
/// START_TIME is at or before \p now. Caller is responsible for performing the
|
||||
/// flip + notify + clear inside a transaction.
|
||||
virtual std::vector<PendingSupersedeActivation>
|
||||
get_der_control_pending_supersede_activations(const DateTime& now) = 0;
|
||||
|
||||
/// \brief R04.FR.20/21: return all scheduled, non-superseded rows with
|
||||
/// START_TIME <= \p now that have not yet been flagged STARTED_NOTIFIED.
|
||||
/// Caller emits NotifyDERStartStop(started=true) for each and then calls
|
||||
/// \ref mark_der_control_started_notified on the same id.
|
||||
virtual std::vector<std::string> get_der_controls_needing_start_notify(const DateTime& now) = 0;
|
||||
|
||||
/// \brief R04.FR.20/21: flag a row as having had its start notification emitted.
|
||||
virtual void mark_der_control_started_notified(const std::string& control_id) = 0;
|
||||
|
||||
virtual std::unique_ptr<everest::db::sqlite::StatementInterface> new_statement(const std::string& sql) = 0;
|
||||
|
||||
/// \brief Begin a database transaction. Destructor rolls back unless commit() is called.
|
||||
[[nodiscard]] virtual std::unique_ptr<everest::db::sqlite::TransactionInterface> begin_transaction() = 0;
|
||||
};
|
||||
|
||||
class DatabaseHandler : public DatabaseHandlerInterface, public common::DatabaseHandlerCommon {
|
||||
private:
|
||||
void init_sql() override;
|
||||
|
||||
void inintialize_enum_tables();
|
||||
void init_enum_table_inner(const std::string& table_name, const int begin, const int end,
|
||||
std::function<std::string(int)> conversion);
|
||||
template <typename T>
|
||||
void init_enum_table(const std::string& table_name, T begin, T end, std::function<std::string(T)> conversion);
|
||||
|
||||
// Availability management (internal helpers)
|
||||
// Setting evse_id to 0 addresses the whole CS, setting evse_id > 0 and connector_id=0 addresses a whole EVSE
|
||||
void insert_availability(std::int32_t evse_id, std::int32_t connector_id, OperationalStatusEnum operational_status,
|
||||
bool replace);
|
||||
OperationalStatusEnum get_availability(std::int32_t evse_id, std::int32_t connector_id);
|
||||
|
||||
public:
|
||||
DatabaseHandler(std::unique_ptr<everest::db::sqlite::ConnectionInterface> database,
|
||||
const fs::path& sql_migration_files_path);
|
||||
|
||||
// Authorization cache management
|
||||
void authorization_cache_insert_entry(const std::string& id_token_hash, const IdTokenInfo& id_token_info) override;
|
||||
void authorization_cache_update_last_used(const std::string& id_token_hash) override;
|
||||
std::optional<AuthorizationCacheEntry> authorization_cache_get_entry(const std::string& id_token_hash) override;
|
||||
void authorization_cache_delete_entry(const std::string& id_token_hash) override;
|
||||
void authorization_cache_delete_nr_of_oldest_entries(size_t nr_to_remove) override;
|
||||
void authorization_cache_delete_expired_entries(std::optional<std::chrono::seconds> auth_cache_lifetime) override;
|
||||
void authorization_cache_clear() override;
|
||||
size_t authorization_cache_get_binary_size() override;
|
||||
|
||||
// Availability
|
||||
void insert_cs_availability(OperationalStatusEnum operational_status, bool replace) override;
|
||||
OperationalStatusEnum get_cs_availability() override;
|
||||
void insert_evse_availability(std::int32_t evse_id, OperationalStatusEnum operational_status,
|
||||
bool replace) override;
|
||||
OperationalStatusEnum get_evse_availability(std::int32_t evse_id) override;
|
||||
void insert_connector_availability(std::int32_t evse_id, std::int32_t connector_id,
|
||||
OperationalStatusEnum operational_status, bool replace) override;
|
||||
OperationalStatusEnum get_connector_availability(std::int32_t evse_id, std::int32_t connector_id) override;
|
||||
|
||||
// Local authorization list management
|
||||
void insert_or_update_local_authorization_list_version(std::int32_t version) override;
|
||||
std::int32_t get_local_authorization_list_version() override;
|
||||
void insert_or_update_local_authorization_list_entry(const IdToken& id_token,
|
||||
const IdTokenInfo& id_token_info) override;
|
||||
void insert_or_update_local_authorization_list(
|
||||
const std::vector<v2::AuthorizationData>& local_authorization_list) override;
|
||||
void delete_local_authorization_list_entry(const IdToken& id_token) override;
|
||||
std::optional<v2::IdTokenInfo> get_local_authorization_list_entry(const IdToken& id_token) override;
|
||||
void clear_local_authorization_list() override;
|
||||
std::int32_t get_local_authorization_list_number_of_entries() override;
|
||||
|
||||
// Transaction metervalues
|
||||
void transaction_metervalues_insert(const std::string& transaction_id, const MeterValue& meter_value) override;
|
||||
std::vector<MeterValue> transaction_metervalues_get_all(const std::string& transaction_id) override;
|
||||
void transaction_metervalues_clear(const std::string& transaction_id) override;
|
||||
|
||||
// transactions
|
||||
void transaction_insert(const EnhancedTransaction& transaction, std::int32_t evse_id) override;
|
||||
std::unique_ptr<EnhancedTransaction> transaction_get(const std::int32_t evse_id) override;
|
||||
void transaction_update_seq_no(const std::string& transaction_id, std::int32_t seq_no) override;
|
||||
void transaction_update_charging_state(const std::string& transaction_id,
|
||||
const ChargingStateEnum charging_state) override;
|
||||
void transaction_update_id_token_sent(const std::string& transaction_id, bool id_token_sent) override;
|
||||
void transaction_delete(const std::string& transaction_id) override;
|
||||
|
||||
/// charging profiles
|
||||
void insert_or_update_charging_profile(
|
||||
const int evse_id, const v2::ChargingProfile& profile,
|
||||
const CiString<20> charging_limit_source = ChargingLimitSourceEnumStringType::CSO) override;
|
||||
bool delete_charging_profile(const int profile_id) override;
|
||||
void delete_charging_profile_by_transaction_id(const std::string& transaction_id) override;
|
||||
bool clear_charging_profiles() override;
|
||||
std::vector<std::int32_t>
|
||||
clear_charging_profiles_matching_criteria(const std::optional<std::int32_t> profile_id,
|
||||
const std::optional<ClearChargingProfile>& criteria) override;
|
||||
std::vector<ReportedChargingProfile>
|
||||
get_charging_profiles_matching_criteria(const std::optional<std::int32_t> evse_id,
|
||||
const ChargingProfileCriterion& criteria) override;
|
||||
std::vector<v2::ChargingProfile> get_charging_profiles_for_evse(const int evse_id) override;
|
||||
std::vector<v2::ChargingProfile> get_all_charging_profiles() override;
|
||||
std::map<std::int32_t, std::vector<v2::ChargingProfile>> get_all_charging_profiles_group_by_evse() override;
|
||||
CiString<20> get_charging_limit_source_for_profile(const int profile_id) override;
|
||||
|
||||
// DER Control persistence
|
||||
void insert_or_update_der_control(const std::string& control_id, bool is_default, const std::string& control_type,
|
||||
bool is_superseded, int32_t priority,
|
||||
const std::optional<std::string>& start_time,
|
||||
const std::optional<float>& duration, const std::string& control_json) override;
|
||||
std::optional<std::string> get_der_control(const std::string& control_id) override;
|
||||
std::size_t count_der_controls() override;
|
||||
std::vector<std::string> get_der_controls_matching_criteria(const std::optional<bool>& is_default,
|
||||
const std::optional<std::string>& control_type,
|
||||
const std::optional<std::string>& control_id) override;
|
||||
bool delete_der_control(const std::string& control_id) override;
|
||||
bool delete_der_control_by_id_and_default(const std::string& control_id, bool is_default) override;
|
||||
int delete_der_controls_matching_criteria(bool is_default, const std::optional<std::string>& control_type) override;
|
||||
void update_der_control_superseded(const std::string& control_id, bool is_superseded) override;
|
||||
void append_der_control_displaced_id(const std::string& control_id, const std::string& displaced_id) override;
|
||||
|
||||
std::unique_ptr<everest::db::sqlite::StatementInterface> new_statement(const std::string& sql) override;
|
||||
|
||||
void set_der_control_pending_supersede(const std::string& new_control_id,
|
||||
const std::string& existing_control_id) override;
|
||||
void clear_der_control_pending_supersede(const std::string& control_id) override;
|
||||
std::vector<PendingSupersedeActivation> get_der_control_pending_supersede_activations(const DateTime& now) override;
|
||||
std::vector<std::string> get_der_controls_needing_start_notify(const DateTime& now) override;
|
||||
void mark_der_control_started_notified(const std::string& control_id) override;
|
||||
|
||||
[[nodiscard]] std::unique_ptr<everest::db::sqlite::TransactionInterface> begin_transaction() override;
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,157 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef DEVICE_MODEL_HPP
|
||||
#define DEVICE_MODEL_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
#include <ocpp/v2/ctrlr_component_variables.hpp>
|
||||
#include <ocpp/v2/device_model_abstract.hpp>
|
||||
#include <ocpp/v2/device_model_storage_interface.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
using on_variable_changed = std::function<void(
|
||||
const std::unordered_map<std::int64_t, VariableMonitoringMeta>& monitors, const Component& component,
|
||||
const Variable& variable, const VariableCharacteristics& characteristics, const VariableAttribute& attribute,
|
||||
const std::string& value_previous, const std::string& value_current)>;
|
||||
|
||||
using on_monitor_updated = std::function<void(const VariableMonitoringMeta& updated_monitor, const Component& component,
|
||||
const Variable& variable, const VariableCharacteristics& characteristics,
|
||||
const VariableAttribute& attribute, const std::string& current_value)>;
|
||||
|
||||
/// \brief This class manages access to the device model representation and to the device model interface and provides
|
||||
/// functionality to support the use cases defined in the functional block Provisioning
|
||||
class DeviceModel : public DeviceModelAbstract {
|
||||
|
||||
private:
|
||||
DeviceModelMap device_model_map;
|
||||
std::unique_ptr<DeviceModelStorageInterface> device_model;
|
||||
|
||||
/// \brief Listener for the internal change of a variable
|
||||
std::vector<on_variable_changed> variable_listener;
|
||||
/// \brief Listener for the internal update of a monitor
|
||||
on_monitor_updated monitor_update_listener;
|
||||
|
||||
/// \brief Private helper method that does some checks with the device model representation in memory to evaluate if
|
||||
/// a value for the given parameters can be requested. If it can be requested it will be retrieved from the device
|
||||
/// model interface and the given \p value will be set to the value that was retrieved
|
||||
/// \param component_id
|
||||
/// \param variable_id
|
||||
/// \param attribute_enum
|
||||
/// \param value string reference to value: will be set to requested value if value is present
|
||||
/// \param allow_write_only true to allow a writeOnly value to be read.
|
||||
/// \return GetVariableStatusEnum that indicates the result of the request
|
||||
GetVariableStatusEnum request_value_internal(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, std::string& value,
|
||||
bool allow_write_only) const;
|
||||
|
||||
/// \brief Iterates over the given \p component_criteria and converts this to the variable names
|
||||
/// (Active,Available,Enabled,Problem). If any of the variables can not be found as part of a component this
|
||||
/// function returns false. If any of those variable's value is true, this function returns true (except for
|
||||
/// criteria problem). If all variable's value are false, this function returns false
|
||||
/// \param component_id
|
||||
/// \param /// component_criteria
|
||||
/// \return
|
||||
bool component_criteria_match(const Component& component_id,
|
||||
const std::vector<ComponentCriterionEnum>& component_criteria);
|
||||
|
||||
///
|
||||
/// \brief Helper function to check if a variable has a value.
|
||||
/// \param component_variable Component variable to check.
|
||||
/// \param attribute Attribute to check.
|
||||
///
|
||||
/// \throws DeviceModelError if variable has no value or value is an empty string.
|
||||
///
|
||||
void check_variable_has_value(const ComponentVariable& component_variable,
|
||||
const AttributeEnum attribute = AttributeEnum::Actual);
|
||||
|
||||
///
|
||||
/// \brief Helper function to check if a required variable has a value.
|
||||
/// \param required_variable Required component variable to check.
|
||||
/// \param supported_versions The current supported ocpp versions.
|
||||
/// \throws DeviceModelError if variable has no value or value is an empty string.
|
||||
///
|
||||
void check_required_variable(const RequiredComponentVariable& required_variable,
|
||||
const std::vector<OcppProtocolVersion>& supported_versions);
|
||||
|
||||
///
|
||||
/// \brief Loop over all required variables to check if they have a value.
|
||||
///
|
||||
/// This will check for all required variables from `ctrlr_component_variables.cpp` `required_variables`.
|
||||
/// It will also check for specific required variables that belong to a specific controller. If a controller is not
|
||||
/// available, the 'required' variables of that component are not required at this point.
|
||||
///
|
||||
/// \throws DeviceModelError if one of the variables does not have a value or value is an empty string.
|
||||
///
|
||||
void check_required_variables();
|
||||
|
||||
public:
|
||||
/// \brief Constructor for the device model
|
||||
/// \param device_model_storage_interface pointer to a device model interface class
|
||||
explicit DeviceModel(std::unique_ptr<DeviceModelStorageInterface> device_model_storage_interface);
|
||||
|
||||
GetVariableStatusEnum get_variable(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, std::string& value,
|
||||
bool allow_write_only = false) const override;
|
||||
|
||||
SetVariableStatusEnum set_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, const std::string& value,
|
||||
const std::string& source, bool allow_read_only = false) override;
|
||||
|
||||
bool create_network_configuration_slot_from_default_schema(std::int32_t new_slot) override;
|
||||
|
||||
SetVariableStatusEnum set_read_only_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, const std::string& value,
|
||||
const std::string& source) override;
|
||||
|
||||
SetVariableStatusEnum clear_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, const std::string& source) override;
|
||||
|
||||
std::optional<MutabilityEnum> get_mutability(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum) override;
|
||||
|
||||
std::optional<VariableMetaData> get_variable_meta_data(const Component& component_id,
|
||||
const Variable& variable_id) override;
|
||||
|
||||
std::vector<ReportData> get_base_report_data(const ReportBaseEnum& report_base) override;
|
||||
|
||||
std::vector<ReportData> get_custom_report_data(
|
||||
const std::optional<std::vector<ComponentVariable>>& component_variables = std::nullopt,
|
||||
const std::optional<std::vector<ComponentCriterionEnum>>& component_criteria = std::nullopt) override;
|
||||
|
||||
std::vector<SetMonitoringResult>
|
||||
set_monitors(const std::vector<SetMonitoringData>& requests,
|
||||
const VariableMonitorType type = VariableMonitorType::CustomMonitor) override;
|
||||
|
||||
bool update_monitor_reference(std::int32_t monitor_id, const std::string& reference_value) override;
|
||||
|
||||
std::vector<VariableMonitoringPeriodic> get_periodic_monitors() override;
|
||||
|
||||
std::vector<MonitoringData> get_monitors(const std::vector<MonitoringCriterionEnum>& criteria,
|
||||
const std::vector<ComponentVariable>& component_variables) override;
|
||||
|
||||
std::vector<ClearMonitoringResult> clear_monitors(const std::vector<int>& request_ids,
|
||||
bool allow_protected = false) override;
|
||||
|
||||
std::int32_t clear_custom_monitors() override;
|
||||
|
||||
void register_variable_listener(on_variable_changed&& listener) override {
|
||||
variable_listener.push_back(std::move(listener));
|
||||
}
|
||||
|
||||
void register_monitor_listener(on_monitor_updated&& listener) override {
|
||||
monitor_update_listener = std::move(listener);
|
||||
}
|
||||
|
||||
void check_integrity(const std::map<std::int32_t, std::int32_t>& evse_connector_structure) override;
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // DEVICE_MODEL_HPP
|
||||
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ocpp/v2/device_model_base.hpp>
|
||||
#include <ocpp/v2/device_model_interface.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
class DeviceModelAbstract : public DeviceModelBase, public DeviceModelInterface {};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,135 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
#include <ocpp/v2/comparators.hpp>
|
||||
#include <ocpp/v2/device_model_helpers.hpp>
|
||||
#include <ocpp/v2/device_model_interface.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
/// \brief Response to requesting a value from the device model
|
||||
/// \tparam T
|
||||
template <typename T> struct RequestDeviceModelResponse {
|
||||
GetVariableStatusEnum status;
|
||||
std::optional<T> value;
|
||||
};
|
||||
|
||||
/// \brief Base class for device model implementations, provides templated getters for variable attribute values
|
||||
class DeviceModelBase {
|
||||
|
||||
public:
|
||||
// ============================================================================
|
||||
// Value getters
|
||||
// ============================================================================
|
||||
|
||||
/// \brief Retrieves a variable attribute value
|
||||
/// \tparam T The target type (must be: std::string, int, double, size_t, DateTime, bool, or uint64_t)
|
||||
/// \param component_id The component
|
||||
/// \param variable_id The variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \return The requested value
|
||||
template <typename T>
|
||||
T get_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum = AttributeEnum::Actual) const {
|
||||
std::string value;
|
||||
const auto status = request_value_internal(component_id, variable_id, attribute_enum, value, true);
|
||||
|
||||
if (status != GetVariableStatusEnum::Accepted) {
|
||||
EVLOG_critical << "Required value " << variable_id.name << " of component " << component_id.name
|
||||
<< " could not be retrieved";
|
||||
EVLOG_AND_THROW(std::runtime_error("Required value not available"));
|
||||
}
|
||||
|
||||
return to_specific_type<T>(value);
|
||||
}
|
||||
|
||||
/// \brief Retrieves a variable attribute value
|
||||
/// \tparam T The target type (must be: std::string, int, double, size_t, DateTime, bool, or uint64_t)
|
||||
/// \param component_variable The component and variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \return The requested value
|
||||
template <typename T>
|
||||
T get_value(const ComponentVariable& component_variable,
|
||||
const AttributeEnum& attribute_enum = AttributeEnum::Actual) const {
|
||||
if (!component_variable.variable.has_value()) {
|
||||
EVLOG_critical << "ComponentVariable has no variable set for component: " << component_variable.component;
|
||||
EVLOG_AND_THROW(std::runtime_error("ComponentVariable has no variable set"));
|
||||
}
|
||||
return get_value<T>(component_variable.component, component_variable.variable.value(), attribute_enum);
|
||||
}
|
||||
|
||||
/// \brief Retrieves an optional variable attribute value
|
||||
/// \tparam T The target type (must be: std::string, int, double, size_t, DateTime, bool, or uint64_t)
|
||||
/// \param component_id The component
|
||||
/// \param variable_id The variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \return The requested value or std::nullopt
|
||||
template <typename T>
|
||||
std::optional<T> get_optional_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum = AttributeEnum::Actual) const {
|
||||
std::string value;
|
||||
const auto status = request_value_internal(component_id, variable_id, attribute_enum, value, true);
|
||||
|
||||
if (status != GetVariableStatusEnum::Accepted) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
try {
|
||||
return to_specific_type<T>(value);
|
||||
} catch (const std::exception&) {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Retrieves an optional variable attribute value
|
||||
/// \tparam T The target type (must be: std::string, int, double, size_t, DateTime, bool, or uint64_t)
|
||||
/// \param component_variable The component and variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \return The requested value or std::nullopt
|
||||
template <typename T>
|
||||
std::optional<T> get_optional_value(const ComponentVariable& component_variable,
|
||||
const AttributeEnum& attribute_enum = AttributeEnum::Actual) const {
|
||||
if (!component_variable.variable.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return get_optional_value<T>(component_variable.component, component_variable.variable.value(), attribute_enum);
|
||||
}
|
||||
|
||||
/// \brief Requests a value of a VariableAttribute specified by combination of \p component_id and \p variable_id
|
||||
/// from the device model
|
||||
/// \tparam T datatype of the value that is requested
|
||||
/// \param component_id
|
||||
/// \param variable_id
|
||||
/// \param attribute_enum
|
||||
/// \return Response to request that contains status of the request and the requested value as std::optional<T> .
|
||||
/// The value is present if the status is GetVariableStatusEnum::Accepted
|
||||
template <typename T>
|
||||
RequestDeviceModelResponse<T> request_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum) const {
|
||||
std::string value;
|
||||
const auto status = request_value_internal(component_id, variable_id, attribute_enum, value, false);
|
||||
|
||||
if (status != GetVariableStatusEnum::Accepted) {
|
||||
return {status, std::nullopt};
|
||||
}
|
||||
|
||||
try {
|
||||
return {status, to_specific_type<T>(value)};
|
||||
} catch (const std::exception&) {
|
||||
return {GetVariableStatusEnum::Rejected, std::nullopt};
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
virtual GetVariableStatusEnum request_value_internal(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, std::string& value,
|
||||
bool allow_write_only = false) const = 0;
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,157 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include <everest/logging.hpp>
|
||||
|
||||
#include <ocpp/common/utils.hpp>
|
||||
#include <ocpp/v2/device_model_interface.hpp>
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
template <typename T> T to_specific_type(const std::string& value) {
|
||||
static_assert(std::is_same_v<T, std::string> || std::is_same_v<T, int> || std::is_same_v<T, double> ||
|
||||
std::is_same_v<T, size_t> || std::is_same_v<T, DateTime> || std::is_same_v<T, bool> ||
|
||||
std::is_same_v<T, std::uint64_t>,
|
||||
"Requested unknown datatype");
|
||||
|
||||
if constexpr (std::is_same_v<T, std::string>) {
|
||||
return value;
|
||||
} else if constexpr (std::is_same_v<T, int>) {
|
||||
return std::stoi(value);
|
||||
} else if constexpr (std::is_same_v<T, double>) {
|
||||
return std::stod(value);
|
||||
} else if constexpr (std::is_same_v<T, std::size_t>) {
|
||||
const std::size_t res = std::stoul(value);
|
||||
return res;
|
||||
} else if constexpr (std::is_same_v<T, DateTime>) {
|
||||
return DateTime(value);
|
||||
} else if constexpr (std::is_same_v<T, bool>) {
|
||||
if (!is_boolean(value)) {
|
||||
throw std::invalid_argument("Invalid boolean value: " + value);
|
||||
}
|
||||
return ocpp::conversions::string_to_bool(value);
|
||||
} else if constexpr (std::is_same_v<T, std::uint64_t>) {
|
||||
return std::stoull(value);
|
||||
}
|
||||
}
|
||||
|
||||
template <DataEnum T> auto to_specific_type_auto(const std::string& value) {
|
||||
static_assert(T == DataEnum::string || T == DataEnum::integer || T == DataEnum::decimal ||
|
||||
T == DataEnum::dateTime || T == DataEnum::boolean,
|
||||
"Requested unknown datatype");
|
||||
|
||||
if constexpr (T == DataEnum::string) {
|
||||
return to_specific_type<std::string>(value);
|
||||
} else if constexpr (T == DataEnum::integer) {
|
||||
return to_specific_type<int>(value);
|
||||
} else if constexpr (T == DataEnum::decimal) {
|
||||
return to_specific_type<double>(value);
|
||||
} else if constexpr (T == DataEnum::dateTime) {
|
||||
return to_specific_type<DateTime>(value);
|
||||
} else if constexpr (T == DataEnum::boolean) {
|
||||
return to_specific_type<bool>(value);
|
||||
}
|
||||
}
|
||||
|
||||
template <DataEnum T> bool is_type_numeric() {
|
||||
static_assert(T == DataEnum::string || T == DataEnum::integer || T == DataEnum::decimal ||
|
||||
T == DataEnum::dateTime || T == DataEnum::boolean || T == DataEnum::OptionList ||
|
||||
T == DataEnum::SequenceList || T == DataEnum::MemberList,
|
||||
"Requested unknown datatype");
|
||||
|
||||
if constexpr (T == DataEnum::integer || T == DataEnum::decimal) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Gets a variable attribute value from the device model
|
||||
/// \tparam T The target type (must be: std::string, int, double, size_t, DateTime, bool, or uint64_t)
|
||||
/// \param dm The device model interface
|
||||
/// \param component_id The component
|
||||
/// \param variable_id The variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \return The requested value
|
||||
/// \throws std::runtime_error if the value cannot be retrieved
|
||||
template <typename T>
|
||||
T get_value(const DeviceModelInterface& dm, const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum = AttributeEnum::Actual) {
|
||||
std::string value;
|
||||
const auto status = dm.get_variable(component_id, variable_id, attribute_enum, value, true);
|
||||
if (status != GetVariableStatusEnum::Accepted) {
|
||||
throw std::runtime_error("Required value not available");
|
||||
}
|
||||
return to_specific_type<T>(value);
|
||||
}
|
||||
|
||||
/// \brief Gets a variable attribute value from the device model
|
||||
/// \tparam T The target type (must be: std::string, int, double, size_t, DateTime, bool, or uint64_t)
|
||||
/// \param dm The device model interface
|
||||
/// \param component_variable The component and variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \return The requested value
|
||||
/// \throws std::runtime_error if the value cannot be retrieved
|
||||
template <typename T>
|
||||
T get_value(const DeviceModelInterface& dm, const ComponentVariable& component_variable,
|
||||
const AttributeEnum& attribute_enum = AttributeEnum::Actual) {
|
||||
if (!component_variable.variable.has_value()) {
|
||||
throw std::runtime_error("ComponentVariable has no variable set");
|
||||
}
|
||||
return get_value<T>(dm, component_variable.component, component_variable.variable.value(), attribute_enum);
|
||||
}
|
||||
|
||||
/// \brief Gets an optional variable attribute value from the device model
|
||||
/// \tparam T The target type (must be: std::string, int, double, size_t, DateTime, bool, or uint64_t)
|
||||
/// \param dm The device model interface
|
||||
/// \param component_id The component
|
||||
/// \param variable_id The variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \return The requested value or std::nullopt
|
||||
template <typename T>
|
||||
std::optional<T> get_optional_value(const DeviceModelInterface& dm, const Component& component_id,
|
||||
const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum = AttributeEnum::Actual) {
|
||||
std::string value;
|
||||
const auto status = dm.get_variable(component_id, variable_id, attribute_enum, value, true);
|
||||
if (status != GetVariableStatusEnum::Accepted) {
|
||||
return std::nullopt;
|
||||
}
|
||||
try {
|
||||
return to_specific_type<T>(value);
|
||||
} catch (const std::exception& e) {
|
||||
// Conversion failed: the value is present in the DM but cannot be represented as T
|
||||
// (malformed integer, malformed bool, out-of-range, etc.). Log at warning level so a
|
||||
// caller seeing std::nullopt can distinguish "absent" from "present-but-unparseable".
|
||||
EVLOG_warning << "Failed to convert device model value '" << value << "' to requested type for component '"
|
||||
<< component_id.name.get() << "', variable '" << variable_id.name.get() << "': " << e.what();
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Gets an optional variable attribute value from the device model
|
||||
/// \tparam T The target type (must be: std::string, int, double, size_t, DateTime, bool, or uint64_t)
|
||||
/// \param dm The device model interface
|
||||
/// \param component_variable The component and variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \return The requested value or std::nullopt
|
||||
template <typename T>
|
||||
std::optional<T> get_optional_value(const DeviceModelInterface& dm, const ComponentVariable& component_variable,
|
||||
const AttributeEnum& attribute_enum = AttributeEnum::Actual) {
|
||||
if (!component_variable.variable.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return get_optional_value<T>(dm, component_variable.component, component_variable.variable.value(), attribute_enum);
|
||||
}
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,220 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef DEVICE_MODEL_INTERFACE_HPP
|
||||
#define DEVICE_MODEL_INTERFACE_HPP
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <ocpp/v2/enums.hpp>
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
/// \brief Helper struct that holds values that don't have spec coverage
|
||||
struct VariableMonitoringMeta {
|
||||
VariableMonitoring monitor;
|
||||
VariableMonitorType type;
|
||||
std::optional<std::string> reference_value;
|
||||
};
|
||||
|
||||
/// \brief Helper struct that contains all monitors related to a variable that are of a periodic type
|
||||
struct VariableMonitoringPeriodic {
|
||||
Component component;
|
||||
Variable variable;
|
||||
std::vector<VariableMonitoringMeta> monitors;
|
||||
};
|
||||
|
||||
/// \brief Helper struct that combines VariableCharacteristics and VariableMonitoring
|
||||
struct VariableMetaData {
|
||||
VariableCharacteristics characteristics;
|
||||
std::unordered_map<std::int64_t, VariableMonitoringMeta> monitors;
|
||||
std::optional<std::string> source;
|
||||
};
|
||||
|
||||
using VariableMap = std::map<Variable, VariableMetaData>;
|
||||
using DeviceModelMap = std::map<Component, VariableMap>;
|
||||
|
||||
class DeviceModelError : public std::exception {
|
||||
public:
|
||||
[[nodiscard]] const char* what() const noexcept override {
|
||||
return this->reason.c_str();
|
||||
}
|
||||
explicit DeviceModelError(std::string msg) : reason(std::move(msg)) {
|
||||
}
|
||||
explicit DeviceModelError(const char* msg) : reason(std::string(msg)) {
|
||||
}
|
||||
|
||||
private:
|
||||
std::string reason;
|
||||
};
|
||||
|
||||
/// \brief Pure abstract interface for device model access.
|
||||
class DeviceModelInterface {
|
||||
public:
|
||||
virtual ~DeviceModelInterface() = default;
|
||||
|
||||
// ============================================================================
|
||||
// Value getters
|
||||
// ============================================================================
|
||||
|
||||
/// \brief Gets a variable attribute value
|
||||
/// \param component_id The component
|
||||
/// \param variable_id The variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \param value The value to get (as string)
|
||||
/// \param allow_write_only If true, write-only variables can be accessed
|
||||
/// \return Result of the requested operation
|
||||
virtual GetVariableStatusEnum get_variable(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, std::string& value,
|
||||
bool allow_write_only = false) const = 0;
|
||||
|
||||
// ============================================================================
|
||||
// Value setters
|
||||
// ============================================================================
|
||||
|
||||
/// \brief Sets a variable attribute value
|
||||
/// \param component_id The component
|
||||
/// \param variable_id The variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \param value The value to set (as string)
|
||||
/// \param source The source of the value (e.g., 'csms', 'default', 'internal')
|
||||
/// \param allow_read_only If true, read-only variables can be changed
|
||||
/// \return Result of the requested operation
|
||||
virtual SetVariableStatusEnum set_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, const std::string& value,
|
||||
const std::string& source, bool allow_read_only = false) = 0;
|
||||
|
||||
/// \brief Sets a read-only variable attribute value (only works on certain allowed components)
|
||||
/// \param component_id The component
|
||||
/// \param variable_id The variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \param value The value to set (as string)
|
||||
/// \param source The source of the value (e.g., 'csms', 'default', 'internal')
|
||||
/// \return Result of the requested operation
|
||||
virtual SetVariableStatusEnum set_read_only_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, const std::string& value,
|
||||
const std::string& source) = 0;
|
||||
|
||||
/// \brief Clear the Actual attribute of \p variable on \p component, bypassing
|
||||
/// validate_value AND the read-only mutability check. Intended for spec-mandated
|
||||
/// clears where the empty-string sentinel would otherwise fail length / range
|
||||
/// constraints (e.g. B09.FR.27 clearing a per-slot BasicAuthPassword that has
|
||||
/// minLimit=16). Do not use to clear ReadOnly attributes outside of an explicit
|
||||
/// spec-mandated clear path: this method does not enforce the mutability
|
||||
/// allowlist that set_read_only_value uses.
|
||||
/// \param source identifier for the change source ("internal" / OCPP source)
|
||||
/// \return SetVariableStatusEnum reflecting the storage write outcome
|
||||
virtual SetVariableStatusEnum clear_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, const std::string& source) = 0;
|
||||
|
||||
// ============================================================================
|
||||
// Metadata and monitoring
|
||||
// ============================================================================
|
||||
|
||||
/// \brief Get the mutability for the given component, variable and attribute
|
||||
/// \param component_id The component
|
||||
/// \param variable_id The variable
|
||||
/// \param attribute_enum The attribute
|
||||
/// \return The mutability of the given component variable, or std::nullopt
|
||||
virtual std::optional<MutabilityEnum> get_mutability(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum) = 0;
|
||||
|
||||
/// \brief Gets the VariableMetaData for the given component and variable
|
||||
/// \param component_id The component
|
||||
/// \param variable_id The variable
|
||||
/// \return VariableMetaData or std::nullopt if not present
|
||||
virtual std::optional<VariableMetaData> get_variable_meta_data(const Component& component_id,
|
||||
const Variable& variable_id) = 0;
|
||||
|
||||
/// \brief Gets the ReportData for the specified report base
|
||||
/// \param report_base The report base filter
|
||||
/// \return Vector of ReportData
|
||||
virtual std::vector<ReportData> get_base_report_data(const ReportBaseEnum& report_base) = 0;
|
||||
|
||||
/// \brief Gets the ReportData for the specified filters
|
||||
/// \param component_variables Optional component variables filter
|
||||
/// \param component_criteria Optional component criteria filter
|
||||
/// \return Vector of ReportData
|
||||
virtual std::vector<ReportData> get_custom_report_data(
|
||||
const std::optional<std::vector<ComponentVariable>>& component_variables = std::nullopt,
|
||||
const std::optional<std::vector<ComponentCriterionEnum>>& component_criteria = std::nullopt) = 0;
|
||||
|
||||
// ============================================================================
|
||||
// Monitoring operations
|
||||
// ============================================================================
|
||||
|
||||
/// \brief Sets the given monitor requests in the device model
|
||||
/// \param requests The monitoring requests
|
||||
/// \param type The type of monitors (HardWiredMonitor, PreconfiguredMonitor, CustomMonitor)
|
||||
/// \return List of results of the requested operation
|
||||
virtual std::vector<SetMonitoringResult>
|
||||
set_monitors(const std::vector<SetMonitoringData>& requests,
|
||||
const VariableMonitorType type = VariableMonitorType::CustomMonitor) = 0;
|
||||
|
||||
/// \brief Updates the reference value for a monitor
|
||||
/// \param monitor_id The monitor ID
|
||||
/// \param reference_value The new reference value
|
||||
/// \return true if successful, false otherwise
|
||||
virtual bool update_monitor_reference(std::int32_t monitor_id, const std::string& reference_value) = 0;
|
||||
|
||||
/// \brief Gets all periodic monitors
|
||||
/// \return Vector of periodic monitors
|
||||
virtual std::vector<VariableMonitoringPeriodic> get_periodic_monitors() = 0;
|
||||
|
||||
/// \brief Gets the monitoring data for the requested criteria and component variables
|
||||
/// \param criteria The monitoring criteria
|
||||
/// \param component_variables The component variables to get monitors for
|
||||
/// \return List of monitoring data
|
||||
virtual std::vector<MonitoringData> get_monitors(const std::vector<MonitoringCriterionEnum>& criteria,
|
||||
const std::vector<ComponentVariable>& component_variables) = 0;
|
||||
|
||||
/// \brief Clears the given monitor IDs from the registered monitors
|
||||
/// \param request_ids The monitor IDs to clear
|
||||
/// \param allow_protected If true, non-custom monitors can be deleted
|
||||
/// \return List of results of the requested operation
|
||||
virtual std::vector<ClearMonitoringResult> clear_monitors(const std::vector<int>& request_ids,
|
||||
bool allow_protected = false) = 0;
|
||||
|
||||
/// \brief Clears all custom monitors (set by the CSMS)
|
||||
/// \return Count of monitors deleted
|
||||
virtual std::int32_t clear_custom_monitors() = 0;
|
||||
|
||||
/// \brief Registers a listener for variable changes
|
||||
/// \param listener The listener function to register
|
||||
virtual void register_variable_listener(
|
||||
std::function<void(const std::unordered_map<std::int64_t, VariableMonitoringMeta>& monitors,
|
||||
const Component& component, const Variable& variable,
|
||||
const VariableCharacteristics& characteristics, const VariableAttribute& attribute,
|
||||
const std::string& value_previous, const std::string& value_current)>&& listener) = 0;
|
||||
|
||||
/// \brief Registers a listener for monitor updates
|
||||
/// \param listener The listener function to register
|
||||
virtual void register_monitor_listener(
|
||||
std::function<void(const VariableMonitoringMeta& updated_monitor, const Component& component,
|
||||
const Variable& variable, const VariableCharacteristics& characteristics,
|
||||
const VariableAttribute& attribute, const std::string& current_value)>&& listener) = 0;
|
||||
|
||||
// ============================================================================
|
||||
// Integrity check
|
||||
// ============================================================================
|
||||
|
||||
/// \brief Check data integrity of the device model
|
||||
/// \param evse_connector_structure The EVSE connector structure
|
||||
virtual void check_integrity(const std::map<std::int32_t, std::int32_t>& evse_connector_structure) = 0;
|
||||
|
||||
/// \brief Create a fresh NetworkConfiguration_<new_slot> from the embedded default schema.
|
||||
/// \param new_slot New NetworkConfiguration instance to create.
|
||||
/// \return true on success; false on failure.
|
||||
virtual bool create_network_configuration_slot_from_default_schema(std::int32_t /*new_slot*/) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // DEVICE_MODEL_INTERFACE_HPP
|
||||
@@ -0,0 +1,111 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ocpp/common/support_older_cpp_versions.hpp>
|
||||
#include <optional>
|
||||
|
||||
#include <ocpp/v2/device_model_abstract.hpp>
|
||||
#include <ocpp/v2/enums.hpp>
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
/// \brief Abstract base class for device model interface. This class provides an interface for accessing and modifying
|
||||
/// device model data. Implementations of this class should provide concrete implementations for the virtual methods
|
||||
/// declared here.
|
||||
class DeviceModelStorageInterface {
|
||||
|
||||
public:
|
||||
virtual ~DeviceModelStorageInterface() = default;
|
||||
|
||||
/// \brief Gets the device model from the device model interface
|
||||
/// \return std::map<Component, std::map<Variable, VariableMetaData>> that will contain a full representation of the
|
||||
/// device model except for the VariableAttribute(s) of each Variable.
|
||||
virtual DeviceModelMap get_device_model() = 0;
|
||||
|
||||
/// \brief Gets a VariableAttribute from the storage if present
|
||||
/// \param component_id
|
||||
/// \param variable_id
|
||||
/// \param attribute_enum
|
||||
/// \return VariableAttribute or std::nullopt if not present in the storage
|
||||
virtual std::optional<VariableAttribute> get_variable_attribute(const Component& component_id,
|
||||
const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum) = 0;
|
||||
/// \brief Gets a std::vector<VariableAttribute> from the storage.
|
||||
/// \param component_id
|
||||
/// \param variable_id
|
||||
/// \param attribute_enum optionally specifies an AttributeEnum. In this case this std::vector will contain max. one
|
||||
/// element
|
||||
/// \return std::vector<VariableAttribute> with maximum size of 4 elements (Actual, Target, MinSet, MaxSet) and
|
||||
/// minum size of 0 elements (if no VariableAttribute is present for the requested parameters)
|
||||
virtual std::vector<VariableAttribute>
|
||||
get_variable_attributes(const Component& component_id, const Variable& variable_id,
|
||||
const std::optional<AttributeEnum>& attribute_enum = std::nullopt) = 0;
|
||||
|
||||
/// \brief Sets the value of an VariableAttribute if present
|
||||
/// \param component_id
|
||||
/// \param variable_id
|
||||
/// \param attribute_enum
|
||||
/// \param value
|
||||
/// \param source The source of the value.
|
||||
/// \return Accepted if the value could be set in the storage, RebootRequired or Rejected if not (immediately
|
||||
/// possible)
|
||||
virtual SetVariableStatusEnum set_variable_attribute_value(const Component& component_id,
|
||||
const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum,
|
||||
const std::string& value, const std::string& source) = 0;
|
||||
|
||||
/// \brief Inserts or replaces a variable monitor in the database
|
||||
/// \param data Monitor data to set
|
||||
/// \return true if the value could be inserted, or valse otherwise
|
||||
virtual std::optional<VariableMonitoringMeta> set_monitoring_data(const SetMonitoringData& data,
|
||||
const VariableMonitorType type) = 0;
|
||||
|
||||
/// \brief Updates the reference value for a monitor. The reference values is used for the
|
||||
/// delta monitors to detect a trigger, and must be updated when a trigger is detected
|
||||
/// \param monitor_id Id of the monitor that requires the reference changed
|
||||
/// \param reference_value Value to replace the reference with
|
||||
/// \return true if the reference value could be updated, false otherwise
|
||||
virtual bool update_monitoring_reference(const std::int32_t monitor_id, const std::string& reference_value) = 0;
|
||||
|
||||
/// \brief Returns all the monitors currently in the database based
|
||||
/// on the provided filtering criteria
|
||||
/// \param criteria
|
||||
/// \param component_id
|
||||
/// \param variable_id
|
||||
/// \return the monitoring data if it could be found or an empty vector
|
||||
virtual std::vector<VariableMonitoringMeta>
|
||||
get_monitoring_data(const std::vector<MonitoringCriterionEnum>& criteria, const Component& component_id,
|
||||
const Variable& variable_id) = 0;
|
||||
|
||||
/// \brief Clears a single monitor based on the ID from the database
|
||||
/// \param monitor_id Monitor ID
|
||||
/// \param allow_protected If we are allowed to delete non-custom monitors
|
||||
/// \return if not Accepted, NotFound if the monitor could not be
|
||||
/// found, or Rejected if it is a protected monitor
|
||||
virtual ClearMonitoringStatusEnum clear_variable_monitor(int monitor_id, bool allow_protected) = 0;
|
||||
|
||||
/// \brief Clears all custom monitors (that were added by the CSMS)
|
||||
/// from the database
|
||||
/// \return count of monitors deleted, or 0 if none were deleted
|
||||
virtual std::int32_t clear_custom_variable_monitors() = 0;
|
||||
|
||||
/// \brief Check data integrity of the stored data:
|
||||
/// For "required" variables, assert values exist. Checks might be extended in the future.
|
||||
virtual void check_integrity() = 0;
|
||||
|
||||
/// \brief Create a fresh NetworkConfiguration_<new_slot> from the embedded default schema.
|
||||
/// \param new_slot The instance index to create.
|
||||
/// \return true on success; false on failure.
|
||||
virtual bool create_network_configuration_slot_from_default_schema(std::int32_t /*new_slot*/) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,88 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#ifndef DEVICE_MODEL_STORAGE_SQLITE_HPP
|
||||
#define DEVICE_MODEL_STORAGE_SQLITE_HPP
|
||||
|
||||
#include <filesystem>
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <everest/database/sqlite/connection.hpp>
|
||||
#include <everest/logging.hpp>
|
||||
#include <ocpp/v2/device_model_storage_interface.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
class DeviceModelStorageSqlite : public DeviceModelStorageInterface {
|
||||
|
||||
private:
|
||||
std::unique_ptr<everest::db::sqlite::ConnectionInterface> db;
|
||||
|
||||
int get_component_id(const Component& component_id);
|
||||
|
||||
int get_variable_id(const Component& component_id, const Variable& variable_id);
|
||||
|
||||
void initialize_connection(const fs::path& db_path);
|
||||
|
||||
public:
|
||||
/// \brief Opens SQLite connection at given \p db_path
|
||||
///
|
||||
/// If init_db is true, all other paths must be given as well.
|
||||
///
|
||||
/// \param db_path Path to database
|
||||
/// \param migration_files_path Path to the migration files to initialize the database (only needs to be set if
|
||||
/// `init_db` is true)
|
||||
/// \param config_path Path to the device model config used to initialize the database
|
||||
///
|
||||
explicit DeviceModelStorageSqlite(const fs::path& db_path, const std::filesystem::path& migration_files_path,
|
||||
const std::filesystem::path& config_path);
|
||||
|
||||
/// \brief Opens SQLite connection at given \p db_path
|
||||
///
|
||||
/// \param db_path Path to database
|
||||
/// \param migration_files_path Path to the migration files to initialize the database
|
||||
///
|
||||
DeviceModelStorageSqlite(const fs::path& db_path, const fs::path& migration_files_path);
|
||||
|
||||
/// \brief Opens SQLite connection at given \p db_path
|
||||
///
|
||||
/// \param db_path Path to database
|
||||
DeviceModelStorageSqlite(const fs::path& db_path);
|
||||
|
||||
~DeviceModelStorageSqlite() override = default;
|
||||
|
||||
std::map<Component, std::map<Variable, VariableMetaData>> get_device_model() final;
|
||||
|
||||
std::optional<VariableAttribute> get_variable_attribute(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum) final;
|
||||
|
||||
std::vector<VariableAttribute> get_variable_attributes(const Component& component_id, const Variable& variable_id,
|
||||
const std::optional<AttributeEnum>& attribute_enum) final;
|
||||
|
||||
SetVariableStatusEnum set_variable_attribute_value(const Component& component_id, const Variable& variable_id,
|
||||
const AttributeEnum& attribute_enum, const std::string& value,
|
||||
const std::string& source) final;
|
||||
|
||||
std::optional<VariableMonitoringMeta> set_monitoring_data(const SetMonitoringData& data,
|
||||
const VariableMonitorType type) final;
|
||||
|
||||
bool update_monitoring_reference(const std::int32_t monitor_id, const std::string& reference_value) final;
|
||||
|
||||
std::vector<VariableMonitoringMeta> get_monitoring_data(const std::vector<MonitoringCriterionEnum>& criteria,
|
||||
const Component& component_id,
|
||||
const Variable& variable_id) final;
|
||||
|
||||
ClearMonitoringStatusEnum clear_variable_monitor(int monitor_id, bool allow_protected) final;
|
||||
|
||||
std::int32_t clear_custom_variable_monitors() final;
|
||||
|
||||
void check_integrity() final;
|
||||
|
||||
bool create_network_configuration_slot_from_default_schema(std::int32_t new_slot) final;
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // DEVICE_MODEL_STORAGE_SQLITE_HPP
|
||||
@@ -0,0 +1,51 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
// Manually added enums for OCPP, for the auto-generated ones see 'ocpp_enums.hpp'
|
||||
|
||||
#ifndef OCPP_V2_ENUMS_HPP
|
||||
#define OCPP_V2_ENUMS_HPP
|
||||
|
||||
#include <ocpp/v2/ocpp_enums.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
enum class VariableMonitorType {
|
||||
HardWiredMonitor,
|
||||
PreconfiguredMonitor,
|
||||
CustomMonitor,
|
||||
};
|
||||
|
||||
namespace conversions {
|
||||
/// \brief Converts the given std::string \p s to VariableMonitorType
|
||||
/// \returns a VariableMonitorType from a string representation
|
||||
VariableMonitorType string_to_variable_monitor_type(const std::string& s);
|
||||
|
||||
/// \brief Converts the given VariableMonitorType \p type to std::string
|
||||
/// \returns a string representation of the VariableMonitorType
|
||||
EventNotificationEnum variable_monitor_type_to_event_notification_type(const VariableMonitorType& type);
|
||||
} // namespace conversions
|
||||
|
||||
namespace MonitoringLevelSeverity {
|
||||
constexpr std::int32_t Danger = 0;
|
||||
constexpr std::int32_t HardwareFailure = 1;
|
||||
constexpr std::int32_t SystemFailure = 2;
|
||||
constexpr std::int32_t Critical = 3;
|
||||
constexpr std::int32_t Error = 4;
|
||||
constexpr std::int32_t Alert = 5;
|
||||
constexpr std::int32_t Warning = 6;
|
||||
constexpr std::int32_t Notice = 7;
|
||||
constexpr std::int32_t Informational = 8;
|
||||
constexpr std::int32_t Debug = 9;
|
||||
|
||||
constexpr std::int32_t MIN = Danger;
|
||||
constexpr std::int32_t MAX = Debug;
|
||||
} // namespace MonitoringLevelSeverity
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
|
||||
#endif // OCPP_V2_ENUMS_HPP
|
||||
309
tools/EVerest-main/lib/everest/ocpp/include/ocpp/v2/evse.hpp
Normal file
309
tools/EVerest-main/lib/everest/ocpp/include/ocpp/v2/evse.hpp
Normal file
@@ -0,0 +1,309 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2023 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
#include <ocpp/v2/average_meter_values.hpp>
|
||||
#include <ocpp/v2/component_state_manager.hpp>
|
||||
#include <ocpp/v2/connector.hpp>
|
||||
#include <ocpp/v2/database_handler.hpp>
|
||||
#include <ocpp/v2/device_model_abstract.hpp>
|
||||
#include <ocpp/v2/ocpp_types.hpp>
|
||||
#include <ocpp/v2/transaction.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
enum class CurrentPhaseType {
|
||||
AC,
|
||||
DC,
|
||||
Unknown,
|
||||
};
|
||||
|
||||
class EvseInterface {
|
||||
public:
|
||||
virtual ~EvseInterface() = default;
|
||||
|
||||
/// \brief Return the evse_id of this EVSE
|
||||
/// \return
|
||||
virtual std::int32_t get_id() const = 0;
|
||||
|
||||
/// \brief Returns the number of connectors of this EVSE
|
||||
/// \return
|
||||
virtual std::uint32_t get_number_of_connectors() const = 0;
|
||||
|
||||
///
|
||||
/// \brief Check if the given connector type exists on this evse.
|
||||
/// \param connector_type The connector type to check.
|
||||
/// \return True if connector type is unknown or this evse has the given connector type.
|
||||
///
|
||||
virtual bool does_connector_exist(CiString<20> connector_type) const = 0;
|
||||
|
||||
///
|
||||
/// \brief Get connector status.
|
||||
///
|
||||
/// This will search if there is a connector on this evse with status 'Available'. It will search through all
|
||||
/// connectors, optionally filtering by connector type, and return on the first connector that is 'Available'. If
|
||||
/// there is no 'Available' connector, it will return the status of the last found connector with the given
|
||||
/// connector type.
|
||||
///
|
||||
/// \param connector_type The connector type to filter on (optional).
|
||||
/// \return Connector status. If connector type is given and does not exist, std::nullopt.
|
||||
///
|
||||
virtual std::optional<ConnectorStatusEnum> get_connector_status(std::optional<CiString<20>> connector_type) = 0;
|
||||
|
||||
/// \brief Opens a new transaction
|
||||
/// \param transaction_id id of the transaction
|
||||
/// \param connector_id id of the connector
|
||||
/// \param timestamp timestamp of the start of the transaction
|
||||
/// \param meter_start start meter value of the transaction
|
||||
/// \param id_token id_token with which the transaction was authorized / started
|
||||
/// \param group_id_token optional group id_token
|
||||
/// \param reservation optional reservation_id if evse was reserved
|
||||
/// \param sampled_data_tx_updated_interval Interval between sampling of metering (or other) data, intended to
|
||||
/// be transmitted via TransactionEventRequest (eventType = Updated) messages
|
||||
virtual void open_transaction(const std::string& transaction_id, const std::int32_t connector_id,
|
||||
const DateTime& timestamp, const MeterValue& meter_start,
|
||||
const std::optional<IdToken>& id_token, const std::optional<IdToken>& group_id_token,
|
||||
const std::optional<std::int32_t> reservation_id,
|
||||
const ChargingStateEnum charging_state) = 0;
|
||||
|
||||
/// \brief Closes the transaction on this evse by adding the given \p timestamp \p meter_stop and \p reason .
|
||||
/// \param timestamp
|
||||
/// \param meter_stop
|
||||
/// \param reason
|
||||
virtual void close_transaction(const DateTime& timestamp, const MeterValue& meter_stop,
|
||||
const ReasonEnum& reason) = 0;
|
||||
|
||||
/// \brief Start checking if the max energy on invalid id has exceeded.
|
||||
/// Will call pause_charging_callback when that happens.
|
||||
virtual void start_checking_max_energy_on_invalid_id() = 0;
|
||||
|
||||
/// \brief Indicates if a transaction is active at this evse
|
||||
/// \return
|
||||
virtual bool has_active_transaction() const = 0;
|
||||
|
||||
/// \brief Indicates if a transaction is active at this evse at the given \p connector_id
|
||||
/// \param connector_id id of the connector of the evse
|
||||
/// \return
|
||||
virtual bool has_active_transaction(const std::int32_t connector_id) const = 0;
|
||||
|
||||
/// \brief Releases the reference of the transaction on this evse
|
||||
virtual void release_transaction() = 0;
|
||||
|
||||
/// \brief Returns a pointer to the EnhancedTransaction of this evse
|
||||
/// \return pointer to transaction (nullptr if no transaction is active)
|
||||
virtual std::unique_ptr<EnhancedTransaction>& get_transaction() = 0;
|
||||
|
||||
/// \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
|
||||
/// \param event
|
||||
virtual void submit_event(const std::int32_t connector_id, ConnectorEvent event) = 0;
|
||||
|
||||
/// \brief Event handler that should be called when a new meter_value for this evse is present
|
||||
/// \param meter_value
|
||||
virtual void on_meter_value(const MeterValue& meter_value) = 0;
|
||||
|
||||
/// \brief Returns the last present meter value for this evse
|
||||
/// \return
|
||||
virtual MeterValue get_meter_value() = 0;
|
||||
|
||||
/// @brief Return the idle meter values for this evse
|
||||
/// \return MeterValue type
|
||||
virtual MeterValue get_idle_meter_value() = 0;
|
||||
|
||||
/// @brief Clear the idle meter values for this evse
|
||||
virtual void clear_idle_meter_values() = 0;
|
||||
|
||||
/// \brief Returns a pointer to the connector with ID \param connector_id in this EVSE.
|
||||
virtual Connector* get_connector(std::int32_t connector_id) const = 0;
|
||||
|
||||
/// \brief Gets the effective Operative/Inoperative status of this EVSE
|
||||
virtual OperationalStatusEnum get_effective_operational_status() = 0;
|
||||
|
||||
/// \brief Switches the operative status of the EVSE
|
||||
/// \param new_status The operative status to switch to
|
||||
/// \param persist True the updated operative state should be persisted
|
||||
virtual void set_evse_operative_status(OperationalStatusEnum new_status, bool persist) = 0;
|
||||
|
||||
/// \brief Switches the operative status of a connector within this EVSE
|
||||
/// \param connector_id The ID of the connector
|
||||
/// \param new_status The operative status to switch to
|
||||
/// \param persist True the updated operative state should be persisted
|
||||
virtual void set_connector_operative_status(std::int32_t connector_id, OperationalStatusEnum new_status,
|
||||
bool persist) = 0;
|
||||
|
||||
/// \brief Restores the operative status of a connector within this EVSE to the persisted status and recomputes its
|
||||
/// effective status \param connector_id The ID of the connector
|
||||
virtual void restore_connector_operative_status(std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Get the operational status of a connector within this evse.
|
||||
/// \param connector_id The id of the connector.
|
||||
/// \return The operational status.
|
||||
virtual OperationalStatusEnum get_connector_effective_operational_status(const std::int32_t connector_id) = 0;
|
||||
|
||||
/// \brief Returns the phase type for the EVSE based on its SupplyPhases. It can be AC, DC, or Unknown.
|
||||
virtual CurrentPhaseType get_current_phase_type() = 0;
|
||||
|
||||
///
|
||||
/// \brief Set metervalue triggers for California Pricing.
|
||||
/// \param trigger_metervalue_on_power_kw Send metervalues on this amount of kw (with hysteresis).
|
||||
/// \param trigger_metervalue_on_energy_kwh Send metervalues when this kwh is reached.
|
||||
/// \param trigger_metervalue_at_time Send metervalues at a specific time.
|
||||
/// \param send_metervalue_function Function used to send the metervalues.
|
||||
/// \param io_context io context for the timers.
|
||||
///
|
||||
virtual void set_meter_value_pricing_triggers(
|
||||
std::optional<double> trigger_metervalue_on_power_kw, std::optional<double> trigger_metervalue_on_energy_kwh,
|
||||
std::optional<DateTime> trigger_metervalue_at_time,
|
||||
std::function<void(const std::vector<MeterValue>& meter_values)> send_metervalue_function,
|
||||
boost::asio::io_context& io_context) = 0;
|
||||
};
|
||||
|
||||
/// \brief Represents an EVSE. An EVSE can contain multiple Connector objects, but can only supply energy to one of
|
||||
/// them.
|
||||
class Evse : public EvseInterface {
|
||||
|
||||
private:
|
||||
std::int32_t evse_id;
|
||||
DeviceModelAbstract& device_model;
|
||||
std::map<std::int32_t, std::unique_ptr<Connector>> id_connector_map;
|
||||
std::function<void(const MeterValue& meter_value, EnhancedTransaction& transaction)> transaction_meter_value_req;
|
||||
std::function<void(std::int32_t evse_id)> pause_charging_callback;
|
||||
std::unique_ptr<EnhancedTransaction> transaction; // pointer to active transaction (can be nullptr)
|
||||
MeterValue meter_value; // represents current meter value
|
||||
std::recursive_mutex meter_value_mutex;
|
||||
Everest::SteadyTimer sampled_meter_values_timer;
|
||||
std::shared_ptr<DatabaseHandler> database_handler;
|
||||
|
||||
std::optional<double> trigger_metervalue_on_power_kw;
|
||||
std::optional<double> trigger_metervalue_on_energy_kwh;
|
||||
std::unique_ptr<Everest::SystemTimer> trigger_metervalue_at_time_timer;
|
||||
std::optional<double> last_triggered_metervalue_power_kw;
|
||||
std::function<void(const std::vector<MeterValue>& meter_values)> send_metervalue_function;
|
||||
boost::asio::io_context io_context;
|
||||
|
||||
/// \brief gets the active import energy meter value from meter_value, normalized to Wh.
|
||||
std::optional<float> get_active_import_register_meter_value();
|
||||
|
||||
/// \brief function to check if the max energy has been exceeded, calls pause_charging_callback if so.
|
||||
void check_max_energy_on_invalid_id();
|
||||
|
||||
/// \brief Start all metering timers referenced to \p timestamp
|
||||
/// \param timestamp
|
||||
void start_metering_timers(const DateTime& timestamp);
|
||||
|
||||
///
|
||||
/// \brief Send metervalue to CSMS after a pricing trigger occured.
|
||||
/// \param meter_value The metervalue to send.
|
||||
///
|
||||
void send_meter_value_on_pricing_trigger(const MeterValue& meter_value);
|
||||
|
||||
///
|
||||
/// \brief Reset pricing triggers.
|
||||
///
|
||||
/// Resets timer, set all pricing trigger related members to std::nullopt and / or nullptr.
|
||||
///
|
||||
void reset_pricing_triggers();
|
||||
|
||||
AverageMeterValues aligned_data_updated;
|
||||
AverageMeterValues aligned_data_tx_end;
|
||||
|
||||
/// \brief Perform a check to see if there is an open transaction and resume it if there is.
|
||||
void try_resume_transaction();
|
||||
|
||||
/// \brief Delete the transaction related to this EVSE from the database, if there is one.
|
||||
void delete_database_transaction();
|
||||
|
||||
/// \brief Component responsible for maintaining and persisting the operational status of CS, EVSEs, and connectors.
|
||||
std::shared_ptr<ComponentStateManagerInterface> component_state_manager;
|
||||
|
||||
///
|
||||
/// \brief Get connector type of Connector
|
||||
/// \param connector_id Connector id
|
||||
/// \return The connector type. If evse or connector id is not correct: std::nullopt.
|
||||
///
|
||||
std::optional<CiString<20>> get_evse_connector_type(const std::uint32_t connector_id) const;
|
||||
|
||||
public:
|
||||
/// \brief Construct a new Evse object
|
||||
/// \param evse_id id of the evse
|
||||
/// \param number_of_connectors of the evse
|
||||
/// \param device_model reference to the device model
|
||||
/// \param database_handler shared_ptr to the database handler
|
||||
/// \param component_state_manager shared_ptr to the component state manager
|
||||
/// \param transaction_meter_value_req that is called to transmit a meter value request related to a transaction
|
||||
/// \param pause_charging_callback that is called when the charging should be paused due to max energy on
|
||||
/// invalid id being exceeded
|
||||
Evse(const std::int32_t evse_id, const std::int32_t number_of_connectors, DeviceModelAbstract& device_model,
|
||||
std::shared_ptr<DatabaseHandler> database_handler,
|
||||
std::shared_ptr<ComponentStateManagerInterface> component_state_manager,
|
||||
const std::function<void(const MeterValue& meter_value, EnhancedTransaction& transaction)>&
|
||||
transaction_meter_value_req,
|
||||
const std::function<void(std::int32_t evse_id)>& pause_charging_callback);
|
||||
|
||||
~Evse() override;
|
||||
|
||||
std::int32_t get_id() const override;
|
||||
|
||||
std::uint32_t get_number_of_connectors() const override;
|
||||
bool does_connector_exist(const CiString<20> connector_type) const override;
|
||||
std::optional<ConnectorStatusEnum> get_connector_status(std::optional<CiString<20>> connector_type) override;
|
||||
|
||||
void open_transaction(const std::string& transaction_id, const std::int32_t connector_id, const DateTime& timestamp,
|
||||
const MeterValue& meter_start, const std::optional<IdToken>& id_token,
|
||||
const std::optional<IdToken>& group_id_token,
|
||||
const std::optional<std::int32_t> reservation_id,
|
||||
const ChargingStateEnum charging_state) override;
|
||||
void close_transaction(const DateTime& timestamp, const MeterValue& meter_stop, const ReasonEnum& reason) override;
|
||||
|
||||
/// \brief Start checking if the max energy on invalid id has exceeded.
|
||||
/// Will call pause_charging_callback when that happens.
|
||||
void start_checking_max_energy_on_invalid_id() override;
|
||||
|
||||
bool has_active_transaction() const override;
|
||||
bool has_active_transaction(const std::int32_t connector_id) const override;
|
||||
void release_transaction() override;
|
||||
std::unique_ptr<EnhancedTransaction>& get_transaction() override;
|
||||
|
||||
void submit_event(const std::int32_t connector_id, ConnectorEvent event) override;
|
||||
|
||||
void on_meter_value(const MeterValue& meter_value) override;
|
||||
MeterValue get_meter_value() override;
|
||||
|
||||
MeterValue get_idle_meter_value() override;
|
||||
void clear_idle_meter_values() override;
|
||||
|
||||
Connector* get_connector(std::int32_t connector_id) const override;
|
||||
|
||||
OperationalStatusEnum get_effective_operational_status() override;
|
||||
void set_evse_operative_status(OperationalStatusEnum new_status, bool persist) override;
|
||||
void set_connector_operative_status(std::int32_t connector_id, OperationalStatusEnum new_status,
|
||||
bool persist) override;
|
||||
void restore_connector_operative_status(std::int32_t connector_id) override;
|
||||
OperationalStatusEnum get_connector_effective_operational_status(const std::int32_t connector_id) override;
|
||||
|
||||
CurrentPhaseType get_current_phase_type() override;
|
||||
|
||||
///
|
||||
/// \brief Set pricing triggers to send the meter value.
|
||||
/// \param trigger_metervalue_on_power_kw Trigger for this amount of kw
|
||||
/// \param trigger_metervalue_on_energy_kwh Trigger when amount of kwh is reached
|
||||
/// \param trigger_metervalue_at_time Trigger for a specific time
|
||||
/// \param send_metervalue_function Function to send metervalues when trigger 'fires'
|
||||
/// \param io_context Io service needed for the timer
|
||||
///
|
||||
void set_meter_value_pricing_triggers(
|
||||
std::optional<double> trigger_metervalue_on_power_kw, std::optional<double> trigger_metervalue_on_energy_kwh,
|
||||
std::optional<DateTime> trigger_metervalue_at_time,
|
||||
std::function<void(const std::vector<MeterValue>& meter_values)> send_metervalue_function,
|
||||
boost::asio::io_context& io_context) override;
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,111 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2024 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ocpp/common/custom_iterators.hpp>
|
||||
#include <ocpp/v2/evse.hpp>
|
||||
|
||||
namespace ocpp {
|
||||
namespace v2 {
|
||||
|
||||
///
|
||||
/// \brief Set all connectors of a given evse to unavailable.
|
||||
/// \param evse The evse.
|
||||
/// \param persist True if unavailability should persist. If it is set to false, there will be a check per
|
||||
/// connector if it was already set to true and if that is the case, it will be persisted anyway.
|
||||
///
|
||||
void set_evse_connectors_unavailable(EvseInterface& evse, bool persist);
|
||||
|
||||
/// \brief Class used to access the Evse instances
|
||||
class EvseManagerInterface {
|
||||
public:
|
||||
using EvseIterator = ForwardIterator<EvseInterface>;
|
||||
|
||||
/// \brief Default destructor
|
||||
virtual ~EvseManagerInterface() = default;
|
||||
|
||||
/// \brief Get a reference to the evse with \p id
|
||||
/// \note If \p id is not present this could throw an EvseOutOfRangeException
|
||||
virtual EvseInterface& get_evse(std::int32_t id) = 0;
|
||||
|
||||
/// \brief Get a const reference to the evse with \p id
|
||||
/// \note If \p id is not present this could throw an EvseOutOfRangeException
|
||||
virtual const EvseInterface& get_evse(std::int32_t id) const = 0;
|
||||
|
||||
/// \brief Check if the connector exists on the given evse id.
|
||||
/// \param evse_id The evse id to check for.
|
||||
/// \param connector_type The connector type.
|
||||
/// \return False if evse id does not exist or evse does not have the given connector type.
|
||||
virtual bool does_connector_exist(const std::int32_t evse_id, const CiString<20> connector_type) const = 0;
|
||||
|
||||
/// \brief Check if an evse with \p id exists
|
||||
virtual bool does_evse_exist(std::int32_t id) const = 0;
|
||||
|
||||
/// \brief Checks if all connectors are effectively inoperative.
|
||||
/// If this is the case, calls the all_connectors_unavailable_callback
|
||||
/// This is used e.g. to allow firmware updates once all transactions have finished
|
||||
virtual bool are_all_connectors_effectively_inoperative() const = 0;
|
||||
|
||||
/// \brief Get the number of evses
|
||||
virtual size_t get_number_of_evses() const = 0;
|
||||
|
||||
/// \brief Get evseid for the given transaction id.
|
||||
/// \param transaction_id The transactionid
|
||||
/// \return The evse id belonging the the transaction id. std::nullopt if there is no transaction with the given
|
||||
/// transaction id.
|
||||
///
|
||||
virtual std::optional<std::int32_t> get_transaction_evseid(const CiString<36>& transaction_id) const = 0;
|
||||
|
||||
/// \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 for the whole
|
||||
/// charging station
|
||||
/// \return
|
||||
virtual bool any_transaction_active(const std::optional<EVSE>& evse) const = 0;
|
||||
|
||||
///
|
||||
/// \brief Check if the given evse is valid.
|
||||
/// \param evse The evse to check.
|
||||
/// \return True when evse is valid.
|
||||
///
|
||||
virtual bool is_valid_evse(const EVSE& evse) const = 0;
|
||||
|
||||
/// \brief Gets an iterator pointing to the first evse
|
||||
virtual EvseIterator begin() = 0;
|
||||
/// \brief Gets an iterator pointing past the last evse
|
||||
virtual EvseIterator end() = 0;
|
||||
};
|
||||
|
||||
class EvseManager : public EvseManagerInterface {
|
||||
private:
|
||||
std::vector<std::unique_ptr<EvseInterface>> evses;
|
||||
|
||||
public:
|
||||
EvseManager(const std::map<std::int32_t, std::int32_t>& evse_connector_structure, DeviceModelAbstract& device_model,
|
||||
std::shared_ptr<DatabaseHandler> database_handler,
|
||||
std::shared_ptr<ComponentStateManagerInterface> component_state_manager,
|
||||
const std::function<void(const MeterValue& meter_value, EnhancedTransaction& transaction)>&
|
||||
transaction_meter_value_req,
|
||||
const std::function<void(std::int32_t evse_id)>& pause_charging_callback);
|
||||
|
||||
EvseInterface& get_evse(std::int32_t id) override;
|
||||
const EvseInterface& get_evse(const std::int32_t id) const override;
|
||||
|
||||
bool does_connector_exist(const std::int32_t evse_id, const CiString<20> connector_type) const override;
|
||||
bool does_evse_exist(const std::int32_t id) const override;
|
||||
|
||||
bool are_all_connectors_effectively_inoperative() const override;
|
||||
|
||||
size_t get_number_of_evses() const override;
|
||||
|
||||
std::optional<std::int32_t> get_transaction_evseid(const CiString<36>& transaction_id) const override;
|
||||
|
||||
bool any_transaction_active(const std::optional<EVSE>& evse) const override;
|
||||
bool is_valid_evse(const EVSE& evse) const override;
|
||||
|
||||
EvseIterator begin() override;
|
||||
EvseIterator end() override;
|
||||
};
|
||||
|
||||
} // namespace v2
|
||||
} // namespace ocpp
|
||||
@@ -0,0 +1,94 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ocpp/v2/message_handler.hpp>
|
||||
|
||||
namespace ocpp::v2 {
|
||||
struct FunctionalBlockContext;
|
||||
struct AuthorizationCacheEntry;
|
||||
struct AuthorizeResponse;
|
||||
struct ClearCacheRequest;
|
||||
struct SendLocalListRequest;
|
||||
struct GetLocalListVersionRequest;
|
||||
|
||||
class DatabaseHandlerInterface;
|
||||
|
||||
class AuthorizationInterface : public MessageHandlerInterface {
|
||||
public:
|
||||
~AuthorizationInterface() override = default;
|
||||
|
||||
virtual void start_auth_cache_cleanup_thread() = 0;
|
||||
virtual AuthorizeResponse authorize_req(const IdToken id_token, const std::optional<CiString<10000>>& certificate,
|
||||
const std::optional<std::vector<OCSPRequestData>>& ocsp_request_data) = 0;
|
||||
virtual void trigger_authorization_cache_cleanup() = 0;
|
||||
///\brief Calculate and update the authorization cache size in the device model
|
||||
///
|
||||
virtual void update_authorization_cache_size() = 0;
|
||||
virtual bool is_auth_cache_ctrlr_enabled() = 0;
|
||||
virtual void authorization_cache_insert_entry(const std::string& id_token_hash,
|
||||
const IdTokenInfo& id_token_info) = 0;
|
||||
virtual std::optional<AuthorizationCacheEntry> authorization_cache_get_entry(const std::string& id_token_hash) = 0;
|
||||
virtual void authorization_cache_delete_entry(const std::string& id_token_hash) = 0;
|
||||
|
||||
/// \brief Validates provided \p id_token \p certificate and \p ocsp_request_data using CSMS, AuthCache or AuthList
|
||||
/// \param id_token
|
||||
/// \param certificate
|
||||
/// \param ocsp_request_data
|
||||
/// \return AuthorizeResponse containing the result of the validation
|
||||
virtual AuthorizeResponse validate_token(const IdToken id_token, const std::optional<CiString<10000>>& certificate,
|
||||
const std::optional<std::vector<OCSPRequestData>>& ocsp_request_data) = 0;
|
||||
};
|
||||
|
||||
class Authorization : public AuthorizationInterface {
|
||||
private: // Members
|
||||
const FunctionalBlockContext& context;
|
||||
|
||||
// threads and synchronization
|
||||
bool auth_cache_cleanup_required;
|
||||
std::condition_variable auth_cache_cleanup_cv;
|
||||
std::mutex auth_cache_cleanup_mutex;
|
||||
std::thread auth_cache_cleanup_thread;
|
||||
std::atomic_bool auth_cache_cleanup_handler_running;
|
||||
|
||||
public:
|
||||
explicit Authorization(const FunctionalBlockContext& context);
|
||||
~Authorization() override;
|
||||
void start_auth_cache_cleanup_thread() override;
|
||||
void handle_message(const ocpp::EnhancedMessage<MessageType>& message) override;
|
||||
AuthorizeResponse authorize_req(const IdToken id_token, const std::optional<ocpp::CiString<10000>>& certificate,
|
||||
const std::optional<std::vector<OCSPRequestData>>& ocsp_request_data) override;
|
||||
void trigger_authorization_cache_cleanup() override;
|
||||
void update_authorization_cache_size() override;
|
||||
bool is_auth_cache_ctrlr_enabled() override;
|
||||
void authorization_cache_insert_entry(const std::string& id_token_hash, const IdTokenInfo& id_token_info) override;
|
||||
std::optional<AuthorizationCacheEntry> authorization_cache_get_entry(const std::string& id_token_hash) override;
|
||||
void authorization_cache_delete_entry(const std::string& id_token_hash) override;
|
||||
|
||||
/// \brief Validates provided \p id_token \p certificate and \p ocsp_request_data using CSMS, AuthCache or AuthList
|
||||
/// \param id_token
|
||||
/// \param certificate
|
||||
/// \param ocsp_request_data
|
||||
/// \return AuthorizeResponse containing the result of the validation
|
||||
AuthorizeResponse validate_token(const IdToken id_token, const std::optional<CiString<10000>>& certificate,
|
||||
const std::optional<std::vector<OCSPRequestData>>& ocsp_request_data) override;
|
||||
|
||||
private: // Functions
|
||||
void stop_auth_cache_cleanup_thread();
|
||||
|
||||
// Functional Block C: Authorization
|
||||
void handle_clear_cache_req(Call<ClearCacheRequest> call);
|
||||
void cache_cleanup_handler();
|
||||
|
||||
// Functional Block D: Local authorization list management
|
||||
void handle_send_local_authorization_list_req(Call<SendLocalListRequest> call);
|
||||
void handle_get_local_authorization_list_version_req(Call<GetLocalListVersionRequest> call);
|
||||
|
||||
///\brief Apply a local list request to the database if allowed
|
||||
///
|
||||
///\param request The local list request to apply
|
||||
///\retval Accepted if applied, otherwise will return either Failed or VersionMismatch
|
||||
SendLocalListStatusEnum apply_local_authorization_list(const SendLocalListRequest& request);
|
||||
};
|
||||
} // namespace ocpp::v2
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user