feat: add status notification transition check to OCPP 2.x.x code
authorJérôme Benoit <jerome.benoit@sap.com>
Tue, 18 Apr 2023 17:08:48 +0000 (19:08 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Tue, 18 Apr 2023 17:08:48 +0000 (19:08 +0200)
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
package.json
pnpm-lock.yaml
src/charging-station/ChargingStation.ts
src/charging-station/ocpp/1.6/OCPP16Constants.ts
src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts
src/charging-station/ocpp/2.0/OCPP20Constants.ts [new file with mode: 0644]
src/charging-station/ocpp/OCPPServiceUtils.ts
src/charging-station/ocpp/internal.ts
src/types/index.ts
ui/web/pnpm-lock.yaml

index 0e96b5b889c38fb05d5baa190384b635dc27e071..578b5fc9e6b07c999beb02d68e27310e2d7c6384 100644 (file)
     "eslint-config-prettier": "^8.8.0",
     "eslint-import-resolver-typescript": "^3.5.5",
     "eslint-plugin-import": "^2.27.5",
-    "eslint-plugin-jsdoc": "^41.1.2",
+    "eslint-plugin-jsdoc": "^43.0.3",
     "eslint-plugin-n": "^15.7.0",
     "eslint-plugin-prettier": "^4.2.1",
     "eslint-plugin-tsdoc": "^0.2.17",
     "release-it": "^15.10.1",
     "rimraf": "^5.0.0",
     "robohydra": "^0.6.9",
-    "rollup": "^3.20.4",
+    "rollup": "^3.20.6",
     "rollup-plugin-analyzer": "^4.0.0",
     "rollup-plugin-copy": "^3.4.0",
     "rollup-plugin-delete": "^2.0.0",
index e788fd89cedc22d76effb626f8ebeb003bc4328f..26d14cc57e98c2f7b6e8c125a82a9875e71b7f6c 100644 (file)
@@ -94,13 +94,13 @@ devDependencies:
     version: 4.0.2(release-it@15.10.1)
   '@rollup/plugin-json':
     specifier: ^6.0.0
-    version: 6.0.0(rollup@3.20.4)
+    version: 6.0.0(rollup@3.20.6)
   '@rollup/plugin-terser':
     specifier: ^0.4.1
-    version: 0.4.1(rollup@3.20.4)
+    version: 0.4.1(rollup@3.20.6)
   '@rollup/plugin-typescript':
     specifier: ^11.1.0
-    version: 11.1.0(rollup@3.20.4)(tslib@2.5.0)(typescript@5.0.4)
+    version: 11.1.0(rollup@3.20.6)(tslib@2.5.0)(typescript@5.0.4)
   '@types/mocha':
     specifier: ^10.0.1
     version: 10.0.1
@@ -153,8 +153,8 @@ devDependencies:
     specifier: ^2.27.5
     version: 2.27.5(@typescript-eslint/parser@5.59.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.38.0)
   eslint-plugin-jsdoc:
-    specifier: ^41.1.2
-    version: 41.1.2(eslint@8.38.0)
+    specifier: ^43.0.3
+    version: 43.0.3(eslint@8.38.0)
   eslint-plugin-n:
     specifier: ^15.7.0
     version: 15.7.0(eslint@8.38.0)
@@ -192,8 +192,8 @@ devDependencies:
     specifier: ^0.6.9
     version: 0.6.9(bufferutil@4.0.7)(utf-8-validate@6.0.3)
   rollup:
-    specifier: ^3.20.4
-    version: 3.20.4
+    specifier: ^3.20.6
+    version: 3.20.6
   rollup-plugin-analyzer:
     specifier: ^4.0.0
     version: 4.0.0
@@ -1176,6 +1176,13 @@ packages:
       '@octokit/openapi-types': 16.0.0
     dev: true
 
+  /@pkgjs/parseargs@0.11.0:
+    resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+    engines: {node: '>=14'}
+    requiresBuild: true
+    dev: true
+    optional: true
+
   /@pkgr/utils@2.3.1:
     resolution: {integrity: sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==}
     engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
@@ -1227,7 +1234,7 @@ packages:
       semver: 7.5.0
     dev: true
 
-  /@rollup/plugin-json@6.0.0(rollup@3.20.4):
+  /@rollup/plugin-json@6.0.0(rollup@3.20.6):
     resolution: {integrity: sha512-i/4C5Jrdr1XUarRhVu27EEwjt4GObltD7c+MkCIpO2QIbojw8MUs+CCTqOphQi3Qtg1FLmYt+l+6YeoIf51J7w==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -1236,11 +1243,11 @@ packages:
       rollup:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 5.0.2(rollup@3.20.4)
-      rollup: 3.20.4
+      '@rollup/pluginutils': 5.0.2(rollup@3.20.6)
+      rollup: 3.20.6
     dev: true
 
-  /@rollup/plugin-terser@0.4.1(rollup@3.20.4):
+  /@rollup/plugin-terser@0.4.1(rollup@3.20.6):
     resolution: {integrity: sha512-aKS32sw5a7hy+fEXVy+5T95aDIwjpGHCTv833HXVtyKMDoVS7pBr5K3L9hEQoNqbJFjfANPrNpIXlTQ7is00eA==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -1249,13 +1256,13 @@ packages:
       rollup:
         optional: true
     dependencies:
-      rollup: 3.20.4
+      rollup: 3.20.6
       serialize-javascript: 6.0.1
       smob: 0.0.6
-      terser: 5.16.9
+      terser: 5.17.0
     dev: true
 
-  /@rollup/plugin-typescript@11.1.0(rollup@3.20.4)(tslib@2.5.0)(typescript@5.0.4):
+  /@rollup/plugin-typescript@11.1.0(rollup@3.20.6)(tslib@2.5.0)(typescript@5.0.4):
     resolution: {integrity: sha512-86flrfE+bSHB69znnTV6kVjkncs2LBMhcTCyxWgRxLyfXfQrxg4UwlAqENnjrrxnSNS/XKCDJCl8EkdFJVHOxw==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -1268,14 +1275,14 @@ packages:
       tslib:
         optional: true
     dependencies:
-      '@rollup/pluginutils': 5.0.2(rollup@3.20.4)
+      '@rollup/pluginutils': 5.0.2(rollup@3.20.6)
       resolve: 1.22.2
-      rollup: 3.20.4
+      rollup: 3.20.6
       tslib: 2.5.0
       typescript: 5.0.4
     dev: true
 
-  /@rollup/pluginutils@5.0.2(rollup@3.20.4):
+  /@rollup/pluginutils@5.0.2(rollup@3.20.6):
     resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==}
     engines: {node: '>=14.0.0'}
     peerDependencies:
@@ -1287,7 +1294,7 @@ packages:
       '@types/estree': 1.0.0
       estree-walker: 2.0.2
       picomatch: 2.3.1
-      rollup: 3.20.4
+      rollup: 3.20.6
     dev: true
 
   /@sinclair/typebox@0.25.24:
@@ -4057,8 +4064,8 @@ packages:
       - supports-color
     dev: true
 
-  /eslint-plugin-jsdoc@41.1.2(eslint@8.38.0):
-    resolution: {integrity: sha512-MePJXdGiPW7AG06CU5GbKzYtKpoHwTq1lKijjq+RwL/cQkZtBZ59Zbv5Ep0RVxSMnq6242249/n+w4XrTZ1Afg==}
+  /eslint-plugin-jsdoc@43.0.3(eslint@8.38.0):
+    resolution: {integrity: sha512-tHlpaUqB8ih2IhQw7Es/R3Z3anQZVfPUb33nUAVOgIcMugVYyD1ZE/KXjjN8HxykZsV1IXqrKZkKpUBrEi3G9Q==}
     engines: {node: ^14 || ^16 || ^17 || ^18 || ^19}
     peerDependencies:
       eslint: ^7.0.0 || ^8.0.0
@@ -4549,6 +4556,14 @@ packages:
       signal-exit: 3.0.7
     dev: true
 
+  /foreground-child@3.1.1:
+    resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==}
+    engines: {node: '>=14'}
+    dependencies:
+      cross-spawn: 7.0.3
+      signal-exit: 4.0.1
+    dev: true
+
   /forever-agent@0.6.1:
     resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==}
     dev: true
@@ -4821,11 +4836,14 @@ packages:
       is-glob: 4.0.3
     dev: true
 
-  /glob@10.1.0:
-    resolution: {integrity: sha512-daGobsYuT0G4hng24B5LbeLNvwKZYRhWyDl3RvqqAGZjJnCopWWK6PWnAGBY1M/vdA63QE+jddhZcYp+74Bq6Q==}
+  /glob@10.2.1:
+    resolution: {integrity: sha512-ngom3wq2UhjdbmRE/krgkD8BQyi1KZ5l+D2dVm4+Yj+jJIBp74/ZGunL6gNGc/CYuQmvUBiavWEXIotRiv5R6A==}
     engines: {node: '>=16 || 14 >=14.17'}
+    hasBin: true
     dependencies:
+      foreground-child: 3.1.1
       fs.realpath: 1.0.0
+      jackspeak: 2.0.3
       minimatch: 9.0.0
       minipass: 5.0.0
       path-scurry: 1.7.0
@@ -5886,6 +5904,15 @@ packages:
       iterate-iterator: 1.0.2
     dev: true
 
+  /jackspeak@2.0.3:
+    resolution: {integrity: sha512-0Jud3OMUdMbrlr3PyUMKESq51LXVAB+a239Ywdvd+Kgxj3MaBRml/nVRxf8tQFyfthMjuRkxkv7Vg58pmIMfuQ==}
+    engines: {node: '>=14'}
+    dependencies:
+      cliui: 7.0.4
+    optionalDependencies:
+      '@pkgjs/parseargs': 0.11.0
+    dev: true
+
   /jake@10.8.5:
     resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==}
     engines: {node: '>=10'}
@@ -6438,8 +6465,8 @@ packages:
     dependencies:
       yallist: 4.0.0
 
-  /lru-cache@9.0.3:
-    resolution: {integrity: sha512-cyjNRew29d4kbgnz1sjDqxg7qg8NW4s+HQzCGjeon7DV5T2yDije16W9HaUFV1dhVEMh+SjrOcK0TomBmf3Egg==}
+  /lru-cache@9.1.0:
+    resolution: {integrity: sha512-qFXQEwchrZcMVen2uIDceR8Tii6kCJak5rzDStfEM0qA3YLMswaxIEZO0DhIbJ3aqaJiDjt+3crlplOb0tDtKQ==}
     engines: {node: 14 || >=16.14}
     dev: true
 
@@ -7710,7 +7737,7 @@ packages:
     resolution: {integrity: sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg==}
     engines: {node: '>=16 || 14 >=14.17'}
     dependencies:
-      lru-cache: 9.0.3
+      lru-cache: 9.1.0
       minipass: 5.0.0
     dev: true
 
@@ -8439,7 +8466,7 @@ packages:
     engines: {node: '>=14'}
     hasBin: true
     dependencies:
-      glob: 10.1.0
+      glob: 10.2.1
     dev: true
 
   /ripemd160@2.0.2:
@@ -8487,8 +8514,8 @@ packages:
       del: 5.1.0
     dev: true
 
-  /rollup@3.20.4:
-    resolution: {integrity: sha512-n7J4tuctZXUErM9Uc916httwqmTc63zzCr2+TLCiSCpfO/Xuk3g/marGN1IlRJZi+QF3XMYx75PxXRfZDVgaRw==}
+  /rollup@3.20.6:
+    resolution: {integrity: sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==}
     engines: {node: '>=14.18.0', npm: '>=8.0.0'}
     hasBin: true
     optionalDependencies:
@@ -8695,6 +8722,11 @@ packages:
   /signal-exit@3.0.7:
     resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
 
+  /signal-exit@4.0.1:
+    resolution: {integrity: sha512-uUWsN4aOxJAS8KOuf3QMyFtgm1pkb6I+KRZbRF/ghdf5T7sM+B1lLLzPDxswUjkmHyxQAVzEgG35E3NzDM9GVw==}
+    engines: {node: '>=14'}
+    dev: true
+
   /signed-varint@2.0.1:
     resolution: {integrity: sha512-abgDPg1106vuZZOvw7cFwdCABddfJRz5akcCcchzTbhyhYnsG31y4AlZEgp315T7W3nQq5P4xeOm186ZiPVFzw==}
     dependencies:
@@ -9286,8 +9318,8 @@ packages:
       source-map-support: 0.5.21
     dev: true
 
-  /terser@5.16.9:
-    resolution: {integrity: sha512-HPa/FdTB9XGI2H1/keLFZHxl6WNvAI4YalHGtDQTlMnJcoqSab1UwL4l1hGEhs6/GmLHBZIg/YgB++jcbzoOEg==}
+  /terser@5.17.0:
+    resolution: {integrity: sha512-3die3+pYW4mta4xF6K8Wtf7id8+oYyfqtAhjwzqY01+CfDSDMx/VA1Sp8sXWs5AVNIoAKoUfmp/gnPqRjBxuDA==}
     engines: {node: '>=10'}
     hasBin: true
     dependencies:
index a60f877174635e64a4c66f798e7e8869e495eb51..92f15e4c20f7c71fdd5f1fffe55723eec306532e 100644 (file)
@@ -1847,15 +1847,7 @@ export class ChargingStation {
         // Set default status
         connectorStatus = ConnectorStatusEnum.Available;
       }
-      await this.ocppRequestService.requestHandler<
-        StatusNotificationRequest,
-        StatusNotificationResponse
-      >(
-        this,
-        RequestCommand.STATUS_NOTIFICATION,
-        OCPPServiceUtils.buildStatusNotificationRequest(this, connectorId, connectorStatus)
-      );
-      this.getConnectorStatus(connectorId).status = connectorStatus;
+      await OCPPServiceUtils.sendAndSetConnectorStatus(this, connectorId, connectorStatus);
     }
     if (this.stationInfo?.firmwareStatus === FirmwareStatus.Installing) {
       await this.ocppRequestService.requestHandler<
index b0fb1ef8b06bf1fb640bebe197a1d2e5c496c82f..2697171c372b09d4bc74eab0704236f521b30c66 100644 (file)
 import { OCPP16ChargePointStatus } from '../../../types';
 import { OCPPConstants } from '../internal';
 
+type Transition = { from?: OCPP16ChargePointStatus; to: OCPP16ChargePointStatus };
+
 export class OCPP16Constants extends OCPPConstants {
-  static readonly OCPP16ChargePointStatusChargingStationTransition = new Set<
-    [OCPP16ChargePointStatus | undefined, OCPP16ChargePointStatus | undefined]
-  >([
-    [undefined, OCPP16ChargePointStatus.Available],
-    // [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Available],
-    [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Faulted],
-    [undefined, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Available],
-    // [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Faulted],
-    [undefined, OCPP16ChargePointStatus.Faulted],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Available],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Unavailable],
-    // [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Faulted],
-  ]);
+  static readonly ChargePointStatusChargingStationTransitions: Transition[] = [
+    { to: OCPP16ChargePointStatus.Available },
+    // { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Available },
+    { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Faulted },
+    { to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Available },
+    // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Faulted },
+    { to: OCPP16ChargePointStatus.Faulted },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Available },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Unavailable },
+    // { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Faulted },
+  ];
 
-  static readonly OCPP16ChargePointStatusConnectorTransition = new Set<
-    [OCPP16ChargePointStatus | undefined, OCPP16ChargePointStatus | undefined]
-  >([
-    [undefined, OCPP16ChargePointStatus.Available],
-    // [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Available],
-    [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Preparing],
-    [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Charging],
-    [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.SuspendedEV],
-    [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.SuspendedEVSE],
-    // [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Finishing],
-    [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Reserved],
-    [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Available, OCPP16ChargePointStatus.Faulted],
-    // [undefined, OCPP16ChargePointStatus.Preparing],
-    [OCPP16ChargePointStatus.Preparing, OCPP16ChargePointStatus.Available],
-    // [OCPP16ChargePointStatus.Preparing, OCPP16ChargePointStatus.Preparing],
-    [OCPP16ChargePointStatus.Preparing, OCPP16ChargePointStatus.Charging],
-    [OCPP16ChargePointStatus.Preparing, OCPP16ChargePointStatus.SuspendedEV],
-    [OCPP16ChargePointStatus.Preparing, OCPP16ChargePointStatus.SuspendedEVSE],
-    [OCPP16ChargePointStatus.Preparing, OCPP16ChargePointStatus.Finishing],
-    // [OCPP16ChargePointStatus.Preparing, OCPP16ChargePointStatus.Reserved],
-    // [OCPP16ChargePointStatus.Preparing, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Preparing, OCPP16ChargePointStatus.Faulted],
-    // [undefined, OCPP16ChargePointStatus.Charging],
-    [OCPP16ChargePointStatus.Charging, OCPP16ChargePointStatus.Available],
-    // [OCPP16ChargePointStatus.Charging, OCPP16ChargePointStatus.Preparing],
-    // [OCPP16ChargePointStatus.Charging, OCPP16ChargePointStatus.Charging],
-    [OCPP16ChargePointStatus.Charging, OCPP16ChargePointStatus.SuspendedEV],
-    [OCPP16ChargePointStatus.Charging, OCPP16ChargePointStatus.SuspendedEVSE],
-    [OCPP16ChargePointStatus.Charging, OCPP16ChargePointStatus.Finishing],
-    // [OCPP16ChargePointStatus.Charging, OCPP16ChargePointStatus.Reserved],
-    [OCPP16ChargePointStatus.Charging, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Charging, OCPP16ChargePointStatus.Faulted],
-    // [undefined, OCPP16ChargePointStatus.SuspendedEV],
-    [OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.Available],
-    // [OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.Preparing],
-    [OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.Charging],
-    // [OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.SuspendedEV],
-    [OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.SuspendedEVSE],
-    [OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.Finishing],
-    // [OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.Reserved],
-    [OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.Faulted],
-    // [undefined, OCPP16ChargePointStatus.SuspendedEVSE],
-    [OCPP16ChargePointStatus.SuspendedEVSE, OCPP16ChargePointStatus.Available],
-    // [OCPP16ChargePointStatus.SuspendedEVSE, OCPP16ChargePointStatus.Preparing],
-    [OCPP16ChargePointStatus.SuspendedEVSE, OCPP16ChargePointStatus.Charging],
-    [OCPP16ChargePointStatus.SuspendedEVSE, OCPP16ChargePointStatus.SuspendedEV],
-    // [OCPP16ChargePointStatus.SuspendedEVSE, OCPP16ChargePointStatus.SuspendedEVSE],
-    [OCPP16ChargePointStatus.SuspendedEVSE, OCPP16ChargePointStatus.Finishing],
-    // [OCPP16ChargePointStatus.SuspendedEVSE, OCPP16ChargePointStatus.Reserved],
-    [OCPP16ChargePointStatus.SuspendedEVSE, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.SuspendedEVSE, OCPP16ChargePointStatus.Faulted],
-    // [undefined, OCPP16ChargePointStatus.Finishing],
-    [OCPP16ChargePointStatus.Finishing, OCPP16ChargePointStatus.Available],
-    [OCPP16ChargePointStatus.Finishing, OCPP16ChargePointStatus.Preparing],
-    // [OCPP16ChargePointStatus.Finishing, OCPP16ChargePointStatus.Charging],
-    // [OCPP16ChargePointStatus.Finishing, OCPP16ChargePointStatus.SuspendedEV],
-    // [OCPP16ChargePointStatus.Finishing, OCPP16ChargePointStatus.SuspendedEVSE],
-    // [OCPP16ChargePointStatus.Finishing, OCPP16ChargePointStatus.Finishing],
-    // [OCPP16ChargePointStatus.Finishing, OCPP16ChargePointStatus.Reserved],
-    [OCPP16ChargePointStatus.Finishing, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Finishing, OCPP16ChargePointStatus.Faulted],
-    // [undefined, OCPP16ChargePointStatus.Reserved],
-    [OCPP16ChargePointStatus.Reserved, OCPP16ChargePointStatus.Available],
-    [OCPP16ChargePointStatus.Reserved, OCPP16ChargePointStatus.Preparing],
-    // [OCPP16ChargePointStatus.Reserved, OCPP16ChargePointStatus.Charging],
-    // [OCPP16ChargePointStatus.Reserved, OCPP16ChargePointStatus.SuspendedEV],
-    // [OCPP16ChargePointStatus.Reserved, OCPP16ChargePointStatus.SuspendedEVSE],
-    // [OCPP16ChargePointStatus.Reserved, OCPP16ChargePointStatus.Finishing],
-    // [OCPP16ChargePointStatus.Reserved, OCPP16ChargePointStatus.Reserved],
-    [OCPP16ChargePointStatus.Reserved, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Reserved, OCPP16ChargePointStatus.Faulted],
-    [undefined, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Available],
-    [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Preparing],
-    [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Charging],
-    [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.SuspendedEV],
-    [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.SuspendedEVSE],
-    // [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Finishing],
-    // [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Reserved],
-    // [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Unavailable],
-    [OCPP16ChargePointStatus.Unavailable, OCPP16ChargePointStatus.Faulted],
-    [undefined, OCPP16ChargePointStatus.Faulted],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Available],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Preparing],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Charging],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.SuspendedEV],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.SuspendedEVSE],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Finishing],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Reserved],
-    [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Unavailable],
-    // [OCPP16ChargePointStatus.Faulted, OCPP16ChargePointStatus.Faulted],
-  ]);
+  static readonly ChargePointStatusConnectorTransitions: Transition[] = [
+    { to: OCPP16ChargePointStatus.Available },
+    // { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Available },
+    { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Preparing },
+    { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Charging },
+    { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.SuspendedEV },
+    { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.SuspendedEVSE },
+    // { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Finishing },
+    { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Reserved },
+    { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Available, to: OCPP16ChargePointStatus.Faulted },
+    // { to: OCPP16ChargePointStatus.Preparing },
+    { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Available },
+    // { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Preparing },
+    { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Charging },
+    { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.SuspendedEV },
+    { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.SuspendedEVSE },
+    { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Finishing },
+    // { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Reserved },
+    // { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Preparing, to: OCPP16ChargePointStatus.Faulted },
+    // { to: OCPP16ChargePointStatus.Charging },
+    { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Available },
+    // { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Preparing },
+    // { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Charging },
+    { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.SuspendedEV },
+    { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.SuspendedEVSE },
+    { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Finishing },
+    // { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Reserved },
+    { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Charging, to: OCPP16ChargePointStatus.Faulted },
+    // { to: OCPP16ChargePointStatus.SuspendedEV },
+    { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Available },
+    // { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Preparing },
+    { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Charging },
+    // { from: OCPP16ChargePointStatus.SuspendedEV, OCPP16ChargePointStatus.SuspendedEV },
+    { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.SuspendedEVSE },
+    { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Finishing },
+    // { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Reserved },
+    { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.SuspendedEV, to: OCPP16ChargePointStatus.Faulted },
+    // { to: OCPP16ChargePointStatus.SuspendedEVSE },
+    { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Available },
+    // { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Preparing },
+    { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Charging },
+    { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.SuspendedEV },
+    // { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.SuspendedEVSE },
+    { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Finishing },
+    // { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Reserved },
+    { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.SuspendedEVSE, to: OCPP16ChargePointStatus.Faulted },
+    // { to: OCPP16ChargePointStatus.Finishing},
+    { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Available },
+    { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Preparing },
+    // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Charging },
+    // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.SuspendedEV },
+    // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.SuspendedEVSE },
+    // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Finishing },
+    // { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Reserved },
+    { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Finishing, to: OCPP16ChargePointStatus.Faulted },
+    // { to: OCPP16ChargePointStatus.Reserved },
+    { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Available },
+    { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Preparing },
+    // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Charging },
+    // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.SuspendedEV },
+    // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.SuspendedEVSE },
+    // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Finishing },
+    // { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Reserved },
+    { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Reserved, to: OCPP16ChargePointStatus.Faulted },
+    { to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Available },
+    { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Preparing },
+    { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Charging },
+    { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.SuspendedEV },
+    { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.SuspendedEVSE },
+    // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Finishing },
+    // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Reserved },
+    // { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Unavailable },
+    { from: OCPP16ChargePointStatus.Unavailable, to: OCPP16ChargePointStatus.Faulted },
+    { to: OCPP16ChargePointStatus.Faulted },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Available },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Preparing },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Charging },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.SuspendedEV },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.SuspendedEVSE },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Finishing },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Reserved },
+    { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Unavailable },
+    // { from: OCPP16ChargePointStatus.Faulted, to: OCPP16ChargePointStatus.Faulted },
+  ];
 }
index 52157e3474578ed7b782645370f40c88e86667fa..932d4515f6d0fcc7d0c259f3fe8ff000e11423ed 100644 (file)
@@ -16,8 +16,6 @@ import {
   MeterValueContext,
   MeterValueLocation,
   MeterValueUnit,
-  OCPP16ChargePointErrorCode,
-  type OCPP16ChargePointStatus,
   type OCPP16ChargingProfile,
   type OCPP16IncomingRequestCommand,
   type OCPP16MeterValue,
@@ -26,15 +24,13 @@ import {
   OCPP16RequestCommand,
   type OCPP16SampledValue,
   OCPP16StandardParametersKey,
-  type OCPP16StatusNotificationRequest,
-  type OCPP16StatusNotificationResponse,
   type OCPP16SupportedFeatureProfiles,
   OCPPVersion,
   type SampledValueTemplate,
   Voltage,
 } from '../../../types';
 import { ACElectricUtils, Constants, DCElectricUtils, Utils, logger } from '../../../utils';
-import { OCPP16Constants, OCPPServiceUtils } from '../internal';
+import { OCPPServiceUtils } from '../internal';
 
 export class OCPP16ServiceUtils extends OCPPServiceUtils {
   public static checkFeatureProfile(
@@ -844,58 +840,6 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils {
     );
   }
 
-  public static async sendAndSetConnectorStatus(
-    chargingStation: ChargingStation,
-    connectorId: number,
-    status: OCPP16ChargePointStatus,
-    errorCode: OCPP16ChargePointErrorCode = OCPP16ChargePointErrorCode.NO_ERROR
-  ) {
-    OCPP16ServiceUtils.checkConnectorStatusTransition(chargingStation, connectorId, status);
-    await chargingStation.ocppRequestService.requestHandler<
-      OCPP16StatusNotificationRequest,
-      OCPP16StatusNotificationResponse
-    >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, {
-      connectorId,
-      status,
-      errorCode,
-    });
-    chargingStation.getConnectorStatus(connectorId).status = status;
-  }
-
-  private static checkConnectorStatusTransition(
-    chargingStation: ChargingStation,
-    connectorId: number,
-    status: OCPP16ChargePointStatus
-  ): boolean {
-    if (
-      connectorId === 0 &&
-      !OCPP16Constants.OCPP16ChargePointStatusChargingStationTransition.has([
-        chargingStation.getConnectorStatus(connectorId).status as OCPP16ChargePointStatus,
-        status,
-      ])
-    ) {
-      logger.warn(
-        `${chargingStation.logPrefix()} Connector ${connectorId} status transition from ${
-          chargingStation.getConnectorStatus(connectorId).status
-        } to ${status} is not allowed`
-      );
-      return false;
-    } else if (
-      !OCPP16Constants.OCPP16ChargePointStatusConnectorTransition.has([
-        chargingStation.getConnectorStatus(connectorId).status as OCPP16ChargePointStatus,
-        status,
-      ])
-    ) {
-      logger.warn(
-        `${chargingStation.logPrefix()} Connector ${connectorId} status transition from ${
-          chargingStation.getConnectorStatus(connectorId).status
-        } to ${status} is not allowed`
-      );
-      return false;
-    }
-    return true;
-  }
-
   private static buildSampledValue(
     sampledValueTemplate: SampledValueTemplate,
     value: number,
diff --git a/src/charging-station/ocpp/2.0/OCPP20Constants.ts b/src/charging-station/ocpp/2.0/OCPP20Constants.ts
new file mode 100644 (file)
index 0000000..58a1004
--- /dev/null
@@ -0,0 +1,69 @@
+import { OCPP20ConnectorStatusEnumType } from '../../../types';
+import { OCPPConstants } from '../internal';
+
+type Transition = { from?: OCPP20ConnectorStatusEnumType; to: OCPP20ConnectorStatusEnumType };
+
+export class OCPP20Constants extends OCPPConstants {
+  static readonly ChargingStationStatusTransitions: Transition[] = [
+    { to: OCPP20ConnectorStatusEnumType.Available },
+    // { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Available },
+    {
+      from: OCPP20ConnectorStatusEnumType.Available,
+      to: OCPP20ConnectorStatusEnumType.Unavailable,
+    },
+    { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Faulted },
+    { to: OCPP20ConnectorStatusEnumType.Unavailable },
+    {
+      from: OCPP20ConnectorStatusEnumType.Unavailable,
+      to: OCPP20ConnectorStatusEnumType.Available,
+    },
+    // {
+    //   from: OCPP20ConnectorStatusEnumType.Unavailable,
+    //   to: OCPP20ConnectorStatusEnumType.Unavailable,
+    // },
+    { from: OCPP20ConnectorStatusEnumType.Unavailable, to: OCPP20ConnectorStatusEnumType.Faulted },
+    { to: OCPP20ConnectorStatusEnumType.Faulted },
+    { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Available },
+    { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Unavailable },
+    // { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Faulted },
+  ];
+
+  static readonly ConnectorStatusTransitions: Transition[] = [
+    { to: OCPP20ConnectorStatusEnumType.Available },
+    // { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Available },
+    { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Occupied },
+    { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Reserved },
+    {
+      from: OCPP20ConnectorStatusEnumType.Available,
+      to: OCPP20ConnectorStatusEnumType.Unavailable,
+    },
+    { from: OCPP20ConnectorStatusEnumType.Available, to: OCPP20ConnectorStatusEnumType.Faulted },
+    // { to: OCPP20ConnectorStatusEnumType.Occupied },
+    { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Available },
+    // { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Occupied },
+    // { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Reserved },
+    { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Unavailable },
+    { from: OCPP20ConnectorStatusEnumType.Occupied, to: OCPP20ConnectorStatusEnumType.Faulted },
+    // { to: OCPP20ConnectorStatusEnumType.Reserved },
+    { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Available },
+    { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Occupied },
+    // { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Reserved },
+    { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Unavailable },
+    { from: OCPP20ConnectorStatusEnumType.Reserved, to: OCPP20ConnectorStatusEnumType.Faulted },
+    { to: OCPP20ConnectorStatusEnumType.Unavailable },
+    {
+      from: OCPP20ConnectorStatusEnumType.Unavailable,
+      to: OCPP20ConnectorStatusEnumType.Available,
+    },
+    { from: OCPP20ConnectorStatusEnumType.Unavailable, to: OCPP20ConnectorStatusEnumType.Occupied },
+    // { from: OCPP20ConnectorStatusEnumType.Unavailable, to: OCPP20ConnectorStatusEnumType.Reserved },
+    // { from: OCPP20ConnectorStatusEnumType.Unavailable, to: OCPP20ConnectorStatusEnumType.Unavailable },
+    { from: OCPP20ConnectorStatusEnumType.Unavailable, to: OCPP20ConnectorStatusEnumType.Faulted },
+    { to: OCPP20ConnectorStatusEnumType.Faulted },
+    { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Available },
+    { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Occupied },
+    { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Reserved },
+    { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Unavailable },
+    // { from: OCPP20ConnectorStatusEnumType.Faulted, to: OCPP20ConnectorStatusEnumType.Faulted },
+  ];
+}
index f7a5d61ceb772f23d4da6b7fc5e394848ca52d8f..ea3dfe7ecd0d79efa02049a571a1c0dfcd6f2f59 100644 (file)
@@ -2,6 +2,7 @@ import fs from 'node:fs';
 
 import type { DefinedError, ErrorObject, JSONSchemaType } from 'ajv';
 
+import { OCPP16Constants, OCPP20Constants } from './internal';
 import { type ChargingStation, ChargingStationConfigurationUtils } from '../../charging-station';
 import { BaseError } from '../../exception';
 import {
@@ -23,6 +24,7 @@ import {
   type SampledValueTemplate,
   StandardParametersKey,
   type StatusNotificationRequest,
+  type StatusNotificationResponse,
 } from '../../types';
 import { Constants, FileUtils, Utils, logger } from '../../utils';
 
@@ -174,6 +176,82 @@ export class OCPPServiceUtils {
     }
   }
 
+  public static async sendAndSetConnectorStatus(
+    chargingStation: ChargingStation,
+    connectorId: number,
+    status: ConnectorStatusEnum
+  ) {
+    OCPPServiceUtils.checkConnectorStatusTransition(chargingStation, connectorId, status);
+    await chargingStation.ocppRequestService.requestHandler<
+      StatusNotificationRequest,
+      StatusNotificationResponse
+    >(
+      chargingStation,
+      RequestCommand.STATUS_NOTIFICATION,
+      OCPPServiceUtils.buildStatusNotificationRequest(chargingStation, connectorId, status)
+    );
+    chargingStation.getConnectorStatus(connectorId).status = status;
+  }
+
+  protected static checkConnectorStatusTransition(
+    chargingStation: ChargingStation,
+    connectorId: number,
+    status: ConnectorStatusEnum
+  ): boolean {
+    const fromStatus = chargingStation.getConnectorStatus(connectorId).status;
+    let transitionAllowed = false;
+    switch (chargingStation.stationInfo.ocppVersion) {
+      case OCPPVersion.VERSION_16:
+        if (
+          connectorId === 0 &&
+          OCPP16Constants.ChargePointStatusChargingStationTransitions.findIndex(
+            (transition) => transition.from === fromStatus && transition.to === status
+          ) !== -1
+        ) {
+          transitionAllowed = true;
+        } else if (
+          OCPP16Constants.ChargePointStatusConnectorTransitions.findIndex(
+            (transition) => transition.from === fromStatus && transition.to === status
+          ) !== -1
+        ) {
+          transitionAllowed = true;
+        }
+        break;
+      case OCPPVersion.VERSION_20:
+      case OCPPVersion.VERSION_201:
+        if (
+          connectorId === 0 &&
+          OCPP20Constants.ChargingStationStatusTransitions.findIndex(
+            (transition) => transition.from === fromStatus && transition.to === status
+          ) !== -1
+        ) {
+          transitionAllowed = true;
+        } else if (
+          OCPP20Constants.ConnectorStatusTransitions.findIndex(
+            (transition) => transition.from === fromStatus && transition.to === status
+          ) !== -1
+        ) {
+          transitionAllowed = true;
+        }
+        break;
+      default:
+        throw new BaseError(
+          // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+          `Cannot check connector status transition: OCPP version ${chargingStation.stationInfo.ocppVersion} not supported`
+        );
+    }
+    if (transitionAllowed === false) {
+      logger.warn(
+        `${chargingStation.logPrefix()} OCPP ${
+          chargingStation.stationInfo.ocppVersion
+        } connector ${connectorId} status transition from '${
+          chargingStation.getConnectorStatus(connectorId).status
+        }' to '${status}' is not allowed`
+      );
+    }
+    return transitionAllowed;
+  }
+
   protected static parseJsonSchemaFile<T extends JsonType>(
     filePath: string,
     ocppVersion: OCPPVersion,
index c7f0fe728a2e10cc3ce66c8d7a3914f68f4014a4..f1c9af00315e6ace7c04a6040ccff98018e8f896 100644 (file)
@@ -4,6 +4,7 @@ export * from './1.6/OCPP16RequestService';
 export * from './1.6/OCPP16ResponseService';
 export * from './1.6/OCPP16ServiceUtils';
 
+export * from './2.0/OCPP20Constants';
 export * from './2.0/OCPP20IncomingRequestService';
 export * from './2.0/OCPP20RequestService';
 export * from './2.0/OCPP20ResponseService';
index 6255a3c2ea808594c648c565b82218496df211df..5170678f7c66a3774d6937482dcbb431716c43b2 100644 (file)
@@ -144,6 +144,7 @@ export {
   type OCPP20BootNotificationResponse,
   type OCPP20ClearCacheRequest,
   type OCPP20ClearCacheResponse,
+  OCPP20ConnectorStatusEnumType,
   type OCPP20HeartbeatRequest,
   type OCPP20HeartbeatResponse,
   OCPP20IncomingRequestCommand,
index 8344a97d3988fed5b365bc5e365ddcc518313972..7b7d1494110606356715ca1bae6614a9757dfac2 100644 (file)
@@ -3793,7 +3793,7 @@ packages:
     hasBin: true
     dependencies:
       caniuse-lite: 1.0.30001480
-      electron-to-chromium: 1.4.366
+      electron-to-chromium: 1.4.367
       node-releases: 2.0.10
       update-browserslist-db: 1.0.11(browserslist@4.21.5)
     dev: true
@@ -4946,8 +4946,8 @@ packages:
     resolution: {integrity: sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg==}
     dev: true
 
-  /dns-packet@5.5.0:
-    resolution: {integrity: sha512-USawdAUzRkV6xrqTjiAEp6M9YagZEzWcSUaZTcIFAiyQWW1SoI6KyId8y2+/71wbgHKQAKd+iupLv4YvEwYWvA==}
+  /dns-packet@5.6.0:
+    resolution: {integrity: sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==}
     engines: {node: '>=6'}
     dependencies:
       '@leichtgewicht/ip-codec': 2.0.4
@@ -5076,8 +5076,8 @@ packages:
       jake: 10.8.5
     dev: true
 
-  /electron-to-chromium@1.4.366:
-    resolution: {integrity: sha512-XjC4pyf1no8kJe24nUfyexpWwiGRbZWXU/KbprSEvXcTXUlr3Zr5vK3lQt2to0ttpMhAc3iENccwPSKbnEW2Fg==}
+  /electron-to-chromium@1.4.367:
+    resolution: {integrity: sha512-mNuDxb+HpLhPGUKrg0hSxbTjHWw8EziwkwlJNkFUj3W60ypigLDRVz04vU+VRsJPi8Gub+FDhYUpuTm9xiEwRQ==}
     dev: true
 
   /emoji-regex@7.0.3:
@@ -6264,7 +6264,7 @@ packages:
       he: 1.2.0
       param-case: 3.0.4
       relateurl: 0.2.7
-      terser: 5.16.9
+      terser: 5.17.0
     dev: true
 
   /html-tags@2.0.0:
@@ -7553,7 +7553,7 @@ packages:
     resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==}
     hasBin: true
     dependencies:
-      dns-packet: 5.5.0
+      dns-packet: 5.6.0
       thunky: 1.1.0
     dev: true
 
@@ -9678,12 +9678,12 @@ packages:
       jest-worker: 27.5.1
       schema-utils: 3.1.2
       serialize-javascript: 6.0.1
-      terser: 5.16.9
+      terser: 5.17.0
       webpack: 5.79.0
     dev: true
 
-  /terser@5.16.9:
-    resolution: {integrity: sha512-HPa/FdTB9XGI2H1/keLFZHxl6WNvAI4YalHGtDQTlMnJcoqSab1UwL4l1hGEhs6/GmLHBZIg/YgB++jcbzoOEg==}
+  /terser@5.17.0:
+    resolution: {integrity: sha512-3die3+pYW4mta4xF6K8Wtf7id8+oYyfqtAhjwzqY01+CfDSDMx/VA1Sp8sXWs5AVNIoAKoUfmp/gnPqRjBxuDA==}
     engines: {node: '>=10'}
     hasBin: true
     dependencies: