1 // Partial Copyright Jerome Benoit. 2021-2023. All Rights Reserved.
3 import fs from
'node:fs';
4 import path from
'node:path';
5 import { URL
, fileURLToPath
} from
'node:url';
7 import type { JSONSchemaType
} from
'ajv';
8 import { Client
, type FTPResponse
} from
'basic-ftp';
13 ChargingStationConfigurationUtils
,
15 } from
'../../../charging-station';
16 import { OCPPError
} from
'../../../exception';
18 type ChangeAvailabilityRequest
,
19 type ChangeAvailabilityResponse
,
20 type ChangeConfigurationRequest
,
21 type ChangeConfigurationResponse
,
22 ChargingProfilePurposeType
,
23 type ClearChargingProfileRequest
,
24 type ClearChargingProfileResponse
,
27 type GetConfigurationRequest
,
28 type GetConfigurationResponse
,
29 type GetDiagnosticsRequest
,
30 type GetDiagnosticsResponse
,
31 type IncomingRequestHandler
,
34 OCPP16AuthorizationStatus
,
35 type OCPP16AuthorizeRequest
,
36 type OCPP16AuthorizeResponse
,
37 OCPP16AvailabilityType
,
38 type OCPP16BootNotificationRequest
,
39 type OCPP16BootNotificationResponse
,
40 OCPP16ChargePointErrorCode
,
41 OCPP16ChargePointStatus
,
42 type OCPP16ChargingProfile
,
43 type OCPP16ClearCacheRequest
,
44 type OCPP16DataTransferRequest
,
45 type OCPP16DataTransferResponse
,
46 OCPP16DataTransferStatus
,
47 OCPP16DataTransferVendorId
,
48 OCPP16DiagnosticsStatus
,
49 type OCPP16DiagnosticsStatusNotificationRequest
,
50 type OCPP16DiagnosticsStatusNotificationResponse
,
52 type OCPP16FirmwareStatusNotificationRequest
,
53 type OCPP16FirmwareStatusNotificationResponse
,
54 type OCPP16HeartbeatRequest
,
55 type OCPP16HeartbeatResponse
,
56 OCPP16IncomingRequestCommand
,
59 OCPP16StandardParametersKey
,
60 type OCPP16StartTransactionRequest
,
61 type OCPP16StartTransactionResponse
,
62 type OCPP16StatusNotificationRequest
,
63 type OCPP16StatusNotificationResponse
,
64 OCPP16StopTransactionReason
,
65 OCPP16SupportedFeatureProfiles
,
66 type OCPP16TriggerMessageRequest
,
67 type OCPP16TriggerMessageResponse
,
68 type OCPP16UpdateFirmwareRequest
,
69 type OCPP16UpdateFirmwareResponse
,
70 type OCPPConfigurationKey
,
72 type RemoteStartTransactionRequest
,
73 type RemoteStopTransactionRequest
,
75 type SetChargingProfileRequest
,
76 type SetChargingProfileResponse
,
77 type UnlockConnectorRequest
,
78 type UnlockConnectorResponse
,
79 } from
'../../../types';
80 import { Constants
} from
'../../../utils/Constants';
81 import { logger
} from
'../../../utils/Logger';
82 import { Utils
} from
'../../../utils/Utils';
83 import { OCPP16ServiceUtils
, OCPPConstants
, OCPPIncomingRequestService
} from
'../internal';
85 const moduleName
= 'OCPP16IncomingRequestService';
87 export class OCPP16IncomingRequestService
extends OCPPIncomingRequestService
{
88 protected jsonSchemas
: Map
<OCPP16IncomingRequestCommand
, JSONSchemaType
<JsonObject
>>;
89 private incomingRequestHandlers
: Map
<OCPP16IncomingRequestCommand
, IncomingRequestHandler
>;
91 public constructor() {
92 if (new.target
?.name
=== moduleName
) {
93 throw new TypeError(`Cannot construct ${new.target?.name} instances directly`);
95 super(OCPPVersion
.VERSION_16
);
96 this.incomingRequestHandlers
= new Map
<OCPP16IncomingRequestCommand
, IncomingRequestHandler
>([
97 [OCPP16IncomingRequestCommand
.RESET
, this.handleRequestReset
.bind(this)],
98 [OCPP16IncomingRequestCommand
.CLEAR_CACHE
, this.handleRequestClearCache
.bind(this)],
99 [OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
, this.handleRequestUnlockConnector
.bind(this)],
101 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
102 this.handleRequestGetConfiguration
.bind(this),
105 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
106 this.handleRequestChangeConfiguration
.bind(this),
109 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
110 this.handleRequestSetChargingProfile
.bind(this),
113 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
114 this.handleRequestClearChargingProfile
.bind(this),
117 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
118 this.handleRequestChangeAvailability
.bind(this),
121 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
122 this.handleRequestRemoteStartTransaction
.bind(this),
125 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
126 this.handleRequestRemoteStopTransaction
.bind(this),
128 [OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
, this.handleRequestGetDiagnostics
.bind(this)],
129 [OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
, this.handleRequestTriggerMessage
.bind(this)],
130 [OCPP16IncomingRequestCommand
.DATA_TRANSFER
, this.handleRequestDataTransfer
.bind(this)],
131 [OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
, this.handleRequestUpdateFirmware
.bind(this)],
133 this.jsonSchemas
= new Map
<OCPP16IncomingRequestCommand
, JSONSchemaType
<JsonObject
>>([
135 OCPP16IncomingRequestCommand
.RESET
,
136 OCPP16ServiceUtils
.parseJsonSchemaFile
<ResetRequest
>(
137 '../../../assets/json-schemas/ocpp/1.6/Reset.json',
143 OCPP16IncomingRequestCommand
.CLEAR_CACHE
,
144 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16ClearCacheRequest
>(
145 '../../../assets/json-schemas/ocpp/1.6/ClearCache.json',
151 OCPP16IncomingRequestCommand
.UNLOCK_CONNECTOR
,
152 OCPP16ServiceUtils
.parseJsonSchemaFile
<UnlockConnectorRequest
>(
153 '../../../assets/json-schemas/ocpp/1.6/UnlockConnector.json',
159 OCPP16IncomingRequestCommand
.GET_CONFIGURATION
,
160 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetConfigurationRequest
>(
161 '../../../assets/json-schemas/ocpp/1.6/GetConfiguration.json',
167 OCPP16IncomingRequestCommand
.CHANGE_CONFIGURATION
,
168 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeConfigurationRequest
>(
169 '../../../assets/json-schemas/ocpp/1.6/ChangeConfiguration.json',
175 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
176 OCPP16ServiceUtils
.parseJsonSchemaFile
<GetDiagnosticsRequest
>(
177 '../../../assets/json-schemas/ocpp/1.6/GetDiagnostics.json',
183 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
,
184 OCPP16ServiceUtils
.parseJsonSchemaFile
<SetChargingProfileRequest
>(
185 '../../../assets/json-schemas/ocpp/1.6/SetChargingProfile.json',
191 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
,
192 OCPP16ServiceUtils
.parseJsonSchemaFile
<ClearChargingProfileRequest
>(
193 '../../../assets/json-schemas/ocpp/1.6/ClearChargingProfile.json',
199 OCPP16IncomingRequestCommand
.CHANGE_AVAILABILITY
,
200 OCPP16ServiceUtils
.parseJsonSchemaFile
<ChangeAvailabilityRequest
>(
201 '../../../assets/json-schemas/ocpp/1.6/ChangeAvailability.json',
207 OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
,
208 OCPP16ServiceUtils
.parseJsonSchemaFile
<RemoteStartTransactionRequest
>(
209 '../../../assets/json-schemas/ocpp/1.6/RemoteStartTransaction.json',
215 OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
,
216 OCPP16ServiceUtils
.parseJsonSchemaFile
<RemoteStopTransactionRequest
>(
217 '../../../assets/json-schemas/ocpp/1.6/RemoteStopTransaction.json',
223 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
224 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16TriggerMessageRequest
>(
225 '../../../assets/json-schemas/ocpp/1.6/TriggerMessage.json',
231 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
232 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16DataTransferRequest
>(
233 '../../../assets/json-schemas/ocpp/1.6/DataTransfer.json',
239 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
,
240 OCPP16ServiceUtils
.parseJsonSchemaFile
<OCPP16UpdateFirmwareRequest
>(
241 '../../../assets/json-schemas/ocpp/1.6/UpdateFirmware.json',
247 this.validatePayload
.bind(this);
250 public async incomingRequestHandler(
251 chargingStation
: ChargingStation
,
253 commandName
: OCPP16IncomingRequestCommand
,
254 commandPayload
: JsonType
256 let response
: JsonType
;
258 chargingStation
.getOcppStrictCompliance() === true &&
259 chargingStation
.isInPendingState() === true &&
260 (commandName
=== OCPP16IncomingRequestCommand
.REMOTE_START_TRANSACTION
||
261 commandName
=== OCPP16IncomingRequestCommand
.REMOTE_STOP_TRANSACTION
)
264 ErrorType
.SECURITY_ERROR
,
265 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
269 )} while the charging station is in pending state on the central server`,
275 chargingStation
.isRegistered() === true ||
276 (chargingStation
.getOcppStrictCompliance() === false &&
277 chargingStation
.isInUnknownState() === true)
280 this.incomingRequestHandlers
.has(commandName
) === true &&
281 OCPP16ServiceUtils
.isIncomingRequestCommandSupported(chargingStation
, commandName
) === true
284 this.validatePayload(chargingStation
, commandName
, commandPayload
);
285 // Call the method to build the response
286 response
= await this.incomingRequestHandlers
.get(commandName
)(
293 `${chargingStation.logPrefix()} ${moduleName}.incomingRequestHandler: Handle incoming request error:`,
301 ErrorType
.NOT_IMPLEMENTED
,
302 `${commandName} is not implemented to handle request PDU ${JSON.stringify(
313 ErrorType
.SECURITY_ERROR
,
314 `${commandName} cannot be issued to handle request PDU ${JSON.stringify(
318 )} while the charging station is not registered on the central server.`,
323 // Send the built response
324 await chargingStation
.ocppRequestService
.sendResponse(
332 private validatePayload(
333 chargingStation
: ChargingStation
,
334 commandName
: OCPP16IncomingRequestCommand
,
335 commandPayload
: JsonType
337 if (this.jsonSchemas
.has(commandName
) === true) {
338 return this.validateIncomingRequestPayload(
341 this.jsonSchemas
.get(commandName
),
346 `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command '${commandName}' PDU validation`
351 // Simulate charging station restart
352 private handleRequestReset(
353 chargingStation
: ChargingStation
,
354 commandPayload
: ResetRequest
356 this.runInAsyncScope(
357 chargingStation
.reset
.bind(chargingStation
) as (
358 this: ChargingStation
,
362 `${commandPayload.type}Reset` as OCPP16StopTransactionReason
364 /* This is intentional */
367 `${chargingStation.logPrefix()} ${
369 } reset command received, simulating it. The station will be back online in ${Utils.formatDurationMilliSeconds(
370 chargingStation.stationInfo.resetTime
373 return OCPPConstants
.OCPP_RESPONSE_ACCEPTED
;
376 private async handleRequestUnlockConnector(
377 chargingStation
: ChargingStation
,
378 commandPayload
: UnlockConnectorRequest
379 ): Promise
<UnlockConnectorResponse
> {
380 const connectorId
= commandPayload
.connectorId
;
381 if (chargingStation
.connectors
.has(connectorId
) === false) {
383 `${chargingStation.logPrefix()} Trying to unlock a non existing connector Id ${connectorId.toString()}`
385 return OCPPConstants
.OCPP_RESPONSE_UNLOCK_NOT_SUPPORTED
;
387 if (connectorId
=== 0) {
389 `${chargingStation.logPrefix()} Trying to unlock connector Id ${connectorId.toString()}`
391 return OCPPConstants
.OCPP_RESPONSE_UNLOCK_NOT_SUPPORTED
;
393 if (chargingStation
.getConnectorStatus(connectorId
)?.transactionStarted
=== true) {
394 const stopResponse
= await chargingStation
.stopTransactionOnConnector(
396 OCPP16StopTransactionReason
.UNLOCK_COMMAND
398 if (stopResponse
.idTagInfo
?.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
399 return OCPPConstants
.OCPP_RESPONSE_UNLOCKED
;
401 return OCPPConstants
.OCPP_RESPONSE_UNLOCK_FAILED
;
403 await chargingStation
.ocppRequestService
.requestHandler
<
404 OCPP16StatusNotificationRequest
,
405 OCPP16StatusNotificationResponse
406 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
408 status: OCPP16ChargePointStatus
.AVAILABLE
,
409 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
411 chargingStation
.getConnectorStatus(connectorId
).status = OCPP16ChargePointStatus
.AVAILABLE
;
412 return OCPPConstants
.OCPP_RESPONSE_UNLOCKED
;
415 private handleRequestGetConfiguration(
416 chargingStation
: ChargingStation
,
417 commandPayload
: GetConfigurationRequest
418 ): GetConfigurationResponse
{
419 const configurationKey
: OCPPConfigurationKey
[] = [];
420 const unknownKey
: string[] = [];
421 if (Utils
.isUndefined(commandPayload
.key
) === true) {
422 for (const configuration
of chargingStation
.ocppConfiguration
.configurationKey
) {
423 if (Utils
.isUndefined(configuration
.visible
) === true) {
424 configuration
.visible
= true;
426 if (configuration
.visible
=== false) {
429 configurationKey
.push({
430 key
: configuration
.key
,
431 readonly: configuration
.readonly,
432 value
: configuration
.value
,
435 } else if (Utils
.isNotEmptyArray(commandPayload
.key
) === true) {
436 for (const key
of commandPayload
.key
) {
437 const keyFound
= ChargingStationConfigurationUtils
.getConfigurationKey(
443 if (Utils
.isUndefined(keyFound
.visible
) === true) {
444 keyFound
.visible
= true;
446 if (keyFound
.visible
=== false) {
449 configurationKey
.push({
451 readonly: keyFound
.readonly,
452 value
: keyFound
.value
,
455 unknownKey
.push(key
);
465 private handleRequestChangeConfiguration(
466 chargingStation
: ChargingStation
,
467 commandPayload
: ChangeConfigurationRequest
468 ): ChangeConfigurationResponse
{
469 const keyToChange
= ChargingStationConfigurationUtils
.getConfigurationKey(
475 return OCPPConstants
.OCPP_CONFIGURATION_RESPONSE_NOT_SUPPORTED
;
476 } else if (keyToChange
&& keyToChange
.readonly) {
477 return OCPPConstants
.OCPP_CONFIGURATION_RESPONSE_REJECTED
;
478 } else if (keyToChange
&& !keyToChange
.readonly) {
479 let valueChanged
= false;
480 if (keyToChange
.value
!== commandPayload
.value
) {
481 ChargingStationConfigurationUtils
.setConfigurationKeyValue(
484 commandPayload
.value
,
489 let triggerHeartbeatRestart
= false;
490 if (keyToChange
.key
=== OCPP16StandardParametersKey
.HeartBeatInterval
&& valueChanged
) {
491 ChargingStationConfigurationUtils
.setConfigurationKeyValue(
493 OCPP16StandardParametersKey
.HeartbeatInterval
,
496 triggerHeartbeatRestart
= true;
498 if (keyToChange
.key
=== OCPP16StandardParametersKey
.HeartbeatInterval
&& valueChanged
) {
499 ChargingStationConfigurationUtils
.setConfigurationKeyValue(
501 OCPP16StandardParametersKey
.HeartBeatInterval
,
504 triggerHeartbeatRestart
= true;
506 if (triggerHeartbeatRestart
) {
507 chargingStation
.restartHeartbeat();
509 if (keyToChange
.key
=== OCPP16StandardParametersKey
.WebSocketPingInterval
&& valueChanged
) {
510 chargingStation
.restartWebSocketPing();
512 if (keyToChange
.reboot
) {
513 return OCPPConstants
.OCPP_CONFIGURATION_RESPONSE_REBOOT_REQUIRED
;
515 return OCPPConstants
.OCPP_CONFIGURATION_RESPONSE_ACCEPTED
;
519 private handleRequestSetChargingProfile(
520 chargingStation
: ChargingStation
,
521 commandPayload
: SetChargingProfileRequest
522 ): SetChargingProfileResponse
{
524 OCPP16ServiceUtils
.checkFeatureProfile(
526 OCPP16SupportedFeatureProfiles
.SmartCharging
,
527 OCPP16IncomingRequestCommand
.SET_CHARGING_PROFILE
530 return OCPPConstants
.OCPP_SET_CHARGING_PROFILE_RESPONSE_NOT_SUPPORTED
;
532 if (chargingStation
.connectors
.has(commandPayload
.connectorId
) === false) {
534 `${chargingStation.logPrefix()} Trying to set charging profile(s) to a non existing connector Id ${
535 commandPayload.connectorId
538 return OCPPConstants
.OCPP_SET_CHARGING_PROFILE_RESPONSE_REJECTED
;
541 commandPayload
.csChargingProfiles
.chargingProfilePurpose
===
542 ChargingProfilePurposeType
.CHARGE_POINT_MAX_PROFILE
&&
543 commandPayload
.connectorId
!== 0
545 return OCPPConstants
.OCPP_SET_CHARGING_PROFILE_RESPONSE_REJECTED
;
548 commandPayload
.csChargingProfiles
.chargingProfilePurpose
===
549 ChargingProfilePurposeType
.TX_PROFILE
&&
550 (commandPayload
.connectorId
=== 0 ||
551 chargingStation
.getConnectorStatus(commandPayload
.connectorId
)?.transactionStarted
===
555 `${chargingStation.logPrefix()} Trying to set transaction charging profile(s) on connector ${
556 commandPayload.connectorId
557 } without a started transaction`
559 return OCPPConstants
.OCPP_SET_CHARGING_PROFILE_RESPONSE_REJECTED
;
561 OCPP16ServiceUtils
.setChargingProfile(
563 commandPayload
.connectorId
,
564 commandPayload
.csChargingProfiles
567 `${chargingStation.logPrefix()} Charging profile(s) set on connector id ${
568 commandPayload.connectorId
570 commandPayload
.csChargingProfiles
572 return OCPPConstants
.OCPP_SET_CHARGING_PROFILE_RESPONSE_ACCEPTED
;
575 private handleRequestClearChargingProfile(
576 chargingStation
: ChargingStation
,
577 commandPayload
: ClearChargingProfileRequest
578 ): ClearChargingProfileResponse
{
580 OCPP16ServiceUtils
.checkFeatureProfile(
582 OCPP16SupportedFeatureProfiles
.SmartCharging
,
583 OCPP16IncomingRequestCommand
.CLEAR_CHARGING_PROFILE
586 return OCPPConstants
.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_UNKNOWN
;
588 if (chargingStation
.connectors
.has(commandPayload
.connectorId
) === false) {
590 `${chargingStation.logPrefix()} Trying to clear a charging profile(s) to a non existing connector Id ${
591 commandPayload.connectorId
594 return OCPPConstants
.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_UNKNOWN
;
596 const connectorStatus
= chargingStation
.getConnectorStatus(commandPayload
.connectorId
);
598 !Utils
.isNullOrUndefined(commandPayload
.connectorId
) &&
599 Utils
.isNotEmptyArray(connectorStatus
?.chargingProfiles
)
601 connectorStatus
.chargingProfiles
= [];
603 `${chargingStation.logPrefix()} Charging profile(s) cleared on connector id ${
604 commandPayload.connectorId
607 return OCPPConstants
.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_ACCEPTED
;
609 if (Utils
.isNullOrUndefined(commandPayload
.connectorId
)) {
610 let clearedCP
= false;
611 for (const connectorId
of chargingStation
.connectors
.keys()) {
613 Utils
.isNotEmptyArray(chargingStation
.getConnectorStatus(connectorId
)?.chargingProfiles
)
616 .getConnectorStatus(connectorId
)
617 ?.chargingProfiles
?.forEach((chargingProfile
: OCPP16ChargingProfile
, index
: number) => {
618 let clearCurrentCP
= false;
619 if (chargingProfile
.chargingProfileId
=== commandPayload
.id
) {
620 clearCurrentCP
= true;
623 !commandPayload
.chargingProfilePurpose
&&
624 chargingProfile
.stackLevel
=== commandPayload
.stackLevel
626 clearCurrentCP
= true;
629 !chargingProfile
.stackLevel
&&
630 chargingProfile
.chargingProfilePurpose
=== commandPayload
.chargingProfilePurpose
632 clearCurrentCP
= true;
635 chargingProfile
.stackLevel
=== commandPayload
.stackLevel
&&
636 chargingProfile
.chargingProfilePurpose
=== commandPayload
.chargingProfilePurpose
638 clearCurrentCP
= true;
640 if (clearCurrentCP
) {
641 connectorStatus
?.chargingProfiles
?.splice(index
, 1);
643 `${chargingStation.logPrefix()} Matching charging profile(s) cleared: %j`,
652 return OCPPConstants
.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_ACCEPTED
;
655 return OCPPConstants
.OCPP_CLEAR_CHARGING_PROFILE_RESPONSE_UNKNOWN
;
658 private async handleRequestChangeAvailability(
659 chargingStation
: ChargingStation
,
660 commandPayload
: ChangeAvailabilityRequest
661 ): Promise
<ChangeAvailabilityResponse
> {
662 const connectorId
: number = commandPayload
.connectorId
;
663 if (chargingStation
.connectors
.has(connectorId
) === false) {
665 `${chargingStation.logPrefix()} Trying to change the availability of a non existing connector Id ${connectorId.toString()}`
667 return OCPPConstants
.OCPP_AVAILABILITY_RESPONSE_REJECTED
;
669 const chargePointStatus
: OCPP16ChargePointStatus
=
670 commandPayload
.type === OCPP16AvailabilityType
.OPERATIVE
671 ? OCPP16ChargePointStatus
.AVAILABLE
672 : OCPP16ChargePointStatus
.UNAVAILABLE
;
673 if (connectorId
=== 0) {
674 let response
: ChangeAvailabilityResponse
= OCPPConstants
.OCPP_AVAILABILITY_RESPONSE_ACCEPTED
;
675 for (const id
of chargingStation
.connectors
.keys()) {
676 if (chargingStation
.getConnectorStatus(id
)?.transactionStarted
=== true) {
677 response
= OCPPConstants
.OCPP_AVAILABILITY_RESPONSE_SCHEDULED
;
679 chargingStation
.getConnectorStatus(id
).availability
= commandPayload
.type;
680 if (response
=== OCPPConstants
.OCPP_AVAILABILITY_RESPONSE_ACCEPTED
) {
681 await chargingStation
.ocppRequestService
.requestHandler
<
682 OCPP16StatusNotificationRequest
,
683 OCPP16StatusNotificationResponse
684 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
686 status: chargePointStatus
,
687 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
689 chargingStation
.getConnectorStatus(id
).status = chargePointStatus
;
695 (chargingStation
.isChargingStationAvailable() === true ||
696 (chargingStation
.isChargingStationAvailable() === false &&
697 commandPayload
.type === OCPP16AvailabilityType
.INOPERATIVE
))
699 if (chargingStation
.getConnectorStatus(connectorId
)?.transactionStarted
=== true) {
700 chargingStation
.getConnectorStatus(connectorId
).availability
= commandPayload
.type;
701 return OCPPConstants
.OCPP_AVAILABILITY_RESPONSE_SCHEDULED
;
703 chargingStation
.getConnectorStatus(connectorId
).availability
= commandPayload
.type;
704 await chargingStation
.ocppRequestService
.requestHandler
<
705 OCPP16StatusNotificationRequest
,
706 OCPP16StatusNotificationResponse
707 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
709 status: chargePointStatus
,
710 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
712 chargingStation
.getConnectorStatus(connectorId
).status = chargePointStatus
;
713 return OCPPConstants
.OCPP_AVAILABILITY_RESPONSE_ACCEPTED
;
715 return OCPPConstants
.OCPP_AVAILABILITY_RESPONSE_REJECTED
;
718 private async handleRequestRemoteStartTransaction(
719 chargingStation
: ChargingStation
,
720 commandPayload
: RemoteStartTransactionRequest
721 ): Promise
<GenericResponse
> {
722 const transactionConnectorId
= commandPayload
.connectorId
;
723 if (chargingStation
.connectors
.has(transactionConnectorId
) === true) {
724 const remoteStartTransactionLogMsg
= `${chargingStation.logPrefix()} Transaction remotely STARTED on ${
725 chargingStation.stationInfo.chargingStationId
726 }#${transactionConnectorId.toString()} for idTag '${commandPayload.idTag}'`;
727 await chargingStation
.ocppRequestService
.requestHandler
<
728 OCPP16StatusNotificationRequest
,
729 OCPP16StatusNotificationResponse
730 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
731 connectorId
: transactionConnectorId
,
732 status: OCPP16ChargePointStatus
.PREPARING
,
733 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
735 const connectorStatus
= chargingStation
.getConnectorStatus(transactionConnectorId
);
736 connectorStatus
.status = OCPP16ChargePointStatus
.PREPARING
;
737 if (chargingStation
.isChargingStationAvailable() === true) {
738 // Check if authorized
739 if (chargingStation
.getAuthorizeRemoteTxRequests() === true) {
740 let authorized
= false;
742 chargingStation
.getLocalAuthListEnabled() === true &&
743 chargingStation
.hasAuthorizedTags() === true &&
744 Utils
.isNotEmptyString(
745 chargingStation
.authorizedTagsCache
747 ChargingStationUtils
.getAuthorizationFile(chargingStation
.stationInfo
)
749 ?.find((idTag
) => idTag
=== commandPayload
.idTag
)
752 connectorStatus
.localAuthorizeIdTag
= commandPayload
.idTag
;
753 connectorStatus
.idTagLocalAuthorized
= true;
755 } else if (chargingStation
.getMustAuthorizeAtRemoteStart() === true) {
756 connectorStatus
.authorizeIdTag
= commandPayload
.idTag
;
757 const authorizeResponse
: OCPP16AuthorizeResponse
=
758 await chargingStation
.ocppRequestService
.requestHandler
<
759 OCPP16AuthorizeRequest
,
760 OCPP16AuthorizeResponse
761 >(chargingStation
, OCPP16RequestCommand
.AUTHORIZE
, {
762 idTag
: commandPayload
.idTag
,
764 if (authorizeResponse
?.idTagInfo
?.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
769 `${chargingStation.logPrefix()} The charging station configuration expects authorize at remote start transaction but local authorization or authorize isn't enabled`
772 if (authorized
=== true) {
773 // Authorization successful, start transaction
775 this.setRemoteStartTransactionChargingProfile(
777 transactionConnectorId
,
778 commandPayload
.chargingProfile
781 connectorStatus
.transactionRemoteStarted
= true;
784 await chargingStation
.ocppRequestService
.requestHandler
<
785 OCPP16StartTransactionRequest
,
786 OCPP16StartTransactionResponse
787 >(chargingStation
, OCPP16RequestCommand
.START_TRANSACTION
, {
788 connectorId
: transactionConnectorId
,
789 idTag
: commandPayload
.idTag
,
791 ).idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
793 logger
.debug(remoteStartTransactionLogMsg
);
794 return OCPPConstants
.OCPP_RESPONSE_ACCEPTED
;
796 return this.notifyRemoteStartTransactionRejected(
798 transactionConnectorId
,
802 return this.notifyRemoteStartTransactionRejected(
804 transactionConnectorId
,
808 return this.notifyRemoteStartTransactionRejected(
810 transactionConnectorId
,
814 // No authorization check required, start transaction
816 this.setRemoteStartTransactionChargingProfile(
818 transactionConnectorId
,
819 commandPayload
.chargingProfile
822 connectorStatus
.transactionRemoteStarted
= true;
825 await chargingStation
.ocppRequestService
.requestHandler
<
826 OCPP16StartTransactionRequest
,
827 OCPP16StartTransactionResponse
828 >(chargingStation
, OCPP16RequestCommand
.START_TRANSACTION
, {
829 connectorId
: transactionConnectorId
,
830 idTag
: commandPayload
.idTag
,
832 ).idTagInfo
.status === OCPP16AuthorizationStatus
.ACCEPTED
834 logger
.debug(remoteStartTransactionLogMsg
);
835 return OCPPConstants
.OCPP_RESPONSE_ACCEPTED
;
837 return this.notifyRemoteStartTransactionRejected(
839 transactionConnectorId
,
843 return this.notifyRemoteStartTransactionRejected(
845 transactionConnectorId
,
849 return this.notifyRemoteStartTransactionRejected(
851 transactionConnectorId
,
855 return this.notifyRemoteStartTransactionRejected(
857 transactionConnectorId
,
862 private async notifyRemoteStartTransactionRejected(
863 chargingStation
: ChargingStation
,
866 ): Promise
<GenericResponse
> {
868 chargingStation
.getConnectorStatus(connectorId
)?.status !== OCPP16ChargePointStatus
.AVAILABLE
870 await chargingStation
.ocppRequestService
.requestHandler
<
871 OCPP16StatusNotificationRequest
,
872 OCPP16StatusNotificationResponse
873 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
875 status: OCPP16ChargePointStatus
.AVAILABLE
,
876 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
878 chargingStation
.getConnectorStatus(connectorId
).status = OCPP16ChargePointStatus
.AVAILABLE
;
881 `${chargingStation.logPrefix()} Remote starting transaction REJECTED on connector Id ${connectorId.toString()}, idTag '${idTag}', availability '${
882 chargingStation.getConnectorStatus(connectorId)?.availability
883 }', status '${chargingStation.getConnectorStatus(connectorId)?.status}'`
885 return OCPPConstants
.OCPP_RESPONSE_REJECTED
;
888 private setRemoteStartTransactionChargingProfile(
889 chargingStation
: ChargingStation
,
891 cp
: OCPP16ChargingProfile
893 if (cp
&& cp
.chargingProfilePurpose
=== ChargingProfilePurposeType
.TX_PROFILE
) {
894 OCPP16ServiceUtils
.setChargingProfile(chargingStation
, connectorId
, cp
);
896 `${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on connector id ${connectorId}: %j`,
900 } else if (cp
&& cp
.chargingProfilePurpose
!== ChargingProfilePurposeType
.TX_PROFILE
) {
902 `${chargingStation.logPrefix()} Not allowed to set ${
903 cp.chargingProfilePurpose
904 } charging profile(s) at remote start transaction`
912 private async handleRequestRemoteStopTransaction(
913 chargingStation
: ChargingStation
,
914 commandPayload
: RemoteStopTransactionRequest
915 ): Promise
<GenericResponse
> {
916 const transactionId
= commandPayload
.transactionId
;
917 for (const connectorId
of chargingStation
.connectors
.keys()) {
920 chargingStation
.getConnectorStatus(connectorId
)?.transactionId
=== transactionId
922 await chargingStation
.ocppRequestService
.requestHandler
<
923 OCPP16StatusNotificationRequest
,
924 OCPP16StatusNotificationResponse
925 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
927 status: OCPP16ChargePointStatus
.FINISHING
,
928 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
930 chargingStation
.getConnectorStatus(connectorId
).status = OCPP16ChargePointStatus
.FINISHING
;
931 const stopResponse
= await chargingStation
.stopTransactionOnConnector(
933 OCPP16StopTransactionReason
.REMOTE
935 if (stopResponse
.idTagInfo
?.status === OCPP16AuthorizationStatus
.ACCEPTED
) {
936 return OCPPConstants
.OCPP_RESPONSE_ACCEPTED
;
938 return OCPPConstants
.OCPP_RESPONSE_REJECTED
;
942 `${chargingStation.logPrefix()} Trying to remote stop a non existing transaction ${transactionId.toString()}`
944 return OCPPConstants
.OCPP_RESPONSE_REJECTED
;
947 private handleRequestUpdateFirmware(
948 chargingStation
: ChargingStation
,
949 commandPayload
: OCPP16UpdateFirmwareRequest
950 ): OCPP16UpdateFirmwareResponse
{
952 OCPP16ServiceUtils
.checkFeatureProfile(
954 OCPP16SupportedFeatureProfiles
.FirmwareManagement
,
955 OCPP16IncomingRequestCommand
.UPDATE_FIRMWARE
959 `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: feature profile not supported`
961 return OCPPConstants
.OCPP_RESPONSE_EMPTY
;
964 !Utils
.isNullOrUndefined(chargingStation
.stationInfo
.firmwareStatus
) &&
965 chargingStation
.stationInfo
.firmwareStatus
!== OCPP16FirmwareStatus
.Installed
968 `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: firmware update is already in progress`
970 return OCPPConstants
.OCPP_RESPONSE_EMPTY
;
972 const retrieveDate
= Utils
.convertToDate(commandPayload
.retrieveDate
);
973 const now
= Date.now();
974 if (retrieveDate
?.getTime() <= now
) {
975 this.runInAsyncScope(
976 this.updateFirmware
.bind(this) as (
977 this: OCPP16IncomingRequestService
,
983 /* This is intentional */
987 this.updateFirmware(chargingStation
).catch(() => {
990 }, retrieveDate
?.getTime() - now
);
992 return OCPPConstants
.OCPP_RESPONSE_EMPTY
;
995 private async updateFirmware(
996 chargingStation
: ChargingStation
,
1000 chargingStation
.stopAutomaticTransactionGenerator();
1001 for (const connectorId
of chargingStation
.connectors
.keys()) {
1004 chargingStation
.getConnectorStatus(connectorId
)?.transactionStarted
=== false
1006 await chargingStation
.ocppRequestService
.requestHandler
<
1007 OCPP16StatusNotificationRequest
,
1008 OCPP16StatusNotificationResponse
1009 >(chargingStation
, OCPP16RequestCommand
.STATUS_NOTIFICATION
, {
1011 status: OCPP16ChargePointStatus
.UNAVAILABLE
,
1012 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
1014 chargingStation
.getConnectorStatus(connectorId
).status =
1015 OCPP16ChargePointStatus
.UNAVAILABLE
;
1019 chargingStation
.stationInfo
?.firmwareUpgrade
?.failureStatus
&&
1020 Utils
.isNotEmptyString(chargingStation
.stationInfo
?.firmwareUpgrade
?.failureStatus
)
1022 await chargingStation
.ocppRequestService
.requestHandler
<
1023 OCPP16FirmwareStatusNotificationRequest
,
1024 OCPP16FirmwareStatusNotificationResponse
1025 >(chargingStation
, OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, {
1026 status: chargingStation
.stationInfo
?.firmwareUpgrade
?.failureStatus
,
1030 await chargingStation
.ocppRequestService
.requestHandler
<
1031 OCPP16FirmwareStatusNotificationRequest
,
1032 OCPP16FirmwareStatusNotificationResponse
1033 >(chargingStation
, OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, {
1034 status: OCPP16FirmwareStatus
.Downloading
,
1036 chargingStation
.stationInfo
.firmwareStatus
= OCPP16FirmwareStatus
.Downloading
;
1037 await Utils
.sleep(Utils
.getRandomInteger(maxDelay
, minDelay
) * 1000);
1038 await chargingStation
.ocppRequestService
.requestHandler
<
1039 OCPP16FirmwareStatusNotificationRequest
,
1040 OCPP16FirmwareStatusNotificationResponse
1041 >(chargingStation
, OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, {
1042 status: OCPP16FirmwareStatus
.Downloaded
,
1044 chargingStation
.stationInfo
.firmwareStatus
= OCPP16FirmwareStatus
.Downloaded
;
1045 await Utils
.sleep(Utils
.getRandomInteger(maxDelay
, minDelay
) * 1000);
1046 await chargingStation
.ocppRequestService
.requestHandler
<
1047 OCPP16FirmwareStatusNotificationRequest
,
1048 OCPP16FirmwareStatusNotificationResponse
1049 >(chargingStation
, OCPP16RequestCommand
.FIRMWARE_STATUS_NOTIFICATION
, {
1050 status: OCPP16FirmwareStatus
.Installing
,
1052 chargingStation
.stationInfo
.firmwareStatus
= OCPP16FirmwareStatus
.Installing
;
1053 if (chargingStation
.stationInfo
?.firmwareUpgrade
?.reset
=== true) {
1054 await Utils
.sleep(Utils
.getRandomInteger(maxDelay
, minDelay
) * 1000);
1055 await chargingStation
.reset(OCPP16StopTransactionReason
.REBOOT
);
1059 private async handleRequestGetDiagnostics(
1060 chargingStation
: ChargingStation
,
1061 commandPayload
: GetDiagnosticsRequest
1062 ): Promise
<GetDiagnosticsResponse
> {
1064 OCPP16ServiceUtils
.checkFeatureProfile(
1066 OCPP16SupportedFeatureProfiles
.FirmwareManagement
,
1067 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
1071 `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetDiagnostics: Cannot get diagnostics: feature profile not supported`
1073 return OCPPConstants
.OCPP_RESPONSE_EMPTY
;
1075 const uri
= new URL(commandPayload
.location
);
1076 if (uri
.protocol
.startsWith('ftp:')) {
1077 let ftpClient
: Client
;
1080 .readdirSync(path
.resolve(path
.dirname(fileURLToPath(import.meta
.url
)), '../../../../'))
1081 .filter((file
) => file
.endsWith('.log'))
1082 .map((file
) => path
.join('./', file
));
1083 const diagnosticsArchive
= `${chargingStation.stationInfo.chargingStationId}_logs.tar.gz`;
1084 tar
.create({ gzip
: true }, logFiles
).pipe(fs
.createWriteStream(diagnosticsArchive
));
1085 ftpClient
= new Client();
1086 const accessResponse
= await ftpClient
.access({
1088 ...(Utils
.isNotEmptyString(uri
.port
) && { port
: Utils
.convertToInt(uri
.port
) }),
1089 ...(Utils
.isNotEmptyString(uri
.username
) && { user
: uri
.username
}),
1090 ...(Utils
.isNotEmptyString(uri
.password
) && { password
: uri
.password
}),
1092 let uploadResponse
: FTPResponse
;
1093 if (accessResponse
.code
=== 220) {
1094 ftpClient
.trackProgress((info
) => {
1096 `${chargingStation.logPrefix()} ${
1098 } bytes transferred from diagnostics archive ${info.name}`
1100 chargingStation
.ocppRequestService
1102 OCPP16DiagnosticsStatusNotificationRequest
,
1103 OCPP16DiagnosticsStatusNotificationResponse
1104 >(chargingStation
, OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, {
1105 status: OCPP16DiagnosticsStatus
.Uploading
,
1109 `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetDiagnostics: Error while sending '${
1110 OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION
1116 uploadResponse
= await ftpClient
.uploadFrom(
1118 path
.resolve(path
.dirname(fileURLToPath(import.meta
.url
)), '../../../../'),
1121 `${uri.pathname}${diagnosticsArchive}`
1123 if (uploadResponse
.code
=== 226) {
1124 await chargingStation
.ocppRequestService
.requestHandler
<
1125 OCPP16DiagnosticsStatusNotificationRequest
,
1126 OCPP16DiagnosticsStatusNotificationResponse
1127 >(chargingStation
, OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, {
1128 status: OCPP16DiagnosticsStatus
.Uploaded
,
1133 return { fileName
: diagnosticsArchive
};
1135 throw new OCPPError(
1136 ErrorType
.GENERIC_ERROR
,
1137 `Diagnostics transfer failed with error code ${accessResponse.code.toString()}${
1138 uploadResponse?.code && `|${uploadResponse?.code.toString()}
`
1140 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
1143 throw new OCPPError(
1144 ErrorType
.GENERIC_ERROR
,
1145 `Diagnostics transfer failed with error code ${accessResponse.code.toString()}${
1146 uploadResponse?.code && `|${uploadResponse?.code.toString()}
`
1148 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
1151 await chargingStation
.ocppRequestService
.requestHandler
<
1152 OCPP16DiagnosticsStatusNotificationRequest
,
1153 OCPP16DiagnosticsStatusNotificationResponse
1154 >(chargingStation
, OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, {
1155 status: OCPP16DiagnosticsStatus
.UploadFailed
,
1160 return this.handleIncomingRequestError(
1162 OCPP16IncomingRequestCommand
.GET_DIAGNOSTICS
,
1164 { errorResponse
: OCPPConstants
.OCPP_RESPONSE_EMPTY
}
1169 `${chargingStation.logPrefix()} Unsupported protocol ${
1171 } to transfer the diagnostic logs archive`
1173 await chargingStation
.ocppRequestService
.requestHandler
<
1174 OCPP16DiagnosticsStatusNotificationRequest
,
1175 OCPP16DiagnosticsStatusNotificationResponse
1176 >(chargingStation
, OCPP16RequestCommand
.DIAGNOSTICS_STATUS_NOTIFICATION
, {
1177 status: OCPP16DiagnosticsStatus
.UploadFailed
,
1179 return OCPPConstants
.OCPP_RESPONSE_EMPTY
;
1183 private handleRequestTriggerMessage(
1184 chargingStation
: ChargingStation
,
1185 commandPayload
: OCPP16TriggerMessageRequest
1186 ): OCPP16TriggerMessageResponse
{
1188 !OCPP16ServiceUtils
.checkFeatureProfile(
1190 OCPP16SupportedFeatureProfiles
.RemoteTrigger
,
1191 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
1193 !OCPP16ServiceUtils
.isMessageTriggerSupported(
1195 commandPayload
.requestedMessage
1198 return OCPPConstants
.OCPP_TRIGGER_MESSAGE_RESPONSE_NOT_IMPLEMENTED
;
1201 !OCPP16ServiceUtils
.isConnectorIdValid(
1203 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
1204 commandPayload
.connectorId
1207 return OCPPConstants
.OCPP_TRIGGER_MESSAGE_RESPONSE_REJECTED
;
1210 switch (commandPayload
.requestedMessage
) {
1211 case OCPP16MessageTrigger
.BootNotification
:
1213 chargingStation
.ocppRequestService
1214 .requestHandler
<OCPP16BootNotificationRequest
, OCPP16BootNotificationResponse
>(
1216 OCPP16RequestCommand
.BOOT_NOTIFICATION
,
1217 chargingStation
.bootNotificationRequest
,
1218 { skipBufferingOnError
: true, triggerMessage
: true }
1220 .then((response
) => {
1221 chargingStation
.bootNotificationResponse
= response
;
1224 /* This is intentional */
1226 }, Constants
.OCPP_TRIGGER_MESSAGE_DELAY
);
1227 return OCPPConstants
.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED
;
1228 case OCPP16MessageTrigger
.Heartbeat
:
1230 chargingStation
.ocppRequestService
1231 .requestHandler
<OCPP16HeartbeatRequest
, OCPP16HeartbeatResponse
>(
1233 OCPP16RequestCommand
.HEARTBEAT
,
1236 triggerMessage
: true,
1240 /* This is intentional */
1242 }, Constants
.OCPP_TRIGGER_MESSAGE_DELAY
);
1243 return OCPPConstants
.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED
;
1244 case OCPP16MessageTrigger
.StatusNotification
:
1246 if (!Utils
.isNullOrUndefined(commandPayload
?.connectorId
)) {
1247 chargingStation
.ocppRequestService
1248 .requestHandler
<OCPP16StatusNotificationRequest
, OCPP16StatusNotificationResponse
>(
1250 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
1252 connectorId
: commandPayload
.connectorId
,
1253 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
1254 status: chargingStation
.getConnectorStatus(commandPayload
.connectorId
)?.status,
1257 triggerMessage
: true,
1261 /* This is intentional */
1264 for (const connectorId
of chargingStation
.connectors
.keys()) {
1265 chargingStation
.ocppRequestService
1267 OCPP16StatusNotificationRequest
,
1268 OCPP16StatusNotificationResponse
1271 OCPP16RequestCommand
.STATUS_NOTIFICATION
,
1274 errorCode
: OCPP16ChargePointErrorCode
.NO_ERROR
,
1275 status: chargingStation
.getConnectorStatus(connectorId
)?.status,
1278 triggerMessage
: true,
1282 /* This is intentional */
1286 }, Constants
.OCPP_TRIGGER_MESSAGE_DELAY
);
1287 return OCPPConstants
.OCPP_TRIGGER_MESSAGE_RESPONSE_ACCEPTED
;
1289 return OCPPConstants
.OCPP_TRIGGER_MESSAGE_RESPONSE_NOT_IMPLEMENTED
;
1292 return this.handleIncomingRequestError(
1294 OCPP16IncomingRequestCommand
.TRIGGER_MESSAGE
,
1296 { errorResponse
: OCPPConstants
.OCPP_TRIGGER_MESSAGE_RESPONSE_REJECTED
}
1301 private handleRequestDataTransfer(
1302 chargingStation
: ChargingStation
,
1303 commandPayload
: OCPP16DataTransferRequest
1304 ): OCPP16DataTransferResponse
{
1306 if (Object.values(OCPP16DataTransferVendorId
).includes(commandPayload
.vendorId
)) {
1308 status: OCPP16DataTransferStatus
.ACCEPTED
,
1312 status: OCPP16DataTransferStatus
.UNKNOWN_VENDOR_ID
,
1315 return this.handleIncomingRequestError(
1317 OCPP16IncomingRequestCommand
.DATA_TRANSFER
,
1319 { errorResponse
: OCPPConstants
.OCPP_DATA_TRANSFER_RESPONSE_REJECTED
}