+ return OCPP16Constants.OCPP_RESPONSE_REJECTED;
+ }
+
+ private handleRequestUpdateFirmware(
+ chargingStation: ChargingStation,
+ commandPayload: OCPP16UpdateFirmwareRequest
+ ): OCPP16UpdateFirmwareResponse {
+ if (
+ OCPP16ServiceUtils.checkFeatureProfile(
+ chargingStation,
+ OCPP16SupportedFeatureProfiles.FirmwareManagement,
+ OCPP16IncomingRequestCommand.UPDATE_FIRMWARE
+ ) === false
+ ) {
+ logger.warn(
+ `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: feature profile not supported`
+ );
+ return OCPP16Constants.OCPP_RESPONSE_EMPTY;
+ }
+ 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 OCPP16Constants.OCPP_RESPONSE_EMPTY;
+ }
+ const retrieveDate = Utils.convertToDate(commandPayload.retrieveDate);
+ const now = Date.now();
+ if (retrieveDate?.getTime() <= now) {
+ this.runInAsyncScope(
+ this.updateFirmwareSimulation.bind(this) as (
+ this: OCPP16IncomingRequestService,
+ ...args: any[]
+ ) => Promise<void>,
+ this,
+ 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 (
+ ChargingStationUtils.checkChargingStation(chargingStation, chargingStation.logPrefix()) ===
+ false
+ ) {
+ 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,
+ });
+ chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Downloading;
+ if (
+ chargingStation.stationInfo?.firmwareUpgrade?.failureStatus ===
+ OCPP16FirmwareStatus.DownloadFailed
+ ) {
+ await Utils.sleep(Utils.getRandomInteger(maxDelay, minDelay) * 1000);
+ 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 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;
+ let wasTransactionsStarted = false;
+ let transactionsStarted: boolean;
+ do {
+ const runningTransactions = chargingStation.getNumberOfRunningTransactions();
+ if (runningTransactions > 0) {
+ const waitTime = 15 * 1000;
+ logger.debug(
+ `${chargingStation.logPrefix()} ${moduleName}.updateFirmwareSimulation: ${runningTransactions} transaction(s) in progress, waiting ${
+ waitTime / 1000
+ } seconds before continuing firmware update simulation`
+ );
+ await Utils.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 Utils.sleep(Utils.getRandomInteger(maxDelay, minDelay) * 1000));
+ if (
+ ChargingStationUtils.checkChargingStation(chargingStation, chargingStation.logPrefix()) ===
+ false
+ ) {
+ return;
+ }
+ await chargingStation.ocppRequestService.requestHandler<
+ OCPP16FirmwareStatusNotificationRequest,
+ OCPP16FirmwareStatusNotificationResponse
+ >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, {
+ status: OCPP16FirmwareStatus.Installing,
+ });
+ chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Installing;
+ if (
+ chargingStation.stationInfo?.firmwareUpgrade?.failureStatus ===
+ OCPP16FirmwareStatus.InstallationFailed
+ ) {
+ await Utils.sleep(Utils.getRandomInteger(maxDelay, minDelay) * 1000);
+ 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 Utils.sleep(Utils.getRandomInteger(maxDelay, minDelay) * 1000);
+ await chargingStation.reset(OCPP16StopTransactionReason.REBOOT);
+ }