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

jsonschema.exceptions.ValidationError: 'Hz' #1576

Open
KoalaWerewolf opened this issue Mar 12, 2025 · 4 comments
Open

jsonschema.exceptions.ValidationError: 'Hz' #1576

KoalaWerewolf opened this issue Mar 12, 2025 · 4 comments

Comments

@KoalaWerewolf
Copy link

Describe the bug
Chargepoint communication seems to fail due to a validation error.

I'm connecting my ChargeAmps Halo to Home Assistant using OCPP. I know it's not listed as one of the tested chargers but it looks promising overall. I've configured the charger, the measurands appear, the Diagnostic sensors report sensible values.

I've connected my car to see if I can get other values and see how I can control the charger. During this testing I've come up against a ValidationError.

To Reproduce
Connect a ChargeAmps Halo charger.

Expected behavior
Working communication and sensors reporting correct values.

** Versions **

  • OCPP 0.8.4
  • HAOS 2025.3.2

Additional context
Logger: ocpp
Source: /usr/local/lib/python3.13/site-packages/ocpp/charge_point.py:274
First occurred: 13:35:37 (15 occurrences)
Last logged: 13:54:12

Error while handling request '<Call - unique_id=265468940-1621710057-682692942, action=MeterValues, payload={'connectorId': 1, 'transactionId': 1741782933, 'meterValue': [{'timestamp': '2025-03-12T12:37:37Z', 'sampledValue': [{'value': '14', 'context': 'Sample.Periodic', 'measurand': 'Temperature', 'unit': 'Celsius'}, {'value': '49.97', 'context': 'Sample.Periodic', 'measurand': 'Frequency', 'unit': 'Hz'}, {'value': '10', 'context': 'Sample.Periodic', 'measurand': 'Energy.Active.Import.Register', 'unit': 'Wh'}, {'value': '16.0', 'context': 'Sample.Periodic', 'measurand': 'Current.Offered', 'unit': 'A'}, {'value': '262.56', 'context': 'Sample.Periodic', 'measurand': 'Power.Active.Import', 'unit': 'W'}, {'value': '1.379', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L1', 'unit': 'A'}, {'value': '234.09', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L1', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L2', 'unit': 'A'}, {'value': '234.66', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L2', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L3', 'unit': 'A'}, {'value': '235.83', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L3', 'unit': 'V'}]}]}>'
Error while handling request '<Call - unique_id=1089303919-1647867889-10146282, action=MeterValues, payload={'connectorId': 1, 'transactionId': 1741782933, 'meterValue': [{'timestamp': '2025-03-12T12:37:37Z', 'sampledValue': [{'value': '14', 'context': 'Sample.Periodic', 'measurand': 'Temperature', 'unit': 'Celsius'}, {'value': '49.97', 'context': 'Sample.Periodic', 'measurand': 'Frequency', 'unit': 'Hz'}, {'value': '10', 'context': 'Sample.Periodic', 'measurand': 'Energy.Active.Import.Register', 'unit': 'Wh'}, {'value': '16.0', 'context': 'Sample.Periodic', 'measurand': 'Current.Offered', 'unit': 'A'}, {'value': '262.56', 'context': 'Sample.Periodic', 'measurand': 'Power.Active.Import', 'unit': 'W'}, {'value': '1.379', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L1', 'unit': 'A'}, {'value': '234.09', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L1', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L2', 'unit': 'A'}, {'value': '234.66', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L2', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L3', 'unit': 'A'}, {'value': '235.83', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L3', 'unit': 'V'}]}]}>'
Error while handling request '<Call - unique_id=1394007239-761799734-28452108, action=MeterValues, payload={'connectorId': 1, 'transactionId': 1741782933, 'meterValue': [{'timestamp': '2025-03-12T12:38:37Z', 'sampledValue': [{'value': '14', 'context': 'Sample.Periodic', 'measurand': 'Temperature', 'unit': 'Celsius'}, {'value': '49.99', 'context': 'Sample.Periodic', 'measurand': 'Frequency', 'unit': 'Hz'}, {'value': '11', 'context': 'Sample.Periodic', 'measurand': 'Energy.Active.Import.Register', 'unit': 'Wh'}, {'value': '16.0', 'context': 'Sample.Periodic', 'measurand': 'Current.Offered', 'unit': 'A'}, {'value': '2.29', 'context': 'Sample.Periodic', 'measurand': 'Power.Active.Import', 'unit': 'W'}, {'value': '0.460', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L1', 'unit': 'A'}, {'value': '234.73', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L1', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L2', 'unit': 'A'}, {'value': '234.99', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L2', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L3', 'unit': 'A'}, {'value': '237.71', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L3', 'unit': 'V'}]}]}>'
Error while handling request '<Call - unique_id=1248899787-1482653785-20610958, action=MeterValues, payload={'connectorId': 1, 'transactionId': 1741782933, 'meterValue': [{'timestamp': '2025-03-12T12:38:37Z', 'sampledValue': [{'value': '14', 'context': 'Sample.Periodic', 'measurand': 'Temperature', 'unit': 'Celsius'}, {'value': '49.99', 'context': 'Sample.Periodic', 'measurand': 'Frequency', 'unit': 'Hz'}, {'value': '11', 'context': 'Sample.Periodic', 'measurand': 'Energy.Active.Import.Register', 'unit': 'Wh'}, {'value': '16.0', 'context': 'Sample.Periodic', 'measurand': 'Current.Offered', 'unit': 'A'}, {'value': '2.29', 'context': 'Sample.Periodic', 'measurand': 'Power.Active.Import', 'unit': 'W'}, {'value': '0.460', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L1', 'unit': 'A'}, {'value': '234.73', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L1', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L2', 'unit': 'A'}, {'value': '234.99', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L2', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L3', 'unit': 'A'}, {'value': '237.71', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L3', 'unit': 'V'}]}]}>'
Error while handling request '<Call - unique_id=389571790-1074765951-172066813, action=MeterValues, payload={'connectorId': 1, 'transactionId': 1741782933, 'meterValue': [{'timestamp': '2025-03-12T12:38:37Z', 'sampledValue': [{'value': '14', 'context': 'Sample.Periodic', 'measurand': 'Temperature', 'unit': 'Celsius'}, {'value': '49.99', 'context': 'Sample.Periodic', 'measurand': 'Frequency', 'unit': 'Hz'}, {'value': '11', 'context': 'Sample.Periodic', 'measurand': 'Energy.Active.Import.Register', 'unit': 'Wh'}, {'value': '16.0', 'context': 'Sample.Periodic', 'measurand': 'Current.Offered', 'unit': 'A'}, {'value': '2.29', 'context': 'Sample.Periodic', 'measurand': 'Power.Active.Import', 'unit': 'W'}, {'value': '0.460', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L1', 'unit': 'A'}, {'value': '234.73', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L1', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L2', 'unit': 'A'}, {'value': '234.99', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L2', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L3', 'unit': 'A'}, {'value': '237.71', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L3', 'unit': 'V'}]}]}>'
Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/ocpp/messages.py", line 239, in _validate_payload
validator.validate(message.payload)
~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.13/site-packages/jsonschema/validators.py", line 451, in validate
raise error
jsonschema.exceptions.ValidationError: 'Hz' is not one of ['Wh', 'kWh', 'varh', 'kvarh', 'W', 'kW', 'VA', 'kVA', 'var', 'kvar', 'A', 'V', 'K', 'Celcius', 'Celsius', 'Fahrenheit', 'Percent', 'Hertz']

Failed validating 'enum' in schema['properties']['meterValue']['items']['properties']['sampledValue']['items']['properties']['unit']:
{'type': 'string',
'additionalProperties': False,
'enum': ['Wh',
'kWh',
'varh',
'kvarh',
'W',
'kW',
'VA',
'kVA',
'var',
'kvar',
'A',
'V',
'K',
'Celcius',
'Celsius',
'Fahrenheit',
'Percent',
'Hertz']}

On instance['meterValue'][0]['sampledValue'][1]['unit']:
'Hz'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 272, in route_message
await self._handle_call(msg)
File "/config/custom_components/ocpp/chargepoint.py", line 396, in _handle_call
await super()._handle_call(msg)
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 300, in _handle_call
await validate_payload(msg, self._ocpp_version)
File "/usr/local/lib/python3.13/site-packages/ocpp/messages.py", line 179, in validate_payload
await asyncio.get_event_loop().run_in_executor(
None, _validate_payload, message, ocpp_version
)
File "/usr/local/lib/python3.13/concurrent/futures/thread.py", line 59, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.13/site-packages/ocpp/messages.py", line 257, in _validate_payload
raise FormatViolationError(
...<5 lines>...
)
ocpp.exceptions.FormatViolationError: FormatViolationError: Payload for Action is syntactically incorrect or structure for Action, {'cause': "Payload '{'connectorId': 1, 'transactionId': 1741782933, 'meterValue': [{'timestamp': '2025-03-12T12:35:37Z', 'sampledValue': [{'value': '14', 'context': 'Sample.Periodic', 'measurand': 'Temperature', 'unit': 'Celsius'}, {'value': '49.97', 'context': 'Sample.Periodic', 'measurand': 'Frequency', 'unit': 'Hz'}, {'value': '0', 'context': 'Sample.Periodic', 'measurand': 'Energy.Active.Import.Register', 'unit': 'Wh'}, {'value': '16.0', 'context': 'Sample.Periodic', 'measurand': 'Current.Offered', 'unit': 'A'}, {'value': '2.37', 'context': 'Sample.Periodic', 'measurand': 'Power.Active.Import', 'unit': 'W'}, {'value': '0.460', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L1', 'unit': 'A'}, {'value': '234.93', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L1', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L2', 'unit': 'A'}, {'value': '235.04', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L2', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L3', 'unit': 'A'}, {'value': '236.30', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L3', 'unit': 'V'}]}]}' for action 'MeterValues' is not valid: 'Hz' is not one of ['Wh', 'kWh', 'varh', 'kvarh', 'W', 'kW', 'VA', 'kVA', 'var', 'kvar', 'A', 'V', 'K', 'Celcius', 'Celsius', 'Fahrenheit', 'Percent', 'Hertz']\n\nFailed validating 'enum' in schema['properties']['meterValue']['items']['properties']['sampledValue']['items']['properties']['unit']:\n {'type': 'string',\n 'additionalProperties': False,\n 'enum': ['Wh',\n 'kWh',\n 'varh',\n 'kvarh',\n 'W',\n 'kW',\n 'VA',\n 'kVA',\n 'var',\n 'kvar',\n 'A',\n 'V',\n 'K',\n 'Celcius',\n 'Celsius',\n 'Fahrenheit',\n 'Percent',\n 'Hertz']}\n\nOn instance['meterValue'][0]['sampledValue'][1]['unit']:\n 'Hz'", 'ocpp_message': <Call - unique_id=1388909911-1037070112-12868847, action=MeterValues, payload={'connectorId': 1, 'transactionId': 1741782933, 'meterValue': [{'timestamp': '2025-03-12T12:35:37Z', 'sampledValue': [{'value': '14', 'context': 'Sample.Periodic', 'measurand': 'Temperature', 'unit': 'Celsius'}, {'value': '49.97', 'context': 'Sample.Periodic', 'measurand': 'Frequency', 'unit': 'Hz'}, {'value': '0', 'context': 'Sample.Periodic', 'measurand': 'Energy.Active.Import.Register', 'unit': 'Wh'}, {'value': '16.0', 'context': 'Sample.Periodic', 'measurand': 'Current.Offered', 'unit': 'A'}, {'value': '2.37', 'context': 'Sample.Periodic', 'measurand': 'Power.Active.Import', 'unit': 'W'}, {'value': '0.460', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L1', 'unit': 'A'}, {'value': '234.93', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L1', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L2', 'unit': 'A'}, {'value': '235.04', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L2', 'unit': 'V'}, {'value': '0.000', 'context': 'Sample.Periodic', 'measurand': 'Current.Import', 'phase': 'L3', 'unit': 'A'}, {'value': '236.30', 'context': 'Sample.Periodic', 'measurand': 'Voltage', 'phase': 'L3', 'unit': 'V'}]}]}>}

@BJReplay
Copy link
Contributor

The charger should be sending Hertz, not Hz.

This is a bug in the charger's implementation.

You can work around it by checking the "Skip OCPP schema validation" Checkbox when you set up the charger. You would need to remove it and add it again to change this.

@KoalaWerewolf
Copy link
Author

The charger should be sending Hertz, not Hz.

This is a bug in the charger's implementation.

You can work around it by checking the "Skip OCPP schema validation" Checkbox when you set up the charger. You would need to remove it and add it again to change this.

Understood. However, considering the values in the enum that it validates against, Hz seems like a perfectly reasonable value. Making sure that the most used string representation for the unit for frequency does not throw an error would probably be a good thing.

@drc38
Copy link
Collaborator

drc38 commented Mar 13, 2025

You can propose adding to the upstream library:
https://github.com/mobilityhouse/ocpp

@BJReplay
Copy link
Contributor

Hz seems like a perfectly reasonable value.

Yes, it does. But you could argue that kilowatt and kiloWatt also seem perfectly reasonable - and they do.

% seems reasonable, instead of Percent

But there is a standard, and it is explicit on what UOMs are acceptable.

It is a optional element in the specification, but if supplied, must be one of the values from the spec.

Remember, the charger needs to operate with every OCPP central system if it wants to a) be compliant and b) grow market share.

I would be surprised if the charger manufacturer would not change the UOM once made aware of the error.

The spec https://groups.oasis-open.org/higherlogic/ws/public/download/58944/ocpp-1.6.pdf/latest specifies this at 7.45.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants