X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2Focpp%2F1.6%2FOCPP16IncomingRequestService.ts;h=6e31a43b80095f9900fce1695ae57b2d16761265;hb=7164966d863b4539243b473c5e2e9d22fb9b5fd1;hp=fbae8f85b05382e328bb0a931834fc35be936026;hpb=6a8329b4df5d3b236927e4b33a1730784b49a7ee;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 fbae8f85..6e31a43b 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -1,8 +1,8 @@ // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved. -import fs from 'fs'; -import path from 'path'; -import { URL, fileURLToPath } from 'url'; +import fs from 'node:fs'; +import path from 'node:path'; +import { URL, fileURLToPath } from 'node:url'; import type { JSONSchemaType } from 'ajv'; import { Client, type FTPResponse } from 'basic-ftp'; @@ -140,83 +140,85 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer this.jsonSchemas = new Map>([ [ OCPP16IncomingRequestCommand.RESET, - this.parseJsonSchemaFile('../../../assets/json-schemas/ocpp/1.6/Reset.json'), + OCPP16ServiceUtils.parseJsonSchemaFile( + '../../../assets/json-schemas/ocpp/1.6/Reset.json' + ), ], [ OCPP16IncomingRequestCommand.CLEAR_CACHE, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/ClearCache.json' ), ], [ OCPP16IncomingRequestCommand.UNLOCK_CONNECTOR, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/UnlockConnector.json' ), ], [ OCPP16IncomingRequestCommand.GET_CONFIGURATION, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/GetConfiguration.json' ), ], [ OCPP16IncomingRequestCommand.CHANGE_CONFIGURATION, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/ChangeConfiguration.json' ), ], [ OCPP16IncomingRequestCommand.GET_DIAGNOSTICS, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/GetDiagnostics.json' ), ], [ OCPP16IncomingRequestCommand.SET_CHARGING_PROFILE, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/SetChargingProfile.json' ), ], [ OCPP16IncomingRequestCommand.CLEAR_CHARGING_PROFILE, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/ClearChargingProfile.json' ), ], [ OCPP16IncomingRequestCommand.CHANGE_AVAILABILITY, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/ChangeAvailability.json' ), ], [ OCPP16IncomingRequestCommand.REMOTE_START_TRANSACTION, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/RemoteStartTransaction.json' ), ], [ OCPP16IncomingRequestCommand.REMOTE_STOP_TRANSACTION, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/RemoteStopTransaction.json' ), ], [ OCPP16IncomingRequestCommand.TRIGGER_MESSAGE, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/TriggerMessage.json' ), ], [ OCPP16IncomingRequestCommand.DATA_TRANSFER, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/DataTransfer.json' ), ], [ OCPP16IncomingRequestCommand.UPDATE_FIRMWARE, - this.parseJsonSchemaFile( + OCPP16ServiceUtils.parseJsonSchemaFile( '../../../assets/json-schemas/ocpp/1.6/UpdateFirmware.json' ), ], @@ -337,7 +339,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ...args: any[] ) => Promise, chargingStation, - (commandPayload.type + 'Reset') as OCPP16StopTransactionReason + `${commandPayload.type}Reset` as OCPP16StopTransactionReason ) .catch(() => { /* This is intentional */ @@ -365,7 +367,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer } if (connectorId === 0) { logger.error( - chargingStation.logPrefix() + ' Trying to unlock connector Id ' + connectorId.toString() + `${chargingStation.logPrefix()} Trying to unlock connector Id ${connectorId.toString()}` ); return OCPPConstants.OCPP_RESPONSE_UNLOCK_NOT_SUPPORTED; } @@ -544,8 +546,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; } @@ -572,23 +574,27 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer return OCPPConstants.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_UNKNOWN; } const connectorStatus = chargingStation.getConnectorStatus(commandPayload.connectorId); - if (commandPayload.connectorId && !Utils.isEmptyArray(connectorStatus.chargingProfiles)) { + if ( + !Utils.isNullOrUndefined(commandPayload.connectorId) && + !Utils.isEmptyArray(connectorStatus?.chargingProfiles) + ) { connectorStatus.chargingProfiles = []; 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; } - if (!commandPayload.connectorId) { + if (Utils.isNullOrUndefined(commandPayload.connectorId)) { let clearedCP = false; for (const connectorId of chargingStation.connectors.keys()) { - if (!Utils.isEmptyArray(chargingStation.getConnectorStatus(connectorId).chargingProfiles)) { + if ( + !Utils.isEmptyArray(chargingStation.getConnectorStatus(connectorId)?.chargingProfiles) + ) { chargingStation .getConnectorStatus(connectorId) - .chargingProfiles?.forEach((chargingProfile: OCPP16ChargingProfile, index: number) => { + ?.chargingProfiles?.forEach((chargingProfile: OCPP16ChargingProfile, index: number) => { let clearCurrentCP = false; if (chargingProfile.chargingProfileId === commandPayload.id) { clearCurrentCP = true; @@ -612,12 +618,10 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer clearCurrentCP = true; } if (clearCurrentCP) { - connectorStatus.chargingProfiles.splice(index, 1); + 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; } @@ -697,15 +701,9 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ): Promise { const transactionConnectorId = commandPayload.connectorId; if (chargingStation.connectors.has(transactionConnectorId) === true) { - const remoteStartTransactionLogMsg = - chargingStation.logPrefix() + - ' Transaction remotely STARTED on ' + - chargingStation.stationInfo.chargingStationId + - '#' + - transactionConnectorId.toString() + - " for idTag '" + - commandPayload.idTag + - "'"; + const remoteStartTransactionLogMsg = `${chargingStation.logPrefix()} Transaction remotely STARTED on ${ + chargingStation.stationInfo.chargingStationId + }#${transactionConnectorId.toString()} for idTag '${commandPayload.idTag}'`; await chargingStation.ocppRequestService.requestHandler< OCPP16StatusNotificationRequest, OCPP16StatusNotificationResponse @@ -723,11 +721,13 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer if ( chargingStation.getLocalAuthListEnabled() === true && chargingStation.hasAuthorizedTags() === true && - chargingStation.authorizedTagsCache - .getAuthorizedTags( - ChargingStationUtils.getAuthorizationFile(chargingStation.stationInfo) - ) - .find((idTag) => idTag === commandPayload.idTag) + !Utils.isEmptyString( + chargingStation.authorizedTagsCache + .getAuthorizedTags( + ChargingStationUtils.getAuthorizationFile(chargingStation.stationInfo) + ) + ?.find((idTag) => idTag === commandPayload.idTag) + ) ) { connectorStatus.localAuthorizeIdTag = commandPayload.idTag; connectorStatus.idTagLocalAuthorized = true; @@ -845,7 +845,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer idTag: string ): Promise { if ( - chargingStation.getConnectorStatus(connectorId).status !== OCPP16ChargePointStatus.AVAILABLE + chargingStation.getConnectorStatus(connectorId)?.status !== OCPP16ChargePointStatus.AVAILABLE ) { await chargingStation.ocppRequestService.requestHandler< OCPP16StatusNotificationRequest, @@ -858,16 +858,9 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer chargingStation.getConnectorStatus(connectorId).status = OCPP16ChargePointStatus.AVAILABLE; } logger.warn( - chargingStation.logPrefix() + - ' Remote starting transaction REJECTED on connector Id ' + - connectorId.toString() + - ", idTag '" + - idTag + - "', availability '" + - chargingStation.getConnectorStatus(connectorId).availability + - "', status '" + - chargingStation.getConnectorStatus(connectorId).status + - "'" + `${chargingStation.logPrefix()} Remote starting transaction REJECTED on connector Id ${connectorId.toString()}, idTag '${idTag}', availability '${ + chargingStation.getConnectorStatus(connectorId)?.availability + }', status '${chargingStation.getConnectorStatus(connectorId)?.status}'` ); return OCPPConstants.OCPP_RESPONSE_REJECTED; } @@ -880,8 +873,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) { @@ -926,9 +919,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer } } logger.warn( - chargingStation.logPrefix() + - ' Trying to remote stop a non existing transaction ' + - transactionId.toString() + `${chargingStation.logPrefix()} Trying to remote stop a non existing transaction ${transactionId.toString()}` ); return OCPPConstants.OCPP_RESPONSE_REJECTED; } @@ -959,7 +950,8 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer return OCPPConstants.OCPP_RESPONSE_EMPTY; } const retrieveDate = Utils.convertToDate(commandPayload.retrieveDate); - if (retrieveDate.getTime() <= Date.now()) { + const now = Date.now(); + if (retrieveDate?.getTime() <= now) { this.asyncResource .runInAsyncScope( this.updateFirmware.bind(this) as ( @@ -977,7 +969,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer this.updateFirmware(chargingStation).catch(() => { /* Intentional */ }); - }, retrieveDate.getTime() - Date.now()); + }, retrieveDate?.getTime() - now); } return OCPPConstants.OCPP_RESPONSE_EMPTY; } @@ -991,7 +983,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer for (const connectorId of chargingStation.connectors.keys()) { if ( connectorId > 0 && - chargingStation.getConnectorStatus(connectorId).transactionStarted === false + chargingStation.getConnectorStatus(connectorId)?.transactionStarted === false ) { await chargingStation.ocppRequestService.requestHandler< OCPP16StatusNotificationRequest, @@ -1070,7 +1062,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer .readdirSync(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../')) .filter((file) => file.endsWith('.log')) .map((file) => path.join('./', file)); - const diagnosticsArchive = chargingStation.stationInfo.chargingStationId + '_logs.tar.gz'; + const diagnosticsArchive = `${chargingStation.stationInfo.chargingStationId}_logs.tar.gz`; tar.create({ gzip: true }, logFiles).pipe(fs.createWriteStream(diagnosticsArchive)); ftpClient = new Client(); const accessResponse = await ftpClient.access({ @@ -1108,7 +1100,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../../../'), diagnosticsArchive ), - uri.pathname + diagnosticsArchive + `${uri.pathname}${diagnosticsArchive}` ); if (uploadResponse.code === 226) { await chargingStation.ocppRequestService.requestHandler< @@ -1125,7 +1117,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer throw new OCPPError( ErrorType.GENERIC_ERROR, `Diagnostics transfer failed with error code ${accessResponse.code.toString()}${ - uploadResponse?.code && '|' + uploadResponse?.code.toString() + uploadResponse?.code && `|${uploadResponse?.code.toString()}` }`, OCPP16IncomingRequestCommand.GET_DIAGNOSTICS ); @@ -1133,7 +1125,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer throw new OCPPError( ErrorType.GENERIC_ERROR, `Diagnostics transfer failed with error code ${accessResponse.code.toString()}${ - uploadResponse?.code && '|' + uploadResponse?.code.toString() + uploadResponse?.code && `|${uploadResponse?.code.toString()}` }`, OCPP16IncomingRequestCommand.GET_DIAGNOSTICS ); @@ -1233,7 +1225,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer return OCPPConstants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED; case OCPP16MessageTrigger.StatusNotification: setTimeout(() => { - if (commandPayload?.connectorId) { + if (!Utils.isNullOrUndefined(commandPayload?.connectorId)) { chargingStation.ocppRequestService .requestHandler( chargingStation, @@ -1241,7 +1233,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer { connectorId: commandPayload.connectorId, errorCode: OCPP16ChargePointErrorCode.NO_ERROR, - status: chargingStation.getConnectorStatus(commandPayload.connectorId).status, + status: chargingStation.getConnectorStatus(commandPayload.connectorId)?.status, }, { triggerMessage: true, @@ -1262,7 +1254,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer { connectorId, errorCode: OCPP16ChargePointErrorCode.NO_ERROR, - status: chargingStation.getConnectorStatus(connectorId).status, + status: chargingStation.getConnectorStatus(connectorId)?.status, }, { triggerMessage: true, @@ -1310,13 +1302,4 @@ 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; - } }