+ logger.error(
+ `${chargingStation.logPrefix()} Unsupported protocol ${
+ uri.protocol
+ } to transfer the diagnostic logs archive`,
+ );
+ await chargingStation.ocppRequestService.requestHandler<
+ OCPP16DiagnosticsStatusNotificationRequest,
+ OCPP16DiagnosticsStatusNotificationResponse
+ >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, {
+ status: OCPP16DiagnosticsStatus.UploadFailed,
+ });
+ return OCPP16Constants.OCPP_RESPONSE_EMPTY;
+ }
+ }
+
+ private handleRequestTriggerMessage(
+ chargingStation: ChargingStation,
+ commandPayload: OCPP16TriggerMessageRequest,
+ ): OCPP16TriggerMessageResponse {
+ const { requestedMessage, connectorId } = commandPayload;
+ if (
+ !OCPP16ServiceUtils.checkFeatureProfile(
+ chargingStation,
+ OCPP16SupportedFeatureProfiles.RemoteTrigger,
+ OCPP16IncomingRequestCommand.TRIGGER_MESSAGE,
+ ) ||
+ !OCPP16ServiceUtils.isMessageTriggerSupported(chargingStation, requestedMessage)
+ ) {
+ return OCPP16Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_NOT_IMPLEMENTED;
+ }
+ if (
+ !OCPP16ServiceUtils.isConnectorIdValid(
+ chargingStation,
+ OCPP16IncomingRequestCommand.TRIGGER_MESSAGE,
+ connectorId!,
+ )
+ ) {
+ return OCPP16Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_REJECTED;
+ }
+ try {
+ switch (requestedMessage) {
+ case OCPP16MessageTrigger.BootNotification:
+ setTimeout(() => {
+ chargingStation.ocppRequestService
+ .requestHandler<OCPP16BootNotificationRequest, OCPP16BootNotificationResponse>(
+ chargingStation,
+ OCPP16RequestCommand.BOOT_NOTIFICATION,
+ chargingStation.bootNotificationRequest,
+ { skipBufferingOnError: true, triggerMessage: true },
+ )
+ .then((response) => {
+ chargingStation.bootNotificationResponse = response;
+ })
+ .catch(Constants.EMPTY_FUNCTION);
+ }, OCPP16Constants.OCPP_TRIGGER_MESSAGE_DELAY);
+ return OCPP16Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED;
+ case OCPP16MessageTrigger.Heartbeat:
+ setTimeout(() => {
+ chargingStation.ocppRequestService
+ .requestHandler<OCPP16HeartbeatRequest, OCPP16HeartbeatResponse>(
+ chargingStation,
+ OCPP16RequestCommand.HEARTBEAT,
+ undefined,
+ {
+ triggerMessage: true,
+ },
+ )
+ .catch(Constants.EMPTY_FUNCTION);
+ }, OCPP16Constants.OCPP_TRIGGER_MESSAGE_DELAY);
+ return OCPP16Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED;
+ case OCPP16MessageTrigger.StatusNotification:
+ setTimeout(() => {
+ if (!isNullOrUndefined(connectorId)) {
+ chargingStation.ocppRequestService
+ .requestHandler<OCPP16StatusNotificationRequest, OCPP16StatusNotificationResponse>(
+ chargingStation,
+ OCPP16RequestCommand.STATUS_NOTIFICATION,
+ {
+ connectorId,
+ errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
+ status: chargingStation.getConnectorStatus(connectorId!)?.status,
+ },
+ {
+ triggerMessage: true,
+ },
+ )
+ .catch(Constants.EMPTY_FUNCTION);
+ } else {
+ // eslint-disable-next-line no-lonely-if
+ if (chargingStation.hasEvses) {
+ for (const evseStatus of chargingStation.evses.values()) {
+ for (const [id, connectorStatus] of evseStatus.connectors) {
+ chargingStation.ocppRequestService
+ .requestHandler<
+ OCPP16StatusNotificationRequest,
+ OCPP16StatusNotificationResponse
+ >(
+ chargingStation,
+ OCPP16RequestCommand.STATUS_NOTIFICATION,
+ {
+ connectorId: id,
+ errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
+ status: connectorStatus.status,
+ },
+ {
+ triggerMessage: true,
+ },
+ )
+ .catch(Constants.EMPTY_FUNCTION);
+ }
+ }
+ } else {
+ for (const id of chargingStation.connectors.keys()) {
+ chargingStation.ocppRequestService
+ .requestHandler<
+ OCPP16StatusNotificationRequest,
+ OCPP16StatusNotificationResponse
+ >(
+ chargingStation,
+ OCPP16RequestCommand.STATUS_NOTIFICATION,
+ {
+ connectorId: id,
+ errorCode: OCPP16ChargePointErrorCode.NO_ERROR,
+ status: chargingStation.getConnectorStatus(id)?.status,
+ },
+ {
+ triggerMessage: true,
+ },
+ )
+ .catch(Constants.EMPTY_FUNCTION);
+ }
+ }
+ }
+ }, OCPP16Constants.OCPP_TRIGGER_MESSAGE_DELAY);
+ return OCPP16Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED;
+ default:
+ return OCPP16Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_NOT_IMPLEMENTED;
+ }
+ } catch (error) {
+ return this.handleIncomingRequestError<OCPP16TriggerMessageResponse>(
+ chargingStation,
+ OCPP16IncomingRequestCommand.TRIGGER_MESSAGE,
+ error as Error,
+ { errorResponse: OCPP16Constants.OCPP_TRIGGER_MESSAGE_RESPONSE_REJECTED },
+ )!;
+ }
+ }
+
+ private handleRequestDataTransfer(
+ chargingStation: ChargingStation,
+ commandPayload: OCPP16DataTransferRequest,
+ ): OCPP16DataTransferResponse {
+ const { vendorId } = commandPayload;
+ try {
+ if (Object.values(OCPP16DataTransferVendorId).includes(vendorId)) {
+ return OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_ACCEPTED;
+ }
+ return OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_UNKNOWN_VENDOR_ID;
+ } catch (error) {
+ return this.handleIncomingRequestError<OCPP16DataTransferResponse>(
+ chargingStation,
+ OCPP16IncomingRequestCommand.DATA_TRANSFER,
+ error as Error,
+ { errorResponse: OCPP16Constants.OCPP_DATA_TRANSFER_RESPONSE_REJECTED },
+ )!;
+ }
+ }
+
+ private async handleRequestReserveNow(
+ chargingStation: ChargingStation,
+ commandPayload: OCPP16ReserveNowRequest,
+ ): Promise<OCPP16ReserveNowResponse> {
+ if (
+ !OCPP16ServiceUtils.checkFeatureProfile(
+ chargingStation,
+ OCPP16SupportedFeatureProfiles.Reservation,
+ OCPP16IncomingRequestCommand.RESERVE_NOW,
+ )
+ ) {
+ return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED;
+ }
+ const { reservationId, idTag, connectorId } = commandPayload;
+ let response: OCPP16ReserveNowResponse;
+ try {
+ if (connectorId > 0 && !chargingStation.isConnectorAvailable(connectorId)) {
+ return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED;
+ }
+ if (connectorId === 0 && !chargingStation.getReserveConnectorZeroSupported()) {
+ return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED;
+ }
+ if (!(await OCPP16ServiceUtils.isIdTagAuthorized(chargingStation, connectorId, idTag))) {
+ return OCPP16Constants.OCPP_RESERVATION_RESPONSE_REJECTED;
+ }
+ await removeExpiredReservations(chargingStation);
+ switch (chargingStation.getConnectorStatus(connectorId)!.status) {
+ case OCPP16ChargePointStatus.Faulted:
+ response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_FAULTED;
+ break;
+ case OCPP16ChargePointStatus.Preparing:
+ case OCPP16ChargePointStatus.Charging:
+ case OCPP16ChargePointStatus.SuspendedEV:
+ case OCPP16ChargePointStatus.SuspendedEVSE:
+ case OCPP16ChargePointStatus.Finishing:
+ response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_OCCUPIED;
+ break;
+ case OCPP16ChargePointStatus.Unavailable:
+ response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_UNAVAILABLE;
+ break;
+ case OCPP16ChargePointStatus.Reserved:
+ if (!chargingStation.isConnectorReservable(reservationId, idTag, connectorId)) {
+ response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_OCCUPIED;
+ break;
+ }
+ // eslint-disable-next-line no-fallthrough
+ default:
+ if (!chargingStation.isConnectorReservable(reservationId, idTag)) {
+ response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_OCCUPIED;
+ break;
+ }
+ await chargingStation.addReservation({
+ id: commandPayload.reservationId,
+ ...commandPayload,
+ });
+ response = OCPP16Constants.OCPP_RESERVATION_RESPONSE_ACCEPTED;
+ break;
+ }
+ return response;
+ } catch (error) {
+ chargingStation.getConnectorStatus(connectorId)!.status = OCPP16ChargePointStatus.Available;
+ return this.handleIncomingRequestError<OCPP16ReserveNowResponse>(
+ chargingStation,
+ OCPP16IncomingRequestCommand.RESERVE_NOW,
+ error as Error,
+ { errorResponse: OCPP16Constants.OCPP_RESERVATION_RESPONSE_FAULTED },
+ )!;
+ }
+ }
+
+ private async handleRequestCancelReservation(
+ chargingStation: ChargingStation,
+ commandPayload: OCPP16CancelReservationRequest,
+ ): Promise<GenericResponse> {
+ if (
+ !OCPP16ServiceUtils.checkFeatureProfile(
+ chargingStation,
+ OCPP16SupportedFeatureProfiles.Reservation,
+ OCPP16IncomingRequestCommand.CANCEL_RESERVATION,
+ )
+ ) {
+ return OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED;
+ }
+ try {
+ const { reservationId } = commandPayload;
+ const reservation = chargingStation.getReservationBy('reservationId', reservationId);
+ if (isUndefined(reservation)) {
+ logger.debug(
+ `${chargingStation.logPrefix()} Reservation with id ${reservationId} does not exist on charging station`,
+ );
+ return OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED;
+ }
+ await chargingStation.removeReservation(
+ reservation!,
+ ReservationTerminationReason.RESERVATION_CANCELED,
+ );
+ return OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_ACCEPTED;
+ } catch (error) {
+ return this.handleIncomingRequestError<GenericResponse>(
+ chargingStation,
+ OCPP16IncomingRequestCommand.CANCEL_RESERVATION,
+ error as Error,
+ { errorResponse: OCPP16Constants.OCPP_CANCEL_RESERVATION_RESPONSE_REJECTED },
+ )!;