Ensure charging station data is always JSON serializable
authorJérôme Benoit <jerome.benoit@sap.com>
Sat, 27 Aug 2022 23:07:01 +0000 (01:07 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Sat, 27 Aug 2022 23:07:01 +0000 (01:07 +0200)
And fix/improve logging messages

Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
12 files changed:
build-requirements.js
docker/docker-compose.yml
src/charging-station/ChargingStation.ts
src/charging-station/ChargingStationUtils.ts
src/charging-station/MessageChannelUtils.ts
src/charging-station/ocpp/1.6/OCPP16ResponseService.ts
src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts
src/charging-station/ocpp/OCPPIncomingRequestService.ts
src/charging-station/ocpp/OCPPRequestService.ts
src/ui/web/package.json
src/ui/web/src/components/charging-stations/CSTable.vue
src/ui/web/src/types/UIProtocol.ts

index 7f36a4876c4ade6c23e0aa8548c2cb5c8be97527..74d38ccd6c24d86ebbc9e280ef3d825822a4f446 100644 (file)
@@ -5,7 +5,7 @@ const SemVer = require('semver');
 const enginesNodeVersion = require('./package.json').engines.node;
 
 /**
- *
+ * Check if the current node version match the required engines version.
  */
 function checkNodeVersion() {
   if (SemVer.satisfies(process.version, enginesNodeVersion) === false) {
index c9065cdae8c50e8178531c7e2bb21caea45d7818..db6f914cdf6e6e42ac5c199d6d6fbefb316ec8ea 100644 (file)
@@ -13,4 +13,4 @@ services:
     networks:
       - ev_network
     ports:
-      - "3030:3030"
+      - '3030:3030'
index c5b89152199f53373bc6680648545c7205edab83..bd23b37d9cdd7a57cc1a616e5a978c2284443a35 100644 (file)
@@ -583,7 +583,7 @@ export default class ChargingStation {
     if (!Utils.isEmptyArray(chargingProfiles)) {
       const result = ChargingStationUtils.getLimitFromChargingProfiles(
         chargingProfiles,
-        Utils.logPrefix()
+        this.logPrefix()
       );
       if (!Utils.isNullOrUndefined(result)) {
         limit = result.limit;
@@ -846,14 +846,14 @@ export default class ChargingStation {
     ChargingStationUtils.checkConfiguredMaxConnectors(
       configuredMaxConnectors,
       this.templateFile,
-      Utils.logPrefix()
+      this.logPrefix()
     );
     const templateMaxConnectors =
       ChargingStationUtils.getTemplateMaxNumberOfConnectors(stationTemplate);
     ChargingStationUtils.checkTemplateMaxConnectors(
       templateMaxConnectors,
       this.templateFile,
-      Utils.logPrefix()
+      this.logPrefix()
     );
     if (
       configuredMaxConnectors >
@@ -920,10 +920,8 @@ export default class ChargingStation {
   }
 
   private handleUnsupportedVersion(version: OCPPVersion) {
-    const errMsg = `${this.logPrefix()} Unsupported protocol version '${version}' configured in template file ${
-      this.templateFile
-    }`;
-    logger.error(errMsg);
+    const errMsg = `Unsupported protocol version '${version}' configured in template file ${this.templateFile}`;
+    logger.error(`${this.logPrefix()} ${errMsg}`);
     throw new BaseError(errMsg);
   }
 
@@ -1142,10 +1140,8 @@ export default class ChargingStation {
     templateMaxConnectors: number
   ): void {
     if (!stationInfo?.Connectors && this.connectors.size === 0) {
-      const logMsg = `${this.logPrefix()} No already defined connectors and charging station information from template ${
-        this.templateFile
-      } with no connectors configuration defined`;
-      logger.error(logMsg);
+      const logMsg = `No already defined connectors and charging station information from template ${this.templateFile} with no connectors configuration defined`;
+      logger.error(`${this.logPrefix()} ${logMsg}`);
       throw new BaseError(logMsg);
     }
     if (!stationInfo?.Connectors[0]) {
@@ -1506,8 +1502,8 @@ export default class ChargingStation {
           // Error
           default:
             // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
-            errMsg = `${this.logPrefix()} Wrong message type ${messageType}`;
-            logger.error(errMsg);
+            errMsg = `Wrong message type ${messageType}`;
+            logger.error(`${this.logPrefix()} ${errMsg}`);
             throw new OCPPError(ErrorType.PROTOCOL_ERROR, errMsg);
         }
         parentPort.postMessage(MessageChannelUtils.buildUpdatedMessage(this));
@@ -1519,19 +1515,18 @@ export default class ChargingStation {
     } catch (error) {
       // Log
       logger.error(
-        "%s Incoming OCPP '%s' message '%j' matching cached request '%j' processing error:",
-        this.logPrefix(),
-        commandName ?? requestCommandName ?? null,
-        data.toString(),
-        this.requests.get(messageId),
+        `${this.logPrefix()} Incoming OCPP '${
+          commandName ?? requestCommandName ?? null
+        }' message '${data.toString()}' matching cached request '${JSON.stringify(
+          this.requests.get(messageId)
+        )}' processing error:`,
         error
       );
       if (!(error instanceof OCPPError)) {
         logger.warn(
-          "%s Error thrown at incoming OCPP '%s' message '%j' handling is not an OCPPError:",
-          this.logPrefix(),
-          commandName ?? requestCommandName ?? null,
-          data.toString(),
+          `${this.logPrefix()} Error thrown at incoming OCPP '${
+            commandName ?? requestCommandName ?? null
+          }' message '${data.toString()}' handling is not an OCPPError:`,
           error
         );
       }
index 645fbd95f31aea77430cc43e9163aa69848acde3..8978f0c8805fcf4c01c733bad855415f84a60710 100644 (file)
@@ -426,7 +426,7 @@ export class ChargingStationUtils {
     templateFile: string,
     logPrefix: string
   ): Voltage {
-    const errMsg = `${logPrefix} Unknown ${currentType} currentOutType in template file ${templateFile}, cannot define default voltage out`;
+    const errMsg = `Unknown ${currentType} currentOutType in template file ${templateFile}, cannot define default voltage out`;
     let defaultVoltageOut: number;
     switch (currentType) {
       case CurrentType.AC:
@@ -436,7 +436,7 @@ export class ChargingStationUtils {
         defaultVoltageOut = Voltage.VOLTAGE_400;
         break;
       default:
-        logger.error(errMsg);
+        logger.error(`${logPrefix} ${errMsg}`);
         throw new BaseError(errMsg);
     }
     return defaultVoltageOut;
@@ -514,8 +514,8 @@ export class ChargingStationUtils {
       }
     }
     if (measurand === MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) {
-      const errorMsg = `${chargingStation.logPrefix()} Missing MeterValues for default measurand '${measurand}' in template on connectorId ${connectorId}`;
-      logger.error(errorMsg);
+      const errorMsg = `Missing MeterValues for default measurand '${measurand}' in template on connectorId ${connectorId}`;
+      logger.error(`${chargingStation.logPrefix()} ${errorMsg}`);
       throw new BaseError(errorMsg);
     }
     logger.debug(
index 3084a38899c40789979ea9314614ea5a1bb063d0..4cf037ba28e890dbb82eeae840dcc42bf221dbb5 100644 (file)
@@ -55,7 +55,9 @@ export class MessageChannelUtils {
       stationInfo: chargingStation.stationInfo,
       stopped: chargingStation.stopped,
       bootNotificationResponse: chargingStation.bootNotificationResponse,
-      connectors: Array.from(chargingStation.connectors.values()),
+      connectors: Array.from(chargingStation.connectors.values()).map(
+        ({ transactionSetInterval, ...connectorStatusRest }) => connectorStatusRest
+      ),
     };
   }
 }
index 70ae3c258445285b18a183794cb6765bba33dccc..d765e1d25826d1e452b38d025845f26c287bf9a7 100644 (file)
@@ -417,14 +417,14 @@ export default class OCPP16ResponseService extends OCPPResponseService {
       );
       return;
     }
-    if (!Number.isInteger(payload.transactionId)) {
-      logger.warn(
-        `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()} with a non integer transaction Id ${
-          payload.transactionId
-        }, converting to integer`
-      );
-      payload.transactionId = Utils.convertToInt(payload.transactionId);
-    }
+    // if (!Number.isInteger(payload.transactionId)) {
+    //   logger.warn(
+    //     `${chargingStation.logPrefix()} Trying to start a transaction on connector ${connectorId.toString()} with a non integer transaction Id ${
+    //       payload.transactionId
+    //     }, converting to integer`
+    //   );
+    //   payload.transactionId = Utils.convertToInt(payload.transactionId);
+    // }
 
     if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) {
       chargingStation.getConnectorStatus(connectorId).transactionStarted = true;
@@ -489,8 +489,9 @@ export default class OCPP16ResponseService extends OCPPResponseService {
           payload.transactionId.toString() +
           " REJECTED with status '" +
           payload?.idTagInfo?.status +
-          "', idTag " +
-          requestPayload.idTag
+          "', idTag '" +
+          requestPayload.idTag +
+          "'"
       );
       await this.resetConnectorOnStartTransactionError(chargingStation, connectorId);
     }
index 0915aa462b3fa70deefacd04cdcdc9918063c2fc..62fa8e50b19a7617654157e887a9639d37113d2c 100644 (file)
@@ -224,7 +224,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils {
         chargingStation,
         powerSampledValueTemplate.measurand
       );
-      const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${
+      const errMsg = `MeterValues measurand ${
         powerSampledValueTemplate.measurand ??
         OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
       }: Unknown ${chargingStation.getCurrentOutType()} currentOutType in template file ${
@@ -334,7 +334,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils {
             : Utils.getRandomFloatRounded(connectorMaximumPower / unitDivider);
           break;
         default:
-          logger.error(errMsg);
+          logger.error(`${chargingStation.logPrefix()} ${errMsg}`);
           throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
       }
       meterValue.sampledValue.push(
@@ -431,7 +431,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils {
         chargingStation,
         currentSampledValueTemplate.measurand
       );
-      const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${
+      const errMsg = `MeterValues measurand ${
         currentSampledValueTemplate.measurand ??
         OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
       }: Unknown ${chargingStation.getCurrentOutType()} currentOutType in template file ${
@@ -547,7 +547,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils {
             : Utils.getRandomFloatRounded(connectorMaximumAmperage);
           break;
         default:
-          logger.error(errMsg);
+          logger.error(`${chargingStation.logPrefix()} ${errMsg}`);
           throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
       }
       meterValue.sampledValue.push(
@@ -770,16 +770,16 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils {
     measurandType: OCPP16MeterValueMeasurand
   ): void {
     if (Utils.isUndefined(chargingStation.powerDivider)) {
-      const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${
+      const errMsg = `MeterValues measurand ${
         measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
       }: powerDivider is undefined`;
-      logger.error(errMsg);
+      logger.error(`${chargingStation.logPrefix()} ${errMsg}`);
       throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
     } else if (chargingStation?.powerDivider <= 0) {
-      const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${
+      const errMsg = `MeterValues measurand ${
         measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
       }: powerDivider have zero or below value ${chargingStation.powerDivider}`;
-      logger.error(errMsg);
+      logger.error(`${chargingStation.logPrefix()} ${errMsg}`);
       throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
     }
   }
index 4b68b8a8be7483f7b53a03555d5faa70995986f4..2ee0465cb583476288289fdd9523d637b2fbde27 100644 (file)
@@ -37,8 +37,7 @@ export default abstract class OCPPIncomingRequestService {
     params: HandleErrorParams<T> = { throwError: true }
   ): T {
     logger.error(
-      `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command %s error:`,
-      commandName,
+      `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command ${commandName} error:`,
       error
     );
     if (!params?.throwError && params?.errorResponse) {
index c3311b856d3a21e267dd52141715a9a3cd6bc72d..25c8943564a7f91afc639c22a7f99a0a28d247d9 100644 (file)
@@ -268,10 +268,10 @@ export default abstract class OCPPRequestService {
               );
             }
             logger.error(
-              `${chargingStation.logPrefix()} Error %j occurred when calling command %s with message data %j`,
-              error,
-              commandName,
-              messagePayload
+              `${chargingStation.logPrefix()} Error occurred when calling command ${commandName} with message data ${JSON.stringify(
+                messagePayload
+              )}:`,
+              error
             );
             chargingStation.requests.delete(messageId);
             reject(error);
@@ -361,7 +361,7 @@ export default abstract class OCPPRequestService {
     error: Error,
     params: HandleErrorParams<EmptyObject> = { throwError: true }
   ): void {
-    logger.error(chargingStation.logPrefix() + ' Request command %s error:', commandName, error);
+    logger.error(`${chargingStation.logPrefix()} Request command ${commandName} error:`, error);
     if (params?.throwError) {
       throw error;
     }
index 8050bbce3844989f042d586a44f5f6420d37c3d1..03e86c5118b8ea806f26bb2525bf42cb9ca64606 100644 (file)
@@ -2,11 +2,11 @@
   "name": "webui",
   "version": "0.1.0",
   "scripts": {
+    "start": "npm run build && node start.js",
     "serve": "vue-cli-service serve",
     "build": "vue-cli-service build",
     "lint": "vue-cli-service lint",
     "lint:fix": "vue-cli-service lint --fix",
-    "start": "npm run build && node start.js",
     "test": "vue-cli-service test:unit"
   },
   "dependencies": {
index fb50b2f5a919c77fbfd85c2a4adc844ac99b178f..c76d9e4d1eda6d9fc190eee8cd00f47c4fa42bd0 100644 (file)
@@ -51,8 +51,8 @@ const props = defineProps<{
 #cs-table__head,
 #cs-table__body {
   width: 100%;
-  display: block;
   min-width: 930px;
+  display: block;
 }
 
 #cs-table__body {
index d324acc5a54fedbf34af830885bd38574fc1140a..22871d688b42d400648ec63000d0ccd9efd3b52b 100644 (file)
@@ -43,4 +43,5 @@ export enum ResponseStatus {
 
 export interface ResponsePayload extends JsonObject {
   status: ResponseStatus;
+  hashIds?: string[];
 }