+Simple [node.js](https://nodejs.org/) program to simulate a set of charging stations based on the OCPP-J 1.6 protocol.
+
+## Prerequisites
+
+### Windows
+
+* [Chocolatey](https://chocolatey.org/):
+
+```powershell
+choco install -y nodejs-lts
+```
+
+### MacOSX
+
+* [Homebrew](https://brew.sh/):
+
+```shell
+brew install node@14
+```
+
+### GNU/Linux:
+
+* [NodeSource](https://github.com/nodesource/distributions) Node.js Binary Distributions for version 14.X
+
+## Configuration syntax
+
+All configuration files are in the JSON standard format.
+
+The charging stations simulator's main configuration parameters must be within the `src/assets/config.json` file. A configuration template file is available at [src/assets/config-template.json](src/assets/config-template.json).
+
+All charging station templates are in the directory [src/assets/station-templates](src/assets/station-templates).
+
+A list of RFID tags must be defined for the automatic transaction generator with the default location and name `src/assets/authorization-tags.json`. A template file is available at [src/assets/authorization-tags-template.json](src/assets/authorization-tags-template.json).
+
+The charging stations simulator have an automatic configuration files reload feature at change for:
+* main configuration;
+* charging station templates;
+* authorization RFID tags.
+
+But the modifications to test have to be done to the files in the build result directory [dist/assets](dist/assets). Once the modifications are finished, they have to be reported or copied to the matching files in the build source directory [src/assets](src/assets) to ensure they will be taken into account at next build.
+
+### Main configuration
+
+**src/assets/config.json**:
+
+Key | Value(s) | Default Value | Value type | Description
+--- | -------| --------------| ---------- | ------------
+supervisionURLs | | [] | string[] | array of connection URIs to OCPP-J servers
+distributeStationsToTenantsEqually | true/false | true | boolean | distribute charging stations uniformly to the OCPP-J servers
+workerProcess | workerSet/staticPool/dynamicPool | workerSet | string | worker threads process type
+workerStartDelay | | 500 | integer | milliseconds to wait at charging station worker threads startup
+workerPoolMinSize | | 4 | integer | worker threads pool minimum number of threads
+workerPoolMaxSize | | 16 | integer | worker threads pool maximum number of threads
+workerPoolStrategy | ROUND_ROBIN/LESS_RECENTLY_USED/... | [poolifier](https://github.com/poolifier/poolifier) default: ROUND_ROBBIN | string | worker threads pool [poolifier](https://github.com/poolifier/poolifier) worker choice strategy
+chargingStationsPerWorker | | 1 | integer | number of charging stations per worker threads for the `workerSet` process type
+logStatisticsInterval | | 60 | integer | seconds between charging stations statistics output in the logs
+logConsole | true/false | false | boolean | output logs on the console
+logFormat | | simple | string | winston log format
+logRotate | true/false | true | boolean | enable daily log files rotation
+logMaxFiles | | 7 | integer | maximum number of log files to keep
+logLevel | emerg/alert/crit/error/warning/notice/info/debug | info | string | winston logging level
+logFile | | combined.log | string | log file relative path
+logErrorFile | | error.log | string | error log file relative path
+performanceStorage | | { "enabled": false, "type": "jsonfile", "file:///performanceRecords.json" } | { enabled: string; type: string; URI: string; } where type can be 'jsonfile' or 'mongodb' | performance storage configuration section
+stationTemplateURLs | | {}[] | { file: string; numberOfStations: number; }[] | array of charging station templates URIs configuration section (template file name and number of stations)
+
+#### Worker process model:
+
+- **workerSet**:
+ Worker set executing each a static number (chargingStationsPerWorker) of simulated charging stations from the total
+
+- **staticPool**:
+ Statically sized worker pool executing a static total number of simulated charging stations
+
+- **dynamicPool**:
+ Dynamically sized worker pool executing a static total number of simulated charging stations
+
+### Charging station template
+
+Key | Value(s) | Default Value | Value type | Description
+--- | -------| --------------| ---------- | ------------
+supervisionURL | | '' | string | connection URI to OCPP-J server
+supervisionUser | | '' | string | basic HTTP authentication user to OCPP-J server
+supervisionPassword | | '' | string | basic HTTP authentication password to OCPP-J server
+ocppVersion | 1.6 | 1.6 | string | OCPP version
+ocppProtocol | json | json | string | OCPP protocol
+authorizationFile | | '' | string | RFID tags list file relative to src/assets path
+baseName | | '' | string | base name to build charging stations name
+nameSuffix | | '' | string | name suffix to build charging stations name
+fixedName | true/false | false | boolean | use the baseName as the charging stations unique name
+chargePointModel | | '' | string | charging stations model
+chargePointVendor | | '' | string | charging stations vendor
+chargeBoxSerialNumberPrefix | | '' | string | charging stations serial number prefix
+firmwareVersion | | '' | string | charging stations firmware version
+power | | | float\|float[] | charging stations maximum power value(s)
+powerSharedByConnectors | true/false | false | boolean | charging stations power shared by its connectors
+powerUnit | W/kW | W | string | charging stations power unit
+currentOutType | AC/DC | AC | string | charging stations current out type
+voltageOut | | AC:230/DC:400 | integer | charging stations voltage out
+numberOfPhases | 0/1/3 | AC:3/DC:0 | integer | charging stations number of phase(s)
+numberOfConnectors | | | integer\|integer[] | charging stations number of connector(s)
+useConnectorId0 | true/false | true | boolean | use connector id 0 definition from the template
+randomConnectors | true/false | false | boolean | randomize runtime connector id affectation from the connector id definition in template
+resetTime | | 60 | integer | seconds to wait before the charging stations come back at reset
+autoRegister | true/false | false | boolean | set the charging station as registered at boot notification for testing purpose
+autoReconnectMaxRetries | | -1 (unlimited) | integer | connection retries to the OCPP-J server
+reconnectExponentialDelay | true/false | false | boolean | connection delay retry to the OCPP-J server
+registrationMaxRetries | | -1 (unlimited) | integer | charging stations boot notification retries
+enableStatistics | true/false | true | boolean | enable charging stations statistics
+mayAuthorizeAtRemoteStart | true/false | true | boolean | always send authorize at remote start transaction when AuthorizeRemoteTxRequests is enabled
+beginEndMeterValues | true/false | false | boolean | enable Transaction.{Begin,End} MeterValues
+outOfOrderEndMeterValues | true/false | false | boolean | send Transaction.End MeterValues out of order
+meteringPerTransaction | true/false | true | boolean | enable metering history on a per transaction basis
+transactionDataMeterValues | true/false | false | boolean | enable transaction data MeterValues at stop transaction
+mainVoltageMeterValues | true/false | true | boolean | include charging station main voltage MeterValues on three phased charging stations
+phaseLineToLineVoltageMeterValues | true/false | true | boolean | include charging station line to line voltage MeterValues on three phased charging stations
+Configuration | | | ChargingStationConfiguration | charging stations OCPP parameters configuration section
+AutomaticTransactionGenerator | | | AutomaticTransactionGenerator | charging stations ATG configuration section
+Connectors | | | Connectors | charging stations connectors configuration section
+
+#### Configuration section
+
+```json
+ "Configuration": {
+ "configurationKey": [
+ ...
+ {
+ "key": "StandardKey",
+ "readonly": false,
+ "value": "StandardValue",
+ "visible": true,
+ "reboot": false
+ },
+ ...
+ {
+ "key": "VendorKey",
+ "readonly": false,
+ "value": "VendorValue",
+ "visible": false,
+ "reboot": true
+ },
+ ...
+ ]
+ }
+```
+
+#### AutomaticTransactionGenerator section
+
+```json
+ "AutomaticTransactionGenerator": {
+ "enable": false,
+ "minDuration": 60,
+ "maxDuration": 80,
+ "minDelayBetweenTwoTransactions": 15,
+ "maxDelayBetweenTwoTransactions": 30,
+ "probabilityOfStart": 1,
+ "stopAfterHours": 0.3,
+ "stopOnConnectionFailure": true,
+ "requireAuthorize": true
+ }
+```
+#### Connectors section
+
+```json
+ "Connectors": {
+ "0": {},
+ "1": {
+ "bootStatus": "Available",
+ "MeterValues": [
+ ...
+ {
+ "unit": "W",
+ "measurand": "Power.Active.Import",
+ "phase": "L1-N",
+ "value": "5000",
+ "fluctuationPercent": "10"
+ },
+ ...
+ {
+ "unit": "A",
+ "measurand": "Current.Import"
+ },
+ ...
+ {
+ "unit": "Wh"
+ },
+ ...
+ ]
+ }
+ },
+```
+
+## Start