Add CS template tunable to enable persistent OCPP configuration
authorJérôme Benoit <jerome.benoit@sap.com>
Sat, 12 Mar 2022 10:40:16 +0000 (11:40 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Sat, 12 Mar 2022 10:40:16 +0000 (11:40 +0100)
Reference: #196

Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
README.md
src/charging-station/ChargingStation.ts
src/charging-station/ocpp/1.6/OCPP16ResponseService.ts
src/types/ChargingStationTemplate.ts

index 3cf78f623fb977ec0e34be333374bde685eaa931..ff6070e9d8a304ec3bec4ac986fffe26f8dda0cd 100644 (file)
--- a/README.md
+++ b/README.md
@@ -93,7 +93,8 @@ But the modifications to test have to be done to the files in the build result d
 | supervisionUrlOcppKey             |            | 'ConnectionUrl' | string                            | The vendor string that will be used as a vendor OCPP parameter key to set the supervision URL                                         |
 | ocppVersion                       | 1.6        | 1.6             | string                            | OCPP version                                                                                                                          |
 | ocppProtocol                      | json       | json            | string                            | OCPP protocol                                                                                                                         |
-| ocppStrictCompliance              | true/false | true            | boolean                           | Strict adherence to the OCPP version and protocol specifications                                                                      |
+| ocppStrictCompliance              | true/false | false           | boolean                           | Strict adherence to the OCPP version and protocol specifications                                                                      |
+| ocppPersistentConfiguration       | true/false | true            | boolean                           | Enable persistent OCPP parameters by charging station autogenerated name                                                              |
 | wsOptions                         |            | {}              | ClientOptions & ClientRequestArgs | [ws](https://github.com/websockets/ws) and node.js [http](https://nodejs.org/api/http.html) clients options intersection              |
 | authorizationFile                 |            | ''              | string                            | RFID tags list file relative to src/assets path                                                                                       |
 | baseName                          |            | ''              | string                            | base name to build charging stations name                                                                                             |
index cc0fd47f2ab9edd15f41d7202a1a4b0bab24cb38..3000d6d08533c32dc4b23b8ac198acdd51ab72e1 100644 (file)
@@ -536,12 +536,15 @@ export default class ChargingStation {
         }
       }
     );
-    FileUtils.watchJsonFile<ChargingStationConfiguration>(
-      this.logPrefix(),
-      FileType.ChargingStationConfiguration,
-      this.configurationFile,
-      this.configuration
-    );
+    // FIXME: triggered by saveConfiguration()
+    // if (this.getOcppPersistentConfiguration()) {
+    //   FileUtils.watchJsonFile<ChargingStationConfiguration>(
+    //     this.logPrefix(),
+    //     FileType.ChargingStationConfiguration,
+    //     this.configurationFile,
+    //     this.configuration
+    //   );
+    // }
     // Handle WebSocket message
     this.wsConnection.on(
       'message',
@@ -718,14 +721,14 @@ export default class ChargingStation {
     }
   }
 
-  private getSupervisionUrlOcppKey(): string {
-    return this.stationInfo.supervisionUrlOcppKey ?? VendorDefaultParametersKey.ConnectionUrl;
-  }
-
   private getSupervisionUrlOcppConfiguration(): boolean {
     return this.stationInfo.supervisionUrlOcppConfiguration ?? false;
   }
 
+  private getSupervisionUrlOcppKey(): string {
+    return this.stationInfo.supervisionUrlOcppKey ?? VendorDefaultParametersKey.ConnectionUrl;
+  }
+
   private getChargingStationId(stationTemplate: ChargingStationTemplate): string {
     // In case of multiple instances: add instance index to charging station id
     const instanceIndex = process.env.CF_INSTANCE_INDEX ?? 0;
@@ -795,6 +798,10 @@ export default class ChargingStation {
     return this.stationInfo.ocppVersion ? this.stationInfo.ocppVersion : OCPPVersion.VERSION_16;
   }
 
+  private getOcppPersistentConfiguration(): boolean {
+    return this.stationInfo.ocppPersistentConfiguration ?? true;
+  }
+
   private handleUnsupportedVersion(version: OCPPVersion) {
     const errMsg = `${this.logPrefix()} Unsupported protocol version '${version}' configured in template file ${
       this.stationTemplateFile
@@ -807,8 +814,7 @@ export default class ChargingStation {
     this.stationInfo = this.buildStationInfo();
     this.configurationFile = path.join(
       path.resolve(__dirname, '../'),
-      'assets',
-      'configurations',
+      'assets/configurations',
       this.stationInfo.chargingStationId + '.json'
     );
     this.configuration = this.getConfiguration();
@@ -1025,7 +1031,11 @@ export default class ChargingStation {
 
   private getConfigurationFromFile(): ChargingStationConfiguration | null {
     let configuration: ChargingStationConfiguration = null;
-    if (this.configurationFile && fs.existsSync(this.configurationFile)) {
+    if (
+      this.getOcppPersistentConfiguration() &&
+      this.configurationFile &&
+      fs.existsSync(this.configurationFile)
+    ) {
       try {
         configuration = JSON.parse(
           fs.readFileSync(this.configurationFile, 'utf8')
@@ -1043,26 +1053,28 @@ export default class ChargingStation {
   }
 
   private saveConfiguration(): void {
-    if (this.configurationFile) {
-      try {
-        if (!fs.existsSync(path.dirname(this.configurationFile))) {
-          fs.mkdirSync(path.dirname(this.configurationFile), { recursive: true });
+    if (this.getOcppPersistentConfiguration()) {
+      if (this.configurationFile) {
+        try {
+          if (!fs.existsSync(path.dirname(this.configurationFile))) {
+            fs.mkdirSync(path.dirname(this.configurationFile), { recursive: true });
+          }
+          const fileDescriptor = fs.openSync(this.configurationFile, 'w');
+          fs.writeFileSync(fileDescriptor, JSON.stringify(this.configuration, null, 2));
+          fs.closeSync(fileDescriptor);
+        } catch (error) {
+          FileUtils.handleFileException(
+            this.logPrefix(),
+            FileType.ChargingStationConfiguration,
+            this.configurationFile,
+            error as NodeJS.ErrnoException
+          );
         }
-        const fileDescriptor = fs.openSync(this.configurationFile, 'w');
-        fs.writeFileSync(fileDescriptor, JSON.stringify(this.configuration, null, 2));
-        fs.closeSync(fileDescriptor);
-      } catch (error) {
-        FileUtils.handleFileException(
-          this.logPrefix(),
-          FileType.ChargingStationConfiguration,
-          this.configurationFile,
-          error as NodeJS.ErrnoException
+      } else {
+        logger.error(
+          `${this.logPrefix()} Trying to save charging station configuration to undefined file`
         );
       }
-    } else {
-      logger.error(
-        `${this.logPrefix()} Trying to save charging station configuration to undefined file`
-      );
     }
   }
 
index c8d59eac8235f2626cabf670c851dd7ff4dc3090..93465c620fb9ff04584a1adecead5781ead24935 100644 (file)
@@ -172,9 +172,9 @@ export default class OCPP16ResponseService extends OCPPResponseService {
       this.chargingStation.getConnectorStatus(authorizeConnectorId).idTagAuthorized = false;
       delete this.chargingStation.getConnectorStatus(authorizeConnectorId).authorizeIdTag;
       logger.debug(
-        `${this.chargingStation.logPrefix()} IdTag ${requestPayload.idTag} refused with status ${
+        `${this.chargingStation.logPrefix()} IdTag ${requestPayload.idTag} refused with status '${
           payload.idTagInfo.status
-        } on connector ${authorizeConnectorId}`
+        }' on connector ${authorizeConnectorId}`
       );
     }
   }
@@ -360,9 +360,9 @@ export default class OCPP16ResponseService extends OCPPResponseService {
         this.chargingStation.logPrefix() +
           ' Starting transaction id ' +
           payload.transactionId.toString() +
-          ' REJECTED with status ' +
+          " REJECTED with status '" +
           payload?.idTagInfo?.status +
-          ', idTag ' +
+          "', idTag " +
           requestPayload.idTag
       );
       await this.resetConnectorOnStartTransactionError(connectorId);
@@ -463,8 +463,9 @@ export default class OCPP16ResponseService extends OCPPResponseService {
         this.chargingStation.logPrefix() +
           ' Stopping transaction id ' +
           requestPayload.transactionId.toString() +
-          ' REJECTED with status ' +
-          payload.idTagInfo?.status
+          " REJECTED with status '" +
+          payload.idTagInfo?.status +
+          "'"
       );
     }
   }
index eabe60d09ff3930b4303e0edda4e2854608a5daf..914f131ee30398a8ee2324043dd9a3774037dfcf 100644 (file)
@@ -43,6 +43,7 @@ export default interface ChargingStationTemplate {
   ocppVersion?: OCPPVersion;
   ocppProtocol?: OCPPProtocol;
   ocppStrictCompliance?: boolean;
+  ocppPersistentConfiguration?: boolean;
   wsOptions?: ClientOptions & ClientRequestArgs;
   authorizationFile?: string;
   baseName: string;