ocpp icon indicating copy to clipboard operation
ocpp copied to clipboard

Grizzl-e Smart v2 support

Open mkbrown opened this issue 1 year ago • 103 comments

Describe the bug

Grizzl-e Smart v2 does not work with the OCPP integration version 0.4.40

Firmware WiFi Module: GWM-07.013-03

Firmware Power Board: GCW-10.18-05.7

To Reproduce

Upon configuring the Grizzl-e, it connects and has the following errors in the HA logs:


This error originated from a custom integration.

Logger: custom_components.ocpp
Source: custom_components/ocpp/api.py:212 
Integration: Open Charge Point Protocol (OCPP) (documentation, issues)
First occurred: September 7, 2023 at 5:42:35 PM (9 occurrences) 
Last logged: 9:29:52 AM

Skipping websocket subprotocol validation


This error originated from a custom integration.

Logger: custom_components.ocpp
Source: custom_components/ocpp/api.py:865 
Integration: Open Charge Point Protocol (OCPP) (documentation, issues) 
First occurred: September 7, 2023 at 5:42:46 PM (8 occurrences) 
Last logged: 9:29:54 AM

Unexpected exception in connection to ‘GRS-170000xxxx’: ‘(“Error code ‘%s’ is not defined by the OCPP specification”, ‘FormationViolation’)’
Traceback (most recent call last):
  File “/config/custom_components/ocpp/api.py”, line 930, in run
    await asyncio.gather(*self.tasks)
  File “/config/custom_components/ocpp/api.py”, line 421, in post_connect
    await self.get_supported_features()
  File “/config/custom_components/ocpp/api.py”, line 495, in get_supported_features
    resp = await self.call(req)
           ^^^^^^^^^^^^^^^^^^^^
  File “/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py”, line 281, in call
    response = await self._get_specific_response(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File “/config/custom_components/ocpp/api.py”, line 865, in _get_specific_response
    raise resp.to_exception()
          ^^^^^^^^^^^^^^^^^^^
  File “/usr/local/lib/python3.11/site-packages/ocpp/messages.py”, line 439, in to_exception
    raise UnknownCallErrorCodeError(
ocpp.exceptions.UnknownCallErrorCodeError: (“Error code ‘%s’ is not defined by the OCPP specification”, ‘FormationViolation’)


This error originated from a custom integration.

Logger: homeassistant
Source: custom_components/ocpp/api.py:495 
Integration: Open Charge Point Protocol (OCPP) (documentation, issues) 
First occurred: September 7, 2023 at 5:43:16 PM (7 occurrences) 
Last logged: 9:30:24 AM

Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File “/usr/local/lib/python3.11/asyncio/tasks.py”, line 490, in wait_for
    return fut.result()
           ^^^^^^^^^^^^
  File “/usr/local/lib/python3.11/asyncio/queues.py”, line 158, in get
    await getter
asyncio.exceptions.CancelledError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File “/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py”, line 281, in call
    response = await self._get_specific_response(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File “/config/custom_components/ocpp/api.py”, line 862, in _get_specific_response
    resp = await super()._get_specific_response(unique_id, timeout)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File “/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py”, line 315, in _get_specific_response
    response = await asyncio.wait_for(self._response_queue.get(), timeout)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File “/usr/local/lib/python3.11/asyncio/tasks.py”, line 492, in wait_for
    raise exceptions.TimeoutError() from exc
TimeoutError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File “/config/custom_components/ocpp/api.py”, line 421, in post_connect
    await self.get_supported_features()
  File “/config/custom_components/ocpp/api.py”, line 495, in get_supported_features
    resp = await self.call(req)
           ^^^^^^^^^^^^^^^^^^^^
  File “/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py”, line 285, in call
    raise asyncio.TimeoutError(
TimeoutError: Waited 30s for response on [2,”ce60af0b-a978-47ef-a458-e01567d40ff6”,”GetConfiguration”,{“key”:[“SupportedFeatureProfiles”]}].

Additional context

With websockets debug added.


2023-09-08 15:34:07.476 INFO (MainThread) [ocpp] GRS-170000xxxxx: send [2,"13236754-38b2-424a-a4e3-0f54eeffaf3a","GetConfiguration",{"key":["SupportedFeatureProfiles"]}]
2023-09-08 15:34:07.477 DEBUG (MainThread) [websockets.server] > TEXT '[2,"13236754-38b2-424a-a4e3-0f54eeffaf3a","GetC...rtedFeatureProfiles"]}]' [98 bytes]
2023-09-08 15:34:07.662 DEBUG (MainThread) [websockets.server] < TEXT '[4, "13236754-38b2-424a-a4e3-0f54eeffaf3a", "FormationViolation", ""]' [69 bytes]
2023-09-08 15:34:07.663 INFO (MainThread) [ocpp] GRS-170000xxxxx: receive message [4, "13236754-38b2-424a-a4e3-0f54eeffaf3a", "FormationViolation", ""]
2023-09-08 15:34:07.663 INFO (MainThread) [ocpp] GRS-170000xxxxx: send [2,"aedabe09-d6ed-4f95-9dc2-e9186be0a005","GetConfiguration",{"key":["SupportedFeatureProfiles"]}]
2023-09-08 15:34:07.663 DEBUG (MainThread) [websockets.server] > TEXT '[2,"aedabe09-d6ed-4f95-9dc2-e9186be0a005","GetC...rtedFeatureProfiles"]}]' [98 bytes]
2023-09-08 15:34:07.664 ERROR (MainThread) [custom_components.ocpp] Unexpected exception in connection to 'GRS-170000xxxx': '("Error code '%s' is not defined by the OCPP specification", 'FormationViolation')'
Traceback (most recent call last):
File "/config/custom_components/ocpp/api.py", line 930, in run
await asyncio.gather(*self.tasks)
File "/config/custom_components/ocpp/api.py", line 421, in post_connect
await self.get_supported_features()
File "/config/custom_components/ocpp/api.py", line 495, in get_supported_features
resp = await self.call(req)
^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py", line 281, in call
response = await self._get_specific_response(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/ocpp/api.py", line 865, in _get_specific_response
raise resp.to_exception()
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/ocpp/messages.py", line 439, in to_exception
raise UnknownCallErrorCodeError(
ocpp.exceptions.UnknownCallErrorCodeError: ("Error code '%s' is not defined by the OCPP specification", 'FormationViolation')
2023-09-08 15:34:07.668 DEBUG (MainThread) [custom_components.ocpp] Closing websocket to 'GRS-170000xxxxx'
2023-09-08 15:34:07.668 DEBUG (MainThread) [websockets.server] = connection is CLOSING
2023-09-08 15:34:07.668 DEBUG (MainThread) [websockets.server] > CLOSE 1000 (OK) [2 bytes]
2023-09-08 15:34:07.813 DEBUG (MainThread) [websockets.server] < TEXT '[4, "aedabe09-d6ed-4f95-9dc2-e9186be0a005", "FormationViolation", ""]' [69 bytes]
2023-09-08 15:34:07.813 DEBUG (MainThread) [websockets.server] < CLOSE 1005 (no status code [internal]) [0 bytes]
2023-09-08 15:34:07.813 DEBUG (MainThread) [websockets.server] x half-closing TCP connection
2023-09-08 15:34:07.813 INFO (MainThread) [ocpp] GRS-170000xxxxx: receive message [4, "aedabe09-d6ed-4f95-9dc2-e9186be0a005", "FormationViolation", ""]
2023-09-08 15:34:07.814 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File "/config/custom_components/ocpp/api.py", line 421, in post_connect
await self.get_supported_features()
File "/config/custom_components/ocpp/api.py", line 495, in get_supported_features
resp = await self.call(req)

^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py", line 281, in call
response = await self._get_specific_response(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/ocpp/api.py", line 865, in _get_specific_response
raise resp.to_exception()
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/ocpp/messages.py", line 439, in to_exception
raise UnknownCallErrorCodeError(
ocpp.exceptions.UnknownCallErrorCodeError: ("Error code '%s' is not defined by the OCPP specification", 'FormationViolation')
2023-09-08 15:34:07.668 DEBUG (MainThread) [custom_components.ocpp] Closing websocket to 'GRS-170000xxxxx'
2023-09-08 15:34:07.668 DEBUG (MainThread) [websockets.server] = connection is CLOSING
2023-09-08 15:34:07.668 DEBUG (MainThread) [websockets.server] > CLOSE 1000 (OK) [2 bytes]
2023-09-08 15:34:07.813 DEBUG (MainThread) [websockets.server] < TEXT '[4, "aedabe09-d6ed-4f95-9dc2-e9186be0a005", "FormationViolation", ""]' [69 bytes]
2023-09-08 15:34:07.813 DEBUG (MainThread) [websockets.server] < CLOSE 1005 (no status code [internal]) [0 bytes]
2023-09-08 15:34:07.813 DEBUG (MainThread) [websockets.server] x half-closing TCP connection
2023-09-08 15:34:07.813 INFO (MainThread) [ocpp] GRS-170000xxxxx: receive message [4, "aedabe09-d6ed-4f95-9dc2-e9186be0a005", "FormationViolation", ""]
2023-09-08 15:34:07.814 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File "/config/custom_components/ocpp/api.py", line 421, in post_connect
await self.get_supported_features()
File "/config/custom_components/ocpp/api.py", line 495, in get_supported_features
resp = await self.call(req)
^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py", line 281, in call
response = await self._get_specific_response(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/ocpp/api.py", line 865, in _get_specific_response
raise resp.to_exception()
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/ocpp/messages.py", line 439, in to_exception
raise UnknownCallErrorCodeError(
ocpp.exceptions.UnknownCallErrorCodeError: ("Error code '%s' is not defined by the OCPP specification", 'FormationViolation')
2023-09-08 15:34:07.832 DEBUG (MainThread) [websockets.server] = connection is CLOSED
2023-09-08 15:34:07.833 INFO (MainThread) [custom_components.ocpp] Charger GRS-170000xxxxx disconnected from 172.20.21.150:9000.
2023-09-08 15:34:07.834 INFO (MainThread) [websockets.server] connection closed

mkbrown avatar Sep 08 '23 20:09 mkbrown

Chargers web page for online/offline status, WIFI configuration and optionally the OCPP connection. Online means connected to WIFI AND connected to an OCPP server. The default is their https://connect.unitedchargers.com/ service

IMG_1364

OCPP configuration page, basically the server, auth key and station ID (defaults to serial number) IMG_1365

mkbrown avatar Sep 08 '23 20:09 mkbrown

The config flow gets the firmware version, but all sensors are unavailable due to not getting the supported profiles. The charger won’t work in this state, as the flashing yellow light indicates that the charger has limits being applied (due to lack of supported profiles). When setting it up, I did tick off skip validation and force configuration profiles (going from memory).

IMG_1366

mkbrown avatar Sep 08 '23 20:09 mkbrown

I'm not an expert in deciphering these logs but I'm curious to better understand the issue. I don't have a v2 unit (yet).

The log does indicate "Skipping websocket subprotocol validation" which seems to be required for all versions of the firmware. It appears that the OCPP integration is attempting to query the feature profile. For some reason the EVSE is responding that is doesn't like the format of the request (FormationViolation). I recall reading that in at least some version of the firmware they only support the Core profile. I don't know about the force profile setting but could that be causing a problem?

The description for FormationViolation violation: Payload for Action is syntactically incorrect or not conform the PDU structure for Action. This is only valid for OCPP 1.6.

Is there a second request made that returns garbage (EVSE in a bad state?), or is the OCPP integration just not handling the FormationViolation error gracefully?

Are you able to capture the contents of the 98 byte websocket request (or even the entire transaction) to compare against the OCPP specification or some other working example?

You could try hacking the integration, perhaps by modifying the get_supported_features() function in api.py.

I could try to capture the exchange on my v1 unit to compare.

8jmm3 avatar Sep 09 '23 19:09 8jmm3

Excuse the crude formatting but to follow up my v1 unit performs the following initial exchange (captured with tcpdump -v -X dst grizzle or src grizzle):

16:12:59.761679 IP (tos 0x0, ttl 64, id 25330, offset 0, flags [DF], proto TCP (6), length 140)
    hass.9000 > grizzle.60988: Flags [P.], cksum 0x85e0 (incorrect -> 0x2412), seq 206:306, ack 239, win 64002, length 100
	0x0000:  4500 008c 62f2 4000 4006 5218 c0a8 0006  E...b.@[email protected].....
	0x0010:  c0a8 040b 2328 ee3c 7c2d 13ca a6a7 9192  ....#(.<|-......
	0x0020:  5018 fa02 85e0 0000 8162 5b32 2c22 3730  P........b[2,"70
	0x0030:  6633 6632 3437 2d63 3333 362d 3439 6563  f3f247-c336-49ec
	0x0040:  2d38 6139 632d 6262 3834 6632 3662 3839  -8a9c-bb84f26b89
	0x0050:  3466 222c 2247 6574 436f 6e66 6967 7572  4f","GetConfigur
	0x0060:  6174 696f 6e22 2c7b 226b 6579 223a 5b22  ation",{"key":["
	0x0070:  5375 7070 6f72 7465 6446 6561 7475 7265  SupportedFeature
	0x0080:  5072 6f66 696c 6573 225d 7d5d            Profiles"]}]
16:12:59.831183 IP (tos 0x0, ttl 254, id 507, offset 0, flags [none], proto TCP (6), length 321)
    grizzle.60988 > hass.9000: Flags [P.], cksum 0x2d43 (correct), seq 239:520, ack 306, win 5439, length 281
	0x0000:  4500 0141 01fb 0000 fe06 345a c0a8 040b  E..A......4Z....
	0x0010:  c0a8 0006 ee3c 2328 a6a7 9192 7c2d 142e  .....<#(....|-..
	0x0020:  5018 153f 2d43 0000 81fe 0111 0000 0000  P..?-C..........
	0x0030:  5b33 2c22 3730 6633 6632 3437 2d63 3333  [3,"70f3f247-c33
	0x0040:  362d 3439 6563 2d38 6139 632d 6262 3834  6-49ec-8a9c-bb84
	0x0050:  6632 3662 3839 3466 222c 7b22 636f 6e66  f26b894f",{"conf
	0x0060:  6967 7572 6174 696f 6e4b 6579 223a 5b7b  igurationKey":[{
	0x0070:  226b 6579 223a 2253 7570 706f 7274 6564  "key":"Supported
	0x0080:  4665 6174 7572 6550 726f 6669 6c65 7322  FeatureProfiles"
	0x0090:  2c22 7661 6c75 6522 3a22 436f 7265 2c46  ,"value":"Core,F
	0x00a0:  6972 6d77 6172 654d 616e 6167 656d 656e  irmwareManagemen
	0x00b0:  742c 4c6f 6361 6c41 7574 684c 6973 744d  t,LocalAuthListM
	0x00c0:  616e 6167 656d 656e 742c 5265 7365 7276  anagement,Reserv
	0x00d0:  6174 696f 6e2c 536d 6172 7443 6861 7267  ation,SmartCharg
	0x00e0:  696e 672c 5265 6d6f 7465 5472 6967 6765  ing,RemoteTrigge
	0x00f0:  7222 2c22 7265 6164 6f6e 6c79 223a 7472  r","readonly":tr
	0x0100:  7565 7d2c 7b22 6b65 7922 3a22 5769 4669  ue},{"key":"WiFi
	0x0110:  5369 676e 616c 5374 7265 6e67 7468 222c  SignalStrength",
	0x0120:  2276 616c 7565 223a 222d 3631 222c 2272  "value":"-61","r
	0x0130:  6561 646f 6e6c 7922 3a74 7275 657d 5d7d  eadonly":true}]}
	0x0140:  5d                                       ]

8jmm3 avatar Sep 09 '23 20:09 8jmm3

I have the same error:

I make my WS server to try the command I have the same error.

This what I do (I'm not a programmer)

` import { WebSocketServer } from 'ws';

const wss = new WebSocketServer({ port: 9000 });

wss.on('connection', function connection(ws) { ws.on('message', function message(data) { console.log('received: %s', data); if (data.includes('BootNotification')) { ws.send('[3,"1481766031",{"currentTime":"2023-09-10T09:46:52Z","interval":3600,"status":"Accepted"}]'); } if (data.includes('1481766032')) { ws.send('[3,"1481766032",{}]'); } if (data.includes('1481766033')) { ws.send('[3,"1481766033",{}]'); ws.send('[2,"########-####-####-####-############","GetConfiguration",{"key":["SupportedFeatureProfiles"]}]'); // [2,"########-####-####-####-############","GetConfiguration",{"key":["MeterValueSampleInterval"]}] } });

}); `

And I got: received: [4, "49eab272-b834-45e1-8674-90dee33e5fbd", "FormationViolation", ""]

In de documentation, the server can ask: [2,"0116359a-f5b2-4f6b-af28-b845dd10c138","GetConfiguration",{}]

When I try, the charger return: [3,"########-####-####-####-############",{"configurationKey":[{"key":"MaxCurrent","readonly":true,"value":"32000"},{"key":"MinCurrent","readonly":true,"value":"8000"},{"key":"SetCurrent","readonly":false,"value":"32000"},{"key":"StartChargingAfterConnect","readonly":false,"value":"true"},{"key":"AuthorizeRemoteTxRequests","readonly":true,"value":"true"},{"key":"ConnectorPhaseRotation","readonly":true,"value":"NotApplicable"},{"key":"HeartbeatInterval","readonly":false,"value":"3600"},{"key":"LocalAuthorizeOffline","readonly":true,"value":"true"},{"key":"LocalPreAuthorize","readonly":true,"value":"true"},{"key":"MeterValueSampleInterval","readonly":false,"value":"20"},{"key":"NumberOfConnectors","readonly":true,"value":"1"},{"key":"ResetRetries","readonly":true,"value":"1"},{"key":"StopTransactionOnInvalid","readonly":true,"value":"false"},{"key":"SupportedFeatureProfiles","readonly":true,"value":"Core,FirmwareManagement"},{"key":"UnlockConnectorOnEVSideDisconnect","readonly":true,"value":"false"}]}]

I try with MeterValueSampleInterval, I have the same error. If I try {"key":"SupportedFeatureProfiles"} i got the same thing of [2,"0116359a-f5b2-4f6b-af28-b845dd10c138","GetConfiguration",{}]

djiesr avatar Sep 10 '23 14:09 djiesr

The issue appears to be buggy firmware, you can try getting further diagnostics from the unit. See thread #221 for details on using get_diagnostics.

drc38 avatar Sep 10 '23 19:09 drc38

The issue appears to be buggy firmware, you can try getting further diagnostics from the unit. See thread #221 for details on using get_diagnostics.

The integration doesn’t get to a state where any ocpp service is available in the developer tools services, so get_diagnostics is not present. I’ve enabled asyncio debug as well, and will try to capture a trace with that and websockets, as well as tcpdump.

mkbrown avatar Sep 10 '23 20:09 mkbrown

In post_connect go through and comment out any lines the unit is not accepting and see if you can get to the point the integration loads.

drc38 avatar Sep 10 '23 20:09 drc38

It's possible to patch if I get [2,"0116359a-f5b2-4f6b-af28-b845dd10c138","GetConfiguration",{}] and select SupportedFeatureProfiles from it.

djiesr avatar Sep 10 '23 22:09 djiesr

Ok, so I commented out some stuff from get_supported features and forced the core profile.

IMG_1370

Looks like it’s having issues with NumberOfConnectors

2023-09-10 20:41:08.211 DEBUG (MainThread) [websockets.server] = connection is CONNECTING
2023-09-10 20:41:08.215 DEBUG (MainThread) [websockets.server] < GET /GRS-170000xxxxx HTTP/1.1
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] < Connection: Upgrade
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] < Host: 172.20.21.150:9000
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] < User-Agent: ESP32 Websocket Client
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] < Upgrade: websocket
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] < Sec-WebSocket-Version: 13
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] < Sec-WebSocket-Key: qZP1iJqdMi3Tt+UcdeiyDg==
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] < Sec-WebSocket-Protocol: ocpp1.6
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] < Authorization: Basic R1JTLTE3MDAwMDNjNjgzOg==
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] > HTTP/1.1 101 Switching Protocols
2023-09-10 20:41:08.216 DEBUG (MainThread) [websockets.server] > Upgrade: websocket
2023-09-10 20:41:08.217 DEBUG (MainThread) [websockets.server] > Connection: Upgrade
2023-09-10 20:41:08.217 DEBUG (MainThread) [websockets.server] > Sec-WebSocket-Accept: Qhqjr2rHLkeVqzJpI/gfKL+CaFc=
2023-09-10 20:41:08.217 DEBUG (MainThread) [websockets.server] > Sec-WebSocket-Protocol: ocpp1.6
2023-09-10 20:41:08.217 DEBUG (MainThread) [websockets.server] > Date: Mon, 11 Sep 2023 00:41:08 GMT
2023-09-10 20:41:08.217 DEBUG (MainThread) [websockets.server] > Server: Python/3.11 websockets/11.0.3
2023-09-10 20:41:08.217 INFO (MainThread) [websockets.server] connection open
2023-09-10 20:41:08.217 DEBUG (MainThread) [websockets.server] = connection is OPEN
2023-09-10 20:41:08.217 WARNING (MainThread) [custom_components.ocpp] Skipping websocket subprotocol validation
2023-09-10 20:41:08.220 INFO (MainThread) [custom_components.ocpp] Charger websocket path=/GRS-170000xxxxx
2023-09-10 20:41:08.220 INFO (MainThread) [custom_components.ocpp] Charger GRS-170000xxxxx connected to 172.20.21.150:9000.
2023-09-10 20:41:08.297 DEBUG (MainThread) [websockets.server] < TEXT ‘[2,”1481766072”,”BootNotification”,{“chargePoin...7”,”meterType”:”wifi”}]’ [222 bytes]
2023-09-10 20:41:08.298 INFO (MainThread) [ocpp] GRS-170000xxxxx: receive message [2,”1481766072”,”BootNotification”,{“chargePointModel”:”Grizzl-E Smart”,”chargePointVendor”:”UnitedChargers”,”chargePointSerialNumber”:”GRS-170000xxxxx”,”firmwareVersion”:”GWM-07.013-03_GCW-10.18-05.7”,”meterType”:”wifi”}]
2023-09-10 20:41:08.300 DEBUG (MainThread) [custom_components.ocpp] Received boot notification for GRS-170000xxxxx: {‘charge_point_model’: ‘Grizzl-E Smart’, ‘charge_point_vendor’: ‘UnitedChargers’, ‘charge_point_serial_number’: ‘GRS-170000xxxxx’, ‘firmware_version’: ‘GWM-07.013-03_GCW-10.18-05.7’, ‘meter_type’: ‘wifi’}
2023-09-10 20:41:08.302 INFO (MainThread) [ocpp] GRS-170000xxxxx: send [3,”1481766072”,{“currentTime”:”2023-09-11T00:41:08Z”,”interval”:3600,”status”:”Accepted”}]
2023-09-10 20:41:08.303 DEBUG (MainThread) [websockets.server] > TEXT ‘[3,”1481766072”,{“currentTime”:”2023-09-11T00:4...0,”status”:”Accepted”}]’ [91 bytes]
2023-09-10 20:41:08.303 DEBUG (MainThread) [custom_components.ocpp] Updating device info charger: {‘charge_point_model’: ‘Grizzl-E Smart’, ‘charge_point_vendor’: ‘UnitedChargers’, ‘charge_point_serial_number’: ‘GRS-170000xxxxx’, ‘firmware_version’: ‘GWM-07.013-03_GCW-10.18-05.7’, ‘meter_type’: ‘wifi’}
2023-09-10 20:41:08.398 DEBUG (MainThread) [websockets.server] < TEXT ‘[2,”1481766073”,”StartTransaction”,{“connectorI...0000-00-00T00:00:00Z”}]’ [118 bytes]
2023-09-10 20:41:08.398 INFO (MainThread) [ocpp] GRS-170000xxxxx: receive message [2,”1481766073”,”StartTransaction”,{“connectorId”:0, “idTag”:””, “meterStart”:0, “timestamp”: “0000-00-00T00:00:00Z”}]
2023-09-10 20:41:08.400 DEBUG (MainThread) [custom_components.ocpp] id_tag=‘’ not found in auth_list, default authorization_status=‘Accepted’
2023-09-10 20:41:08.401 INFO (MainThread) [ocpp] GRS-170000xxxxx: send [3,”1481766073”,{“transactionId”:1694392868,”idTagInfo”:{“status”:”Accepted”}}]
2023-09-10 20:41:08.401 DEBUG (MainThread) [websockets.server] > TEXT ‘[3,”1481766073”,{“transactionId”:1694392868,”id...{“status”:”Accepted”}}]’ [79 bytes]
2023-09-10 20:41:09.530 DEBUG (MainThread) [websockets.server] < TEXT ‘[2,”1481766074”,”StatusNotification”,{“connecto...,”status”:”Available”}]’ [98 bytes]
2023-09-10 20:41:09.531 DEBUG (MainThread) [websockets.server] < TEXT ‘[2,”1481766075”,”StatusNotification”,{“connecto...,”status”:”Available”}]’ [98 bytes]
2023-09-10 20:41:09.531 INFO (MainThread) [ocpp] GRS-170000xxxxx: receive message [2,”1481766074”,”StatusNotification”,{“connectorId”:0,”errorCode”:”NoError”,”status”:”Available”}]
2023-09-10 20:41:09.539 INFO (MainThread) [ocpp] GRS-170000xxxxx: send [3,”1481766074”,{}]
2023-09-10 20:41:09.539 DEBUG (MainThread) [websockets.server] > TEXT ‘[3,”1481766074”,{}]’ [19 bytes]
2023-09-10 20:41:09.540 INFO (MainThread) [ocpp] GRS-170000xxxxx: receive message [2,”1481766075”,”StatusNotification”,{“connectorId”:1,”errorCode”:”NoError”,”status”:”Available”}]
2023-09-10 20:41:09.540 INFO (MainThread) [ocpp] GRS-170000xxxxx: send [3,”1481766075”,{}]
2023-09-10 20:41:09.540 DEBUG (MainThread) [websockets.server] > TEXT ‘[3,”1481766075”,{}]’ [19 bytes]
2023-09-10 20:41:10.221 DEBUG (MainThread) [custom_components.ocpp] Feature profiles returned: 1
2023-09-10 20:41:10.229 INFO (MainThread) [ocpp] GRS-170000xxxxx: send [2,”12e3576c-17be-40e2-be39-5a79126989b5”,”GetConfiguration”,{“key”:[“NumberOfConnectors”]}]
2023-09-10 20:41:10.229 DEBUG (MainThread) [websockets.server] > TEXT ‘[2,”12e3576c-17be-40e2-be39-5a79126989b5”,”GetC...”NumberOfConnectors”]}]’ [92 bytes]
2023-09-10 20:41:10.306 DEBUG (MainThread) [custom_components.ocpp] Feature profiles returned: 1
2023-09-10 20:41:10.400 DEBUG (MainThread) [websockets.server] < TEXT ‘[4, “12e3576c-17be-40e2-be39-5a79126989b5”, “FormationViolation”, “”]’ [69 bytes]
2023-09-10 20:41:10.400 INFO (MainThread) [ocpp] GRS-170000xxxxx: receive message [4, “12e3576c-17be-40e2-be39-5a79126989b5”, “FormationViolation”, “”]
2023-09-10 20:41:10.401 INFO (MainThread) [ocpp] GRS-170000xxxxx: send [2,”dd71025b-4c5b-4d93-a772-a5b857a72af7”,”GetConfiguration”,{“key”:[“NumberOfConnectors”]}]
2023-09-10 20:41:10.401 DEBUG (MainThread) [websockets.server] > TEXT ‘[2,”dd71025b-4c5b-4d93-a772-a5b857a72af7”,”GetC...”NumberOfConnectors”]}]’ [92 bytes]
2023-09-10 20:41:10.401 ERROR (MainThread) [custom_components.ocpp] Unexpected exception in connection to ‘GRS-170000xxxxx’: ‘(“Error code ‘%s’ is not defined by the OCPP specification”, ‘FormationViolation’)’
Traceback (most recent call last):
File “/config/custom_components/ocpp/api.py”, line 930, in run
await asyncio.gather(*self.tasks)
File “/config/custom_components/ocpp/api.py”, line 422, in post_connect
resp = await self.get_configuration(ckey.number_of_connectors.value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/config/custom_components/ocpp/api.py”, line 797, in get_configuration
resp = await self.call(req)
^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py”, line 281, in call
response = await self._get_specific_response(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/config/custom_components/ocpp/api.py”, line 865, in _get_specific_response
raise resp.to_exception()
^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/site-packages/ocpp/messages.py”, line 439, in to_exception
raise UnknownCallErrorCodeError(
ocpp.exceptions.UnknownCallErrorCodeError: (“Error code ‘%s’ is not defined by the OCPP specification”, ‘FormationViolation’)
2023-09-10 20:41:10.407 DEBUG (MainThread) [custom_components.ocpp] Closing websocket to ‘GRS-170000xxxxx’
2023-09-10 20:41:10.407 DEBUG (MainThread) [websockets.server] = connection is CLOSING
2023-09-10 20:41:10.407 DEBUG (MainThread) [websockets.server] > CLOSE 1000 (OK) [2 bytes]
2023-09-10 20:41:10.447 DEBUG (MainThread) [websockets.server] < CLOSE 1005 (no status code [internal]) [0 bytes]
2023-09-10 20:41:10.448 DEBUG (MainThread) [websockets.server] x half-closing TCP connection
2023-09-10 20:41:10.455 DEBUG (MainThread) [websockets.server] = connection is CLOSED
2023-09-10 20:41:10.456 INFO (MainThread) [custom_components.ocpp] Charger GRS-170000xxxxx disconnected from 172.20.21.150:9000.
2023-09-10 20:41:10.456 INFO (MainThread) [websockets.server] connection closed
2023-09-10 20:41:40.403 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File “/usr/local/lib/python3.11/asyncio/tasks.py”, line 490, in wait_for
return fut.result()
^^^^^^^^^^^^
File “/usr/local/lib/python3.11/asyncio/queues.py”, line 158, in get
await getter
asyncio.exceptions.CancelledError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File “/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py”, line 281, in call
response = await self._get_specific_response(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/config/custom_components/ocpp/api.py”, line 862, in _get_specific_response
resp = await super()._get_specific_response(unique_id, timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py”, line 315, in _get_specific_response
response = await asyncio.wait_for(self._response_queue.get(), timeout)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/asyncio/tasks.py”, line 492, in wait_for
raise exceptions.TimeoutError() from exc
TimeoutError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File “/config/custom_components/ocpp/api.py”, line 422, in post_connect
resp = await self.get_configuration(ckey.number_of_connectors.value)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File “/config/custom_components/ocpp/api.py”, line 797, in get_configuration
resp = await self.call(req)
^^^^^^^^^^^^^^^^^^^^
File “/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py”, line 285, in call
raise asyncio.TimeoutError(
TimeoutError: Waited 30s for response on [2,”dd71025b-4c5b-4d93-a772-a5b857a72af7”,”GetConfiguration”,{“key”:[“NumberOfConnectors”]}].
2023-09-10 20:50:31.618 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved

mkbrown avatar Sep 11 '23 01:09 mkbrown

Looks like the issue is any get_configuration call that passes a parameter. So they'll all need to be commented out and replaced with a default value.

drc38 avatar Sep 11 '23 07:09 drc38

Ok, I know enough about python to be dangerous (to myself)… the integration still won’t load enough to have get_diagnostics. Is there a way I can force it to run at the start of get_supported_features so that we can have the diag output before it tries to do anything that will likely fail?

mkbrown avatar Sep 11 '23 13:09 mkbrown

like a say before, it's possible to use [2,"0116359a-f5b2-4f6b-af28-b845dd10c138","GetConfiguration",{}] to get all informatgion (like SupportedFeatureProfiles) and select what you want in the list.

But it's not possible to use [2,"0116359a-f5b2-4f6b-af28-b845dd10c138","GetConfiguration",{"key":["SupportedFeatureProfiles"]}]' You will receive "FormationViolation"

djiesr avatar Sep 11 '23 15:09 djiesr

Ok, so I tried the SteVe add-on, and was able to successfully connect to the Grizzl-e. Here’s it’s get configuration function

IMG_1371

Edit:

Looks like only the core profile is supported. It shows firmware management as well, but I haven’t looked into that yet. It does show the Number of connectors as one.

mkbrown avatar Sep 11 '23 20:09 mkbrown

Looks like Get diagnostics isn’t implemented in the Grizzl-e v2 firmware.

IMG_1372

mkbrown avatar Sep 11 '23 22:09 mkbrown

They've obviously implemented (prioritized) the Grizzl-E v2 firmware to work with the Grizzl-E Connect app and it is still a work in progress. Is it possible to capture a trace of the traffic in a Grizzl-E Connect session to see what they are exchanging? Would this be of any use?

Do you have any idea what charging statistics the app is able to obtain from the EVSE? I notice that several of the sensors (e.g. Current Export, Current Offered, Power Offered, etc.) don't seem to populate with the v1 hardware. I presume these should come from MeterValues messages? I don't know if this is a limitation of the firmware and whether it's any better with v2.

Of note, it seems like the v2 firmware is only advertising support for the Core and FirmwareManagement profiles. With my v1 I see the OCPP integration sending several "TriggerMessage" requests to the EVSE to general a boot notification and status. I presume this would require the RemoteTrigger profile and wouldn't be possible with v2. Based on the last post it seems like even the advertised profiles are incomplete (i.e. missing GetDiagnostics from the FirmwareManagement profile).

    hass.9000 > grizzle.60988: Flags [P.], cksum 0x85f3 (incorrect -> 0xb409), seq 1118:1237, ack 1750, win 64002, length 119
	0x0000:  4500 009f 62fb 4000 4006 51fc c0a8 0006  E...b.@[email protected].....
	0x0010:  c0a8 040b 2328 ee3c 7c2d 175a a6a7 9779  ....#(.<|-.Z...y
	0x0020:  5018 fa02 85f3 0000 8175 5b32 2c22 6333  P........u[2,"c3
	0x0030:  3030 3038 3065 2d38 3064 392d 3463 6637  00080e-80d9-4cf7
	0x0040:  2d38 3633 352d 3930 3864 6432 3465 3630  -8635-908dd24e60
	0x0050:  3830 222c 2254 7269 6767 6572 4d65 7373  80","TriggerMess
	0x0060:  6167 6522 2c7b 2272 6571 7565 7374 6564  age",{"requested
	0x0070:  4d65 7373 6167 6522 3a22 5374 6174 7573  Message":"Status
	0x0080:  4e6f 7469 6669 6361 7469 6f6e 222c 2263  Notification","c
	0x0090:  6f6e 6e65 6374 6f72 4964 223a 317d 5d    onnectorId":1}]

    grizzle.60988 > hass.9000: Flags [P.], cksum 0xaa84 (correct), seq 1750:1820, ack 1237, win 4508, length 70
	0x0000:  4500 006e 0205 0000 fe06 3523 c0a8 040b  E..n......5#....
	0x0010:  c0a8 0006 ee3c 2328 a6a7 9779 7c2d 17d1  .....<#(...y|-..
	0x0020:  5018 119c aa84 0000 81c0 0000 0000 5b33  P.............[3
	0x0030:  2c22 6333 3030 3038 3065 2d38 3064 392d  ,"c300080e-80d9-
	0x0040:  3463 6637 2d38 3633 352d 3930 3864 6432  4cf7-8635-908dd2
	0x0050:  3465 3630 3830 222c 7b22 7374 6174 7573  4e6080",{"status
	0x0060:  223a 2241 6363 6570 7465 6422 7d5d       ":"Accepted"}]

    grizzle.60988 > hass.9000: Flags [P.], cksum 0x4754 (correct), seq 1820:2044, ack 1237, win 4508, length 224
	0x0000:  4500 0108 0206 0000 fe06 3488 c0a8 040b  E.........4.....
	0x0010:  c0a8 0006 ee3c 2328 a6a7 97bf 7c2d 17d1  .....<#(....|-..
	0x0020:  5018 119c 4754 0000 81fe 00d8 0000 0000  P...GT..........
	0x0030:  5b32 2c22 3030 3030 3030 3030 3433 6232  [2,"00000000xxxx
	0x0040:  3035 6432 3062 6433 222c 2253 7461 7475  xxxxxxxx","Statu
	0x0050:  734e 6f74 6966 6963 6174 696f 6e22 2c7b  sNotification",{
	0x0060:  2265 7272 6f72 436f 6465 223a 224e 6f45  "errorCode":"NoE
	0x0070:  7272 6f72 222c 2273 7461 7475 7322 3a22  rror","status":"
	0x0080:  4176 6169 6c61 626c 6522 2c22 7469 6d65  Available","time
	0x0090:  7374 616d 7022 3a22 3230 3233 2d30 392d  stamp":"2023-09-
	0x00a0:  3039 5432 303a 3133 3a30 302e 3030 315a  09T20:13:00.001Z
	0x00b0:  222c 2269 6e66 6f22 3a22 5069 6c6f 7420  ","info":"Pilot.
	0x00c0:  616e 6420 4368 6172 6765 723a 4331 6822  and.Charger:C1h"
	0x00d0:  2c22 7665 6e64 6f72 4964 223a 2255 4322  ,"vendorId":"UC"
	0x00e0:  2c22 7665 6e64 6f72 4572 726f 7243 6f64  ,"vendorErrorCod
	0x00f0:  6522 3a22 3022 2c22 636f 6e6e 6563 746f  e":"0","connecto
	0x0100:  7249 6422 3a31 7d5d                      rId":1}]

8jmm3 avatar Sep 11 '23 23:09 8jmm3

It's work after I modified 2 sections in api.py

###First:

async def get_supported_features(self):
    feature_string = "Core,FirmwareManagement"
    feature_list = feature_string.split(',')
    if feature_list[0] == "":
        _LOGGER.warning("No feature profiles detected, defaulting to Core")
        await self.notify_ha("No feature profiles detected, defaulting to Core")
        feature_list = [om.feature_profile_core.value]
    if self.central.config.get(
        CONF_FORCE_SMART_CHARGING, DEFAULT_FORCE_SMART_CHARGING
    ):
        _LOGGER.warning("Force Smart Charging feature profile")
        self._attr_supported_features |= prof.SMART
    for item in feature_list:
        item = item.strip().replace(" ", "")
        if item == om.feature_profile_core.value:
            self._attr_supported_features |= prof.CORE
        elif item == om.feature_profile_firmware.value:
            self._attr_supported_features |= prof.FW
        elif item == om.feature_profile_smart.value:
            self._attr_supported_features |= prof.SMART
        elif item == om.feature_profile_reservation.value:
            self._attr_supported_features |= prof.RES
        elif item == om.feature_profile_remote.value:
            self._attr_supported_features |= prof.REM
        elif item == om.feature_profile_auth.value:
            self._attr_supported_features |= prof.AUTH
        else:
            _LOGGER.warning("Unknown feature profile detected ignoring: %s", item)
            await self.notify_ha(
                f"Warning: Unknown feature profile detected ignoring {item}"
            )
    self._metrics[cdet.features.value].value = self._attr_supported_features
    _LOGGER.debug("Feature profiles returned: %s", self._attr_supported_features)

###And this one:

async def get_configuration(self, key: str = ""):
    req = call.GetConfigurationPayload()
    resp = await self.call(req)
    _LOGGER.debug("Complet get config value is %s", resp)

    if key:
        for config_item in resp.configuration_key:
            if config_item.get("key") == key:
                value = config_item.get("value")
                _LOGGER.debug("Get Configuration for %s: %s", key, value)
                self._metrics[cdet.config_response.value].value = datetime.now(tz=timezone.utc)
                self._metrics[cdet.config_response.value].extra_attr = {key: value}
                return value


    if resp.configuration_key is not None:
        value = resp.configuration_key[0][om.value.value]
        _LOGGER.debug("Get Configuration for %s: %s", key, value)
        self._metrics[cdet.config_response.value].value = datetime.now(tz=timezone.utc)
        self._metrics[cdet.config_response.value].extra_attr = {key: value}
        return value

    if resp.unknown_key is not None:
        _LOGGER.warning("Get Configuration returned unknown key for: %s", key)
        await self.notify_ha(f"Warning: charger reports {key} is unknown")

    return None


async def configure(self, key: str, value: str):

    req = call.GetConfigurationPayload()
    resp = await self.call(req)
    _LOGGER.debug("Complet get config value is %s", resp)

    if key:
        for config_item in resp.configuration_key:
            if config_item.get("key") == key:
                value = config_item.get("value")
                _LOGGER.debug("Get Configuration for %s: %s", key, value)
                self._metrics[cdet.config_response.value].value = datetime.now(tz=timezone.utc)
                self._metrics[cdet.config_response.value].extra_attr = {key: value}
                return value

    if resp.unknown_key is not None:
        if key in resp.unknown_key:
            _LOGGER.warning("%s is unknown (not supported)", key)
            return

    for key_value in resp.configuration_key:
        # If the key already has the targeted value we don't need to set
        # it.
        if key_value[om.key.value] == key and key_value[om.value.value] == value:
            return

        if key_value.get(om.readonly.name, False):
            _LOGGER.warning("%s is a read only setting", key)
            await self.notify_ha(f"Warning: {key} is read-only")

    req = call.ChangeConfigurationPayload(key=key, value=value)

    resp = await self.call(req)

    if resp.status in [
        ConfigurationStatus.rejected,
        ConfigurationStatus.not_supported,
    ]:
        _LOGGER.warning("%s while setting %s to %s", resp.status, key, value)
        await self.notify_ha(
            f"Warning: charger reported {resp.status} while setting {key}={value}"
        )

    if resp.status == ConfigurationStatus.reboot_required:
        self._requires_reboot = True
        await self.notify_ha(f"A reboot is required to apply {key}={value}")

And, prevent disconnecting, I modified const.py with this:

DEFAULT_WEBSOCKET_PING_TRIES = 5 #2 DEFAULT_WEBSOCKET_PING_INTERVAL = 60 #20 DEFAULT_WEBSOCKET_PING_TIMEOUT = 30 #20

image

djiesr avatar Sep 21 '23 20:09 djiesr

I am very interested in this discussion. I just received a replacement Grizzl-E Smart EVSE for the one that I bricked by loading old firmware. UC Connect says I now have Firmware Version:GWM-07.020-03_GCW-10.18-05.7. The Advanced OCPP Configuration option has been removed from this firmware. I have to decide whether to keep this unit or sell it on the used market because Homeassistant connectivity is a must-have for me. It seems that there is optimism in this group that an OCPP compliant firmware will be developed although not by United Chargers. Am I being overly optimistic? Should I keep the unit and hope for a solution?

windseye avatar Oct 06 '23 19:10 windseye

I am very interested in this discussion. I just received a replacement Grizzl-E Smart EVSE for the one that I bricked by loading old firmware. UC Connect says I now have Firmware Version:GWM-07.020-03_GCW-10.18-05.7. The Advanced OCPP Configuration option has been removed from this firmware. I have to decide whether to keep this unit or sell it on the used market because Homeassistant connectivity is a must-have for me. It seems that there is optimism in this group that an OCPP compliant firmware will be developed although not by United Chargers. Am I being overly optimistic? Should I keep the unit and hope for a solution?

The Advanced OCPP Configuration is now hidden in this firmware. On the WiFI configuration page you need to click the "ONLINE" at the top left 10 times. The Advanced OCPP Configuration button will then appear as before. I haven't had time to test out the above patching to see if it gives me the right functionality yet.

image

kenttse avatar Oct 06 '23 19:10 kenttse

thanks!

windseye avatar Oct 06 '23 20:10 windseye

Let me know if this firmware work well with the OCPP intergration. My version didn't work properly, so I make this fork with some modification: https://github.com/djiesr/ocpp

djiesr avatar Oct 06 '23 20:10 djiesr

Thanks djiesr. I am making progress with your fork but get this error:

2023-10-07 09:27:38.423 ERROR (MainThread) [ocpp] Error while handling request '<Call - unique_id=1481765945, action=BootNotification, payload={'chargePointModel': 'Grizzl-E Smart Connect', 'chargePointVendor': 'UnitedChargers', 'chargePointSerialNumber': 'GRS-1700003fb5d', 'firmwareVersion': 'GWM-07.020-03_GCW-10.18-05.7', 'meterType': ''}>' Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/ocpp/messages.py", line 227, in validate_payload validator.validate(message.payload) File "/usr/local/lib/python3.11/site-packages/jsonschema/validators.py", line 435, in validate raise error jsonschema.exceptions.ValidationError: 'Grizzl-E Smart Connect' is too long Failed validating 'maxLength' in schema['properties']['chargePointModel']: {'maxLength': 20, 'type': 'string'} On instance['chargePointModel']: 'Grizzl-E Smart Connect' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py", line 153, in route_message await self._handle_call(msg) File "/config/custom_components/ocpp/api.py", line 945, in _handle_call await super()._handle_call(msg) File "/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py", line 181, in _handle_call validate_payload(msg, self._ocpp_version) File "/usr/local/lib/python3.11/site-packages/ocpp/messages.py", line 240, in validate_payload raise TypeConstraintViolationError( ocpp.exceptions.TypeConstraintViolationError: TypeConstraintViolationError: Payload for Action is syntactically correct but at least one of the fields violates data type constraints (e.g. “somestring”: 12), {'cause': "'Grizzl-E Smart Connect' is too long", 'ocpp_message': <Call - unique_id=1481765945, action=BootNotification, payload={'chargePointModel': 'Grizzl-E Smart Connect', 'chargePointVendor': 'UnitedChargers', 'chargePointSerialNumber': 'GRS-1700003fb5d', 'firmwareVersion': 'GWM-07.020-03_GCW-10.18-05.7', 'meterType': ''}>} 2023-10-07 09:27:38.431 INFO (MainThread) [ocpp] GRS-1700003fb5d: send [4,"1481765945","TypeConstraintViolation","Payload for Action is syntactically correct but at least one of the fields violates data type constraints (e.g. \u201csomestring\u201d: 12)",{"cause":"'Grizzl-E Smart Connect' is too long","ocpp_message":"[2,"1481765945","BootNotification",{"chargePointModel":"Grizzl-E Smart Connect","chargePointVendor":"UnitedChargers","chargePointSerialNumber":"GRS-1700003fb5d","firmwareVersion":"GWM-07.020-03_GCW-10.18-05.7","meterType":""}]"}] 2023-10-07 09:27:38.432 DEBUG (MainThread) [websockets.server] > TEXT '[4,"1481765945","TypeConstraintViolation","Payl...eterType\":\"\"}]"}]' [501 bytes] 2023-10-07 09:27:48.458 DEBUG (MainThread) [websockets.server] < PING '' [0 bytes] 2023-10-07 09:27:48.458 DEBUG (MainThread) [websockets.server] > PONG '' [0 bytes] 2023-10-07 09:27:48.634 DEBUG (MainThread) [websockets.server] > PING 8c 55 b3 59 [binary, 4 bytes] 2023-10-07 09:27:48.902 DEBUG (MainThread) [websockets.server] < PONG 8c 55 b3 59 [binary, 4 bytes] 2023-10-07 09:27:48.903 DEBUG (MainThread) [custom_components.ocpp] Connection latency from 'central' to 'GRS-1700003fb5d': ping=1.0 ms, pong=268.0 ms, retry=0 2023-10-07 09:27:58.873 DEBUG (MainThread) [websockets.server] < PING '' [0 bytes] 2023-10-07 09:27:58.873 DEBUG (MainThread) [websockets.server] > PONG '' [0 bytes] 2023-10-07 09:28:08.904 DEBUG (MainThread) [websockets.server] < PING '' [0 bytes] 2023-10-07 09:28:08.904 DEBUG (MainThread) [websockets.server] > PONG '' [0 bytes] 2023-10-07 09:28:08.906 DEBUG (MainThread) [websockets.server] > PING e8 c0 b7 6e [binary, 4 bytes] 2023-10-07 09:28:08.967 DEBUG (MainThread) [websockets.server] < PONG e8 c0 b7 6e [binary, 4 bytes] 2023-10-07 09:28:08.967 DEBUG (MainThread) [custom_components.ocpp] Connection latency from 'central' to 'GRS-1700003fb5d': ping=2.0 ms, pong=60.0 ms, retry=0

windseye avatar Oct 07 '23 13:10 windseye

Ok, in my version is Grizzl-E Smart and in your firmware is "Grizzl-E Smart Connect". I didn't modify this part, so you would have the same error in OCPP. Let me look at this.

Le sam. 7 oct. 2023, à 09 h 32, windseye @.***> a écrit :

Thanks djiesr. I am making progress with your fork but get this error:

2023-10-07 09:27:38.423 ERROR (MainThread) [ocpp] Error while handling request '<Call - unique_id=1481765945, action=BootNotification, payload={'chargePointModel': 'Grizzl-E Smart Connect', 'chargePointVendor': 'UnitedChargers', 'chargePointSerialNumber': 'GRS-1700003fb5d', 'firmwareVersion': 'GWM-07.020-03_GCW-10.18-05.7', 'meterType': ''}>' Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/ocpp/messages.py", line 227, in validate_payload validator.validate(message.payload) File "/usr/local/lib/python3.11/site-packages/jsonschema/validators.py", line 435, in validate raise error jsonschema.exceptions.ValidationError: 'Grizzl-E Smart Connect' is too long Failed validating 'maxLength' in schema['properties']['chargePointModel']: {'maxLength': 20, 'type': 'string'} On instance['chargePointModel']: 'Grizzl-E Smart Connect' The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py", line 153, in route_message await self._handle_call(msg) File "/config/custom_components/ocpp/api.py", line 945, in _handle_call await super()._handle_call(msg) File "/usr/local/lib/python3.11/site-packages/ocpp/charge_point.py", line 181, in _handle_call validate_payload(msg, self._ocpp_version) File "/usr/local/lib/python3.11/site-packages/ocpp/messages.py", line 240, in validate_payload raise TypeConstraintViolationError( ocpp.exceptions.TypeConstraintViolationError: TypeConstraintViolationError: Payload for Action is syntactically correct but at least one of the fields violates data type constraints (e.g. “somestring”: 12), {'cause': "'Grizzl-E Smart Connect' is too long", 'ocpp_message': <Call - unique_id=1481765945, action=BootNotification, payload={'chargePointModel': 'Grizzl-E Smart Connect', 'chargePointVendor': 'UnitedChargers', 'chargePointSerialNumber': 'GRS-1700003fb5d', 'firmwareVersion': 'GWM-07.020-03_GCW-10.18-05.7', 'meterType': ''}>} 2023-10-07 09:27:38.431 INFO (MainThread) [ocpp] GRS-1700003fb5d: send [4,"1481765945","TypeConstraintViolation","Payload for Action is syntactically correct but at least one of the fields violates data type constraints (e.g. \u201csomestring\u201d: 12)",{"cause":"'Grizzl-E Smart Connect' is too long","ocpp_message":"[2,"1481765945","BootNotification",{"chargePointModel":"Grizzl-E Smart Connect","chargePointVendor":"UnitedChargers","chargePointSerialNumber":"GRS-1700003fb5d","firmwareVersion":"GWM-07.020-03_GCW-10.18-05.7","meterType":""}]"}] 2023-10-07 09:27:38.432 DEBUG (MainThread) [websockets.server] > TEXT '[4,"1481765945","TypeConstraintViolation","Payl...eterType":""}]"}]' [501 bytes] 2023-10-07 09:27:48.458 DEBUG (MainThread) [websockets.server] < PING '' [0 bytes] 2023-10-07 09:27:48.458 DEBUG (MainThread) [websockets.server] > PONG '' [0 bytes] 2023-10-07 09:27:48.634 DEBUG (MainThread) [websockets.server] > PING 8c 55 b3 59 [binary, 4 bytes] 2023-10-07 09:27:48.902 DEBUG (MainThread) [websockets.server] < PONG 8c 55 b3 59 [binary, 4 bytes] 2023-10-07 09:27:48.903 DEBUG (MainThread) [custom_components.ocpp] Connection latency from 'central' to 'GRS-1700003fb5d': ping=1.0 ms, pong=268.0 ms, retry=0 2023-10-07 09:27:58.873 DEBUG (MainThread) [websockets.server] < PING '' [0 bytes] 2023-10-07 09:27:58.873 DEBUG (MainThread) [websockets.server] > PONG '' [0 bytes] 2023-10-07 09:28:08.904 DEBUG (MainThread) [websockets.server] < PING '' [0 bytes] 2023-10-07 09:28:08.904 DEBUG (MainThread) [websockets.server] > PONG '' [0 bytes] 2023-10-07 09:28:08.906 DEBUG (MainThread) [websockets.server] > PING e8 c0 b7 6e [binary, 4 bytes] 2023-10-07 09:28:08.967 DEBUG (MainThread) [websockets.server] < PONG e8 c0 b7 6e [binary, 4 bytes] 2023-10-07 09:28:08.967 DEBUG (MainThread) [custom_components.ocpp] Connection latency from 'central' to 'GRS-1700003fb5d': ping=2.0 ms, pong=60.0 ms, retry=0

— Reply to this email directly, view it on GitHub https://github.com/lbbrhzn/ocpp/issues/899#issuecomment-1751714292, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHPIGUKCNRZ2Q3MCNJWNPD3X6FKYRAVCNFSM6AAAAAA4Q3HBIGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONJRG4YTIMRZGI . You are receiving this because you commented.Message ID: @.***>

djiesr avatar Oct 07 '23 13:10 djiesr

I make a v0.1.5. I just limit the model at 20 character, so you will have a "Grizzl-E Smart Conne". Sorry about that, I just patch the it, thje problem is in "/usr/local/lib/python3.11/site-packages/" and I don't know how resolve that.

djiesr avatar Oct 07 '23 14:10 djiesr

home-assistant_2023-10-07T15-30-02.492Z.log I am still having the same problem.

windseye avatar Oct 07 '23 15:10 windseye

It appears that the problem is with the United Chargers firmware: OCPP 1.6 defines chargePointModel as CiString20Type The firmware outputs a string of 22 characters and fails the validation test. I have notified their technical support of this deficiency. Is there some way that we can truncate this field in at the server so it passes the validation test?

windseye avatar Oct 07 '23 16:10 windseye

I make a v0.1.5. I just limit the model at 20 character, so you will have a "Grizzl-E Smart Conne". Sorry about that, I just patch the it, thje problem is in "/usr/local/lib/python3.11/site-packages/" and I don't know how resolve that.

In the on function you can add skip_schema_validation=True

However this should already be enabled if when you configure the integration and tick "Skip schema validation". Changing the default value for your branch would be easiest.

drc38 avatar Oct 07 '23 19:10 drc38

That does not fix the problem. I believe the problem is packet validation not schema validationSent from my T-Mobile 5G Device -------- Original message --------From: drc38 @.> Date: 10/7/23 3:46 PM (GMT-05:00) To: lbbrhzn/ocpp @.> Cc: windseye @.>, Comment @.> Subject: Re: [lbbrhzn/ocpp] Grizzl-e Smart v2 support (Issue #899) In the on function you can add skip_schema_validation=True

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you commented.Message ID: @.***>

windseye avatar Oct 07 '23 20:10 windseye

Sorry about that, In api.py, I already add the limit of 20. Exemple:

@on(Action.BootNotification) def on_boot_notification(self, **kwargs): """Handle a boot notification.""" resp = call_result.BootNotificationPayload( current_time=datetime.now(tz=timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), interval=3600, status=RegistrationStatus.accepted.value, ) self.received_boot_notification = True _LOGGER.debug("Received boot notification for %s: %s", self.id, kwargs) # update metrics self._metrics[cdet.model.value].value = kwargs.get( om.charge_point_model.name[:20], None ....

But, that did't change for you.

The probleme is in the OCPP 1.6

image

You can ask to change "chargePointModel": { "type": "string", "maxLength": 20 },

20 for 25

djiesr avatar Oct 07 '23 20:10 djiesr

Another option would be to copy and modify the ocpp package schema length. The Mobilityhouse package needs to go into deps/lib/python3.11/site-packages/ under your config folder and then can be modified.

drc38 avatar Oct 07 '23 20:10 drc38