+ private handleRequestUpdateFirmware (
+ chargingStation: ChargingStation,
+ commandPayload: OCPP16UpdateFirmwareRequest
+ ): OCPP16UpdateFirmwareResponse {
+ if (
+ !OCPP16ServiceUtils.checkFeatureProfile(
+ chargingStation,
+ OCPP16SupportedFeatureProfiles.FirmwareManagement,
+ OCPP16IncomingRequestCommand.UPDATE_FIRMWARE
+ )
+ ) {
+ logger.warn(
+ `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: feature profile not supported`
+ )
+ return OCPP16Constants.OCPP_RESPONSE_EMPTY
+ }
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ commandPayload.retrieveDate = convertToDate(commandPayload.retrieveDate)!
+ const { retrieveDate } = commandPayload
+ if (chargingStation.stationInfo?.firmwareStatus !== OCPP16FirmwareStatus.Installed) {
+ logger.warn(
+ `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: firmware update is already in progress`
+ )
+ return OCPP16Constants.OCPP_RESPONSE_EMPTY
+ }
+ const now = Date.now()
+ if (retrieveDate.getTime() <= now) {
+ this.updateFirmwareSimulation(chargingStation).catch(Constants.EMPTY_FUNCTION)
+ } else {
+ setTimeout(() => {
+ this.updateFirmwareSimulation(chargingStation).catch(Constants.EMPTY_FUNCTION)
+ }, retrieveDate.getTime() - now)
+ }
+ return OCPP16Constants.OCPP_RESPONSE_EMPTY
+ }
+
+ private async updateFirmwareSimulation (
+ chargingStation: ChargingStation,
+ maxDelay = 30,
+ minDelay = 15
+ ): Promise<void> {
+ if (!checkChargingStation(chargingStation, chargingStation.logPrefix())) {
+ return
+ }
+ if (chargingStation.hasEvses) {
+ for (const [evseId, evseStatus] of chargingStation.evses) {
+ if (evseId > 0) {
+ for (const [connectorId, connectorStatus] of evseStatus.connectors) {
+ if (connectorStatus.transactionStarted === false) {
+ await OCPP16ServiceUtils.sendAndSetConnectorStatus(
+ chargingStation,
+ connectorId,
+ OCPP16ChargePointStatus.Unavailable
+ )
+ }
+ }
+ }
+ }
+ } else {
+ for (const connectorId of chargingStation.connectors.keys()) {
+ if (
+ connectorId > 0 &&
+ chargingStation.getConnectorStatus(connectorId)?.transactionStarted === false
+ ) {
+ await OCPP16ServiceUtils.sendAndSetConnectorStatus(
+ chargingStation,
+ connectorId,
+ OCPP16ChargePointStatus.Unavailable
+ )
+ }
+ }
+ }
+ await chargingStation.ocppRequestService.requestHandler<
+ OCPP16FirmwareStatusNotificationRequest,
+ OCPP16FirmwareStatusNotificationResponse
+ >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
+ status: OCPP16FirmwareStatus.Downloading
+ })
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.stationInfo!.firmwareStatus = OCPP16FirmwareStatus.Downloading
+ if (
+ chargingStation.stationInfo?.firmwareUpgrade?.failureStatus ===
+ OCPP16FirmwareStatus.DownloadFailed
+ ) {
+ await sleep(secondsToMilliseconds(getRandomInteger(maxDelay, minDelay)))
+ await chargingStation.ocppRequestService.requestHandler<
+ OCPP16FirmwareStatusNotificationRequest,
+ OCPP16FirmwareStatusNotificationResponse
+ >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
+ status: chargingStation.stationInfo.firmwareUpgrade.failureStatus
+ })
+ chargingStation.stationInfo.firmwareStatus =
+ chargingStation.stationInfo.firmwareUpgrade.failureStatus
+ return
+ }
+ await sleep(secondsToMilliseconds(getRandomInteger(maxDelay, minDelay)))
+ await chargingStation.ocppRequestService.requestHandler<
+ OCPP16FirmwareStatusNotificationRequest,
+ OCPP16FirmwareStatusNotificationResponse
+ >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
+ status: OCPP16FirmwareStatus.Downloaded
+ })
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.stationInfo!.firmwareStatus = OCPP16FirmwareStatus.Downloaded
+ let wasTransactionsStarted = false
+ let transactionsStarted: boolean
+ do {
+ const runningTransactions = chargingStation.getNumberOfRunningTransactions()
+ if (runningTransactions > 0) {
+ const waitTime = secondsToMilliseconds(15)
+ logger.debug(
+ `${chargingStation.logPrefix()} ${moduleName}.updateFirmwareSimulation: ${runningTransactions} transaction(s) in progress, waiting ${formatDurationMilliSeconds(
+ waitTime
+ )} before continuing firmware update simulation`
+ )
+ await sleep(waitTime)
+ transactionsStarted = true
+ wasTransactionsStarted = true
+ } else {
+ if (chargingStation.hasEvses) {
+ for (const [evseId, evseStatus] of chargingStation.evses) {
+ if (evseId > 0) {
+ for (const [connectorId, connectorStatus] of evseStatus.connectors) {
+ if (connectorStatus.status !== OCPP16ChargePointStatus.Unavailable) {
+ await OCPP16ServiceUtils.sendAndSetConnectorStatus(
+ chargingStation,
+ connectorId,
+ OCPP16ChargePointStatus.Unavailable
+ )
+ }
+ }
+ }
+ }
+ } else {
+ for (const connectorId of chargingStation.connectors.keys()) {
+ if (
+ connectorId > 0 &&
+ chargingStation.getConnectorStatus(connectorId)?.status !==
+ OCPP16ChargePointStatus.Unavailable
+ ) {
+ await OCPP16ServiceUtils.sendAndSetConnectorStatus(
+ chargingStation,
+ connectorId,
+ OCPP16ChargePointStatus.Unavailable
+ )
+ }
+ }
+ }
+ transactionsStarted = false
+ }
+ } while (transactionsStarted)
+ !wasTransactionsStarted &&
+ (await sleep(secondsToMilliseconds(getRandomInteger(maxDelay, minDelay))))
+ if (!checkChargingStation(chargingStation, chargingStation.logPrefix())) {
+ return
+ }
+ await chargingStation.ocppRequestService.requestHandler<
+ OCPP16FirmwareStatusNotificationRequest,
+ OCPP16FirmwareStatusNotificationResponse
+ >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
+ status: OCPP16FirmwareStatus.Installing
+ })
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ chargingStation.stationInfo!.firmwareStatus = OCPP16FirmwareStatus.Installing
+ if (
+ chargingStation.stationInfo?.firmwareUpgrade?.failureStatus ===
+ OCPP16FirmwareStatus.InstallationFailed
+ ) {
+ await sleep(secondsToMilliseconds(getRandomInteger(maxDelay, minDelay)))
+ await chargingStation.ocppRequestService.requestHandler<
+ OCPP16FirmwareStatusNotificationRequest,
+ OCPP16FirmwareStatusNotificationResponse
+ >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
+ status: chargingStation.stationInfo.firmwareUpgrade.failureStatus
+ })
+ chargingStation.stationInfo.firmwareStatus =
+ chargingStation.stationInfo.firmwareUpgrade.failureStatus
+ return
+ }
+ if (chargingStation.stationInfo?.firmwareUpgrade?.reset === true) {
+ await sleep(secondsToMilliseconds(getRandomInteger(maxDelay, minDelay)))
+ await chargingStation.reset(OCPP16StopTransactionReason.REBOOT)
+ }
+ }
+
+ private async handleRequestGetDiagnostics (
+ chargingStation: ChargingStation,