From 6aee7daef8239a1ad01089266c1697d65adcd475 Mon Sep 17 00:00:00 2001 From: Daniel Moore <9156191+drmrd@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:44:35 -0400 Subject: [PATCH 1/4] Move 2.0.1 use case documentation into a dedicated guide Signed-off-by: Daniel Moore <9156191+drmrd@users.noreply.github.com> --- doc/ocpp_201_use_cases_in_depth.md | 214 +++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 doc/ocpp_201_use_cases_in_depth.md diff --git a/doc/ocpp_201_use_cases_in_depth.md b/doc/ocpp_201_use_cases_in_depth.md new file mode 100644 index 000000000..255f8a1e1 --- /dev/null +++ b/doc/ocpp_201_use_cases_in_depth.md @@ -0,0 +1,214 @@ +## OCPP 2.0.1 Use Cases in `libocpp` + +The OCPP 2.0.1 specification is broken down into concrete functional requirements using a three-tier system. At the top, there are sixteen **functional blocks** lettered A through P that describe the high-level desired capabilities of actors adhering to the standard. These functional blocks are then broken into **use cases** that describe different scenarios in which one or more charging stations, local controllers, and charging station management systems might find themselves. The required and optional behaviors of these systems in these scenarios are then declared as **functional requirements** within each use case. + +This section includes an overview of how a subset of the OCPP 2.0.1 use cases that supported by `libocpp` are implemented in conjunction with callbacks provided by the charging station. We hope it serves as a useful guide to portions of the `libocpp` API and illustrates patterns of interaction between `libocpp` and other systems within a charging station. + +> [!NOTE] +> Our goal is not to reproduce the entire OCPP 2.0.1 specification in this document. Rather we intend to illustrate how various use cases are realized using `ChargePoint` methods in `libocpp` in conjunction with callback implementations and event handlers. +> +> Please refer to the [OCPP 2.0.1 standard](https://openchargealliance.org/protocols/open-charge-point-protocol/#OCPP2.0.1) for more details. Functional blocks, use cases, and functional requirements are addressed in Part 2 of Edition 2. + +| Functional Block | Subject | +| :--------------- | :------------------------------------------ | +| A | Security | +| B | Provisioning | +| C | Authorization | +| D | Local Authorization List Management | +| E | Transactions | +| F | Remote Control | +| G | Availability | +| H | Reservation | +| I | Tariff and Cost | +| J | Meter Values | +| K | [Smart Charging](#smart-charging-use-cases) | +| L | Firmware Management | +| M | ISO 15118 Certificate Management | +| N | Diagnostics | +| O | Display Message | +| P | Data Transfer | + +### Smart Charging Use Cases + +The use cases within the Smart Charging functional block are subdivided into the following three categories of use cases: + +1. General Smart Charging (Use Cases K01–K10) +2. External Charging Limit-based Smart Charging (K11–K14) +3. ISO 15118-based Smart Charging (K15–K17) + +Support for General and External Charging Limit-based Smart Charging is largely complete, with ISO 15118-based Smart Charging under active development. For an up-to-date overview of exactly which features are currently supported as well as design decisions that have been made to address optional or ambiguous functional requirements, please refer to the [OCPP 2.0.1 Status document](ocpp_201_status.md). + +#### K01 SetChargingProfile + +Allows the CSMS to influence the charging power or current drawn from a specific EVSE or the +entire Charging Station over a period of time. + +```mermaid +sequenceDiagram + CSMS->>+ChargePoint : SetChargingProfileRequest(call) + + ChargePoint->>+DeviceModel : SmartChargingCtrlrAvailable? + DeviceModel-->>-ChargePoint : Component + + rect Red + break SmartChargingCtrlrAvailable = false + ChargePoint-->>CSMS : Smart Charging NotSupported CallError + end + end + + ChargePoint->>+SmartCharging : validate_and_add_profile(call.msg.Profile, call.msg.EVSE ID) + + SmartCharging->>SmartCharging : validate_profile(Profile, EVSE ID) + + rect Red + break Invalid Profile + SmartCharging-->>ChargePoint : SetChargingProfileResponse: Rejected + ChargePoint-->>CSMS : SetChargingProfileResponse: Rejected + end + end + + SmartCharging->>+SmartCharging : add_profile(Profile, EVSE ID) + SmartCharging->>-EVerest : signal_set_charging_profiles_callback + + SmartCharging-->>-ChargePoint : SetChargingProfileResponse: Accepted + + ChargePoint-->>-CSMS : SetChargingProfileResponse: Accepted +``` + +Profile validation returns the following errors to the caller when a Profile +is `Rejected`: + +| Errors | Description | +| :------------------------------------------------------------ | :-------------------------------------------------------------- | +| `ChargingProfileFirstStartScheduleIsNotZero` | The `startPeriod` of the first `chargingSchedulePeriod` needs to be 0.
[K01.FR.31] | +| `ChargingProfileNoChargingSchedulePeriods` | Happens when the `ChargingProfile` doesn't have any Charging Schedule Periods. | +| `ChargingScheduleChargingRateUnitUnsupported` | Happens when a chargingRateUnit is passed in that is not configured in the `ChargingScheduleChargingRateUnit`. [K01.FR.26] | +| `ChargingSchedulePeriodInvalidPhaseToUse` | Happens when an invalid `phaseToUse` is passed in. [K01.FR.19] [K01.FR.48] | +| `ChargingSchedulePeriodPhaseToUseACPhaseSwitchingUnsupported` | Happens when phaseToUse is passed in and the EVSE does not have `ACPhaseSwitchingSupported` defined and set to true. [K01.FR.20] [K01.FR.48] | +| `ChargingSchedulePeriodsOutOfOrder` | `ChargingSchedulePeriod.startPeriod` elements need to be in increasing values. [K01.FR.35] | +| `ChargingStationMaxProfileCannotBeRelative` | Happens when a `ChargingStationMaxProfile.chargingProfileKind` is set to `Relative`. [K01.FR.38] | +| `ChargingStationMaxProfileEvseIdGreaterThanZero` | Happens when a `ChargingStationMaxProfile` is attempted to be set with an EvseID isn't `0`. [K01.FR.03] | +| `ChargingProfileMissingRequiredStartSchedule` | Happens when an `Absolute` or `Recurring` `ChargingProfile` doesn't have a `startSchedule`. [K01.FR.40] | +| `ChargingProfileExtraneousStartSchedule` | Happens when a Relative `ChargingProfile` has a `startSchedule`. [K01.FR.41] | +| `EvseDoesNotExist` | Happens when the `evseId`of a `SetChargingProfileRequest` does not exist. [K01.FR.28] | +| `ExistingChargingStationExternalConstraints` | Happens when a `SetChargingProfileRequest` Profile has a purpose of `ChargingStationExternalConstraints` and one already exists with the same `ChargingProfile.id` exists. [K01.FR.05] | +| `InvalidProfileType` | Happens when a `ChargingStationMaxProfile` is attempted to be set with a `ChargingProfile` that isn't a `ChargingStationMaxProfile`. | +| `TxProfileEvseHasNoActiveTransaction` | Happens when a `SetChargingProfileRequest` with a `TxProfile` is submitted and there is no transaction active on the specified EVSE. [K01.FR.09] | +| `TxProfileEvseIdNotGreaterThanZero` | `TxProfile` needs to have an `evseId` greater than 0. [K01.FR.16] | +| `TxProfileMissingTransactionId` | A `transactionId` is required for`SetChargingProfileRequest`s with a `TxProfile` in order to match the profile to a specific transation. [K01.FR.03] | +| `TxProfileTransactionNotOnEvse` | Happens when the provided `transactionId` is not known. [K01.FR.33] | +| `TxProfileConflictingStackLevel` | Happens when a TxProfile has a stackLevel and transactionId combination already exists in a TxProfile with a different id in order to ensure that no two charging profiles with same stack level and purpose can be valid at the same time. [K01.FR.39] | + + +#### K08 Get Composite Schedule + +The CSMS requests the Charging Station to report the Composite Charging +Schedule, as calculated by the Charging Station for a specific point of +time, and may change over time due to external causes such as local +balancing based on grid connection capacity and EVSE availablity. + +The Composite Schedule is the result of result of merging the time periods +set in the `ChargingStationMaxProfile`, `ChargingStationExternalConstraints`, +`TxDefaultProfile` and `TxProfile` type profiles. + +```mermaid +sequenceDiagram + + CSMS->>+ChargePoint: GetCompositeSchedule(call) + + ChargePoint->>+DeviceModel : ChargingScheduleChargingRateUnit? + DeviceModel-->>-ChargePoint : Component + + rect Red + break call.msg.chargingRateUnit is not supported + ChargePoint-->>CSMS : ChargingScheduleChargingRateUnitUnsupported CallError + end + end + + ChargePoint->>+EvseManager : does_evse_exist(call.msg.evseId) + EvseManager-->>-ChargePoint : bool + rect Red + break EVSE does not exist + ChargePoint-->>CSMS : EvseDoesNotExist CallError + end + end + + ChargePoint->>+SmartChargingHandler : get_valid_profiles(call.msg.evseId) + + SmartChargingHandler-->>-ChargePoint : vector + + ChargePoint->>+SmartChargingHandler : calculate_composite_schedule
(vector>+Profile: calculate_composite_schedule(profiles) + Profile-->>-SmartChargingHandler: composite_schedule + end + + note right of SmartChargingHandler: Create consolidated CompositeSchedule
from all 4 Profile types + + + SmartChargingHandler->>+Profile: calculate_composite_schedule(ExternalConstraints, Max, TxDefault, Tx) + Profile-->>-SmartChargingHandler: CompositeSchedule + + SmartChargingHandler-->>-ChargePoint: CompositeSchedule + + ChargePoint-->>-CSMS : GetCompositeScheduleResponse(CompositeSchedule) +``` + + +#### K09 Get Charging Profiles + +Returns to the CSMS the Charging Schedules/limits installed on a Charging Station based on the +passed in criteria. + +```mermaid +sequenceDiagram + + CSMS->>+ChargePoint: GetChargingProfiles(criteria) + + ChargePoint->>+SmartChargingHandler : get_reported_profiles(criteria) + + loop filter ChargingProfiles + SmartChargingHandler->>SmartChargingHandler: filter on ChargingProfile criteria + end + + SmartChargingHandler-->>-ChargePoint : Vector + + ChargePoint-->>CSMS : GetChargingProfilesResponse(profiles) + + alt no Profiles + rect Red + ChargePoint-->>CSMS : GetChargingProfilesResponse(NoProfiles) + ChargePoint->>CSMS : return + end + + else Profiles + ChargePoint-->>CSMS : GetChargingProfilesResponse(Accepted) + end + + ChargePoint->>ChargePoint : determine profiles_to_report + + ChargePoint-->>-CSMS : ReportChargingProfilesRequest(profiles_to_report) +``` + + +#### K10 Clear Charging Profile + +Clears Charging Profiles installed on a Charging Station based on the +passed in criteria. + +```mermaid +sequenceDiagram + + CSMS->>+ChargePoint: ClearChargingProfileRequest(criteria) + + alt no Profiles matching criteria + rect Red + ChargePoint-->>CSMS : ClearChargingProfileResponse(Unknown) + + end + + else found matching Profiles + ChargePoint-->>-CSMS : ClearChargingProfileResponse(Accepted) + end +``` From cd6c8ddb34ba1ac6127ab925a7a9378720b74547 Mon Sep 17 00:00:00 2001 From: Daniel Moore <9156191+drmrd@users.noreply.github.com> Date: Tue, 15 Oct 2024 15:46:25 -0400 Subject: [PATCH 2/4] Update highlight color in use case diagrams Signed-off-by: Daniel Moore <9156191+drmrd@users.noreply.github.com> --- doc/ocpp_201_use_cases_in_depth.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/ocpp_201_use_cases_in_depth.md b/doc/ocpp_201_use_cases_in_depth.md index 255f8a1e1..dfccb01c1 100644 --- a/doc/ocpp_201_use_cases_in_depth.md +++ b/doc/ocpp_201_use_cases_in_depth.md @@ -50,7 +50,7 @@ sequenceDiagram ChargePoint->>+DeviceModel : SmartChargingCtrlrAvailable? DeviceModel-->>-ChargePoint : Component - rect Red + rect rgb(128,202,255) break SmartChargingCtrlrAvailable = false ChargePoint-->>CSMS : Smart Charging NotSupported CallError end @@ -60,7 +60,7 @@ sequenceDiagram SmartCharging->>SmartCharging : validate_profile(Profile, EVSE ID) - rect Red + rect rgb(128,202,255) break Invalid Profile SmartCharging-->>ChargePoint : SetChargingProfileResponse: Rejected ChargePoint-->>CSMS : SetChargingProfileResponse: Rejected @@ -119,7 +119,7 @@ sequenceDiagram ChargePoint->>+DeviceModel : ChargingScheduleChargingRateUnit? DeviceModel-->>-ChargePoint : Component - rect Red + rect rgb(128,202,255) break call.msg.chargingRateUnit is not supported ChargePoint-->>CSMS : ChargingScheduleChargingRateUnitUnsupported CallError end @@ -127,7 +127,7 @@ sequenceDiagram ChargePoint->>+EvseManager : does_evse_exist(call.msg.evseId) EvseManager-->>-ChargePoint : bool - rect Red + rect rgb(128,202,255) break EVSE does not exist ChargePoint-->>CSMS : EvseDoesNotExist CallError end @@ -177,7 +177,7 @@ sequenceDiagram ChargePoint-->>CSMS : GetChargingProfilesResponse(profiles) alt no Profiles - rect Red + rect rgb(128,202,255) ChargePoint-->>CSMS : GetChargingProfilesResponse(NoProfiles) ChargePoint->>CSMS : return end @@ -203,7 +203,7 @@ sequenceDiagram CSMS->>+ChargePoint: ClearChargingProfileRequest(criteria) alt no Profiles matching criteria - rect Red + rect rgb(128,202,255) ChargePoint-->>CSMS : ClearChargingProfileResponse(Unknown) end From c730aa06604704da8f24e490d0fe9d91da244202 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piet=20G=C3=B6mpel?= Date: Tue, 10 Dec 2024 09:59:37 +0100 Subject: [PATCH 3/4] Moved smart charging in depth to doc directory and removed generic explainations apart from smart charging MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Piet Gömpel --- .../ocpp_201_smart_charging_in_depth.md} | 43 +++---------------- 1 file changed, 5 insertions(+), 38 deletions(-) rename doc/{ocpp_201_use_cases_in_depth.md => v201/ocpp_201_smart_charging_in_depth.md} (75%) diff --git a/doc/ocpp_201_use_cases_in_depth.md b/doc/v201/ocpp_201_smart_charging_in_depth.md similarity index 75% rename from doc/ocpp_201_use_cases_in_depth.md rename to doc/v201/ocpp_201_smart_charging_in_depth.md index dfccb01c1..1aaa2a03d 100644 --- a/doc/ocpp_201_use_cases_in_depth.md +++ b/doc/v201/ocpp_201_smart_charging_in_depth.md @@ -1,34 +1,4 @@ -## OCPP 2.0.1 Use Cases in `libocpp` - -The OCPP 2.0.1 specification is broken down into concrete functional requirements using a three-tier system. At the top, there are sixteen **functional blocks** lettered A through P that describe the high-level desired capabilities of actors adhering to the standard. These functional blocks are then broken into **use cases** that describe different scenarios in which one or more charging stations, local controllers, and charging station management systems might find themselves. The required and optional behaviors of these systems in these scenarios are then declared as **functional requirements** within each use case. - -This section includes an overview of how a subset of the OCPP 2.0.1 use cases that supported by `libocpp` are implemented in conjunction with callbacks provided by the charging station. We hope it serves as a useful guide to portions of the `libocpp` API and illustrates patterns of interaction between `libocpp` and other systems within a charging station. - -> [!NOTE] -> Our goal is not to reproduce the entire OCPP 2.0.1 specification in this document. Rather we intend to illustrate how various use cases are realized using `ChargePoint` methods in `libocpp` in conjunction with callback implementations and event handlers. -> -> Please refer to the [OCPP 2.0.1 standard](https://openchargealliance.org/protocols/open-charge-point-protocol/#OCPP2.0.1) for more details. Functional blocks, use cases, and functional requirements are addressed in Part 2 of Edition 2. - -| Functional Block | Subject | -| :--------------- | :------------------------------------------ | -| A | Security | -| B | Provisioning | -| C | Authorization | -| D | Local Authorization List Management | -| E | Transactions | -| F | Remote Control | -| G | Availability | -| H | Reservation | -| I | Tariff and Cost | -| J | Meter Values | -| K | [Smart Charging](#smart-charging-use-cases) | -| L | Firmware Management | -| M | ISO 15118 Certificate Management | -| N | Diagnostics | -| O | Display Message | -| P | Data Transfer | - -### Smart Charging Use Cases +# Smart Charging Use Cases The use cases within the Smart Charging functional block are subdivided into the following three categories of use cases: @@ -38,7 +8,7 @@ The use cases within the Smart Charging functional block are subdivided into the Support for General and External Charging Limit-based Smart Charging is largely complete, with ISO 15118-based Smart Charging under active development. For an up-to-date overview of exactly which features are currently supported as well as design decisions that have been made to address optional or ambiguous functional requirements, please refer to the [OCPP 2.0.1 Status document](ocpp_201_status.md). -#### K01 SetChargingProfile +## K01 SetChargingProfile Allows the CSMS to influence the charging power or current drawn from a specific EVSE or the entire Charging Station over a period of time. @@ -99,8 +69,7 @@ is `Rejected`: | `TxProfileTransactionNotOnEvse` | Happens when the provided `transactionId` is not known. [K01.FR.33] | | `TxProfileConflictingStackLevel` | Happens when a TxProfile has a stackLevel and transactionId combination already exists in a TxProfile with a different id in order to ensure that no two charging profiles with same stack level and purpose can be valid at the same time. [K01.FR.39] | - -#### K08 Get Composite Schedule +## K08 Get Composite Schedule The CSMS requests the Charging Station to report the Composite Charging Schedule, as calculated by the Charging Station for a specific point of @@ -155,8 +124,7 @@ sequenceDiagram ChargePoint-->>-CSMS : GetCompositeScheduleResponse(CompositeSchedule) ``` - -#### K09 Get Charging Profiles +## K09 Get Charging Profiles Returns to the CSMS the Charging Schedules/limits installed on a Charging Station based on the passed in criteria. @@ -191,8 +159,7 @@ sequenceDiagram ChargePoint-->>-CSMS : ReportChargingProfilesRequest(profiles_to_report) ``` - -#### K10 Clear Charging Profile +## K10 Clear Charging Profile Clears Charging Profiles installed on a Charging Station based on the passed in criteria. From 300bc8febb104a0694da5558f25913d99bdebf9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piet=20G=C3=B6mpel?= Date: Tue, 17 Dec 2024 00:02:09 +0100 Subject: [PATCH 4/4] Adressed some stylistic comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Piet Gömpel --- doc/v201/ocpp_201_smart_charging_in_depth.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/v201/ocpp_201_smart_charging_in_depth.md b/doc/v201/ocpp_201_smart_charging_in_depth.md index 1aaa2a03d..9fe215d18 100644 --- a/doc/v201/ocpp_201_smart_charging_in_depth.md +++ b/doc/v201/ocpp_201_smart_charging_in_depth.md @@ -54,7 +54,7 @@ is `Rejected`: | `ChargingProfileNoChargingSchedulePeriods` | Happens when the `ChargingProfile` doesn't have any Charging Schedule Periods. | | `ChargingScheduleChargingRateUnitUnsupported` | Happens when a chargingRateUnit is passed in that is not configured in the `ChargingScheduleChargingRateUnit`. [K01.FR.26] | | `ChargingSchedulePeriodInvalidPhaseToUse` | Happens when an invalid `phaseToUse` is passed in. [K01.FR.19] [K01.FR.48] | -| `ChargingSchedulePeriodPhaseToUseACPhaseSwitchingUnsupported` | Happens when phaseToUse is passed in and the EVSE does not have `ACPhaseSwitchingSupported` defined and set to true. [K01.FR.20] [K01.FR.48] | +| `ChargingSchedulePeriodPhaseToUseACPhaseSwitchingUnsupported` | Happens when `phaseToUse` is passed in and the EVSE does not have `ACPhaseSwitchingSupported` defined and set to true. [K01.FR.20] [K01.FR.48] | | `ChargingSchedulePeriodsOutOfOrder` | `ChargingSchedulePeriod.startPeriod` elements need to be in increasing values. [K01.FR.35] | | `ChargingStationMaxProfileCannotBeRelative` | Happens when a `ChargingStationMaxProfile.chargingProfileKind` is set to `Relative`. [K01.FR.38] | | `ChargingStationMaxProfileEvseIdGreaterThanZero` | Happens when a `ChargingStationMaxProfile` is attempted to be set with an EvseID isn't `0`. [K01.FR.03] | @@ -67,7 +67,7 @@ is `Rejected`: | `TxProfileEvseIdNotGreaterThanZero` | `TxProfile` needs to have an `evseId` greater than 0. [K01.FR.16] | | `TxProfileMissingTransactionId` | A `transactionId` is required for`SetChargingProfileRequest`s with a `TxProfile` in order to match the profile to a specific transation. [K01.FR.03] | | `TxProfileTransactionNotOnEvse` | Happens when the provided `transactionId` is not known. [K01.FR.33] | -| `TxProfileConflictingStackLevel` | Happens when a TxProfile has a stackLevel and transactionId combination already exists in a TxProfile with a different id in order to ensure that no two charging profiles with same stack level and purpose can be valid at the same time. [K01.FR.39] | +| `TxProfileConflictingStackLevel` | Happens when a `TxProfile` has a `stackLevel` and `transactionId` combination already exists in a `TxProfile` with a different id in order to ensure that no two charging profiles with same stack level and purpose can be valid at the same time. [K01.FR.39] | ## K08 Get Composite Schedule