- public async sendMessage(messageId: string, messageData: JsonType | OCPPError, messageType: MessageType, commandName: RequestCommand | IncomingRequestCommand,
- params: SendParams = {
- skipBufferingOnError: false,
- triggerMessage: false
- }): Promise<JsonType | OCPPError | string> {
- if (this.chargingStation.isInRejectedState() || (this.chargingStation.isInPendingState() && !params.triggerMessage)) {
- throw new OCPPError(ErrorType.SECURITY_ERROR, 'Cannot send command payload if the charging station is not in accepted state', commandName);
- // FIXME: Add template tunable for accepting incoming configuration requests while in unknown state
- } else if ((this.chargingStation.isInUnknownState() && (commandName === RequestCommand.BOOT_NOTIFICATION || commandName === IncomingRequestCommand.GET_CONFIGURATION || commandName === IncomingRequestCommand.CHANGE_CONFIGURATION || commandName === IncomingRequestCommand.CHANGE_AVAILABILITY || commandName === IncomingRequestCommand.TRIGGER_MESSAGE))
- || this.chargingStation.isInAcceptedState() || (this.chargingStation.isInPendingState() && params.triggerMessage)) {
+ public async sendResponse(
+ chargingStation: ChargingStation,
+ messageId: string,
+ messagePayload: JsonType,
+ commandName: IncomingRequestCommand
+ ): Promise<ResponseType> {
+ try {
+ // Send response message
+ return await this.internalSendMessage(
+ chargingStation,
+ messageId,
+ messagePayload,
+ MessageType.CALL_RESULT_MESSAGE,
+ commandName
+ );
+ } catch (error) {
+ this.handleRequestError(chargingStation, commandName, error as Error);
+ }
+ }
+
+ public async sendError(
+ chargingStation: ChargingStation,
+ messageId: string,
+ ocppError: OCPPError,
+ commandName: RequestCommand | IncomingRequestCommand
+ ): Promise<ResponseType> {
+ try {
+ // Send error message
+ return await this.internalSendMessage(
+ chargingStation,
+ messageId,
+ ocppError,
+ MessageType.CALL_ERROR_MESSAGE,
+ commandName
+ );
+ } catch (error) {
+ this.handleRequestError(chargingStation, commandName, error as Error);
+ }
+ }
+
+ protected async sendMessage(
+ chargingStation: ChargingStation,
+ messageId: string,
+ messagePayload: JsonType,
+ commandName: RequestCommand,
+ params: RequestParams = {
+ skipBufferingOnError: false,
+ triggerMessage: false,
+ }
+ ): Promise<ResponseType> {
+ try {
+ return await this.internalSendMessage(
+ chargingStation,
+ messageId,
+ messagePayload,
+ MessageType.CALL_MESSAGE,
+ commandName,
+ params
+ );
+ } catch (error) {
+ this.handleRequestError(chargingStation, commandName, error as Error, { throwError: false });
+ }
+ }
+
+ protected validateRequestPayload<T extends JsonType>(
+ chargingStation: ChargingStation,
+ commandName: RequestCommand,
+ schema: JSONSchemaType<T>,
+ payload: T
+ ): boolean {
+ if (!chargingStation.getPayloadSchemaValidation()) {
+ return true;
+ }
+ const validate = this.ajv.compile(schema);
+ if (validate(payload)) {
+ return true;
+ }
+ logger.error(
+ `${chargingStation.logPrefix()} ${moduleName}.validateRequestPayload: Request PDU is invalid: %j`,
+ validate.errors
+ );
+ throw new OCPPError(
+ OCPPServiceUtils.ajvErrorsToErrorType(validate.errors),
+ 'Request PDU is invalid',
+ commandName,
+ JSON.stringify(validate.errors, null, 2)
+ );
+ }
+
+ private async internalSendMessage(
+ chargingStation: ChargingStation,
+ messageId: string,
+ messagePayload: JsonType | OCPPError,
+ messageType: MessageType,
+ commandName?: RequestCommand | IncomingRequestCommand,
+ params: RequestParams = {
+ skipBufferingOnError: false,
+ triggerMessage: false,
+ }
+ ): Promise<ResponseType> {
+ if (
+ (chargingStation.isInUnknownState() && commandName === RequestCommand.BOOT_NOTIFICATION) ||
+ (!chargingStation.getOcppStrictCompliance() && chargingStation.isInUnknownState()) ||
+ chargingStation.isInAcceptedState() ||
+ (chargingStation.isInPendingState() &&
+ (params.triggerMessage || messageType === MessageType.CALL_RESULT_MESSAGE))
+ ) {