Skip to content

Commit

Permalink
OCPP2.0.1: Device model access for EVSE and Connector specific variab…
Browse files Browse the repository at this point in the history
…les (EVerest#553)

* Implemented dm access for EVSE and Connector
* Enhanced integrity check of device model by checking correct number of EVSE and Connectors
* DM Availability state and Power is updated at runtime
---------

Signed-off-by: pietfried <[email protected]>
Signed-off-by: Piet Gömpel <[email protected]>
  • Loading branch information
Pietfried authored and folkengine committed Apr 15, 2024
1 parent 29e50d9 commit 7fe1852
Show file tree
Hide file tree
Showing 12 changed files with 184 additions and 80 deletions.
4 changes: 4 additions & 0 deletions config/v201/component_schemas/custom/EVSE_1.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
{
"type": "Actual",
"mutability": "ReadOnly"
},
{
"type": "MaxSet",
"mutability": "ReadOnly"
}
],
"description": " kW,The variableCharacteristic maxLimit, that holds the maximum power that this EVSE can provide, is required. The Actual value of the instantaneous (real) power is desired, but not required.",
Expand Down
4 changes: 4 additions & 0 deletions config/v201/component_schemas/custom/EVSE_2.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
{
"type": "Actual",
"mutability": "ReadOnly"
},
{
"type": "MaxSet",
"mutability": "ReadOnly"
}
],
"description": " kW,The variableCharacteristic maxLimit, that holds the maximum power that this EVSE can provide, is required. The Actual value of the instantaneous (real) power is desired, but not required.",
Expand Down
16 changes: 2 additions & 14 deletions config/v201/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,6 @@
"name": "EVSE",
"evse_id": 1,
"variables": {
"EVSEAvailabilityState": {
"variable_name": "AvailabilityState",
"attributes": {
"Actual": ""
}
},
"EVSEAvailable": {
"variable_name": "Available",
"attributes": {
Expand All @@ -61,7 +55,7 @@
"EVSEPower": {
"variable_name": "Power",
"attributes": {
"Actual": 42
"MaxSet": 22000
}
},
"EVSESupplyPhases": {
Expand Down Expand Up @@ -101,12 +95,6 @@
"name": "EVSE",
"evse_id": 2,
"variables": {
"EVSEAvailabilityState": {
"variable_name": "AvailabilityState",
"attributes": {
"Actual": ""
}
},
"EVSEAvailable": {
"variable_name": "Available",
"attributes": {
Expand All @@ -116,7 +104,7 @@
"EVSEPower": {
"variable_name": "Power",
"attributes": {
"Actual": 42
"MaxSet": 22000
}
},
"EVSESupplyPhases": {
Expand Down
3 changes: 3 additions & 0 deletions include/ocpp/v201/charge_point.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,9 @@ class ChargePoint : ocpp::ChargingStationBase {
void init_certificate_expiration_check_timers();
void scheduled_check_client_certificate_expiration();
void scheduled_check_v2g_certificate_expiration();
void update_dm_availability_state(const int32_t evse_id, const int32_t connector_id,
const ConnectorStatusEnum status);
void update_dm_evse_power(const int32_t evse_id, const MeterValue& meter_value);

/// \brief Gets the configured NetworkConnectionProfile based on the given \p configuration_slot . The
/// central system uri ofthe connection options will not contain ws:// or wss:// because this method removes it if
Expand Down
26 changes: 18 additions & 8 deletions include/ocpp/v201/ctrlr_component_variables.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,6 @@ extern const ComponentVariable& TimeOffset;
extern const ComponentVariable& TimeOffsetNextTransition;
extern const RequiredComponentVariable& TimeSource;
extern const ComponentVariable& TimeZone;
extern const RequiredComponentVariable& ConnectorAvailable;
extern const RequiredComponentVariable& ConnectorType;
extern const RequiredComponentVariable& ConnectorSupplyPhases;
extern const ComponentVariable& CustomImplementationEnabled;
extern const RequiredComponentVariable& BytesPerMessageGetReport;
extern const RequiredComponentVariable& BytesPerMessageGetVariables;
Expand All @@ -122,10 +119,6 @@ extern const ComponentVariable& DisplayMessageCtrlrAvailable;
extern const RequiredComponentVariable& NumberOfDisplayMessages;
extern const RequiredComponentVariable& DisplayMessageSupportedFormats;
extern const RequiredComponentVariable& DisplayMessageSupportedPriorities;
extern const ComponentVariable& EVSEAllowReset;
extern const RequiredComponentVariable& EVSEAvailable;
extern const RequiredComponentVariable& EVSEPower;
extern const RequiredComponentVariable& EVSESupplyPhases;
extern const ComponentVariable& CentralContractValidationAllowed;
extern const RequiredComponentVariable& ContractValidationOffline;
extern const ComponentVariable& RequestMeteringReceipt;
Expand Down Expand Up @@ -210,8 +203,25 @@ extern const RequiredComponentVariable& StopTxOnInvalidId;
extern const ComponentVariable& TxBeforeAcceptedEnabled;
extern const RequiredComponentVariable& TxStartPoint;
extern const RequiredComponentVariable& TxStopPoint;

} // namespace ControllerComponentVariables

namespace EvseComponentVariables {
extern const Variable& Available;
extern const Variable& AvailabilityState;
extern const Variable& SupplyPhases;
extern const Variable& AllowReset;
extern const Variable& Power;
ComponentVariable get_component_variable(const 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 int32_t evse_id, const int32_t connector_id, const Variable& variable);
} // namespace ConnectorComponentVariables

} // namespace v201
} // namespace ocpp

Expand Down
2 changes: 1 addition & 1 deletion include/ocpp/v201/device_model.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class DeviceModel {

/// \brief Check data integrity of the device model provided by the device model data storage:
/// For "required" variables, assert values exist. Checks might be extended in the future.
void check_integrity();
void check_integrity(const std::map<int32_t, int32_t>& evse_connector_structure);
};

} // namespace v201
Expand Down
3 changes: 3 additions & 0 deletions include/ocpp/v201/utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ std::string generate_token_hash(const IdToken& token);
/// \return DateTime type timestamp
ocpp::DateTime align_timestamp(const DateTime timestamp, std::chrono::seconds align_interval);

/// \brief Returns the total Power_Active_Import value from the \p meter_value or std::nullopt if it is not present
std::optional<float> get_total_power_active_import(const MeterValue& meter_value);

} // namespace utils
} // namespace v201
} // namespace ocpp
Expand Down
39 changes: 38 additions & 1 deletion lib/ocpp/v201/charge_point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ ChargePoint::ChargePoint(const std::map<int32_t, int32_t>& evse_connector_struct
}

this->device_model = std::make_unique<DeviceModel>(std::move(device_model_storage));
this->device_model->check_integrity();
this->device_model->check_integrity(evse_connector_structure);

auto database_connection = std::make_unique<common::DatabaseConnection>(fs::path(core_database_path) / "cp.db");
this->database_handler = std::make_shared<DatabaseHandler>(std::move(database_connection), sql_init_path);
Expand All @@ -88,6 +88,7 @@ ChargePoint::ChargePoint(const std::map<int32_t, int32_t>& evse_connector_struct
// Set up the component state manager
this->component_state_manager = std::make_shared<ComponentStateManager>(
evse_connector_structure, database_handler, [this](auto evse_id, auto connector_id, auto status) {
this->update_dm_availability_state(evse_id, connector_id, status);
if (this->websocket == nullptr || !this->websocket->is_connected() ||
this->registration_status != RegistrationStatusEnum::Accepted) {
return false;
Expand Down Expand Up @@ -466,6 +467,7 @@ void ChargePoint::on_meter_value(const int32_t evse_id, const MeterValue& meter_
this->aligned_data_evse0.set_values(meter_value);
} else {
this->evses.at(evse_id)->on_meter_value(meter_value);
this->update_dm_evse_power(evse_id, meter_value);
}
}

Expand Down Expand Up @@ -3199,6 +3201,41 @@ void ChargePoint::scheduled_check_v2g_certificate_expiration() {
.value_or(12 * 60 * 60)));
}

void ChargePoint::update_dm_availability_state(const int32_t evse_id, const int32_t connector_id,
const ConnectorStatusEnum status) {
ComponentVariable evse_cv =
EvseComponentVariables::get_component_variable(evse_id, EvseComponentVariables::AvailabilityState);
ComponentVariable connector_cv = ConnectorComponentVariables::get_component_variable(
evse_id, connector_id, ConnectorComponentVariables::AvailabilityState);
if (evse_cv.variable.has_value()) {
this->device_model->set_read_only_value(evse_cv.component, evse_cv.variable.value(),
ocpp::v201::AttributeEnum::Actual,
conversions::connector_status_enum_to_string(status));
}
if (connector_cv.variable.has_value()) {
this->device_model->set_read_only_value(connector_cv.component, connector_cv.variable.value(),
ocpp::v201::AttributeEnum::Actual,
conversions::connector_status_enum_to_string(status));
}
}

void ChargePoint::update_dm_evse_power(const int32_t evse_id, const MeterValue& meter_value) {
ComponentVariable evse_power_cv =
EvseComponentVariables::get_component_variable(evse_id, EvseComponentVariables::Power);

if (!evse_power_cv.variable.has_value()) {
return;
}

const auto power = utils::get_total_power_active_import(meter_value);
if (!power.has_value()) {
return;
}

this->device_model->set_read_only_value(evse_power_cv.component, evse_power_cv.variable.value(),
AttributeEnum::Actual, std::to_string(power.value()));
}

void ChargePoint::set_cs_operative_status(OperationalStatusEnum new_status, bool persist) {
this->component_state_manager->set_cs_individual_operational_status(new_status, persist);
}
Expand Down
81 changes: 30 additions & 51 deletions lib/ocpp/v201/ctrlr_component_variables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@ const Component& AuthCacheCtrlr = {"AuthCacheCtrlr"};
const Component& AuthCtrlr = {"AuthCtrlr"};
const Component& ChargingStation = {"ChargingStation"};
const Component& ClockCtrlr = {"ClockCtrlr"};
const Component& Connector = {"Connector"};
const Component& CustomizationCtrlr = {"CustomizationCtrlr"};
const Component& DeviceDataCtrlr = {"DeviceDataCtrlr"};
const Component& DisplayMessageCtrlr = {"DisplayMessageCtrlr"};
const Component& EVSE = {"EVSE"};
const Component& ISO15118Ctrlr = {"ISO15118Ctrlr"};
const Component& LocalAuthListCtrlr = {"LocalAuthListCtrlr"};
const Component& MonitoringCtrlr = {"MonitoringCtrlr"};
Expand Down Expand Up @@ -525,27 +523,6 @@ const ComponentVariable& TimeZone = {
"TimeZone",
}),
};
const RequiredComponentVariable& ConnectorAvailable = {
ControllerComponents::Connector,
std::nullopt,
std::optional<Variable>({
"Available",
}),
};
const RequiredComponentVariable& ConnectorType = {
ControllerComponents::Connector,
std::nullopt,
std::optional<Variable>({
"ConnectorType",
}),
};
const RequiredComponentVariable& ConnectorSupplyPhases = {
ControllerComponents::Connector,
std::nullopt,
std::optional<Variable>({
"SupplyPhases",
}),
};
const ComponentVariable& CustomImplementationEnabled = {
ControllerComponents::CustomizationCtrlr,
std::nullopt,
Expand Down Expand Up @@ -625,34 +602,6 @@ const RequiredComponentVariable& DisplayMessageSupportedPriorities = {
"SupportedPriorities",
}),
};
const ComponentVariable& EVSEAllowReset = {
ControllerComponents::EVSE,
std::nullopt,
std::optional<Variable>({
"AllowReset",
}),
};
const RequiredComponentVariable& EVSEAvailable = {
ControllerComponents::EVSE,
std::nullopt,
std::optional<Variable>({
"Available",
}),
};
const RequiredComponentVariable& EVSEPower = {
ControllerComponents::EVSE,
std::nullopt,
std::optional<Variable>({
"Power",
}),
};
const RequiredComponentVariable& EVSESupplyPhases = {
ControllerComponents::EVSE,
std::nullopt,
std::optional<Variable>({
"SupplyPhases",
}),
};
const ComponentVariable& CentralContractValidationAllowed = {
ControllerComponents::ISO15118Ctrlr,
std::nullopt,
Expand Down Expand Up @@ -1219,5 +1168,35 @@ const RequiredComponentVariable& TxStopPoint = {
};

} // namespace ControllerComponentVariables

namespace EvseComponentVariables {

const Variable& Available = {"Available"};
const Variable& AvailabilityState = {"AvailabilityState"};
const Variable& SupplyPhases = {"SupplyPhases"};
const Variable& AllowReset = {"AllowReset"};
const Variable& Power = {"Power"};

ComponentVariable get_component_variable(const int32_t evse_id, const Variable& variable) {
EVSE evse = {evse_id};
Component component = {"EVSE", std::nullopt, evse};
return {component, std::nullopt, variable};
}
} // namespace EvseComponentVariables

namespace ConnectorComponentVariables {

const Variable& Available = {"Available"};
const Variable& AvailabilityState = {"AvailabilityState"};
const Variable& Type = {"Type"};
const Variable& SupplyPhases = {"SupplyPhases"};

ComponentVariable get_component_variable(const int32_t evse_id, const int32_t connector_id, const Variable& variable) {
EVSE evse = {evse_id, std::nullopt, connector_id};
Component component = {"Connector", std::nullopt, evse};
return {component, std::nullopt, variable};
}
} // namespace ConnectorComponentVariables

} // namespace v201
} // namespace ocpp
Loading

0 comments on commit 7fe1852

Please sign in to comment.