Make the station worker self contained.
authorJérôme Benoit <jerome.benoit@sap.com>
Sat, 17 Oct 2020 14:47:53 +0000 (16:47 +0200)
committerJérôme Benoit <jerome.benoit@sap.com>
Sat, 17 Oct 2020 14:47:53 +0000 (16:47 +0200)
And various other cleanups.

Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
31 files changed:
.vscode/settings.json [new file with mode: 0644]
src/assets/authorization-tags.json [new file with mode: 0644]
src/assets/config-template.json
src/assets/station-templates/abb.station-template.json [new file with mode: 0644]
src/assets/station-templates/evlink.station-template.json [new file with mode: 0644]
src/assets/station-templates/keba.station-template.json [new file with mode: 0644]
src/assets/station-templates/schneider-imredd.station-template.json [new file with mode: 0644]
src/assets/station-templates/schneider.station-template.json [new file with mode: 0644]
src/assets/station-templates/siemens.mougins69.station-template.json [new file with mode: 0644]
src/assets/station-templates/virtual-simple-atg.station-template.json [new file with mode: 0644]
src/assets/station-templates/virtual-simple.station-template.json [new file with mode: 0644]
src/assets/station-templates/virtual.station-template.json [new file with mode: 0644]
src/assets/station/abb.station [deleted file]
src/assets/station/evlink.station [deleted file]
src/assets/station/keba.station [deleted file]
src/assets/station/schneider-imredd.station [deleted file]
src/assets/station/schneider.station [deleted file]
src/assets/station/siemens.mougins69.station [deleted file]
src/assets/station/virtual-simple-atg.station [deleted file]
src/assets/station/virtual-simple.station [deleted file]
src/assets/station/virtual.station [deleted file]
src/assets/templateAuthorization.auth [deleted file]
src/charging-station/AutomaticTransactionGenerator.js
src/charging-station/ChargingStation.js
src/charging-station/StationWorker.js
src/index.js
src/utils/Configuration.js
src/utils/Constants.js
src/utils/Logger.js
src/utils/Statistics.js
src/utils/Utils.js

diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644 (file)
index 0000000..246e9c6
--- /dev/null
@@ -0,0 +1,5 @@
+{
+  "editor.codeActionsOnSave": {
+    "source.fixAll.eslint": true
+  }
+}
diff --git a/src/assets/authorization-tags.json b/src/assets/authorization-tags.json
new file mode 100644 (file)
index 0000000..4ea9409
--- /dev/null
@@ -0,0 +1,247 @@
+[
+  "007",
+  "0080001EDBA4E1",
+  "00B700FE0CA4E1",
+  "00E1007E6BA4E1",
+  "030163E9",
+  "037A60E9",
+  "0422A5F2464B80",
+  "048F9F7B",
+  "04DA521AA74880",
+  "070000155AE117",
+  "070000155AE119",
+  "070000155AE11A",
+  "070000155AE11F",
+  "070000155AE121",
+  "070000155AE1BF",
+  "070000155AE1C0",
+  "070000155AE1C1",
+  "07000015AAB292",
+  "07000015AAB293",
+  "07000015AAEAB3",
+  "07000015AAEAB4",
+  "07000015AAEAB5",
+  "07000015AAEAB6",
+  "07000015AAEAB7",
+  "07000015AAEAB8",
+  "07000015AAEAB9",
+  "07000015AAEABB",
+  "07000015AAEABC",
+  "07000015AE119",
+  "087B22D1",
+  "08C1B4F7",
+  "0A847D05",
+  "0A8CBBE6",
+  "0AEA7C05",
+  "0BC217AD",
+  "0BE715AD",
+  "0C029E16",
+  "0CC39E16",
+  "0E3BA5E1",
+  "0E9783CB",
+  "0E9B83CB",
+  "13926AEF",
+  "168A05D0",
+  "16A591B3",
+  "1A21BDE6",
+  "1AF17F05",
+  "1B1A1BAD",
+  "1BD215AD",
+  "1BD51AAD",
+  "1C3B0952",
+  "1C440752",
+  "1C74A216",
+  "1C751002",
+  "1CE50F02",
+  "1CEA0D02",
+  "1E3AA5E1",
+  "1E656DCB",
+  "1ECF6CCB",
+  "1EDBA4E1",
+  "2A7ABDE6",
+  "2A8B7F05",
+  "2B5D19AD",
+  "2C73A116",
+  "2E020D00000000",
+  "2E566CCB",
+  "2E5769CB",
+  "33F161E9",
+  "363306D0",
+  "3A407B05",
+  "3A5E8105",
+  "3A877B05",
+  "3B6F18AD",
+  "3BC317AD",
+  "3BF019AD",
+  "3BF616AD",
+  "3BFB1522",
+  "3C310B02",
+  "3E219E12",
+  "3E7B6ECB",
+  "43329EF7",
+  "43E562E9",
+  "4CAA9414",
+  "4CB69E16",
+  "4CF70F02",
+  "4EF282CB",
+  "521B7C04",
+  "530B63E9",
+  "53D898F7",
+  "53F762E9",
+  "590153",
+  "5A727C05",
+  "5CA50D02",
+  "5D37367F",
+  "5E65CB60",
+  "5E806BCB",
+  "5E886DCB",
+  "630D63E9",
+  "640D1821",
+  "696E1E10",
+  "6A08BAE6",
+  "6A1D6E3C",
+  "6AAE7B05",
+  "6B0918AD",
+  "6B8BB4EE",
+  "6C13A216",
+  "6C610A02",
+  "6E26A5E1",
+  "6E666CCB",
+  "6E6869CB",
+  "7099C291",
+  "730399F7",
+  "7376B3DD",
+  "73C862E9",
+  "7A177E05",
+  "7A3DBBE6",
+  "7B1B1AAD",
+  "7B3B1AAD",
+  "7B8278E6",
+  "7C519414",
+  "7CA70C02",
+  "7E586ACB",
+  "7E6BA4E1",
+  "7EF168CB",
+  "8A457C05",
+  "930862E9",
+  "931063E9",
+  "93E8B1DD",
+  "9A3C7E05",
+  "9AA18105",
+  "9C4D0B02",
+  "9CE20C02",
+  "9CFA0D02",
+  "9E806ECB",
+  "9E936BCB",
+  "9E956DCB",
+  "A20D2107",
+  "A3C3B1DD",
+  "A48FFFCC",
+  "AA417B05",
+  "ABB21AAD",
+  "AC1CC50D",
+  "ACB99E16",
+  "AD1A6A4B",
+  "ADMINIT",
+  "ADUFIRHG",
+  "AE4FC860",
+  "AEF76DCB",
+  "AJ67365NCA",
+  "B31FB2DD",
+  "B3CAA2F7",
+  "B650B67E6BA4E1",
+  "BB6B18AD",
+  "BB9019AD",
+  "BBA7B2EE",
+  "BC0E0E02",
+  "BC510A02",
+  "BC9B0B02",
+  "BC9E9714",
+  "BE5469CB",
+  "BEA6C760",
+  "BECEA2E1",
+  "BEEAABE1",
+  "C41F1821",
+  "C69505D0",
+  "CA1C8105",
+  "CA637F05",
+  "CA65BCE6",
+  "CB071AAD",
+  "CBFF17AD",
+  "CC211002",
+  "CC7B0552",
+  "CCA30E02",
+  "CD64CD4C",
+  "CE18A012",
+  "CEDAA4E1",
+  "CJ00001",
+  "CL844776NCA",
+  "CR1602274633",
+  "CV00001",
+  "CV737334672",
+  "D3AFB3DD",
+  "D62706D0",
+  "D6C106D0",
+  "DA00001",
+  "DA15BEE6",
+  "DA9CBDE6",
+  "DB081BAD",
+  "DB9419AD",
+  "DC970C02",
+  "DE246CCB",
+  "DEMO",
+  "DEMOADMIN",
+  "DEMOBASIC",
+  "DM00001",
+  "E3FFA0F7",
+  "E6EA04D0",
+  "E766EF25",
+  "EAB17D05",
+  "EBE819AD",
+  "EC849E16",
+  "ECA10B02",
+  "F35C9FF7",
+  "F3B2B3DD",
+  "F3C0B4DD",
+  "F3CFB1DD",
+  "F66393B3",
+  "F68805D0",
+  "FAFABDE6",
+  "FB2A1BAD",
+  "FC4E0952",
+  "FE0CA4E1",
+  "FE2DA3E1",
+  "FE5069CB",
+  "FE5A6ACB",
+  "FE6D6ECB",
+  "FED86CCB",
+  "FF00001",
+  "FO00001",
+  "FS553378971",
+  "GF1287569582",
+  "GN00001",
+  "GS00001",
+  "HC1777052478",
+  "JM0001",
+  "KA00001",
+  "KO00001",
+  "LA17469521",
+  "LC20181002",
+  "MA00001",
+  "MS498782046",
+  "OF00001",
+  "PP162826911",
+  "RC733661034",
+  "SB1542003451",
+  "SL00001",
+  "SR00001",
+  "TESTADMINID",
+  "UNDEFINED",
+  "US00001",
+  "VN00001",
+  "mr20181005",
+  "rf2005127191",
+  "C3E4B3DD",
+  "GD5JD6GN",
+  "BB2TBR09"
+]
index ad8ec20153d09baa3f4bc7544a2b9b249a899c7e..60f1d2d1a255506e056dca71caabc3d6536f6481 100644 (file)
   "workerPoolSize": 16,
   "stationTemplateURLs": [
     {
-      "file": "./src/assets/station/siemens.mougins69.station",
+      "file": "./src/assets/station-templates/siemens.mougins69.station-template.json-template.json",
       "numberOfStation": 1
     },
     {
-      "file": "./src/assets/station/keba.station",
+      "file": "./src/assets/station-templates/keba.station-template.json-template.json",
       "numberOfStation": 2
     },
     {
-      "file": "./src/assets/station/abb.station",
+      "file": "./src/assets/station-templates/abb.station-template.json",
       "numberOfStation": 2
     },
     {
-      "file": "./src/assets/station/evlink.station",
+      "file": "./src/assets/station-templates/evlink.station-template.json",
       "numberOfStation": 4
     },
     {
-      "file": "./src/assets/station/schneider.station",
+      "file": "./src/assets/station-templates/schneider.station-template.json",
       "numberOfStation": 1
     }
   ],
-  "consoleLog": false,
   "logFile": "combined.log",
-  "errorFile": "error.log"
+  "errorFile": "error.log",
+  "consoleLog": false
 }
diff --git a/src/assets/station-templates/abb.station-template.json b/src/assets/station-templates/abb.station-template.json
new file mode 100644 (file)
index 0000000..161febe
--- /dev/null
@@ -0,0 +1,79 @@
+{
+  "authorizationFile": "./src/assets/authorization-tags.json",
+  "baseName": "CS-ABB",
+  "chargePointModel": "ABB 5678",
+  "chargePointVendor": "ABB",
+  "power": 50000,
+  "powerUnit": "W",
+  "numberOfConnectors": 2,
+  "randomConnectors": false,
+  "Configuration": {
+    "configurationKey": [
+      {
+        "key": "NumberOfConnectors",
+        "readonly": true,
+        "value": 2
+      },
+      {
+        "key": "MeterValueSampleInterval",
+        "readonly": false,
+        "value": 30
+      },
+      {
+        "key": "SupportedFeatureProfiles",
+        "readonly": true,
+        "value": "Core,LocalAuthListManagement"
+      },
+      {
+        "key": "LocalAuthListEnabled",
+        "readonly": false,
+        "value": false
+      },
+      {
+        "key": "AuthorizeRemoteTxRequests",
+        "readonly": false,
+        "value": false
+      }
+    ]
+  },
+  "AutomaticTransactionGenerator": {
+    "enable": false,
+    "minDuration": 60,
+    "maxDuration": 80,
+    "minDelayBetweenTwoTransaction": 15,
+    "maxDelayBetweenTwoTransaction": 30,
+    "probabilityOfStart": 1,
+    "stopAutomaticTransactionGeneratorAfterHours": 0.3
+  },
+  "Connectors": {
+    "0": {},
+    "1": {
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "2": {
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/assets/station-templates/evlink.station-template.json b/src/assets/station-templates/evlink.station-template.json
new file mode 100644 (file)
index 0000000..9525117
--- /dev/null
@@ -0,0 +1,58 @@
+{
+  "authorizationFile": "./src/assets/authorization-tags.json",
+  "baseName": "CS-EVLINK",
+  "chargePointModel": "EVLINKXX213",
+  "chargePointVendor": "SCHNEIDER",
+  "power": 7340,
+  "powerUnit": "W",
+  "numberOfConnectors": 1,
+  "randomConnectors": false,
+  "Configuration": {
+    "configurationKey": [
+      {
+        "key": "NumberOfConnectors",
+        "readonly": true,
+        "value": 1
+      },
+      {
+        "key": "MeterValueSampleInterval",
+        "readonly": false,
+        "value": 20
+      },
+      {
+        "key": "SupportedFeatureProfiles",
+        "readonly": true,
+        "value": "Core,LocalAuthListManagement"
+      },
+      {
+        "key": "LocalAuthListEnabled",
+        "readonly": false,
+        "value": false
+      },
+      {
+        "key": "AuthorizeRemoteTxRequests",
+        "readonly": false,
+        "value": false
+      }
+    ]
+  },
+  "AutomaticTransactionGenerator": {
+    "enable": false,
+    "minDuration": 60,
+    "maxDuration": 80,
+    "minDelayBetweenTwoTransaction": 15,
+    "maxDelayBetweenTwoTransaction": 30,
+    "probabilityOfStart": 1,
+    "stopAutomaticTransactionGeneratorAfterHours": 0.3
+  },
+  "Connectors": {
+    "1": {
+      "MeterValues": [
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/assets/station-templates/keba.station-template.json b/src/assets/station-templates/keba.station-template.json
new file mode 100644 (file)
index 0000000..8c00f7c
--- /dev/null
@@ -0,0 +1,66 @@
+{
+  "authorizationFile": "./src/assets/authorization-tags.json",
+  "baseName": "CS-KEBA",
+  "chargePointModel": "KC-P30-ESS400C2-E0R",
+  "chargePointVendor": "Keba AG",
+  "power": 22000,
+  "powerUnit": "W",
+  "numberOfConnectors": 1,
+  "randomConnectors": false,
+  "Configuration": {
+    "configurationKey": [
+      {
+        "key": "NumberOfConnectors",
+        "readonly": true,
+        "value": 2
+      },
+      {
+        "key": "MeterValueSampleInterval",
+        "readonly": false,
+        "value": 30
+      },
+      {
+        "key": "SupportedFeatureProfiles",
+        "readonly": true,
+        "value": "Core,LocalAuthListManagement"
+      },
+      {
+        "key": "LocalAuthListEnabled",
+        "readonly": false,
+        "value": false
+      },
+      {
+        "key": "AuthorizeRemoteTxRequests",
+        "readonly": false,
+        "value": false
+      }
+    ]
+  },
+  "AutomaticTransactionGenerator": {
+    "enable": false,
+    "minDuration": 30,
+    "maxDuration": 60,
+    "minDelayBetweenTwoTransaction": 15,
+    "maxDelayBetweenTwoTransaction": 30,
+    "probabilityOfStart": 1,
+    "stopAutomaticTransactionGeneratorAfterHours": 0.3
+  },
+  "Connectors": {
+    "1": {
+      "MeterValues": [
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "2": {
+      "MeterValues": [
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/assets/station-templates/schneider-imredd.station-template.json b/src/assets/station-templates/schneider-imredd.station-template.json
new file mode 100644 (file)
index 0000000..26c92a6
--- /dev/null
@@ -0,0 +1,66 @@
+{
+  "authorizationFile": "./src/assets/authorization-tags.json",
+  "baseName": "CS-SCHNEIDER",
+  "chargePointModel": "SCHNEIDERXX213",
+  "chargePointVendor": "SCHNEIDER",
+  "power": 44000,
+  "powerUnit": "W",
+  "numberOfConnectors": 2,
+  "randomConnectors": false,
+  "Configuration": {
+    "configurationKey": [
+      {
+        "key": "NumberOfConnectors",
+        "readonly": true,
+        "value": 2
+      },
+      {
+        "key": "MeterValueSampleInterval",
+        "readonly": false,
+        "value": 20
+      },
+      {
+        "key": "SupportedFeatureProfiles",
+        "readonly": true,
+        "value": "Core,LocalAuthListManagement"
+      },
+      {
+        "key": "LocalAuthListEnabled",
+        "readonly": false,
+        "value": false
+      },
+      {
+        "key": "AuthorizeRemoteTxRequests",
+        "readonly": false,
+        "value": false
+      }
+    ]
+  },
+  "AutomaticTransactionGenerator": {
+    "enable": false,
+    "minDuration": 60,
+    "maxDuration": 80,
+    "minDelayBetweenTwoTransaction": 15,
+    "maxDelayBetweenTwoTransaction": 30,
+    "probabilityOfStart": 1,
+    "stopAutomaticTransactionGeneratorAfterHours": 0.3
+  },
+  "Connectors": {
+    "1": {
+      "MeterValues": [
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "2": {
+      "MeterValues": [
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/assets/station-templates/schneider.station-template.json b/src/assets/station-templates/schneider.station-template.json
new file mode 100644 (file)
index 0000000..26c92a6
--- /dev/null
@@ -0,0 +1,66 @@
+{
+  "authorizationFile": "./src/assets/authorization-tags.json",
+  "baseName": "CS-SCHNEIDER",
+  "chargePointModel": "SCHNEIDERXX213",
+  "chargePointVendor": "SCHNEIDER",
+  "power": 44000,
+  "powerUnit": "W",
+  "numberOfConnectors": 2,
+  "randomConnectors": false,
+  "Configuration": {
+    "configurationKey": [
+      {
+        "key": "NumberOfConnectors",
+        "readonly": true,
+        "value": 2
+      },
+      {
+        "key": "MeterValueSampleInterval",
+        "readonly": false,
+        "value": 20
+      },
+      {
+        "key": "SupportedFeatureProfiles",
+        "readonly": true,
+        "value": "Core,LocalAuthListManagement"
+      },
+      {
+        "key": "LocalAuthListEnabled",
+        "readonly": false,
+        "value": false
+      },
+      {
+        "key": "AuthorizeRemoteTxRequests",
+        "readonly": false,
+        "value": false
+      }
+    ]
+  },
+  "AutomaticTransactionGenerator": {
+    "enable": false,
+    "minDuration": 60,
+    "maxDuration": 80,
+    "minDelayBetweenTwoTransaction": 15,
+    "maxDelayBetweenTwoTransaction": 30,
+    "probabilityOfStart": 1,
+    "stopAutomaticTransactionGeneratorAfterHours": 0.3
+  },
+  "Connectors": {
+    "1": {
+      "MeterValues": [
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "2": {
+      "MeterValues": [
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/assets/station-templates/siemens.mougins69.station-template.json b/src/assets/station-templates/siemens.mougins69.station-template.json
new file mode 100644 (file)
index 0000000..87a538a
--- /dev/null
@@ -0,0 +1,70 @@
+{
+  "authorizationFile": "./src/assets/authorization-tags.json",
+  "baseName": "SAP-Mougins-69",
+  "fixedName": true,
+  "chargePointModel": "SiemensXX213",
+  "chargePointVendor": "SIEMENS",
+  "power": 44000,
+  "powerUnit": "W",
+  "numberOfConnectors": 2,
+  "randomConnectors": false,
+  "Configuration": {
+    "configurationKey": [
+      {
+        "key": "NumberOfConnectors",
+        "readonly": true,
+        "value": 2
+      },
+      {
+        "key": "MeterValueSampleInterval",
+        "readonly": false,
+        "value": 30
+      },
+      {
+        "key": "SupportedFeatureProfiles",
+        "readonly": true,
+        "value": "Core,LocalAuthListManagement"
+      },
+      {
+        "key": "LocalAuthListEnabled",
+        "readonly": false,
+        "value": false
+      },
+      {
+        "key": "AuthorizeRemoteTxRequests",
+        "readonly": false,
+        "value": false
+      }
+    ]
+  },
+  "AutomaticTransactionGenerator": {
+    "enable": false,
+    "minDuration": 60,
+    "maxDuration": 80,
+    "minDelayBetweenTwoTransaction": 15,
+    "maxDelayBetweenTwoTransaction": 30,
+    "probabilityOfStart": 1,
+    "stopAutomaticTransactionGeneratorAfterHours": 0.3
+  },
+  "Connectors": {
+    "1": {
+      "bootStatus": "Unavailable",
+      "MeterValues": [
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "2": {
+      "MeterValues": [
+        {
+          "context": "Sample.Periodic",
+          "format": "Raw",
+          "measurand": "Energey.Active.Import.Register",
+          "unit": "Wh"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/assets/station-templates/virtual-simple-atg.station-template.json b/src/assets/station-templates/virtual-simple-atg.station-template.json
new file mode 100644 (file)
index 0000000..fcc8095
--- /dev/null
@@ -0,0 +1,96 @@
+{
+  "authorizationFile": "./src/assets/authorization-tags.json",
+  "baseName": "CS-BASIC",
+  "chargePointModel": "Simulator simple",
+  "chargePointVendor": "Ovomaltin",
+  "power": 75000,
+  "powerUnit": "W",
+  "numberOfConnectors": 3,
+  "randomConnectors": false,
+  "Configuration": {
+    "configurationKey": [
+      {
+        "key": "NumberOfConnectors",
+        "readonly": true,
+        "value": 3
+      },
+      {
+        "key": "MeterValueSampleInterval",
+        "readonly": false,
+        "value": 30
+      },
+      {
+        "key": "SupportedFeatureProfiles",
+        "readonly": true,
+        "value": "Core,LocalAuthListManagement"
+      },
+      {
+        "key": "LocalAuthListEnabled",
+        "readonly": false,
+        "value": false
+      },
+      {
+        "key": "AuthorizeRemoteTxRequests",
+        "readonly": false,
+        "value": false
+      }
+    ]
+  },
+  "AutomaticTransactionGenerator": {
+    "enable": true,
+    "minDuration": 60,
+    "maxDuration": 80,
+    "minDelayBetweenTwoTransaction": 15,
+    "maxDelayBetweenTwoTransaction": 30,
+    "probabilityOfStart": 1,
+    "stopAutomaticTransactionGeneratorAfterHours": 0.3
+  },
+  "Connectors": {
+    "0": {},
+    "1": {
+      "bootStatus": "Available",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "2": {
+      "bootStatus": "Preparing",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "3": {
+      "bootStatus": "Faulted",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/assets/station-templates/virtual-simple.station-template.json b/src/assets/station-templates/virtual-simple.station-template.json
new file mode 100644 (file)
index 0000000..0bef7cf
--- /dev/null
@@ -0,0 +1,96 @@
+{
+  "authorizationFile": "./src/assets/authorization-tags.json",
+  "baseName": "CS-BASIC",
+  "chargePointModel": "Simulator simple",
+  "chargePointVendor": "Ovomaltin",
+  "power": 50000,
+  "powerUnit": "W",
+  "numberOfConnectors": 3,
+  "randomConnectors": false,
+  "Configuration": {
+    "configurationKey": [
+      {
+        "key": "NumberOfConnectors",
+        "readonly": true,
+        "value": 3
+      },
+      {
+        "key": "MeterValueSampleInterval",
+        "readonly": false,
+        "value": 30
+      },
+      {
+        "key": "SupportedFeatureProfiles",
+        "readonly": true,
+        "value": "Core,LocalAuthListManagement"
+      },
+      {
+        "key": "LocalAuthListEnabled",
+        "readonly": false,
+        "value": false
+      },
+      {
+        "key": "AuthorizeRemoteTxRequests",
+        "readonly": false,
+        "value": false
+      }
+    ]
+  },
+  "AutomaticTransactionGenerator": {
+    "enable": false,
+    "minDuration": 60,
+    "maxDuration": 80,
+    "minDelayBetweenTwoTransaction": 15,
+    "maxDelayBetweenTwoTransaction": 30,
+    "probabilityOfStart": 1,
+    "stopAutomaticTransactionGeneratorAfterHours": 0.3
+  },
+  "Connectors": {
+    "0": {},
+    "1": {
+      "bootStatus": "Available",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "2": {
+      "bootStatus": "Preparing",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "3": {
+      "bootStatus": "Faulted",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/assets/station-templates/virtual.station-template.json b/src/assets/station-templates/virtual.station-template.json
new file mode 100644 (file)
index 0000000..6eb7d2e
--- /dev/null
@@ -0,0 +1,186 @@
+{
+  "authorizationFile": "./src/assets/authorization-tags.json",
+  "baseName": "CS-SIMU",
+  "chargePointModel": "Simulator connectors",
+  "chargePointVendor": "Ovomaltin",
+  "power": 50000,
+  "powerUnit": "W",
+  "numberOfConnectors": 9,
+  "randomConnectors": false,
+  "Configuration": {
+    "configurationKey": [
+      {
+        "key": "NumberOfConnectors",
+        "readonly": true,
+        "value": 9
+      },
+      {
+        "key": "MeterValueSampleInterval",
+        "readonly": false,
+        "value": 30
+      },
+      {
+        "key": "SupportedFeatureProfiles",
+        "readonly": true,
+        "value": "Core,LocalAuthListManagement"
+      },
+      {
+        "key": "LocalAuthListEnabled",
+        "readonly": false,
+        "value": false
+      },
+      {
+        "key": "AuthorizeRemoteTxRequests",
+        "readonly": false,
+        "value": false
+      }
+    ]
+  },
+  "AutomaticTransactionGenerator": {
+    "enable": false,
+    "minDuration": 60,
+    "maxDuration": 80,
+    "minDelayBetweenTwoTransaction": 15,
+    "maxDelayBetweenTwoTransaction": 30,
+    "probabilityOfStart": 1,
+    "stopAutomaticTransactionGeneratorAfterHours": 0.3
+  },
+  "Connectors": {
+    "0": {},
+    "1": {
+      "bootStatus": "Available",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "2": {
+      "bootStatus": "Preparing",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "3": {
+      "bootStatus": "SuspendedEVSE",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "4": {
+      "bootStatus": "SuspendedEV",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "5": {
+      "bootStatus": "Finishing",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "6": {
+      "bootStatus": "Reserved",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "7": {
+      "bootStatus": "Charging",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "8": {
+      "bootStatus": "Unavailable",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    },
+    "9": {
+      "bootStatus": "Faulted",
+      "MeterValues": [
+        {
+          "unit": "Percent",
+          "context": "Sample.Periodic",
+          "measurand": "SoC",
+          "location": "EV"
+        },
+        {
+          "unit": "Wh",
+          "context": "Sample.Periodic"
+        }
+      ]
+    }
+  }
+}
diff --git a/src/assets/station/abb.station b/src/assets/station/abb.station
deleted file mode 100644 (file)
index 1335a77..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-{
-    "authorizationFile": "./src/assets/templateAuthorization.auth",
-    "baseName": "CS-ABB",
-    "chargePointModel": "ABB 5678",
-    "chargePointVendor": "ABB",
-    "power": 50000,
-    "powerUnit": "W",
-    "numberOfConnectors": 2,
-    "randomConnectors": false,
-    "Configuration": { "configurationKey": [
-            { "key": "NumberOfConnectors", "readonly": true, "value": 2},
-            { "key": "MeterValueSampleInterval", "readonly": false, "value": 30},
-            { "key": "SupportedFeatureProfiles", "readonly": true, "value": "Core,LocalAuthListManagement"},
-            { "key": "LocalAuthListEnabled", "readonly": false, "value": false},
-            { "key": "AuthorizeRemoteTxRequests", "readonly": false, "value": false}
-        ]
-    },
-    "AutomaticTransactionGenerator": {
-        "enable": false,
-        "minDuration": 60,
-        "maxDuration": 80,
-        "minDelayBetweenTwoTransaction": 15,
-        "maxDelayBetweenTwoTransaction": 30,
-        "probabilityOfStart": 1,
-        "stopAutomaticTransactionGeneratorAfterHours": 0.3
-    },
-    "Connectors": {
-        "0": {
-
-        },
-        "1": {
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "2": {
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        }
-    }
-}
diff --git a/src/assets/station/evlink.station b/src/assets/station/evlink.station
deleted file mode 100644 (file)
index ac8418c..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-{
-    "authorizationFile": "./src/assets/templateAuthorization.auth",
-    "baseName": "CS-EVLINK",
-    "chargePointModel": "EVLINKXX213",
-    "chargePointVendor": "SCHNEIDER",
-    "power": 7340,
-    "powerUnit": "W",
-    "numberOfConnectors": 1,
-    "randomConnectors": false,
-    "Configuration": { "configurationKey": [
-            { "key": "NumberOfConnectors", "readonly": true, "value": 1},
-            { "key": "MeterValueSampleInterval", "readonly": false, "value": 20},
-            { "key": "SupportedFeatureProfiles", "readonly": true, "value": "Core,LocalAuthListManagement"},
-            { "key": "LocalAuthListEnabled", "readonly": false, "value": false},
-            { "key": "AuthorizeRemoteTxRequests", "readonly": false, "value": false}
-        ]
-    },
-    "AutomaticTransactionGenerator": {
-        "enable": false,
-        "minDuration": 60,
-        "maxDuration": 80,
-        "minDelayBetweenTwoTransaction": 15,
-        "maxDelayBetweenTwoTransaction": 30,
-        "probabilityOfStart": 1,
-        "stopAutomaticTransactionGeneratorAfterHours": 0.3
-    },
-    "Connectors": {
-        "1": {
-            "MeterValues": [ {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        }
-    }
-}
diff --git a/src/assets/station/keba.station b/src/assets/station/keba.station
deleted file mode 100644 (file)
index ec6cc13..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-    "authorizationFile": "./src/assets/templateAuthorization.auth",
-    "baseName": "CS-keba",
-    "chargePointModel": "keba 4321",
-    "chargePointVendor": "keba",
-    "power": 14000,
-    "powerUnit": "W",
-    "numberOfConnectors": 1,
-    "randomConnectors": false,
-    "Configuration": { "configurationKey": [
-            { "key": "NumberOfConnectors", "readonly": true, "value": 2},
-            { "key": "MeterValueSampleInterval", "readonly": false, "value": 30},
-            { "key": "SupportedFeatureProfiles", "readonly": true, "value": "Core,LocalAuthListManagement"},
-            { "key": "LocalAuthListEnabled", "readonly": false, "value": false},
-            { "key": "AuthorizeRemoteTxRequests", "readonly": false, "value": false}
-        ]
-    },
-    "AutomaticTransactionGenerator": {
-        "enable": false,
-        "minDuration": 30,
-        "maxDuration": 60,
-        "minDelayBetweenTwoTransaction": 15,
-        "maxDelayBetweenTwoTransaction": 30,
-        "probabilityOfStart": 1,
-        "stopAutomaticTransactionGeneratorAfterHours": 0.3
-    },
-    "Connectors": {
-        "1": {
-            "MeterValues": [ {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "2": {
-            "MeterValues": [ {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        }
-    }
-}
diff --git a/src/assets/station/schneider-imredd.station b/src/assets/station/schneider-imredd.station
deleted file mode 100644 (file)
index a862690..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-    "authorizationFile": "./src/assets/templateAuthorization.auth",
-    "baseName": "CS-SCHNEIDER",
-    "chargePointModel": "SCHNEIDERXX213",
-    "chargePointVendor": "SCHNEIDER",
-    "power": 44000,
-    "powerUnit": "W",
-    "numberOfConnectors": 2,
-    "randomConnectors": false,
-    "Configuration": { "configurationKey": [
-            { "key": "NumberOfConnectors", "readonly": true, "value": 2},
-            { "key": "MeterValueSampleInterval", "readonly": false, "value": 20},
-            { "key": "SupportedFeatureProfiles", "readonly": true, "value": "Core,LocalAuthListManagement"},
-            { "key": "LocalAuthListEnabled", "readonly": false, "value": false},
-            { "key": "AuthorizeRemoteTxRequests", "readonly": false, "value": false}
-        ]
-    },
-    "AutomaticTransactionGenerator": {
-        "enable": false,
-        "minDuration": 60,
-        "maxDuration": 80,
-        "minDelayBetweenTwoTransaction": 15,
-        "maxDelayBetweenTwoTransaction": 30,
-        "probabilityOfStart": 1,
-        "stopAutomaticTransactionGeneratorAfterHours": 0.3
-    },
-    "Connectors": {
-        "1": {
-            "MeterValues": [ {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "2": {
-            "MeterValues": [ {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        }
-    }
-}
diff --git a/src/assets/station/schneider.station b/src/assets/station/schneider.station
deleted file mode 100644 (file)
index a862690..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-{
-    "authorizationFile": "./src/assets/templateAuthorization.auth",
-    "baseName": "CS-SCHNEIDER",
-    "chargePointModel": "SCHNEIDERXX213",
-    "chargePointVendor": "SCHNEIDER",
-    "power": 44000,
-    "powerUnit": "W",
-    "numberOfConnectors": 2,
-    "randomConnectors": false,
-    "Configuration": { "configurationKey": [
-            { "key": "NumberOfConnectors", "readonly": true, "value": 2},
-            { "key": "MeterValueSampleInterval", "readonly": false, "value": 20},
-            { "key": "SupportedFeatureProfiles", "readonly": true, "value": "Core,LocalAuthListManagement"},
-            { "key": "LocalAuthListEnabled", "readonly": false, "value": false},
-            { "key": "AuthorizeRemoteTxRequests", "readonly": false, "value": false}
-        ]
-    },
-    "AutomaticTransactionGenerator": {
-        "enable": false,
-        "minDuration": 60,
-        "maxDuration": 80,
-        "minDelayBetweenTwoTransaction": 15,
-        "maxDelayBetweenTwoTransaction": 30,
-        "probabilityOfStart": 1,
-        "stopAutomaticTransactionGeneratorAfterHours": 0.3
-    },
-    "Connectors": {
-        "1": {
-            "MeterValues": [ {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "2": {
-            "MeterValues": [ {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        }
-    }
-}
diff --git a/src/assets/station/siemens.mougins69.station b/src/assets/station/siemens.mougins69.station
deleted file mode 100644 (file)
index 548099d..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-{
-    "authorizationFile": "./src/assets/templateAuthorization.auth",
-    "baseName": "SAP-Mougins-69",
-    "fixedName": true,
-    "chargePointModel": "SiemensXX213",
-    "chargePointVendor": "SIEMENS",
-    "power": 44000,
-    "powerUnit": "W",
-    "numberOfConnectors": 2,
-    "randomConnectors": false,
-    "Configuration": { "configurationKey": [
-            { "key": "NumberOfConnectors", "readonly": true, "value": 2},
-            { "key": "MeterValueSampleInterval", "readonly": false, "value": 30},
-            { "key": "SupportedFeatureProfiles", "readonly": true, "value": "Core,LocalAuthListManagement"},
-            { "key": "LocalAuthListEnabled", "readonly": false, "value": false},
-            { "key": "AuthorizeRemoteTxRequests", "readonly": false, "value": false}
-        ]
-    },
-    "AutomaticTransactionGenerator": {
-        "enable": false,
-        "minDuration": 60,
-        "maxDuration": 80,
-        "minDelayBetweenTwoTransaction": 15,
-        "maxDelayBetweenTwoTransaction": 30,
-        "probabilityOfStart": 1,
-        "stopAutomaticTransactionGeneratorAfterHours": 0.3
-    },
-    "Connectors": {
-        "1": {
-            "bootStatus": "Unavailable",
-            "MeterValues": [ {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "2": {
-            "MeterValues": [{
-                "context": "Sample.Periodic",
-                "format": "Raw",
-                "measurand": "Energey.Active.Import.Register",
-                "unit": "Wh"
-            }]
-        }
-    }
-}
diff --git a/src/assets/station/virtual-simple-atg.station b/src/assets/station/virtual-simple-atg.station
deleted file mode 100644 (file)
index f6f7c27..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-{
-    "authorizationFile": "./src/assets/templateAuthorization.auth",
-    "baseName": "CS-BASIC",
-    "chargePointModel": "Simu simple",
-    "chargePointVendor": "Ovomaltin",
-    "power": 75000,
-    "powerUnit": "W",
-    "numberOfConnectors": 3,
-    "randomConnectors": false,
-    "Configuration": { "configurationKey": [
-            { "key": "NumberOfConnectors", "readonly": true, "value": 3},
-            { "key": "MeterValueSampleInterval", "readonly": false, "value": 30},
-            { "key": "SupportedFeatureProfiles", "readonly": true, "value": "Core,LocalAuthListManagement"},
-            { "key": "LocalAuthListEnabled", "readonly": false, "value": false},
-            { "key": "AuthorizeRemoteTxRequests", "readonly": false, "value": false}
-        ]
-    },
-    "AutomaticTransactionGenerator": {
-        "enable": true,
-        "minDuration": 60,
-        "maxDuration": 80,
-        "minDelayBetweenTwoTransaction": 15,
-        "maxDelayBetweenTwoTransaction": 30,
-        "probabilityOfStart": 1,
-        "stopAutomaticTransactionGeneratorAfterHours": 0.3
-    },
-    "Connectors": {
-        "0": {
-        },
-        "1": {
-            "bootStatus": "Available",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-                }
-            ]
-        },
-        "2": {
-            "bootStatus": "Preparing",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "3": {
-            "bootStatus": "Faulted",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        }
-
-
-    }
-}
diff --git a/src/assets/station/virtual-simple.station b/src/assets/station/virtual-simple.station
deleted file mode 100644 (file)
index 939e5c2..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-{
-    "authorizationFile": "./src/assets/templateAuthorization.auth",
-    "baseName": "CS-BASIC",
-    "chargePointModel": "Simu simple",
-    "chargePointVendor": "Ovomaltin",
-    "power": 50000,
-    "powerUnit": "W",
-    "numberOfConnectors": 3,
-    "randomConnectors": false,
-    "Configuration": { "configurationKey": [
-            { "key": "NumberOfConnectors", "readonly": true, "value": 3},
-            { "key": "MeterValueSampleInterval", "readonly": false, "value": 30},
-            { "key": "SupportedFeatureProfiles", "readonly": true, "value": "Core,LocalAuthListManagement"},
-            { "key": "LocalAuthListEnabled", "readonly": false, "value": false},
-            { "key": "AuthorizeRemoteTxRequests", "readonly": false, "value": false}
-        ]
-    },
-    "AutomaticTransactionGenerator": {
-        "enable": false,
-        "minDuration": 60,
-        "maxDuration": 80,
-        "minDelayBetweenTwoTransaction": 15,
-        "maxDelayBetweenTwoTransaction": 30,
-        "probabilityOfStart": 1,
-        "stopAutomaticTransactionGeneratorAfterHours": 0.3
-    },
-    "Connectors": {
-        "0": {
-        },
-        "1": {
-            "bootStatus": "Available",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-                }
-            ]
-        },
-        "2": {
-            "bootStatus": "Preparing",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "3": {
-            "bootStatus": "Faulted",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        }
-
-
-    }
-}
diff --git a/src/assets/station/virtual.station b/src/assets/station/virtual.station
deleted file mode 100644 (file)
index 0bf089b..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-{
-    "authorizationFile": "./src/assets/templateAuthorization.auth",
-    "baseName": "CS-SIMU",
-    "chargePointModel": "Simu all connectors",
-    "chargePointVendor": "Ovomaltin",
-    "power": 50000,
-    "powerUnit": "W",
-    "numberOfConnectors": 9,
-    "randomConnectors": false,
-    "Configuration": { "configurationKey": [
-            { "key": "NumberOfConnectors", "readonly": true, "value": 9},
-            { "key": "MeterValueSampleInterval", "readonly": false, "value": 30},
-            { "key": "SupportedFeatureProfiles", "readonly": true, "value": "Core,LocalAuthListManagement"},
-            { "key": "LocalAuthListEnabled", "readonly": false, "value": false},
-            { "key": "AuthorizeRemoteTxRequests", "readonly": false, "value": false}
-        ]
-    },
-    "AutomaticTransactionGenerator": {
-        "enable": false,
-        "minDuration": 60,
-        "maxDuration": 80,
-        "minDelayBetweenTwoTransaction": 15,
-        "maxDelayBetweenTwoTransaction": 30,
-        "probabilityOfStart": 1,
-        "stopAutomaticTransactionGeneratorAfterHours": 0.3
-    },
-    "Connectors": {
-        "0": {
-        },
-        "1": {
-            "bootStatus": "Available",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-                }
-            ]
-        },
-        "2": {
-            "bootStatus": "Preparing",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "3": {
-            "bootStatus": "SuspendedEVSE",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "4": {
-            "bootStatus": "SuspendedEV",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "5": {
-            "bootStatus": "Finishing",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "6": {
-            "bootStatus": "Reserved",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "7": {
-            "bootStatus": "Charging",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "8": {
-            "bootStatus": "Unavailable",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        },
-        "9": {
-            "bootStatus": "Faulted",
-            "MeterValues": [ {
-                    "unit": "Percent",
-                    "context": "Sample.Periodic",
-                    "measurand": "SoC",
-                    "location": "EV"
-                },
-                {
-                "unit": "Wh",
-                "context": "Sample.Periodic"
-            }
-            ]
-        }
-    }
-}
diff --git a/src/assets/templateAuthorization.auth b/src/assets/templateAuthorization.auth
deleted file mode 100644 (file)
index 6fd9690..0000000
+++ /dev/null
@@ -1,245 +0,0 @@
-[
-"007",
-"0080001EDBA4E1",
-"00B700FE0CA4E1",
-"00E1007E6BA4E1",
-"030163E9",
-"037A60E9",
-"0422A5F2464B80",
-"048F9F7B",
-"04DA521AA74880",
-"070000155AE117",
-"070000155AE119",
-"070000155AE11A",
-"070000155AE11F",
-"070000155AE121",
-"070000155AE1BF",
-"070000155AE1C0",
-"070000155AE1C1",
-"07000015AAB292",
-"07000015AAB293",
-"07000015AAEAB3",
-"07000015AAEAB4",
-"07000015AAEAB5",
-"07000015AAEAB6",
-"07000015AAEAB7",
-"07000015AAEAB8",
-"07000015AAEAB9",
-"07000015AAEABB",
-"07000015AAEABC",
-"07000015AE119",
-"087B22D1",
-"08C1B4F7",
-"0A847D05",
-"0A8CBBE6",
-"0AEA7C05",
-"0BC217AD",
-"0BE715AD",
-"0C029E16",
-"0CC39E16",
-"0E3BA5E1",
-"0E9783CB",
-"0E9B83CB",
-"13926AEF",
-"168A05D0",
-"16A591B3",
-"1A21BDE6",
-"1AF17F05",
-"1B1A1BAD",
-"1BD215AD",
-"1BD51AAD",
-"1C3B0952",
-"1C440752",
-"1C74A216",
-"1C751002",
-"1CE50F02",
-"1CEA0D02",
-"1E3AA5E1",
-"1E656DCB",
-"1ECF6CCB",
-"1EDBA4E1",
-"2A7ABDE6",
-"2A8B7F05",
-"2B5D19AD",
-"2C73A116",
-"2E020D00000000",
-"2E566CCB",
-"2E5769CB",
-"33F161E9",
-"363306D0",
-"3A407B05",
-"3A5E8105",
-"3A877B05",
-"3B6F18AD",
-"3BC317AD",
-"3BF019AD",
-"3BF616AD",
-"3BFB1522",
-"3C310B02",
-"3E219E12",
-"3E7B6ECB",
-"43329EF7",
-"43E562E9",
-"4CAA9414",
-"4CB69E16",
-"4CF70F02",
-"4EF282CB",
-"521B7C04",
-"530B63E9",
-"53D898F7",
-"53F762E9",
-"590153",
-"5A727C05",
-"5CA50D02",
-"5D37367F",
-"5E65CB60",
-"5E806BCB",
-"5E886DCB",
-"630D63E9",
-"640D1821",
-"696E1E10",
-"6A08BAE6",
-"6A1D6E3C",
-"6AAE7B05",
-"6B0918AD",
-"6B8BB4EE",
-"6C13A216",
-"6C610A02",
-"6E26A5E1",
-"6E666CCB",
-"6E6869CB",
-"7099C291",
-"730399F7",
-"7376B3DD",
-"73C862E9",
-"7A177E05",
-"7A3DBBE6",
-"7B1B1AAD",
-"7B3B1AAD",
-"7B8278E6",
-"7C519414",
-"7CA70C02",
-"7E586ACB",
-"7E6BA4E1",
-"7EF168CB",
-"8A457C05",
-"930862E9",
-"931063E9",
-"93E8B1DD",
-"9A3C7E05",
-"9AA18105",
-"9C4D0B02",
-"9CE20C02",
-"9CFA0D02",
-"9E806ECB",
-"9E936BCB",
-"9E956DCB",
-"A20D2107",
-"A3C3B1DD",
-"A48FFFCC",
-"AA417B05",
-"ABB21AAD",
-"AC1CC50D",
-"ACB99E16",
-"AD1A6A4B",
-"ADMINIT",
-"ADUFIRHG",
-"AE4FC860",
-"AEF76DCB",
-"AJ67365NCA",
-"B31FB2DD",
-"B3CAA2F7",
-"B650B67E6BA4E1",
-"BB6B18AD",
-"BB9019AD",
-"BBA7B2EE",
-"BC0E0E02",
-"BC510A02",
-"BC9B0B02",
-"BC9E9714",
-"BE5469CB",
-"BEA6C760",
-"BECEA2E1",
-"BEEAABE1",
-"C41F1821",
-"C69505D0",
-"CA1C8105",
-"CA637F05",
-"CA65BCE6",
-"CB071AAD",
-"CBFF17AD",
-"CC211002",
-"CC7B0552",
-"CCA30E02",
-"CD64CD4C",
-"CE18A012",
-"CEDAA4E1",
-"CJ00001",
-"CL844776NCA",
-"CR1602274633",
-"CV00001",
-"CV737334672",
-"D3AFB3DD",
-"D62706D0",
-"D6C106D0",
-"DA00001",
-"DA15BEE6",
-"DA9CBDE6",
-"DB081BAD",
-"DB9419AD",
-"DC970C02",
-"DE246CCB",
-"DEMO",
-"DEMOADMIN",
-"DEMOBASIC",
-"DM00001",
-"E3FFA0F7",
-"E6EA04D0",
-"E766EF25",
-"EAB17D05",
-"EBE819AD",
-"EC849E16",
-"ECA10B02",
-"F35C9FF7",
-"F3B2B3DD",
-"F3C0B4DD",
-"F3CFB1DD",
-"F66393B3",
-"F68805D0",
-"FAFABDE6",
-"FB2A1BAD",
-"FC4E0952",
-"FE0CA4E1",
-"FE2DA3E1",
-"FE5069CB",
-"FE5A6ACB",
-"FE6D6ECB",
-"FED86CCB",
-"FF00001",
-"FO00001",
-"FS553378971",
-"GF1287569582",
-"GN00001",
-"GS00001",
-"HC1777052478",
-"JM0001",
-"KA00001",
-"KO00001",
-"LA17469521",
-"LC20181002",
-"MA00001",
-"MS498782046",
-"OF00001",
-"PP162826911",
-"RC733661034",
-"SB1542003451",
-"SL00001",
-"SR00001",
-"TESTADMINID",
-"UNDEFINED",
-"US00001",
-"VN00001",
-"mr20181005",
-"rf2005127191",
-"C3E4B3DD"
-]
index 05a11044f54064a6454dd1adeaa89f7708d7de15..5ba078f8874cc7a6fe08341ec06adfd200c6c1ef 100644 (file)
@@ -88,7 +88,7 @@ class AutomaticTransactionGenerator {
 
   // eslint-disable-next-line class-methods-use-this
   async startTransaction(connectorId, self) {
-    if (self._chargingStation.hasAuthorizationKeys()) {
+    if (self._chargingStation.hasAuthorizedTags()) {
       const tagId = self._chargingStation.getRandomTagId();
       logger.info(self._basicFormatLog(connectorId) + ' start transaction for tagID ' + tagId);
       return self._chargingStation.sendStartTransaction(connectorId, tagId);
index 0fccef4895d0b27a4abb8d51a370269dcb3a81f6..daa9475f44d2907218547049729c76105b50acbe 100644 (file)
@@ -11,51 +11,100 @@ const fs = require('fs');
 const {performance, PerformanceObserver} = require('perf_hooks');
 
 class ChargingStation {
-  constructor(index, stationTemplate) {
-    this._requests = {};
+  constructor(index, stationTemplateFile) {
+    this._index = index;
+    this._stationTemplateFile = stationTemplateFile;
+    this._initialize();
+
     this._autoReconnectRetryCount = 0;
     this._autoReconnectMaxRetries = Configuration.getAutoReconnectMaxRetries(); // -1 for unlimited
     this._autoReconnectTimeout = Configuration.getAutoReconnectTimeout() * 1000; // ms, zero for disabling
+
+    this._requests = {};
+    this._messageQueue = [];
+
     this._isSocketRestart = false;
-    this._stationInfo = this._buildChargingStation(index, stationTemplate);
+  }
+
+  _initialize() {
+    this._stationInfo = this._buildStationInfo();
+    this._bootNotificationMessage = {
+      chargePointModel: this._stationInfo.chargePointModel,
+      chargePointVendor: this._stationInfo.chargePointVendor,
+    };
+    this._configuration = this._getConfiguration();
+    this._authorizedTags = this._getAuthorizedTags();
+    this._supervisionUrl = this._getSupervisionURL();
     this._statistics = new Statistics(this._stationInfo.name);
     this._performanceObserver = new PerformanceObserver((list) => {
       const entry = list.getEntries()[0];
       this._statistics.logPerformance(entry, 'ChargingStation');
       this._performanceObserver.disconnect();
     });
-    this._index = index;
-    this._messageQueue = [];
-    this._bootNotificationMessage = {
-      chargePointModel: this._stationInfo.chargePointModel,
-      chargePointVendor: this._stationInfo.chargePointVendor,
-    };
-    this._configuration = this._getConfiguration(stationTemplate);
-    this._authorizationFile = this._getAuthorizationFile(stationTemplate);
-    this._supervisionUrl = this._getSupervisionURL(index, stationTemplate);
   }
 
   _basicFormatLog() {
     return Utils.basicFormatLog(` ${this._stationInfo.name}:`);
   }
 
-  // eslint-disable-next-line class-methods-use-this
-  _getConfiguration(stationTemplate) {
-    return stationTemplate.Configuration ? stationTemplate.Configuration : {};
+  _getConfiguration() {
+    return this._stationInfo.Configuration ? this._stationInfo.Configuration : {};
   }
 
-  // eslint-disable-next-line class-methods-use-this
-  _getAuthorizationFile(stationTemplate) {
-    return stationTemplate.authorizationFile ? stationTemplate.authorizationFile : '';
+  _getAuthorizationFile() {
+    return this._stationInfo.authorizationFile ? this._stationInfo.authorizationFile : '';
   }
 
-  // eslint-disable-next-line class-methods-use-this
-  _getSupervisionURL(index, stationTemplate) {
-    const supervisionUrls = JSON.parse(JSON.stringify(stationTemplate.supervisionURL ? stationTemplate.supervisionURL : Configuration.getSupervisionURLs()));
+  _getAuthorizedTags() {
+    let authorizedTags = [];
+    const authorizationFile = this._getAuthorizationFile();
+    if (authorizationFile) {
+      try {
+        // Load authorization file
+        const fileDescriptor = fs.openSync(authorizationFile, 'r');
+        authorizedTags = JSON.parse(fs.readFileSync(fileDescriptor, 'utf8'));
+        fs.closeSync(fileDescriptor);
+      } catch (error) {
+        logger.error(this._basicFormatLog() + ' Authorization file loading error: ' + error);
+      }
+    } else {
+      logger.info(this._basicFormatLog() + ' No authorization file given in template file ' + this._stationTemplateFile);
+    }
+    return authorizedTags;
+  }
+
+  _startAuthorizationFileMonitoring() {
+    // eslint-disable-next-line no-unused-vars
+    fs.watchFile(this._getAuthorizationFile(), (current, previous) => {
+      try {
+        logger.debug(this._basicFormatLog() + ' Authorization file ' + this._getAuthorizationFile() + ' have changed, reload');
+        // Initialize _authorizedTags
+        this._authorizedTags = this._getAuthorizedTags();
+      } catch (error) {
+        logger.error(this._basicFormatLog() + ' Authorization file monitoring error: ' + error);
+      }
+    });
+  }
+
+  _startStationTemplateFileMonitoring() {
+    // eslint-disable-next-line no-unused-vars
+    fs.watchFile(this._stationTemplateFile, (current, previous) => {
+      try {
+        logger.debug(this._basicFormatLog() + ' Template file ' + this._stationTemplateFile + ' have changed, reload');
+        // Initialize
+        this._initialize();
+      } catch (error) {
+        logger.error(this._basicFormatLog() + ' Charging station template file monitoring error: ' + error);
+      }
+    });
+  }
+
+  _getSupervisionURL() {
+    const supervisionUrls = Utils.cloneJSonDocument(this._stationInfo.supervisionURL ? this._stationInfo.supervisionURL : Configuration.getSupervisionURLs());
     let indexUrl = 0;
     if (Array.isArray(supervisionUrls)) {
-      if (Configuration.getEquallySupervisionDistribution()) {
-        indexUrl = index % supervisionUrls.length;
+      if (Configuration.getDistributeStationToTenantEqually()) {
+        indexUrl = this._index % supervisionUrls.length;
       } else {
         // Get a random url
         indexUrl = Math.floor(Math.random() * supervisionUrls.length);
@@ -65,9 +114,8 @@ class ChargingStation {
     return supervisionUrls;
   }
 
-  // eslint-disable-next-line class-methods-use-this
-  _getStationName(index, stationTemplate) {
-    return stationTemplate.fixedName ? stationTemplate.baseName : stationTemplate.baseName + '-' + ('000000000' + index).substr(('000000000' + index).length - 4);
+  _getStationName(stationTemplate) {
+    return stationTemplate.fixedName ? stationTemplate.baseName : stationTemplate.baseName + '-' + ('000000000' + this._index).substr(('000000000' + this._index).length - 4);
   }
 
   _getAuthorizeRemoteTxRequests() {
@@ -80,44 +128,34 @@ class ChargingStation {
     return localAuthListEnabled ? Utils.convertToBoolean(localAuthListEnabled.value) : false;
   }
 
-  _buildChargingStation(index, stationTemplate) {
-    if (Array.isArray(stationTemplate.power)) {
-      stationTemplate.maxPower = stationTemplate.power[Math.floor(Math.random() * stationTemplate.power.length)];
+  _buildStationInfo() {
+    let stationTemplateFromFile;
+    try {
+      // Load template file
+      const fileDescriptor = fs.openSync(this._stationTemplateFile, 'r');
+      stationTemplateFromFile = JSON.parse(fs.readFileSync(fileDescriptor, 'utf8'));
+      fs.closeSync(fileDescriptor);
+    } catch (error) {
+      logger.error(this._basicFormatLog() + ' Template file loading error: ' + error);
+    }
+    const stationTemplate = stationTemplateFromFile || {};
+    if (Array.isArray(stationTemplateFromFile.power)) {
+      stationTemplate.maxPower = stationTemplateFromFile.power[Math.floor(Math.random() * stationTemplateFromFile.power.length)];
     } else {
-      stationTemplate.maxPower = stationTemplate.power;
+      stationTemplate.maxPower = stationTemplateFromFile.power;
     }
-    stationTemplate.name = this._getStationName(index, stationTemplate);
+    stationTemplate.name = this._getStationName(stationTemplateFromFile);
     return stationTemplate;
   }
 
   async start() {
     logger.info(this._basicFormatLog() + ' Will communicate with ' + this._supervisionUrl);
+    // Monitor authorization file
+    this._startAuthorizationFileMonitoring();
+    // Monitor station template file
+    this._startStationTemplateFileMonitoring();
     this._url = this._supervisionUrl + '/' + this._stationInfo.name;
     this._wsConnection = new WebSocket(this._url, 'ocpp1.6');
-    if (this._authorizationFile) {
-      try {
-        // load file
-        const fileDescriptor = fs.openSync(this._authorizationFile, 'r');
-        this._authorizedKeys = JSON.parse(fs.readFileSync(fileDescriptor, 'utf8'));
-        fs.closeSync(fileDescriptor);
-        // monitor authorization file
-        // eslint-disable-next-line no-unused-vars
-        fs.watchFile(this._authorizationFile, (current, previous) => {
-          try {
-            // reload file
-            const fileDescriptor = fs.openSync(this._authorizationFile, 'r');
-            this._authorizedKeys = JSON.parse(fs.readFileSync(fileDescriptor, 'utf8'));
-            fs.closeSync(fileDescriptor);
-          } catch (error) {
-            logger.error(this._basicFormatLog() + ' Authorization file error: ' + error);
-          }
-        });
-      } catch (error) {
-        logger.error(this._basicFormatLog() + ' Authorization file error: ' + error);
-      }
-    } else {
-      logger.info(this._basicFormatLog() + ' No authorization file given in template ' + this._stationInfo.baseName);
-    }
     // Handle Socket incoming messages
     this._wsConnection.on('message', this.onMessage.bind(this));
     // Handle Socket error
@@ -307,7 +345,7 @@ class ChargingStation {
           messageToSend = JSON.stringify([messageType, messageId, command.code ? command.code : Constants.OCPP_ERROR_GENERIC_ERROR, command.message ? command.message : '', command.details ? command.details : {}]);
           break;
       }
-      // Check if wsConnection in ready
+      // Check if wsConnection is ready
       if (this._wsConnection.readyState === WebSocket.OPEN) {
         // Yes: Send Message
         this._wsConnection.send(messageToSend);
@@ -332,7 +370,7 @@ class ChargingStation {
         if (typeof self[responseCallbackFn] === 'function') {
           self[responseCallbackFn](payload, requestPayload, self);
         } else {
-          // logger.error(this._basicFormatLog() + ' Trying to call an undefined callback function: ' + responseCallbackFn)
+          logger.debug(self._basicFormatLog() + ' Trying to call an undefined callback function: ' + responseCallbackFn);
         }
         // Send the response
         resolve(payload);
@@ -354,18 +392,22 @@ class ChargingStation {
     if (payload.status === 'Accepted') {
       this._heartbeatInterval = payload.interval * 1000;
       this.basicStartMessageSequence();
+    } else {
+      logger.info(this._basicFormatLog() + ' Boot Notification rejected');
     }
   }
 
   async basicStartMessageSequence() {
     this._startHeartbeat(this);
-    if (!this._connectors) { // build connectors
+    // build connectors
+    if (!this._connectors) {
       this._connectors = {};
-      const connectorsConfig = JSON.parse(JSON.stringify(this._stationInfo.Connectors));
+      const connectorsConfig = Utils.cloneJSonDocument(this._stationInfo.Connectors);
       // determine number of customized connectors
       let lastConnector;
       for (lastConnector in connectorsConfig) {
-        if (Utils.convertToInt(lastConnector) === 0 && this._stationInfo.usedConnectorId0) {
+        // add connector 0, OCPP specification violation that for example KEBA have
+        if (Utils.convertToInt(lastConnector) === 0 && this._stationInfo.useConnectorId0) {
           this._connectors[lastConnector] = connectorsConfig[lastConnector];
         }
       }
@@ -378,7 +420,7 @@ class ChargingStation {
       }
       // generate all connectors
       for (let index = 1; index <= maxConnectors; index++) {
-        const randConnectorID = (this._stationInfo.randomConnectors ? Utils.getRandomInt(lastConnector, 1) : index);
+        const randConnectorID = this._stationInfo.randomConnectors ? Utils.getRandomInt(maxConnectors, 1) : index;
         this._connectors[index] = connectorsConfig[randConnectorID];
       }
     }
@@ -386,12 +428,12 @@ class ChargingStation {
     for (const connector in this._connectors) {
       if (!this._connectors[connector].transactionStarted) {
         if (this._connectors[connector].bootStatus) {
-          setTimeout(() => this.sendStatusNotification(connector, this._connectors[connector].bootStatus), 500);
+          setTimeout(() => this.sendStatusNotification(connector, this._connectors[connector].bootStatus), Constants.STATUS_NOTIFICATION_TIMEOUT);
         } else {
-          setTimeout(() => this.sendStatusNotification(connector, 'Available'), 500);
+          setTimeout(() => this.sendStatusNotification(connector, 'Available'), Constants.STATUS_NOTIFICATION_TIMEOUT);
         }
       } else {
-        setTimeout(() => this.sendStatusNotification(connector, 'Charging'), 500);
+        setTimeout(() => this.sendStatusNotification(connector, 'Charging'), Constants.STATUS_NOTIFICATION_TIMEOUT);
       }
     }
 
@@ -506,21 +548,20 @@ class ChargingStation {
 
   async handleRemoteStartTransaction(commandPayload) {
     const transactionConnectorID = (commandPayload.connectorId ? commandPayload.connectorId : '1');
-    if (this.hasAuthorizationKeys() && this._getLocalAuthListEnabled() && this._getAuthorizeRemoteTxRequests()) {
+    if (this.hasAuthorizedTags() && this._getLocalAuthListEnabled() && this._getAuthorizeRemoteTxRequests()) {
       // Check if authorized
-      if (this._authorizedKeys.find((value) => value === commandPayload.idTag)) {
+      if (this._authorizedTags.find((value) => value === commandPayload.idTag)) {
         // Authorization successful start transaction
-        setTimeout(() => this.sendStartTransaction(transactionConnectorID, commandPayload.idTag), 500);
-        logger.info(this._basicFormatLog() + ' Transaction remotely STARTED on ' + this._stationInfo.name + '#' + transactionConnectorID + ' with idTag ' + commandPayload.idTag);
+        setTimeout(() => this.sendStartTransaction(transactionConnectorID, commandPayload.idTag), Constants.START_TRANSACTION_TIMEOUT);
+        logger.debug(this._basicFormatLog() + ' Transaction remotely STARTED on ' + this._stationInfo.name + '#' + transactionConnectorID + ' with idTag ' + commandPayload.idTag);
         return Constants.OCPP_RESPONSE_ACCEPTED;
       }
-      // Start authorization checks
       logger.error(this._basicFormatLog() + ' Remote starting transaction REJECTED with status ' + commandPayload.idTagInfo.status + ', idTag ' + commandPayload.idTag);
       return Constants.OCPP_RESPONSE_REJECTED;
     }
     // No local authorization check required => start transaction
-    setTimeout(() => this.sendStartTransaction(transactionConnectorID, commandPayload.idTag), 500);
-    logger.info(this._basicFormatLog() + ' Transaction remotely STARTED on ' + this._stationInfo.name + '#' + transactionConnectorID + ' with idTag ' + commandPayload.idTag);
+    setTimeout(() => this.sendStartTransaction(transactionConnectorID, commandPayload.idTag), Constants.START_TRANSACTION_TIMEOUT);
+    logger.debug(this._basicFormatLog() + ' Transaction remotely STARTED on ' + this._stationInfo.name + '#' + transactionConnectorID + ' with idTag ' + commandPayload.idTag);
     return Constants.OCPP_RESPONSE_ACCEPTED;
   }
 
@@ -574,7 +615,7 @@ class ChargingStation {
       const sampledValueLcl = {
         timestamp: new Date().toISOString(),
       };
-      const meterValuesClone = JSON.parse(JSON.stringify(self._getConnector(connectorID).MeterValues));
+      const meterValuesClone = Utils.cloneJSonDocument(self._getConnector(connectorID).MeterValues);
       if (Array.isArray(meterValuesClone)) {
         sampledValueLcl.sampledValue = meterValuesClone;
       } else {
@@ -622,7 +663,7 @@ class ChargingStation {
 
   async startMeterValues(connectorID, interval, self) {
     if (!this._connectors[connectorID].transactionStarted) {
-      logger.debug(`${self._basicFormatLog()} Trying to start meter values on connector ID ${connectorID} with no transaction`);
+      logger.debug(`${self._basicFormatLog()} Trying to start meter values on connector ID ${connectorID} with no transaction started`);
     } else if (this._connectors[connectorID].transactionStarted && !this._connectors[connectorID].transactionId) {
       logger.debug(`${self._basicFormatLog()} Trying to start meter values on connector ID ${connectorID} with no transaction id`);
     }
@@ -644,13 +685,13 @@ class ChargingStation {
     return Constants.OCPP_RESPONSE_ACCEPTED;
   }
 
-  hasAuthorizationKeys() {
-    return this._authorizedKeys && this._authorizedKeys.length > 0;
+  hasAuthorizedTags() {
+    return Array.isArray(this._authorizedTags) && this._authorizedTags.length > 0;
   }
 
   getRandomTagId() {
-    const index = Math.round(Math.floor(Math.random() * this._authorizedKeys.length - 1));
-    return this._authorizedKeys[index];
+    const index = Math.round(Math.floor(Math.random() * this._authorizedTags.length - 1));
+    return this._authorizedTags[index];
   }
 
   _getConnector(number) {
index 1f25f14511388883858c9055c044da83f8feb665..1aa6d8e5e7f5f5e1635ed45f90860fdcdb587c27 100644 (file)
@@ -2,6 +2,6 @@ const {isMainThread, workerData} = require('worker_threads');
 const ChargingStation = require('./ChargingStation');
 
 if (!isMainThread) {
-  const station = new ChargingStation(workerData.index, workerData.template);
+  const station = new ChargingStation(workerData.index, workerData.templateFile);
   station.start();
 }
index 3f47f1fe0b1806b8088014a59c46a05a01edcd1a..fb54b6c06f1045cce9b41f2caa73d914182a8817 100644 (file)
@@ -1,7 +1,6 @@
 const Configuration = require('./utils/Configuration');
 const Utils = require('./utils/Utils');
 const Wrk = require('./charging-station/Worker');
-const fs = require('fs');
 const logger = require('./utils/Logger');
 
 class Bootstrap {
@@ -9,37 +8,26 @@ class Bootstrap {
     try {
       logger.info('%s Configuration: %j', Utils.basicFormatLog(), Configuration.getConfig());
       // Start each ChargingStation object in a worker thread
-      if (Configuration.getChargingStationTemplateURLs()) {
+      if (Configuration.getStationTemplateURLs()) {
         let numStationsTotal = 0;
-        Configuration.getChargingStationTemplateURLs().forEach((stationURL) => {
+        Configuration.getStationTemplateURLs().forEach((stationURL) => {
           try {
-            // Load file
-            const fileDescriptor = fs.openSync(stationURL.file, 'r');
-            const stationTemplate = JSON.parse(fs.readFileSync(fileDescriptor, 'utf8'));
-            fs.closeSync(fileDescriptor);
-            const nbStation = (stationURL.numberOfStation ? stationURL.numberOfStation : 0);
+            const nbStation = stationURL.numberOfStation ? stationURL.numberOfStation : 0;
             numStationsTotal += nbStation;
             for (let index = 1; index <= nbStation; index++) {
               const worker = new Wrk('./src/charging-station/StationWorker.js', {
                 index,
-                template: JSON.parse(JSON.stringify(stationTemplate)),
+                templateFile: stationURL.file,
               }, numStationsTotal);
               worker.start();
             }
           } catch (error) {
             // eslint-disable-next-line no-console
-            console.log('Template file' + stationURL.file + ' error' + error);
+            console.log('Charging station start with template file ' + stationURL.file + ' error ' + JSON.stringify(error, null, ' '));
           }
         });
       } else {
-        const nbStation = Configuration.getNumberofChargingStation();
-        for (let index = 1; index <= nbStation; index++) {
-          const worker = new Wrk('./src/charging-station/StationWorker.js', {
-            index,
-            template: JSON.parse(JSON.stringify(Configuration.getChargingStationTemplate())),
-          }, nbStation);
-          worker.start();
-        }
+        console.log('No stationURLS defined in configuration, exiting');
       }
     } catch (error) {
       // eslint-disable-next-line no-console
index 31ab1d6b561e0e61abdd1159518351e62a67995a..9220127ceaad763eaa85daea562cd6632d1b4033 100644 (file)
@@ -14,7 +14,7 @@ class Configuration {
 
   static getStatisticsDisplayInterval() {
     // Read conf
-    return Configuration.getConfig().statisticsDisplayInterval;
+    return Utils.objectHasOwnProperty(Configuration.getConfig(), 'statisticsDisplayInterval') ? Configuration.getConfig().statisticsDisplayInterval : 60;
   }
 
   static getAutoReconnectTimeout() {
@@ -27,21 +27,11 @@ class Configuration {
     return Utils.objectHasOwnProperty(Configuration.getConfig(), 'autoReconnectMaxRetries') ? Configuration.getConfig().autoReconnectMaxRetries : -1;
   }
 
-  static getChargingStationTemplateURLs() {
+  static getStationTemplateURLs() {
     // Read conf
     return Configuration.getConfig().stationTemplateURLs;
   }
 
-  static getChargingStationTemplate() {
-    // Read conf
-    return Configuration.getConfig().stationTemplate;
-  }
-
-  static getNumberofChargingStation() {
-    // Read conf
-    return Configuration.getConfig().numberOfStation ? Configuration.getConfig().numberOfStation : 0;
-  }
-
   static useWorkerPool() {
     return Configuration.getConfig().useWorkerPool;
   }
@@ -54,6 +44,10 @@ class Configuration {
     return Utils.objectHasOwnProperty(Configuration.getConfig(), 'consoleLog') ? Configuration.getConfig().consoleLog : false;
   }
 
+  static getLogLevel() {
+    return Utils.objectHasOwnProperty(Configuration.getConfig(), 'logLevel') ? Configuration.getConfig().logLevel : 'info';
+  }
+
   static getLogFile() {
     return Utils.objectHasOwnProperty(Configuration.getConfig(), 'logFile') ? Configuration.getConfig().logFile : 'combined.log';
   }
@@ -62,34 +56,13 @@ class Configuration {
     return Utils.objectHasOwnProperty(Configuration.getConfig(), 'errorFile') ? Configuration.getConfig().errorFile : 'error.log';
   }
 
-  static getAutomaticTransactionConfiguration() {
-    // Read conf
-    return Configuration.getChargingStationTemplate().AutomaticTransactionGenerator;
-  }
-
   static getSupervisionURLs() {
     // Read conf
     return Configuration.getConfig().supervisionURLs;
   }
 
-  static getEquallySupervisionDistribution() {
-    return Configuration.getConfig().distributeStationToTenantEqually;
-  }
-
-  static getChargingStationConfiguration() {
-    return Utils.objectHasOwnProperty(Configuration.getChargingStationTemplate(), 'Configuration') ? Configuration.getChargingStationTemplate().Configuration : {};
-  }
-
-  static getChargingStationAuthorizationFile() {
-    return Utils.objectHasOwnProperty(Configuration.getChargingStationTemplate(), 'authorizationFile') ? Configuration.getChargingStationTemplate().authorizationFile : '';
-  }
-
-  static getChargingStationConnectors() {
-    return Configuration.getChargingStationTemplate().Connectors;
-  }
-
-  static getChargingStationConnector(number) {
-    return Configuration.getChargingStationTemplate().Connectors[number];
+  static getDistributeStationToTenantEqually() {
+    return Utils.objectHasOwnProperty(Configuration.getConfig(), 'distributeStationToTenantEqually') ? Configuration.getConfig().distributeStationToTenantEqually : true;
   }
 }
 
index d8a265c51091bdcce2ad7b8f58bdddbe0478b7fb..3c7e13a05939c2afed7824ca65b4a5520220d234 100644 (file)
@@ -134,6 +134,9 @@ class Constants {
   static OCPP_VERSION_15 = '1.5';
   static OCPP_VERSION_16 = '1.6';
   static OCPP_VERSION_20 = '2.0';
+
+  static STATUS_NOTIFICATION_TIMEOUT = 500;
+  static START_TRANSACTION_TIMEOUT = 500;
 }
 
 module.exports = Constants;
index 1a71c294aa5a320fb6aab46f88cad0861d86e16c..0f0fff0ebda47d28c2bdf33d8ba4dfb3d807f71d 100644 (file)
@@ -2,7 +2,7 @@ const Configuration = require('./Configuration');
 const Winston = require('winston');
 
 const logger = Winston.createLogger({
-  level: 'info',
+  level: Configuration.getLogLevel(),
   format: Winston.format.combine(Winston.format.splat(), Winston.format.json()),
   defaultMeta: {service: 'user-service'},
   transports: [
index bba3d6b174fd829b8dcc9e714042ae67363c2e1d..edbec26221680267b35122e5a40c2a84ab1d6d6d 100644 (file)
@@ -40,7 +40,8 @@ class Statistics {
       startTransaction: 'StartTransaction',
       stopTransaction: 'StopTransaction',
     };
-    if (MAPCOMMAND[command]) { // Get current command statistics
+    // Get current command statistics
+    if (MAPCOMMAND[command]) {
       currentStatistics = this._statistics[MAPCOMMAND[command]];
     } else if (this._statistics[command]) {
       currentStatistics = this._statistics[command];
@@ -65,13 +66,11 @@ class Statistics {
   }
 
   _display() {
-    // logger.info(this._basicFormatLog() + ' STARTING')
     logger.info(this._basicFormatLog() + ' %j', this._statistics);
-    // logger.info(this._basicFormatLog() + ' ENDING')
   }
 
   _displayInterval() {
-    if (Configuration.getStatisticsDisplayInterval()) {
+    if (Configuration.getStatisticsDisplayInterval() !== 0) {
       logger.info(this._basicFormatLog() + ' displayed every ' + Configuration.getStatisticsDisplayInterval() + 's');
       setInterval(() => {
         this._display();
index b04f06130f30616db1722e3431328dce76d930c3..a06d57ead326e3dc052417fe902b54a9036b04fa 100644 (file)
@@ -131,6 +131,10 @@ class Utils {
   static objectHasOwnProperty(object, property) {
     return Object.prototype.hasOwnProperty.call(object, property);
   }
+
+  static cloneJSonDocument(jsonDocument) {
+    return JSON.parse(JSON.stringify(jsonDocument));
+  }
 }
 
 module.exports = Utils;