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,48 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
#ifndef UTILS_CONFIG_MQTT_SETTINGS_HPP
|
||||
#define UTILS_CONFIG_MQTT_SETTINGS_HPP
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace Everest {
|
||||
|
||||
/// \brief minimal MQTT connection settings needed for an initial connection of a module to the manager
|
||||
struct MQTTSettings {
|
||||
std::string broker_socket_path; ///< A path to a socket the MQTT broker uses in socket mode. If this is set
|
||||
///< broker_host and broker_port are ignored
|
||||
std::string broker_host; ///< The hostname of the MQTT broker
|
||||
std::uint16_t broker_port = 0; ///< The port the MQTT broker listens on
|
||||
std::string everest_prefix; ///< MQTT topic prefix for the "everest" topic
|
||||
std::string external_prefix; ///< MQTT topic prefix for external topics
|
||||
|
||||
/// \brief Indicates if a Unix Domain Socket is used for connection to the MQTT broker
|
||||
/// \returns true is a UDS is used, false if a connection via host and port is used
|
||||
bool uses_socket() const;
|
||||
};
|
||||
|
||||
/// \brief Creates MQTTSettings with a Unix Domain Socket with the provided \p mqtt_broker_socket_path
|
||||
/// using the \p mqtt_everest_prefix and \p mqtt_external_prefix
|
||||
MQTTSettings create_mqtt_settings(const std::string& mqtt_broker_socket_path, const std::string& mqtt_everest_prefix,
|
||||
const std::string& mqtt_external_prefix);
|
||||
|
||||
/// \brief Creates MQTTSettings for IP based connections with the provided \p mqtt_broker_host
|
||||
/// and \p mqtt_broker_port using the \p mqtt_everest_prefix and \p mqtt_external_prefix
|
||||
MQTTSettings create_mqtt_settings(const std::string& mqtt_broker_host, std::uint16_t mqtt_broker_port,
|
||||
const std::string& mqtt_everest_prefix, const std::string& mqtt_external_prefix);
|
||||
|
||||
/// \brief Populates the given MQTTSettings \p mqtt_settings with a Unix Domain Socket with the provided \p
|
||||
/// mqtt_broker_socket_path using the \p mqtt_everest_prefix and \p mqtt_external_prefix
|
||||
void populate_mqtt_settings(MQTTSettings& mqtt_settings, const std::string& mqtt_broker_socket_path,
|
||||
const std::string& mqtt_everest_prefix, const std::string& mqtt_external_prefix);
|
||||
|
||||
/// \brief Populates the given MQTTSettings \p mqtt_settings for IP based connections with the provided \p
|
||||
/// mqtt_broker_host and \p mqtt_broker_port using the \p mqtt_everest_prefix and \p mqtt_external_prefix
|
||||
void populate_mqtt_settings(MQTTSettings& mqtt_settings, const std::string& mqtt_broker_host,
|
||||
std::uint16_t mqtt_broker_port, const std::string& mqtt_everest_prefix,
|
||||
const std::string& mqtt_external_prefix);
|
||||
|
||||
} // namespace Everest
|
||||
|
||||
#endif // UTILS_CONFIG_MQTT_SETTINGS_HPP
|
||||
@@ -0,0 +1,107 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <utils/config/mqtt_settings.hpp>
|
||||
#include <utils/config/storage_sqlite.hpp>
|
||||
#include <utils/config/types.hpp>
|
||||
|
||||
namespace Everest {
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
enum class ConfigBootMode {
|
||||
YamlFile = 1, // configuration is loaded from a YAML file
|
||||
Database = 2, // configuration is loaded from a database
|
||||
DatabaseInit = 3 // configuration is preferably loaded from a database, but if no valid config is found, it falls
|
||||
// back to a YAML file and initializes the database
|
||||
};
|
||||
|
||||
/// \brief EVerest framework runtime settings needed to successfully run modules
|
||||
struct RuntimeSettings {
|
||||
fs::path prefix; ///< Prefix for EVerest installation
|
||||
fs::path etc_dir; ///< Directory that contains configs, certificates
|
||||
fs::path data_dir; ///< Directory for general data, definitions for EVerest interfaces, types, errors an schemas
|
||||
fs::path modules_dir; ///< Directory that contains EVerest modules
|
||||
fs::path logging_config_file; ///< Path to the logging configuration file
|
||||
std::string telemetry_prefix; ///< MQTT prefix for telemetry
|
||||
bool telemetry_enabled = false; ///< If telemetry is enabled
|
||||
bool validate_schema = false; ///< If schema validation for all var publishes and cmd calls is enabled
|
||||
bool forward_exceptions = false; ///< If exceptions in cmd handlers should be caught and forwarded to the caller
|
||||
};
|
||||
|
||||
RuntimeSettings create_runtime_settings(const fs::path& prefix, const fs::path& etc_dir, const fs::path& data_dir,
|
||||
const fs::path& modules_dir, const fs::path& logging_config_file,
|
||||
const std::string& telemetry_prefix, bool telemetry_enabled,
|
||||
bool validate_schema, bool forward_exceptions);
|
||||
void populate_runtime_settings(RuntimeSettings& runtime_settings, const fs::path& prefix, const fs::path& etc_dir,
|
||||
const fs::path& data_dir, const fs::path& modules_dir,
|
||||
const fs::path& logging_config_file, const std::string& telemetry_prefix,
|
||||
bool telemetry_enabled, bool validate_schema, bool forward_exceptions);
|
||||
|
||||
struct DatabaseTag {};
|
||||
|
||||
/// \brief Settings needed by the manager to load and validate a config
|
||||
struct ManagerSettings {
|
||||
fs::path configs_dir; ///< Directory that contains EVerest configs
|
||||
fs::path db_dir; ///< Directory that contains the database
|
||||
fs::path schemas_dir; ///< Directory that contains schemas for config, manifest, interfaces, etc.
|
||||
fs::path interfaces_dir; ///< Directory that contains interface definitions
|
||||
fs::path types_dir; ///< Directory that contains type definitions
|
||||
fs::path errors_dir; ///< Directory that contains error definitions
|
||||
fs::path config_file; ///< Path to the loaded config file
|
||||
fs::path www_dir; ///< Directory that contains the everest-admin-panel
|
||||
int controller_port = 0; ///< Websocket port of the controller
|
||||
int controller_rpc_timeout_ms = 0; ///< RPC timeout for controller commands
|
||||
|
||||
std::string run_as_user; ///< Username under which EVerest should run
|
||||
|
||||
std::string version_information; ///< Version information string reported on startup of the manager
|
||||
|
||||
nlohmann::json config; ///< Parsed json of the config_file
|
||||
|
||||
MQTTSettings mqtt_settings; ///< MQTT connection settings
|
||||
RuntimeSettings runtime_settings; ///< Runtime settings needed to successfully run modules
|
||||
ConfigBootMode boot_mode =
|
||||
ConfigBootMode::YamlFile; ///< Source of the config, can be YamlFile, Database or DatabaseInit
|
||||
std::unique_ptr<everest::config::SqliteStorage> storage; ///< Sqlite Storage for settings and module configs
|
||||
|
||||
ManagerSettings() = default;
|
||||
|
||||
/// \brief Constructor that initializes the ManagerSettings with the given prefix and config file. Boot source is
|
||||
/// set to YamlFile.
|
||||
ManagerSettings(const std::string& prefix, const std::string& config);
|
||||
|
||||
/// \brief Constructor that initializes the ManagerSettings with the given database path. Boot source is set to
|
||||
/// Database.
|
||||
ManagerSettings(const std::string& prefix, const std::string& db, DatabaseTag);
|
||||
|
||||
/// \brief Constructor that initializes the ManagerSettings with the given prefix, config file and database path.
|
||||
/// Boot Source is set to DatabaseInit.
|
||||
ManagerSettings(const std::string& prefix, const std::string& config, const std::string& db);
|
||||
|
||||
/// \brief Initializes the ManagerSettings with the given settings and prefix.
|
||||
void init_settings(const everest::config::Settings& settings);
|
||||
|
||||
/// \brief Initializes the ManagerSettings based on the user provided \p config file or fallback options
|
||||
void init_config_file(const std::string& config);
|
||||
|
||||
/// \brief Initializes the ManagerSettings prefix and data_dir base on user provided \p prefix or the default
|
||||
/// prefix.
|
||||
void init_prefix_and_data_dir(const std::string& prefix);
|
||||
};
|
||||
} // namespace Everest
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
template <> struct adl_serializer<Everest::RuntimeSettings> {
|
||||
static void to_json(nlohmann::json& j, const Everest::RuntimeSettings& r);
|
||||
|
||||
static void from_json(const nlohmann::json& j, Everest::RuntimeSettings& r);
|
||||
};
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
@@ -0,0 +1,76 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <utils/config/storage_types.hpp>
|
||||
|
||||
namespace Everest {
|
||||
struct ManagerSettings;
|
||||
}
|
||||
|
||||
namespace everest::config {
|
||||
|
||||
/// \brief EVerest Storage Interface providing read and write access to configurations
|
||||
class StorageInterface {
|
||||
public:
|
||||
virtual ~StorageInterface() = default;
|
||||
|
||||
/// \brief Writes given EVerest \p module_configs to persistent storage
|
||||
/// \param config EVerest config
|
||||
/// \return
|
||||
virtual GenericResponseStatus write_module_configs(const ModuleConfigurations& module_configs) = 0;
|
||||
|
||||
/// \brief Writes EVerest config \p settings to persistent storage
|
||||
/// \param settings EVerest settings configuration
|
||||
/// \return
|
||||
virtual GenericResponseStatus write_settings(const Everest::ManagerSettings& manager_settings) = 0;
|
||||
|
||||
/// \brief Wipes all configuration entries from persistent storage
|
||||
virtual GenericResponseStatus wipe() = 0;
|
||||
|
||||
/// \brief Gets EVerest config from persistent storage
|
||||
/// \return Response with status of operation and config. config is only set if status is OK. Config contains all
|
||||
/// module configurations and manager settings
|
||||
virtual GetModuleConfigsResponse get_module_configs() = 0;
|
||||
|
||||
/// \brief Gets EVerest manager settings from persistent storage
|
||||
/// \return
|
||||
virtual GetSettingsResponse get_settings() = 0;
|
||||
|
||||
/// \brief Gets EVerest config from persistent storage for a single module
|
||||
/// \param module_id
|
||||
/// \return Response with status of operation and module config. config is only set if status is OK
|
||||
virtual GetModuleConfigurationResponse get_module_config(const std::string& module_id) = 0;
|
||||
|
||||
/// \brief Gets single configuration parameter from persistent storage
|
||||
/// \param identifier Identifies configuration parameter
|
||||
/// \return Response with status of operation and configuration parameter. configuration parameter is only set if
|
||||
/// status is OK.
|
||||
virtual GetConfigurationParameterResponse
|
||||
get_configuration_parameter(const ConfigurationParameterIdentifier& identifier) = 0;
|
||||
|
||||
/// \brief Writes single configuration parameter to persistent storage
|
||||
/// \param identifier Identifies configuration parameter
|
||||
/// \param value
|
||||
/// \return Response with status of operation
|
||||
virtual GetSetResponseStatus update_configuration_parameter(const ConfigurationParameterIdentifier& identifier,
|
||||
const std::string& value) = 0;
|
||||
|
||||
/// \brief Writes single configuration parameter including characteristics to persistent storage
|
||||
/// \param identifier Identifies configuration parameter
|
||||
/// \param characteristics of the configuration parameter
|
||||
/// \param value
|
||||
/// \return Response with status of operation
|
||||
virtual GetSetResponseStatus
|
||||
write_configuration_parameter(const ConfigurationParameterIdentifier& identifier,
|
||||
const ConfigurationParameterCharacteristics characteristics,
|
||||
const std::string& value) = 0;
|
||||
};
|
||||
|
||||
} // namespace everest::config
|
||||
@@ -0,0 +1,64 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <everest/database/sqlite/connection.hpp>
|
||||
#include <utils/config/storage.hpp>
|
||||
|
||||
namespace everest::config {
|
||||
|
||||
/// \brief Implements StorageInterface with SQLite
|
||||
class SqliteStorage : public StorageInterface {
|
||||
|
||||
public:
|
||||
/// \brief Constructor
|
||||
/// \param db_path Path to SQLite database file
|
||||
/// \param migration_files_path Path to SQL migration files
|
||||
/// \throws MigrationException if migration fails
|
||||
/// \throws std::runtime_error if database cannot be opened
|
||||
SqliteStorage(const fs::path& db_path, const std::filesystem::path& migration_files_path);
|
||||
|
||||
GenericResponseStatus write_module_configs(const ModuleConfigurations& module_configs) override;
|
||||
GenericResponseStatus write_settings(const Everest::ManagerSettings& manager_settings) override;
|
||||
GenericResponseStatus wipe() override;
|
||||
GetModuleConfigsResponse get_module_configs() override;
|
||||
GetSettingsResponse get_settings() override;
|
||||
GetModuleConfigurationResponse get_module_config(const std::string& module_id) override;
|
||||
GetConfigurationParameterResponse
|
||||
get_configuration_parameter(const ConfigurationParameterIdentifier& identifier) override;
|
||||
GetSetResponseStatus update_configuration_parameter(const ConfigurationParameterIdentifier& identifier,
|
||||
const std::string& value) override;
|
||||
GetSetResponseStatus write_configuration_parameter(const ConfigurationParameterIdentifier& identifier,
|
||||
const ConfigurationParameterCharacteristics characteristics,
|
||||
const std::string& value) override;
|
||||
|
||||
/// \brief Checks if the database contains a valid configuration
|
||||
bool contains_valid_config();
|
||||
|
||||
/// \brief Marks the current configuration as valid
|
||||
/// \param is_valid True if the configuration is valid, false otherwise
|
||||
/// \param config_dump JSON dump of the config file that was used to create the configuration
|
||||
/// \param yaml_file_path Path to the config file that was used to create the configuration
|
||||
void mark_valid(const bool is_valid, const std::string& config_dump,
|
||||
const std::optional<fs::path>& config_file_path);
|
||||
|
||||
private:
|
||||
std::unique_ptr<everest::db::sqlite::ConnectionInterface> db;
|
||||
GenericResponseStatus write_module_data(const ModuleData& module_info);
|
||||
GenericResponseStatus write_module_fulfillment(const std::string& module_id, const Fulfillment& fulfillment);
|
||||
GenericResponseStatus write_module_tier_mapping(const std::string& module_id, const std::string& implementation_id,
|
||||
const int32_t evse_id, const std::optional<int32_t> connector_id);
|
||||
GenericResponseStatus write_access(const std::string& module_id, const Access& access);
|
||||
GenericResponseStatus write_config_access(const std::string& module_id, const ConfigAccess& config_access);
|
||||
GenericResponseStatus write_module_config_access(const std::string& module_id, const std::string& other_module_id,
|
||||
const ModuleConfigAccess& module_config_access);
|
||||
GenericResponseStatus write_setting(const std::string& setting_name, const std::string& value);
|
||||
GetModuleFulfillmentsResponse get_module_fulfillments(const std::string& module_id);
|
||||
GetModuleDataResponse get_module_data(const std::string& module_id);
|
||||
GetModuleTierMappingsResponse get_module_tier_mappings(const std::string& module_id);
|
||||
GetModuleConfigAccessResponse get_module_config_access(const std::string& module_id);
|
||||
GetConfigAccessResponse get_config_access(const std::string& module_id);
|
||||
};
|
||||
|
||||
} // namespace everest::config
|
||||
@@ -0,0 +1,87 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <nlohmann/json_fwd.hpp>
|
||||
|
||||
#include <utils/config/types.hpp>
|
||||
|
||||
namespace everest::config {
|
||||
|
||||
enum class GenericResponseStatus {
|
||||
OK,
|
||||
Failed
|
||||
};
|
||||
|
||||
enum class GetSetResponseStatus {
|
||||
OK,
|
||||
Failed,
|
||||
NotFound
|
||||
};
|
||||
|
||||
struct ModuleData {
|
||||
std::string module_id;
|
||||
std::string module_name;
|
||||
bool standalone = false;
|
||||
std::optional<std::vector<std::string>> capabilities;
|
||||
};
|
||||
|
||||
struct GetConfigurationParameterResponse {
|
||||
GetSetResponseStatus status = GetSetResponseStatus::Failed;
|
||||
std::optional<ConfigurationParameter> configuration_parameter;
|
||||
};
|
||||
|
||||
struct GetModuleConfigsResponse {
|
||||
GenericResponseStatus status = GenericResponseStatus::Failed;
|
||||
ModuleConfigurations module_configs;
|
||||
};
|
||||
|
||||
struct GetSettingsResponse {
|
||||
GenericResponseStatus status = GenericResponseStatus::Failed;
|
||||
std::optional<Settings> settings;
|
||||
};
|
||||
|
||||
struct GetModuleFulfillmentsResponse {
|
||||
GenericResponseStatus status = GenericResponseStatus::Failed;
|
||||
std::vector<Fulfillment> module_fulfillments;
|
||||
};
|
||||
|
||||
struct GetModuleTierMappingsResponse {
|
||||
GenericResponseStatus status = GenericResponseStatus::Failed;
|
||||
ModuleTierMappings module_tier_mappings;
|
||||
};
|
||||
|
||||
struct GetConfigAccessResponse {
|
||||
GenericResponseStatus status = GenericResponseStatus::Failed;
|
||||
std::optional<ConfigAccess> config_access;
|
||||
};
|
||||
|
||||
struct GetModuleConfigAccessResponse {
|
||||
GenericResponseStatus status = GenericResponseStatus::Failed;
|
||||
std::map<std::string, everest::config::ModuleConfigAccess> module_config_access;
|
||||
};
|
||||
|
||||
struct GetModuleConfigurationResponse {
|
||||
GenericResponseStatus status = GenericResponseStatus::Failed;
|
||||
std::optional<ModuleConfig> config;
|
||||
};
|
||||
|
||||
struct GetModuleDataResponse {
|
||||
GenericResponseStatus status = GenericResponseStatus::Failed;
|
||||
std::optional<ModuleData> module_data;
|
||||
};
|
||||
|
||||
struct ConfigurationParameterIdentifier {
|
||||
std::string module_id;
|
||||
std::string configuration_parameter_name;
|
||||
std::optional<std::string> module_implementation_id;
|
||||
|
||||
bool operator<(const ConfigurationParameterIdentifier& rhs) const;
|
||||
};
|
||||
|
||||
} // namespace everest::config
|
||||
@@ -0,0 +1,41 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <utils/config/storage.hpp>
|
||||
|
||||
namespace everest::config {
|
||||
|
||||
/// \brief Implements StorageInterface with YAML user-config
|
||||
class UserConfigStorage : public StorageInterface {
|
||||
|
||||
public:
|
||||
/// \brief Constructor
|
||||
/// \param user_config_path Path to user-config file
|
||||
UserConfigStorage(const fs::path& user_config_path);
|
||||
|
||||
GenericResponseStatus write_module_configs(const ModuleConfigurations& module_configs) override;
|
||||
GenericResponseStatus write_settings(const Everest::ManagerSettings& manager_settings) override;
|
||||
GenericResponseStatus wipe() override;
|
||||
GetModuleConfigsResponse get_module_configs() override;
|
||||
GetSettingsResponse get_settings() override;
|
||||
GetModuleConfigurationResponse get_module_config(const std::string& module_id) override;
|
||||
GetConfigurationParameterResponse
|
||||
get_configuration_parameter(const ConfigurationParameterIdentifier& identifier) override;
|
||||
GetSetResponseStatus update_configuration_parameter(const ConfigurationParameterIdentifier& identifier,
|
||||
const std::string& value) override;
|
||||
GetSetResponseStatus write_configuration_parameter(const ConfigurationParameterIdentifier& identifier,
|
||||
const ConfigurationParameterCharacteristics characteristics,
|
||||
const std::string& value) override;
|
||||
|
||||
const nlohmann::json& get_user_config() const;
|
||||
|
||||
private:
|
||||
fs::path user_config_path;
|
||||
nlohmann::json user_config;
|
||||
};
|
||||
|
||||
} // namespace everest::config
|
||||
@@ -0,0 +1,281 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2020 - 2025 Pionix GmbH and Contributors to EVerest
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
class ConfigParseException : public std::exception {
|
||||
public:
|
||||
enum ParseErrorType {
|
||||
MISSING_ENTRY,
|
||||
SCHEMA
|
||||
};
|
||||
ConfigParseException(ParseErrorType err_t, const std::string& entry, const std::string& what = "") :
|
||||
err_t(err_t), entry(entry), what(what){};
|
||||
|
||||
const ParseErrorType err_t;
|
||||
const std::string entry;
|
||||
const std::string what;
|
||||
};
|
||||
|
||||
/// \brief A Mapping that can be used to map a module or implementation to a specific EVSE or optionally to a Connector
|
||||
struct Mapping {
|
||||
int evse; ///< The EVSE id
|
||||
std::optional<int> connector; ///< An optional Connector id
|
||||
|
||||
Mapping(int evse) : evse(evse) {
|
||||
}
|
||||
|
||||
Mapping(int evse, int connector) : evse(evse), connector(connector) {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Writes the string representation of the given Mapping \p mapping to the given output stream \p os
|
||||
/// \returns an output stream with the Mapping written to
|
||||
inline std::ostream& operator<<(std::ostream& os, const Mapping& mapping) {
|
||||
os << "Mapping(evse: " << mapping.evse;
|
||||
if (mapping.connector.has_value()) {
|
||||
os << ", connector: " << mapping.connector.value();
|
||||
}
|
||||
os << ")";
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/// \brief Writes the string representation of the given Mapping \p mapping to the given output stream \p os
|
||||
/// \returns an output stream with the Mapping written to
|
||||
inline std::ostream& operator<<(std::ostream& os, const std::optional<Mapping>& mapping) {
|
||||
if (mapping.has_value()) {
|
||||
os << mapping.value();
|
||||
} else {
|
||||
os << "Mapping(charging station)";
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
/// \brief A 3 tier mapping for a module and its individual implementations
|
||||
struct ModuleTierMappings {
|
||||
std::optional<Mapping> module; ///< Mapping of the whole module to an EVSE id and optional Connector id. If this is
|
||||
///< absent the module is assumed to be mapped to the whole charging station
|
||||
std::map<std::string, std::optional<Mapping>, std::less<>>
|
||||
implementations; ///< Mappings for the individual implementations of the module
|
||||
};
|
||||
|
||||
/// \brief A Requirement of an EVerest module
|
||||
struct Requirement {
|
||||
std::string id;
|
||||
size_t index = 0;
|
||||
};
|
||||
|
||||
bool operator<(const Requirement& lhs, const Requirement& rhs);
|
||||
|
||||
/// \brief A Fulfillment relates a Requirement to its connected implementation, identified via its module and
|
||||
/// implementation id.
|
||||
struct Fulfillment {
|
||||
std::string module_id; // the id of the module that fulfills the requirement
|
||||
std::string implementation_id; // the id of the implementation that fulfills the requirement
|
||||
Requirement requirement; // the requirement of the module that is fulfilled
|
||||
};
|
||||
|
||||
struct TelemetryConfig {
|
||||
int id;
|
||||
explicit TelemetryConfig(int id) : id(id) {
|
||||
}
|
||||
};
|
||||
|
||||
namespace everest::config {
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
struct ConfigurationParameter;
|
||||
struct ModuleConfig;
|
||||
using ModuleId = std::string;
|
||||
using RequirementId = std::string;
|
||||
using ConfigEntry = std::variant<std::string, bool, int, double>;
|
||||
using ImplementationIdentifier = std::string;
|
||||
using ModuleConnections = std::map<RequirementId, std::vector<Fulfillment>, std::less<>>;
|
||||
using ModuleConfigurations = std::map<ModuleId, ModuleConfig, std::less<>>;
|
||||
using ModuleConfigurationParameters = std::map<ImplementationIdentifier, std::vector<ConfigurationParameter>>;
|
||||
using Keys = std::set<std::string, std::less<>>;
|
||||
|
||||
struct VisitConfigEntry {
|
||||
std::string operator()(const std::string& value) const {
|
||||
return value;
|
||||
};
|
||||
std::string operator()(bool value) const {
|
||||
return value ? "true" : "false";
|
||||
};
|
||||
std::string operator()(int value) const {
|
||||
return std::to_string(value);
|
||||
};
|
||||
std::string operator()(double value) const {
|
||||
return std::to_string(value);
|
||||
};
|
||||
};
|
||||
|
||||
std::string config_entry_to_string(const everest::config::ConfigEntry& entry);
|
||||
|
||||
enum class Mutability {
|
||||
ReadOnly,
|
||||
ReadWrite,
|
||||
WriteOnly
|
||||
};
|
||||
|
||||
enum class Datatype {
|
||||
Unknown,
|
||||
String,
|
||||
Decimal,
|
||||
Integer,
|
||||
Boolean
|
||||
};
|
||||
|
||||
struct Settings {
|
||||
std::optional<fs::path> prefix;
|
||||
std::optional<fs::path> config_file;
|
||||
std::optional<fs::path> configs_dir;
|
||||
std::optional<fs::path> schemas_dir;
|
||||
std::optional<fs::path> modules_dir;
|
||||
std::optional<fs::path> interfaces_dir;
|
||||
std::optional<fs::path> types_dir;
|
||||
std::optional<fs::path> errors_dir;
|
||||
std::optional<fs::path> www_dir;
|
||||
std::optional<fs::path> logging_config_file;
|
||||
std::optional<int> controller_port;
|
||||
std::optional<int> controller_rpc_timeout_ms;
|
||||
std::optional<std::string> mqtt_broker_socket_path;
|
||||
std::optional<std::string> mqtt_broker_host;
|
||||
std::optional<std::uint16_t> mqtt_broker_port;
|
||||
std::optional<std::string> mqtt_everest_prefix;
|
||||
std::optional<std::string> mqtt_external_prefix;
|
||||
std::optional<std::string> telemetry_prefix;
|
||||
std::optional<bool> telemetry_enabled;
|
||||
std::optional<bool> validate_schema;
|
||||
std::optional<std::string> run_as_user;
|
||||
std::optional<bool> forward_exceptions;
|
||||
};
|
||||
|
||||
/// \brief Struct that contains the characteristics of a configuration parameter including its datatype, mutability and
|
||||
/// unit
|
||||
struct ConfigurationParameterCharacteristics {
|
||||
Datatype datatype = Datatype::Unknown;
|
||||
Mutability mutability = Mutability::ReadOnly;
|
||||
std::optional<std::string> unit;
|
||||
};
|
||||
|
||||
/// \brief Struct that contains the name, value and characteristics of a configuration parameter
|
||||
struct ConfigurationParameter {
|
||||
std::string name;
|
||||
ConfigEntry value;
|
||||
ConfigurationParameterCharacteristics characteristics;
|
||||
|
||||
bool validate_type() const;
|
||||
};
|
||||
|
||||
/// \brief Access control information to an individual module config
|
||||
struct ModuleConfigAccess {
|
||||
bool allow_read = false; ///< Allow read access to config items
|
||||
bool allow_write = false; ///< Allow write access to config items
|
||||
|
||||
bool allow_set_read_only = false; ///< If ReadOnly config items can be treated as ReadWrite (this typically requires
|
||||
///< a reboot to have an effect)
|
||||
};
|
||||
|
||||
/// \brief
|
||||
struct ConfigAccess {
|
||||
bool allow_global_read = false; ///< Allow this module to read the config items of all other modules
|
||||
bool allow_global_write = false; ///< Allow this module to write the config items of all other modules
|
||||
bool allow_set_read_only = false; ///< If ReadOnly config items can be treated as ReadWrite (this typically requires
|
||||
///< a reboot to have an effect)
|
||||
std::map<std::string, everest::config::ModuleConfigAccess>
|
||||
modules; ///< Individual access to other modules config. The key represents the other modules module_id
|
||||
///< and the value the associated access rights
|
||||
};
|
||||
|
||||
/// \brief Access control information for a particular module
|
||||
struct Access {
|
||||
std::optional<ConfigAccess> config; ///< Access control to other modules configuration items
|
||||
};
|
||||
|
||||
/// \brief Struct that contains the configuration of an EVerest module
|
||||
struct ModuleConfig {
|
||||
bool standalone = false;
|
||||
std::string module_name;
|
||||
std::string module_id;
|
||||
std::optional<std::vector<std::string>> capabilities;
|
||||
ModuleConfigurationParameters configuration_parameters; // contains: config_module and config_implementations
|
||||
// as well as the upcoming "config" key
|
||||
bool telemetry_enabled = false;
|
||||
std::optional<TelemetryConfig> telemetry_config;
|
||||
ModuleConnections connections;
|
||||
ModuleTierMappings mapping;
|
||||
Access access;
|
||||
};
|
||||
|
||||
enum class SetConfigStatus {
|
||||
Accepted,
|
||||
Rejected,
|
||||
RebootRequired
|
||||
};
|
||||
|
||||
ConfigEntry parse_config_value(Datatype datatype, const std::string& value_str);
|
||||
ModuleConfigurations parse_module_configs(const nlohmann::json& config);
|
||||
Settings parse_settings(const nlohmann::json& settings_json);
|
||||
|
||||
Datatype string_to_datatype(const std::string& str);
|
||||
std::string datatype_to_string(const Datatype datatype);
|
||||
|
||||
Mutability string_to_mutability(const std::string& str);
|
||||
std::string mutability_to_string(const Mutability mutability);
|
||||
|
||||
ModuleTierMappings parse_mapping(const nlohmann::json& mapping_json);
|
||||
|
||||
} // namespace everest::config
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_BEGIN
|
||||
|
||||
template <> struct adl_serializer<everest::config::ModuleConfig> {
|
||||
static void to_json(nlohmann::json& j, const everest::config::ModuleConfig& m);
|
||||
static void from_json(const nlohmann::json& j, everest::config::ModuleConfig& m);
|
||||
};
|
||||
|
||||
template <> struct adl_serializer<everest::config::ConfigurationParameterCharacteristics> {
|
||||
static void to_json(nlohmann::json& j, const everest::config::ConfigurationParameterCharacteristics& c);
|
||||
static void from_json(const nlohmann::json& j, everest::config::ConfigurationParameterCharacteristics& c);
|
||||
};
|
||||
|
||||
template <> struct adl_serializer<everest::config::ConfigEntry> {
|
||||
static void to_json(nlohmann::json& j, const everest::config::ConfigEntry& entry);
|
||||
static void from_json(const nlohmann::json& j, everest::config::ConfigEntry& entry);
|
||||
};
|
||||
|
||||
template <> struct adl_serializer<everest::config::ConfigurationParameter> {
|
||||
static void to_json(nlohmann::json& j, const everest::config::ConfigurationParameter& p);
|
||||
static void from_json(const nlohmann::json& j, everest::config::ConfigurationParameter& p);
|
||||
};
|
||||
|
||||
template <> struct adl_serializer<everest::config::ModuleConfigAccess> {
|
||||
static void to_json(nlohmann::json& j, const everest::config::ModuleConfigAccess& m);
|
||||
static void from_json(const nlohmann::json& j, everest::config::ModuleConfigAccess& m);
|
||||
};
|
||||
|
||||
template <> struct adl_serializer<everest::config::ConfigAccess> {
|
||||
static void to_json(nlohmann::json& j, const everest::config::ConfigAccess& c);
|
||||
static void from_json(const nlohmann::json& j, everest::config::ConfigAccess& c);
|
||||
};
|
||||
|
||||
template <> struct adl_serializer<everest::config::Access> {
|
||||
static void to_json(nlohmann::json& j, const everest::config::Access& c);
|
||||
static void from_json(const nlohmann::json& j, everest::config::Access& c);
|
||||
};
|
||||
|
||||
NLOHMANN_JSON_NAMESPACE_END
|
||||
Reference in New Issue
Block a user