@open-charging-cloud/chargy-core 0.6.4 → 0.7.1
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/README.md +1 -1
- package/dist/ACrypt.d.ts +2 -2
- package/dist/ACrypt.d.ts.map +1 -1
- package/dist/Alfen.d.ts +3 -3
- package/dist/Alfen.d.ts.map +1 -1
- package/dist/BSMCrypt01.d.ts +1 -1
- package/dist/BSMCrypt01.d.ts.map +1 -1
- package/dist/EMHCrypt01.d.ts +1 -1
- package/dist/EMHCrypt01.d.ts.map +1 -1
- package/dist/GDFCrypt01.d.ts +1 -1
- package/dist/GDFCrypt01.d.ts.map +1 -1
- package/dist/Mennekes.d.ts +0 -3
- package/dist/Mennekes.d.ts.map +1 -1
- package/dist/OCMF.d.ts +8 -7
- package/dist/OCMF.d.ts.map +1 -1
- package/dist/OCPI.d.ts +2 -1
- package/dist/OCPI.d.ts.map +1 -1
- package/dist/PCDF.d.ts +5 -4
- package/dist/PCDF.d.ts.map +1 -1
- package/dist/QIDigital_DCC.d.ts +20 -19
- package/dist/QIDigital_DCC.d.ts.map +1 -1
- package/dist/SAFE_XML.d.ts +1 -26
- package/dist/SAFE_XML.d.ts.map +1 -1
- package/dist/browser/index.js +1010 -800
- package/dist/browser/index.js.map +1 -1
- package/dist/chargeIT.d.ts +2 -2
- package/dist/chargeIT.d.ts.map +1 -1
- package/dist/chargePoint.d.ts +1 -1
- package/dist/chargePoint.d.ts.map +1 -1
- package/dist/chargy.d.ts +14 -12
- package/dist/chargy.d.ts.map +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/{CryptoUtils.d.ts → interfaces/CryptoUtils.d.ts} +7 -2
- package/dist/interfaces/CryptoUtils.d.ts.map +1 -0
- package/dist/interfaces/IChargeTransparencyLiveLink.d.ts +2 -2
- package/dist/interfaces/IChargeTransparencyLiveLink.d.ts.map +1 -1
- package/dist/interfaces/IChargeTransparencyRecord.d.ts +43 -19
- package/dist/interfaces/IChargeTransparencyRecord.d.ts.map +1 -1
- package/dist/interfaces/IPublicKeyInfo.d.ts +49 -18
- package/dist/interfaces/IPublicKeyInfo.d.ts.map +1 -1
- package/dist/interfaces/chargyInterfaces.d.ts +113 -97
- package/dist/interfaces/chargyInterfaces.d.ts.map +1 -1
- package/dist/{chargyLib.d.ts → interfaces/chargyLib.d.ts} +50 -20
- package/dist/interfaces/chargyLib.d.ts.map +1 -0
- package/dist/interfaces/secp224k1.d.ts.map +1 -0
- package/dist/node/index.js +1010 -800
- package/dist/node/index.js.map +1 -1
- package/dist/verificationResults.d.ts +1 -17
- package/dist/verificationResults.d.ts.map +1 -1
- package/i18n.json +30 -0
- package/package.json +1 -1
- package/dist/CanonicalJSON.d.ts +0 -14
- package/dist/CanonicalJSON.d.ts.map +0 -1
- package/dist/CryptoUtils.d.ts.map +0 -1
- package/dist/chargyLib.d.ts.map +0 -1
- package/dist/secp224k1.d.ts.map +0 -1
- /package/dist/{secp224k1.d.ts → interfaces/secp224k1.d.ts} +0 -0
package/dist/node/index.js
CHANGED
|
@@ -7992,124 +7992,11 @@ var require_elliptic = __commonJS({
|
|
|
7992
7992
|
}
|
|
7993
7993
|
});
|
|
7994
7994
|
|
|
7995
|
-
// src/secp224k1.ts
|
|
7996
|
-
var secp224k1 = class {
|
|
7997
|
-
// Pcurve = 2**224 - 2**32 - 2**12 - 2**11 - 2**9 - 2**7 - 2**4 - 2**1 - 1 or
|
|
7998
|
-
// FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFE56D
|
|
7999
|
-
Zero = BigInt("0");
|
|
8000
|
-
One = BigInt("1");
|
|
8001
|
-
Two = BigInt("2");
|
|
8002
|
-
Three = BigInt("3");
|
|
8003
|
-
Pcurve = BigInt("26959946667150639794667015087019630673637144422540572481099315275117");
|
|
8004
|
-
// The proven prime
|
|
8005
|
-
N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
|
|
8006
|
-
// Number of points in the field
|
|
8007
|
-
Acurve = BigInt(0);
|
|
8008
|
-
// Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
|
|
8009
|
-
Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
|
|
8010
|
-
Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
|
|
8011
|
-
GPoint = [this.Gx, this.Gy];
|
|
8012
|
-
// This is our generator point. Trillions of dif ones possible
|
|
8013
|
-
Sign(hash, RandomNumber, privateKey) {
|
|
8014
|
-
const RandSignPoint = this.ECmultiply(this.GPoint, RandomNumber);
|
|
8015
|
-
if (RandSignPoint.length >= 1 && RandSignPoint[0] != null) {
|
|
8016
|
-
const r = this.modulo(RandSignPoint[0], this.N);
|
|
8017
|
-
const s = this.modulo((hash + r * privateKey) * this.modInv(RandomNumber, this.N), this.N);
|
|
8018
|
-
return [r, s];
|
|
8019
|
-
}
|
|
8020
|
-
return null;
|
|
8021
|
-
}
|
|
8022
|
-
validate(hash, signatureR, signatureS, PublicKey) {
|
|
8023
|
-
if (signatureR == this.Zero || signatureR >= this.N)
|
|
8024
|
-
throw new Error("Invalid R");
|
|
8025
|
-
if (signatureS == this.Zero || signatureS >= this.N)
|
|
8026
|
-
throw new Error("Invalid S");
|
|
8027
|
-
const w = this.modInv(signatureS, this.N);
|
|
8028
|
-
const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
|
|
8029
|
-
const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
|
|
8030
|
-
const validation = this.ECadd(u1, u2);
|
|
8031
|
-
return validation[0] == signatureR;
|
|
8032
|
-
}
|
|
8033
|
-
modulo(n, m) {
|
|
8034
|
-
return (n % m + m) % m;
|
|
8035
|
-
}
|
|
8036
|
-
zfill(s) {
|
|
8037
|
-
while (s.length < 56) {
|
|
8038
|
-
s = "0" + s;
|
|
8039
|
-
}
|
|
8040
|
-
return s;
|
|
8041
|
-
}
|
|
8042
|
-
modInv(a, n = this.Pcurve) {
|
|
8043
|
-
let lm = BigInt(1), hm = BigInt(0), high = n, low = this.modulo(a, n);
|
|
8044
|
-
while (low > 1) {
|
|
8045
|
-
const ratio = high / low, nm = hm - ratio * lm, newm = high - ratio * low;
|
|
8046
|
-
hm = lm;
|
|
8047
|
-
lm = nm;
|
|
8048
|
-
high = low;
|
|
8049
|
-
low = newm;
|
|
8050
|
-
}
|
|
8051
|
-
return this.modulo(lm, n);
|
|
8052
|
-
}
|
|
8053
|
-
ECadd(a, b) {
|
|
8054
|
-
if (a[0] != void 0 && b[0] != void 0 && a[1] != void 0 && b[1] != void 0) {
|
|
8055
|
-
const LamAdd = this.modulo((b[1] - a[1]) * this.modInv(b[0] - a[0]), this.Pcurve);
|
|
8056
|
-
const x = this.modulo(LamAdd * LamAdd - a[0] - b[0], this.Pcurve);
|
|
8057
|
-
const y = this.modulo(LamAdd * (a[0] - x) - a[1], this.Pcurve);
|
|
8058
|
-
return [x, y];
|
|
8059
|
-
}
|
|
8060
|
-
throw new Error("Invalid EC Point Addition!");
|
|
8061
|
-
}
|
|
8062
|
-
ECdouble(a) {
|
|
8063
|
-
if (a[0] != void 0 && a[1] != void 0) {
|
|
8064
|
-
const Lam = this.modulo((a[0] * a[0] * this.Three + this.Acurve) * this.modInv(a[1] * this.Two), this.Pcurve);
|
|
8065
|
-
const x = this.modulo(Lam * Lam - a[0] * this.Two, this.Pcurve);
|
|
8066
|
-
const y = this.modulo(Lam * (a[0] - x) - a[1], this.Pcurve);
|
|
8067
|
-
return [x, y];
|
|
8068
|
-
}
|
|
8069
|
-
throw new Error("Invalid EC Point Doubling!");
|
|
8070
|
-
}
|
|
8071
|
-
ECmultiply(GenPoint, ScalarHex) {
|
|
8072
|
-
if (ScalarHex == this.Zero || ScalarHex >= this.N)
|
|
8073
|
-
throw new Error("Invalid Scalar/Private Key");
|
|
8074
|
-
const ScalarBinary = ScalarHex.toString(2);
|
|
8075
|
-
let Q = GenPoint;
|
|
8076
|
-
for (let i = 1; i < ScalarBinary.length; i++) {
|
|
8077
|
-
Q = this.ECdouble(Q);
|
|
8078
|
-
if (ScalarBinary[i] === "1") {
|
|
8079
|
-
Q = this.ECadd(Q, GenPoint);
|
|
8080
|
-
}
|
|
8081
|
-
}
|
|
8082
|
-
return Q;
|
|
8083
|
-
}
|
|
8084
|
-
// uncompressed is the accumulation of both the x and y points
|
|
8085
|
-
// compressed is the public key to share in transactions
|
|
8086
|
-
// address is the public address tho whom someone can send coin
|
|
8087
|
-
PublicKeyGenerate(PrivateKey) {
|
|
8088
|
-
if (typeof PrivateKey === "number")
|
|
8089
|
-
PrivateKey = BigInt(PrivateKey);
|
|
8090
|
-
if (typeof PrivateKey === "string")
|
|
8091
|
-
PrivateKey = BigInt(PrivateKey);
|
|
8092
|
-
const publicKey = this.ECmultiply(this.GPoint, PrivateKey);
|
|
8093
|
-
if (publicKey[0] !== void 0 && publicKey[1] !== void 0) {
|
|
8094
|
-
const Px = this.zfill(publicKey[0].toString(16));
|
|
8095
|
-
const Py = this.zfill(publicKey[1].toString(16));
|
|
8096
|
-
return {
|
|
8097
|
-
x: publicKey[0],
|
|
8098
|
-
y: publicKey[1],
|
|
8099
|
-
xy: [Px, Py],
|
|
8100
|
-
uncompressed: publicKey[0].toString(16) + publicKey[1].toString(16),
|
|
8101
|
-
compressed: "04" + Px + Py,
|
|
8102
|
-
address: this.modulo(publicKey[1], this.Two) == this.One ? "03" + Px : "02" + Px
|
|
8103
|
-
};
|
|
8104
|
-
}
|
|
8105
|
-
return void 0;
|
|
8106
|
-
}
|
|
8107
|
-
};
|
|
8108
|
-
|
|
8109
7995
|
// src/interfaces/chargyInterfaces.ts
|
|
8110
7996
|
var chargyInterfaces_exports = {};
|
|
8111
7997
|
__export(chargyInterfaces_exports, {
|
|
8112
7998
|
CreateError: () => CreateError,
|
|
7999
|
+
CreateWarning: () => CreateWarning,
|
|
8113
8000
|
CryptoAlgorithms: () => CryptoAlgorithms,
|
|
8114
8001
|
CryptoHashAlgorithms: () => CryptoHashAlgorithms,
|
|
8115
8002
|
DayOfWeek: () => DayOfWeek,
|
|
@@ -8118,7 +8005,7 @@ __export(chargyInterfaces_exports, {
|
|
|
8118
8005
|
IECCurves: () => IECCurves,
|
|
8119
8006
|
IEncoding: () => IEncoding,
|
|
8120
8007
|
InformationRelevance: () => InformationRelevance,
|
|
8121
|
-
|
|
8008
|
+
OIDInfo: () => OIDInfo,
|
|
8122
8009
|
SessionVerificationResult: () => SessionVerificationResult,
|
|
8123
8010
|
SignatureFormats: () => SignatureFormats,
|
|
8124
8011
|
VerificationResult: () => VerificationResult,
|
|
@@ -8126,23 +8013,9 @@ __export(chargyInterfaces_exports, {
|
|
|
8126
8013
|
isGeoLocation: () => isGeoLocation,
|
|
8127
8014
|
isICryptoResult: () => isICryptoResult,
|
|
8128
8015
|
isIFileInfo: () => isIFileInfo,
|
|
8129
|
-
isIPublicKeyXY: () => isIPublicKeyXY,
|
|
8130
8016
|
isISessionCryptoResult1: () => isISessionCryptoResult1,
|
|
8131
|
-
isISessionCryptoResult2: () => isISessionCryptoResult2
|
|
8132
|
-
isMultilanguageText: () => isMultilanguageText,
|
|
8133
|
-
isOIDInfo: () => isOIDInfo,
|
|
8134
|
-
isObject: () => isObject,
|
|
8135
|
-
isString: () => isString,
|
|
8136
|
-
isStringArray: () => isStringArray,
|
|
8137
|
-
isStringOrOIDInfo: () => isStringOrOIDInfo,
|
|
8138
|
-
isStringOrStringArray: () => isStringOrStringArray
|
|
8017
|
+
isISessionCryptoResult2: () => isISessionCryptoResult2
|
|
8139
8018
|
});
|
|
8140
|
-
function isObject(data) {
|
|
8141
|
-
return typeof data === "object" && data !== null;
|
|
8142
|
-
}
|
|
8143
|
-
function isMultilanguageText(data) {
|
|
8144
|
-
return isObject(data) && Object.values(data).every((value) => typeof value === "string");
|
|
8145
|
-
}
|
|
8146
8019
|
function isGeoLocation(data) {
|
|
8147
8020
|
if (!isObject(data))
|
|
8148
8021
|
return false;
|
|
@@ -8150,26 +8023,6 @@ function isGeoLocation(data) {
|
|
|
8150
8023
|
const longitude = data["lng"];
|
|
8151
8024
|
return (latitude === void 0 || typeof latitude === "number") && (longitude === void 0 || typeof longitude === "number");
|
|
8152
8025
|
}
|
|
8153
|
-
function isString(value) {
|
|
8154
|
-
return typeof value === "string";
|
|
8155
|
-
}
|
|
8156
|
-
function isStringArray(value) {
|
|
8157
|
-
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
8158
|
-
}
|
|
8159
|
-
function isStringOrStringArray(value) {
|
|
8160
|
-
return typeof value === "string" || isStringArray(value);
|
|
8161
|
-
}
|
|
8162
|
-
function isOIDInfo(data) {
|
|
8163
|
-
if (!isObject(data))
|
|
8164
|
-
return false;
|
|
8165
|
-
return typeof data["oid"] === "string" && typeof data["name"] === "string";
|
|
8166
|
-
}
|
|
8167
|
-
function isStringOrOIDInfo(value) {
|
|
8168
|
-
return typeof value === "string" || isOIDInfo(value);
|
|
8169
|
-
}
|
|
8170
|
-
function isIPublicKeyXY(obj) {
|
|
8171
|
-
return typeof obj === "object" && obj !== null && typeof obj.x === "string" && typeof obj.y === "string";
|
|
8172
|
-
}
|
|
8173
8026
|
var IECCurves = /* @__PURE__ */ ((IECCurves2) => {
|
|
8174
8027
|
IECCurves2["secp192r1"] = "secp192r1";
|
|
8175
8028
|
IECCurves2["secp224k1"] = "secp224k1";
|
|
@@ -8184,11 +8037,6 @@ var IEncoding = /* @__PURE__ */ ((IEncoding2) => {
|
|
|
8184
8037
|
IEncoding2["base64"] = "base64";
|
|
8185
8038
|
return IEncoding2;
|
|
8186
8039
|
})(IEncoding || {});
|
|
8187
|
-
var PublicKeyFormats = /* @__PURE__ */ ((PublicKeyFormats2) => {
|
|
8188
|
-
PublicKeyFormats2["DER"] = "DER";
|
|
8189
|
-
PublicKeyFormats2["XY"] = "XY";
|
|
8190
|
-
return PublicKeyFormats2;
|
|
8191
|
-
})(PublicKeyFormats || {});
|
|
8192
8040
|
var SignatureFormats = /* @__PURE__ */ ((SignatureFormats2) => {
|
|
8193
8041
|
SignatureFormats2["DER"] = "DER";
|
|
8194
8042
|
SignatureFormats2["RS"] = "RS";
|
|
@@ -8224,6 +8072,12 @@ var ErrorLevel = /* @__PURE__ */ ((ErrorLevel2) => {
|
|
|
8224
8072
|
ErrorLevel2["high"] = "high";
|
|
8225
8073
|
return ErrorLevel2;
|
|
8226
8074
|
})(ErrorLevel || {});
|
|
8075
|
+
function CreateWarning(message, level = "low" /* low */) {
|
|
8076
|
+
return {
|
|
8077
|
+
level,
|
|
8078
|
+
message
|
|
8079
|
+
};
|
|
8080
|
+
}
|
|
8227
8081
|
function CreateError(message, level = "high" /* high */) {
|
|
8228
8082
|
return {
|
|
8229
8083
|
level,
|
|
@@ -8310,12 +8164,19 @@ var DayOfWeek = /* @__PURE__ */ ((DayOfWeek2) => {
|
|
|
8310
8164
|
DayOfWeek2[DayOfWeek2["Saturday"] = 6] = "Saturday";
|
|
8311
8165
|
return DayOfWeek2;
|
|
8312
8166
|
})(DayOfWeek || {});
|
|
8167
|
+
function OIDInfo(data) {
|
|
8168
|
+
if (typeof data === "string")
|
|
8169
|
+
return data;
|
|
8170
|
+
if (isOIDInfo(data))
|
|
8171
|
+
return data.name;
|
|
8172
|
+
return "";
|
|
8173
|
+
}
|
|
8313
8174
|
function isJSONLDObject(value) {
|
|
8314
8175
|
if (typeof value !== "object" || value === null) {
|
|
8315
8176
|
return false;
|
|
8316
8177
|
}
|
|
8317
8178
|
const obj = value;
|
|
8318
|
-
return typeof obj["@context"] === "string";
|
|
8179
|
+
return typeof obj["@context"] === "string" || Array.isArray(obj["@context"]);
|
|
8319
8180
|
}
|
|
8320
8181
|
function toArrayBuffer(data) {
|
|
8321
8182
|
if (data instanceof ArrayBuffer)
|
|
@@ -8775,36 +8636,6 @@ function pad(text, paddingValue) {
|
|
|
8775
8636
|
text ??= "";
|
|
8776
8637
|
return (text + Array(2 * paddingValue).join("0")).substring(0, 2 * paddingValue);
|
|
8777
8638
|
}
|
|
8778
|
-
async function sha256(message) {
|
|
8779
|
-
let hashBuffer;
|
|
8780
|
-
if (typeof message === "string")
|
|
8781
|
-
hashBuffer = await crypto.subtle.digest("SHA-256", Buffer.from(message, "utf8"));
|
|
8782
|
-
else
|
|
8783
|
-
hashBuffer = await crypto.subtle.digest("SHA-256", message);
|
|
8784
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
8785
|
-
const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
|
|
8786
|
-
return hashHex;
|
|
8787
|
-
}
|
|
8788
|
-
async function sha384(message) {
|
|
8789
|
-
let hashBuffer;
|
|
8790
|
-
if (typeof message === "string")
|
|
8791
|
-
hashBuffer = await crypto.subtle.digest("SHA-384", Buffer.from(message, "utf8"));
|
|
8792
|
-
else
|
|
8793
|
-
hashBuffer = await crypto.subtle.digest("SHA-384", message);
|
|
8794
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
8795
|
-
const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
|
|
8796
|
-
return hashHex;
|
|
8797
|
-
}
|
|
8798
|
-
async function sha512(message) {
|
|
8799
|
-
let hashBuffer;
|
|
8800
|
-
if (typeof message === "string")
|
|
8801
|
-
hashBuffer = await crypto.subtle.digest("SHA-512", Buffer.from(message, "utf8"));
|
|
8802
|
-
else
|
|
8803
|
-
hashBuffer = await crypto.subtle.digest("SHA-512", message);
|
|
8804
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
8805
|
-
const hashHex = hashArray.map((b) => ("00" + b.toString(16)).slice(-2)).join("").toLowerCase();
|
|
8806
|
-
return hashHex;
|
|
8807
|
-
}
|
|
8808
8639
|
function asJSONObject(value) {
|
|
8809
8640
|
return isMandatoryJSONObject(value) ? value : void 0;
|
|
8810
8641
|
}
|
|
@@ -8901,6 +8732,48 @@ function parseNumber(value) {
|
|
|
8901
8732
|
}
|
|
8902
8733
|
return null;
|
|
8903
8734
|
}
|
|
8735
|
+
function isObject(data) {
|
|
8736
|
+
return typeof data === "object" && data !== null;
|
|
8737
|
+
}
|
|
8738
|
+
function isI18NString(data) {
|
|
8739
|
+
return isObject(data) && Object.values(data).every((value) => typeof value === "string");
|
|
8740
|
+
}
|
|
8741
|
+
function isString(value) {
|
|
8742
|
+
return typeof value === "string";
|
|
8743
|
+
}
|
|
8744
|
+
function isStringArray(value) {
|
|
8745
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
8746
|
+
}
|
|
8747
|
+
function isStringOrStringArray(value) {
|
|
8748
|
+
return typeof value === "string" || isStringArray(value);
|
|
8749
|
+
}
|
|
8750
|
+
function isOIDInfo(data) {
|
|
8751
|
+
if (!isObject(data))
|
|
8752
|
+
return false;
|
|
8753
|
+
return typeof data["oid"] === "string" && typeof data["name"] === "string";
|
|
8754
|
+
}
|
|
8755
|
+
function isStringOrOIDInfo(value) {
|
|
8756
|
+
return typeof value === "string" || isOIDInfo(value);
|
|
8757
|
+
}
|
|
8758
|
+
function isOptionalStringArray(data) {
|
|
8759
|
+
return data === void 0 || Array.isArray(data) && data.every(isString);
|
|
8760
|
+
}
|
|
8761
|
+
function isOptionalStringOrOIDInfo(data) {
|
|
8762
|
+
return data === void 0 || isStringOrOIDInfo(data);
|
|
8763
|
+
}
|
|
8764
|
+
function isEncodedValue(data) {
|
|
8765
|
+
if (isString(data))
|
|
8766
|
+
return true;
|
|
8767
|
+
if (!isMandatoryJSONObject(data))
|
|
8768
|
+
return false;
|
|
8769
|
+
if (!isString(data["value"]))
|
|
8770
|
+
return false;
|
|
8771
|
+
if (!isOptionalString(data["format"]))
|
|
8772
|
+
return false;
|
|
8773
|
+
if (!isOptionalString(data["encoding"]))
|
|
8774
|
+
return false;
|
|
8775
|
+
return true;
|
|
8776
|
+
}
|
|
8904
8777
|
function InformationRelevanceToString(InfoRelevance) {
|
|
8905
8778
|
switch (InfoRelevance) {
|
|
8906
8779
|
case "Ignored" /* Ignored */:
|
|
@@ -8961,6 +8834,187 @@ function _jsonPrettyPrinter(value, indentLevel, path, keyLookup) {
|
|
|
8961
8834
|
html += String(value);
|
|
8962
8835
|
return html;
|
|
8963
8836
|
}
|
|
8837
|
+
function base64ToBytes(value) {
|
|
8838
|
+
if (typeof Buffer !== "undefined")
|
|
8839
|
+
return Uint8Array.from(Buffer.from(value, "base64"));
|
|
8840
|
+
const binary = atob(value);
|
|
8841
|
+
const bytes = new Uint8Array(binary.length);
|
|
8842
|
+
for (let i = 0; i < binary.length; i++)
|
|
8843
|
+
bytes[i] = binary.charCodeAt(i);
|
|
8844
|
+
return bytes;
|
|
8845
|
+
}
|
|
8846
|
+
function bytesToBase64(bytes) {
|
|
8847
|
+
if (typeof Buffer !== "undefined")
|
|
8848
|
+
return Buffer.from(bytes).toString("base64");
|
|
8849
|
+
let binary = "";
|
|
8850
|
+
for (const byte of bytes)
|
|
8851
|
+
binary += String.fromCharCode(byte);
|
|
8852
|
+
return btoa(binary);
|
|
8853
|
+
}
|
|
8854
|
+
function cleanHex(hex) {
|
|
8855
|
+
return hex.replace(/\s+/g, "");
|
|
8856
|
+
}
|
|
8857
|
+
function hexToBytes(hex) {
|
|
8858
|
+
const cleanedHex = cleanHex(hex);
|
|
8859
|
+
if (cleanedHex.length % 2 !== 0)
|
|
8860
|
+
throw new Error("Hex strings must have even length!");
|
|
8861
|
+
if (!/^[0-9a-fA-F]*$/.test(cleanedHex))
|
|
8862
|
+
throw new Error("Invalid hexadecimal string!");
|
|
8863
|
+
const bytes = new Uint8Array(cleanedHex.length / 2);
|
|
8864
|
+
for (let index = 0; index < cleanedHex.length; index += 2)
|
|
8865
|
+
bytes[index / 2] = Number.parseInt(cleanedHex.substring(index, index + 2), 16);
|
|
8866
|
+
return bytes;
|
|
8867
|
+
}
|
|
8868
|
+
function bytesToHex(bytes) {
|
|
8869
|
+
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
8870
|
+
}
|
|
8871
|
+
async function sha256(message) {
|
|
8872
|
+
return bytesToHex(await sha256____(message));
|
|
8873
|
+
}
|
|
8874
|
+
async function sha384(message) {
|
|
8875
|
+
return bytesToHex(await sha384____(message));
|
|
8876
|
+
}
|
|
8877
|
+
async function sha512(message) {
|
|
8878
|
+
return bytesToHex(await sha512____(message));
|
|
8879
|
+
}
|
|
8880
|
+
async function sha256____(message) {
|
|
8881
|
+
let hashBuffer;
|
|
8882
|
+
if (typeof message === "string")
|
|
8883
|
+
hashBuffer = await crypto.subtle.digest("SHA-256", Buffer.from(message, "utf8"));
|
|
8884
|
+
else
|
|
8885
|
+
hashBuffer = await crypto.subtle.digest("SHA-256", message);
|
|
8886
|
+
return new Uint8Array(hashBuffer);
|
|
8887
|
+
}
|
|
8888
|
+
async function sha384____(message) {
|
|
8889
|
+
let hashBuffer;
|
|
8890
|
+
if (typeof message === "string")
|
|
8891
|
+
hashBuffer = await crypto.subtle.digest("SHA-384", Buffer.from(message, "utf8"));
|
|
8892
|
+
else
|
|
8893
|
+
hashBuffer = await crypto.subtle.digest("SHA-384", message);
|
|
8894
|
+
return new Uint8Array(hashBuffer);
|
|
8895
|
+
}
|
|
8896
|
+
async function sha512____(message) {
|
|
8897
|
+
let hashBuffer;
|
|
8898
|
+
if (typeof message === "string")
|
|
8899
|
+
hashBuffer = await crypto.subtle.digest("SHA-512", Buffer.from(message, "utf8"));
|
|
8900
|
+
else
|
|
8901
|
+
hashBuffer = await crypto.subtle.digest("SHA-512", message);
|
|
8902
|
+
return new Uint8Array(hashBuffer);
|
|
8903
|
+
}
|
|
8904
|
+
|
|
8905
|
+
// src/interfaces/secp224k1.ts
|
|
8906
|
+
var secp224k1 = class {
|
|
8907
|
+
// Pcurve = 2**224 - 2**32 - 2**12 - 2**11 - 2**9 - 2**7 - 2**4 - 2**1 - 1 or
|
|
8908
|
+
// FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFE56D
|
|
8909
|
+
Zero = BigInt("0");
|
|
8910
|
+
One = BigInt("1");
|
|
8911
|
+
Two = BigInt("2");
|
|
8912
|
+
Three = BigInt("3");
|
|
8913
|
+
Pcurve = BigInt("26959946667150639794667015087019630673637144422540572481099315275117");
|
|
8914
|
+
// The proven prime
|
|
8915
|
+
N = BigInt("0x010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7");
|
|
8916
|
+
// Number of points in the field
|
|
8917
|
+
Acurve = BigInt(0);
|
|
8918
|
+
// Defined on the elliptic curve. y^2 = x^3 + Acurve * x + 5
|
|
8919
|
+
Gx = BigInt("0xA1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C");
|
|
8920
|
+
Gy = BigInt("0x7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5");
|
|
8921
|
+
GPoint = [this.Gx, this.Gy];
|
|
8922
|
+
// This is our generator point. Trillions of dif ones possible
|
|
8923
|
+
Sign(hash, RandomNumber, privateKey) {
|
|
8924
|
+
const RandSignPoint = this.ECmultiply(this.GPoint, RandomNumber);
|
|
8925
|
+
if (RandSignPoint.length >= 1 && RandSignPoint[0] != null) {
|
|
8926
|
+
const r = this.modulo(RandSignPoint[0], this.N);
|
|
8927
|
+
const s = this.modulo((hash + r * privateKey) * this.modInv(RandomNumber, this.N), this.N);
|
|
8928
|
+
return [r, s];
|
|
8929
|
+
}
|
|
8930
|
+
return null;
|
|
8931
|
+
}
|
|
8932
|
+
validate(hash, signatureR, signatureS, PublicKey) {
|
|
8933
|
+
if (signatureR == this.Zero || signatureR >= this.N)
|
|
8934
|
+
throw new Error("Invalid R");
|
|
8935
|
+
if (signatureS == this.Zero || signatureS >= this.N)
|
|
8936
|
+
throw new Error("Invalid S");
|
|
8937
|
+
const w = this.modInv(signatureS, this.N);
|
|
8938
|
+
const u1 = this.ECmultiply(this.GPoint, this.modulo(w * hash, this.N));
|
|
8939
|
+
const u2 = this.ECmultiply(PublicKey, this.modulo(w * signatureR, this.N));
|
|
8940
|
+
const validation = this.ECadd(u1, u2);
|
|
8941
|
+
return validation[0] == signatureR;
|
|
8942
|
+
}
|
|
8943
|
+
modulo(n, m) {
|
|
8944
|
+
return (n % m + m) % m;
|
|
8945
|
+
}
|
|
8946
|
+
zfill(s) {
|
|
8947
|
+
while (s.length < 56) {
|
|
8948
|
+
s = "0" + s;
|
|
8949
|
+
}
|
|
8950
|
+
return s;
|
|
8951
|
+
}
|
|
8952
|
+
modInv(a, n = this.Pcurve) {
|
|
8953
|
+
let lm = BigInt(1), hm = BigInt(0), high = n, low = this.modulo(a, n);
|
|
8954
|
+
while (low > 1) {
|
|
8955
|
+
const ratio = high / low, nm = hm - ratio * lm, newm = high - ratio * low;
|
|
8956
|
+
hm = lm;
|
|
8957
|
+
lm = nm;
|
|
8958
|
+
high = low;
|
|
8959
|
+
low = newm;
|
|
8960
|
+
}
|
|
8961
|
+
return this.modulo(lm, n);
|
|
8962
|
+
}
|
|
8963
|
+
ECadd(a, b) {
|
|
8964
|
+
if (a[0] != void 0 && b[0] != void 0 && a[1] != void 0 && b[1] != void 0) {
|
|
8965
|
+
const LamAdd = this.modulo((b[1] - a[1]) * this.modInv(b[0] - a[0]), this.Pcurve);
|
|
8966
|
+
const x = this.modulo(LamAdd * LamAdd - a[0] - b[0], this.Pcurve);
|
|
8967
|
+
const y = this.modulo(LamAdd * (a[0] - x) - a[1], this.Pcurve);
|
|
8968
|
+
return [x, y];
|
|
8969
|
+
}
|
|
8970
|
+
throw new Error("Invalid EC Point Addition!");
|
|
8971
|
+
}
|
|
8972
|
+
ECdouble(a) {
|
|
8973
|
+
if (a[0] != void 0 && a[1] != void 0) {
|
|
8974
|
+
const Lam = this.modulo((a[0] * a[0] * this.Three + this.Acurve) * this.modInv(a[1] * this.Two), this.Pcurve);
|
|
8975
|
+
const x = this.modulo(Lam * Lam - a[0] * this.Two, this.Pcurve);
|
|
8976
|
+
const y = this.modulo(Lam * (a[0] - x) - a[1], this.Pcurve);
|
|
8977
|
+
return [x, y];
|
|
8978
|
+
}
|
|
8979
|
+
throw new Error("Invalid EC Point Doubling!");
|
|
8980
|
+
}
|
|
8981
|
+
ECmultiply(GenPoint, ScalarHex) {
|
|
8982
|
+
if (ScalarHex == this.Zero || ScalarHex >= this.N)
|
|
8983
|
+
throw new Error("Invalid Scalar/Private Key");
|
|
8984
|
+
const ScalarBinary = ScalarHex.toString(2);
|
|
8985
|
+
let Q = GenPoint;
|
|
8986
|
+
for (let i = 1; i < ScalarBinary.length; i++) {
|
|
8987
|
+
Q = this.ECdouble(Q);
|
|
8988
|
+
if (ScalarBinary[i] === "1") {
|
|
8989
|
+
Q = this.ECadd(Q, GenPoint);
|
|
8990
|
+
}
|
|
8991
|
+
}
|
|
8992
|
+
return Q;
|
|
8993
|
+
}
|
|
8994
|
+
// uncompressed is the accumulation of both the x and y points
|
|
8995
|
+
// compressed is the public key to share in transactions
|
|
8996
|
+
// address is the public address tho whom someone can send coin
|
|
8997
|
+
PublicKeyGenerate(PrivateKey) {
|
|
8998
|
+
if (typeof PrivateKey === "number")
|
|
8999
|
+
PrivateKey = BigInt(PrivateKey);
|
|
9000
|
+
if (typeof PrivateKey === "string")
|
|
9001
|
+
PrivateKey = BigInt(PrivateKey);
|
|
9002
|
+
const publicKey = this.ECmultiply(this.GPoint, PrivateKey);
|
|
9003
|
+
if (publicKey[0] !== void 0 && publicKey[1] !== void 0) {
|
|
9004
|
+
const Px = this.zfill(publicKey[0].toString(16));
|
|
9005
|
+
const Py = this.zfill(publicKey[1].toString(16));
|
|
9006
|
+
return {
|
|
9007
|
+
x: publicKey[0],
|
|
9008
|
+
y: publicKey[1],
|
|
9009
|
+
xy: [Px, Py],
|
|
9010
|
+
uncompressed: publicKey[0].toString(16) + publicKey[1].toString(16),
|
|
9011
|
+
compressed: "04" + Px + Py,
|
|
9012
|
+
address: this.modulo(publicKey[1], this.Two) == this.One ? "03" + Px : "02" + Px
|
|
9013
|
+
};
|
|
9014
|
+
}
|
|
9015
|
+
return void 0;
|
|
9016
|
+
}
|
|
9017
|
+
};
|
|
8964
9018
|
|
|
8965
9019
|
// src/ACrypt.ts
|
|
8966
9020
|
var ACrypt = class {
|
|
@@ -9192,8 +9246,8 @@ var Alfen = class {
|
|
|
9192
9246
|
"Signature": this.bufferToHex(Signature)
|
|
9193
9247
|
});
|
|
9194
9248
|
}
|
|
9195
|
-
const evseId =
|
|
9196
|
-
const chargingStationId =
|
|
9249
|
+
const evseId = ContainerInfos.chargingStations?.[0]?.EVSEs?.[0]?.["@id"] ?? "DE*GEF*EVSE*CHARGY*1";
|
|
9250
|
+
const chargingStationId = ContainerInfos.chargingStations?.[0]?.["@id"] ?? "DE*GEF*STATION*CHARGY*1";
|
|
9197
9251
|
const chargingSessionId = asString(chargingSession?.["@id"]);
|
|
9198
9252
|
const firstDataSet = getFirstArrayElement(common.dataSets, "Missing first Alfen data set");
|
|
9199
9253
|
const lastDataSet = getLastArrayElement(common.dataSets, "Missing last Alfen data set");
|
|
@@ -9218,10 +9272,18 @@ var Alfen = class {
|
|
|
9218
9272
|
"@id": chargingStationId,
|
|
9219
9273
|
// ToDo: The container infos are not validated yet!
|
|
9220
9274
|
"description": asJSONObject(chargingStation?.["description"]),
|
|
9221
|
-
"manufacturer":
|
|
9222
|
-
|
|
9223
|
-
|
|
9224
|
-
"
|
|
9275
|
+
"manufacturer": {
|
|
9276
|
+
"name": asString(chargingStation?.["manufacturer"])
|
|
9277
|
+
},
|
|
9278
|
+
"model": {
|
|
9279
|
+
"name": asString(chargingStation?.["type"])
|
|
9280
|
+
},
|
|
9281
|
+
"hardware": {
|
|
9282
|
+
"serialNumber": asString(chargingStation?.["serialNumber"])
|
|
9283
|
+
},
|
|
9284
|
+
"firmware": {
|
|
9285
|
+
"version": asString(chargingStation?.["softwareVersion"])
|
|
9286
|
+
},
|
|
9225
9287
|
"legalCompliance": asJSONObject(chargingStation?.["legalCompliance"]),
|
|
9226
9288
|
"geoLocation": asJSONObject(chargingStation?.["geoLocation"]),
|
|
9227
9289
|
"address": asJSONObject(chargingStation?.["address"]),
|
|
@@ -9231,18 +9293,29 @@ var Alfen = class {
|
|
|
9231
9293
|
"description": asJSONObject(evse?.["description"]),
|
|
9232
9294
|
"connectors": [{
|
|
9233
9295
|
"type": asString(connector?.["type"]) ?? "",
|
|
9234
|
-
"
|
|
9296
|
+
"cable": {
|
|
9297
|
+
"length": asNumber(connector?.["cableLength"]) ?? 0,
|
|
9298
|
+
"looses": asNumber(connector?.["cableLooses"]) ?? 0
|
|
9299
|
+
}
|
|
9235
9300
|
}],
|
|
9236
|
-
"
|
|
9301
|
+
"energyMeters": [
|
|
9237
9302
|
{
|
|
9238
9303
|
"@id": common.MeterId,
|
|
9239
|
-
"manufacturer":
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
"
|
|
9244
|
-
|
|
9245
|
-
|
|
9304
|
+
"manufacturer": {
|
|
9305
|
+
"name": asString(energyMeter?.["manufacturer"]),
|
|
9306
|
+
"contact": { "web": asString(energyMeter?.["manufacturerURL"]) }
|
|
9307
|
+
},
|
|
9308
|
+
"model": {
|
|
9309
|
+
"name": asString(energyMeter?.["model"]),
|
|
9310
|
+
"url": asString(energyMeter?.["modelURL"])
|
|
9311
|
+
},
|
|
9312
|
+
"hardware": {
|
|
9313
|
+
"revision": asString(energyMeter?.["hardwareVersion"])
|
|
9314
|
+
},
|
|
9315
|
+
"firmware": {
|
|
9316
|
+
"version": common.AdapterFWVersion,
|
|
9317
|
+
"checksum": common.AdapterFWChecksum
|
|
9318
|
+
},
|
|
9246
9319
|
"signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/AlfenCrypt01",
|
|
9247
9320
|
"publicKeys": [
|
|
9248
9321
|
{
|
|
@@ -9322,6 +9395,8 @@ var Alfen = class {
|
|
|
9322
9395
|
);
|
|
9323
9396
|
}
|
|
9324
9397
|
_CTR["status"] = "Unvalidated" /* Unvalidated */;
|
|
9398
|
+
if (ContainerInfos.warnings !== void 0)
|
|
9399
|
+
_CTR.warnings = [..._CTR.warnings ?? [], ...ContainerInfos.warnings];
|
|
9325
9400
|
return _CTR;
|
|
9326
9401
|
} catch (exception) {
|
|
9327
9402
|
return {
|
|
@@ -9342,23 +9417,21 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
9342
9417
|
}
|
|
9343
9418
|
async VerifyChargingSession(chargingSession) {
|
|
9344
9419
|
let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
|
|
9345
|
-
{
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9356
|
-
sessionResult = "InvalidSignature" /* InvalidSignature */;
|
|
9357
|
-
}
|
|
9420
|
+
for (const measurement of chargingSession.measurements ?? []) {
|
|
9421
|
+
measurement.chargingSession = chargingSession;
|
|
9422
|
+
if (measurement.values.length > 1) {
|
|
9423
|
+
for (const measurementValue of measurement.values) {
|
|
9424
|
+
measurementValue.measurement = measurement;
|
|
9425
|
+
await this.VerifyMeasurement(measurementValue);
|
|
9426
|
+
}
|
|
9427
|
+
sessionResult = "ValidSignature" /* ValidSignature */;
|
|
9428
|
+
for (const measurementValue of measurement.values) {
|
|
9429
|
+
if (sessionResult == "ValidSignature" /* ValidSignature */ && measurementValue.result?.status != "ValidSignature" /* ValidSignature */) {
|
|
9430
|
+
sessionResult = "InvalidSignature" /* InvalidSignature */;
|
|
9358
9431
|
}
|
|
9359
|
-
}
|
|
9360
|
-
|
|
9361
|
-
|
|
9432
|
+
}
|
|
9433
|
+
} else
|
|
9434
|
+
sessionResult = "AtLeastTwoMeasurementsRequired" /* AtLeastTwoMeasurementsRequired */;
|
|
9362
9435
|
}
|
|
9363
9436
|
return {
|
|
9364
9437
|
status: sessionResult,
|
|
@@ -9388,7 +9461,7 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
9388
9461
|
unitEncoded: SetInt8(cryptoBuffer, measurementValue.measurement.unitEncoded ?? 0, 44),
|
|
9389
9462
|
scalar: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 45),
|
|
9390
9463
|
value: SetUInt64D(cryptoBuffer, measurementValue.value, 46, true),
|
|
9391
|
-
uid: SetText(cryptoBuffer, measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "", 54),
|
|
9464
|
+
uid: SetText(cryptoBuffer, measurementValue.measurement.chargingSession?.authorizationStart?.["@id"] ?? "", 54),
|
|
9392
9465
|
sessionId: SetUInt32(cryptoBuffer, parseInt(measurementValue.measurement.chargingSession?.internalSessionId ?? ""), 74, true),
|
|
9393
9466
|
paging: SetUInt32(cryptoBuffer, measurementValue.paginationId, 78, true)
|
|
9394
9467
|
};
|
|
@@ -9426,8 +9499,8 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
9426
9499
|
cryptoResult.hashValue = hashValue224k1;
|
|
9427
9500
|
result = this.curve224k1.validate(
|
|
9428
9501
|
hashValue224k1,
|
|
9429
|
-
BigInt(
|
|
9430
|
-
BigInt(
|
|
9502
|
+
BigInt("0x" + signatureExpected.r),
|
|
9503
|
+
BigInt("0x" + signatureExpected.s),
|
|
9431
9504
|
[
|
|
9432
9505
|
BigInt("0x" + publicKey.substring(2, 58)),
|
|
9433
9506
|
BigInt("0x" + publicKey.substring(58))
|
|
@@ -9514,7 +9587,7 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
9514
9587
|
this.CreateLocalizedLine("Unit (encoded)", measurementValue.measurement.unitEncoded ?? 0, result.unitEncoded ?? "", infoDiv, PlainTextDiv);
|
|
9515
9588
|
this.CreateLocalizedLine("Scaling", measurementValue.measurement.scale, result.scalar ?? "", infoDiv, PlainTextDiv);
|
|
9516
9589
|
this.CreateLocalizedLine("Measurement Value", measurementValue.value.toString() + " Wh", result.value ?? "", infoDiv, PlainTextDiv);
|
|
9517
|
-
this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart["@id"] ?? "") + " hex", pad(result.uid, 20), infoDiv, PlainTextDiv);
|
|
9590
|
+
this.CreateLocalizedLine("Authorization", (measurementValue.measurement.chargingSession?.authorizationStart?.["@id"] ?? "") + " hex", pad(result.uid, 20), infoDiv, PlainTextDiv);
|
|
9518
9591
|
this.CreateLocalizedLine("SessionId", measurementValue.measurement.chargingSession?.["@id"] ?? "", result.sessionId ?? "", infoDiv, PlainTextDiv);
|
|
9519
9592
|
this.CreateLocalizedLine("Pagination counter", measurementValue.paginationId, result.paging ?? "", infoDiv, PlainTextDiv);
|
|
9520
9593
|
}
|
|
@@ -9541,8 +9614,8 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
9541
9614
|
signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
|
|
9542
9615
|
measurementValue.measurement.chargingSession?.chargingStation,
|
|
9543
9616
|
measurementValue.measurement.chargingSession?.EVSE,
|
|
9544
|
-
measurementValue.measurement.chargingSession?.EVSE?.
|
|
9545
|
-
measurementValue.measurement.chargingSession?.EVSE?.
|
|
9617
|
+
measurementValue.measurement.chargingSession?.EVSE?.energyMeters?.[0],
|
|
9618
|
+
measurementValue.measurement.chargingSession?.EVSE?.energyMeters?.[0]?.publicKeys?.[0],
|
|
9546
9619
|
signature
|
|
9547
9620
|
);
|
|
9548
9621
|
} catch {
|
|
@@ -9554,7 +9627,7 @@ var AlfenCrypt01 = class extends ACrypt {
|
|
|
9554
9627
|
if (SignatureExpectedDiv.parentElement) {
|
|
9555
9628
|
getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (" + (result.signature.format ?? "") + ", hex)";
|
|
9556
9629
|
}
|
|
9557
|
-
if (result.signature.r
|
|
9630
|
+
if (result.signature.r.length > 0 && result.signature.s.length > 0) {
|
|
9558
9631
|
const signatureR = result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
|
|
9559
9632
|
const signatureS = result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
|
|
9560
9633
|
SignatureExpectedDiv.innerHTML = "r: " + signatureR + "<br />s: " + signatureS;
|
|
@@ -10059,7 +10132,7 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
10059
10132
|
"@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/bsm-ws36a-v0+json",
|
|
10060
10133
|
"begin": firstDataSet.time,
|
|
10061
10134
|
"end": lastDataSet.time,
|
|
10062
|
-
"EVSEId": CTR.chargingStationOperators?.[0]?.["chargingStations"]?.[0]?.["EVSEs"][0]?.["@id"],
|
|
10135
|
+
"EVSEId": CTR.chargingStationOperators?.[0]?.["chargingStations"]?.[0]?.["EVSEs"]?.[0]?.["@id"],
|
|
10063
10136
|
"authorizationStart": {
|
|
10064
10137
|
"@id": common.contract_id,
|
|
10065
10138
|
"@context": common.contract_type
|
|
@@ -10166,7 +10239,7 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
10166
10239
|
{
|
|
10167
10240
|
const firstChargingSession = getFirstArrayElement(CTR.chargingSessions, "Missing first BSM charging session");
|
|
10168
10241
|
const lastChargingSession = getLastArrayElement(CTR.chargingSessions, "Missing last BSM charging session");
|
|
10169
|
-
if (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin) {
|
|
10242
|
+
if (firstChargingSession.begin !== void 0 && (CTR.begin == void 0 || CTR.begin === "" || CTR.begin > firstChargingSession.begin)) {
|
|
10170
10243
|
CTR.begin = firstChargingSession.begin;
|
|
10171
10244
|
}
|
|
10172
10245
|
if (lastChargingSession.end !== void 0) {
|
|
@@ -10174,21 +10247,22 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
10174
10247
|
CTR.end = lastChargingSession.end;
|
|
10175
10248
|
}
|
|
10176
10249
|
}
|
|
10177
|
-
|
|
10178
|
-
|
|
10179
|
-
|
|
10180
|
-
|
|
10181
|
-
|
|
10182
|
-
else {
|
|
10183
|
-
CTR.contract["@id"] = common.contract_id;
|
|
10184
|
-
CTR.contract["@context"] = common.contract_type;
|
|
10185
|
-
}
|
|
10186
|
-
CTR.chargingStationOperators?.[0]?.chargingStations?.[0]?.EVSEs[0]?.meters?.push({
|
|
10250
|
+
CTR.contracts = [{
|
|
10251
|
+
"@id": common.contract_id,
|
|
10252
|
+
"@context": common.contract_type
|
|
10253
|
+
}];
|
|
10254
|
+
CTR.chargingStationOperators?.[0]?.chargingStations?.[0]?.EVSEs?.[0]?.energyMeters?.push({
|
|
10187
10255
|
"@id": common.meterInfo_meterId,
|
|
10188
|
-
model: common.meterInfo_type,
|
|
10189
|
-
manufacturer:
|
|
10190
|
-
|
|
10191
|
-
|
|
10256
|
+
model: { name: common.meterInfo_type },
|
|
10257
|
+
manufacturer: {
|
|
10258
|
+
name: common.meterInfo_manufacturer,
|
|
10259
|
+
contact: {
|
|
10260
|
+
web: "https://www.bzr-bauer.de"
|
|
10261
|
+
}
|
|
10262
|
+
},
|
|
10263
|
+
firmware: {
|
|
10264
|
+
version: common.meterInfo_firmwareVersion
|
|
10265
|
+
},
|
|
10192
10266
|
//hardwareVersion?: string;
|
|
10193
10267
|
signatureInfos: {
|
|
10194
10268
|
hash: "SHA256" /* SHA256 */,
|
|
@@ -10223,7 +10297,7 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
10223
10297
|
async VerifyChargingSession(chargingSession) {
|
|
10224
10298
|
let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
|
|
10225
10299
|
{
|
|
10226
|
-
for (const measurement of chargingSession.measurements) {
|
|
10300
|
+
for (const measurement of chargingSession.measurements ?? []) {
|
|
10227
10301
|
measurement.chargingSession = chargingSession;
|
|
10228
10302
|
if (measurement.values.length > 1) {
|
|
10229
10303
|
for (const measurementValue of measurement.values) {
|
|
@@ -10390,13 +10464,13 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
10390
10464
|
const signatureDiv = publicKeySignatureContainer?.appendChild(document.createElement("div"));
|
|
10391
10465
|
const chargingSession = measurementValue.measurement.chargingSession;
|
|
10392
10466
|
const evse = chargingSession?.EVSE;
|
|
10393
|
-
const
|
|
10394
|
-
const publicKey =
|
|
10395
|
-
if (signatureDiv != null && chargingSession != null && evse != null &&
|
|
10467
|
+
const energyMeter = evse?.energyMeters?.at(0);
|
|
10468
|
+
const publicKey = energyMeter?.publicKeys?.at(0);
|
|
10469
|
+
if (signatureDiv != null && chargingSession != null && evse != null && energyMeter != null && publicKey != null) {
|
|
10396
10470
|
signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
|
|
10397
10471
|
chargingSession.chargingStation,
|
|
10398
10472
|
evse,
|
|
10399
|
-
|
|
10473
|
+
energyMeter,
|
|
10400
10474
|
publicKey,
|
|
10401
10475
|
signature
|
|
10402
10476
|
);
|
|
@@ -10411,7 +10485,7 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
10411
10485
|
if (SignatureExpectedDiv.parentElement) {
|
|
10412
10486
|
getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
|
|
10413
10487
|
}
|
|
10414
|
-
if (result.signature.r
|
|
10488
|
+
if (result.signature.r.length > 0 && result.signature.s.length > 0)
|
|
10415
10489
|
SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-");
|
|
10416
10490
|
else if (result.signature.value != null && result.signature.value.length > 0)
|
|
10417
10491
|
SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
|
|
@@ -10549,97 +10623,7 @@ var BSMCrypt01 = class extends ACrypt {
|
|
|
10549
10623
|
// //#endregion
|
|
10550
10624
|
};
|
|
10551
10625
|
|
|
10552
|
-
// src/
|
|
10553
|
-
var CanonicalJSONError = class extends TypeError {
|
|
10554
|
-
constructor(message) {
|
|
10555
|
-
super(message);
|
|
10556
|
-
this.name = "CanonicalJSONError";
|
|
10557
|
-
}
|
|
10558
|
-
};
|
|
10559
|
-
function canonicalJSONStringify(value) {
|
|
10560
|
-
return serializeJSONValue(value, "$", /* @__PURE__ */ new WeakSet());
|
|
10561
|
-
}
|
|
10562
|
-
function canonicalJSONBytes(value) {
|
|
10563
|
-
return new TextEncoder().encode(canonicalJSONStringify(value));
|
|
10564
|
-
}
|
|
10565
|
-
function serializeJSONValue(value, path, seen) {
|
|
10566
|
-
switch (typeof value) {
|
|
10567
|
-
case "string":
|
|
10568
|
-
return JSON.stringify(value);
|
|
10569
|
-
case "number":
|
|
10570
|
-
if (!Number.isFinite(value))
|
|
10571
|
-
throw new CanonicalJSONError(`Non-finite number at ${path} is not valid JSON.`);
|
|
10572
|
-
return JSON.stringify(value);
|
|
10573
|
-
case "boolean":
|
|
10574
|
-
return value ? "true" : "false";
|
|
10575
|
-
case "object":
|
|
10576
|
-
if (value === null)
|
|
10577
|
-
return "null";
|
|
10578
|
-
return Array.isArray(value) ? serializeJSONArray(value, path, seen) : serializeJSONObject(value, path, seen);
|
|
10579
|
-
case "bigint":
|
|
10580
|
-
throw new CanonicalJSONError(`BigInt at ${path} is not valid JSON.`);
|
|
10581
|
-
case "undefined":
|
|
10582
|
-
throw new CanonicalJSONError(`Undefined value at ${path} is not valid JSON.`);
|
|
10583
|
-
case "function":
|
|
10584
|
-
throw new CanonicalJSONError(`Function at ${path} is not valid JSON.`);
|
|
10585
|
-
case "symbol":
|
|
10586
|
-
throw new CanonicalJSONError(`Symbol at ${path} is not valid JSON.`);
|
|
10587
|
-
}
|
|
10588
|
-
}
|
|
10589
|
-
function serializeJSONArray(value, path, seen) {
|
|
10590
|
-
if (seen.has(value))
|
|
10591
|
-
throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
|
|
10592
|
-
seen.add(value);
|
|
10593
|
-
const indexedKeys = /* @__PURE__ */ new Set();
|
|
10594
|
-
for (let i = 0; i < value.length; i++) {
|
|
10595
|
-
if (!Object.prototype.hasOwnProperty.call(value, i))
|
|
10596
|
-
throw new CanonicalJSONError(`Sparse array slot at ${path}[${String(i)}] is not valid JSON.`);
|
|
10597
|
-
indexedKeys.add(String(i));
|
|
10598
|
-
}
|
|
10599
|
-
for (const key of Object.keys(value)) {
|
|
10600
|
-
if (!indexedKeys.has(key))
|
|
10601
|
-
throw new CanonicalJSONError(`Non-index array property ${formatPathProperty(key)} at ${path} is not valid JSON.`);
|
|
10602
|
-
}
|
|
10603
|
-
rejectEnumerableSymbolProperties(value, path);
|
|
10604
|
-
const serializedItems = value.map(
|
|
10605
|
-
(item, index) => serializeJSONValue(item, `${path}[${String(index)}]`, seen)
|
|
10606
|
-
);
|
|
10607
|
-
seen.delete(value);
|
|
10608
|
-
return `[${serializedItems.join(",")}]`;
|
|
10609
|
-
}
|
|
10610
|
-
function serializeJSONObject(value, path, seen) {
|
|
10611
|
-
if (Object.prototype.toString.call(value) !== "[object Object]")
|
|
10612
|
-
throw new CanonicalJSONError(`Unsupported object at ${path} is not valid JSON.`);
|
|
10613
|
-
if (seen.has(value))
|
|
10614
|
-
throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
|
|
10615
|
-
seen.add(value);
|
|
10616
|
-
rejectEnumerableSymbolProperties(value, path);
|
|
10617
|
-
const serializedProperties = Object.keys(value).sort(compareOrdinal).map((key) => {
|
|
10618
|
-
const serializedKey = JSON.stringify(key);
|
|
10619
|
-
const serializedValue = serializeJSONValue(
|
|
10620
|
-
value[key],
|
|
10621
|
-
`${path}${formatPathProperty(key)}`,
|
|
10622
|
-
seen
|
|
10623
|
-
);
|
|
10624
|
-
return `${serializedKey}:${serializedValue}`;
|
|
10625
|
-
});
|
|
10626
|
-
seen.delete(value);
|
|
10627
|
-
return `{${serializedProperties.join(",")}}`;
|
|
10628
|
-
}
|
|
10629
|
-
function rejectEnumerableSymbolProperties(value, path) {
|
|
10630
|
-
for (const symbol of Object.getOwnPropertySymbols(value)) {
|
|
10631
|
-
if (Object.prototype.propertyIsEnumerable.call(value, symbol))
|
|
10632
|
-
throw new CanonicalJSONError(`Symbol property at ${path} is not valid JSON.`);
|
|
10633
|
-
}
|
|
10634
|
-
}
|
|
10635
|
-
function compareOrdinal(left, right) {
|
|
10636
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
10637
|
-
}
|
|
10638
|
-
function formatPathProperty(propertyName) {
|
|
10639
|
-
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName) ? `.${propertyName}` : `[${JSON.stringify(propertyName)}]`;
|
|
10640
|
-
}
|
|
10641
|
-
|
|
10642
|
-
// src/CryptoUtils.ts
|
|
10626
|
+
// src/interfaces/CryptoUtils.ts
|
|
10643
10627
|
var import_elliptic = __toESM(require_elliptic());
|
|
10644
10628
|
var JSONSignatureVerificationStatus = /* @__PURE__ */ ((JSONSignatureVerificationStatus2) => {
|
|
10645
10629
|
JSONSignatureVerificationStatus2["True"] = "True";
|
|
@@ -10680,7 +10664,7 @@ async function signJSONMessage(JSONMessage, KeyPairs, options) {
|
|
|
10680
10664
|
continue;
|
|
10681
10665
|
const messageJSON = cloneMessageWithoutSignatures(JSONMessage);
|
|
10682
10666
|
const plainText = canonicalJSONBytes(messageJSON);
|
|
10683
|
-
const sha256Hash = await
|
|
10667
|
+
const sha256Hash = await sha256____(plainText);
|
|
10684
10668
|
JSONMessage.signatures ??= [];
|
|
10685
10669
|
const publicKeyBytes = Uint8Array.from(KeyPair.getPublic(false, "array"));
|
|
10686
10670
|
const signature = KeyPair.sign(sha256Hash, {
|
|
@@ -10727,7 +10711,7 @@ async function verifyJSONSignatureResult(JSONMessage, signature, options) {
|
|
|
10727
10711
|
try {
|
|
10728
10712
|
const messageJSON = cloneMessageWithoutSignatures(JSONMessage);
|
|
10729
10713
|
const plainText = canonicalJSONBytes(messageJSON);
|
|
10730
|
-
sha256Hash = await
|
|
10714
|
+
sha256Hash = await sha256____(plainText);
|
|
10731
10715
|
} catch (exception) {
|
|
10732
10716
|
return verificationResult(
|
|
10733
10717
|
"InvalidCanonicalJSON" /* InvalidCanonicalJSON */,
|
|
@@ -10835,7 +10819,7 @@ function parseSignedJSONMessage(JSONMessage) {
|
|
|
10835
10819
|
};
|
|
10836
10820
|
}
|
|
10837
10821
|
}
|
|
10838
|
-
if (!
|
|
10822
|
+
if (!isMandatoryJSONObject(parsedMessage))
|
|
10839
10823
|
return {
|
|
10840
10824
|
result: verificationResult(
|
|
10841
10825
|
"InvalidJSON" /* InvalidJSON */,
|
|
@@ -10854,7 +10838,7 @@ function parseSignedJSONMessage(JSONMessage) {
|
|
|
10854
10838
|
};
|
|
10855
10839
|
}
|
|
10856
10840
|
function isJSONSignature(value) {
|
|
10857
|
-
return
|
|
10841
|
+
return isMandatoryJSONObject(value) && typeof value["publicKey"] === "string" && typeof value["publicKeyHEX"] === "string" && typeof value["signature"] === "string" && typeof value["signatureHEX"] === "string";
|
|
10858
10842
|
}
|
|
10859
10843
|
function signatureEncodingsMatch(signature) {
|
|
10860
10844
|
try {
|
|
@@ -10878,32 +10862,93 @@ function verificationResult(status, description) {
|
|
|
10878
10862
|
function isVerificationTrue(result) {
|
|
10879
10863
|
return (typeof result === "string" ? result : result.status) === "True" /* True */;
|
|
10880
10864
|
}
|
|
10881
|
-
|
|
10882
|
-
|
|
10865
|
+
var CanonicalJSONError = class extends TypeError {
|
|
10866
|
+
constructor(message) {
|
|
10867
|
+
super(message);
|
|
10868
|
+
this.name = "CanonicalJSONError";
|
|
10869
|
+
}
|
|
10870
|
+
};
|
|
10871
|
+
function canonicalJSONStringify(value) {
|
|
10872
|
+
return serializeJSONValue(value, "$", /* @__PURE__ */ new WeakSet());
|
|
10883
10873
|
}
|
|
10884
|
-
|
|
10885
|
-
|
|
10886
|
-
return new Uint8Array(digest);
|
|
10874
|
+
function canonicalJSONBytes(value) {
|
|
10875
|
+
return new TextEncoder().encode(canonicalJSONStringify(value));
|
|
10887
10876
|
}
|
|
10888
|
-
function
|
|
10889
|
-
|
|
10877
|
+
function serializeJSONValue(value, path, seen) {
|
|
10878
|
+
switch (typeof value) {
|
|
10879
|
+
case "string":
|
|
10880
|
+
return JSON.stringify(value);
|
|
10881
|
+
case "number":
|
|
10882
|
+
if (!Number.isFinite(value))
|
|
10883
|
+
throw new CanonicalJSONError(`Non-finite number at ${path} is not valid JSON.`);
|
|
10884
|
+
return JSON.stringify(value);
|
|
10885
|
+
case "boolean":
|
|
10886
|
+
return value ? "true" : "false";
|
|
10887
|
+
case "object":
|
|
10888
|
+
if (value === null)
|
|
10889
|
+
return "null";
|
|
10890
|
+
return Array.isArray(value) ? serializeJSONArray(value, path, seen) : serializeJSONObject(value, path, seen);
|
|
10891
|
+
case "bigint":
|
|
10892
|
+
throw new CanonicalJSONError(`BigInt at ${path} is not valid JSON.`);
|
|
10893
|
+
case "undefined":
|
|
10894
|
+
throw new CanonicalJSONError(`Undefined value at ${path} is not valid JSON.`);
|
|
10895
|
+
case "function":
|
|
10896
|
+
throw new CanonicalJSONError(`Function at ${path} is not valid JSON.`);
|
|
10897
|
+
case "symbol":
|
|
10898
|
+
throw new CanonicalJSONError(`Symbol at ${path} is not valid JSON.`);
|
|
10899
|
+
}
|
|
10890
10900
|
}
|
|
10891
|
-
function
|
|
10892
|
-
if (
|
|
10893
|
-
|
|
10894
|
-
|
|
10895
|
-
const
|
|
10896
|
-
for (let i = 0; i <
|
|
10897
|
-
|
|
10898
|
-
|
|
10901
|
+
function serializeJSONArray(value, path, seen) {
|
|
10902
|
+
if (seen.has(value))
|
|
10903
|
+
throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
|
|
10904
|
+
seen.add(value);
|
|
10905
|
+
const indexedKeys = /* @__PURE__ */ new Set();
|
|
10906
|
+
for (let i = 0; i < value.length; i++) {
|
|
10907
|
+
if (!Object.prototype.hasOwnProperty.call(value, i))
|
|
10908
|
+
throw new CanonicalJSONError(`Sparse array slot at ${path}[${String(i)}] is not valid JSON.`);
|
|
10909
|
+
indexedKeys.add(String(i));
|
|
10910
|
+
}
|
|
10911
|
+
for (const key of Object.keys(value)) {
|
|
10912
|
+
if (!indexedKeys.has(key))
|
|
10913
|
+
throw new CanonicalJSONError(`Non-index array property ${formatPathProperty(key)} at ${path} is not valid JSON.`);
|
|
10914
|
+
}
|
|
10915
|
+
rejectEnumerableSymbolProperties(value, path);
|
|
10916
|
+
const serializedItems = value.map(
|
|
10917
|
+
(item, index) => serializeJSONValue(item, `${path}[${String(index)}]`, seen)
|
|
10918
|
+
);
|
|
10919
|
+
seen.delete(value);
|
|
10920
|
+
return `[${serializedItems.join(",")}]`;
|
|
10899
10921
|
}
|
|
10900
|
-
function
|
|
10901
|
-
if (
|
|
10902
|
-
|
|
10903
|
-
|
|
10904
|
-
|
|
10905
|
-
|
|
10906
|
-
|
|
10922
|
+
function serializeJSONObject(value, path, seen) {
|
|
10923
|
+
if (Object.prototype.toString.call(value) !== "[object Object]")
|
|
10924
|
+
throw new CanonicalJSONError(`Unsupported object at ${path} is not valid JSON.`);
|
|
10925
|
+
if (seen.has(value))
|
|
10926
|
+
throw new CanonicalJSONError(`Circular reference at ${path} is not valid JSON.`);
|
|
10927
|
+
seen.add(value);
|
|
10928
|
+
rejectEnumerableSymbolProperties(value, path);
|
|
10929
|
+
const serializedProperties = Object.keys(value).sort(compareOrdinal).map((key) => {
|
|
10930
|
+
const serializedKey = JSON.stringify(key);
|
|
10931
|
+
const serializedValue = serializeJSONValue(
|
|
10932
|
+
value[key],
|
|
10933
|
+
`${path}${formatPathProperty(key)}`,
|
|
10934
|
+
seen
|
|
10935
|
+
);
|
|
10936
|
+
return `${serializedKey}:${serializedValue}`;
|
|
10937
|
+
});
|
|
10938
|
+
seen.delete(value);
|
|
10939
|
+
return `{${serializedProperties.join(",")}}`;
|
|
10940
|
+
}
|
|
10941
|
+
function rejectEnumerableSymbolProperties(value, path) {
|
|
10942
|
+
for (const symbol of Object.getOwnPropertySymbols(value)) {
|
|
10943
|
+
if (Object.prototype.propertyIsEnumerable.call(value, symbol))
|
|
10944
|
+
throw new CanonicalJSONError(`Symbol property at ${path} is not valid JSON.`);
|
|
10945
|
+
}
|
|
10946
|
+
}
|
|
10947
|
+
function compareOrdinal(left, right) {
|
|
10948
|
+
return left < right ? -1 : left > right ? 1 : 0;
|
|
10949
|
+
}
|
|
10950
|
+
function formatPathProperty(propertyName) {
|
|
10951
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(propertyName) ? `.${propertyName}` : `[${JSON.stringify(propertyName)}]`;
|
|
10907
10952
|
}
|
|
10908
10953
|
|
|
10909
10954
|
// src/EMHCrypt01.ts
|
|
@@ -10918,7 +10963,7 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
10918
10963
|
async VerifyChargingSession(chargingSession) {
|
|
10919
10964
|
let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
|
|
10920
10965
|
{
|
|
10921
|
-
for (const measurement of chargingSession.measurements) {
|
|
10966
|
+
for (const measurement of chargingSession.measurements ?? []) {
|
|
10922
10967
|
measurement.chargingSession = chargingSession;
|
|
10923
10968
|
if (measurement.values.length > 1) {
|
|
10924
10969
|
for (const measurementValue of measurement.values) {
|
|
@@ -10966,8 +11011,8 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
10966
11011
|
scale: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 30),
|
|
10967
11012
|
value: SetUInt64D(cryptoBuffer, measurementValue.value, 31, true),
|
|
10968
11013
|
logBookIndex: SetHex(cryptoBuffer, measurementValue.logBookIndex, 39, false),
|
|
10969
|
-
authorizationStart: SetText(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart["@id"], 41),
|
|
10970
|
-
authorizationStartTimestamp: SetTimestamp32(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart.timestamp, 169)
|
|
11014
|
+
authorizationStart: SetText(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.["@id"] ?? "", 41),
|
|
11015
|
+
authorizationStartTimestamp: SetTimestamp32(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.timestamp ?? measurementValue.timestamp, 169)
|
|
10971
11016
|
};
|
|
10972
11017
|
const firstSignature = measurementValue.signatures?.[0];
|
|
10973
11018
|
if (firstSignature != null) {
|
|
@@ -10986,7 +11031,7 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
10986
11031
|
if (meter.publicKeys != null && meter.publicKeys.length > 0) {
|
|
10987
11032
|
try {
|
|
10988
11033
|
const publicKey = meter.publicKeys.at(0);
|
|
10989
|
-
cryptoResult.publicKey = publicKey?.value
|
|
11034
|
+
cryptoResult.publicKey = publicKey?.value.toLowerCase();
|
|
10990
11035
|
cryptoResult.publicKeyFormat = publicKey?.format;
|
|
10991
11036
|
cryptoResult.publicKeySignatures = publicKey?.signatures;
|
|
10992
11037
|
try {
|
|
@@ -11014,7 +11059,7 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
11014
11059
|
return {};
|
|
11015
11060
|
}
|
|
11016
11061
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
11017
|
-
if (measurementValue.measurement?.chargingSession?.authorizationStart
|
|
11062
|
+
if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
|
|
11018
11063
|
return new Error("Invalid measurement!");
|
|
11019
11064
|
}
|
|
11020
11065
|
const result = measurementValue.result;
|
|
@@ -11065,8 +11110,8 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
11065
11110
|
signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
|
|
11066
11111
|
measurementValue.measurement.chargingSession.chargingStation,
|
|
11067
11112
|
measurementValue.measurement.chargingSession.EVSE,
|
|
11068
|
-
measurementValue.measurement.chargingSession.EVSE?.
|
|
11069
|
-
measurementValue.measurement.chargingSession.EVSE?.
|
|
11113
|
+
measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
|
|
11114
|
+
measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
|
|
11070
11115
|
signature
|
|
11071
11116
|
);
|
|
11072
11117
|
signatureDiv.onclick = () => {
|
|
@@ -11083,7 +11128,7 @@ var EMHCrypt01 = class extends ACrypt {
|
|
|
11083
11128
|
if (SignatureExpectedDiv.parentElement) {
|
|
11084
11129
|
getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
|
|
11085
11130
|
}
|
|
11086
|
-
if (result.signature.r
|
|
11131
|
+
if (result.signature.r.length > 0 && result.signature.s.length > 0)
|
|
11087
11132
|
SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
|
|
11088
11133
|
else if (result.signature.value != null && result.signature.value.length > 0)
|
|
11089
11134
|
SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
|
|
@@ -11154,7 +11199,7 @@ var GDFCrypt01 = class extends ACrypt {
|
|
|
11154
11199
|
async VerifyChargingSession(chargingSession) {
|
|
11155
11200
|
let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
|
|
11156
11201
|
{
|
|
11157
|
-
for (const measurement of chargingSession.measurements) {
|
|
11202
|
+
for (const measurement of chargingSession.measurements ?? []) {
|
|
11158
11203
|
measurement.chargingSession = chargingSession;
|
|
11159
11204
|
if (measurement.values.length > 1) {
|
|
11160
11205
|
for (const measurementValue of measurement.values) {
|
|
@@ -11198,8 +11243,8 @@ var GDFCrypt01 = class extends ACrypt {
|
|
|
11198
11243
|
unitEncoded: SetInt8(cryptoBuffer, measurementValue.measurement.unitEncoded ?? 0, 29),
|
|
11199
11244
|
scale: SetInt8(cryptoBuffer, measurementValue.measurement.scale, 30),
|
|
11200
11245
|
value: SetUInt64D(cryptoBuffer, measurementValue.value, 31, true),
|
|
11201
|
-
authorizationStart: SetHex(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart["@id"], 41),
|
|
11202
|
-
authorizationStartTimestamp: SetTimestamp(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart
|
|
11246
|
+
authorizationStart: SetHex(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.["@id"] ?? "", 41),
|
|
11247
|
+
authorizationStartTimestamp: SetTimestamp(cryptoBuffer, measurementValue.measurement.chargingSession.authorizationStart?.timestamp, 169)
|
|
11203
11248
|
};
|
|
11204
11249
|
const firstSignature = measurementValue.signatures?.[0];
|
|
11205
11250
|
if (firstSignature != null) {
|
|
@@ -11218,7 +11263,7 @@ var GDFCrypt01 = class extends ACrypt {
|
|
|
11218
11263
|
if (meter.publicKeys != null && meter.publicKeys.length > 0) {
|
|
11219
11264
|
try {
|
|
11220
11265
|
const publicKey = meter.publicKeys.at(0);
|
|
11221
|
-
cryptoResult.publicKey = publicKey?.value
|
|
11266
|
+
cryptoResult.publicKey = publicKey?.value.toLowerCase();
|
|
11222
11267
|
cryptoResult.publicKeyFormat = publicKey?.format;
|
|
11223
11268
|
cryptoResult.publicKeySignatures = publicKey?.signatures;
|
|
11224
11269
|
try {
|
|
@@ -11246,7 +11291,7 @@ var GDFCrypt01 = class extends ACrypt {
|
|
|
11246
11291
|
return {};
|
|
11247
11292
|
}
|
|
11248
11293
|
async ViewMeasurement(measurementValue, _errorDiv, introDiv, infoDiv, PlainTextDiv, HashedPlainTextDiv, PublicKeyDiv, SignatureExpectedDiv, SignatureCheckDiv) {
|
|
11249
|
-
if (measurementValue.measurement?.chargingSession?.authorizationStart
|
|
11294
|
+
if (measurementValue.measurement?.chargingSession?.authorizationStart?.timestamp === void 0) {
|
|
11250
11295
|
return new Error("Invalid measurement!");
|
|
11251
11296
|
}
|
|
11252
11297
|
const result = measurementValue.result;
|
|
@@ -11292,8 +11337,8 @@ var GDFCrypt01 = class extends ACrypt {
|
|
|
11292
11337
|
signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
|
|
11293
11338
|
measurementValue.measurement.chargingSession.chargingStation,
|
|
11294
11339
|
measurementValue.measurement.chargingSession.EVSE,
|
|
11295
|
-
measurementValue.measurement.chargingSession.EVSE?.
|
|
11296
|
-
measurementValue.measurement.chargingSession.EVSE?.
|
|
11340
|
+
measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
|
|
11341
|
+
measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
|
|
11297
11342
|
signature
|
|
11298
11343
|
);
|
|
11299
11344
|
} catch (exception) {
|
|
@@ -11306,7 +11351,7 @@ var GDFCrypt01 = class extends ACrypt {
|
|
|
11306
11351
|
if (SignatureExpectedDiv.parentElement) {
|
|
11307
11352
|
getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (" + (result.signature.format ?? "") + ", hex)";
|
|
11308
11353
|
}
|
|
11309
|
-
if (result.signature.r
|
|
11354
|
+
if (result.signature.r.length > 0 && result.signature.s.length > 0)
|
|
11310
11355
|
SignatureExpectedDiv.innerHTML = "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "");
|
|
11311
11356
|
else if (result.signature.value != null && result.signature.value.length > 0)
|
|
11312
11357
|
SignatureExpectedDiv.innerHTML = result.signature.value.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
|
|
@@ -11338,7 +11383,118 @@ var GDFCrypt01 = class extends ACrypt {
|
|
|
11338
11383
|
}
|
|
11339
11384
|
return void 0;
|
|
11340
11385
|
}
|
|
11341
|
-
};
|
|
11386
|
+
};
|
|
11387
|
+
|
|
11388
|
+
// src/interfaces/IPublicKeyInfo.ts
|
|
11389
|
+
var IPublicKeyInfo_exports = {};
|
|
11390
|
+
__export(IPublicKeyInfo_exports, {
|
|
11391
|
+
IsAPublicKey: () => IsAPublicKey,
|
|
11392
|
+
IsAPublicKeyLookup: () => IsAPublicKeyLookup,
|
|
11393
|
+
IsAPublicKeySignature: () => IsAPublicKeySignature,
|
|
11394
|
+
IsAPublicKeyXY: () => IsAPublicKeyXY,
|
|
11395
|
+
PublicKeyFormats: () => PublicKeyFormats,
|
|
11396
|
+
isPublicKeySubject: () => isPublicKeySubject
|
|
11397
|
+
});
|
|
11398
|
+
var PublicKeyFormats = /* @__PURE__ */ ((PublicKeyFormats2) => {
|
|
11399
|
+
PublicKeyFormats2["DER"] = "DER";
|
|
11400
|
+
PublicKeyFormats2["XY"] = "XY";
|
|
11401
|
+
return PublicKeyFormats2;
|
|
11402
|
+
})(PublicKeyFormats || {});
|
|
11403
|
+
function IsAPublicKeyLookup(data) {
|
|
11404
|
+
if (!isMandatoryJSONObject(data))
|
|
11405
|
+
return false;
|
|
11406
|
+
return Array.isArray(data["publicKeys"]);
|
|
11407
|
+
}
|
|
11408
|
+
function IsAPublicKey(data) {
|
|
11409
|
+
if (!isMandatoryJSONObject(data))
|
|
11410
|
+
return false;
|
|
11411
|
+
if (data["@context"] !== void 0 && !isStringOrStringArray(data["@context"])) {
|
|
11412
|
+
return false;
|
|
11413
|
+
}
|
|
11414
|
+
if (!isPublicKeySubject(data["subject"]))
|
|
11415
|
+
return false;
|
|
11416
|
+
if (data["value"] !== void 0 && !isString(data["value"])) {
|
|
11417
|
+
return false;
|
|
11418
|
+
}
|
|
11419
|
+
if (data["value"] === void 0 && (data["x"] === void 0 || data["y"] === void 0)) {
|
|
11420
|
+
return false;
|
|
11421
|
+
}
|
|
11422
|
+
if (data["value"] !== void 0 && !isStringOrOIDInfo(data["algorithm"])) {
|
|
11423
|
+
return false;
|
|
11424
|
+
}
|
|
11425
|
+
if (data["certainty"] !== void 0 && (typeof data["certainty"] !== "number" || !Number.isFinite(data["certainty"]))) {
|
|
11426
|
+
return false;
|
|
11427
|
+
}
|
|
11428
|
+
if (data["type"] !== void 0 && !isStringOrOIDInfo(data["type"])) {
|
|
11429
|
+
return false;
|
|
11430
|
+
}
|
|
11431
|
+
if (data["encoding"] !== void 0 && typeof data["encoding"] !== "string") {
|
|
11432
|
+
return false;
|
|
11433
|
+
}
|
|
11434
|
+
if (data["signatures"] !== void 0 && (!Array.isArray(data["signatures"]) || !data["signatures"].every(IsAPublicKeySignature))) {
|
|
11435
|
+
return false;
|
|
11436
|
+
}
|
|
11437
|
+
return true;
|
|
11438
|
+
}
|
|
11439
|
+
function isPublicKeySubject(data) {
|
|
11440
|
+
if (data === void 0)
|
|
11441
|
+
return true;
|
|
11442
|
+
if (isStringOrStringArray(data))
|
|
11443
|
+
return true;
|
|
11444
|
+
if (!isMandatoryJSONObject(data))
|
|
11445
|
+
return false;
|
|
11446
|
+
return Object.values(data).every(
|
|
11447
|
+
(value) => typeof value === "string" || isStringOrStringArray(value)
|
|
11448
|
+
);
|
|
11449
|
+
}
|
|
11450
|
+
function IsAPublicKeySignature(data) {
|
|
11451
|
+
if (!isMandatoryJSONObject(data))
|
|
11452
|
+
return false;
|
|
11453
|
+
if (!isOptionalString(data["@id"]))
|
|
11454
|
+
return false;
|
|
11455
|
+
if (data["@context"] !== void 0 && !isStringOrStringArray(data["@context"]))
|
|
11456
|
+
return false;
|
|
11457
|
+
if (!isOptionalStringOrOIDInfo(data["algorithm"]))
|
|
11458
|
+
return false;
|
|
11459
|
+
if (!isOptionalString(data["format"]))
|
|
11460
|
+
return false;
|
|
11461
|
+
if (!isOptionalString(data["encoding"]))
|
|
11462
|
+
return false;
|
|
11463
|
+
if (data["value"] !== void 0 && !isString(data["value"]))
|
|
11464
|
+
return false;
|
|
11465
|
+
if (data["publicKey"] !== void 0 && !isEncodedValue(data["publicKey"]))
|
|
11466
|
+
return false;
|
|
11467
|
+
if (data["signature"] !== void 0 && !isEncodedValue(data["signature"]))
|
|
11468
|
+
return false;
|
|
11469
|
+
if (!isOptionalString(data["timestamp"]))
|
|
11470
|
+
return false;
|
|
11471
|
+
if (!isOptionalString(data["issuer"]))
|
|
11472
|
+
return false;
|
|
11473
|
+
if (!isOptionalString(data["signer"]))
|
|
11474
|
+
return false;
|
|
11475
|
+
if (!isOptionalString(data["notBefore"]))
|
|
11476
|
+
return false;
|
|
11477
|
+
if (!isOptionalString(data["notAfter"]))
|
|
11478
|
+
return false;
|
|
11479
|
+
if (!isOptionalStringArray(data["keyUsage"]))
|
|
11480
|
+
return false;
|
|
11481
|
+
if (data["operations"] !== void 0 && !isMandatoryJSONObject(data["operations"]))
|
|
11482
|
+
return false;
|
|
11483
|
+
if (data["comment"] !== void 0 && !isMandatoryJSONObject(data["comment"]))
|
|
11484
|
+
return false;
|
|
11485
|
+
return data["value"] !== void 0 || data["signature"] !== void 0 || data["algorithm"] !== void 0 || data["timestamp"] !== void 0 || data["issuer"] !== void 0 || data["signer"] !== void 0 || data["keyUsage"] !== void 0;
|
|
11486
|
+
}
|
|
11487
|
+
function IsAPublicKeyXY(data) {
|
|
11488
|
+
if (!IsAPublicKey(data))
|
|
11489
|
+
return false;
|
|
11490
|
+
if (!isString(data["x"])) {
|
|
11491
|
+
return false;
|
|
11492
|
+
}
|
|
11493
|
+
if (!isString(data["y"])) {
|
|
11494
|
+
return false;
|
|
11495
|
+
}
|
|
11496
|
+
return true;
|
|
11497
|
+
}
|
|
11342
11498
|
var MENNEKES_EDL40_XMLNS = "http://www.mennekes.de/Mennekes.EdlVerification.xsd";
|
|
11343
11499
|
var MENNEKES_EDL40_OBIS = "1-0:1.17.0*255";
|
|
11344
11500
|
var Mennekes = class {
|
|
@@ -11400,15 +11556,15 @@ var Mennekes = class {
|
|
|
11400
11556
|
return {
|
|
11401
11557
|
"@id": chargingStationId,
|
|
11402
11558
|
"description": { "en": "Mennekes EDL40 charging station" },
|
|
11403
|
-
"manufacturer": "MENNEKES",
|
|
11559
|
+
"manufacturer": { "name": "MENNEKES" },
|
|
11404
11560
|
"address": chargingProcess.siteAddress,
|
|
11405
11561
|
"EVSEs": [
|
|
11406
11562
|
{
|
|
11407
11563
|
"@id": evseId,
|
|
11408
|
-
"
|
|
11564
|
+
"energyMeters": [
|
|
11409
11565
|
{
|
|
11410
11566
|
"@id": meterId,
|
|
11411
|
-
"manufacturer": "MENNEKES",
|
|
11567
|
+
"manufacturer": { "name": "MENNEKES" },
|
|
11412
11568
|
"signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/MennekesCrypt01",
|
|
11413
11569
|
"publicKeys": [
|
|
11414
11570
|
{
|
|
@@ -11486,7 +11642,7 @@ var MennekesCrypt01 = class extends ACrypt {
|
|
|
11486
11642
|
}
|
|
11487
11643
|
async VerifyChargingSession(chargingSession) {
|
|
11488
11644
|
let sessionResult = "UnknownSessionFormat" /* UnknownSessionFormat */;
|
|
11489
|
-
for (const measurement of chargingSession.measurements) {
|
|
11645
|
+
for (const measurement of chargingSession.measurements ?? []) {
|
|
11490
11646
|
measurement.chargingSession = chargingSession;
|
|
11491
11647
|
if (measurement.values.length >= 2) {
|
|
11492
11648
|
sessionResult = "ValidSignature" /* ValidSignature */;
|
|
@@ -11553,8 +11709,6 @@ var MennekesCrypt01 = class extends ACrypt {
|
|
|
11553
11709
|
if (meter.publicKeys == null || meter.publicKeys.length === 0)
|
|
11554
11710
|
return setResult("PublicKeyNotFound" /* PublicKeyNotFound */);
|
|
11555
11711
|
const signatureExpected = measurementValue.signatures?.[0];
|
|
11556
|
-
if (signatureExpected.r == null || signatureExpected.s == null)
|
|
11557
|
-
return setResult("InvalidSignature" /* InvalidSignature */);
|
|
11558
11712
|
const signedData = buildMennekesSignatureData(
|
|
11559
11713
|
{
|
|
11560
11714
|
serverId: measurement.serverId,
|
|
@@ -11576,7 +11730,7 @@ var MennekesCrypt01 = class extends ACrypt {
|
|
|
11576
11730
|
secondIndex: measurementValue.secondsIndex ?? 0
|
|
11577
11731
|
}
|
|
11578
11732
|
);
|
|
11579
|
-
cryptoResult.signedData =
|
|
11733
|
+
cryptoResult.signedData = bytesToHex(signedData);
|
|
11580
11734
|
cryptoResult.logBytes = cryptoResult.signedData.substring(78, 82);
|
|
11581
11735
|
const signedDataBuffer = signedData.buffer.slice(
|
|
11582
11736
|
signedData.byteOffset,
|
|
@@ -11614,7 +11768,7 @@ var MennekesCrypt01 = class extends ACrypt {
|
|
|
11614
11768
|
PublicKeyDiv.innerHTML = result.publicKey?.match(/.{1,8}/g)?.join(" ") ?? "";
|
|
11615
11769
|
if (SignatureExpectedDiv.parentElement?.children[0])
|
|
11616
11770
|
SignatureExpectedDiv.parentElement.children[0].innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
|
|
11617
|
-
SignatureExpectedDiv.innerHTML = result.signature
|
|
11771
|
+
SignatureExpectedDiv.innerHTML = result.signature != null && result.signature.r.length > 0 && result.signature.s.length > 0 ? "r: " + (result.signature.r.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (result.signature.s.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "") : "";
|
|
11618
11772
|
SignatureCheckDiv.innerHTML = result.status === "ValidSignature" /* ValidSignature */ ? '<i class="fas fa-check-circle"></i><div id="description">' + this.chargy.GetLocalizedMessage("Valid signature") + "</div>" : '<i class="fas fa-times-circle"></i><div id="description">' + this.chargy.GetLocalizedMessage("Invalid signature") + "</div>";
|
|
11619
11773
|
return Promise.resolve(void 0);
|
|
11620
11774
|
}
|
|
@@ -11676,23 +11830,6 @@ function dateToMennekesLocalEpochSeconds(isoTimestamp) {
|
|
|
11676
11830
|
const offsetSeconds = sign * (Number(offsetMatch[2]) * 3600 + Number(offsetMatch[3]) * 60);
|
|
11677
11831
|
return Math.floor(date.getTime() / 1e3) + offsetSeconds;
|
|
11678
11832
|
}
|
|
11679
|
-
function cleanHex(hex) {
|
|
11680
|
-
return hex.replace(/\s+/g, "");
|
|
11681
|
-
}
|
|
11682
|
-
function hexToBytes(hex) {
|
|
11683
|
-
const cleanedHex = cleanHex(hex);
|
|
11684
|
-
if (cleanedHex.length % 2 !== 0)
|
|
11685
|
-
throw new Error("Hex strings must have even length!");
|
|
11686
|
-
if (!/^[0-9a-fA-F]*$/.test(cleanedHex))
|
|
11687
|
-
throw new Error("Invalid hexadecimal string!");
|
|
11688
|
-
const bytes = new Uint8Array(cleanedHex.length / 2);
|
|
11689
|
-
for (let index = 0; index < cleanedHex.length; index += 2)
|
|
11690
|
-
bytes[index / 2] = Number.parseInt(cleanedHex.substring(index, index + 2), 16);
|
|
11691
|
-
return bytes;
|
|
11692
|
-
}
|
|
11693
|
-
function bytesToHex2(bytes) {
|
|
11694
|
-
return Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
11695
|
-
}
|
|
11696
11833
|
function parseChargingProcessElement(chargingProcessElement) {
|
|
11697
11834
|
const siteAddressElement = child(chargingProcessElement, "SiteAddress");
|
|
11698
11835
|
return {
|
|
@@ -11830,7 +11967,7 @@ var OCMFv1_x = class extends ACrypt {
|
|
|
11830
11967
|
async VerifyChargingSession(chargingSession) {
|
|
11831
11968
|
let sessionResult = "Unvalidated" /* Unvalidated */;
|
|
11832
11969
|
{
|
|
11833
|
-
for (const measurement of chargingSession.measurements) {
|
|
11970
|
+
for (const measurement of chargingSession.measurements ?? []) {
|
|
11834
11971
|
measurement.chargingSession = chargingSession;
|
|
11835
11972
|
if (measurement.values.length > 1) {
|
|
11836
11973
|
for (const measurementValue of measurement.values) {
|
|
@@ -11978,7 +12115,7 @@ var OCMFv1_x = class extends ACrypt {
|
|
|
11978
12115
|
return new Error("Invalid measurement!");
|
|
11979
12116
|
}
|
|
11980
12117
|
{
|
|
11981
|
-
introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "OCMFCrypt01").replace("{cryptoAlgorithm}", measurementValue.ocmfDocument.publicKey != null && typeof measurementValue.ocmfDocument.publicKey !== "string" ? "(" + measurementValue.ocmfDocument.publicKey.algorithm + ") " : "");
|
|
12118
|
+
introDiv.innerHTML = this.chargy.GetLocalizedMessage("The following data of the charging session is relevant for metrological and legal metrological purposes and therefore part of the digital signature").replace("{methodName}", "OCMFCrypt01").replace("{cryptoAlgorithm}", measurementValue.ocmfDocument.publicKey != null && typeof measurementValue.ocmfDocument.publicKey !== "string" ? "(" + OIDInfo(measurementValue.ocmfDocument.publicKey.algorithm) + ") " : "");
|
|
11982
12119
|
}
|
|
11983
12120
|
{
|
|
11984
12121
|
if (PlainTextDiv.parentElement) {
|
|
@@ -12021,9 +12158,9 @@ var OCMFv1_x = class extends ACrypt {
|
|
|
12021
12158
|
}
|
|
12022
12159
|
if (measurementValue.ocmfDocument.publicKey != null) {
|
|
12023
12160
|
if (PublicKeyDiv.parentElement) {
|
|
12024
|
-
getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? this.chargy.GetLocalizedMessage("Public Key") : this.chargy.GetLocalizedMessage("Public Key") + " (" + measurementValue.ocmfDocument.publicKey.algorithm + ", " + measurementValue.ocmfDocument.publicKey.encoding + ")";
|
|
12161
|
+
getArrayLikeElement(PublicKeyDiv.parentElement.children, 0, "Missing public key header").innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? this.chargy.GetLocalizedMessage("Public Key") : this.chargy.GetLocalizedMessage("Public Key") + " (" + OIDInfo(measurementValue.ocmfDocument.publicKey.algorithm) + ", " + (measurementValue.ocmfDocument.publicKey.encoding ?? "-") + ")";
|
|
12025
12162
|
}
|
|
12026
|
-
PublicKeyDiv.innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? measurementValue.ocmfDocument.publicKey : "der: " + (measurementValue.ocmfDocument.publicKey.value
|
|
12163
|
+
PublicKeyDiv.innerHTML = typeof measurementValue.ocmfDocument.publicKey === "string" ? measurementValue.ocmfDocument.publicKey : "der: " + (measurementValue.ocmfDocument.publicKey.value.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br /><br />x: " + (measurementValue.ocmfDocument.publicKey.x.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />y: " + (measurementValue.ocmfDocument.publicKey.y.match(/.{1,8}/g)?.join(" ") ?? "-");
|
|
12027
12164
|
}
|
|
12028
12165
|
const publicKeySignatureContainer = PublicKeyDiv.parentElement?.children[3];
|
|
12029
12166
|
if (publicKeySignatureContainer !== void 0) {
|
|
@@ -12036,8 +12173,8 @@ var OCMFv1_x = class extends ACrypt {
|
|
|
12036
12173
|
signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
|
|
12037
12174
|
measurementValue.measurement.chargingSession.chargingStation,
|
|
12038
12175
|
measurementValue.measurement.chargingSession.EVSE,
|
|
12039
|
-
measurementValue.measurement.chargingSession.EVSE?.
|
|
12040
|
-
measurementValue.measurement.chargingSession.EVSE?.
|
|
12176
|
+
measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0),
|
|
12177
|
+
measurementValue.measurement.chargingSession.EVSE?.energyMeters?.at(0)?.publicKeys?.at(0),
|
|
12041
12178
|
signature
|
|
12042
12179
|
);
|
|
12043
12180
|
} catch {
|
|
@@ -12050,7 +12187,7 @@ var OCMFv1_x = class extends ACrypt {
|
|
|
12050
12187
|
if (SignatureExpectedDiv.parentElement) {
|
|
12051
12188
|
getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = this.chargy.GetLocalizedMessage("Expected signature") + " (rs, hex)";
|
|
12052
12189
|
}
|
|
12053
|
-
SignatureExpectedDiv.innerHTML = "der: " + (measurementValue.ocmfDocument.signature.SD.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br /><br />r: " + (measurementValue.ocmfDocument.signatureRS?.r
|
|
12190
|
+
SignatureExpectedDiv.innerHTML = "der: " + (measurementValue.ocmfDocument.signature.SD.match(/.{1,8}/g)?.join(" ") ?? "-") + "<br /><br />r: " + (measurementValue.ocmfDocument.signatureRS?.r.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "-") + "<br />s: " + (measurementValue.ocmfDocument.signatureRS?.s.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "-");
|
|
12054
12191
|
}
|
|
12055
12192
|
if (measurementValue.measurement.chargingSession.verificationResult) {
|
|
12056
12193
|
switch (measurementValue.measurement.chargingSession.verificationResult.status) {
|
|
@@ -12095,15 +12232,6 @@ var OCMF = class {
|
|
|
12095
12232
|
//#region (private) tryToParseOCMFv1_0(OCMFDataList, ContainerInfos?)
|
|
12096
12233
|
tryToParseOCMFv1_0(OCMFJSONDocuments, ContainerInfos) {
|
|
12097
12234
|
try {
|
|
12098
|
-
const containerInfos = asJSONObject(ContainerInfos) ?? {};
|
|
12099
|
-
const chargingStationInfo = asJSONObject(containerInfos["chargingStation"]);
|
|
12100
|
-
const evseInfo = asJSONObject(containerInfos["EVSE"]);
|
|
12101
|
-
const connectorInfo = asJSONObject(containerInfos["connector"]);
|
|
12102
|
-
const energyMeterInfo = asJSONObject(containerInfos["energyMeter"]);
|
|
12103
|
-
const chargingStationId = asString(containerInfos["ChargingStationId"]) ?? asString(chargingStationInfo?.["@id"]) ?? "DE*GEF*STATION*CHARGY*1";
|
|
12104
|
-
const evseId = asString(containerInfos["EVSEId"]) ?? asString(evseInfo?.["@id"]) ?? "DE*GEF*EVSE*CHARGY*1";
|
|
12105
|
-
const stationDescription = asJSONObject(chargingStationInfo?.["description"]);
|
|
12106
|
-
const evseDescription = asJSONObject(evseInfo?.["description"]);
|
|
12107
12235
|
const firstOCMDJSONDocument = getFirstArrayElement(OCMFJSONDocuments, "Missing first OCMF JSON document");
|
|
12108
12236
|
const formatVersion = firstOCMDJSONDocument.payload.FV;
|
|
12109
12237
|
const gatewayInformation = firstOCMDJSONDocument.payload.GI ?? firstOCMDJSONDocument.payload.VI;
|
|
@@ -12176,49 +12304,71 @@ var OCMF = class {
|
|
|
12176
12304
|
"gatewayVersion": gatewayVersion
|
|
12177
12305
|
},
|
|
12178
12306
|
// "chargingStationOperators": [{
|
|
12179
|
-
"chargingPools":
|
|
12180
|
-
|
|
12181
|
-
|
|
12182
|
-
|
|
12183
|
-
|
|
12184
|
-
|
|
12185
|
-
|
|
12186
|
-
|
|
12187
|
-
|
|
12188
|
-
|
|
12189
|
-
|
|
12190
|
-
|
|
12191
|
-
|
|
12192
|
-
|
|
12193
|
-
|
|
12194
|
-
|
|
12195
|
-
|
|
12196
|
-
|
|
12197
|
-
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12202
|
-
|
|
12203
|
-
|
|
12204
|
-
|
|
12205
|
-
|
|
12206
|
-
|
|
12207
|
-
|
|
12208
|
-
|
|
12209
|
-
|
|
12210
|
-
|
|
12211
|
-
|
|
12212
|
-
|
|
12213
|
-
|
|
12214
|
-
|
|
12215
|
-
}
|
|
12307
|
+
// "chargingPools": [{
|
|
12308
|
+
// "@id": "DE*GEF*POOL*CHARGY*1",
|
|
12309
|
+
// "description": { "en": "GraphDefined CHARGY Virtual Charging Pool 1" },
|
|
12310
|
+
// "chargingStations": [{
|
|
12311
|
+
// "@id": chargingStationId,
|
|
12312
|
+
// "description": stationDescription && Object.keys(stationDescription).length > 0
|
|
12313
|
+
// ? stationDescription
|
|
12314
|
+
// : { "en": "GraphDefined CHARGY Virtual Charging Station 1" },
|
|
12315
|
+
// // "firmware": {
|
|
12316
|
+
// // "version": chargyLib.asString(chargingStationInfo?.["softwareVersion"])
|
|
12317
|
+
// // ?? chargyLib.asString(chargingStationInfo?.["firmwareVersion"])
|
|
12318
|
+
// // },
|
|
12319
|
+
// "geoLocation": chargyLib.asJSONObject(chargingStationInfo?.["geoLocation"]) as chargyInterfaces.IGeoLocation | undefined,
|
|
12320
|
+
// "address": chargyLib.asJSONObject(chargingStationInfo?.["address"]) as chargyInterfaces.IAddress | undefined,
|
|
12321
|
+
// "EVSEs": [{
|
|
12322
|
+
// "@id": evseId,
|
|
12323
|
+
// "description": evseDescription && Object.keys(evseDescription).length > 0
|
|
12324
|
+
// ? evseDescription
|
|
12325
|
+
// : { "en": "GraphDefined CHARGY Virtual EVSE 1" },
|
|
12326
|
+
// "connectors": connectorInfo
|
|
12327
|
+
// ? [{
|
|
12328
|
+
// "type": chargyLib.asString(connectorInfo["type"]) ?? "",
|
|
12329
|
+
// "cable": {
|
|
12330
|
+
// "length": chargyLib.asNumber(connectorInfo["length"]) ?? 0,
|
|
12331
|
+
// "looses": chargyLib.asNumber(connectorInfo["looses"]) ?? 0
|
|
12332
|
+
// }
|
|
12333
|
+
// }]
|
|
12334
|
+
// : [],
|
|
12335
|
+
// "energyMeters": [{
|
|
12336
|
+
// "@id": effectiveMeterSerial,
|
|
12337
|
+
// // The signed OCMF payload values always win,
|
|
12338
|
+
// // the container infos only fill the gaps!
|
|
12339
|
+
// "manufacturer": {
|
|
12340
|
+
// "name": meterVendor ?? chargyLib.asString(energyMeterInfo?.["manufacturer"]),
|
|
12341
|
+
// "contact": {
|
|
12342
|
+
// "web": chargyLib.asString(energyMeterInfo?.["manufacturerURL"])
|
|
12343
|
+
// }
|
|
12344
|
+
// },
|
|
12345
|
+
// "model": {
|
|
12346
|
+
// "name": meterModel ?? chargyLib.asString(energyMeterInfo?.["model"]),
|
|
12347
|
+
// "url": chargyLib.asString(energyMeterInfo?.["modelURL"])
|
|
12348
|
+
// },
|
|
12349
|
+
// "hardware": {
|
|
12350
|
+
// "revision": chargyLib.asString(energyMeterInfo?.["hardwareVersion"])
|
|
12351
|
+
// },
|
|
12352
|
+
// "firmware": {
|
|
12353
|
+
// "version": meterFirmware ?? chargyLib.asString(energyMeterInfo?.["firmwareVersion"])
|
|
12354
|
+
// },
|
|
12355
|
+
// "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/OCMFv1.0+json",
|
|
12356
|
+
// "publicKeys": [{
|
|
12357
|
+
// "algorithm": "?",
|
|
12358
|
+
// "encoding": "?",
|
|
12359
|
+
// "format": "?",
|
|
12360
|
+
// "value": "?",
|
|
12361
|
+
// }]
|
|
12362
|
+
// }]
|
|
12363
|
+
// }],
|
|
12364
|
+
// }]
|
|
12365
|
+
// }],
|
|
12216
12366
|
"chargingSessions": [{
|
|
12217
12367
|
"@id": "1554181214441:-1965658344385548683:2",
|
|
12218
12368
|
"@context": "https://open.charging.cloud/contexts/SessionSignatureFormats/OCMFv1.0+json",
|
|
12219
12369
|
"begin": "?",
|
|
12220
12370
|
"end": "?",
|
|
12221
|
-
"EVSEId":
|
|
12371
|
+
//"EVSEId": evseId,
|
|
12222
12372
|
"authorizationStart": {
|
|
12223
12373
|
"@id": identificationData ?? "?",
|
|
12224
12374
|
"type": identificationType ?? "?",
|
|
@@ -12231,6 +12381,8 @@ var OCMF = class {
|
|
|
12231
12381
|
}],
|
|
12232
12382
|
"certainty": 1
|
|
12233
12383
|
};
|
|
12384
|
+
if (ContainerInfos?.chargingStations !== void 0)
|
|
12385
|
+
CTR.chargingStations = ContainerInfos.chargingStations;
|
|
12234
12386
|
const measurementsByKey = /* @__PURE__ */ new Map();
|
|
12235
12387
|
for (const ocmfJSONDocument of OCMFJSONDocuments) {
|
|
12236
12388
|
let inheritedReading = {};
|
|
@@ -12363,6 +12515,10 @@ var OCMF = class {
|
|
|
12363
12515
|
}
|
|
12364
12516
|
}
|
|
12365
12517
|
}
|
|
12518
|
+
if (ContainerInfos?.chargingStations !== void 0)
|
|
12519
|
+
CTR.chargingStations = ContainerInfos.chargingStations;
|
|
12520
|
+
if (ContainerInfos?.warnings !== void 0)
|
|
12521
|
+
CTR.warnings = [...CTR.warnings ?? [], ...ContainerInfos.warnings];
|
|
12366
12522
|
CTR.status = OCMFJSONDocuments.every((ocmfJSONDocument) => ocmfJSONDocument.validationStatus === "ValidSignature" /* ValidSignature */) ? "ValidSignature" /* ValidSignature */ : "InvalidSignature" /* InvalidSignature */;
|
|
12367
12523
|
if (CTR.chargingSessions != null && CTR.chargingSessions.length > 0 && CTR.chargingSessions[0]) {
|
|
12368
12524
|
CTR.begin = CTR.chargingSessions[0].begin;
|
|
@@ -12609,7 +12765,7 @@ var OCMF = class {
|
|
|
12609
12765
|
x: publicKeyXY.x,
|
|
12610
12766
|
y: publicKeyXY.y
|
|
12611
12767
|
};
|
|
12612
|
-
} else if (
|
|
12768
|
+
} else if (IsAPublicKeyXY(OCMFJSONDocument.publicKey)) {
|
|
12613
12769
|
publicKey = curve.keyFromPublic({
|
|
12614
12770
|
x: OCMFJSONDocument.publicKey.x,
|
|
12615
12771
|
y: OCMFJSONDocument.publicKey.y
|
|
@@ -12719,17 +12875,17 @@ var OCMF = class {
|
|
|
12719
12875
|
// Not an OCMF standard!
|
|
12720
12876
|
case "ECDSA-secp384r1-SHA384":
|
|
12721
12877
|
hashAlgorithm = "SHA384, 384 Bits, hex";
|
|
12722
|
-
hashValue = await
|
|
12878
|
+
hashValue = await sha384(plaintext);
|
|
12723
12879
|
break;
|
|
12724
12880
|
// Not an OCMF standard!
|
|
12725
12881
|
case "ECDSA-brainpool384r1-SHA384":
|
|
12726
12882
|
hashAlgorithm = "SHA384, 384 Bits, hex";
|
|
12727
|
-
hashValue = await
|
|
12883
|
+
hashValue = await sha384(plaintext);
|
|
12728
12884
|
break;
|
|
12729
12885
|
// Not an OCMF standard!
|
|
12730
12886
|
case "ECDSA-secp521r1-SHA512":
|
|
12731
12887
|
hashAlgorithm = "SHA512, 512 Bits, hex";
|
|
12732
|
-
hashValue = await
|
|
12888
|
+
hashValue = await sha512(plaintext);
|
|
12733
12889
|
break;
|
|
12734
12890
|
// ECDSA-secp256r1-SHA256
|
|
12735
12891
|
default:
|
|
@@ -12811,7 +12967,12 @@ var OCMF = class {
|
|
|
12811
12967
|
//#endregion
|
|
12812
12968
|
//#region TryToParseOCMFDocument (OCMFDocument, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
|
|
12813
12969
|
async TryToParseOCMFDocument(OCMFDocument, PublicKey, PublicKeyEncoding, ContainerInfos) {
|
|
12814
|
-
return this.TryToParseOCMFDocuments(
|
|
12970
|
+
return this.TryToParseOCMFDocuments(
|
|
12971
|
+
[OCMFDocument],
|
|
12972
|
+
PublicKey,
|
|
12973
|
+
PublicKeyEncoding,
|
|
12974
|
+
ContainerInfos
|
|
12975
|
+
);
|
|
12815
12976
|
}
|
|
12816
12977
|
//#endregion
|
|
12817
12978
|
//#region TryToParseOCMFDocuments(OCMFDocuments, PublicKey?, PublicKeyEncoding?, ContainerInfos?)
|
|
@@ -12932,13 +13093,16 @@ var OCPI = class {
|
|
|
12932
13093
|
const firstSignedData = asString(asJSONObject(signed_values[0])?.["signed_data"]);
|
|
12933
13094
|
if (firstSignedData != null && firstSignedData.length > 0) {
|
|
12934
13095
|
const placeInfo = asJSONObject(SomeJSON["placeInfo"]);
|
|
13096
|
+
const evseId = asString(placeInfo?.["evseId"]);
|
|
13097
|
+
const evseIdStr = asString(evseId) ?? "";
|
|
12935
13098
|
const geoLocation = asJSONObject(placeInfo?.["geoLocation"]);
|
|
12936
13099
|
const address = asJSONObject(placeInfo?.["address"]);
|
|
12937
13100
|
const geoLat = asNumber(geoLocation?.["lat"]);
|
|
12938
13101
|
const geoLon = asNumber(geoLocation?.["lon"]);
|
|
12939
13102
|
const containerInfos = {
|
|
12940
|
-
|
|
12941
|
-
|
|
13103
|
+
EVSEIds: [evseId],
|
|
13104
|
+
chargingStations: [{
|
|
13105
|
+
"@id": evseIdStr.substring(0, evseIdStr.lastIndexOf("*")),
|
|
12942
13106
|
geoLocation: geoLat !== void 0 && geoLon !== void 0 ? { lat: geoLat, lng: geoLon } : void 0,
|
|
12943
13107
|
address: address ? {
|
|
12944
13108
|
street: asString(address["street"]),
|
|
@@ -12946,8 +13110,8 @@ var OCPI = class {
|
|
|
12946
13110
|
city: asString(address["town"]),
|
|
12947
13111
|
country: asString(address["country"]) ?? ""
|
|
12948
13112
|
} : void 0
|
|
12949
|
-
}
|
|
12950
|
-
energyMeter:
|
|
13113
|
+
}]
|
|
13114
|
+
//energyMeter: chargyLib.asJSONObject(SomeJSON["meterInfo"])
|
|
12951
13115
|
};
|
|
12952
13116
|
return new OCMF(this.chargy).TryToParseOCMFDocument(
|
|
12953
13117
|
firstSignedData,
|
|
@@ -12962,7 +13126,7 @@ var OCPI = class {
|
|
|
12962
13126
|
const numberOfFormatChecks = 81;
|
|
12963
13127
|
let secondaryErrors = 0;
|
|
12964
13128
|
try {
|
|
12965
|
-
const chargingSessionId = SomeJSON["@id"];
|
|
13129
|
+
const chargingSessionId = asString(SomeJSON["@id"]);
|
|
12966
13130
|
const chargePointInfo = asJSONObject(SomeJSON["chargePointInfo"]);
|
|
12967
13131
|
const evseId = chargePointInfo?.["evseId"];
|
|
12968
13132
|
const placeInfo = asJSONObject(chargePointInfo?.["placeInfo"]);
|
|
@@ -13193,7 +13357,7 @@ var OCPI = class {
|
|
|
13193
13357
|
"value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
|
|
13194
13358
|
"signatures": [
|
|
13195
13359
|
{
|
|
13196
|
-
"
|
|
13360
|
+
"@id": "...",
|
|
13197
13361
|
"algorithm": "secp192r1",
|
|
13198
13362
|
"format": "DER",
|
|
13199
13363
|
"value": "????"
|
|
@@ -13258,7 +13422,7 @@ var OCPI = class {
|
|
|
13258
13422
|
// "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
|
|
13259
13423
|
// },
|
|
13260
13424
|
//"connectors": [ ],
|
|
13261
|
-
"
|
|
13425
|
+
"energyMeters": []
|
|
13262
13426
|
}
|
|
13263
13427
|
]
|
|
13264
13428
|
}
|
|
@@ -13273,29 +13437,29 @@ var OCPI = class {
|
|
|
13273
13437
|
return new Alfen(this.chargy).TryToParseALFENFormat(
|
|
13274
13438
|
signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
|
|
13275
13439
|
{
|
|
13276
|
-
|
|
13277
|
-
|
|
13278
|
-
},
|
|
13279
|
-
EVSEId:
|
|
13280
|
-
|
|
13281
|
-
|
|
13282
|
-
|
|
13283
|
-
|
|
13284
|
-
|
|
13285
|
-
|
|
13286
|
-
|
|
13287
|
-
|
|
13288
|
-
|
|
13289
|
-
|
|
13290
|
-
|
|
13291
|
-
|
|
13292
|
-
|
|
13293
|
-
|
|
13294
|
-
|
|
13295
|
-
},
|
|
13296
|
-
energyMeter:
|
|
13297
|
-
connector:
|
|
13298
|
-
chargingCosts:
|
|
13440
|
+
// chargingSessions: [{
|
|
13441
|
+
// "@id": chargingSessionId ?? ""
|
|
13442
|
+
// }],
|
|
13443
|
+
// // EVSEId: evseId,
|
|
13444
|
+
// chargingStations: [{
|
|
13445
|
+
// manufacturer: chargingStation_manufacturer,
|
|
13446
|
+
// type: chargingStation_type,
|
|
13447
|
+
// serialNumber: chargingStation_serialNumber,
|
|
13448
|
+
// firmwareVersion: chargingStation_controllerSoftwareVersion,
|
|
13449
|
+
// legalCompliance: {
|
|
13450
|
+
// conformity: [{
|
|
13451
|
+
// freeText: chargingStation_compliance
|
|
13452
|
+
// }],
|
|
13453
|
+
// calibration: [{
|
|
13454
|
+
// freeText: chargingStation_calibration
|
|
13455
|
+
// }]
|
|
13456
|
+
// },
|
|
13457
|
+
// geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
|
|
13458
|
+
// address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
|
|
13459
|
+
// }],
|
|
13460
|
+
// energyMeter: meterInfo,
|
|
13461
|
+
// connector: connectorInfo,
|
|
13462
|
+
// chargingCosts: chargingCostsInfo
|
|
13299
13463
|
}
|
|
13300
13464
|
);
|
|
13301
13465
|
}
|
|
@@ -13546,7 +13710,7 @@ var PCDFCrypt01 = class extends ACrypt {
|
|
|
13546
13710
|
async VerifyChargingSession(chargingSession) {
|
|
13547
13711
|
let sessionResult = "ValidSignature" /* ValidSignature */;
|
|
13548
13712
|
let valueCount = 0;
|
|
13549
|
-
for (const measurement of chargingSession.measurements) {
|
|
13713
|
+
for (const measurement of chargingSession.measurements ?? []) {
|
|
13550
13714
|
measurement.chargingSession = chargingSession;
|
|
13551
13715
|
for (const measurementValue of measurement.values) {
|
|
13552
13716
|
valueCount++;
|
|
@@ -13645,10 +13809,10 @@ var PCDF = class {
|
|
|
13645
13809
|
"de": "Porsche Charging Data Format Ladevorgang",
|
|
13646
13810
|
"en": "Porsche Charging Data Format charging session"
|
|
13647
13811
|
},
|
|
13648
|
-
"
|
|
13812
|
+
"contracts": [{
|
|
13649
13813
|
"@id": data.session.idTag,
|
|
13650
13814
|
"type": data.session.idTagType
|
|
13651
|
-
},
|
|
13815
|
+
}],
|
|
13652
13816
|
"pcdf": {
|
|
13653
13817
|
"chargingSessionCounter": data.chargingSessionCounter,
|
|
13654
13818
|
"timeValid": data.timeValid,
|
|
@@ -13667,11 +13831,17 @@ var PCDF = class {
|
|
|
13667
13831
|
"EVSEs": [{
|
|
13668
13832
|
"@id": virtualEVSEId,
|
|
13669
13833
|
"description": { "en": "GraphDefined CHARGY Virtual EVSE 1" },
|
|
13670
|
-
"
|
|
13834
|
+
"energyMeters": [{
|
|
13671
13835
|
"@id": meterId,
|
|
13672
|
-
"manufacturer":
|
|
13673
|
-
|
|
13674
|
-
|
|
13836
|
+
"manufacturer": {
|
|
13837
|
+
"name": "Porsche"
|
|
13838
|
+
},
|
|
13839
|
+
"model": {
|
|
13840
|
+
"name": data.dcMeterType === 0 ? "PES DCMeter EU" : "Unknown DC Meter"
|
|
13841
|
+
},
|
|
13842
|
+
"firmware": {
|
|
13843
|
+
"checksum": data.softwareChecksum
|
|
13844
|
+
},
|
|
13675
13845
|
"signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/PCDF+json",
|
|
13676
13846
|
"publicKeys": [{
|
|
13677
13847
|
"algorithm": "secp256r1",
|
|
@@ -13870,60 +14040,101 @@ var SAFEXML = class _SAFEXML {
|
|
|
13870
14040
|
constructor(chargy) {
|
|
13871
14041
|
this.chargy = chargy;
|
|
13872
14042
|
}
|
|
13873
|
-
static
|
|
13874
|
-
const
|
|
13875
|
-
|
|
13876
|
-
|
|
13877
|
-
|
|
13878
|
-
|
|
13879
|
-
|
|
13880
|
-
const geoLocationElement = getDirectChildByLocalName(chargingStationElement, "geoLocation");
|
|
13881
|
-
const latitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "latitude")) ?? "");
|
|
13882
|
-
const longitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement ?? chargingStationElement, "longitude")) ?? "");
|
|
13883
|
-
const geoLocation = Number.isFinite(latitude) && Number.isFinite(longitude) ? { lat: latitude, lng: longitude } : void 0;
|
|
13884
|
-
if (getDirectChildByLocalName(chargingStationElement, "EVSEs") !== void 0)
|
|
13885
|
-
throw new Error("The SAFE chargingStation XML element must contain EVSE directly and no EVSEs container element!");
|
|
13886
|
-
const evseElements = getDirectChildrenByLocalName(chargingStationElement, "EVSE");
|
|
13887
|
-
if (evseElements.length > 1)
|
|
13888
|
-
throw new Error("The SAFE chargingStation XML element must not contain more than one EVSE element!");
|
|
13889
|
-
const evseElement = evseElements.at(0);
|
|
13890
|
-
const evseAttributeId = evseElement?.getAttribute("id")?.trim();
|
|
13891
|
-
const evseTextId = getTrimmedTextContent(getDirectChildByLocalName(evseElement ?? chargingStationElement, "id"));
|
|
13892
|
-
const evseId = evseAttributeId != null && evseAttributeId.length > 0 ? evseAttributeId : evseTextId ?? "";
|
|
13893
|
-
const connectorElements = evseElement !== void 0 ? getDirectChildrenByLocalName(evseElement, "connector") : [];
|
|
13894
|
-
if (connectorElements.length > 1)
|
|
13895
|
-
throw new Error("The SAFE EVSE XML element must not contain more than one connector element!");
|
|
13896
|
-
const connectorElement = connectorElements.at(0);
|
|
13897
|
-
const connectorId = connectorElement?.getAttribute("id")?.trim();
|
|
13898
|
-
const connectorType = getTrimmedTextContent(getDirectChildByLocalName(connectorElement ?? evseElement ?? chargingStationElement, "type"));
|
|
13899
|
-
const connector = connectorType != null && connectorType.length > 0 ? { "@id": connectorId, type: connectorType, looses: 0 } : void 0;
|
|
13900
|
-
const parsedEVSE = evseElement !== void 0 ? {
|
|
13901
|
-
"@id": evseId,
|
|
13902
|
-
"description": parseDescription(evseElement),
|
|
13903
|
-
"meters": [],
|
|
13904
|
-
"connector": connector
|
|
13905
|
-
} : void 0;
|
|
13906
|
-
const chargingStation = {
|
|
13907
|
-
"@id": chargingStationId ?? "",
|
|
13908
|
-
"description": parseDescription(chargingStationElement),
|
|
13909
|
-
"firmwareVersion": softwareVersion,
|
|
13910
|
-
"softwareVersion": softwareVersion,
|
|
13911
|
-
"geoLocation": geoLocation,
|
|
13912
|
-
"EVSE": parsedEVSE
|
|
14043
|
+
static ParseContainerInfos(XMLDocument, chargy) {
|
|
14044
|
+
const containerInfos = {};
|
|
14045
|
+
const addWarning = (message) => {
|
|
14046
|
+
containerInfos.warnings ??= [];
|
|
14047
|
+
containerInfos.warnings.push(
|
|
14048
|
+
CreateWarning(chargy.GetMultilanguageText(message))
|
|
14049
|
+
);
|
|
13913
14050
|
};
|
|
13914
|
-
|
|
13915
|
-
|
|
13916
|
-
|
|
13917
|
-
|
|
13918
|
-
"
|
|
13919
|
-
|
|
14051
|
+
const chargingStationElements = getElementsByLocalName(XMLDocument, "chargingStation");
|
|
14052
|
+
if (chargingStationElements.length == 0)
|
|
14053
|
+
return containerInfos;
|
|
14054
|
+
if (chargingStationElements.length > 1)
|
|
14055
|
+
addWarning("Only one chargingStation element is allowed within the given SAFE XML container!");
|
|
14056
|
+
if (chargingStationElements[0] === void 0) {
|
|
14057
|
+
addWarning("The chargingStation element within the given SAFE XML container is invalid!");
|
|
14058
|
+
return containerInfos;
|
|
14059
|
+
}
|
|
14060
|
+
const chargingStationElement = chargingStationElements[0];
|
|
14061
|
+
const chargingStationId = chargingStationElement.getAttribute("id")?.trim();
|
|
14062
|
+
if (chargingStationId === void 0 || chargingStationId.length == 0) {
|
|
14063
|
+
addWarning("The chargingStation identifier within the given SAFE XML container is invalid!");
|
|
14064
|
+
return containerInfos;
|
|
14065
|
+
}
|
|
14066
|
+
const chargingStation = {
|
|
14067
|
+
"@id": chargingStationId
|
|
13920
14068
|
};
|
|
14069
|
+
containerInfos.chargingStations = [chargingStation];
|
|
14070
|
+
const description = parseDescription(chargingStationElement);
|
|
14071
|
+
if (description !== void 0)
|
|
14072
|
+
chargingStation.description = description;
|
|
14073
|
+
const firmware = getDirectChildByLocalName(chargingStationElement, "firmware");
|
|
14074
|
+
if (firmware !== void 0) {
|
|
14075
|
+
chargingStation.firmware = {};
|
|
14076
|
+
const firmwareVersion = getTrimmedTextContent(getDirectChildByLocalName(firmware, "version"));
|
|
14077
|
+
if (firmwareVersion !== void 0)
|
|
14078
|
+
chargingStation.firmware.version = firmwareVersion;
|
|
14079
|
+
const firmwareChecksum = getTrimmedTextContent(getDirectChildByLocalName(firmware, "checksum"));
|
|
14080
|
+
if (firmwareChecksum !== void 0)
|
|
14081
|
+
chargingStation.firmware.checksum = firmwareChecksum;
|
|
14082
|
+
if (Object.keys(chargingStation.firmware).length === 0)
|
|
14083
|
+
delete chargingStation.firmware;
|
|
14084
|
+
}
|
|
14085
|
+
const geoLocationElement = getDirectChildByLocalName(chargingStationElement, "geoLocation");
|
|
14086
|
+
if (geoLocationElement !== void 0) {
|
|
14087
|
+
const latitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement, "latitude")) ?? "");
|
|
14088
|
+
const longitude = Number.parseFloat(getTrimmedTextContent(getDirectChildByLocalName(geoLocationElement, "longitude")) ?? "");
|
|
14089
|
+
const geoLocation = Number.isFinite(latitude) && Number.isFinite(longitude) ? { lat: latitude, lng: longitude } : void 0;
|
|
14090
|
+
if (geoLocation !== void 0)
|
|
14091
|
+
chargingStation.geoLocation = geoLocation;
|
|
14092
|
+
}
|
|
14093
|
+
const evseElements = getElementsByLocalName(chargingStationElement, "EVSE");
|
|
14094
|
+
if (evseElements.length > 1)
|
|
14095
|
+
addWarning("Only one EVSE element is allowed within the given SAFE XML chargingStation element!");
|
|
14096
|
+
if (evseElements[0] === void 0) {
|
|
14097
|
+
addWarning("The EVSE element within the given SAFE XML chargingStation element is invalid!");
|
|
14098
|
+
return containerInfos;
|
|
14099
|
+
}
|
|
14100
|
+
const evseElement = evseElements[0];
|
|
14101
|
+
const evseId = evseElement.getAttribute("id")?.trim();
|
|
14102
|
+
if (evseId !== void 0 && evseId.length > 0) {
|
|
14103
|
+
const evse = {
|
|
14104
|
+
"@id": evseId
|
|
14105
|
+
};
|
|
14106
|
+
chargingStation.EVSEs = [evse];
|
|
14107
|
+
const evseDescription = parseDescription(evseElement);
|
|
14108
|
+
if (evseDescription !== void 0)
|
|
14109
|
+
evse.description = evseDescription;
|
|
14110
|
+
const connectorElements = getElementsByLocalName(evseElement, "connector");
|
|
14111
|
+
if (connectorElements.length > 1)
|
|
14112
|
+
addWarning("Only one connector element is allowed within the given SAFE XML EVSE element!");
|
|
14113
|
+
if (connectorElements[0] === void 0) {
|
|
14114
|
+
addWarning("The connector element within the given SAFE XML EVSE element is invalid!");
|
|
14115
|
+
return containerInfos;
|
|
14116
|
+
}
|
|
14117
|
+
const connectorElement = connectorElements[0];
|
|
14118
|
+
const connector = {};
|
|
14119
|
+
const connectorId = connectorElement.getAttribute("id")?.trim();
|
|
14120
|
+
if (connectorId != null && connectorId.length > 0)
|
|
14121
|
+
connector["@id"] = connectorId;
|
|
14122
|
+
const connectorType = getTrimmedTextContent(getDirectChildByLocalName(connectorElement, "type"));
|
|
14123
|
+
if (connectorType !== void 0 && connectorType.length > 0)
|
|
14124
|
+
connector.type = connectorType;
|
|
14125
|
+
if (Object.keys(connector).length > 0)
|
|
14126
|
+
evse.connectors = [connector];
|
|
14127
|
+
}
|
|
14128
|
+
return containerInfos;
|
|
13921
14129
|
}
|
|
13922
14130
|
//#region tryToParseSAFEXML(XMLDocument)
|
|
13923
14131
|
async tryToParseSAFEXML(XMLDocument) {
|
|
13924
14132
|
try {
|
|
13925
14133
|
if (XMLDocument.documentElement.nodeName === "values" || XMLDocument.documentElement.localName === "values") {
|
|
13926
|
-
const safeXMLContext = _SAFEXML.
|
|
14134
|
+
const safeXMLContext = _SAFEXML.ParseContainerInfos(
|
|
14135
|
+
XMLDocument,
|
|
14136
|
+
this.chargy
|
|
14137
|
+
);
|
|
13927
14138
|
const signedDataValues = new Array();
|
|
13928
14139
|
let commonSignedDataFormat = "";
|
|
13929
14140
|
let commonSignedDataEncoding = "";
|
|
@@ -14319,10 +14530,10 @@ var ChargeIT = class {
|
|
|
14319
14530
|
CTR["@id"] = lastMeterValue["transactionId"];
|
|
14320
14531
|
CTR.begin = this.chargy.moment.unix(firstMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
|
|
14321
14532
|
CTR.end = this.chargy.moment.unix(lastMeterValue["measuredValue"]["timestampLocal"]["timestamp"]).utc().format();
|
|
14322
|
-
CTR.
|
|
14533
|
+
CTR.contracts = [{
|
|
14323
14534
|
"@id": firstMeterValue["contract"]["id"],
|
|
14324
14535
|
"@context": firstMeterValue["contract"]["type"]
|
|
14325
|
-
};
|
|
14536
|
+
}];
|
|
14326
14537
|
CTR.chargingStationOperators = [{
|
|
14327
14538
|
"@id": "chargeITmobilityCSO",
|
|
14328
14539
|
"description": { "de": "chargeIT mobility GmbH - Charging Station Operator Services" },
|
|
@@ -14380,7 +14591,9 @@ var ChargeIT = class {
|
|
|
14380
14591
|
// "description": {
|
|
14381
14592
|
// "de": "GraphDefined Charging Station - CI-Tests Pool 3 / Station A"
|
|
14382
14593
|
// },
|
|
14383
|
-
"
|
|
14594
|
+
"firmware": {
|
|
14595
|
+
"version": firstMeterValue["chargePoint"]["softwareVersion"]
|
|
14596
|
+
},
|
|
14384
14597
|
"geoLocation": { "lat": asNumber(geoLocation["lat"]) ?? 0, "lng": asNumber(geoLocation["lon"]) ?? 0 },
|
|
14385
14598
|
"address": {
|
|
14386
14599
|
"street": asString(address["street"]),
|
|
@@ -14395,22 +14608,32 @@ var ChargeIT = class {
|
|
|
14395
14608
|
// "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
|
|
14396
14609
|
// },
|
|
14397
14610
|
// "connectors": [{ }],
|
|
14398
|
-
"
|
|
14611
|
+
"energyMeters": [
|
|
14399
14612
|
{
|
|
14400
14613
|
"@id": firstMeterValue["meterInfo"]["meterId"],
|
|
14401
|
-
"manufacturer":
|
|
14402
|
-
|
|
14403
|
-
|
|
14404
|
-
|
|
14405
|
-
|
|
14614
|
+
"manufacturer": {
|
|
14615
|
+
"name": firstMeterValue["meterInfo"]["manufacturer"],
|
|
14616
|
+
"contact": {
|
|
14617
|
+
"web": "https://www.emh-metering.de"
|
|
14618
|
+
}
|
|
14619
|
+
},
|
|
14620
|
+
"model": {
|
|
14621
|
+
"name": firstMeterValue["meterInfo"]["type"]
|
|
14622
|
+
},
|
|
14623
|
+
"hardware": {
|
|
14624
|
+
"revision": "1.0"
|
|
14625
|
+
},
|
|
14626
|
+
"firmware": {
|
|
14627
|
+
"version": firstMeterValue["meterInfo"]["firmwareVersion"]
|
|
14628
|
+
},
|
|
14406
14629
|
"signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
|
|
14407
14630
|
"publicKeys": [
|
|
14408
14631
|
{
|
|
14409
14632
|
"algorithm": "secp192r1",
|
|
14410
14633
|
"format": "DER",
|
|
14411
14634
|
"encoding": "hex",
|
|
14412
|
-
"value": firstMeterValue["meterInfo"]["publicKey"].startsWith("04") ? firstMeterValue["meterInfo"]["publicKey"] : "04" + firstMeterValue["meterInfo"]["publicKey"]
|
|
14413
|
-
"signatures":
|
|
14635
|
+
"value": firstMeterValue["meterInfo"]["publicKey"].startsWith("04") ? firstMeterValue["meterInfo"]["publicKey"] : "04" + firstMeterValue["meterInfo"]["publicKey"]
|
|
14636
|
+
//"signatures": firstMeterValue["meterInfo"]["publicKeySignatures"]
|
|
14414
14637
|
}
|
|
14415
14638
|
]
|
|
14416
14639
|
}
|
|
@@ -14719,10 +14942,10 @@ var ChargeIT = class {
|
|
|
14719
14942
|
"value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
|
|
14720
14943
|
"signatures": [
|
|
14721
14944
|
{
|
|
14722
|
-
"
|
|
14945
|
+
"@id": "...",
|
|
14723
14946
|
"algorithm": "secp192r1",
|
|
14724
14947
|
"format": "DER",
|
|
14725
|
-
"value": "
|
|
14948
|
+
"value": "..."
|
|
14726
14949
|
}
|
|
14727
14950
|
]
|
|
14728
14951
|
},
|
|
@@ -14781,7 +15004,7 @@ var ChargeIT = class {
|
|
|
14781
15004
|
// "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
|
|
14782
15005
|
// },
|
|
14783
15006
|
//"connectors": [ ],
|
|
14784
|
-
"
|
|
15007
|
+
"energyMeters": []
|
|
14785
15008
|
}
|
|
14786
15009
|
]
|
|
14787
15010
|
}
|
|
@@ -14803,11 +15026,15 @@ var ChargeIT = class {
|
|
|
14803
15026
|
return new Alfen(this.chargy).TryToParseALFENFormat(
|
|
14804
15027
|
signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
|
|
14805
15028
|
{
|
|
14806
|
-
|
|
14807
|
-
|
|
15029
|
+
chargingStations: [{
|
|
15030
|
+
"@id": "?",
|
|
14808
15031
|
geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
|
|
14809
|
-
address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
|
|
14810
|
-
|
|
15032
|
+
address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country },
|
|
15033
|
+
EVSEs: [{
|
|
15034
|
+
"@id": evseId,
|
|
15035
|
+
energyMeters: []
|
|
15036
|
+
}]
|
|
15037
|
+
}]
|
|
14811
15038
|
}
|
|
14812
15039
|
);
|
|
14813
15040
|
}
|
|
@@ -14815,11 +15042,15 @@ var ChargeIT = class {
|
|
|
14815
15042
|
return new Alfen(this.chargy).TryToParseALFENFormat(
|
|
14816
15043
|
signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
|
|
14817
15044
|
{
|
|
14818
|
-
|
|
14819
|
-
|
|
15045
|
+
chargingStations: [{
|
|
15046
|
+
"@id": "?",
|
|
14820
15047
|
geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
|
|
14821
|
-
address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
|
|
14822
|
-
|
|
15048
|
+
address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country },
|
|
15049
|
+
EVSEs: [{
|
|
15050
|
+
"@id": evseId,
|
|
15051
|
+
energyMeters: []
|
|
15052
|
+
}]
|
|
15053
|
+
}]
|
|
14823
15054
|
}
|
|
14824
15055
|
);
|
|
14825
15056
|
if (signedMeterValueContext === oldChargeITMeterValueFormat)
|
|
@@ -14894,7 +15125,6 @@ var ChargeIT = class {
|
|
|
14894
15125
|
const connectorInfo_type = connectorInfo?.["type"];
|
|
14895
15126
|
const connectorInfo_losses = connectorInfo?.["losses"];
|
|
14896
15127
|
const chargingTariffs = SomeJSON["chargingTariffs"];
|
|
14897
|
-
const chargingPeriods = SomeJSON["chargingPeriods"];
|
|
14898
15128
|
const totalCosts = asJSONObject(SomeJSON["totalCosts"]);
|
|
14899
15129
|
const totalCosts_total = totalCosts?.["total"];
|
|
14900
15130
|
const totalCosts_currency = totalCosts?.["currency"];
|
|
@@ -15087,10 +15317,10 @@ var ChargeIT = class {
|
|
|
15087
15317
|
"value": "042313b9e469612b4ca06981bfdecb226e234632b01d84b6a814f63a114b7762c34ddce2e6853395b7a0f87275f63ffe3c",
|
|
15088
15318
|
"signatures": [
|
|
15089
15319
|
{
|
|
15090
|
-
"
|
|
15320
|
+
"@id": "...",
|
|
15091
15321
|
"algorithm": "secp192r1",
|
|
15092
15322
|
"format": "DER",
|
|
15093
|
-
"value": "
|
|
15323
|
+
"value": "..."
|
|
15094
15324
|
}
|
|
15095
15325
|
]
|
|
15096
15326
|
},
|
|
@@ -15152,7 +15382,7 @@ var ChargeIT = class {
|
|
|
15152
15382
|
// "de": "GraphDefined EVSE - CI-Tests Pool 3 / Station A / EVSE 1"
|
|
15153
15383
|
// },
|
|
15154
15384
|
//"connectors": [ ],
|
|
15155
|
-
"
|
|
15385
|
+
"energyMeters": []
|
|
15156
15386
|
}
|
|
15157
15387
|
]
|
|
15158
15388
|
}
|
|
@@ -15169,31 +15399,31 @@ var ChargeIT = class {
|
|
|
15169
15399
|
return new Alfen(this.chargy).TryToParseALFENFormat(
|
|
15170
15400
|
signedMeterValues.map((value) => asString(asJSONObject(value)?.["payload"]) ?? ""),
|
|
15171
15401
|
{
|
|
15172
|
-
chargingSession: {
|
|
15173
|
-
|
|
15174
|
-
},
|
|
15175
|
-
EVSEId:
|
|
15176
|
-
chargingStation: {
|
|
15177
|
-
|
|
15178
|
-
|
|
15179
|
-
|
|
15180
|
-
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
|
|
15184
|
-
|
|
15185
|
-
|
|
15186
|
-
|
|
15187
|
-
|
|
15188
|
-
|
|
15189
|
-
|
|
15190
|
-
|
|
15191
|
-
},
|
|
15192
|
-
energyMeter:
|
|
15193
|
-
connector:
|
|
15194
|
-
chargingTariffs,
|
|
15195
|
-
chargingPeriods,
|
|
15196
|
-
totalCosts
|
|
15402
|
+
// chargingSession: {
|
|
15403
|
+
// "@id": chargingSessionId
|
|
15404
|
+
// },
|
|
15405
|
+
// EVSEId: evseId,
|
|
15406
|
+
// chargingStation: {
|
|
15407
|
+
// manufacturer: chargingStation_manufacturer,
|
|
15408
|
+
// type: chargingStation_type,
|
|
15409
|
+
// serialNumber: chargingStation_serialNumber,
|
|
15410
|
+
// firmwareVersion: chargingStation_controllerSoftwareVersion,
|
|
15411
|
+
// legalCompliance: {
|
|
15412
|
+
// conformity: [{
|
|
15413
|
+
// freeText: chargingStation_compliance
|
|
15414
|
+
// }],
|
|
15415
|
+
// calibration: [{
|
|
15416
|
+
// freeText: chargingStation_calibration
|
|
15417
|
+
// }]
|
|
15418
|
+
// },
|
|
15419
|
+
// geoLocation: { "lat": geoLocation_lat, "lng": geoLocation_lon },
|
|
15420
|
+
// address: { "street": address_street, "postalCode": address_zipCode, "city": address_town, "country": address_country }
|
|
15421
|
+
// },
|
|
15422
|
+
// energyMeter: meterInfo,
|
|
15423
|
+
// connector: connectorInfo,
|
|
15424
|
+
// chargingTariffs: chargingTariffs,
|
|
15425
|
+
// chargingPeriods: chargingPeriods,
|
|
15426
|
+
// totalCosts: totalCosts
|
|
15197
15427
|
}
|
|
15198
15428
|
);
|
|
15199
15429
|
}
|
|
@@ -15325,12 +15555,18 @@ var ChargePoint = class {
|
|
|
15325
15555
|
"address": asJSONObject(SomeJSON["address"]),
|
|
15326
15556
|
"EVSEs": [{
|
|
15327
15557
|
"@id": evseId,
|
|
15328
|
-
"
|
|
15558
|
+
"energyMeters": [{
|
|
15329
15559
|
"@id": meterSerial,
|
|
15330
|
-
"manufacturer":
|
|
15331
|
-
|
|
15332
|
-
|
|
15333
|
-
|
|
15560
|
+
"manufacturer": {
|
|
15561
|
+
"name": "Carlo Gavazzi",
|
|
15562
|
+
"contact": {
|
|
15563
|
+
"web": "https://www.gavazziautomation.com"
|
|
15564
|
+
}
|
|
15565
|
+
},
|
|
15566
|
+
"model": {
|
|
15567
|
+
"name": "EM340-DIN.AV2.3.X.S1.X",
|
|
15568
|
+
"url": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
|
|
15569
|
+
}
|
|
15334
15570
|
// "signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
|
|
15335
15571
|
// "publicKeys": [
|
|
15336
15572
|
// {
|
|
@@ -15485,12 +15721,18 @@ var ChargePoint = class {
|
|
|
15485
15721
|
"address": asJSONObject(SomeJSON["address"]),
|
|
15486
15722
|
"EVSEs": [{
|
|
15487
15723
|
"@id": evseId,
|
|
15488
|
-
"
|
|
15724
|
+
"energyMeters": [{
|
|
15489
15725
|
"@id": meterSerial,
|
|
15490
|
-
"manufacturer":
|
|
15491
|
-
|
|
15492
|
-
|
|
15493
|
-
|
|
15726
|
+
"manufacturer": {
|
|
15727
|
+
"name": "Carlo Gavazzi",
|
|
15728
|
+
"contact": {
|
|
15729
|
+
"web": "https://www.gavazziautomation.com"
|
|
15730
|
+
}
|
|
15731
|
+
},
|
|
15732
|
+
"model": {
|
|
15733
|
+
"name": "EM340-DIN.AV2.3.X.S1.X",
|
|
15734
|
+
"url": "https://www.gavazziautomation.com/fileadmin/images/PIM/DATASHEET/ENG/EM340_DS_ENG.pdf"
|
|
15735
|
+
},
|
|
15494
15736
|
"signatureFormat": "https://open.charging.cloud/contexts/EnergyMeterSignatureFormats/EMHCrypt01",
|
|
15495
15737
|
"signatureInfos": {
|
|
15496
15738
|
"hash": "SHA256",
|
|
@@ -15502,7 +15744,8 @@ var ChargePoint = class {
|
|
|
15502
15744
|
"publicKeys": [{
|
|
15503
15745
|
"algorithm": "secp224k1",
|
|
15504
15746
|
"format": "DER",
|
|
15505
|
-
"encoding": "hex"
|
|
15747
|
+
"encoding": "hex",
|
|
15748
|
+
"value": "..."
|
|
15506
15749
|
}]
|
|
15507
15750
|
}]
|
|
15508
15751
|
}]
|
|
@@ -15604,7 +15847,7 @@ var ChargePointCrypt01 = class extends ACrypt {
|
|
|
15604
15847
|
s: ASN1Signature.s.toString(16)
|
|
15605
15848
|
};
|
|
15606
15849
|
}
|
|
15607
|
-
const publicKeyId = chargingSession.EVSEId
|
|
15850
|
+
const publicKeyId = chargingSession.EVSEId?.replace(/:/g, "").replace(/-/g, "_");
|
|
15608
15851
|
const publicKeys = [];
|
|
15609
15852
|
if (chargingSession.ctr.publicKeys != null) {
|
|
15610
15853
|
for (const publicKeyInfo of chargingSession.ctr.publicKeys) {
|
|
@@ -15635,8 +15878,8 @@ var ChargePointCrypt01 = class extends ACrypt {
|
|
|
15635
15878
|
sha225Value = sha225Value ?? (BigInt("0x" + await sha256(plainText)) >> BigInt(31)).toString(16);
|
|
15636
15879
|
sessionResult = this.curve224k1.validate(
|
|
15637
15880
|
BigInt("0x" + sha225Value),
|
|
15638
|
-
BigInt("0x" +
|
|
15639
|
-
BigInt("0x" +
|
|
15881
|
+
BigInt("0x" + chargingSession.signature.r),
|
|
15882
|
+
BigInt("0x" + chargingSession.signature.s),
|
|
15640
15883
|
[
|
|
15641
15884
|
BigInt("0x" + publicKey.value.slice(2, 58)),
|
|
15642
15885
|
BigInt("0x" + publicKey.value.slice(58, 114))
|
|
@@ -15684,7 +15927,7 @@ var ChargePointCrypt01 = class extends ACrypt {
|
|
|
15684
15927
|
}
|
|
15685
15928
|
}
|
|
15686
15929
|
}
|
|
15687
|
-
for (const measurement of chargingSession.measurements) {
|
|
15930
|
+
for (const measurement of chargingSession.measurements ?? []) {
|
|
15688
15931
|
measurement.chargingSession = chargingSession;
|
|
15689
15932
|
if (measurement.values.length > 1) {
|
|
15690
15933
|
for (const measurementValue of measurement.values) {
|
|
@@ -15827,8 +16070,8 @@ var ChargePointCrypt01 = class extends ACrypt {
|
|
|
15827
16070
|
signatureDiv.innerHTML = await this.chargy.CheckMeterPublicKeySignature(
|
|
15828
16071
|
measurementValue.measurement.chargingSession.chargingStation,
|
|
15829
16072
|
measurementValue.measurement.chargingSession.EVSE,
|
|
15830
|
-
measurementValue.measurement.chargingSession.EVSE?.
|
|
15831
|
-
measurementValue.measurement.chargingSession.EVSE?.
|
|
16073
|
+
measurementValue.measurement.chargingSession.EVSE?.energyMeters?.[0],
|
|
16074
|
+
measurementValue.measurement.chargingSession.EVSE?.energyMeters?.[0]?.publicKeys?.[0],
|
|
15832
16075
|
signature
|
|
15833
16076
|
);
|
|
15834
16077
|
} catch {
|
|
@@ -15841,7 +16084,7 @@ var ChargePointCrypt01 = class extends ACrypt {
|
|
|
15841
16084
|
getArrayLikeElement(SignatureExpectedDiv.parentElement.children, 0, "Missing expected signature header").innerHTML = "Erwartete Signatur (secrrct.sign, rs, hex)";
|
|
15842
16085
|
}
|
|
15843
16086
|
if (typeof chargingSession.signature != "string")
|
|
15844
|
-
SignatureExpectedDiv.innerHTML = "r: " + (chargingSession.signature.r
|
|
16087
|
+
SignatureExpectedDiv.innerHTML = "r: " + (chargingSession.signature.r.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "") + "<br />s: " + (chargingSession.signature.s.toLowerCase().padStart(56, "0").match(/.{1,8}/g)?.join(" ") ?? "");
|
|
15845
16088
|
else if (chargingSession.signature)
|
|
15846
16089
|
SignatureExpectedDiv.innerHTML = chargingSession.signature.toLowerCase().match(/.{1,8}/g)?.join(" ") ?? "-";
|
|
15847
16090
|
}
|
|
@@ -15879,7 +16122,8 @@ var IChargeTransparencyRecord_exports = {};
|
|
|
15879
16122
|
__export(IChargeTransparencyRecord_exports, {
|
|
15880
16123
|
CloneCTR: () => CloneCTR,
|
|
15881
16124
|
IsAChargeTransparencyRecord: () => IsAChargeTransparencyRecord,
|
|
15882
|
-
IsASessionCryptoResult: () => IsASessionCryptoResult
|
|
16125
|
+
IsASessionCryptoResult: () => IsASessionCryptoResult,
|
|
16126
|
+
toSessionVerificationResults: () => toSessionVerificationResults
|
|
15883
16127
|
});
|
|
15884
16128
|
function IsAChargeTransparencyRecord(data) {
|
|
15885
16129
|
if (!isMandatoryJSONObject(data))
|
|
@@ -15897,7 +16141,7 @@ function CloneCTR(CTR) {
|
|
|
15897
16141
|
const clonedCTR = JSON.parse(JSON.stringify(CTR));
|
|
15898
16142
|
if (clonedCTR.chargingSessions) {
|
|
15899
16143
|
for (const session of clonedCTR.chargingSessions) {
|
|
15900
|
-
for (const measurement of session.measurements) {
|
|
16144
|
+
for (const measurement of session.measurements ?? []) {
|
|
15901
16145
|
for (const value of measurement.values) {
|
|
15902
16146
|
if (typeof value.value === "string" || typeof value.value === "number")
|
|
15903
16147
|
value.value = new Decimal(value.value);
|
|
@@ -15907,6 +16151,16 @@ function CloneCTR(CTR) {
|
|
|
15907
16151
|
}
|
|
15908
16152
|
return clonedCTR;
|
|
15909
16153
|
}
|
|
16154
|
+
function toSessionVerificationResults(CTR, noRecordsMessage = { "en": "No charge transparency records found!" }) {
|
|
16155
|
+
const verificationResults = (CTR.chargingSessions ?? []).map((session) => session.verificationResult).filter(isISessionCryptoResult1);
|
|
16156
|
+
if (verificationResults.length > 0)
|
|
16157
|
+
return verificationResults;
|
|
16158
|
+
return {
|
|
16159
|
+
status: "Unvalidated" /* Unvalidated */,
|
|
16160
|
+
message: noRecordsMessage,
|
|
16161
|
+
certainty: 0
|
|
16162
|
+
};
|
|
16163
|
+
}
|
|
15910
16164
|
|
|
15911
16165
|
// src/interfaces/IChargeTransparencyLiveLink.ts
|
|
15912
16166
|
var IChargeTransparencyLiveLink_exports = {};
|
|
@@ -15937,43 +16191,11 @@ function isTransport(data) {
|
|
|
15937
16191
|
function IsAChargeTransparencyLiveLink(data) {
|
|
15938
16192
|
if (!isMandatoryJSONObject(data))
|
|
15939
16193
|
return false;
|
|
15940
|
-
return data["@context"] === ChargeTransparencyLiveLinkContext && (data["timestamp"] === void 0 || data["timestamp"] === null || typeof data["timestamp"] === "string") && (data["description"] === void 0 ||
|
|
16194
|
+
return data["@context"] === ChargeTransparencyLiveLinkContext && (data["timestamp"] === void 0 || data["timestamp"] === null || typeof data["timestamp"] === "string") && (data["description"] === void 0 || isI18NString(data["description"])) && (data["imageURLs"] === void 0 || Array.isArray(data["imageURLs"]) && data["imageURLs"].every((value) => typeof value === "string")) && (data["geoLocation"] === void 0 || isGeoLocation(data["geoLocation"])) && (data["connector"] === void 0 || isConnector(data["connector"])) && (data["transports"] === void 0 || Array.isArray(data["transports"]) && data["transports"].every(isTransport)) && (data["signatures"] === void 0 || Array.isArray(data["signatures"]));
|
|
15941
16195
|
}
|
|
15942
16196
|
function isTOTPConfig(data) {
|
|
15943
16197
|
return isObject(data) && typeof data["initialSharedSecret"] === "string" && typeof data["timeStep"] === "number";
|
|
15944
16198
|
}
|
|
15945
|
-
|
|
15946
|
-
// src/interfaces/IPublicKeyInfo.ts
|
|
15947
|
-
var IPublicKeyInfo_exports = {};
|
|
15948
|
-
__export(IPublicKeyInfo_exports, {
|
|
15949
|
-
IsAPublicKeyInfo: () => IsAPublicKeyInfo,
|
|
15950
|
-
IsAPublicKeyLookup: () => IsAPublicKeyLookup
|
|
15951
|
-
});
|
|
15952
|
-
function IsAPublicKeyLookup(data) {
|
|
15953
|
-
if (!isMandatoryJSONObject(data))
|
|
15954
|
-
return false;
|
|
15955
|
-
return Array.isArray(data["publicKeys"]);
|
|
15956
|
-
}
|
|
15957
|
-
function IsAPublicKeyInfo(data) {
|
|
15958
|
-
if (!isMandatoryJSONObject(data))
|
|
15959
|
-
return false;
|
|
15960
|
-
if (!isStringOrStringArray(data["@context"])) return false;
|
|
15961
|
-
if (!isString(data["value"])) return false;
|
|
15962
|
-
if (!isStringOrOIDInfo(data["algorithm"])) return false;
|
|
15963
|
-
if (data["certainty"] !== void 0 && (typeof data["certainty"] !== "number" || !Number.isFinite(data["certainty"]))) {
|
|
15964
|
-
return false;
|
|
15965
|
-
}
|
|
15966
|
-
if (data["type"] !== void 0 && !isStringOrOIDInfo(data["type"])) {
|
|
15967
|
-
return false;
|
|
15968
|
-
}
|
|
15969
|
-
if (data["encoding"] !== void 0 && typeof data["encoding"] !== "string") {
|
|
15970
|
-
return false;
|
|
15971
|
-
}
|
|
15972
|
-
if (data["signatures"] !== void 0 && !Array.isArray(data["signatures"])) {
|
|
15973
|
-
return false;
|
|
15974
|
-
}
|
|
15975
|
-
return true;
|
|
15976
|
-
}
|
|
15977
16199
|
function isRecord(value) {
|
|
15978
16200
|
return typeof value === "object" && value !== null;
|
|
15979
16201
|
}
|
|
@@ -16231,45 +16453,6 @@ var Chargy = class {
|
|
|
16231
16453
|
return fileName.substring(0, lastDot);
|
|
16232
16454
|
return fileName;
|
|
16233
16455
|
}
|
|
16234
|
-
tryExtractChargeTransparencyTextFromURL(qrText) {
|
|
16235
|
-
if (!qrText.startsWith("http://") && !qrText.startsWith("https://"))
|
|
16236
|
-
return qrText;
|
|
16237
|
-
try {
|
|
16238
|
-
const url = new URL(qrText);
|
|
16239
|
-
const candidates = [
|
|
16240
|
-
url.hash.startsWith("#") ? url.hash.substring(1) : url.hash,
|
|
16241
|
-
url.searchParams.get("data"),
|
|
16242
|
-
url.searchParams.get("content"),
|
|
16243
|
-
url.searchParams.get("ctr"),
|
|
16244
|
-
url.searchParams.get("record"),
|
|
16245
|
-
url.searchParams.get("payload"),
|
|
16246
|
-
url.searchParams.get("q")
|
|
16247
|
-
];
|
|
16248
|
-
for (const candidate of candidates) {
|
|
16249
|
-
const decodedCandidate = candidate != null ? decodeURIComponent(candidate).trim() : "";
|
|
16250
|
-
if (decodedCandidate.startsWith("<?xml") || decodedCandidate.startsWith("<values") || decodedCandidate.startsWith("{") || decodedCandidate.startsWith("[") || decodedCandidate.startsWith("OCMF") || decodedCandidate.startsWith("AP;")) {
|
|
16251
|
-
return decodedCandidate;
|
|
16252
|
-
}
|
|
16253
|
-
}
|
|
16254
|
-
} catch {
|
|
16255
|
-
console.log("Invalid URL in QR code: " + qrText);
|
|
16256
|
-
}
|
|
16257
|
-
return qrText;
|
|
16258
|
-
}
|
|
16259
|
-
tryExtractSignedDataTextFromXML(qrText) {
|
|
16260
|
-
const trimmedQRCodeText = qrText.trim();
|
|
16261
|
-
if (!trimmedQRCodeText.startsWith("<?xml") && !trimmedQRCodeText.startsWith("<"))
|
|
16262
|
-
return qrText;
|
|
16263
|
-
try {
|
|
16264
|
-
const xmlDocument = new DOMParser().parseFromString(trimmedQRCodeText, "text/xml");
|
|
16265
|
-
const signedDataValues = getElementsByLocalName(xmlDocument, "signedData").filter((signedData) => (signedData.getAttribute("format") ?? "").trim().toLowerCase() === "alfen").map((signedData) => signedData.textContent.trim()).filter((signedData) => signedData.startsWith("AP;"));
|
|
16266
|
-
if (signedDataValues.length > 0)
|
|
16267
|
-
return signedDataValues.join("\n");
|
|
16268
|
-
} catch {
|
|
16269
|
-
console.log("Error parsing XML content from QR code: " + qrText);
|
|
16270
|
-
}
|
|
16271
|
-
return qrText;
|
|
16272
|
-
}
|
|
16273
16456
|
//#region Public key methods...
|
|
16274
16457
|
PublicKeyIdFromFileName(fileName) {
|
|
16275
16458
|
return (fileName.includes(".") ? fileName.substring(0, fileName.indexOf(".")) : fileName).replace(/[-_]?public[-_]?key/i, "");
|
|
@@ -16355,25 +16538,70 @@ var Chargy = class {
|
|
|
16355
16538
|
}
|
|
16356
16539
|
//#endregion
|
|
16357
16540
|
//#region QR code image files...
|
|
16358
|
-
|
|
16359
|
-
|
|
16360
|
-
|
|
16361
|
-
|
|
16541
|
+
normalizeMIMEType(mimeType) {
|
|
16542
|
+
return mimeType?.split(";")[0]?.trim().toLowerCase();
|
|
16543
|
+
}
|
|
16544
|
+
getQRCodeImageMIMETypeFromFileName(fileName) {
|
|
16545
|
+
fileName = fileName.toLowerCase();
|
|
16546
|
+
if (fileName.endsWith(".png"))
|
|
16547
|
+
return "image/png";
|
|
16548
|
+
if (fileName.endsWith(".jpeg"))
|
|
16549
|
+
return "image/jpeg";
|
|
16550
|
+
if (fileName.endsWith(".jpg"))
|
|
16551
|
+
return "image/jpg";
|
|
16552
|
+
if (fileName.endsWith(".gif"))
|
|
16553
|
+
return "image/gif";
|
|
16554
|
+
if (fileName.endsWith(".webp"))
|
|
16555
|
+
return "image/webp";
|
|
16556
|
+
if (fileName.endsWith(".bmp"))
|
|
16557
|
+
return "image/bmp";
|
|
16558
|
+
if (fileName.endsWith(".svg"))
|
|
16559
|
+
return "image/svg+xml";
|
|
16560
|
+
return void 0;
|
|
16561
|
+
}
|
|
16562
|
+
getQRCodeImageMIMEType(fileInfo, mimeType) {
|
|
16563
|
+
const detectedMIMEType = this.normalizeMIMEType(mimeType);
|
|
16564
|
+
const declaredMIMEType = this.normalizeMIMEType(fileInfo.type);
|
|
16565
|
+
const fileNameMIMEType = this.getQRCodeImageMIMETypeFromFileName(fileInfo.name);
|
|
16566
|
+
if (this.isSupportedQRCodeImageFileType(detectedMIMEType))
|
|
16567
|
+
return detectedMIMEType;
|
|
16568
|
+
if (this.isSupportedQRCodeImageFileType(declaredMIMEType))
|
|
16569
|
+
return declaredMIMEType;
|
|
16570
|
+
if (fileNameMIMEType !== void 0)
|
|
16571
|
+
return fileNameMIMEType;
|
|
16572
|
+
return detectedMIMEType ?? declaredMIMEType;
|
|
16573
|
+
}
|
|
16574
|
+
isSupportedQRCodeImageFileType(MIMEType) {
|
|
16575
|
+
switch (MIMEType) {
|
|
16576
|
+
case void 0:
|
|
16577
|
+
return false;
|
|
16578
|
+
case "image/png":
|
|
16579
|
+
case "image/jpeg":
|
|
16580
|
+
case "image/jpg":
|
|
16581
|
+
case "image/gif":
|
|
16582
|
+
case "image/webp":
|
|
16583
|
+
case "image/bmp":
|
|
16584
|
+
case "image/svg":
|
|
16585
|
+
case "image/svg+xml":
|
|
16586
|
+
return true;
|
|
16587
|
+
}
|
|
16588
|
+
return false;
|
|
16362
16589
|
}
|
|
16363
16590
|
async expandQRCodeImageFiles(FileInfos) {
|
|
16364
16591
|
const expandedFileInfos = new Array();
|
|
16365
16592
|
for (const fileInfo of FileInfos) {
|
|
16366
|
-
|
|
16367
|
-
|
|
16593
|
+
const mimeType = this.getQRCodeImageMIMEType(fileInfo);
|
|
16594
|
+
if (fileInfo.data != null && this.isSupportedQRCodeImageFileType(mimeType)) {
|
|
16595
|
+
const qrText = await readQRCodeTextFromImage(
|
|
16596
|
+
fileInfo.data,
|
|
16597
|
+
mimeType
|
|
16598
|
+
);
|
|
16368
16599
|
if (qrText != null) {
|
|
16369
|
-
const extractedText = this.tryExtractSignedDataTextFromXML(
|
|
16370
|
-
this.tryExtractChargeTransparencyTextFromURL(qrText)
|
|
16371
|
-
);
|
|
16372
16600
|
expandedFileInfos.push({
|
|
16373
|
-
name: this.textFileNameForQRCodeContent(fileInfo.name,
|
|
16601
|
+
name: this.textFileNameForQRCodeContent(fileInfo.name, qrText),
|
|
16374
16602
|
path: fileInfo.path,
|
|
16375
16603
|
type: "text/plain",
|
|
16376
|
-
data: new TextEncoder().encode(
|
|
16604
|
+
data: new TextEncoder().encode(qrText),
|
|
16377
16605
|
info: "Text extracted from QR code image"
|
|
16378
16606
|
});
|
|
16379
16607
|
continue;
|
|
@@ -16523,11 +16751,13 @@ var Chargy = class {
|
|
|
16523
16751
|
"@id": evse["@id"],
|
|
16524
16752
|
"description": evse.description,
|
|
16525
16753
|
"sockets": evseView["sockets"],
|
|
16526
|
-
"
|
|
16754
|
+
"energyMeter": {
|
|
16527
16755
|
"@id": meter["@id"],
|
|
16528
16756
|
"vendor": meterView["vendor"],
|
|
16529
16757
|
"model": meter.model,
|
|
16530
|
-
"
|
|
16758
|
+
"firmware": {
|
|
16759
|
+
"version": meter.firmware?.version
|
|
16760
|
+
},
|
|
16531
16761
|
"signatureFormat": meter.signatureFormat,
|
|
16532
16762
|
"publicKey": {
|
|
16533
16763
|
"algorithm": publicKey.algorithm,
|
|
@@ -16570,55 +16800,42 @@ var Chargy = class {
|
|
|
16570
16800
|
if (FileInfo.data != null && FileInfo.data.byteLength > 0) {
|
|
16571
16801
|
try {
|
|
16572
16802
|
const filetype = await fileTypeFromBuffer(FileInfo.data);
|
|
16573
|
-
|
|
16574
|
-
|
|
16575
|
-
|
|
16576
|
-
|
|
16577
|
-
|
|
16578
|
-
|
|
16579
|
-
|
|
16580
|
-
|
|
16581
|
-
else if (FileInfo.name.endsWith(".chargy"))
|
|
16582
|
-
expandedFileInfos.push({
|
|
16583
|
-
name: FileInfo.name,
|
|
16584
|
-
data: FileInfo.data,
|
|
16585
|
-
info: ".chargy file"
|
|
16586
|
-
});
|
|
16587
|
-
else
|
|
16588
|
-
expandedFileInfos.push({
|
|
16589
|
-
name: FileInfo.name,
|
|
16590
|
-
data: FileInfo.data,
|
|
16591
|
-
exception: "Unknown file type!"
|
|
16592
|
-
});
|
|
16803
|
+
const mimeType = this.getQRCodeImageMIMEType(FileInfo, filetype?.mime);
|
|
16804
|
+
if (this.isSupportedQRCodeImageFileType(mimeType)) {
|
|
16805
|
+
expandedFileInfos.push({
|
|
16806
|
+
name: FileInfo.name,
|
|
16807
|
+
data: FileInfo.data,
|
|
16808
|
+
type: FileInfo.type ?? mimeType,
|
|
16809
|
+
info: "QR code image file"
|
|
16810
|
+
});
|
|
16593
16811
|
continue;
|
|
16594
|
-
} else if (
|
|
16812
|
+
} else if (FileInfo.name.endsWith(".chargy")) {
|
|
16595
16813
|
expandedFileInfos.push({
|
|
16596
16814
|
name: FileInfo.name,
|
|
16597
16815
|
data: FileInfo.data,
|
|
16598
|
-
info: "
|
|
16816
|
+
info: ".chargy file"
|
|
16599
16817
|
});
|
|
16600
16818
|
continue;
|
|
16601
|
-
} else if (
|
|
16819
|
+
} else if (mimeType === "text/xml" || mimeType === "application/xml") {
|
|
16602
16820
|
expandedFileInfos.push({
|
|
16603
16821
|
name: FileInfo.name,
|
|
16604
16822
|
data: FileInfo.data,
|
|
16605
|
-
info: "
|
|
16823
|
+
info: "XML file"
|
|
16606
16824
|
});
|
|
16607
16825
|
continue;
|
|
16608
|
-
} else if (
|
|
16826
|
+
} else if (mimeType === "text/json" || mimeType === "application/json") {
|
|
16609
16827
|
expandedFileInfos.push({
|
|
16610
16828
|
name: FileInfo.name,
|
|
16611
16829
|
data: FileInfo.data,
|
|
16612
|
-
|
|
16613
|
-
info: "QR code image file"
|
|
16830
|
+
info: "JSON file"
|
|
16614
16831
|
});
|
|
16615
16832
|
continue;
|
|
16616
|
-
} else if (
|
|
16833
|
+
} else if (mimeType === "application/zip" || mimeType === "application/x-bzip2" || mimeType === "application/gzip" || mimeType === "application/x-tar") {
|
|
16617
16834
|
try {
|
|
16618
16835
|
const compressedFiles = await this.extractArchive(
|
|
16619
16836
|
FileInfo.name,
|
|
16620
16837
|
FileInfo.data,
|
|
16621
|
-
|
|
16838
|
+
mimeType
|
|
16622
16839
|
);
|
|
16623
16840
|
if (compressedFiles.length == 0)
|
|
16624
16841
|
continue;
|
|
@@ -16690,6 +16907,12 @@ var Chargy = class {
|
|
|
16690
16907
|
}
|
|
16691
16908
|
continue;
|
|
16692
16909
|
}
|
|
16910
|
+
expandedFileInfos.push({
|
|
16911
|
+
name: FileInfo.name,
|
|
16912
|
+
data: FileInfo.data,
|
|
16913
|
+
exception: "Unknown file type!"
|
|
16914
|
+
});
|
|
16915
|
+
continue;
|
|
16693
16916
|
} catch (exception) {
|
|
16694
16917
|
expandedFileInfos.push({
|
|
16695
16918
|
name: FileInfo.name,
|
|
@@ -16845,11 +17068,12 @@ var Chargy = class {
|
|
|
16845
17068
|
//#endregion
|
|
16846
17069
|
//#region DetectAndConvertContentFormat(FileInfos)
|
|
16847
17070
|
async DetectAndConvertContentFormat(FileInfos) {
|
|
16848
|
-
if (FileInfos.length == 0)
|
|
16849
|
-
|
|
16850
|
-
|
|
16851
|
-
|
|
16852
|
-
|
|
17071
|
+
if (FileInfos.length == 0)
|
|
17072
|
+
return {
|
|
17073
|
+
status: "NoChargeTransparencyRecordsFound" /* NoChargeTransparencyRecordsFound */,
|
|
17074
|
+
message: this.GetMultilanguageText("No charge transparency records found!"),
|
|
17075
|
+
certainty: 0
|
|
17076
|
+
};
|
|
16853
17077
|
let expandedFiles = new Array();
|
|
16854
17078
|
const processedFiles = new Array();
|
|
16855
17079
|
if (FileInfos.length > 0) {
|
|
@@ -17022,42 +17246,40 @@ var Chargy = class {
|
|
|
17022
17246
|
} else if (textContent.startsWith("{") && textContent.endsWith("}")) {
|
|
17023
17247
|
try {
|
|
17024
17248
|
const JSONContent = JSON.parse(textContent);
|
|
17025
|
-
if (typeof JSONContent !== "object" || JSONContent
|
|
17026
|
-
throw new Error("Parsed JSON content is not
|
|
17027
|
-
|
|
17028
|
-
|
|
17029
|
-
|
|
17030
|
-
|
|
17249
|
+
if (JSONContent === null || typeof JSONContent !== "object" || !isMandatoryJSONObject(JSONContent))
|
|
17250
|
+
throw new Error("Parsed JSON content is not a JSON object!");
|
|
17251
|
+
const JSONContext = JSONContent["@context"];
|
|
17252
|
+
if (IsAChargeTransparencyLiveLink(JSONContent)) {
|
|
17253
|
+
JSONContent.timestamp ??= (/* @__PURE__ */ new Date()).toISOString();
|
|
17254
|
+
processedFile.result = JSONContent;
|
|
17255
|
+
} else if (isMandatoryString(JSONContext)) {
|
|
17256
|
+
if (JSONContext.startsWith("https://open.charging.cloud/contexts/CTR+json"))
|
|
17031
17257
|
processedFile.result = JSONContent;
|
|
17032
|
-
|
|
17033
|
-
|
|
17034
|
-
|
|
17035
|
-
|
|
17036
|
-
processedFile.result = JSONContent;
|
|
17037
|
-
else if (JSONContext.startsWith("https://www.lichtblick.de/contexts/charging-station-json") || JSONContext.startsWith("https://www.eneco.com/contexts/charging-station-json") || JSONContext.startsWith("https://www.chargeit-mobility.com/contexts/charging-station-json")) {
|
|
17038
|
-
processedFile.result = new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent);
|
|
17039
|
-
}
|
|
17040
|
-
} else {
|
|
17041
|
-
const results = [
|
|
17042
|
-
new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent),
|
|
17043
|
-
new ChargePoint(this).TryToParseChargepointFormat(JSONContent),
|
|
17044
|
-
await new OCPI(this).tryToParseOCPIFormat(JSONContent)
|
|
17045
|
-
];
|
|
17046
|
-
const filteredResults = results.filter((ctr) => {
|
|
17047
|
-
return isISessionCryptoResult1(ctr);
|
|
17048
|
-
});
|
|
17049
|
-
const sortedResults = filteredResults.sort((ctr1, ctr2) => {
|
|
17050
|
-
if (ctr1.certainty > ctr2.certainty) {
|
|
17051
|
-
return -1;
|
|
17052
|
-
}
|
|
17053
|
-
if (ctr1.certainty < ctr2.certainty) {
|
|
17054
|
-
return 1;
|
|
17055
|
-
}
|
|
17056
|
-
return 0;
|
|
17057
|
-
});
|
|
17058
|
-
if (sortedResults.length >= 1 && sortedResults[0])
|
|
17059
|
-
processedFile.result = sortedResults[0];
|
|
17258
|
+
else if (JSONContext.startsWith("https://open.charging.cloud/contexts/publicKey+json"))
|
|
17259
|
+
processedFile.result = JSONContent;
|
|
17260
|
+
else if (JSONContext.startsWith("https://www.lichtblick.de/contexts/charging-station-json") || JSONContext.startsWith("https://www.eneco.com/contexts/charging-station-json") || JSONContext.startsWith("https://www.chargeit-mobility.com/contexts/charging-station-json")) {
|
|
17261
|
+
processedFile.result = new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent);
|
|
17060
17262
|
}
|
|
17263
|
+
} else {
|
|
17264
|
+
const results = [
|
|
17265
|
+
new ChargeIT(this).TryToParseChargeITContainerFormat(JSONContent),
|
|
17266
|
+
new ChargePoint(this).TryToParseChargepointFormat(JSONContent),
|
|
17267
|
+
await new OCPI(this).tryToParseOCPIFormat(JSONContent)
|
|
17268
|
+
];
|
|
17269
|
+
const filteredResults = results.filter((ctr) => {
|
|
17270
|
+
return isISessionCryptoResult1(ctr);
|
|
17271
|
+
});
|
|
17272
|
+
const sortedResults = filteredResults.sort((ctr1, ctr2) => {
|
|
17273
|
+
if (ctr1.certainty > ctr2.certainty) {
|
|
17274
|
+
return -1;
|
|
17275
|
+
}
|
|
17276
|
+
if (ctr1.certainty < ctr2.certainty) {
|
|
17277
|
+
return 1;
|
|
17278
|
+
}
|
|
17279
|
+
return 0;
|
|
17280
|
+
});
|
|
17281
|
+
if (sortedResults.length >= 1 && sortedResults[0])
|
|
17282
|
+
processedFile.result = sortedResults[0];
|
|
17061
17283
|
}
|
|
17062
17284
|
} catch (exception) {
|
|
17063
17285
|
processedFile.result = {
|
|
@@ -17101,7 +17323,7 @@ var Chargy = class {
|
|
|
17101
17323
|
if (processedFileResult.end != null && processedFileResult.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < processedFileResult.end))
|
|
17102
17324
|
mergedCTR.end = processedFileResult.end;
|
|
17103
17325
|
mergedCTR.description ??= processedFileResult.description;
|
|
17104
|
-
mergedCTR.
|
|
17326
|
+
mergedCTR.contracts ??= processedFileResult.contracts;
|
|
17105
17327
|
if (!mergedCTR.chargingStationOperators)
|
|
17106
17328
|
mergedCTR.chargingStationOperators = processedFileResult.chargingStationOperators;
|
|
17107
17329
|
else if (processedFileResult.chargingStationOperators)
|
|
@@ -17132,7 +17354,7 @@ var Chargy = class {
|
|
|
17132
17354
|
else if (processedFileResult.mediationServices)
|
|
17133
17355
|
for (const mediationService of processedFileResult.mediationServices)
|
|
17134
17356
|
mergedCTR.mediationServices.push(mediationService);
|
|
17135
|
-
} else if (
|
|
17357
|
+
} else if (IsAPublicKey(processedFileResult)) {
|
|
17136
17358
|
mergedCTR.publicKeys ??= new Array();
|
|
17137
17359
|
mergedCTR.publicKeys.push(processedFileResult);
|
|
17138
17360
|
} else if (IsAPublicKeyLookup(processedFileResult)) {
|
|
@@ -17180,11 +17402,11 @@ var Chargy = class {
|
|
|
17180
17402
|
if (chargingPool.chargingStations) {
|
|
17181
17403
|
for (const chargingStation of chargingPool.chargingStations) {
|
|
17182
17404
|
this.chargingStations.push(chargingStation);
|
|
17183
|
-
for (const EVSE of chargingStation.EVSEs) {
|
|
17405
|
+
for (const EVSE of chargingStation.EVSEs ?? []) {
|
|
17184
17406
|
EVSE.chargingStation = chargingStation;
|
|
17185
17407
|
EVSE.chargingStationId = chargingStation["@id"];
|
|
17186
17408
|
this.EVSEs.push(EVSE);
|
|
17187
|
-
for (const meter of EVSE.
|
|
17409
|
+
for (const meter of EVSE.energyMeters ?? []) {
|
|
17188
17410
|
meter.EVSE = EVSE;
|
|
17189
17411
|
meter.EVSEId = EVSE["@id"];
|
|
17190
17412
|
meter.chargingStation = chargingStation;
|
|
@@ -17199,11 +17421,11 @@ var Chargy = class {
|
|
|
17199
17421
|
if (chargingStationOperator.chargingStations) {
|
|
17200
17422
|
for (const chargingStation of chargingStationOperator.chargingStations) {
|
|
17201
17423
|
this.chargingStations.push(chargingStation);
|
|
17202
|
-
for (const EVSE of chargingStation.EVSEs) {
|
|
17424
|
+
for (const EVSE of chargingStation.EVSEs ?? []) {
|
|
17203
17425
|
EVSE.chargingStation = chargingStation;
|
|
17204
17426
|
EVSE.chargingStationId = chargingStation["@id"];
|
|
17205
17427
|
this.EVSEs.push(EVSE);
|
|
17206
|
-
for (const meter of EVSE.
|
|
17428
|
+
for (const meter of EVSE.energyMeters ?? []) {
|
|
17207
17429
|
meter.EVSE = EVSE;
|
|
17208
17430
|
meter.EVSEId = EVSE["@id"];
|
|
17209
17431
|
meter.chargingStation = chargingStation;
|
|
@@ -17216,7 +17438,7 @@ var Chargy = class {
|
|
|
17216
17438
|
if (chargingStationOperator.EVSEs) {
|
|
17217
17439
|
for (const EVSE of chargingStationOperator.EVSEs) {
|
|
17218
17440
|
this.EVSEs.push(EVSE);
|
|
17219
|
-
for (const meter of EVSE.
|
|
17441
|
+
for (const meter of EVSE.energyMeters ?? []) {
|
|
17220
17442
|
meter.EVSE = EVSE;
|
|
17221
17443
|
meter.EVSEId = EVSE["@id"];
|
|
17222
17444
|
this.meters.push(meter);
|
|
@@ -17231,11 +17453,11 @@ var Chargy = class {
|
|
|
17231
17453
|
if (chargingPool.chargingStations) {
|
|
17232
17454
|
for (const chargingStation of chargingPool.chargingStations) {
|
|
17233
17455
|
this.chargingStations.push(chargingStation);
|
|
17234
|
-
for (const EVSE of chargingStation.EVSEs) {
|
|
17456
|
+
for (const EVSE of chargingStation.EVSEs ?? []) {
|
|
17235
17457
|
EVSE.chargingStation = chargingStation;
|
|
17236
17458
|
EVSE.chargingStationId = chargingStation["@id"];
|
|
17237
17459
|
this.EVSEs.push(EVSE);
|
|
17238
|
-
for (const meter of EVSE.
|
|
17460
|
+
for (const meter of EVSE.energyMeters ?? []) {
|
|
17239
17461
|
meter.EVSE = EVSE;
|
|
17240
17462
|
meter.EVSEId = EVSE["@id"];
|
|
17241
17463
|
meter.chargingStation = chargingStation;
|
|
@@ -17250,11 +17472,11 @@ var Chargy = class {
|
|
|
17250
17472
|
if (this.internalCTR.chargingStations) {
|
|
17251
17473
|
for (const chargingStation of this.internalCTR.chargingStations) {
|
|
17252
17474
|
this.chargingStations.push(chargingStation);
|
|
17253
|
-
for (const EVSE of chargingStation.EVSEs) {
|
|
17475
|
+
for (const EVSE of chargingStation.EVSEs ?? []) {
|
|
17254
17476
|
EVSE.chargingStation = chargingStation;
|
|
17255
17477
|
EVSE.chargingStationId = chargingStation["@id"];
|
|
17256
17478
|
this.EVSEs.push(EVSE);
|
|
17257
|
-
for (const meter of EVSE.
|
|
17479
|
+
for (const meter of EVSE.energyMeters ?? []) {
|
|
17258
17480
|
meter.EVSE = EVSE;
|
|
17259
17481
|
meter.EVSEId = EVSE["@id"];
|
|
17260
17482
|
meter.chargingStation = chargingStation;
|
|
@@ -17262,8 +17484,8 @@ var Chargy = class {
|
|
|
17262
17484
|
this.meters.push(meter);
|
|
17263
17485
|
}
|
|
17264
17486
|
}
|
|
17265
|
-
if (chargingStation.
|
|
17266
|
-
for (const meter of chargingStation.
|
|
17487
|
+
if (chargingStation.energyMeters) {
|
|
17488
|
+
for (const meter of chargingStation.energyMeters ?? []) {
|
|
17267
17489
|
meter.chargingStation = chargingStation;
|
|
17268
17490
|
meter.chargingStationId = chargingStation["@id"];
|
|
17269
17491
|
this.meters.push(meter);
|
|
@@ -17290,7 +17512,7 @@ var Chargy = class {
|
|
|
17290
17512
|
//#endregion
|
|
17291
17513
|
//#region (private) hasInplausibleChargingSessionTotalEnergyMeasurement(chargingSession)
|
|
17292
17514
|
hasInplausibleChargingSessionTotalEnergyMeasurement(chargingSession) {
|
|
17293
|
-
for (const measurement of chargingSession.measurements) {
|
|
17515
|
+
for (const measurement of chargingSession.measurements ?? []) {
|
|
17294
17516
|
if (measurement.name !== "ENERGY_TOTAL" || measurement.values.length < 2) {
|
|
17295
17517
|
continue;
|
|
17296
17518
|
}
|
|
@@ -17450,7 +17672,7 @@ var Chargy = class {
|
|
|
17450
17672
|
if (ctr.end != null && ctr.end.length > 0 && (mergedCTR.end == null || mergedCTR.end.length === 0 || mergedCTR.end < ctr.end))
|
|
17451
17673
|
mergedCTR.end = ctr.end;
|
|
17452
17674
|
mergedCTR.description ??= ctr.description;
|
|
17453
|
-
mergedCTR.
|
|
17675
|
+
mergedCTR.contracts ??= ctr.contracts;
|
|
17454
17676
|
if (!mergedCTR.chargingStationOperators)
|
|
17455
17677
|
mergedCTR.chargingStationOperators = ctr.chargingStationOperators;
|
|
17456
17678
|
else if (ctr.chargingStationOperators)
|
|
@@ -17486,18 +17708,6 @@ var Chargy = class {
|
|
|
17486
17708
|
}
|
|
17487
17709
|
};
|
|
17488
17710
|
|
|
17489
|
-
|
|
17490
|
-
function toSessionVerificationResults(CTR, noRecordsMessage = { "en": "No charge transparency records found!" }) {
|
|
17491
|
-
const verificationResults = (CTR.chargingSessions ?? []).map((session) => session.verificationResult).filter(isISessionCryptoResult1);
|
|
17492
|
-
if (verificationResults.length > 0)
|
|
17493
|
-
return verificationResults;
|
|
17494
|
-
return {
|
|
17495
|
-
status: "Unvalidated" /* Unvalidated */,
|
|
17496
|
-
message: noRecordsMessage,
|
|
17497
|
-
certainty: 0
|
|
17498
|
-
};
|
|
17499
|
-
}
|
|
17500
|
-
|
|
17501
|
-
export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKeyInfo, IsAPublicKeyLookup, IsASessionCryptoResult, IsNullOrEmpty, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFTransactionTypes, OCMFv1_x, OCPI, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, TimeStatusTypes, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, buf2hex, buildMennekesSignatureData, bytesToHex2 as bytesToHex, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createHexString, dateToMennekesLocalEpochSeconds, extractMennekesChargingProcesses, firstKey, firstValue, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isGeoLocation, isICryptoResult, isIFileInfo, isIPublicKeyXY, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isMultilanguageText, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalURL, isPCDFText, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, jsonPrettyPrinter, measurementName2human, normalizePCDFPublicKeyHex, normalizeXMLText, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, secp224k1, setUILocale, sha256, sha384, sha512, signJSONMessage, signMessage, stripPCDFControlCharacters, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, unquotePCDFText, validatePCDFFields, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
|
|
17711
|
+
export { ACrypt, Alfen, AlfenCrypt01, BSMCrypt01, CanonicalJSONError, ChargeIT, ChargePoint, ChargePointCrypt01, IChargeTransparencyLiveLink_exports as ChargeTransparencyLiveLink, ChargeTransparencyLiveLinkContext, IChargeTransparencyRecord_exports as ChargeTransparencyRecord, Chargy, chargyInterfaces_exports as ChargyInterfaces, Clone, CloneCTR, ConcatenateBuffers, CreateDiv, CreateDiv2, CreateError, CreateWarning, CryptoAlgorithms, CryptoHashAlgorithms, DayOfWeek, DisplayPrefixes, EMHCrypt01, ErrorLevel, GDFCrypt01, IECCurves, IEncoding, InformationRelevance, InformationRelevanceToString, IsAChargeTransparencyLiveLink, IsAChargeTransparencyRecord, IsAPublicKey, IsAPublicKeyLookup, IsAPublicKeySignature, IsAPublicKeyXY, IsASessionCryptoResult, IsNullOrEmpty, JSONSignatureVerificationStatus, MENNEKES_EDL40_OBIS, MENNEKES_EDL40_XMLNS, Mennekes, MennekesCrypt01, OBIS2Hex, OBIS2MeasurementName, OBIS_RegExpr, OCMF, OCMFTransactionTypes, OCMFv1_x, OCPI, OIDInfo, PCDF, PCDFCrypt01, PCDFParseError, PCDFValidationError, PCDF_FIELD_ORDER, PCDF_PREFIX, ParseJSON_LD, PublicKeyFormats, IPublicKeyInfo_exports as PublicKeyInfo, SAFEXML, SessionVerificationResult, SetHex, SetInt8, SetText, SetText_withLength, SetTimestamp, SetTimestamp32, SetUInt32, SetUInt32_withCode, SetUInt64, SetUInt64D, SignMessage, SignatureFormats, TimeStatusTypes, UTC2human, VerificationResult, VerifyJSONMessageSignatures, WarningLevel, WhenNullOrEmpty, XMLContainer, asJSONArray, asJSONObject, asNumber, asString, base64ToBytes, buf2hex, buildMennekesSignatureData, bytesToBase64, bytesToHex, canonicalJSONBytes, canonicalJSONStringify, cleanHex, closeFullscreen, createHexString, dateToMennekesLocalEpochSeconds, extractMennekesChargingProcesses, firstKey, firstValue, getArrayElement, getArrayLikeElement, getDirectChildByLocalName, getDirectChildrenByLocalName, getElementsByLocalName, getFirstArrayElement, getInt16Bytes, getInt32Bytes, getInt64Bytes, getInt8Bytes, getLastArrayElement, getTrimmedTextContent, hashFile, hex2bin, hex32, hexToArrayBuffer, hexToBytes, intFromBytes, isEncodedValue, isGeoLocation, isI18NString, isICryptoResult, isIFileInfo, isISessionCryptoResult1, isISessionCryptoResult2, isJSONLDObject, isMandatoryArrayOfStrings, isMandatoryBoolean, isMandatoryDecimal, isMandatoryJSONArray, isMandatoryJSONObject, isMandatoryNumber, isMandatoryString, isMandatoryURL, isOIDInfo, isObject, isOptionalArrayOfStrings, isOptionalDecimal, isOptionalJSONArray, isOptionalJSONArrayError, isOptionalJSONArrayOk, isOptionalJSONObject, isOptionalNumber, isOptionalString, isOptionalStringArray, isOptionalStringOrOIDInfo, isOptionalURL, isPCDFText, isPublicKeySubject, isString, isStringArray, isStringOrOIDInfo, isStringOrStringArray, jsonPrettyPrinter, measurementName2human, normalizePCDFPublicKeyHex, normalizeXMLText, openFullscreen, pad, parseAndVerifyJSONSignatures, parseDescription, parseHexString, parseMennekesXMLDocument, parseNumber, parseOBIS, parsePCDFDocument, parsePCDFPublicKey, parsePCDFSignature, parseUTC, readQRCodeTextFromImage, readQRCodeTextFromImageData, secp224k1, setUILocale, sha256, sha256____, sha384, sha384____, sha512, sha512____, signJSONMessage, signMessage, stripPCDFControlCharacters, time2human, toArrayBuffer, toSessionVerificationResults, toUint8Array, unquotePCDFText, validatePCDFFields, verifyJSONMessageSignatureResults, verifyJSONMessageSignatures, verifyJSONSignature, verifyJSONSignatureResult, verifyPCDFDocument };
|
|
17502
17712
|
//# sourceMappingURL=index.js.map
|
|
17503
17713
|
//# sourceMappingURL=index.js.map
|