+ private incomingRequestHandlers: Map<OCPP16IncomingRequestCommand, IncomingRequestHandler>;
+ private jsonSchemas: Map<OCPP16IncomingRequestCommand, JSONSchemaType<JsonObject>>;
+
+ public constructor() {
+ if (new.target?.name === moduleName) {
+ throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
+ }
+ super();
+ this.incomingRequestHandlers = new Map<OCPP16IncomingRequestCommand, IncomingRequestHandler>([
+ [OCPP16IncomingRequestCommand.RESET, this.handleRequestReset.bind(this)],
+ [OCPP16IncomingRequestCommand.CLEAR_CACHE, this.handleRequestClearCache.bind(this)],
+ [OCPP16IncomingRequestCommand.UNLOCK_CONNECTOR, this.handleRequestUnlockConnector.bind(this)],
+ [
+ OCPP16IncomingRequestCommand.GET_CONFIGURATION,
+ this.handleRequestGetConfiguration.bind(this),
+ ],
+ [
+ OCPP16IncomingRequestCommand.CHANGE_CONFIGURATION,
+ this.handleRequestChangeConfiguration.bind(this),
+ ],
+ [
+ OCPP16IncomingRequestCommand.SET_CHARGING_PROFILE,
+ this.handleRequestSetChargingProfile.bind(this),
+ ],
+ [
+ OCPP16IncomingRequestCommand.CLEAR_CHARGING_PROFILE,
+ this.handleRequestClearChargingProfile.bind(this),
+ ],
+ [
+ OCPP16IncomingRequestCommand.CHANGE_AVAILABILITY,
+ this.handleRequestChangeAvailability.bind(this),
+ ],
+ [
+ OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION,
+ this.handleRequestRemoteStartTransaction.bind(this),
+ ],
+ [
+ OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION,
+ this.handleRequestRemoteStopTransaction.bind(this),
+ ],
+ [OCPP16IncomingRequestCommand.GET_DIAGNOSTICS, this.handleRequestGetDiagnostics.bind(this)],
+ [OCPP16IncomingRequestCommand.TRIGGER_MESSAGE, this.handleRequestTriggerMessage.bind(this)],
+ ]);
+ this.jsonSchemas = new Map<OCPP16IncomingRequestCommand, JSONSchemaType<JsonObject>>([
+ [
+ OCPP16IncomingRequestCommand.RESET,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/Reset.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<ResetRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.CLEAR_CACHE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/ClearCache.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16ClearCacheRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.UNLOCK_CONNECTOR,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/UnlockConnector.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<UnlockConnectorRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.GET_CONFIGURATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/GetConfiguration.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<GetConfigurationRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.CHANGE_CONFIGURATION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/ChangeConfiguration.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<ChangeConfigurationRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.GET_DIAGNOSTICS,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/GetDiagnostics.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<GetDiagnosticsRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.SET_CHARGING_PROFILE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/SetChargingProfile.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<SetChargingProfileRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.CLEAR_CHARGING_PROFILE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/ClearChargingProfile.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<ClearChargingProfileRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.CHANGE_AVAILABILITY,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/ChangeAvailability.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<ChangeAvailabilityRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/RemoteStartTransaction.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<RemoteStartTransactionRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/RemoteStopTransaction.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<RemoteStopTransactionRequest>,
+ ],
+ [
+ OCPP16IncomingRequestCommand.TRIGGER_MESSAGE,
+ JSON.parse(
+ fs.readFileSync(
+ path.resolve(
+ path.dirname(fileURLToPath(import.meta.url)),
+ '../../../assets/json-schemas/ocpp/1.6/TriggerMessage.json'
+ ),
+ 'utf8'
+ )
+ ) as JSONSchemaType<OCPP16TriggerMessageRequest>,
+ ],
+ ]);
+ this.validatePayload.bind(this);
+ }
+
+ public async incomingRequestHandler(
+ chargingStation: ChargingStation,
+ messageId: string,
+ commandName: OCPP16IncomingRequestCommand,
+ commandPayload: JsonType
+ ): Promise<void> {
+ let response: JsonType;
+ if (
+ chargingStation.getOcppStrictCompliance() &&
+ chargingStation.isInPendingState() &&
+ (commandName === OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION ||
+ commandName === OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION)
+ ) {
+ throw new OCPPError(
+ ErrorType.SECURITY_ERROR,
+ `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
+ commandPayload,
+ null,
+ 2
+ )} while the charging station is in pending state on the central server`,
+ commandName,
+ commandPayload
+ );
+ }
+ if (
+ chargingStation.isRegistered() ||
+ (!chargingStation.getOcppStrictCompliance() && chargingStation.isInUnknownState())
+ ) {
+ if (
+ this.incomingRequestHandlers.has(commandName) &&
+ ChargingStationUtils.isIncomingRequestCommandSupported(commandName, chargingStation)
+ ) {
+ try {
+ this.validatePayload(chargingStation, commandName, commandPayload);
+ // Call the method to build the response
+ response = await this.incomingRequestHandlers.get(commandName)(
+ chargingStation,
+ commandPayload
+ );
+ } catch (error) {
+ // Log
+ logger.error(
+ `${chargingStation.logPrefix()} ${moduleName}.incomingRequestHandler: Handle incoming request error:`,
+ error
+ );
+ throw error;
+ }
+ } else {
+ // Throw exception
+ throw new OCPPError(
+ ErrorType.NOT_IMPLEMENTED,
+ `${commandName} is not implemented to handle request PDU ${JSON.stringify(
+ commandPayload,
+ null,
+ 2
+ )}`,
+ commandName,
+ commandPayload
+ );