X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2Focpp%2F1.6%2FOCPP16IncomingRequestService.ts;h=9377c605cb94a966c201361311f5eae4e0394fc5;hb=5e0c67e8a137c2c9cf73b49ae2837c469d7b4af5;hp=eb0bdb8036a67f2063a8ef19ac09d385831aea28;hpb=881840227e53e3b8061a4025ff37aa056370e080;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index eb0bdb80..9377c605 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -11,12 +11,12 @@ import Constants from '../../../utils/Constants'; import { DefaultResponse } from '../../../types/ocpp/Responses'; import { ErrorType } from '../../../types/ocpp/ErrorType'; import { IncomingRequestHandler } from '../../../types/ocpp/Requests'; -import { MessageType } from '../../../types/ocpp/MessageType'; +import { JsonType } from '../../../types/JsonType'; import { OCPP16ChargePointStatus } from '../../../types/ocpp/1.6/ChargePointStatus'; import { OCPP16DiagnosticsStatus } from '../../../types/ocpp/1.6/DiagnosticsStatus'; import { OCPP16StandardParametersKey } from '../../../types/ocpp/1.6/Configuration'; import { OCPPConfigurationKey } from '../../../types/ocpp/Configuration'; -import OCPPError from '../OCPPError'; +import OCPPError from '../../../exception/OCPPError'; import OCPPIncomingRequestService from '../OCPPIncomingRequestService'; import { URL } from 'url'; import Utils from '../../../utils/Utils'; @@ -28,7 +28,10 @@ import tar from 'tar'; export default class OCPP16IncomingRequestService extends OCPPIncomingRequestService { private incomingRequestHandlers: Map; - constructor(chargingStation: ChargingStation) { + public constructor(chargingStation: ChargingStation) { + if (new.target?.name === 'OCPP16IncomingRequestService') { + throw new TypeError(`Cannot construct ${new.target?.name} instances directly`); + } super(chargingStation); this.incomingRequestHandlers = new Map([ [OCPP16IncomingRequestCommand.RESET, this.handleRequestReset.bind(this)], @@ -46,23 +49,31 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ]); } - public async handleRequest(messageId: string, commandName: OCPP16IncomingRequestCommand, commandPayload: Record): Promise { - let response: Record; - if (this.incomingRequestHandlers.has(commandName)) { - try { - // Call the method to build the response - response = await this.incomingRequestHandlers.get(commandName)(commandPayload); - } catch (error) { - // Log - logger.error(this.chargingStation.logPrefix() + ' Handle request error: %j', error); - throw error; + public async handleRequest(messageId: string, commandName: OCPP16IncomingRequestCommand, commandPayload: JsonType): Promise { + let result: JsonType; + if (this.chargingStation.getOcppStrictCompliance() && (this.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 payload ${JSON.stringify(commandPayload, null, 2)} while the charging station is in pending state on the central server`, commandName); + } + if (this.chargingStation.isRegistered() || (!this.chargingStation.getOcppStrictCompliance() && this.chargingStation.isInUnknownState())) { + if (this.incomingRequestHandlers.has(commandName)) { + try { + // Call the method to build the result + result = await this.incomingRequestHandlers.get(commandName)(commandPayload); + } catch (error) { + // Log + logger.error(this.chargingStation.logPrefix() + ' Handle request error: %j', error); + throw error; + } + } else { + // Throw exception + throw new OCPPError(ErrorType.NOT_IMPLEMENTED, `${commandName} is not implemented to handle request payload ${JSON.stringify(commandPayload, null, 2)}`, commandName); } } else { - // Throw exception - throw new OCPPError(ErrorType.NOT_IMPLEMENTED, `${commandName} is not implemented to handle request payload ${JSON.stringify(commandPayload, null, 2)}`, commandName); + throw new OCPPError(ErrorType.SECURITY_ERROR, `${commandName} cannot be issued to handle request payload ${JSON.stringify(commandPayload, null, 2)} while the charging station is not registered on the central server.`, commandName); } - // Send the built response - await this.chargingStation.ocppRequestService.sendMessage(messageId, response, MessageType.CALL_RESULT_MESSAGE, commandName); + // Send the built result + await this.chargingStation.ocppRequestService.sendResult(messageId, result, commandName); } // Simulate charging station restart @@ -292,16 +303,17 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer if (this.chargingStation.getAuthorizeRemoteTxRequests()) { let authorized = false; if (this.chargingStation.getLocalAuthListEnabled() && this.chargingStation.hasAuthorizedTags() - && this.chargingStation.authorizedTags.find((value) => value === commandPayload.idTag)) { + && this.chargingStation.authorizedTags.find((value) => value === commandPayload.idTag)) { this.chargingStation.getConnectorStatus(transactionConnectorId).localAuthorizeIdTag = commandPayload.idTag; this.chargingStation.getConnectorStatus(transactionConnectorId).idTagLocalAuthorized = true; authorized = true; - } - if (!authorized && this.chargingStation.getMayAuthorizeAtRemoteStart()) { + } else if (this.chargingStation.getMayAuthorizeAtRemoteStart()) { const authorizeResponse = await this.chargingStation.ocppRequestService.sendAuthorize(transactionConnectorId, commandPayload.idTag); if (authorizeResponse?.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) { authorized = true; } + } else { + logger.warn(`${this.chargingStation.logPrefix()} The charging station configuration expects authorize at remote start transaction but local authorization or authorize isn't enabled`); } if (authorized) { // Authorization successful, start transaction @@ -425,12 +437,15 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer setTimeout(() => { this.chargingStation.ocppRequestService.sendBootNotification(this.chargingStation.getBootNotificationRequest().chargePointModel, this.chargingStation.getBootNotificationRequest().chargePointVendor, this.chargingStation.getBootNotificationRequest().chargeBoxSerialNumber, - this.chargingStation.getBootNotificationRequest().firmwareVersion).catch(() => { /* This is intentional */ }); + this.chargingStation.getBootNotificationRequest().firmwareVersion, this.chargingStation.getBootNotificationRequest().chargePointSerialNumber, + this.chargingStation.getBootNotificationRequest().iccid, this.chargingStation.getBootNotificationRequest().imsi, + this.chargingStation.getBootNotificationRequest().meterSerialNumber, this.chargingStation.getBootNotificationRequest().meterType, + { triggerMessage: true }).catch(() => { /* This is intentional */ }); }, Constants.OCPP_TRIGGER_MESSAGE_DELAY); return Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED; case MessageTrigger.Heartbeat: setTimeout(() => { - this.chargingStation.ocppRequestService.sendHeartbeat().catch(() => { /* This is intentional */ }); + this.chargingStation.ocppRequestService.sendHeartbeat({ triggerMessage: true }).catch(() => { /* This is intentional */ }); }, Constants.OCPP_TRIGGER_MESSAGE_DELAY); return Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED; default: