X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2Focpp%2F1.6%2FOCPP16IncomingRequestService.ts;h=03eb83f83de114e11f2f6865e2fbba2efe3a5bed;hb=ad67a158ed1e333a255b49e0c8b4aaa9c7b85867;hp=93c59ba29cfcedaa63f334270f4f2ca37766372f;hpb=bfbda738d80c83b76e2d38f221bfe305a4a89c2b;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 93c59ba2..03eb83f8 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -8,6 +8,7 @@ import type { JSONSchemaType } from 'ajv'; import { Client, type FTPResponse } from 'basic-ftp'; import tar from 'tar'; +import { OCPP16ServiceUtils } from './OCPP16ServiceUtils'; import OCPPError from '../../../exception/OCPPError'; import type { JsonObject, JsonType } from '../../../types/JsonType'; import { OCPP16ChargePointErrorCode } from '../../../types/ocpp/1.6/ChargePointErrorCode'; @@ -25,7 +26,6 @@ import { type ChangeAvailabilityRequest, type ChangeConfigurationRequest, type ClearChargingProfileRequest, - type DiagnosticsStatusNotificationRequest, type GetConfigurationRequest, type GetDiagnosticsRequest, OCPP16AvailabilityType, @@ -33,6 +33,9 @@ import { type OCPP16ClearCacheRequest, type OCPP16DataTransferRequest, OCPP16DataTransferVendorId, + type OCPP16DiagnosticsStatusNotificationRequest, + OCPP16FirmwareStatus, + type OCPP16FirmwareStatusNotificationRequest, type OCPP16HeartbeatRequest, OCPP16IncomingRequestCommand, OCPP16MessageTrigger, @@ -50,12 +53,13 @@ import { type ChangeAvailabilityResponse, type ChangeConfigurationResponse, type ClearChargingProfileResponse, - type DiagnosticsStatusNotificationResponse, type GetConfigurationResponse, type GetDiagnosticsResponse, type OCPP16BootNotificationResponse, type OCPP16DataTransferResponse, OCPP16DataTransferStatus, + type OCPP16DiagnosticsStatusNotificationResponse, + type OCPP16FirmwareStatusNotificationResponse, type OCPP16HeartbeatResponse, type OCPP16StatusNotificationResponse, type OCPP16TriggerMessageResponse, @@ -75,7 +79,7 @@ import type { OCPPConfigurationKey } from '../../../types/ocpp/Configuration'; import { ErrorType } from '../../../types/ocpp/ErrorType'; import { OCPPVersion } from '../../../types/ocpp/OCPPVersion'; import type { IncomingRequestHandler } from '../../../types/ocpp/Requests'; -import type { DefaultResponse } from '../../../types/ocpp/Responses'; +import type { GenericResponse } from '../../../types/ocpp/Responses'; import Constants from '../../../utils/Constants'; import logger from '../../../utils/Logger'; import Utils from '../../../utils/Utils'; @@ -84,13 +88,12 @@ import { ChargingStationConfigurationUtils } from '../../ChargingStationConfigur import { ChargingStationUtils } from '../../ChargingStationUtils'; import OCPPConstants from '../OCPPConstants'; import OCPPIncomingRequestService from '../OCPPIncomingRequestService'; -import { OCPP16ServiceUtils } from './OCPP16ServiceUtils'; const moduleName = 'OCPP16IncomingRequestService'; export default class OCPP16IncomingRequestService extends OCPPIncomingRequestService { + protected jsonSchemas: Map>; private incomingRequestHandlers: Map; - private jsonSchemas: Map>; public constructor() { if (new.target?.name === moduleName) { @@ -132,176 +135,90 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer [OCPP16IncomingRequestCommand.GET_DIAGNOSTICS, this.handleRequestGetDiagnostics.bind(this)], [OCPP16IncomingRequestCommand.TRIGGER_MESSAGE, this.handleRequestTriggerMessage.bind(this)], [OCPP16IncomingRequestCommand.DATA_TRANSFER, this.handleRequestDataTransfer.bind(this)], - // [OCPP16IncomingRequestCommand.UPDATE_FIRMWARE, this.handleRequestUpdateFirmware.bind(this)], + [OCPP16IncomingRequestCommand.UPDATE_FIRMWARE, this.handleRequestUpdateFirmware.bind(this)], ]); this.jsonSchemas = new Map>([ [ 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, + this.parseJsonSchemaFile('../../../assets/json-schemas/ocpp/1.6/Reset.json'), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/ClearCache.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/UnlockConnector.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/GetConfiguration.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/ChangeConfiguration.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/GetDiagnostics.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/SetChargingProfile.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/ClearChargingProfile.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/ChangeAvailability.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/RemoteStartTransaction.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/RemoteStopTransaction.json' + ), ], [ 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, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/TriggerMessage.json' + ), ], [ OCPP16IncomingRequestCommand.DATA_TRANSFER, - JSON.parse( - fs.readFileSync( - path.resolve( - path.dirname(fileURLToPath(import.meta.url)), - '../../../assets/json-schemas/ocpp/1.6/DataTransfer.json' - ), - 'utf8' - ) - ) as JSONSchemaType, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/DataTransfer.json' + ), ], [ OCPP16IncomingRequestCommand.UPDATE_FIRMWARE, - JSON.parse( - fs.readFileSync( - path.resolve( - path.dirname(fileURLToPath(import.meta.url)), - '../../../assets/json-schemas/ocpp/1.6/UpdateFirmware.json' - ), - 'utf8' - ) - ) as JSONSchemaType, + this.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/UpdateFirmware.json' + ), ], ]); this.validatePayload.bind(this); @@ -403,7 +320,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ); } logger.warn( - `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command ${commandName} PDU validation` + `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation` ); return false; } @@ -412,7 +329,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer private handleRequestReset( chargingStation: ChargingStation, commandPayload: ResetRequest - ): DefaultResponse { + ): GenericResponse { this.asyncResource .runInAsyncScope( chargingStation.reset.bind(chargingStation) as ( @@ -435,13 +352,6 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer return OCPPConstants.OCPP_RESPONSE_ACCEPTED; } - private handleRequestClearCache(chargingStation: ChargingStation): DefaultResponse { - chargingStation.authorizedTagsCache.deleteAuthorizedTags( - ChargingStationUtils.getAuthorizationFile(chargingStation.stationInfo) - ); - return OCPPConstants.OCPP_RESPONSE_ACCEPTED; - } - private async handleRequestUnlockConnector( chargingStation: ChargingStation, commandPayload: UnlockConnectorRequest @@ -634,8 +544,8 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer logger.debug( `${chargingStation.logPrefix()} Charging profile(s) set on connector id ${ commandPayload.connectorId - }, dump their stack: %j`, - chargingStation.getConnectorStatus(commandPayload.connectorId).chargingProfiles + }: %j`, + commandPayload.csChargingProfiles ); return OCPPConstants.OCPP_SET_CHARGING_PROFILE_RESPONSE_ACCEPTED; } @@ -667,8 +577,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer logger.debug( `${chargingStation.logPrefix()} Charging profile(s) cleared on connector id ${ commandPayload.connectorId - }, dump their stack: %j`, - connectorStatus.chargingProfiles + }` ); return OCPPConstants.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_ACCEPTED; } @@ -704,10 +613,8 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer if (clearCurrentCP) { connectorStatus.chargingProfiles.splice(index, 1); logger.debug( - `${chargingStation.logPrefix()} Matching charging profile(s) cleared on connector id ${ - commandPayload.connectorId - }, dump their stack: %j`, - connectorStatus.chargingProfiles + `${chargingStation.logPrefix()} Matching charging profile(s) cleared: %j`, + chargingProfile ); clearedCP = true; } @@ -784,7 +691,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer private async handleRequestRemoteStartTransaction( chargingStation: ChargingStation, commandPayload: RemoteStartTransactionRequest - ): Promise { + ): Promise { const transactionConnectorId = commandPayload.connectorId; if (chargingStation.connectors.has(transactionConnectorId) === true) { const remoteStartTransactionLogMsg = @@ -933,7 +840,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer chargingStation: ChargingStation, connectorId: number, idTag: string - ): Promise { + ): Promise { if ( chargingStation.getConnectorStatus(connectorId).status !== OCPP16ChargePointStatus.AVAILABLE ) { @@ -970,8 +877,8 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer if (cp && cp.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE) { OCPP16ServiceUtils.setChargingProfile(chargingStation, connectorId, cp); logger.debug( - `${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on connector id ${connectorId}, dump their stack: %j`, - chargingStation.getConnectorStatus(connectorId).chargingProfiles + `${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on connector id ${connectorId}: %j`, + cp ); return true; } else if (cp && cp.chargingProfilePurpose !== ChargingProfilePurposeType.TX_PROFILE) { @@ -989,7 +896,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer private async handleRequestRemoteStopTransaction( chargingStation: ChargingStation, commandPayload: RemoteStopTransactionRequest - ): Promise { + ): Promise { const transactionId = commandPayload.transactionId; for (const connectorId of chargingStation.connectors.keys()) { if ( @@ -1034,15 +941,106 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer OCPP16IncomingRequestCommand.UPDATE_FIRMWARE ) === false ) { + logger.warn( + `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: feature profile not supported` + ); return OCPPConstants.OCPP_RESPONSE_EMPTY; } - logger.debug( - chargingStation.logPrefix() + - ' ' + - OCPP16IncomingRequestCommand.UPDATE_FIRMWARE + - ' request received: %j', - commandPayload - ); + if ( + !Utils.isNullOrUndefined(chargingStation.stationInfo.firmwareStatus) && + chargingStation.stationInfo.firmwareStatus !== OCPP16FirmwareStatus.Installed + ) { + logger.warn( + `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: firmware update is already in progress` + ); + return OCPPConstants.OCPP_RESPONSE_EMPTY; + } + const retrieveDate = Utils.convertToDate(commandPayload.retrieveDate); + if (retrieveDate.getTime() <= Date.now()) { + this.asyncResource + .runInAsyncScope( + this.updateFirmware.bind(this) as ( + this: OCPP16IncomingRequestService, + ...args: any[] + ) => Promise, + this, + chargingStation + ) + .catch(() => { + /* This is intentional */ + }); + } else { + setTimeout(() => { + this.updateFirmware(chargingStation).catch(() => { + /* Intentional */ + }); + }, retrieveDate.getTime() - Date.now()); + } + return OCPPConstants.OCPP_RESPONSE_EMPTY; + } + + private async updateFirmware( + chargingStation: ChargingStation, + maxDelay = 30, + minDelay = 15 + ): Promise { + chargingStation.stopAutomaticTransactionGenerator(); + for (const connectorId of chargingStation.connectors.keys()) { + if ( + connectorId > 0 && + chargingStation.getConnectorStatus(connectorId).transactionStarted === false + ) { + await chargingStation.ocppRequestService.requestHandler< + OCPP16StatusNotificationRequest, + OCPP16StatusNotificationResponse + >(chargingStation, OCPP16RequestCommand.STATUS_NOTIFICATION, { + connectorId, + status: OCPP16ChargePointStatus.UNAVAILABLE, + errorCode: OCPP16ChargePointErrorCode.NO_ERROR, + }); + chargingStation.getConnectorStatus(connectorId).status = + OCPP16ChargePointStatus.UNAVAILABLE; + } + } + if ( + chargingStation.stationInfo?.firmwareUpgrade?.failureStatus && + !Utils.isEmptyString(chargingStation.stationInfo?.firmwareUpgrade?.failureStatus) + ) { + await chargingStation.ocppRequestService.requestHandler< + OCPP16FirmwareStatusNotificationRequest, + OCPP16FirmwareStatusNotificationResponse + >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { + status: chargingStation.stationInfo?.firmwareUpgrade?.failureStatus, + }); + return; + } + await chargingStation.ocppRequestService.requestHandler< + OCPP16FirmwareStatusNotificationRequest, + OCPP16FirmwareStatusNotificationResponse + >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { + status: OCPP16FirmwareStatus.Downloading, + }); + chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Downloading; + await Utils.sleep(Utils.getRandomInteger(maxDelay, minDelay) * 1000); + await chargingStation.ocppRequestService.requestHandler< + OCPP16FirmwareStatusNotificationRequest, + OCPP16FirmwareStatusNotificationResponse + >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { + status: OCPP16FirmwareStatus.Downloaded, + }); + chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Downloaded; + await Utils.sleep(Utils.getRandomInteger(maxDelay, minDelay) * 1000); + await chargingStation.ocppRequestService.requestHandler< + OCPP16FirmwareStatusNotificationRequest, + OCPP16FirmwareStatusNotificationResponse + >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { + status: OCPP16FirmwareStatus.Installing, + }); + chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Installing; + if (chargingStation.stationInfo?.firmwareUpgrade?.reset === true) { + await Utils.sleep(Utils.getRandomInteger(maxDelay, minDelay) * 1000); + await chargingStation.reset(OCPP16StopTransactionReason.REBOOT); + } } private async handleRequestGetDiagnostics( @@ -1056,15 +1054,11 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer OCPP16IncomingRequestCommand.GET_DIAGNOSTICS ) === false ) { + logger.warn( + `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetDiagnostics: Cannot get diagnostics: feature profile not supported` + ); return OCPPConstants.OCPP_RESPONSE_EMPTY; } - logger.debug( - chargingStation.logPrefix() + - ' ' + - OCPP16IncomingRequestCommand.GET_DIAGNOSTICS + - ' request received: %j', - commandPayload - ); const uri = new URL(commandPayload.location); if (uri.protocol.startsWith('ftp:')) { let ftpClient: Client; @@ -1084,19 +1078,27 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer }); let uploadResponse: FTPResponse; if (accessResponse.code === 220) { - // eslint-disable-next-line @typescript-eslint/no-misused-promises - ftpClient.trackProgress(async (info) => { + ftpClient.trackProgress((info) => { logger.info( `${chargingStation.logPrefix()} ${ info.bytes / 1024 } bytes transferred from diagnostics archive ${info.name}` ); - await chargingStation.ocppRequestService.requestHandler< - DiagnosticsStatusNotificationRequest, - DiagnosticsStatusNotificationResponse - >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, { - status: OCPP16DiagnosticsStatus.Uploading, - }); + chargingStation.ocppRequestService + .requestHandler< + OCPP16DiagnosticsStatusNotificationRequest, + OCPP16DiagnosticsStatusNotificationResponse + >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, { + status: OCPP16DiagnosticsStatus.Uploading, + }) + .catch((error) => { + logger.error( + `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetDiagnostics: Error while sending '${ + OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION + }'`, + error + ); + }); }); uploadResponse = await ftpClient.uploadFrom( path.join( @@ -1107,8 +1109,8 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ); if (uploadResponse.code === 226) { await chargingStation.ocppRequestService.requestHandler< - DiagnosticsStatusNotificationRequest, - DiagnosticsStatusNotificationResponse + OCPP16DiagnosticsStatusNotificationRequest, + OCPP16DiagnosticsStatusNotificationResponse >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, { status: OCPP16DiagnosticsStatus.Uploaded, }); @@ -1134,8 +1136,8 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ); } catch (error) { await chargingStation.ocppRequestService.requestHandler< - DiagnosticsStatusNotificationRequest, - DiagnosticsStatusNotificationResponse + OCPP16DiagnosticsStatusNotificationRequest, + OCPP16DiagnosticsStatusNotificationResponse >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, { status: OCPP16DiagnosticsStatus.UploadFailed, }); @@ -1156,8 +1158,8 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer } to transfer the diagnostic logs archive` ); await chargingStation.ocppRequestService.requestHandler< - DiagnosticsStatusNotificationRequest, - DiagnosticsStatusNotificationResponse + OCPP16DiagnosticsStatusNotificationRequest, + OCPP16DiagnosticsStatusNotificationResponse >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, { status: OCPP16DiagnosticsStatus.UploadFailed, }); @@ -1305,4 +1307,13 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ); } } + + private parseJsonSchemaFile(relativePath: string): JSONSchemaType { + return JSON.parse( + fs.readFileSync( + path.resolve(path.dirname(fileURLToPath(import.meta.url)), relativePath), + 'utf8' + ) + ) as JSONSchemaType; + } }