X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;ds=sidebyside;f=src%2Fcharging-station%2Focpp%2F1.6%2FOCPP16ResponseService.ts;h=aec5d65f31ba851e199aa865b8b759694b81faea;hb=3024d5b2497e97bdd355243a5d236fa3f7a4d874;hp=e65f8a8cb3f7316a6415d8697e1bb527d1a5c20e;hpb=24d15716245469249b57e5aa790147d703d60a4e;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts index e65f8a8c..aec5d65f 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts @@ -3,10 +3,9 @@ import type { ValidateFunction } from 'ajv' import { secondsToMilliseconds } from 'date-fns' -import { OCPP16ServiceUtils } from './OCPP16ServiceUtils.js' import { - type ChargingStation, addConfigurationKey, + type ChargingStation, getConfigurationKey, hasReservationExpired, resetConnectorStatus @@ -14,6 +13,7 @@ import { import { OCPPError } from '../../../exception/index.js' import { type ChangeConfigurationResponse, + ChargingStationEvents, ErrorType, type GenericResponse, type GetConfigurationResponse, @@ -51,18 +51,19 @@ import { type SetChargingProfileResponse, type UnlockConnectorResponse } from '../../../types/index.js' -import { Constants, convertToInt, logger } from '../../../utils/index.js' +import { Constants, convertToInt, isAsyncFunction, logger } from '../../../utils/index.js' import { OCPPResponseService } from '../OCPPResponseService.js' +import { OCPP16ServiceUtils } from './OCPP16ServiceUtils.js' const moduleName = 'OCPP16ResponseService' export class OCPP16ResponseService extends OCPPResponseService { - public jsonSchemasIncomingRequestResponseValidateFunction: Map< + public incomingRequestResponsePayloadValidateFunctions: Map< OCPP16IncomingRequestCommand, ValidateFunction > - protected jsonSchemasValidateFunction: Map> + protected payloadValidateFunctions: Map> private readonly responseHandlers: Map public constructor () { @@ -97,7 +98,7 @@ export class OCPP16ResponseService extends OCPPResponseService { [OCPP16RequestCommand.DATA_TRANSFER, this.emptyResponseHandler], [OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, this.emptyResponseHandler] ]) - this.jsonSchemasValidateFunction = new Map>([ + this.payloadValidateFunctions = new Map>([ [ OCPP16RequestCommand.BOOT_NOTIFICATION, this.ajv @@ -219,13 +220,13 @@ export class OCPP16ResponseService extends OCPPResponseService { .bind(this) ] ]) - this.jsonSchemasIncomingRequestResponseValidateFunction = new Map< + this.incomingRequestResponsePayloadValidateFunctions = new Map< OCPP16IncomingRequestCommand, ValidateFunction >([ [ OCPP16IncomingRequestCommand.RESET, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/ResetResponse.json', @@ -237,7 +238,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.CLEAR_CACHE, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/ClearCacheResponse.json', @@ -249,7 +250,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.CHANGE_AVAILABILITY, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/ChangeAvailabilityResponse.json', @@ -261,7 +262,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.UNLOCK_CONNECTOR, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/UnlockConnectorResponse.json', @@ -273,7 +274,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.GET_CONFIGURATION, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/GetConfigurationResponse.json', @@ -285,7 +286,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.CHANGE_CONFIGURATION, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/ChangeConfigurationResponse.json', @@ -297,7 +298,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.GET_COMPOSITE_SCHEDULE, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/GetCompositeScheduleResponse.json', @@ -309,7 +310,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.SET_CHARGING_PROFILE, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/SetChargingProfileResponse.json', @@ -321,7 +322,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.CLEAR_CHARGING_PROFILE, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/ClearChargingProfileResponse.json', @@ -333,7 +334,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/RemoteStartTransactionResponse.json', @@ -345,7 +346,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/RemoteStopTransactionResponse.json', @@ -357,7 +358,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.GET_DIAGNOSTICS, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/GetDiagnosticsResponse.json', @@ -369,7 +370,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.TRIGGER_MESSAGE, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/TriggerMessageResponse.json', @@ -381,7 +382,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.DATA_TRANSFER, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/DataTransferResponse.json', @@ -393,7 +394,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.UPDATE_FIRMWARE, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/UpdateFirmwareResponse.json', @@ -405,7 +406,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.RESERVE_NOW, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/ReserveNowResponse.json', @@ -417,7 +418,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ], [ OCPP16IncomingRequestCommand.CANCEL_RESERVATION, - this.ajv + this.ajvIncomingRequest .compile( OCPP16ServiceUtils.parseJsonSchemaFile( 'assets/json-schemas/ocpp/1.6/CancelReservationResponse.json', @@ -445,7 +446,18 @@ export class OCPP16ResponseService extends OCPPResponseService { try { this.validatePayload(chargingStation, commandName, payload) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - await this.responseHandlers.get(commandName)!(chargingStation, payload, requestPayload) + const responseHandler = this.responseHandlers.get(commandName)! + if (isAsyncFunction(responseHandler)) { + await responseHandler(chargingStation, payload, requestPayload) + } else { + ( + responseHandler as ( + chargingStation: ChargingStation, + payload: JsonType, + requestPayload?: JsonType + ) => void + )(chargingStation, payload, requestPayload) + } } catch (error) { logger.error( `${chargingStation.logPrefix()} ${moduleName}.responseHandler: Handle response error:`, @@ -473,7 +485,7 @@ export class OCPP16ResponseService extends OCPPResponseService { payload, undefined, 2 - )} while the charging station is not registered on the central server.`, + )} while the charging station is not registered on the central server`, commandName, payload ) @@ -485,7 +497,7 @@ export class OCPP16ResponseService extends OCPPResponseService { commandName: OCPP16RequestCommand, payload: JsonType ): boolean { - if (this.jsonSchemasValidateFunction.has(commandName)) { + if (this.payloadValidateFunctions.has(commandName)) { return this.validateResponsePayload(chargingStation, commandName, payload) } logger.warn( @@ -498,24 +510,30 @@ export class OCPP16ResponseService extends OCPPResponseService { chargingStation: ChargingStation, payload: OCPP16BootNotificationResponse ): void { - if (payload.status === RegistrationStatusEnumType.ACCEPTED) { - addConfigurationKey( - chargingStation, - OCPP16StandardParametersKey.HeartbeatInterval, - payload.interval.toString(), - {}, - { overwrite: true, save: true } - ) - addConfigurationKey( - chargingStation, - OCPP16StandardParametersKey.HeartBeatInterval, - payload.interval.toString(), - { visible: false }, - { overwrite: true, save: true } - ) - OCPP16ServiceUtils.startHeartbeatInterval(chargingStation, payload.interval) - } if (Object.values(RegistrationStatusEnumType).includes(payload.status)) { + chargingStation.bootNotificationResponse = payload + if (chargingStation.isRegistered()) { + chargingStation.emit(ChargingStationEvents.registered) + if (chargingStation.inAcceptedState()) { + addConfigurationKey( + chargingStation, + OCPP16StandardParametersKey.HeartbeatInterval, + payload.interval.toString(), + {}, + { overwrite: true, save: true } + ) + addConfigurationKey( + chargingStation, + OCPP16StandardParametersKey.HeartBeatInterval, + payload.interval.toString(), + { visible: false }, + { overwrite: true, save: true } + ) + chargingStation.emit(ChargingStationEvents.accepted) + } + } else if (chargingStation.inRejectedState()) { + chargingStation.emit(ChargingStationEvents.rejected) + } const logMsg = `${chargingStation.logPrefix()} Charging station in '${ payload.status }' state on the central server` @@ -523,6 +541,7 @@ export class OCPP16ResponseService extends OCPPResponseService { ? logger.warn(logMsg) : logger.info(logMsg) } else { + delete chargingStation.bootNotificationResponse logger.error( `${chargingStation.logPrefix()} Charging station boot notification response received: %j with undefined registration status`, payload @@ -572,9 +591,9 @@ export class OCPP16ResponseService extends OCPPResponseService { authorizeConnectorStatus.idTagAuthorized = false delete authorizeConnectorStatus.authorizeIdTag logger.debug( - `${chargingStation.logPrefix()} idTag '${requestPayload.idTag}' rejected with status '${ - payload.idTagInfo.status - }` + `${chargingStation.logPrefix()} idTag '${ + requestPayload.idTag + }' rejected with status '${payload.idTagInfo.status}'` ) } } else { @@ -687,7 +706,9 @@ export class OCPP16ResponseService extends OCPPResponseService { connectorStatus?.status !== OCPP16ChargePointStatus.Preparing ) { logger.error( - `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${connectorId} with status ${connectorStatus?.status}` + `${chargingStation.logPrefix()} Trying to start a transaction on connector id ${connectorId} with status ${ + connectorStatus?.status + }` ) return } @@ -722,9 +743,9 @@ export class OCPP16ResponseService extends OCPPResponseService { logger.warn( `${chargingStation.logPrefix()} Reserved transaction ${ payload.transactionId - } started with a different idTag ${requestPayload.idTag} than the reservation one ${ - reservation.idTag - }` + } started with a different idTag ${ + requestPayload.idTag + } than the reservation one ${reservation.idTag}` ) } if (hasReservationExpired(reservation)) { @@ -763,11 +784,9 @@ export class OCPP16ResponseService extends OCPPResponseService { OCPP16ChargePointStatus.Charging ) logger.info( - `${chargingStation.logPrefix()} Transaction with id ${ - payload.transactionId - } STARTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for idTag '${ - requestPayload.idTag - }'` + `${chargingStation.logPrefix()} Transaction with id ${payload.transactionId} STARTED on ${ + chargingStation.stationInfo?.chargingStationId + }#${connectorId} for idTag '${requestPayload.idTag}'` ) if (chargingStation.stationInfo?.powerSharedByConnectors === true) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -805,16 +824,10 @@ export class OCPP16ResponseService extends OCPPResponseService { chargingStation: ChargingStation, connectorId: number ): Promise { + chargingStation.stopMeterValues(connectorId) const connectorStatus = chargingStation.getConnectorStatus(connectorId) resetConnectorStatus(connectorStatus) - chargingStation.stopMeterValues(connectorId) - if (connectorStatus?.status !== OCPP16ChargePointStatus.Available) { - await OCPP16ServiceUtils.sendAndSetConnectorStatus( - chargingStation, - connectorId, - OCPP16ChargePointStatus.Available - ) - } + await OCPP16ServiceUtils.restoreConnectorStatus(chargingStation, connectorId, connectorStatus) } private async handleResponseStopTransaction (