Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation issue with strictMode and the multipleOf keyword in Ajv when using decimal numbers #50

Closed
Nextdrive-IanChiu opened this issue Jul 13, 2023 · 5 comments
Labels
bug Something isn't working

Comments

@Nextdrive-IanChiu
Copy link

Nextdrive-IanChiu commented Jul 13, 2023

Hi,

I noticed that there is a validation issue with the strictMode and multipleOf keyword in Ajv when using decimal numbers. When I receive a certain PDU of GetCompositeSchedule.conf, I encounter an error message stating "data/chargingSchedule/chargingSchedulePeriod/0/limit must be a multiple of 0.1". This occurs because the value of the limit (9.1) is not considered a multiple of 0.1 due to a precision issue in JavaScript where 9.1/0.1 is equal to 90.99999999999999.

// example PDU of GetCompositeSchedule.conf
{
  "status":"Accepted",
  "connectorId":0,
  "scheduleStart":"2023-07-13T07:36:10Z",
  "chargingSchedule":{
    "duration":300,
    "startSchedule":"2023-07-13T07:36:10Z",
    "chargingRateUnit":"A",
    "chargingSchedulePeriod":[{
      "startPeriod":0,
      "limit":9.1,
      "numberPhases":3
    }]
  }
}

I understand that this is an issue with Ajv. However, I was wondering if we could implement a temporary workaround for this problem until Ajv addresses it. One possible solution could be to modify the Ajv configuration by removing the default "multipleOf" keyword and adding a custom implementation that handles decimal numbers using the "number-precision" library.

Here's an example of how we could modify the Ajv configuration:

import Ajv from "ajv";
import NP from "number-precision";

const ajv = new Ajv();
// remove default keyword: multipleOf
ajv.removeKeyword("multipleOf");

ajv.addKeyword({
    keyword: "multipleOf",
    type: "number",
    compile(schema) {
        return (data) => Number.isInteger(NP.divide(data, schema));
    },
    errors: false,
    metaSchema: {
        type: "number",
    },
});

const schema = {
	type: "object",
	properties: {
		price: { type: "number", minimum: 0, multipleOf: 0.01 },
	},
	required: ["price"],
	additionalProperties: false,
};

const data = {price: 2.22}

ajv-validator/ajv#652 (comment)

By implementing this workaround, we can handle decimal numbers more accurately in validation process.

Let me know if you have any further questions or if there's anything else I can assist you with.

@Nextdrive-IanChiu
Copy link
Author

Update:

Perhaps we could use multipleOfPercision instead.
https://ajv.js.org/options.html#multipleofprecision

@mikuso
Copy link
Owner

mikuso commented Jul 13, 2023

Hi @Nextdrive-IanChiu

Thanks for the report.

I will put together some test cases and see if either of these options fix the issue.

Leave it with me 👍

@mikuso mikuso added the bug Something isn't working label Jul 13, 2023
@mikuso
Copy link
Owner

mikuso commented Jul 13, 2023

Thank you for the detailed description of the problem and the suggested fixes.

I settled on a solution that was a combination of both of these ideas.

Rather than add multipleOfPrecision to the schemas, I thought it best to simply re-implement the ajv multipleOf keyword to use a presumed default multipleOfPrecision value of 6 (borrowing the implementation of this from the ajv libarary). Perhaps this might need to be revisited later, but it seems like it should be sane enough for most use cases for the time being.

Fixed in 55a85b9. Version 2.0.1 published to npm.

@mikuso mikuso closed this as completed Jul 13, 2023
@Nextdrive-IanChiu
Copy link
Author

Hi @mikuso

Thanks a ton for getting back to me so quickly and fixing the issue. I gave version 2.0.1 a try, and I'm happy to report that the problem with Ajv's precision has been sorted out. Awesome!

I just wanted to drop a quick note to express my gratitude for not only resolving the issue but also for creating such an amazing library that makes implementing OCPP-related features a piece of cake.

@mikuso
Copy link
Owner

mikuso commented Jul 14, 2023

Thanks for the kind words. Much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants