@open-charging-cloud/wwcp-poi 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +658 -1
- package/README.md +106 -38
- package/dist/common.d.ts +11 -0
- package/dist/common.d.ts.map +1 -1
- package/dist/crypto/ber.d.ts +48 -0
- package/dist/crypto/ber.d.ts.map +1 -0
- package/dist/crypto/certificates.d.ts +21 -0
- package/dist/crypto/certificates.d.ts.map +1 -0
- package/dist/crypto/curves.d.ts +25 -0
- package/dist/crypto/curves.d.ts.map +1 -0
- package/dist/crypto/ecc.d.ts +34 -0
- package/dist/crypto/ecc.d.ts.map +1 -0
- package/dist/crypto/publicKeys.d.ts +51 -0
- package/dist/crypto/publicKeys.d.ts.map +1 -0
- package/dist/crypto/rsa.d.ts +30 -0
- package/dist/crypto/rsa.d.ts.map +1 -0
- package/dist/encoding/text.d.ts +9 -0
- package/dist/encoding/text.d.ts.map +1 -1
- package/dist/evTaler/amounts.d.ts +89 -0
- package/dist/evTaler/amounts.d.ts.map +1 -0
- package/dist/evTaler/contractTerms.d.ts +126 -0
- package/dist/evTaler/contractTerms.d.ts.map +1 -0
- package/dist/evTaler/meterValue.d.ts +65 -0
- package/dist/evTaler/meterValue.d.ts.map +1 -0
- package/dist/evTaler/payURI.d.ts +28 -0
- package/dist/evTaler/payURI.d.ts.map +1 -0
- package/dist/evTaler/settlement.d.ts +85 -0
- package/dist/evTaler/settlement.d.ts.map +1 -0
- package/dist/evTaler/step.d.ts +72 -0
- package/dist/evTaler/step.d.ts.map +1 -0
- package/dist/history/apply.d.ts +6 -1
- package/dist/history/apply.d.ts.map +1 -1
- package/dist/history/changeSet.d.ts +30 -4
- package/dist/history/changeSet.d.ts.map +1 -1
- package/dist/history/checkpoint.d.ts +7 -0
- package/dist/history/checkpoint.d.ts.map +1 -1
- package/dist/history/commit.d.ts +21 -3
- package/dist/history/commit.d.ts.map +1 -1
- package/dist/history/elements.d.ts +19 -0
- package/dist/history/elements.d.ts.map +1 -0
- package/dist/history/history.d.ts +46 -6
- package/dist/history/history.d.ts.map +1 -1
- package/dist/history/preconditions.d.ts +23 -0
- package/dist/history/preconditions.d.ts.map +1 -0
- package/dist/index.d.ts +11 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10170 -2047
- package/dist/index.js.map +1 -1
- package/dist/json/canonical.d.ts.map +1 -1
- package/dist/keys.d.ts.map +1 -1
- package/dist/network/certificates.d.ts +16 -4
- package/dist/network/certificates.d.ts.map +1 -1
- package/dist/network/countries.d.ts +16 -0
- package/dist/network/countries.d.ts.map +1 -0
- package/dist/network/evTaler.d.ts +7 -14
- package/dist/network/evTaler.d.ts.map +1 -1
- package/dist/network/identifications.d.ts +6 -6
- package/dist/network/identifications.d.ts.map +1 -1
- package/dist/network/measurementPublicKey.d.ts +7 -0
- package/dist/network/measurementPublicKey.d.ts.map +1 -0
- package/dist/network/offers.d.ts +53 -0
- package/dist/network/offers.d.ts.map +1 -0
- package/dist/network/partyKeys.d.ts +8 -5
- package/dist/network/partyKeys.d.ts.map +1 -1
- package/dist/network/poiJSON.d.ts +175 -0
- package/dist/network/poiJSON.d.ts.map +1 -0
- package/dist/network/poiValues.d.ts +55 -0
- package/dist/network/poiValues.d.ts.map +1 -0
- package/dist/network/reading.d.ts +58 -0
- package/dist/network/reading.d.ts.map +1 -0
- package/dist/network/references.d.ts +43 -0
- package/dist/network/references.d.ts.map +1 -0
- package/dist/network/roamingNetwork.d.ts +17 -12
- package/dist/network/roamingNetwork.d.ts.map +1 -1
- package/dist/network/timeZones.d.ts +8 -0
- package/dist/network/timeZones.d.ts.map +1 -0
- package/dist/network/tree.d.ts +14 -0
- package/dist/network/tree.d.ts.map +1 -1
- package/dist/network/versionTexts.d.ts +1 -7
- package/dist/network/versionTexts.d.ts.map +1 -1
- package/dist/network/writtenForm.d.ts +27 -1
- package/dist/network/writtenForm.d.ts.map +1 -1
- package/dist/proofs/keyStatement.d.ts.map +1 -1
- package/dist/proofs/priceStatement.d.ts.map +1 -1
- package/dist/verifier/checkpoints.d.ts +6 -0
- package/dist/verifier/checkpoints.d.ts.map +1 -1
- package/dist/verifier/grossRates.d.ts +11 -0
- package/dist/verifier/grossRates.d.ts.map +1 -0
- package/dist/verifier/sessionPrices.d.ts +3 -0
- package/dist/verifier/sessionPrices.d.ts.map +1 -1
- package/package.json +14 -13
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,664 @@
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
## 0.
|
|
6
|
+
## 0.4.0 (prepared; not yet published)
|
|
7
|
+
|
|
8
|
+
Change sets and commits as WWCP_POI3 writes them again, and EV Taler phase 3: a change is read, applied and refused as
|
|
9
|
+
WWCP_POI3 reads, applies and refuses it, each party read again right after the change that changed it; a change set and
|
|
10
|
+
its commit are identified and signed over what WWCP_POI3 writes of them again, not over them as given; a charging
|
|
11
|
+
station operator names where drivers pay ad hoc (`webPaymentURL`) and ask for offers (`offersURL`), and a charging pool
|
|
12
|
+
naming EV Taler the secure dynamic QR code of its stations; a profile of contracts binds the price of a session started
|
|
13
|
+
through an e-mobility provider. Each of them is probed against WWCP_POI3, what differs named below, and the vectors of
|
|
14
|
+
WWCPPOIConformanceTests `448fc73` hold, none deviating, on the run of WWCP_POI `76d3653`. See [Migration](#migration)
|
|
15
|
+
before upgrading: versions and change sets 0.3.0 took are refused, others it refused are taken, and the words of many
|
|
16
|
+
refusals change.
|
|
17
|
+
|
|
18
|
+
- `poi-evtaler.json` of WWCPPOIConformanceTests `448fc73` vendored byte for byte and run in
|
|
19
|
+
`tests/conformance.test.ts`: the amounts of EV Taler (concepts/EVTaler.md of WWCP_POI, section 9 and open point 3,
|
|
20
|
+
no part of SPECIFICATION.md), 57 vectors. The gross rates of the simple profile of a charging tariff or why it has none
|
|
21
|
+
(4 priced, 14 not), what a step costs, rounded up to the minor unit of the currency, or that the tariff does not price
|
|
22
|
+
it (17 and 2), and the price of a session, rounded to the nearest, half away from zero (20). No change of the
|
|
23
|
+
library: it calculates all of them as WWCP_POI3 does.
|
|
24
|
+
|
|
25
|
+
- The authentication mode SecureDynamicQRCode, as WWCP_POI `76d3653` reads it (EV Taler, decision D8 of
|
|
26
|
+
concepts/EVTaler.md): the channels the stations of a charging pool give the URL of their secure dynamic QR code over,
|
|
27
|
+
with its time-based one-time password of OCPP 2.1, `BLE`, `Display` and `NFC`, at least one, each once, by its exact
|
|
28
|
+
name and in the ordinal order of their names; no other type names channels. A charging pool naming the payment option
|
|
29
|
+
EVTaler, as it is at runtime with what its templates give it, names it too, its own or of a template, where its
|
|
30
|
+
operator has an EV Taler merchant: "The charging pool '…' names the payment option 'EVTaler' without the
|
|
31
|
+
authentication mode 'SecureDynamicQRCode': an EV Taler session names the one-time password its EVSE gives right
|
|
32
|
+
then!", checked as the merchant rule, when an operator is read and after the last change of a change set, so that a
|
|
33
|
+
change set adds the merchant, the payment option and the code in any order. Probed against WWCP_POI3 at `76d3653`: the
|
|
34
|
+
43 versions of ZProbeNetworks alike in verdicts and words, one in a JToken text of C# with CRLF only. Example A15
|
|
35
|
+
prints the authentication modes of Jena Paradies as the C# example does.
|
|
36
|
+
|
|
37
|
+
- The frozen run is `csharp-76d3653` (WWCP_POI `76d3653`, Hermod `c5ff091b`, Styx `a6b9f9fb`, .NET 11), AT
|
|
38
|
+
`2026-11-12T21:55:00.000Z`, in place of `csharp-c4c3c5a`: revision 11 of epoch 2 is "Jena Paradies: EV Taler, with a
|
|
39
|
+
secure dynamic QR code" now, which the old run, the payment option alone, no longer is. Vendored byte for byte from
|
|
40
|
+
WWCPPOIConformanceTests `a81db5f` with it: `poi-history.json`, `poi-refusals.json` (6 versions of the code refused or
|
|
41
|
+
held otherwise), `poi-histories.json` (Jena Paradies of history-parties with the code; 3 replays new: the payment
|
|
42
|
+
option without the code refused, the code first, the code removed while named refused) and `poi-qidigital.json`.
|
|
43
|
+
The tests on QA hold the values of the new run, mapped by content; what WWCP_POI3 calculated of changed versions
|
|
44
|
+
(after ETags of the change sets of element, embedded, infrastructure and release changes, the ETags and
|
|
45
|
+
identifications of the preconditions and change sets, the versions with an EV Taler merchant) calculated again by
|
|
46
|
+
WWCP_POI3 at `76d3653` on the very same versions, all alike.
|
|
47
|
+
|
|
48
|
+
- `poi-histories.json` of WWCPPOIConformanceTests `d552a8a` vendored, its other vectors those of `674b173`: 4
|
|
49
|
+
replays of a change set WWCP_POI3 writes again, it and its commit identified and signed so (`791219c`): a
|
|
50
|
+
precondition with ` DE*GEF `, `preconditions: []` and `metadata: {}` taken; the precondition identified as given
|
|
51
|
+
refused, "is not identified by its content".
|
|
52
|
+
|
|
53
|
+
- `poi-refusals.json` and `poi-histories.json` of WWCPPOIConformanceTests `674b173` vendored, its other vectors those of
|
|
54
|
+
`3bb2928`: 11 vectors this library took and refused as given already, of where drivers ask for offers (`offersURL`,
|
|
55
|
+
refused and held as written otherwise, signed for `payments`) and of preconditions held, changed and of no entity.
|
|
56
|
+
|
|
57
|
+
- A commit is identified and signed over its change set as WWCP_POI3 writes it again (`RoamingNetworkCommit.TryParse`),
|
|
58
|
+
as its change set is since `7f5fbe5`: a change set with `metadata: {}`, `preconditions: []` or a precondition with
|
|
59
|
+
` DE*GEF `, its commit identified over it as written again, this library refused, "The commit identification '…' is
|
|
60
|
+
not the one of its content, '…'!", where WWCP_POI3 takes it (reported by WWCPPOIConformanceTests). A change set is
|
|
61
|
+
read in the order WWCP_POI3 reads it, identified by its content last, so that one wrong in two ways is refused for
|
|
62
|
+
the same: its roaming network and createdAt first, then its changes, ETags, description, metadata, preconditions and
|
|
63
|
+
signatures. With the change proposed for WWCP_POI3 on top of `62390ca` (a change set names only what it is written
|
|
64
|
+
with, its createdAt and roaming network as it writes them again), WWCP_POI3 refuses what this library refuses, a
|
|
65
|
+
property it does not read, a `createdAt` written otherwise, a roaming network given as a number, in its words: the 88
|
|
66
|
+
change sets of ZProbePreconditions alike in verdicts and words.
|
|
67
|
+
|
|
68
|
+
- `poi-verifier.json` and `chargy/POIPrices` of WWCPPOIConformanceTests `3bb2928` vendored, its other vectors those of
|
|
69
|
+
`86dfc09`: 3 vectors of the profile of contracts (WWCP_POI `b414296`), `sessionPrice-contract-profile` bound,
|
|
70
|
+
`sessionPrice-adhoc-contract-profile` and `sessionPrice-subscription-mode` unsupported, and their documents
|
|
71
|
+
`contract-profile.chargy`, `adhoc-contract-profile.chargy` and `subscription-mode.chargy`.
|
|
72
|
+
|
|
73
|
+
- EV Taler, phase 3, as WWCP_POI `62390ca` takes it: the merchant of an operator (`evTaler`) names where drivers ask
|
|
74
|
+
for offers, if the operator makes them, its optional `offersURL` (`EVTalerMerchant.offersURL`), a base URL as its
|
|
75
|
+
merchant base URL is one: HTTPS, ending in '/', without user, query and fragment, "The offers URL '…' must be an HTTPS
|
|
76
|
+
URL! (Parameter 'OffersURL')"; read after the exchanges and checked after the merchant base URL, as WWCP_POI3 reads
|
|
77
|
+
and checks it; written as Hermod writes it, or refused, "The offers URL '…' is written as '…'!". Without it, a merchant
|
|
78
|
+
is written as before, byte for byte. `evTalerSessionPrices` gives what prices a session at an EVSE, as the backend of
|
|
79
|
+
an operator makes its steps (`EVTalerContractTerms.TryGetSessionPrices`): its EV Taler tariff, the price statement
|
|
80
|
+
current when the session begins that prices it, one of an EVSE before the station's before the pool's, and the
|
|
81
|
+
elements. Probed with 29 merchants on WWCP_POI3 at `62390ca` (Hermod `c2f4bdde`): the same ETags, refusals and
|
|
82
|
+
words, but for the line ends of a JSON object named in a refusal, which .NET writes as the platform does.
|
|
83
|
+
- A change set is identified by its content as WWCP_POI3 writes it again (`ToJSON`), not only by its changes: its
|
|
84
|
+
preconditions each with its entity type and identification trimmed, also to nothing, without its context and any
|
|
85
|
+
other property, none where there are none (`preconditions: []`); its roaming network trimmed; its description as Styx
|
|
86
|
+
reads a text in languages (each language in lower case, a text of no language it reads left out), none where it is
|
|
87
|
+
JSON null or has no text left; no metadata where they hold nothing. This library identified them as given: a change
|
|
88
|
+
set with ` DE*GEF*P1 ` in a precondition, identified so, it took, which WWCP_POI3 refuses as "not identified by its
|
|
89
|
+
content". Its signatures are verified over it as written again, as WWCP_POI3 signs and verifies them
|
|
90
|
+
(`ToJSON(Embedded: true, IncludeSignatures: false)`), not over it as given, also of the changes written again since
|
|
91
|
+
`eb607f9`. Read as WWCP_POI3 reads it: the texts of a precondition trimmed, empty ones read and refused when applied,
|
|
92
|
+
"Precondition 0: the ChargingPool '' does not exist!", where this library said "Invalid precondition 0!"; its
|
|
93
|
+
roaming network trimmed and compared without case (`RoamingNetwork_Id`), refused in the words of WWCP_POI3 where it
|
|
94
|
+
is missing, JSON null or blank ("Invalid 'roaming network identification'!"); a description or metadata that is no
|
|
95
|
+
JSON object refused ("JSON property 'description' is not an object!", "The metadata must be a JSON object!"), which
|
|
96
|
+
this library took. Probed with 88 change sets with ZProbePreconditions on WWCP_POI3 at `c4c3c5a`, each identified as
|
|
97
|
+
given and as WWCP_POI3 writes it: the same verdicts and words but for those this library refuses where WWCP_POI3
|
|
98
|
+
takes them: a property it does not know of a change set, a change or a precondition, which WWCP_POI3 leaves out; a
|
|
99
|
+
`createdAt` written otherwise than `yyyy-MM-ddTHH:mm:ss.fffZ`, which it writes so; a roaming network given as a
|
|
100
|
+
number, which it reads as its text.
|
|
101
|
+
|
|
102
|
+
- A profile of contracts, `chargy-contract-gross-rates/v1` (`CONTRACT_GROSS_PRICE_PROFILE`), binds the price of a
|
|
103
|
+
session started through an e-mobility provider, of a contract with it, as WWCP_POI `b414296` takes it: a price
|
|
104
|
+
agreement whose `chargingMode` is `contract` is `bound` of it, of the same rates as the simple profile, and its price
|
|
105
|
+
is the one the CPO charges the provider; what the provider charges its customer stays unproven. Contract mode of the
|
|
106
|
+
simple profile stays `unsupported`, as the vector `sessionPrice-contract-mode` has it ("Contract mode requires an
|
|
107
|
+
additional profile"), and so does `adhoc` of the profile of contracts.
|
|
108
|
+
- `examples/validate-examples.ts` checks example A16 as its `Validate()` does: from the file the app kept alone, against
|
|
109
|
+
the trust anchor of epoch 2, the station proof at the time the session began; both steps in their contract terms
|
|
110
|
+
against it and the price statement of the EVSE; the start and the end value in OCMF with the key of the meter the
|
|
111
|
+
proof gives, by an OCMF verifier of its own as `VerifyOCMF` of `exampleA16.cs`; and the settlement statement, signed
|
|
112
|
+
by `DE*GEF` with its key for payments. Refused: another price, the end value left out, step 1 of another merchant,
|
|
113
|
+
step 2 naming the end value as the start. What it prints is what the C# example printed in a run of WWCP_POI
|
|
114
|
+
`c4c3c5a`, line for line. `npm run examples` checks it on the run vendored here, `csharp-c4c3c5a` (below), the nightly
|
|
115
|
+
runs of WWCPPOIConformanceTests on a new run of WWCP_POI master. README lists every test file.
|
|
116
|
+
- The test vectors of a new run of the C# examples, `tests/vectors/csharp-c4c3c5a` in place of `csharp-045e180`:
|
|
117
|
+
WWCP_POI `c4c3c5a` with Hermod `850cab3d` and Styx `21d00134`, examples A1 to A16, MakeProofs at
|
|
118
|
+
`2026-11-10T05:54:00.000Z` (`tests/at.ts`). The head of epoch 2 is revision 11, as before; example A16 adds the file
|
|
119
|
+
the app keeps of its EV Taler session, `driver/evidence-DE_GEF_E1_1-evTaler.json`. With them, of
|
|
120
|
+
WWCPPOIConformanceTests `228041d`, byte for byte: `poi-history.json` (the price statement of that file new, 9),
|
|
121
|
+
`poi-refusals.json` (307, 33 of them with a reason now), `poi-histories.json` (89 replays, 13 new of the web payment
|
|
122
|
+
page signed for payments), `poi-qidigital.json`, `poi-verifier.json` (109, `sessionPrice-flat-fee` bound) and
|
|
123
|
+
`chargy/POIPrices` with `flat-fee.chargy`. The tests on QA hold the values of the new run, mapped by content, a key
|
|
124
|
+
a test picks by its position the key now there; those WWCP_POI3 calculated of changed versions (the after ETags of 75
|
|
125
|
+
element, embedded, infrastructure and release change sets, the ETags of preconditions, the versions with an EV Taler
|
|
126
|
+
merchant) are calculated again by WWCP_POI3 at `c4c3c5a`, and this library takes the very same versions.
|
|
127
|
+
`tests/conformance.test.ts` 825.
|
|
128
|
+
- `poi-histories.json` of WWCPPOIConformanceTests `86dfc09` vendored, its other vectors those of `228041d`: 4 replays of
|
|
129
|
+
the roles every commit must be signed in (POI3-ISSUES.md S24), `required-role-*`, naming `requiredSignatureRoles`,
|
|
130
|
+
which `tests/conformance.ts` now gives the options of the history of a replay: a commit signed in the role
|
|
131
|
+
`roamingNetworkOperator` only by a key of DE*GEF, which the version does not certify for it, or not in it at all, is
|
|
132
|
+
refused; one key that may sign in it is enough. And `offer-of-a-provider-overlapping`, two offers of an e-mobility
|
|
133
|
+
provider overlapping at its EVSE group, refused (9.4). 94 replays, `tests/conformance.test.ts` 830.
|
|
134
|
+
- For development, Vite 8.3.7 (Rolldown 1.2.18) and typescript-eslint 8.72.2. TypeScript stays at 6.0:
|
|
135
|
+
typescript-eslint 8.72.2 still requires a version below 6.1.
|
|
136
|
+
- The simple profile of gross rates (`chargy-gross-rates/v1`) takes a flat fee without a step size, as a FLAT price
|
|
137
|
+
component has none ("A FLAT price component has no step size!"), and as WWCP_POI `c4c3c5a` takes it: it asked every
|
|
138
|
+
component for a step size of at least one, so that a price agreement of a flat fee was `unsupported`, never `bound`,
|
|
139
|
+
with no gross rates. A flat fee with a step size, also `null`, is none of the profile; energy and time need one of at
|
|
140
|
+
least one, as before. `grossRates` is a module of its own, not exported, tested apart.
|
|
141
|
+
- A change is read as WWCP_POI3 reads it and refused in the words of its refusal after "Change N: ", as WWCP_POI3
|
|
142
|
+
refuses it with the change proposed for it on top of `8b0580f` (`RoamingNetworkChange.Refusal`, shared by its
|
|
143
|
+
constructor and `TryParse`; without it WWCP_POI3 says "Invalid change 0: …", and where its constructor refuses, the
|
|
144
|
+
words of an `ArgumentException`, e.g. "Value must not be empty. (Parameter 'EntityId')"). Its texts: anything but a
|
|
145
|
+
text refused, also JSON null, "Change 0: the kind must be a text!", where this library said "The kind of change 0 must
|
|
146
|
+
be a text!", in the order WWCP_POI3 reads them, all before the element path; the kind trimmed, also when nothing is
|
|
147
|
+
left, "Change 0: unknown kind ''!"; a parent type or identification empty, "Change 0: its parent entity type and
|
|
148
|
+
identification must not be empty!", which this library refused only when applied, as not the parent; the property
|
|
149
|
+
name of a segment of an element path trimmed. The context of a change is checked, "Change 0: the JSON-LD context of
|
|
150
|
+
the roaming network change must be '…'!", also JSON null, where this library took any. A change set is identified by
|
|
151
|
+
its changes as WWCP_POI3 writes them again (`ToJSON(Embedded: true)`): without the context of a change or of a
|
|
152
|
+
segment, without an empty element path, the property name of a segment trimmed; this library identified it by them as
|
|
153
|
+
given, taking a change set WWCP_POI3 refuses as not identified by its content. Probed with 77 change sets with
|
|
154
|
+
changes refused when read and the 630 of the earlier probes: the same verdicts as WWCP_POI `8b0580f`, the same words
|
|
155
|
+
as with the proposed change, but of a change or a segment naming a property it does not have: WWCP_POI3 does not
|
|
156
|
+
refuse it when read, and then refuses the change set as not identified by its content, this library "Change 0 must
|
|
157
|
+
not name the property 'foo'!".
|
|
158
|
+
- A new value not given as the content holds it is refused as WWCP_POI3 refuses it (`TryHeldAsGiven`): after the party
|
|
159
|
+
the change changed is read again, not before, and naming what the content holds. "Change 0: the property 'name' of the
|
|
160
|
+
charging pool 'DE*GEF*P1' is not given as the content holds it, '{"en":"x"}'!" of an `UpdateProperty`; "Change 0: the
|
|
161
|
+
EVSE group 'DEGEFEG9' to add is not given as the content holds it, '{"@id":"DE*GEF*EG9",…}'!" of an `Add`, the
|
|
162
|
+
entity without its lastChange; "Change 0: 'chargingConnectors['1']' of the EVSE 'DE*GEF*E1*1' is not given as the
|
|
163
|
+
content holds it, '…'!" of an element change, its element or the property of its element; "… is given as '[]', which
|
|
164
|
+
the content does not hold at all!" of a value it holds none of. This library named where it was written otherwise and
|
|
165
|
+
why, "Change 0, the charging pool 'DE*GEF*P1': 'name' is not given as the content holds it: a text in languages names
|
|
166
|
+
each language as Styx writes it, in lower case, with a text!", the place of an element by its index, before reading
|
|
167
|
+
the party again: of an `Add` with an identification written otherwise and an invalid content, it named the
|
|
168
|
+
identification, WWCP_POI3 the content. `notWritten` tells what the content holds where it is written otherwise,
|
|
169
|
+
`heldAs` makes a new value so. Also held as WWCP_POI3 holds them, where this library took them as given: flags,
|
|
170
|
+
`currentTypes` and `chargingModes`, in the order of their values, each once (`POIJSON.FlagsToJSON`); data licenses
|
|
171
|
+
given empty, which the content leaves out, of every entity; a hotline, trimmed; a language given by its number, also
|
|
172
|
+
with a sign, by its name. A new value of a property is checked as a value too, a URL or a currency, as within an
|
|
173
|
+
object, where a version written otherwise refused it. Probed against WWCP_POI `8b0580f` with 88 change sets on the QA
|
|
174
|
+
network, one with connectors on an EVSE: the same verdict and words for each, but a change refused as WWCP_POI3's
|
|
175
|
+
constructor refuses it ("Invalid change 0: …"; refused so since, see above), and, as before, who must sign identity keys of the roaming network
|
|
176
|
+
operator given twice. The earlier probes: the same verdicts, now also the words of the
|
|
177
|
+
spellings probe's `Add` with an identification written otherwise and an invalid content.
|
|
178
|
+
- A change whose old value is no longer there is refused naming the value it found, as WWCP_POI3 names it
|
|
179
|
+
(`POIJSON.ContentText`): its canonical JSON, "absent" for none. "Change 0: the property 'name' of the charging pool
|
|
180
|
+
'DE*GEF*P1' is no longer the expected old value, but '{"en":"Jena Paradies"}'!", of every kind of entity, its
|
|
181
|
+
embedded objects and the roaming network operator; "…'chargingConnectors['3'].format' of the EVSE 'DE*GEF*E1*1' is no
|
|
182
|
+
longer the expected old value, but '"CABLE"'!" of an element change; "Change 0: the property 'name' is no longer the
|
|
183
|
+
expected old value, but '{"en":"Quality Assurance"}'!" of the roaming network itself, which is no entity named, as
|
|
184
|
+
WWCP_POI3 names it, where this library named it "the property 'name' of the roaming network 'QA'". A change of a
|
|
185
|
+
complete entity names, as before, only whether it exists. Probed against WWCP_POI `8b0580f` with 59 change sets on
|
|
186
|
+
the QA network, one with connectors on an EVSE, of every kind of entity, of properties there and absent, of an old
|
|
187
|
+
value expecting one absent, of the roaming network itself and of the second change of a change set: the same words
|
|
188
|
+
for each. The earlier probes: the same verdicts and words as before, now also the old values.
|
|
189
|
+
- What a change set changes is read again right after each change, as WWCP_POI3 reads it (`TryApplyRegistryChange`,
|
|
190
|
+
`TryApplyInfrastructureChange`, …): the party the change changed, a charging station operator for its
|
|
191
|
+
infrastructure, templates, groups, tariffs, offers, parking spaces and energy meter templates and groups, the party
|
|
192
|
+
embedding a model, a release, a certificate, a grid connection point or parking data, the roaming network operator.
|
|
193
|
+
A change making one a party WWCP_POI3 does not read is refused in its words, "Change 0: Invalid hotline phone number
|
|
194
|
+
'42'!", not after the last change without them; a change set making a party invalid and valid again is refused, as
|
|
195
|
+
WWCP_POI3 refuses it, where it was taken before; of two changes making a party invalid, the first is named, not what
|
|
196
|
+
is read first. The groups, offers and payment options of a charging station operator are still checked after the last
|
|
197
|
+
change, as WWCP_POI3 checks them there. The properties of the roaming network itself are taken as WWCP_POI3 takes
|
|
198
|
+
them: "Change 0: invalid name: A multi-language text must be a JSON object!", "the data source must be a nonempty
|
|
199
|
+
text!" (a blank one taken before), "the custom data must be a JSON object!", "a roaming network has no keys of its
|
|
200
|
+
own: they are the keys of its RoamingNetworkOperator!", "the property 'foo' does not exist!" for one it has not,
|
|
201
|
+
"Add of the roaming network itself is not supported yet!". Its operator: "the operator of a roaming network is
|
|
202
|
+
changed, but neither added nor removed!", "the roaming network operator 'XYZ' does not exist!", "a roaming network
|
|
203
|
+
operator of this roaming network belongs to RoamingNetwork 'QA', not to …". Probed against WWCP_POI `8b0580f` on the
|
|
204
|
+
QA network with 88 change sets, every kind of party and of what it embeds, invalid values, invalid values made valid
|
|
205
|
+
again, two of them in either order: the same verdict for each, the same words for each but two, which this library
|
|
206
|
+
words otherwise for every kind of entity, not as it reads them again: an old value no longer there, which WWCP_POI3
|
|
207
|
+
names, "…, but '{"en":"Quality Assurance"}'!" (named so since, see above), and a new value the content does not
|
|
208
|
+
hold (refused so since, see above). The 116 change sets of the
|
|
209
|
+
spellings probe: four more in WWCP_POI3's words, the rest as before. The reading again costs about 1 s of the 80-odd
|
|
210
|
+
seconds of the conformance tests.
|
|
211
|
+
- The web payment page of a charging station operator, a charging pool, a charging station and their templates, as
|
|
212
|
+
WWCP_POI `848cc52` has it (`webPaymentURL`): the URL where an EV driver pays ad hoc, without an e-mobility provider,
|
|
213
|
+
and starts a session, found in the static data before standing in front of a station; not the URL in the dynamic QR
|
|
214
|
+
code of a station, which is of one EVSE and never part of them. Read and written as WWCP_POI reads and writes it,
|
|
215
|
+
refused when no text or no URL ("Change 0: Invalid web payment URL '42'!"); taken by the members of a template
|
|
216
|
+
without their own (effective pools and stations); changed and removed by change sets. Whoever changes it redirects
|
|
217
|
+
payments: a change of it needs a signing key that may sign `payments`, and a pool, a station or a template added
|
|
218
|
+
with one, a pool by one of its stations as well, a key that may sign `infrastructure` and `payments`, "… that may
|
|
219
|
+
sign 'infrastructure' and 'payments'!". The usage of a change is now a set of usages a key names all of; the roaming
|
|
220
|
+
network operator still signs everything it owns by a key for `party`. Commits with a web payment page were refused
|
|
221
|
+
before. Probed against WWCP_POI `8b0580f` on the network of its `WebPaymentURLTests` and 23 change sets, unsigned and
|
|
222
|
+
signed by keys for `payments`, `infrastructure`, `party` and both: the same verdict and the same signers for each, the
|
|
223
|
+
same content after each of the 19 taken, the two invalid values in the same words since every change is read again.
|
|
224
|
+
- `examples/validate-examples.ts` checks example A15 as its `Validate()` does: the station proof of DE*GEF*E1*1 the app
|
|
225
|
+
gets, against the trust anchor of epoch 2, with the EV Taler merchant of DE*GEF; the EV Taler tariff of the EVSE and
|
|
226
|
+
the exchanges in its currency the app shows, those in another currency not offered there; the merchant base URL and
|
|
227
|
+
the merchant key every offer must name; and the proof refused once its merchant key is changed to the key of an
|
|
228
|
+
exchange, the root its attestations do not attest the one WWCP_POI names. What it prints is what the C# example
|
|
229
|
+
printed in the run `csharp-045e180`, line for line.
|
|
230
|
+
- A charging station, EVSE or energy meter given twice within one charging station operator is refused, as WWCP_POI
|
|
231
|
+
`e76e5d0` refuses it: "The charging station 'DE*GEF*S1' of the operator 'DE*GEF' must not be given twice!", the same
|
|
232
|
+
for an EVSE and an energy meter. Before, a station in two of its pools, or an EVSE in two of its stations, was taken,
|
|
233
|
+
by WWCP_POI3 too; proofs, price statements and evidence name them by their identifications alone. Three refusals of
|
|
234
|
+
`poi-refusals.json` of WWCPPOIConformanceTests `bfc8fa0` hold them, one of each, in the words both give.
|
|
235
|
+
- Data licenses that differ in case only are given twice (Hermod `f7b00ef2`): "OWN-1.0" and "own-1.0", "CC BY 4.0" and
|
|
236
|
+
"cc by 4.0".
|
|
237
|
+
- Refusals speak as WWCP_POI `74f1d8e` and Styx `21d00134` speak them: "An" before A, E, I and O, "A" before any other
|
|
238
|
+
letter ("A public key of …", "An EU vehicle category of …", "An ENERGY price component needs a positive step size!");
|
|
239
|
+
numbers without trailing zeros ("22000.5 W", not "22000.50 W"); "Invalid opening times: " once, not twice; "Besides
|
|
240
|
+
its grid operator, the grid connection point '…' can only be maintained by a charging station operator or a parking
|
|
241
|
+
operator, not by …!".
|
|
242
|
+
- The refusals of changes say their articles as WWCP_POI `8b0580f` says them: "the property 'maxPower' of an EVSE
|
|
243
|
+
group can not be changed!", "of an energy meter model", "of an EVSE template", not "of a EVSE group". A group, a
|
|
244
|
+
template, a tariff or a charging pool added below another parent than its charging station operator is refused in
|
|
245
|
+
WWCP_POI's words: "Change 0: an EVSE group 'DE*GEF*EG9' belongs to ChargingStationOperator 'DE*GEF', not to
|
|
246
|
+
ChargingPool 'DE*GEF*P1'!", not "the EVSE group … is added to its charging station operator 'DE*GEF', …". Probed
|
|
247
|
+
against WWCP_POI `8b0580f` on 29 change sets of every kind of entity: 27 in the same verdict and words. WWCP_POI
|
|
248
|
+
refuses one change when it reads the change set, in other words, and takes the parent 'de*gef' for 'DE*GEF' (see
|
|
249
|
+
below).
|
|
250
|
+
- A change names the infrastructure of a charging station operator in every spelling its identification type considers
|
|
251
|
+
equal, as WWCP_POI3 finds it (`StoredId`): `DEGEFP1`, `DEGEF*P1` or `degefP1` for the charging pool `DE*GEF*P1`,
|
|
252
|
+
`DE*GEF*E11` for the EVSE `DE*GEF*E1*1`, `de*gef` for its operator, as the entity, as its parent and as the parent it
|
|
253
|
+
is added to. The operator is the one its identification names, as its type reads it, and signs the change, whether it
|
|
254
|
+
exists or not ("… needs a signature by a signing key of the ChargingStationOperator 'DE*XXX'!"). Before, only the very
|
|
255
|
+
text it is kept with was found, and other spellings were refused. Refused in WWCP_POI3's words: "invalid charging pool
|
|
256
|
+
identification 'de*gef*p1'!", "the charging station operator 'DE*XXX' of the charging pool 'DE*XXX*P1' does not
|
|
257
|
+
exist!", "adding the charging station '…' needs its ChargingPool as its parent!", "the charging pool '…' of the
|
|
258
|
+
charging station '…' does not exist!", and an entity added under an identification its type writes otherwise, "the EVSE
|
|
259
|
+
group 'DEGEFEG9' to add is not given as the content holds it, '{"@id":"DE*GEF*EG9",…}'!".
|
|
260
|
+
- The kind, the entity type and the entity identification of a change are read trimmed, as WWCP_POI3 reads them
|
|
261
|
+
(`ParseMandatoryText`), and the identification of a change set is of its content so read: a change set naming
|
|
262
|
+
`' DE*GEF*P1'` is identified as one naming `'DE*GEF*P1'`, and refused, "is not identified by its content", when
|
|
263
|
+
identified by the text untrimmed.
|
|
264
|
+
- Probed against WWCP_POI `8b0580f` on 190 change sets, as `TryApplyPendingChangeSet` reads and applies them and
|
|
265
|
+
`TryCheckCoSigning` names their owners: the same verdict for each, the same content after each of the 94 taken (after
|
|
266
|
+
ETags of `CreateChangeSet`), the same words but for seven. Four have two faults at once, refused in another order (an
|
|
267
|
+
EVSE removed whose station then exceeds its maximum power and whose group names it; a tariff without elements added
|
|
268
|
+
under another spelling); a tariff without elements is refused without "Change 0: ", as this library reads the
|
|
269
|
+
operator once after all changes; and WWCP_POI refuses an empty identification and a parent type without its
|
|
270
|
+
identification when it reads a change set, as "Invalid change 0: …" (refused so since, see above). Who must sign a change of a party without
|
|
271
|
+
signing keys was named otherwise in four of them (see below).
|
|
272
|
+
- A change of a party without signing keys, which the roaming network operator signs in its place (`SignerOf`), is
|
|
273
|
+
refused unsigned as WWCP_POI3 refuses it (`TryCheckCoSigning`): naming the roaming network operator, by as many
|
|
274
|
+
holders as its quorum needs, not the party, which has no key to sign with, e.g. "… needs signatures by signing keys of
|
|
275
|
+
2 holders of the roaming network operator 'OCC'!"; signed by a key of it that may sign neither the usage of the
|
|
276
|
+
change nor `party`, with both, "… needs a signature by a signing key of the roaming network operator 'DE*RNO' that
|
|
277
|
+
may sign 'certificates' or 'party'!". Of several owners, e.g. of a grid connection point, the roaming network
|
|
278
|
+
operator is named with its quorum too, its identity keys as well, once each, and "signatures" where one owner needs
|
|
279
|
+
more than one holder. Probed against WWCP_POI `8b0580f`: the 190 change sets above and 11 more name who must sign
|
|
280
|
+
them alike, word for word.
|
|
281
|
+
- The key statement of the roaming network operator is refused as its constructor in WWCP_POI3 refuses it: an identity
|
|
282
|
+
key given twice ("An identity key of a key statement must not be given twice!") before the order of its identity keys
|
|
283
|
+
is looked at, and a signature by one identity key given twice ("An identity key signs a key statement once."), which
|
|
284
|
+
was taken before; its validity in C#'s words. Probed against WWCP_POI `74f1d8e` on 36 versions of QA, the same
|
|
285
|
+
verdict and words for each. Four vectors of `poi-refusals.json` follow the new words.
|
|
286
|
+
|
|
287
|
+
### Migration
|
|
288
|
+
|
|
289
|
+
- A charging pool naming the payment option `EVTaler`, its own or of a template, whose operator has an EV Taler
|
|
290
|
+
merchant, names the authentication mode `SecureDynamicQRCode` with at least one of the channels `BLE`, `Display` and
|
|
291
|
+
`NFC`: a version or change set without it, which 0.3.0 took, is refused. No other authentication mode names channels.
|
|
292
|
+
- A change set is identified, and its signatures are verified, over it as WWCP_POI3 writes it again, and so is its
|
|
293
|
+
commit: one identified over what it was given as, with an untrimmed text, a context or another property in a
|
|
294
|
+
precondition, an empty `preconditions`, `metadata` or element path, a description in languages written otherwise,
|
|
295
|
+
which 0.3.0 took, is refused, "is not identified by its content"; one identified as WWCP_POI3 writes it, which 0.3.0
|
|
296
|
+
refused, is taken. Producers identify and sign change sets and commits as WWCP_POI3 does.
|
|
297
|
+
- A change set is refused where a change makes a party one WWCP_POI3 does not read, also when a later change makes it
|
|
298
|
+
valid again, which 0.3.0 took; the change is named, "Change N: …", in the words of WWCP_POI3. A change naming a
|
|
299
|
+
JSON-LD context other than its own, a description or metadata that is no JSON object, or a new value the content does
|
|
300
|
+
not hold as given is refused as WWCP_POI3 refuses it.
|
|
301
|
+
- Messages of refusals checked by their text change where 0.3.0 worded them on its own: a change refused when read
|
|
302
|
+
("Change 0: the kind must be a text!"), an old value no longer there, which now names the value found, a new value
|
|
303
|
+
not given as the content holds it, who must sign a change of a party without signing keys, the articles of entities
|
|
304
|
+
("An EVSE group", "of an energy meter model") and numbers without trailing zeros.
|
|
305
|
+
- A charging station, an EVSE or an energy meter given twice within one charging station operator, and data licenses
|
|
306
|
+
that differ in case only, which 0.3.0 took, are refused. So is a key statement of the roaming network operator with
|
|
307
|
+
two signatures by one identity key.
|
|
308
|
+
- A change names the infrastructure of a charging station operator in every spelling its identification type considers
|
|
309
|
+
equal, `DEGEFP1` for `DE*GEF*P1`: change sets 0.3.0 refused for another spelling are taken, and an entity added under
|
|
310
|
+
an identification its type writes otherwise is refused.
|
|
311
|
+
- Versions and commits with a web payment page (`webPaymentURL`) or an offers URL of an EV Taler merchant (`offersURL`),
|
|
312
|
+
which 0.3.0 refused, are taken. A change of a web payment page needs a signing key that may sign `payments`, and an
|
|
313
|
+
entity added with one a key that may sign `infrastructure` and `payments`.
|
|
314
|
+
- A price agreement of a flat fee, which 0.3.0 gave as `unsupported`, is `bound` of the simple profile of gross rates
|
|
315
|
+
where its FLAT component has no step size; one with a step size, also `null`, is none of the profile. A price
|
|
316
|
+
agreement whose `chargingMode` is `contract` is `bound` of the new profile `chargy-contract-gross-rates/v1`
|
|
317
|
+
(`CONTRACT_GROSS_PRICE_PROFILE`), and stays `unsupported` of the simple profile.
|
|
318
|
+
- New in the API, nothing removed: `evTalerSessionPrices` and its type `EVTalerSessionPrices`, the `offersURL` of an
|
|
319
|
+
EV Taler merchant, `CONTRACT_GROSS_PRICE_PROFILE`.
|
|
320
|
+
- The dependencies are those of 0.3.0, `@vanaheimr/cose` ^0.15.0 and `@vanaheimr/metrological-cbor` ^0.12.0. The
|
|
321
|
+
minimum runtime remains Node 22.18, and the package remains ESM-only. The package is 3.9 MB unpacked, where 0.3.0
|
|
322
|
+
was 3.7 MB.
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
## 0.3.0 (2026-11-08)
|
|
326
|
+
|
|
327
|
+
WWCP_POI3 as the measure: a roaming network is read as WWCP_POI3 reads it and refused in its words, change sets apply
|
|
328
|
+
what WWCP_POI3 applies (the entities a party embeds, element changes, preconditions, no lastChange going back),
|
|
329
|
+
histories require the signature roles WWCP_POI requires and take a checkpoint with the signatures that verify, and EV
|
|
330
|
+
Taler phase 2 checks the steps and the settlement of a session. Each of them is probed against WWCP_POI3, what differs
|
|
331
|
+
named below, and the vectors of WWCPPOIConformanceTests `215023a` hold, none deviating. See [Migration](#migration)
|
|
332
|
+
before upgrading: versions, change sets and signatures 0.2.0 took are refused, and the types of three properties change.
|
|
333
|
+
|
|
334
|
+
- A roaming network is read as WWCP_POI3 reads it (`RoamingNetwork.TryParse` and the TryParse of every entity) and
|
|
335
|
+
refused in its words and its order: JSON types, mandatory properties, values, identifications, names of enumerations,
|
|
336
|
+
currencies, URLs, timestamps, texts in languages, data licenses, and what the constructor of each entity refuses of
|
|
337
|
+
what it read (`src/network/reading.ts`, `poiJSON.ts`, `poiValues.ts`). Every kind of entity it reads: the roaming
|
|
338
|
+
network and its operator; charging station operators with their pools, stations, EVSEs, connectors, energy meters,
|
|
339
|
+
templates, groups, tariffs, tariff templates, groups and offers, brands and parking spaces; manufacturers of charging
|
|
340
|
+
stations and energy meters with their models, transparency software manufacturers with their releases, conformity
|
|
341
|
+
assessment bodies, e-mobility providers, grid operators with their grid connection points, parking operators.
|
|
342
|
+
- The references the constructor of the roaming network checks, and the identifications it keeps unique among them,
|
|
343
|
+
interleaved in its order (`references.ts`): manufacturers, models, hardware revisions and firmware versions, releases,
|
|
344
|
+
certificates, grid connection points, charging stations, parking spaces and maintainers the network does not have, a
|
|
345
|
+
station or an energy meter contradicting its model, a key of two parties. After the last change of a change set, bare,
|
|
346
|
+
in the order of `RoamingNetwork.ChangeSets.cs`, a reference the version before resolves named as one the change set
|
|
347
|
+
withdrew. They replace the separate checks of identifications, versions, certificates, EV Taler and keys of parties.
|
|
348
|
+
- 1268 versions probed against WWCP_POI3 at 89d2e02 are taken and refused alike, in the same words, but for nine agreed:
|
|
349
|
+
five identifications of the roaming network and its operator given as numbers, which keep the words of this library
|
|
350
|
+
for WWCP_POI3 to take, and four messages of the CBOR and COSE libraries.
|
|
351
|
+
- Values WWCP_POI3 writes otherwise than given are refused in the words of its written form (`writtenForm.ts`): a
|
|
352
|
+
number, a boolean or a text given as another JSON type it reads it of (`"0.390"` as 0.390, `"TRUE"` as true, 5 as
|
|
353
|
+
`"5"`), coordinates of texts and booleans, durations in seconds in whole ticks of 100 ns without trailing zeros (1.50
|
|
354
|
+
as 1.5), the width and height of an image; opening times as Styx writes them, `24/7` always, hours `HH:mm`, periods
|
|
355
|
+
UTC, empty lists and free texts left out; NUTS codes in upper case, a list written otherwise compared element by
|
|
356
|
+
element with the one WWCP_POI3 writes; addresses with their countries by their alpha-3 codes, their street, postal
|
|
357
|
+
code and time zone trimmed, their other texts as given and left out where empty, their languages in lower case,
|
|
358
|
+
nothing else. A country is read as `Country.TryParse` of Styx reads it, of its 251 countries (`countries.ts`): by its
|
|
359
|
+
alpha-2 or alpha-3 code in any case, its numeric code, its calling code or one of its names, and refused where it
|
|
360
|
+
names none. Of 164 more versions probed against WWCP_POI3 at 89d2e02, 163 are taken and refused alike, in the same
|
|
361
|
+
words; the one left gives a number with an exponent, which the probe writes otherwise before WWCP_POI3 reads it.
|
|
362
|
+
- Two charging tariff offers of an operator must not overlap (`offers.ts`, `OverlappingOffers` of WWCP_POI3, SPECIFICATION.md
|
|
363
|
+
9.4): covering one EVSE, for some of the same sessions (ad hoc, or contracts of a provider both name, or one names
|
|
364
|
+
none), at some of the same times within their `notBefore` and `notAfter`, both inclusive, and their opening times in the
|
|
365
|
+
time zone of the EVSE's charging pool, with what its templates give it, else UTC; local times as `TimeZoneInfo`
|
|
366
|
+
converts them, one a change to daylight saving time skips the first after it, one it gives twice the one of standard
|
|
367
|
+
time; exceptional closings
|
|
368
|
+
close, exceptional openings open. Refused in its words, at the first EVSE in the ordinal order, as the constructor of
|
|
369
|
+
the operator refuses it, also after a change set. After a change set also two offers of an e-mobility provider the
|
|
370
|
+
change set changed that overlap and did not in the version before (`NewProviderOfferOverlap`); by the changes of
|
|
371
|
+
others they may. Of 64 versions probed against WWCP_POI3 at d1c41ca, all are taken and refused alike, in the same
|
|
372
|
+
words, also those of time zones a charging pool may not name.
|
|
373
|
+
- The time zone of a charging pool or a charging pool template is one of a region of the IANA time zone database, as
|
|
374
|
+
the database writes it, which this platform knows (`timeZones.ts`, `POITimeZones` of WWCP_POI3 `d1c41ca`,
|
|
375
|
+
SPECIFICATION.md 9.4, D17 of the conformance tests): `Europe/Berlin`, also an older name the database keeps for one,
|
|
376
|
+
`Asia/Kolkata` as `Asia/Calcutta`, or of a part of a region, `America/Argentina/Buenos_Aires`. No name of another
|
|
377
|
+
system (`W. Europe Standard Time`), none without a region (`CET`, `UTC`, `Etc/GMT-1`, `US/Eastern`), none in another
|
|
378
|
+
case (`europe/berlin`), none the platform does not know: refused in the words of WWCP_POI3 as the constructor of the
|
|
379
|
+
pool or template refuses it, trimmed, after its images, no longer taken as UTC, nor a Windows name as its IANA name.
|
|
380
|
+
The case is the one Temporal gives (Node 26); without Temporal (Node 22 and 24) Intl gives it of a name, but of an
|
|
381
|
+
older name only the name it stands for, so an older name is then taken in any case (`Asia/KOLKATA`). Of 92 versions
|
|
382
|
+
probed against WWCP_POI3 at `d1c41ca`, 90 are taken and refused alike, in the same words; the two left name
|
|
383
|
+
`America/Ciudad_Juarez` and `Antarctica/Troll`, which .NET on Windows does not find, and this library takes, as Node
|
|
384
|
+
knows them: databases of different age know different names (SPECIFICATION.md 9.4). `poi-refusals.json` of
|
|
385
|
+
WWCPPOIConformanceTests vendored again without the marker of D17: its 10 time zones are refused by their reasons.
|
|
386
|
+
- A measurement public key is a key as BouncyCastle 2.7.0 makes one, as WWCP_POI3 checks it (`measurementPublicKey.ts`,
|
|
387
|
+
`MeasurementPublicKey.TryCheck`), refused in its words and those of BouncyCastle: a SubjectPublicKeyInfo of DER
|
|
388
|
+
(`ber.ts`), of RSA, also of PSS and OAEP, its modulus odd, of no prime factor up to 743, of 16384 bits at most and no
|
|
389
|
+
prime, its exponent odd (`rsa.ts`); of EC on the 84 named curves BouncyCastle knows (`curves.ts`, taken from it), a point
|
|
390
|
+
it decodes, compressed, uncompressed or hybrid, on its curve and of its order (`ecc.ts`); of Ed25519 and Ed448 a point
|
|
391
|
+
of no small order; of X25519, X448, ML-DSA, ML-KEM and SLH-DSA of their lengths; of DSA in its group. Its certificates
|
|
392
|
+
DER, as X509CertificateParser reads them, the first of the key, each one issued by the next one, its signature of
|
|
393
|
+
ECDSA, DSA, RSA of PKCS #1 v1.5 or PSS, Ed25519, Ed448 or ML-DSA verified with the key of the next one
|
|
394
|
+
(`certificates.ts`). Of 242 keys and chains of BouncyCastle and variants of them probed against WWCP_POI3 at 89d2e02,
|
|
395
|
+
237 are taken and refused alike, in the same words; taken as given, where WWCP_POI3 checks them: points on curves over
|
|
396
|
+
binary fields, explicit curve parameters, keys of Diffie-Hellman, ElGamal, GOST and DSTU. Not verified, so refused: a
|
|
397
|
+
certificate signed with GOST, SM2 or SLH-DSA.
|
|
398
|
+
- Other words: decimals in messages invariant and line breaks `\n`, where WWCP_POI3 writes them in the culture of its
|
|
399
|
+
machine and `\r\n`; timestamps `DateTimeOffset` reads and the written form refuses, refused as invalid; an error of an
|
|
400
|
+
entity changed by a change set without the `Change N:` of WWCP_POI3.
|
|
401
|
+
- A price statement reads its price status as WWCP_POI3 reads it (`ChargingPrices.TryParse`), in its words and order,
|
|
402
|
+
under its "Invalid price status of the price statement:": the prices of each charging tariff once, the tariff named
|
|
403
|
+
by its identification `{operatorId}*T{suffix}` (SPECIFICATION.md 2, 12.1, D16 of the conformance tests), their
|
|
404
|
+
elements, at least one, as a tariff has them, no property or JSON-LD context besides. A statement naming another text
|
|
405
|
+
is no price statement: the price evidence of a session holding one has invalid signatures, as WWCP_POI3 gives it
|
|
406
|
+
(`sessionPrice-foreign-tariff`), not valid ones of a tariff outside the references of its EVSE.
|
|
407
|
+
- The nine vectors of WWCPPOIConformanceTests `fde40c9` vendored, `poi-refusals.json` of 129 vectors (a version naming a
|
|
408
|
+
charging tariff not as `{operatorId}*T{suffix}`), and `poi-verifier.json`, new here: 106 checks of the verifier
|
|
409
|
+
extensions, meter keys, historical meter evidence, session prices, trust transitions, keys of charging documents,
|
|
410
|
+
trust policy identifications, digests of key statements, offer hashes and publication receipts, against the POI
|
|
411
|
+
fixtures of ChargyWebApp at `fc513cd`, vendored as `tests/vectors/chargy-fc513cd`. Run in `tests/conformance.test.ts`
|
|
412
|
+
as WWCPPOIConformanceTests runs them against this library: a refusal after its control, by its reason; none deviates.
|
|
413
|
+
- `poi-refusals.json` of WWCPPOIConformanceTests `7d43d4b` vendored (`586a339` before a rebase there), of 142 vectors:
|
|
414
|
+
13 price statements whose price status is none WWCP_POI3 reads (without one; its prices not an array; the prices of a
|
|
415
|
+
tariff not an object; a property or a JSON-LD context besides, of the status or of the prices of a tariff; a tariff
|
|
416
|
+
not named `{operatorId}*T{suffix}` or named twice, also in another spelling; its elements empty, one not an object or
|
|
417
|
+
without price components), refused as both read them, in the words both give. None deviates.
|
|
418
|
+
- `poi-refusals.json` of WWCPPOIConformanceTests `ed91741` vendored, of 273 vectors: 131 versions built from the tests
|
|
419
|
+
of this library and read as WWCP_POI3 reads them, 59 of reading, 18 of references, 33 of written forms, 11 of offers,
|
|
420
|
+
10 of measurement public keys, refused in the words both give. None deviates. Two of them, offers of `Europe/Berlin`,
|
|
421
|
+
WWCP_POI3 takes where .NET runs without ICU, as it then finds no IANA time zone and compares them in UTC (O5 there).
|
|
422
|
+
- `@vanaheimr/cose` 0.14.0, the codec still `@vanaheimr/metrological-cbor` 0.12: a key of a party of key type RSA (3) is
|
|
423
|
+
read as Styx reads it, identified by its RFC 9679 thumbprint over n and e, and taken as WWCP_POI3 takes it; 0.12.0
|
|
424
|
+
refused it, "Invalid COSE key: The curve of a COSE key must be an integer!". POI names no signature algorithm of RSA
|
|
425
|
+
(SPECIFICATION.md 4), so such a key signs nothing this library verifies, as before.
|
|
426
|
+
- `@vanaheimr/cose` 0.15.0, the codec still `@vanaheimr/metrological-cbor` 0.12. It reads and verifies the
|
|
427
|
+
countersignature of RFC 8152 and holds a key an X.509 certificate writes as `id-RSASSA-PSS` to RSASSA-PSS, as Styx
|
|
428
|
+
`7642de3d` does. This library uses neither, and reads and verifies its keys and signatures as with 0.14.0. For
|
|
429
|
+
development, Playwright 1.65.0 and Vite 8.3.6. TypeScript stays at 6.0: typescript-eslint 8.72.1 requires a version
|
|
430
|
+
below 6.1, and its typed linting needs the compiler API that TypeScript 7 does not ship.
|
|
431
|
+
- `poi-refusals.json` of WWCPPOIConformanceTests `d388929` vendored, of 283 vectors: 10 versions naming a time zone of a
|
|
432
|
+
charging pool or a charging pool template that is none of a region of the IANA time zone database, refused by WWCP_POI3
|
|
433
|
+
since `d1c41ca` and taken by this library, marked as its deviation (D17 there).
|
|
434
|
+
- A change set changes the entities a party embeds, as WWCP_POI3 applies them (`apply.ts`; RoamingNetwork.OfferChanges.cs,
|
|
435
|
+
ProviderChanges.cs, GridChanges.cs and ParkingChanges.cs): the charging tariff offers of charging station operators
|
|
436
|
+
and e-mobility providers, the EVSE, charging station and charging pool groups of e-mobility providers, the grid
|
|
437
|
+
connection points of grid operators, the parking garages, spaces, sensors, space templates, space groups and products
|
|
438
|
+
of parking operators and the parking spaces of charging station operators. Added to the party an `Add` names as its
|
|
439
|
+
parent, found by its identification as its type compares it, e.g. a parking product with case, the properties a change
|
|
440
|
+
set may change, in the words of WWCP_POI3; with their timestamps, but a grid connection point and a parking product,
|
|
441
|
+
which have none. Owned by the party embedding them (4.1), the offers by keys that may sign `tariffs`, the others
|
|
442
|
+
`infrastructure`; a grid connection point by its maintainer, its maintainer changed by it, its grid operator or the
|
|
443
|
+
identity keys of the roaming network operator; also after the earlier changes of the change set, which may add or
|
|
444
|
+
remove them or their party. 0.2.0 refused them as not supported. Of 107 change sets probed against WWCP_POI3 at
|
|
445
|
+
`d1c41ca` (`CreateChangeSet`), the 50 it takes lead to the same content here, and the 57 it refuses are refused here
|
|
446
|
+
too, 34 in the same words; the others in the words of the entity read again without `Change N:`, of the change as
|
|
447
|
+
WWCP_POI3 parses it, or of the written form, where WWCP_POI3 names a property of infrastructure a change set may not
|
|
448
|
+
change.
|
|
449
|
+
- The `effectiveLastChanges` of a snapshot are read as WWCP_POI3 reads them (`TryTakeEffectiveFloors`,
|
|
450
|
+
POIEffectiveLastChange): absent or `null`, or an array of `{entityType, entityId, lastChange}`, a JSON-LD context only
|
|
451
|
+
its own, the timestamp in a form `DateTimeOffset` reads; refused otherwise in its words, "The effective last changes of
|
|
452
|
+
a snapshot must be a JSON array!", "Invalid effective last change '{…}' of a snapshot!". 0.2.0 took any. They are the
|
|
453
|
+
floors of the `lastChange` of effective members POI_API keeps at runtime (SPECIFICATION.md 8.8, point 3), found again
|
|
454
|
+
for what a change set changes; the effective tree takes the `lastChange` of an effective member without them (8.1),
|
|
455
|
+
as WWCP_POI3 does (`EffectiveChargingPoolsOfTheContent`), so this library reads them and keeps none.
|
|
456
|
+
- The preconditions of a change set hold, as WWCP_POI3 checks them (`preconditions.ts`; RoamingNetwork.Preconditions.cs,
|
|
457
|
+
SPECIFICATION.md 4): each names the ETag an entity still has in the version the change set is applied to, after its
|
|
458
|
+
`beforeETags` and before its changes, over the entity as the roaming network embeds it, with everything it embeds, its
|
|
459
|
+
canonical JSON or its deterministic CBOR, in the hash algorithm it names. The entity is found by its type and
|
|
460
|
+
identification as its type compares it, e.g. `DEGEFP1` as `DE*GEF*P1`, among the entities a change set addresses on
|
|
461
|
+
their own (`Flatten`), not a model, which is unique within its manufacturer only, as in WWCP_POI3. Refused otherwise in
|
|
462
|
+
its words, "The change set does not fit this version of the roaming network: Precondition 0: the ChargingPool
|
|
463
|
+
'DE*GEF*P1' changed, it no longer has the ETag json:sha256:hex:…!", and a precondition not read as it reads one in a
|
|
464
|
+
change set, "Invalid precondition 1!". 0.2.0 refused change sets with preconditions as not supported. Of 79 change sets
|
|
465
|
+
with preconditions probed against WWCP_POI3 at `d1c41ca`, ETags of 40 entities of every kind among them, all are taken
|
|
466
|
+
and refused alike, 70 in the same words, the others refused when read, where the probe reads a precondition on its own.
|
|
467
|
+
- A change set changes elements, as WWCP_POI3 applies them (`elements.ts`, `apply.ts`; POIElements.cs and
|
|
468
|
+
RoamingNetwork.ElementChanges.cs): `AddElement`, `RemoveElement`, `ReplaceElement`, `UpdateElementProperty` and
|
|
469
|
+
`RemoveElementProperty` address an element of a property of an entity by their element path, e.g.
|
|
470
|
+
`chargingConnectors['1'].format`, an element of an array by its identification, as the type of the identifications of
|
|
471
|
+
the property compares them, e.g. `EVSEIds` without case, any other ordinally; an added element where the ordinal order
|
|
472
|
+
puts it, in `templateIds` at the end; an array left without elements removed. Each amounts to the `UpdateProperty` or
|
|
473
|
+
`RemoveProperty` of the property its path starts with, checked and owned as that change (4.1), its old value compared
|
|
474
|
+
with the element, or the property of the element, it addresses; keys and tree hash algorithms are changed as a whole
|
|
475
|
+
only. Element changes WWCP_POI3 does not make are refused when the change set is read: an element change without an
|
|
476
|
+
element path, another change with one, a new value of JSON `null`, of each kind of change what it does not take, e.g.
|
|
477
|
+
an `AddElement` with an old value, a segment of a path without a property name or with an empty identification.
|
|
478
|
+
0.2.0 refused element changes as not supported. The properties of charging pools, stations, EVSEs, tariffs, groups and
|
|
479
|
+
templates a change set may change are those of WWCP_POI3 (RoamingNetwork.InfrastructureChanges.cs), refused otherwise
|
|
480
|
+
in its words, e.g. "the property 'chargingStations' of a charging pool can not be changed!", and an infrastructure
|
|
481
|
+
entity is named as WWCP_POI3 names it, e.g. "the charging tariff 'DE*GEF*T_AC'". Of 108 element changes probed against
|
|
482
|
+
WWCP_POI3 at `d1c41ca` (`CreateChangeSet`), the 47 it takes lead to the same content here, and the 61 it refuses are
|
|
483
|
+
refused here too, 31 in the same words; the others in the words of the entity read again without `Change N:`, of an
|
|
484
|
+
old value without the value found, or of a change as this library reads it. Of the 107 change sets of embedded
|
|
485
|
+
entities probed before, 93 are now in the same words.
|
|
486
|
+
- The elements of the prices of a charging tariff in a price statement are written as a charging tariff holds them
|
|
487
|
+
(SPECIFICATION.md 12.1, WWCP_POI3 `5a72313`, D18 of the conformance tests), as a version holds the elements of a tariff:
|
|
488
|
+
an element, a price component or restrictions naming a property their type does not define, a number given as a text,
|
|
489
|
+
the days of the week out of their order, the JSON-LD context of an embedded object are refused before the signature,
|
|
490
|
+
"'elements[0].restrictions.maxStateOfCharge' of the prices of the charging tariff 'DE*GEF*T_DC' is not written as a
|
|
491
|
+
charging tariff holds it: the content leaves it out!" under "Invalid price status of the price statement: ". A reader
|
|
492
|
+
not knowing a restriction would else price a session where its signer did not. The written form knows the
|
|
493
|
+
restrictions of an element now (`startTime` to `reservation`, as ChargingTariffRestrictions writes them): a version
|
|
494
|
+
naming another one, e.g. `maxStateOfCharge`, is refused, which 0.2.0 took. The price evidence of a session whose
|
|
495
|
+
statement names a restriction of OCPI, e.g. `max_kwh`, has invalid signatures now (`sessionPrice-conditional-price`).
|
|
496
|
+
`poi-refusals.json` and `poi-verifier.json` of WWCPPOIConformanceTests `c540c7f` vendored, 290 vectors, 7 of them new;
|
|
497
|
+
none deviates.
|
|
498
|
+
- `poi-histories.json` of WWCPPOIConformanceTests `bc4e5a0` vendored: the 13 replays this library left to WWCP_POI3
|
|
499
|
+
(`notApplicable`) hold here as well and are replayed: the references a version holds, e.g. `station-*`, `meter-*`,
|
|
500
|
+
`withdrawn-while-named-*`, checked since `813e1d7`, and the changes of the groups of a provider and of grid connection
|
|
501
|
+
points, applied since `1946013`, each refused in the words of its reason. `tests/conformance.test.ts` 760.
|
|
502
|
+
- `poi-histories.json` of WWCPPOIConformanceTests `70deea0` vendored: 14 replays of the entities a party embeds, as
|
|
503
|
+
`1946013` applies them, in `history-parties`: offers of an operator, signed for `tariffs`, not overlapping; an offer
|
|
504
|
+
and groups of a provider, signed by the provider, not by the operator of the same prefix; a grid connection point
|
|
505
|
+
handed on and named in one change set, by its new maintainer (csharp-review 9); parking data of a parking operator
|
|
506
|
+
and the parking space of a charging station operator, each signed by its own party. `tests/conformance.test.ts` 774.
|
|
507
|
+
- `poi-verifier.json` of WWCPPOIConformanceTests `aef4b38` vendored, with the price evidence of sessions it makes itself
|
|
508
|
+
(`tests/vectors/chargy/POIPrices`): the cases of `POIPrices` of ChargyWebApp `fc513cd`, every signature
|
|
509
|
+
deterministic. 23 `sessionPrice-*` vectors check the same as before on them; `-foreign-tariff` and
|
|
510
|
+
`-conditional-price` stay on the fixtures. Two new ones are taken: `-tariff-of-another-evse`, a genuine price of a
|
|
511
|
+
tariff of the pattern `{operatorId}*T{suffix}` the EVSE does not name, of which none applies, and
|
|
512
|
+
`-conditional-element`, an element restricted by `maxEnergy`, whose price is selected without a rate.
|
|
513
|
+
`tests/conformance.test.ts` 776.
|
|
514
|
+
- Transparency software releases and certificates are identified under their owners, as WWCP_POI3 `045e180` checks it
|
|
515
|
+
(SPECIFICATION.md 4.1, POI3-ISSUES.md S36, `ForeignTransparencySoftware`, `ForeignConformityCertificate`,
|
|
516
|
+
`IsIdentifiedUnder`): the `@id` of a release is the `@id` of its manufacturer, a colon and a name without one
|
|
517
|
+
(`GraphDefined:chargy-1.5.0`), of a certificate the `@id` of the body issuing it alike (`PTB:2026-0042`), the prefix
|
|
518
|
+
compared without case, both trimmed as read. A version holding one identified otherwise is refused before releases or
|
|
519
|
+
certificates given twice, in its words: "The transparency software release 'chargy-1.5.0' of the manufacturer
|
|
520
|
+
'GraphDefined' is not identified as one of it: by 'GraphDefined:' and a name without a colon!"; so is a change set
|
|
521
|
+
leading to one, after the unknown parking spaces and before the releases given twice. References name them as before.
|
|
522
|
+
Of 38 versions and change sets probed against WWCP_POI3 at `045e180`, all are taken and refused alike, in the same
|
|
523
|
+
words. `tests/releaseIdentifications.test.ts`.
|
|
524
|
+
- The test vectors of a new run of the C# examples, `tests/vectors/csharp-045e180` in place of `csharp-33447ac`: WWCP_POI
|
|
525
|
+
`045e180`, examples A1 to A15, MakeProofs at `2026-11-05T19:46:00.000Z` (`tests/at.ts`). Releases and certificates
|
|
526
|
+
under their owners (`GraphDefined:chargy-1.5.0`, `PTB:2026-0017`, `PTB:2026-0042`); example A15 names the EV Taler
|
|
527
|
+
merchant of DE*GEF, so the head of epoch 2 is revision 11, while `QA.json` stays revision 8, as example A14 left it.
|
|
528
|
+
With them `poi-history.json` (100 vectors), `poi-refusals.json` (296, 6 of them of S36), `poi-histories.json` (75
|
|
529
|
+
replays, 8 of them of S36, the histories naming releases and certificates under their owners) and `poi-qidigital.json`
|
|
530
|
+
of WWCPPOIConformanceTests `2d0780f`. The tests on QA hold the values of the new run; those WWCP_POI3 calculated of
|
|
531
|
+
changed versions (element and embedded changes, preconditions, EV Taler) are calculated again by WWCP_POI3 at
|
|
532
|
+
`045e180`, and this library takes the very same versions. `tests/conformance.test.ts` 794.
|
|
533
|
+
- Required signature roles, as WWCP_POI `12e993a` checks them (POI3-ISSUES.md S24): `requiredSignatureRoles` of a history,
|
|
534
|
+
the roles a commit must be signed in, refused before it is applied where it has no signature in one ("The commit '…'
|
|
535
|
+
is not signed in the role '…'!"), and once its signatures are verified where none of them is by a key the version it
|
|
536
|
+
leads to lets sign in that role ("… by a key that may sign in it!", `keyMaySignIn`): in the role of the roaming
|
|
537
|
+
network operator a signing key certified for it, in the role of a charging station operator a signing key of the
|
|
538
|
+
operator its signer names; leaders and witnesses are the verifier's. So also the commit of a snapshot.
|
|
539
|
+
`requiredCheckpointSignatureRoles`, the roles a checkpoint must be signed in ("The checkpoint '…' is not signed in the
|
|
540
|
+
role '…'!"). A signed commit without a verifier is refused before it is applied, as WWCP_POI does. Signatures of one
|
|
541
|
+
key in one role, e.g. the twin of an ECDSA signature (S11), are kept as given, each verified, and counted once by the
|
|
542
|
+
holder or witness they are of, as WWCP_POI `f7b8643` reads them too (SPECIFICATION.md 5.4): it kept the first alone
|
|
543
|
+
since `12e993a`, so a forged signature behind a genuine one of its key went unchecked. `tests/signatureRoles.test.ts`.
|
|
544
|
+
- A checkpoint is taken with the signatures that verify here, as WWCP_POI `399b7c8` takes it (POI3-ISSUES.md S39,
|
|
545
|
+
SPECIFICATION.md 10.2): `verifyCheckpoint` of a history returns those of its signatures that verify, and the history
|
|
546
|
+
keeps the first of each key and role of them; one that does not verify, invalid or by a key not trusted here, is left
|
|
547
|
+
out, not refused, so that nobody blocks a checkpoint by adding a signature, and a witness trusted elsewhere and not here
|
|
548
|
+
keeps none from it. The roles a checkpoint must be signed in are counted among them: before, a role of a signature
|
|
549
|
+
`verifyCheckpointSignatures` passed over counted ("The checkpoint '…' is not signed in the role '…' by a signature that
|
|
550
|
+
verifies here!", and why the first one was left out). `takeCheckpoint` and a snapshot of a checkpoint hold it with
|
|
551
|
+
those only (`Checkpoint.withSignaturesOnly`). `verifyCheckpointSignatures` returns them as `verified`. The type of
|
|
552
|
+
`verifyCheckpoint` is now `(checkpoint) => readonly RoleSignature[] | undefined`: `undefined`, every signature verifies,
|
|
553
|
+
as before; a callback of a block without `return` is typed `void` and is no longer one.
|
|
554
|
+
- A signature of a commit or checkpoint is read as WWCP_POI3 reads it (`RoamingNetworkCommitSignature.TryParse`): its role,
|
|
555
|
+
time, algorithm, key and value trimmed, its signer as given, and what it signs is what was read; refused when its role,
|
|
556
|
+
signer, algorithm, key or value is empty or whitespace alone (`String.IsNullOrWhiteSpace`), and so is a signature of a
|
|
557
|
+
change set whose algorithm, key or value is ("The … of a signature of … must not be empty!"). Before, this library took
|
|
558
|
+
them, and a role padded with whitespace was not the role.
|
|
559
|
+
- Required signature roles probed against WWCP_POI3 at `12e993a`, `f7b8643` and `399b7c8` (`CheckSignatures` of a
|
|
560
|
+
snapshot, `TryAppend`, `TryAddCheckpoint`), on QA of epoch 2: 1879 cases of roles required of a snapshot, a commit and
|
|
561
|
+
a checkpoint, signed in every role, by keys of the roaming network operator, of DE*GEF and of nobody, by signers named
|
|
562
|
+
in every form, with and without a verifier; a second signature of one key in one role, the same, forged or signed
|
|
563
|
+
later; checkpoints verified by a rule leaving signatures out, forged ones before genuine ones among them; signatures
|
|
564
|
+
read with texts empty, padded and of other types. At `399b7c8` all are taken and refused alike, the checkpoints held with
|
|
565
|
+
the same signatures, the roles in the same words, signatures read refused in the words of this library. Stricter than
|
|
566
|
+
WWCP_POI3 there, which took them: a signer given as a number, an `@context` or another property in a signature of a
|
|
567
|
+
commit or checkpoint, and in the commit of a snapshot an algorithm its epoch does not name. WWCP_POI `b43ff1a` refuses
|
|
568
|
+
them too (POI3-ISSUES.md S40), and `7c6f91c` refuses a signature read in the words of this library, a snapshot naming
|
|
569
|
+
why its commit is refused: probed again at `7c6f91c`, all 1879 alike, word for word.
|
|
570
|
+
- `poi-refusals.json` and `poi-histories.json` of WWCPPOIConformanceTests `215023a` vendored, 806 vectors there, 13 of
|
|
571
|
+
them new: 8 refusals of a signature of the genesis commit or of checkpoint 1 not in its one form (another property,
|
|
572
|
+
`@context`, a signer as a number, a role of whitespace, a signedAt without milliseconds); a replay starting from the
|
|
573
|
+
snapshot of the genesis of epoch 3, its commit signed with Ed448, which the epoch does not name; 4 snapshots of
|
|
574
|
+
checkpoint 0 anchored with a signature that does not verify or a witness the trust anchor does not know (taken, S39), a
|
|
575
|
+
key of one holder signing twice (refused) and with the other holder too (taken). None deviates.
|
|
576
|
+
- What a proof gives of a child array, as WWCP_POI `d35c780` tells it (S29): `givesCompletely`, whether an entity as a proof
|
|
577
|
+
gives it has a child array completely, as an array or none, or pruned or partially; `sizeOf`, how many children it has,
|
|
578
|
+
also where the proof gives only some or none of them. A size or index beyond what this platform holds, and an object as
|
|
579
|
+
the identification of the roaming network, were refused already.
|
|
580
|
+
- No lastChange goes back, as WWCP_POI `12e993a` stamps a change set (SPECIFICATION.md 4, "Timestamps", POI3-ISSUES.md
|
|
581
|
+
S5): with its createdAt, or the lastChange of the roaming network of the version it is applied to, where that is later,
|
|
582
|
+
as the lastChange of the network, of what it changes, adds and embeds, and as the created of what it adds without one.
|
|
583
|
+
Its keys are still checked at its createdAt; nobody is refused for it, only the ETags after it differ (`stampOf`). The
|
|
584
|
+
after ETags of the element and embedded change sets and of the preconditions of the tests, created before QA, are
|
|
585
|
+
those WWCP_POI3 at `12e993a` calculated for the very same changes (67 change sets, all alike). `poi-histories.json` of
|
|
586
|
+
WWCPPOIConformanceTests `249d667` vendored: the three rebased change sets of `history-parties`, created at 08:06:30 on a
|
|
587
|
+
head of 08:07:00, are stamped 08:07:00. `tests/lastChange.test.ts`: every change set of both epochs of QA, created
|
|
588
|
+
before its version, stamped with its lastChange.
|
|
589
|
+
- EV Taler, phase 2, as WWCP_POI `c2d39e5` checks it (concepts/EVTaler.md 5 and 7, `src/evTaler`): the contract terms of
|
|
590
|
+
a step of a session (`EVTalerContractTerms`: version 0, an order, an amount and a maximum fee as GNU Taler writes them,
|
|
591
|
+
the merchant, its exchanges, the times, an auto refund) and their step in `extra.wwcp` (`EVTalerStep`: the roaming
|
|
592
|
+
network, the EVSE, the session, the step after the order before, the EV Taler tariff, the price statement, what it
|
|
593
|
+
covers, from step 2 on the signed meter value at the start, an object as OCPP 2.1 sends it), checked against the proof
|
|
594
|
+
of the station: the operator's merchant and exchanges in the currency of the EV Taler tariff of the EVSE, the price
|
|
595
|
+
statement current when the session began, each step following the one before, the signed start value verified with
|
|
596
|
+
the measurement key of the meter or the station the proof gives, by a transparency software passed in; the amount of a
|
|
597
|
+
step recalculated where the session is priced by one element of the simple profile (`EVTalerRates`), as System.Decimal
|
|
598
|
+
calculates it (`NetDecimal`: 96 bits, 28 places, rounded half to even), rounded up to the minor unit. A `taler://pay`
|
|
599
|
+
URI (`EVTalerPayURI`) names the merchant of the operator. The settlement statement (`EVTalerSettlement`), signed by the
|
|
600
|
+
operator with a key that may sign `payments`, refused without both signed meter values, of the steps of the session,
|
|
601
|
+
its energy and times those of the values, its price recalculated, half away from zero. Read and verified, not signed.
|
|
602
|
+
Of 178 sessions, steps, pay URIs and settlement statements probed against WWCP_POI3 at `c2d39e5`, on station proofs it
|
|
603
|
+
made, all are taken and refused alike, in the same words. `tests/evTalerSessions.test.ts`, on the proof of example A15.
|
|
604
|
+
- EV Taler: a step in minutes costs what it covers, rounded up to the cent, not a cent more, as WWCP_POI `a374855`
|
|
605
|
+
calculates it: the quantity multiplied by the price of an hour before it is divided by 60. A decimal holds no rate of a
|
|
606
|
+
minute such as 0.40 / 60 exactly, and rounding up took its last digit for a cent: 60 minutes at 0.40 EUR an hour were
|
|
607
|
+
0.41 EUR, 30 minutes 0.21 EUR. Found by the probe of this port. The 178 cases probed again against WWCP_POI3 with
|
|
608
|
+
`a374855`: all alike.
|
|
609
|
+
- `hermodURL` as Hermod reads a URL: no `_` in host names, an empty port, an IPv6 address checked.
|
|
610
|
+
- Reading a version takes about two to three times as long as with 0.2.0, e.g. 1.0 to 1.3 s for 3204 charging pools of
|
|
611
|
+
12816 EVSEs, each energy meter with a P-256 key of its own, where 0.2.0 took 0.4 s. A check of a version finds the
|
|
612
|
+
members of the operators in their order, their effective charging stations and energy meters and the charging stations
|
|
613
|
+
parking spaces name once (`whileChecking`); the identifications read of texts and the measurement public keys checked,
|
|
614
|
+
the last 65536 of each, are remembered for the next version too, as a history names most of them again. A key of P-256
|
|
615
|
+
takes about 20 µs, a key of RSA about as long as one exponentiation with its modulus, a certificate of ECDSA a few
|
|
616
|
+
milliseconds.
|
|
617
|
+
|
|
618
|
+
|
|
619
|
+
### Migration
|
|
620
|
+
|
|
621
|
+
- Versions WWCP_POI3 refuses and 0.2.0 took are refused now, in the words of WWCP_POI3; of the probed versions and the
|
|
622
|
+
test vectors, none WWCP_POI3 takes. Messages of refusals checked by their text change where 0.2.0 worded them on its
|
|
623
|
+
own, e.g. a roaming network with keys of its own.
|
|
624
|
+
- A price statement whose price status 0.2.0 took and WWCP_POI3 refuses, e.g. naming the charging tariff
|
|
625
|
+
`DE*POI*FOREIGN`, is refused before its signature is looked at.
|
|
626
|
+
- A charging pool or a charging pool template naming its time zone by a Windows name, an abbreviation or in another case
|
|
627
|
+
than the IANA time zone database, which 0.2.0 took, is refused: it names it as the database writes it, e.g.
|
|
628
|
+
`Europe/Berlin`.
|
|
629
|
+
- `HistoryOptions.verifyCheckpoint` returns the signatures of the checkpoint that verified, `readonly RoleSignature[]`,
|
|
630
|
+
or `undefined` for all of them, e.g. `checkpoint => verifyCheckpointSignatures(checkpoint, trust, options).verified`.
|
|
631
|
+
A callback of a block without `return` no longer compiles; one that throws still refuses the checkpoint. A history,
|
|
632
|
+
`takeCheckpoint` and a snapshot of a checkpoint hold it with those signatures only, its identification the same: what
|
|
633
|
+
an app keeps of a checkpoint it took may hold fewer signatures than it was given (S39).
|
|
634
|
+
- `Change.elementPath` is an array of `ElementPathSegment`, `{propertyName, elementId}`, in place of the JSON objects
|
|
635
|
+
given, and `ChangeSet.preconditions` an array of `Precondition`, `{entityType, entityId, eTag}`, both read as WWCP_POI3
|
|
636
|
+
reads them; the JSON of a change and of a change set stays in its `json`. Both types are exported, and so are
|
|
637
|
+
`MerkleTreeHead`, `PrunedTree` and `TreeNodeKind`, which the API used already.
|
|
638
|
+
- A signature of a commit or checkpoint is read in its one form: its role, signedAt, algorithm, key and value trimmed,
|
|
639
|
+
and refused where one of them or its signer is empty or whitespace alone, where its signer is not a text, or where it
|
|
640
|
+
names an `@context` or another property; so is a signature of a change set whose algorithm, key or value is empty.
|
|
641
|
+
Producers write each signature in this form, as WWCP_POI `7c6f91c` reads it too.
|
|
642
|
+
- A change set created before the `lastChange` of the version it is applied to is stamped with that `lastChange`, not
|
|
643
|
+
with its `createdAt` (S5): the version it leads to, and so its after ETags, differ from those 0.2.0 calculated, and a
|
|
644
|
+
producer calculates them as WWCP_POI `12e993a` does. A change set created after its version, the usual case, is stamped
|
|
645
|
+
with its `createdAt` as before.
|
|
646
|
+
- A transparency software release is identified under its manufacturer, `{manufacturer}:{name}`, and a certificate
|
|
647
|
+
under the body issuing it, `{body}:{name}`, e.g. `GraphDefined:chargy-1.5.0` (S36): a version or change set
|
|
648
|
+
identifying one otherwise, which 0.2.0 took, is refused.
|
|
649
|
+
- The prices of a charging tariff in a price statement are written as a tariff holds them (D18): a statement naming a
|
|
650
|
+
property their type does not define, e.g. the OCPI restriction `max_kwh`, is refused before its signature, and the
|
|
651
|
+
price evidence of a session holding one has invalid signatures. A version naming a restriction outside `startTime` to
|
|
652
|
+
`reservation`, e.g. `maxStateOfCharge`, is refused.
|
|
653
|
+
- A snapshot whose `effectiveLastChanges` WWCP_POI3 does not read, which 0.2.0 took, is refused. Change sets 0.2.0
|
|
654
|
+
refused as not supported, of the entities a party embeds, with element changes or preconditions, are applied now.
|
|
655
|
+
- Reading a version takes two to three times as long as with 0.2.0, about a second for 12816 EVSEs. The package is
|
|
656
|
+
larger, 3.7 MB unpacked where 0.2.0 was 2.2 MB, of it `dist/index.js` 0.9 MB and its source map 2.3 MB.
|
|
657
|
+
- `@vanaheimr/cose` requires ^0.15.0 and `@vanaheimr/metrological-cbor` still ^0.12.0: keep both ranges aligned in
|
|
658
|
+
consumers that use them directly. The minimum runtime remains Node 22.18, and the package remains ESM-only. Without
|
|
659
|
+
Temporal, on Node 22 and 24, a time zone Intl names by another name is taken in any case, e.g. `Asia/KOLKATA`, which
|
|
660
|
+
it names `Asia/Calcutta`; Node 26 takes it only as the database writes it.
|
|
661
|
+
|
|
662
|
+
|
|
663
|
+
## 0.2.0 (2026-11-02)
|
|
7
664
|
|
|
8
665
|
Shared trust and session verification APIs, previously delivered as the unpublished 0.1.2-dev.0 development candidate.
|
|
9
666
|
The experimental evidence and delegation profiles described below remain experimental in this release.
|