From c9a4f9ea603df09541c6837fee50012256fb46ad Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Mon, 9 Jan 2023 00:09:05 +0100 Subject: [PATCH] Add initial support for OCPP 1.6 firmware update simulation MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reference #169 and #36 Signed-off-by: Jérôme Benoit --- README.md | 4 +- src/charging-station/ChargingStation.ts | 13 +++ .../ChargingStationWorkerBroadcastChannel.ts | 30 ++++- .../ocpp/1.6/OCPP16IncomingRequestService.ts | 109 ++++++++++++++---- .../ocpp/1.6/OCPP16RequestService.ts | 23 +++- .../ocpp/1.6/OCPP16ResponseService.ts | 18 ++- .../ui-services/AbstractUIService.ts | 4 + src/types/ChargingStationInfo.ts | 2 + src/types/UIProtocol.ts | 2 + src/types/WorkerBroadcastChannel.ts | 2 + src/types/ocpp/1.6/Requests.ts | 4 +- src/types/ocpp/1.6/Responses.ts | 4 +- src/types/ocpp/Requests.ts | 6 + src/types/ocpp/Responses.ts | 6 + test/robohydra/messages.txt | 2 + 15 files changed, 192 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 131a263c..f1509c61 100644 --- a/README.md +++ b/README.md @@ -328,8 +328,8 @@ make SUBMODULES_INIT=true - :white_check_mark: GetDiagnostics - :white_check_mark: DiagnosticsStatusNotification -- :x: FirmwareStatusNotification -- :x: UpdateFirmware +- :white_check_mark: FirmwareStatusNotification +- :white_check_mark: UpdateFirmware #### Local Auth List Management Profile diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 587ca02f..806bcd75 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -43,6 +43,8 @@ import { type BootNotificationRequest, type CachedRequest, type ErrorCallback, + FirmwareStatus, + type FirmwareStatusNotificationRequest, type HeartbeatRequest, type IncomingRequest, IncomingRequestCommand, @@ -54,6 +56,7 @@ import { import { type BootNotificationResponse, type ErrorResponse, + type FirmwareStatusNotificationResponse, type HeartbeatResponse, type MeterValuesResponse, RegistrationStatusEnumType, @@ -1837,6 +1840,16 @@ export default class ChargingStation { }); this.getConnectorStatus(connectorId).status = chargePointStatus; } + if (this.stationInfo?.firmwareStatus === FirmwareStatus.Installing) { + await this.ocppRequestService.requestHandler< + FirmwareStatusNotificationRequest, + FirmwareStatusNotificationResponse + >(this, RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { + status: FirmwareStatus.Installed, + }); + this.stationInfo.firmwareStatus = FirmwareStatus.Installed; + // TODO: bump firmware version + } // Start the ATG if (this.getAutomaticTransactionGeneratorConfigurationFromTemplate()?.enable === true) { this.startAutomaticTransactionGenerator(); diff --git a/src/charging-station/ChargingStationWorkerBroadcastChannel.ts b/src/charging-station/ChargingStationWorkerBroadcastChannel.ts index 7c9883bd..1528d65c 100644 --- a/src/charging-station/ChargingStationWorkerBroadcastChannel.ts +++ b/src/charging-station/ChargingStationWorkerBroadcastChannel.ts @@ -4,6 +4,8 @@ import { StandardParametersKey } from '../types/ocpp/Configuration'; import { type BootNotificationRequest, type DataTransferRequest, + type DiagnosticsStatusNotificationRequest, + type FirmwareStatusNotificationRequest, type HeartbeatRequest, type MeterValuesRequest, RequestCommand, @@ -13,6 +15,8 @@ import { type BootNotificationResponse, type DataTransferResponse, DataTransferStatus, + type DiagnosticsStatusNotificationResponse, + type FirmwareStatusNotificationResponse, type HeartbeatResponse, type MeterValuesResponse, RegistrationStatusEnumType, @@ -53,7 +57,9 @@ type CommandResponse = | StatusNotificationResponse | HeartbeatResponse | MeterValuesResponse - | DataTransferResponse; + | DataTransferResponse + | DiagnosticsStatusNotificationResponse + | FirmwareStatusNotificationResponse; type CommandHandler = ( requestPayload?: BroadcastChannelRequestPayload @@ -190,6 +196,22 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca DataTransferResponse >(this.chargingStation, RequestCommand.DATA_TRANSFER, requestPayload), ], + [ + BroadcastChannelProcedureName.DIAGNOSTICS_STATUS_NOTIFICATION, + async (requestPayload?: BroadcastChannelRequestPayload) => + this.chargingStation.ocppRequestService.requestHandler< + DiagnosticsStatusNotificationRequest, + DiagnosticsStatusNotificationResponse + >(this.chargingStation, RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, requestPayload), + ], + [ + BroadcastChannelProcedureName.FIRMWARE_STATUS_NOTIFICATION, + async (requestPayload?: BroadcastChannelRequestPayload) => + this.chargingStation.ocppRequestService.requestHandler< + FirmwareStatusNotificationRequest, + FirmwareStatusNotificationResponse + >(this.chargingStation, RequestCommand.FIRMWARE_STATUS_NOTIFICATION, requestPayload), + ], ]); this.chargingStation = chargingStation; this.onmessage = this.requestHandler.bind(this) as (message: MessageEvent) => void; @@ -221,7 +243,11 @@ export default class ChargingStationWorkerBroadcastChannel extends WorkerBroadca let commandResponse: CommandResponse | void; try { commandResponse = await this.commandHandler(command, requestPayload); - if (commandResponse === undefined || commandResponse === null) { + if ( + commandResponse === undefined || + commandResponse === null || + Utils.isEmptyObject(commandResponse as CommandResponse) + ) { responsePayload = { hashId: this.chargingStation.stationInfo.hashId, status: ResponseStatus.SUCCESS, diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index 8b19902e..a170e305 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -25,7 +25,6 @@ import { type ChangeAvailabilityRequest, type ChangeConfigurationRequest, type ClearChargingProfileRequest, - type DiagnosticsStatusNotificationRequest, type GetConfigurationRequest, type GetDiagnosticsRequest, OCPP16AvailabilityType, @@ -33,6 +32,9 @@ import { type OCPP16ClearCacheRequest, type OCPP16DataTransferRequest, OCPP16DataTransferVendorId, + type OCPP16DiagnosticsStatusNotificationRequest, + OCPP16FirmwareStatus, + type OCPP16FirmwareStatusNotificationRequest, type OCPP16HeartbeatRequest, OCPP16IncomingRequestCommand, OCPP16MessageTrigger, @@ -50,12 +52,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, @@ -132,7 +135,7 @@ 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>([ [ @@ -1036,13 +1039,76 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ) { return OCPPConstants.OCPP_RESPONSE_EMPTY; } - logger.debug( - chargingStation.logPrefix() + - ' ' + - OCPP16IncomingRequestCommand.UPDATE_FIRMWARE + - ' request received: %j', - commandPayload - ); + 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, + minDelay = 15, + maxDelay = 30 + ): 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, + }); + } + } + await chargingStation.ocppRequestService.requestHandler< + OCPP16FirmwareStatusNotificationRequest, + OCPP16FirmwareStatusNotificationResponse + >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { + status: OCPP16FirmwareStatus.Downloading, + }); + chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Downloading; + await Utils.sleep(Utils.getRandomInteger(minDelay, maxDelay) * 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(minDelay, maxDelay) * 1000); + await chargingStation.ocppRequestService.requestHandler< + OCPP16FirmwareStatusNotificationRequest, + OCPP16FirmwareStatusNotificationResponse + >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { + status: OCPP16FirmwareStatus.Installing, + }); + chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Installing; + await Utils.sleep(Utils.getRandomInteger(minDelay, maxDelay) * 1000); + await chargingStation.reset(); } private async handleRequestGetDiagnostics( @@ -1058,13 +1124,6 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ) { 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; @@ -1092,8 +1151,8 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer } bytes transferred from diagnostics archive ${info.name}` ); await chargingStation.ocppRequestService.requestHandler< - DiagnosticsStatusNotificationRequest, - DiagnosticsStatusNotificationResponse + OCPP16DiagnosticsStatusNotificationRequest, + OCPP16DiagnosticsStatusNotificationResponse >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, { status: OCPP16DiagnosticsStatus.Uploading, }); @@ -1107,8 +1166,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 +1193,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 +1215,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, }); diff --git a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts index 955dd085..3c72faf2 100644 --- a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts @@ -10,12 +10,13 @@ import OCPPError from '../../../exception/OCPPError'; import type { JsonObject, JsonType } from '../../../types/JsonType'; import type { OCPP16MeterValuesRequest } from '../../../types/ocpp/1.6/MeterValues'; import { - type DiagnosticsStatusNotificationRequest, type OCPP16BootNotificationRequest, type OCPP16DataTransferRequest, + type OCPP16DiagnosticsStatusNotificationRequest, type OCPP16HeartbeatRequest, OCPP16RequestCommand, type OCPP16StatusNotificationRequest, + type OCPP16UpdateFirmwareRequest, } from '../../../types/ocpp/1.6/Requests'; import type { OCPP16AuthorizeRequest, @@ -77,7 +78,7 @@ export default class OCPP16RequestService extends OCPPRequestService { ), 'utf8' ) - ) as JSONSchemaType, + ) as JSONSchemaType, ], [ OCPP16RequestCommand.HEARTBEAT, @@ -151,6 +152,18 @@ export default class OCPP16RequestService extends OCPPRequestService { ) ) as JSONSchemaType, ], + [ + OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, + JSON.parse( + fs.readFileSync( + path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + '../../../assets/json-schemas/ocpp/1.6/FirmwareStatusNotification.json' + ), + 'utf8' + ) + ) as JSONSchemaType, + ], ]); this.buildRequestPayload.bind(this); } @@ -223,7 +236,7 @@ export default class OCPP16RequestService extends OCPPRequestService { } as unknown as Request; case OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION: return { - status: commandParams?.diagnosticsStatus, + status: commandParams?.status, } as unknown as Request; case OCPP16RequestCommand.HEARTBEAT: return {} as unknown as Request; @@ -281,6 +294,10 @@ export default class OCPP16RequestService extends OCPPRequestService { } as unknown as Request; case OCPP16RequestCommand.DATA_TRANSFER: return commandParams as unknown as Request; + case OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION: + return { + status: commandParams?.status, + } as unknown as Request; default: // OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError(). throw new OCPPError( diff --git a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts index e29957be..ac183aec 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts @@ -25,11 +25,12 @@ import type { ChangeAvailabilityResponse, ChangeConfigurationResponse, ClearChargingProfileResponse, - DiagnosticsStatusNotificationResponse, GetConfigurationResponse, GetDiagnosticsResponse, OCPP16BootNotificationResponse, OCPP16DataTransferResponse, + OCPP16DiagnosticsStatusNotificationResponse, + OCPP16FirmwareStatusNotificationResponse, OCPP16HeartbeatResponse, OCPP16StatusNotificationResponse, OCPP16TriggerMessageResponse, @@ -87,6 +88,7 @@ export default class OCPP16ResponseService extends OCPPResponseService { [OCPP16RequestCommand.METER_VALUES, this.emptyResponseHandler.bind(this)], [OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, this.emptyResponseHandler.bind(this)], [OCPP16RequestCommand.DATA_TRANSFER, this.emptyResponseHandler.bind(this)], + [OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, this.emptyResponseHandler.bind(this)], ]); this.jsonSchemas = new Map>([ [ @@ -183,7 +185,7 @@ export default class OCPP16ResponseService extends OCPPResponseService { ), 'utf8' ) - ) as JSONSchemaType, + ) as JSONSchemaType, ], [ OCPP16RequestCommand.DATA_TRANSFER, @@ -197,6 +199,18 @@ export default class OCPP16ResponseService extends OCPPResponseService { ) ) as JSONSchemaType, ], + [ + OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, + JSON.parse( + fs.readFileSync( + path.resolve( + path.dirname(fileURLToPath(import.meta.url)), + '../../../assets/json-schemas/ocpp/1.6/FirmwareStatusNotificationResponse.json' + ), + 'utf8' + ) + ) as JSONSchemaType, + ], ]); this.jsonIncomingRequestResponseSchemas = new Map([ [ diff --git a/src/charging-station/ui-server/ui-services/AbstractUIService.ts b/src/charging-station/ui-server/ui-services/AbstractUIService.ts index 1d270b38..5a418b9d 100644 --- a/src/charging-station/ui-server/ui-services/AbstractUIService.ts +++ b/src/charging-station/ui-server/ui-services/AbstractUIService.ts @@ -44,6 +44,10 @@ export default abstract class AbstractUIService { [ProcedureName.HEARTBEAT]: BroadcastChannelProcedureName.HEARTBEAT, [ProcedureName.METER_VALUES]: BroadcastChannelProcedureName.METER_VALUES, [ProcedureName.DATA_TRANSFER]: BroadcastChannelProcedureName.DATA_TRANSFER, + [ProcedureName.DIAGNOSTICS_STATUS_NOTIFICATION]: + BroadcastChannelProcedureName.DIAGNOSTICS_STATUS_NOTIFICATION, + [ProcedureName.FIRMWARE_STATUS_NOTIFICATION]: + BroadcastChannelProcedureName.FIRMWARE_STATUS_NOTIFICATION, }; protected readonly requestHandlers: Map; diff --git a/src/types/ChargingStationInfo.ts b/src/types/ChargingStationInfo.ts index 65098870..29ff6fb7 100644 --- a/src/types/ChargingStationInfo.ts +++ b/src/types/ChargingStationInfo.ts @@ -1,4 +1,5 @@ import type { ChargingStationTemplate } from './ChargingStationTemplate'; +import type { FirmwareStatus } from './ocpp/Requests'; export type ChargingStationInfo = Omit< ChargingStationTemplate, @@ -18,6 +19,7 @@ export type ChargingStationInfo = Omit< meterSerialNumber?: string; maximumPower?: number; // Always in Watt maximumAmperage?: number; // Always in Ampere + firmwareStatus?: FirmwareStatus; }; export type ChargingStationInfoConfiguration = { diff --git a/src/types/UIProtocol.ts b/src/types/UIProtocol.ts index 8c9379b4..3b6592a5 100644 --- a/src/types/UIProtocol.ts +++ b/src/types/UIProtocol.ts @@ -45,6 +45,8 @@ export enum ProcedureName { HEARTBEAT = 'heartbeat', METER_VALUES = 'meterValues', DATA_TRANSFER = 'dataTransfer', + DIAGNOSTICS_STATUS_NOTIFICATION = 'diagnosticsStatusNotification', + FIRMWARE_STATUS_NOTIFICATION = 'firmwareStatusNotification', } export interface RequestPayload extends JsonObject { diff --git a/src/types/WorkerBroadcastChannel.ts b/src/types/WorkerBroadcastChannel.ts index b7b8580d..2c174cd5 100644 --- a/src/types/WorkerBroadcastChannel.ts +++ b/src/types/WorkerBroadcastChannel.ts @@ -22,6 +22,8 @@ export enum BroadcastChannelProcedureName { HEARTBEAT = 'heartbeat', METER_VALUES = 'meterValues', DATA_TRANSFER = 'dataTransfer', + DIAGNOSTICS_STATUS_NOTIFICATION = 'diagnosticsStatusNotification', + FIRMWARE_STATUS_NOTIFICATION = 'firmwareStatusNotification', } export interface BroadcastChannelRequestPayload extends RequestPayload { diff --git a/src/types/ocpp/1.6/Requests.ts b/src/types/ocpp/1.6/Requests.ts index 678eacc9..47b110ab 100644 --- a/src/types/ocpp/1.6/Requests.ts +++ b/src/types/ocpp/1.6/Requests.ts @@ -135,7 +135,7 @@ export enum OCPP16FirmwareStatus { export type OCPP16FirmwareStatusNotificationRequest = { status: OCPP16FirmwareStatus; -}; +} & JsonObject; export interface GetDiagnosticsRequest extends JsonObject { location: string; @@ -145,7 +145,7 @@ export interface GetDiagnosticsRequest extends JsonObject { stopTime?: Date; } -export interface DiagnosticsStatusNotificationRequest extends JsonObject { +export interface OCPP16DiagnosticsStatusNotificationRequest extends JsonObject { status: OCPP16DiagnosticsStatus; } diff --git a/src/types/ocpp/1.6/Responses.ts b/src/types/ocpp/1.6/Responses.ts index 1ccd78e2..84648e47 100644 --- a/src/types/ocpp/1.6/Responses.ts +++ b/src/types/ocpp/1.6/Responses.ts @@ -72,11 +72,13 @@ export interface ClearChargingProfileResponse extends JsonObject { export type OCPP16UpdateFirmwareResponse = EmptyObject; +export type OCPP16FirmwareStatusNotificationResponse = EmptyObject; + export interface GetDiagnosticsResponse extends JsonObject { fileName?: string; } -export type DiagnosticsStatusNotificationResponse = EmptyObject; +export type OCPP16DiagnosticsStatusNotificationResponse = EmptyObject; export enum OCPP16TriggerMessageStatus { ACCEPTED = 'Accepted', diff --git a/src/types/ocpp/Requests.ts b/src/types/ocpp/Requests.ts index a2194996..884da269 100644 --- a/src/types/ocpp/Requests.ts +++ b/src/types/ocpp/Requests.ts @@ -7,7 +7,9 @@ import { OCPP16AvailabilityType, type OCPP16BootNotificationRequest, type OCPP16DataTransferRequest, + type OCPP16DiagnosticsStatusNotificationRequest, OCPP16FirmwareStatus, + type OCPP16FirmwareStatusNotificationRequest, type OCPP16HeartbeatRequest, OCPP16IncomingRequestCommand, OCPP16MessageTrigger, @@ -68,6 +70,10 @@ export type MeterValuesRequest = OCPP16MeterValuesRequest; export type DataTransferRequest = OCPP16DataTransferRequest; +export type DiagnosticsStatusNotificationRequest = OCPP16DiagnosticsStatusNotificationRequest; + +export type FirmwareStatusNotificationRequest = OCPP16FirmwareStatusNotificationRequest; + export type IncomingRequestHandler = ( chargingStation: ChargingStation, commandPayload: JsonType diff --git a/src/types/ocpp/Responses.ts b/src/types/ocpp/Responses.ts index 35424a78..c2b1f53a 100644 --- a/src/types/ocpp/Responses.ts +++ b/src/types/ocpp/Responses.ts @@ -9,6 +9,8 @@ import { OCPP16ConfigurationStatus, type OCPP16DataTransferResponse, OCPP16DataTransferStatus, + type OCPP16DiagnosticsStatusNotificationResponse, + type OCPP16FirmwareStatusNotificationResponse, type OCPP16HeartbeatResponse, type OCPP16StatusNotificationResponse, OCPP16TriggerMessageStatus, @@ -40,6 +42,10 @@ export type MeterValuesResponse = OCPP16MeterValuesResponse; export type DataTransferResponse = OCPP16DataTransferResponse; +export type DiagnosticsStatusNotificationResponse = OCPP16DiagnosticsStatusNotificationResponse; + +export type FirmwareStatusNotificationResponse = OCPP16FirmwareStatusNotificationResponse; + export enum DefaultStatus { ACCEPTED = 'Accepted', REJECTED = 'Rejected', diff --git a/test/robohydra/messages.txt b/test/robohydra/messages.txt index 47d15bb3..88e12182 100644 --- a/test/robohydra/messages.txt +++ b/test/robohydra/messages.txt @@ -3,3 +3,5 @@ GetDiagnostics: TriggerMessage: curl -d '[2,"123456789","TriggerMessage",{"requestedMessage":"BootNotification"}]' -H "Content-Type: application/json" -X POST http://localhost:3000/message curl -d '[2,"123456789","TriggerMessage",{"requestedMessage":"HeartBeat"}]' -H "Content-Type: application/json" -X POST http://localhost:3000/message +UpdateFirmware: + curl -d '[2,"123456789","UpdateFirmware",{"location":"ftp://localhost","retrieveDate":"2019-01-01T00:00:00.000Z"}]' -H "Content-Type: application/json" -X POST http://localhost:3000/message -- 2.34.1