logger.error(
`${this.logPrefix()} Charging profile id ${
matchingChargingProfile.chargingProfileId
- } limit is greater than connector id ${connectorId} maximum, dump charging profiles' stack: %j`,
+ } limit ${limit} is greater than connector id ${connectorId} maximum ${connectorMaximumPower}, dump charging profiles' stack: %j`,
this.getConnectorStatus(connectorId).chargingProfiles
);
limit = connectorMaximumPower;
commandName: OCPP16IncomingRequestCommand,
commandPayload: JsonType
): boolean {
- if (this.jsonSchemas.has(commandName)) {
+ if (this.jsonSchemas.has(commandName) === true) {
return this.validateIncomingRequestPayload(
chargingStation,
commandName,
],
]);
this.buildRequestPayload.bind(this);
- this.validatePayload.bind(this);
}
public async requestHandler<RequestType extends JsonType, ResponseType extends JsonType>(
commandName,
commandParams
);
- this.validatePayload(chargingStation, commandName, requestPayload);
return (await this.sendMessage(
chargingStation,
Utils.generateUUID(),
);
}
+ protected getRequestPayloadValidationSchema(
+ chargingStation: ChargingStation,
+ commandName: OCPP16RequestCommand
+ ): JSONSchemaType<JsonObject> | false {
+ if (this.jsonSchemas.has(commandName) === true) {
+ return this.jsonSchemas.get(commandName);
+ }
+ logger.warn(
+ `${chargingStation.logPrefix()} ${moduleName}.getPayloadValidationSchema: No JSON schema found for command ${commandName} PDU validation`
+ );
+ return false;
+ }
+
private buildRequestPayload<Request extends JsonType>(
chargingStation: ChargingStation,
commandName: OCPP16RequestCommand,
);
}
}
-
- private validatePayload<Request extends JsonType>(
- chargingStation: ChargingStation,
- commandName: OCPP16RequestCommand,
- requestPayload: Request
- ): boolean {
- if (this.jsonSchemas.has(commandName)) {
- return this.validateRequestPayload(
- chargingStation,
- commandName,
- this.jsonSchemas.get(commandName),
- requestPayload
- );
- }
- logger.warn(
- `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command ${commandName} PDU validation`
- );
- return false;
- }
}
commandName: OCPP16RequestCommand,
payload: JsonType
): boolean {
- if (this.jsonSchemas.has(commandName)) {
+ if (this.jsonSchemas.has(commandName) === true) {
return this.validateResponsePayload(
chargingStation,
commandName,
commandName: OCPP20IncomingRequestCommand,
commandPayload: JsonType
): boolean {
- if (this.jsonSchemas.has(commandName)) {
+ if (this.jsonSchemas.has(commandName) === true) {
return this.validateIncomingRequestPayload(
chargingStation,
commandName,
],
]);
this.buildRequestPayload.bind(this);
- this.validatePayload.bind(this);
}
public async requestHandler<RequestType extends JsonType, ResponseType extends JsonType>(
commandName,
commandParams
);
- this.validatePayload(chargingStation, commandName, requestPayload);
return (await this.sendMessage(
chargingStation,
Utils.generateUUID(),
);
}
+ protected getRequestPayloadValidationSchema(
+ chargingStation: ChargingStation,
+ commandName: OCPP20RequestCommand
+ ): JSONSchemaType<JsonObject> | false {
+ if (this.jsonSchemas.has(commandName) === true) {
+ return this.jsonSchemas.get(commandName);
+ }
+ logger.warn(
+ `${chargingStation.logPrefix()} ${moduleName}.getPayloadValidationSchema: No JSON schema found for command ${commandName} PDU validation`
+ );
+ return false;
+ }
+
private buildRequestPayload<Request extends JsonType>(
chargingStation: ChargingStation,
commandName: OCPP20RequestCommand,
);
}
}
-
- private validatePayload<Request extends JsonType>(
- chargingStation: ChargingStation,
- commandName: OCPP20RequestCommand,
- requestPayload: Request
- ): boolean {
- if (this.jsonSchemas.has(commandName)) {
- return this.validateRequestPayload(
- chargingStation,
- commandName,
- this.jsonSchemas.get(commandName),
- requestPayload
- );
- }
- logger.warn(
- `${chargingStation.logPrefix()} ${moduleName}.validatePayload: No JSON schema found for command ${commandName} PDU validation`
- );
- return false;
- }
}
commandName: OCPP20RequestCommand,
payload: JsonType
): boolean {
- if (this.jsonSchemas.has(commandName)) {
+ if (this.jsonSchemas.has(commandName) === true) {
return this.validateResponsePayload(
chargingStation,
commandName,
protected constructor(version: OCPPVersion) {
this.version = version;
- this.ajv = new Ajv();
+ this.ajv = new Ajv({
+ multipleOfPrecision: 2,
+ });
ajvFormats(this.ajv);
this.asyncResource = new AsyncResource(moduleName);
this.incomingRequestHandler.bind(this);
return true;
}
logger.error(
- `${chargingStation.logPrefix()} ${moduleName}.validateIncomingRequestPayload: Incoming request PDU is invalid: %j`,
+ `${chargingStation.logPrefix()} ${moduleName}.validateIncomingRequestPayload: Command '${commandName}' incoming request PDU is invalid: %j`,
validate.errors
);
throw new OCPPError(
protected constructor(version: OCPPVersion, ocppResponseService: OCPPResponseService) {
this.version = version;
- this.ajv = new Ajv();
+ this.ajv = new Ajv({
+ multipleOfPrecision: 2,
+ });
ajvFormats(this.ajv);
this.ocppResponseService = ocppResponseService;
this.requestHandler.bind(this);
protected validateRequestPayload<T extends JsonType>(
chargingStation: ChargingStation,
- commandName: RequestCommand,
- schema: JSONSchemaType<T>,
+ commandName: RequestCommand | IncomingRequestCommand,
payload: T
): boolean {
if (chargingStation.getPayloadSchemaValidation() === false) {
return true;
}
+ const schema = this.getRequestPayloadValidationSchema(chargingStation, commandName);
+ if (schema === false) {
+ return true;
+ }
const validate = this.ajv.compile(schema);
+ this.convertDateToISOString<T>(payload);
if (validate(payload)) {
return true;
}
logger.error(
- `${chargingStation.logPrefix()} ${moduleName}.validateRequestPayload: Request PDU is invalid: %j`,
+ `${chargingStation.logPrefix()} ${moduleName}.validateRequestPayload: Command '${commandName}' request PDU is invalid: %j`,
validate.errors
);
// OCPPError usage here is debatable: it's an error in the OCPP stack but not targeted to sendError().
commandName,
messagePayload as JsonType,
]);
+ this.validateRequestPayload(chargingStation, commandName, messagePayload as JsonType);
messageToSend = JSON.stringify([
messageType,
messageId,
// Response
case MessageType.CALL_RESULT_MESSAGE:
// Build response
+ // FIXME: Validate response payload
messageToSend = JSON.stringify([messageType, messageId, messagePayload] as Response);
break;
// Error Message
}
}
+ private convertDateToISOString<T extends JsonType>(obj: T): void {
+ for (const k in obj) {
+ if (obj[k] instanceof Date) {
+ (obj as JsonObject)[k] = (obj[k] as Date).toISOString();
+ } else if (obj[k] !== null && typeof obj[k] === 'object') {
+ this.convertDateToISOString<T>(obj[k] as T);
+ }
+ }
+ }
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public abstract requestHandler<ReqType extends JsonType, ResType extends JsonType>(
chargingStation: ChargingStation,
commandParams?: JsonType,
params?: RequestParams
): Promise<ResType>;
+
+ protected abstract getRequestPayloadValidationSchema(
+ chargingStation: ChargingStation,
+ commandName: RequestCommand | IncomingRequestCommand
+ ): JSONSchemaType<JsonObject> | false;
}
protected constructor(version: OCPPVersion) {
this.version = version;
- this.ajv = new Ajv();
+ this.ajv = new Ajv({
+ multipleOfPrecision: 2,
+ });
ajvFormats(this.ajv);
this.responseHandler.bind(this);
this.validateResponsePayload.bind(this);
return true;
}
logger.error(
- `${chargingStation.logPrefix()} ${moduleName}.validateResponsePayload: Response PDU is invalid: %j`,
+ `${chargingStation.logPrefix()} ${moduleName}.validateResponsePayload: Command '${commandName}' response PDU is invalid: %j`,
validate.errors
);
throw new OCPPError(