A plan of OCPP & California Pricing Requirements implementation.
Hi Guys
Here is a plan of standard《OCPP & California Pricing Requirements》implemetation, referencing the pdf: ocpp_and_dms_evse_regulation-v3.0
I plan to implement it in the following steps:
-
Branch: Create
feature/california-pricing-requirementsfrom remodel-api. -
Structure:
- Add a new service at
src/MicroOcpp/Model/California/CaliforniaService.cpp/h.
- Add a new service at
-
Implementation:
- Phase 1: OCPP 1.6 support for default pricing (§3.1.1)、final cost(§3.1.3)、 running cost (§3.1.4)、idle free (§3.4.1) and so on.
- Phase 2: OCPP 2.0.1 compatibility.
-
Testing:
- Add unit/integration tests in
test/California.cpp.
- Add unit/integration tests in
More details, I’ll share detailed design notes in the PR and here below comments.
@matth-x Hi Matthias
As per Default Pricing §3.1.1, a configuration option CustomDisplayCostAndPrice(boolean) will be added to enable or disable the custom cost and price display feature. This option will be included in the configuration file with a default value of false. For the DefaultPrice settings, a new configuration file named default-price.json will be created. This file will contain three main keys: priceText, priceTextOffline, and chargingPrice. The values of priceText and priceTextOffline, will be passed directly to the user interface for display.If offline sessions are enabled, the underlying rate parameters (kWhPrice, hourPrice, flatFee) of chargingPrice will be provided to the user. Simultaneously, The MO middleware will then automatically calculate the real-time and total cost based on these parameters and the energy consumption.
This design efficiently supports multi-language requirements, as the display text is handled separately, while also reducing the user's workload by offloading the complex cost calculations to MO.
As defined in RunningCost § rule 3.1.4, the configuration includes three key parameters: chargingPrice, nextPeriod, and triggerMeterValue. The chargingPrice specifies the current tariff and cost structure, similar to the chargingPrice defined in DefaultPricing. It defines the applicable rates for the ongoing charging session. The nextPeriod parameter is used to pre-configure the cost structure for the subsequent billing period. As this represents future pricing rules, it should be persisted in a dedicated configuration file (e.g. next-period-pricing.json) to ensure a smooth transition at the scheduled time. But would it better be stored in tx-<evseId>-<txnr>.json file?(the transation store file)(I don't remember the exact name). Because i think chargingPrice and nextPeriod are specific attributions of transation. The triggerMeterValue parameter defines the conditions that trigger the transmission of meter values to the CSMS. It supports multiple conditional triggers:
- atTime: Triggers a meter value report at a specific, pre-defined timestamp.
- atEnergykWh: Triggers a report when the cumulative energy delivered reaches a specified threshold (in kWh).
- atPowerkW: Triggers a report when the instantaneous power level matches a specified value (in kW).
- atCPStatus: Triggers a report based on a change in the connector's status (e.g. SuspendedEV and SuspendedEVSE).
To implement triggerMeterValue, my idea is create a new interface to meter value service. This interface will set the meter value trigger condition to true when is called. Then, within the service loop, it will trigger the transmission of one meter value record.
Hi @zhenbin-lin, thanks for the design walk through! Great plan so far, only a few questions:
The nextPeriod parameter is used to pre-configure the cost structure for the subsequent billing period. As this represents future pricing rules, it should be persisted in a dedicated configuration file (e.g. next-period-pricing.json) to ensure a smooth transition at the scheduled time.
I didn't understand this part, i.e. why to use a separate file for the NextPeriod type. For example, a reason to split Configurations into multiple files would be to save RAM during loading and storing to flash (because the JSON needs to be fully represented in heap).
But would it better be stored in tx-<evseId>-
.json file?(the transation store file)(I don't remember the exact name).
This would add details of the California Pricing module into the Transaction module which I would like to avoid. The Transaction module is already too complex at this point to be honest, so its scope shouldn't grow anymore if possible. Plus, imagine there are dozens of countries with their own legal regulations and each required a tiny addition to the Transaction module.
It would be okay however to start a new file series in parallel to the tx files with the further fields you need. E.g. calif-<evseId>-<txNr>.json.
To implement triggerMeterValue, my idea is create a new interface to meter value service. This interface will set the meter value trigger condition to true when is called. Then, within the service loop, it will trigger the transmission of one meter value record.
Sounds good, yes.
Hi @matth-x
Thank you for your feedback.
The nextPeriod parameter is used to pre-configure the cost structure for the subsequent billing period. As this represents future pricing rules, it should be persisted in a dedicated configuration file (e.g. next-period-pricing.json) to ensure a smooth transition at the scheduled time.
I'm sorry to have confused you. Regarding the nextPeriod parameter, I've revisited the documentation and i consider that storing it within the calif-<evseId>-<txNr>.json file is appropriate, as it is tied to the specific transaction context.
I am currently addressing a design challenge related to propagating changes to the priceText and priceTextOffline fields within the DefaultPrice configuration. My idea goal is to notify users via dedicated methods (e.g. priceTextOutput, priceTextOfflineOutput) when these values change, for instance, to update the display on an EVSE screen. The core issue is that the class ConfigurationConcrete lacks a built-in mechanism to notify services like CaliforniaService when its configuration is modified by the CSMS.
I have evaluated two potential approaches to achieve this:
- The CaliforniaService could periodically check for changes in the DefaultPrice configuration during its loop. However, this method is likely inefficient due to potentially high frequency of unnecessary checks (by
std::strcmpeach time), especially if configurations change infrequently. - Modify the ConfigurationConcrete class to implement an observable pattern, allowing it to notify registered listeners upon changes. But it would maybe require significant modifications to the MO....
I wonder if you have any thoughts or suggestions?
The new callback functions priceTextOutput and priceTextOfflineOutput sound like a great idea.
The best method to check string configurations for changes is to remember the "write count", i.e. how often the config was changed. If that number incremented, the server has updated the config:
https://github.com/matth-x/MicroOcpp/blob/f151cecf5f99908a8ab4cea5fe11bda2bdefe241/src/MicroOcpp/Model/Configuration/Configuration.h#L73
If that method has any downsides, let me know!