From adeb7f2973171c0a41fa36151e6c58add1d6751c Mon Sep 17 00:00:00 2001 From: James Chapman Date: Wed, 13 Mar 2024 12:46:51 +0000 Subject: [PATCH 1/4] feat: create YAML/JSON definition for charging schedule Note this is an API breaking change. Originally charging schedules were published: { "0": {...}, "1": {...}} using the connector number as the key. This is not supported in the YAML interface or type definitions. Instead an array is used with an additional key added: [ { "connector": 0, ...}, { "connector": 1, ...} ... ] Note is should not be assumed that the array index will match the connector number. The existing types in libocpp have not been changed. A new mapping has been created in the OCPP module. (OCPP201 doesn't publish schedules at the moment) Signed-off-by: James Chapman --- interfaces/ocpp.yaml | 6 +++- interfaces/ocpp_1_6_charge_point.yaml | 9 +----- modules/OCPP/OCPP.cpp | 40 ++++++++++++++++++++++--- types/ocpp.yaml | 43 +++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 13 deletions(-) diff --git a/interfaces/ocpp.yaml b/interfaces/ocpp.yaml index 3ad858aff..a77a72a59 100644 --- a/interfaces/ocpp.yaml +++ b/interfaces/ocpp.yaml @@ -112,7 +112,11 @@ vars: Object that contains OCPP charging schedules of all connectors. The object contains one composite charging schedule for each connector id starting from connector 0. Connector 0 contains a schedule for the whole charging station. - type: object + type: array + items: + description: schedules for connectors + type: object + $ref: /ocpp#/ChargingSchedule is_connected: description: Indicates if chargepoint is connected to CSMS type: boolean diff --git a/interfaces/ocpp_1_6_charge_point.yaml b/interfaces/ocpp_1_6_charge_point.yaml index c6a0d169a..47483dc82 100644 --- a/interfaces/ocpp_1_6_charge_point.yaml +++ b/interfaces/ocpp_1_6_charge_point.yaml @@ -20,7 +20,7 @@ cmds: false get_configuration_key: description: >- - Gets the response to the requested configuration key containing a list of the values of the requested keys + Gets the response to the requested configuration key containing a list of the values of the requested keys and a list of the keys that are unknown arguments: keys: @@ -74,12 +74,6 @@ cmds: description: Additional information about the occurred security event type: string vars: - charging_schedules: - description: >- - Object that contains OCPP charging schedules of all connectors. The - object contains one composite charging schedule for each connector id starting - from connector 0. Connector 0 contains a schedule for the whole charging station. - type: object is_connected: description: Indicates if chargepoint is connected to CSMS type: boolean @@ -93,4 +87,3 @@ vars: description: Published when an internal security event occured type: object $ref: /ocpp#/SecurityEvent - diff --git a/modules/OCPP/OCPP.cpp b/modules/OCPP/OCPP.cpp index 316e9af3d..969eef197 100644 --- a/modules/OCPP/OCPP.cpp +++ b/modules/OCPP/OCPP.cpp @@ -2,6 +2,7 @@ // Copyright 2020 - 2022 Pionix GmbH and Contributors to EVerest #include "OCPP.hpp" #include "generated/types/ocpp.hpp" +#include "ocpp/v16/types.hpp" #include #include @@ -141,14 +142,45 @@ void OCPP::set_external_limits(const std::map& charging_schedules) { // publish the schedule over mqtt - Object j; - for (const auto charging_schedule : charging_schedules) { - j[std::to_string(charging_schedule.first)] = charging_schedule.second; + Array arr; + for (const auto& charging_schedule : charging_schedules) { + types::ocpp::ChargingSchedule sch = to_ChargingSchedule(charging_schedule.second); + sch.connector = charging_schedule.first; + arr.emplace_back(std::move(sch)); } - this->p_ocpp_generic->publish_charging_schedules(j); + this->p_ocpp_generic->publish_charging_schedules(arr); } void OCPP::process_session_event(int32_t evse_id, const types::evse_manager::SessionEvent& session_event) { diff --git a/types/ocpp.yaml b/types/ocpp.yaml index 1f7642f9c..799d8af14 100644 --- a/types/ocpp.yaml +++ b/types/ocpp.yaml @@ -2,6 +2,49 @@ description: >- OCPP types (OCPP1.6 and OCPP2.0.1). The types are based more on the type definitions of OCPP201, as these offer more flexibility and are easier to transfer to OCPP1.6 than vice versa. types: + ChargingSchedulePeriod: + description: >- + Element providing information on a charging schedule period. + type: object + required: + - startPeriod + - limit + - stackLevel + properties: + startPeriod: + type: integer + limit: + type: number + numberPhases: + type: integer + stackLevel: + type: integer + ChargingSchedule: + description: >- + Element providing information on an OCPP charging schedule. + type: object + required: + - connector + - chargingRateUnit + - chargingSchedulePeriod + properties: + connector: + type: integer + minimum: 0 + chargingRateUnit: + type: string + chargingSchedulePeriod: + type: array + items: + description: schedule periods + type: object + $ref: /ocpp#/ChargingSchedulePeriod + duration: + type: integer + startSchedule: + type: string + minChargingRate: + type: number OcppTransactionEvent: description: >- Element providing information on OCPP transactions. From f86d526b04835b366b0727e7bc83a01c987d5a31 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Wed, 13 Mar 2024 15:57:04 +0000 Subject: [PATCH 2/4] fix: Arrays not supported by the autogenerated code The autogenerated code doesn't support a module var being an array (of a specific object type) [{},{}] Instead the array is now wrapped in an object: {"schedules": [{},{}]} Signed-off-by: James Chapman --- interfaces/ocpp.yaml | 7 ++----- modules/OCPP/OCPP.cpp | 6 +++--- types/ocpp.yaml | 13 +++++++++++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/interfaces/ocpp.yaml b/interfaces/ocpp.yaml index a77a72a59..37ac95919 100644 --- a/interfaces/ocpp.yaml +++ b/interfaces/ocpp.yaml @@ -112,11 +112,8 @@ vars: Object that contains OCPP charging schedules of all connectors. The object contains one composite charging schedule for each connector id starting from connector 0. Connector 0 contains a schedule for the whole charging station. - type: array - items: - description: schedules for connectors - type: object - $ref: /ocpp#/ChargingSchedule + type: object + $ref: /ocpp#/ChargingSchedules is_connected: description: Indicates if chargepoint is connected to CSMS type: boolean diff --git a/modules/OCPP/OCPP.cpp b/modules/OCPP/OCPP.cpp index 969eef197..11f05341f 100644 --- a/modules/OCPP/OCPP.cpp +++ b/modules/OCPP/OCPP.cpp @@ -174,13 +174,13 @@ types::ocpp::ChargingSchedule to_ChargingSchedule(const ocpp::v16::EnhancedCharg void OCPP::publish_charging_schedules( const std::map& charging_schedules) { // publish the schedule over mqtt - Array arr; + types::ocpp::ChargingSchedules schedules; for (const auto& charging_schedule : charging_schedules) { types::ocpp::ChargingSchedule sch = to_ChargingSchedule(charging_schedule.second); sch.connector = charging_schedule.first; - arr.emplace_back(std::move(sch)); + schedules.schedules.emplace_back(std::move(sch)); } - this->p_ocpp_generic->publish_charging_schedules(arr); + this->p_ocpp_generic->publish_charging_schedules(schedules); } void OCPP::process_session_event(int32_t evse_id, const types::evse_manager::SessionEvent& session_event) { diff --git a/types/ocpp.yaml b/types/ocpp.yaml index 799d8af14..663bb86a6 100644 --- a/types/ocpp.yaml +++ b/types/ocpp.yaml @@ -45,6 +45,19 @@ types: type: string minChargingRate: type: number + ChargingSchedules: + description: schedules for connectors + type: object + required: + - schedules + properties: + schedules: + description: array of schedules + type: array + items: + description: schedule for a connector + type: object + $ref: /ocpp#/ChargingSchedule OcppTransactionEvent: description: >- Element providing information on OCPP transactions. From bfe1aa68ae097d072e453c43f02d2bc096131be6 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Thu, 14 Mar 2024 09:33:43 +0000 Subject: [PATCH 3/4] feat: add optional EVSE id for OCPP 2.0.1 Signed-off-by: James Chapman --- modules/OCPP/OCPP.cpp | 1 + types/ocpp.yaml | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/modules/OCPP/OCPP.cpp b/modules/OCPP/OCPP.cpp index 11f05341f..6e39c7f60 100644 --- a/modules/OCPP/OCPP.cpp +++ b/modules/OCPP/OCPP.cpp @@ -158,6 +158,7 @@ types::ocpp::ChargingSchedule to_ChargingSchedule(const ocpp::v16::EnhancedCharg 0, ocpp::v16::conversions::charging_rate_unit_to_string(schedule.chargingRateUnit), {}, + std::nullopt, schedule.duration, std::nullopt, schedule.minChargingRate}; diff --git a/types/ocpp.yaml b/types/ocpp.yaml index 663bb86a6..c528c9c78 100644 --- a/types/ocpp.yaml +++ b/types/ocpp.yaml @@ -28,6 +28,10 @@ types: - chargingRateUnit - chargingSchedulePeriod properties: + evse: + description: The OCPP 2.0.1 EVSE ID (not used in OCPP 1.6). + type: integer + minimum: 0 connector: type: integer minimum: 0 From fa3f464ad08d681d362212db2ef549fd4614f770 Mon Sep 17 00:00:00 2001 From: James Chapman Date: Thu, 14 Mar 2024 15:28:09 +0000 Subject: [PATCH 4/4] fix: addressed PR comments on use of snake_case fix: moved conversions to separate file Signed-off-by: James Chapman --- modules/OCPP/OCPP.cpp | 32 +------------------------------- modules/OCPP/conversions.cpp | 29 +++++++++++++++++++++++++++++ modules/OCPP/conversions.hpp | 7 +++++++ types/ocpp.yaml | 22 +++++++++++----------- 4 files changed, 48 insertions(+), 42 deletions(-) diff --git a/modules/OCPP/OCPP.cpp b/modules/OCPP/OCPP.cpp index 6e39c7f60..677778ffb 100644 --- a/modules/OCPP/OCPP.cpp +++ b/modules/OCPP/OCPP.cpp @@ -142,42 +142,12 @@ void OCPP::set_external_limits(const std::map& charging_schedules) { // publish the schedule over mqtt types::ocpp::ChargingSchedules schedules; for (const auto& charging_schedule : charging_schedules) { - types::ocpp::ChargingSchedule sch = to_ChargingSchedule(charging_schedule.second); + types::ocpp::ChargingSchedule sch = conversions::to_charging_schedule(charging_schedule.second); sch.connector = charging_schedule.first; schedules.schedules.emplace_back(std::move(sch)); } diff --git a/modules/OCPP/conversions.cpp b/modules/OCPP/conversions.cpp index 746fcbba5..a923998c3 100644 --- a/modules/OCPP/conversions.cpp +++ b/modules/OCPP/conversions.cpp @@ -359,5 +359,34 @@ to_everest_authorization_status(const ocpp::v201::AuthorizationStatusEnum status } } +types::ocpp::ChargingSchedulePeriod +to_charging_schedule_period(const ocpp::v16::EnhancedChargingSchedulePeriod& period) { + types::ocpp::ChargingSchedulePeriod csp = { + period.startPeriod, + period.limit, + period.stackLevel, + period.numberPhases, + }; + return csp; +} + +types::ocpp::ChargingSchedule to_charging_schedule(const ocpp::v16::EnhancedChargingSchedule& schedule) { + types::ocpp::ChargingSchedule csch = { + 0, + ocpp::v16::conversions::charging_rate_unit_to_string(schedule.chargingRateUnit), + {}, + std::nullopt, + schedule.duration, + std::nullopt, + schedule.minChargingRate}; + for (const auto& i : schedule.chargingSchedulePeriod) { + csch.charging_schedule_period.emplace_back(to_charging_schedule_period(i)); + } + if (schedule.startSchedule.has_value()) { + csch.start_schedule = schedule.startSchedule.value().to_rfc3339(); + } + return csch; +} + } // namespace conversions } // namespace module diff --git a/modules/OCPP/conversions.hpp b/modules/OCPP/conversions.hpp index 5f6633ba8..9e3524a31 100644 --- a/modules/OCPP/conversions.hpp +++ b/modules/OCPP/conversions.hpp @@ -89,6 +89,13 @@ types::authorization::AuthorizationStatus to_everest_authorization_status(const types::authorization::AuthorizationStatus to_everest_authorization_status(const ocpp::v201::AuthorizationStatusEnum status); +/// \brief Convert ocpp::v16::EnhancedChargingSchedulePeriod to types::ocpp::ChargingSchedulePeriod +types::ocpp::ChargingSchedulePeriod +to_charging_schedule_period(const ocpp::v16::EnhancedChargingSchedulePeriod& period); + +/// \brief Convert ocpp::v16::EnhancedChargingSchedule to types::ocpp::ChargingSchedule +types::ocpp::ChargingSchedule to_charging_schedule(const ocpp::v16::EnhancedChargingSchedule& schedule); + } // namespace conversions } // namespace module diff --git a/types/ocpp.yaml b/types/ocpp.yaml index c528c9c78..811d4bc50 100644 --- a/types/ocpp.yaml +++ b/types/ocpp.yaml @@ -7,17 +7,17 @@ types: Element providing information on a charging schedule period. type: object required: - - startPeriod + - start_period - limit - - stackLevel + - stack_level properties: - startPeriod: + start_period: type: integer limit: type: number - numberPhases: + number_phases: type: integer - stackLevel: + stack_level: type: integer ChargingSchedule: description: >- @@ -25,8 +25,8 @@ types: type: object required: - connector - - chargingRateUnit - - chargingSchedulePeriod + - charging_rate_unit + - charging_schedule_period properties: evse: description: The OCPP 2.0.1 EVSE ID (not used in OCPP 1.6). @@ -35,9 +35,9 @@ types: connector: type: integer minimum: 0 - chargingRateUnit: + charging_rate_unit: type: string - chargingSchedulePeriod: + charging_schedule_period: type: array items: description: schedule periods @@ -45,9 +45,9 @@ types: $ref: /ocpp#/ChargingSchedulePeriod duration: type: integer - startSchedule: + start_schedule: type: string - minChargingRate: + min_charging_rate: type: number ChargingSchedules: description: schedules for connectors