MicroOcpp icon indicating copy to clipboard operation
MicroOcpp copied to clipboard

A plan of OCPP & California Pricing Requirements implementation.

Open zhenbin-lin opened this issue 2 months ago • 5 comments

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:

  1. Branch: Create feature/california-pricing-requirements from remodel-api.
  2. Structure:
    • Add a new service at src/MicroOcpp/Model/California/CaliforniaService.cpp/h.
  3. 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.
  4. Testing:
    • Add unit/integration tests in test/California.cpp.

More details, I’ll share detailed design notes in the PR and here below comments.

zhenbin-lin avatar Nov 20 '25 11:11 zhenbin-lin

@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.

zhenbin-lin avatar Nov 22 '25 16:11 zhenbin-lin

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.

zhenbin-lin avatar Nov 22 '25 16:11 zhenbin-lin

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.

matth-x avatar Nov 23 '25 22:11 matth-x

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:

  1. 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::strcmp each time), especially if configurations change infrequently.
  2. 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?

zhenbin-lin avatar Nov 24 '25 13:11 zhenbin-lin

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!

matth-x avatar Nov 27 '25 10:11 matth-x

Hi @matth-x

When you have a moment, could I ask you to review PR(439)? No rush at all. Thanks!

zhenbin-lin avatar Dec 27 '25 00:12 zhenbin-lin