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

Connection to EVBox Livo charger seems to fail #1432

Open
abko opened this issue Dec 18, 2024 · 10 comments
Open

Connection to EVBox Livo charger seems to fail #1432

abko opened this issue Dec 18, 2024 · 10 comments

Comments

@abko
Copy link

abko commented Dec 18, 2024

I am trying to connect my charger to the plugin in Home Assistant, but believe the connection fails.

I am no expert so would appreciate any hints to narrow down the problem.

I am using these versions:
OCPP v0.6.1
HACS 2.01
Home Assistant Core 2024.12.2
Home Assistant Frontend 20241127.7

I can see the BootNotification message in the logs and data from it in Home Assistant, but then it seems to stop.

Not sure if something is wrong in the certificate I tried to install for Home assistant/ the ocpp server, or if it has to do with the specific charger implementation, e.g. a missing password or something else.

Any hints are appreciated.

Debug log

raspberrypivijf:/config# cat home-assistant.log | grep ocpp
2024-12-17 11:16:04.218 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration ocpp which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2024-12-17 11:16:06.994 WARNING (MainThread) [homeassistant.util.loop] Detected blocking call to load_cert_chain with args (<ssl.SSLContext object at 0x7ffefd2f9250>, '/config/fullchain.pem') inside the event loop by custom integration 'ocpp' at custom_components/ocpp/api.py, line 104: self.ssl_context.load_cert_chain( (offender: /config/custom_components/ocpp/api.py, line 104: self.ssl_context.load_cert_chain(), please create a bug report at https://github.com/lbbrhzn/ocpp/issues
File "/config/custom_components/ocpp/init.py", line 71, in async_setup_entry
File "/config/custom_components/ocpp/api.py", line 113, in create
File "/config/custom_components/ocpp/api.py", line 104, in init
2024-12-17 11:19:49.202 WARNING (MainThread) [custom_components.ocpp] Skipping websocket subprotocol validation
2024-12-17 11:19:49.423 INFO (MainThread) [ocpp] EVB-500-019-341: receive message [2,"1d58f42a-be8c-49ca-a456-eeefcc58e01c","BootNotification",{"reason":"PowerUp","chargingStation":{"vendorName":"EVBox","model":"Livo","firmwareVersion":"v5.24.0;v1.46.1","serialNumber":"oVUEYQCw8pArNfVvp4SB72bw3"}}]
2024-12-17 11:19:49.427 WARNING (MainThread) [homeassistant.util.loop] Detected blocking call to open with args ('/usr/local/lib/python3.13/site-packages/ocpp/v201/schemas/BootNotificationRequest.json', 'r') inside the event loop by custom integration 'ocpp' at custom_components/ocpp/chargepoint.py, line 514: await super()._handle_call(msg) (offender: /usr/local/lib/python3.13/site-packages/ocpp/messages.py, line 164: with open(path, "r", encoding="utf-8-sig") as f:), please create a bug report at https://github.com/lbbrhzn/ocpp/issues
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 238, in start
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 261, in route_message
File "/config/custom_components/ocpp/chargepoint.py", line 514, in _handle_call
2024-12-17 11:19:49.439 INFO (MainThread) [ocpp] EVB-500-019-341: send [3,"1d58f42a-be8c-49ca-a456-eeefcc58e01c",{"currentTime":"2024-12-17T10:19:49.428805+00:00","interval":10,"status":"Accepted"}]
2024-12-17 11:19:51.437 INFO (MainThread) [ocpp] EVB-500-019-341: send [2,"03758573-281e-4b15-b4c6-e9c9b9ba2bf2","GetBaseReport",{"requestId":1,"reportBase":"FullInventory"}]
File "/config/custom_components/ocpp/chargepoint.py", line 332, in post_connect
File "/config/custom_components/ocpp/chargepoint.py", line 266, in fetch_supported_features
File "/config/custom_components/ocpp/ocppv201.py", line 206, in get_supported_features
File "/config/custom_components/ocpp/ocppv201.py", line 126, in _get_inventory
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 404, in call
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 457, in _send
2024-12-17 12:07:57.451 WARNING (MainThread) [custom_components.ocpp] Skipping websocket subprotocol validation
2024-12-17 12:07:57.451 INFO (MainThread) [custom_components.ocpp] Charger websocket path=/EVB-500-019-341
2024-12-17 12:07:57.451 INFO (MainThread) [custom_components.ocpp] Charger EVB-500-019-341 reconnected to 0.0.0.0:9123.
2024-12-17 12:07:57.452 DEBUG (MainThread) [custom_components.ocpp] Reconnect websocket to EVB-500-019-341
2024-12-17 12:07:57.616 INFO (MainThread) [ocpp] EVB-500-019-341: receive message [2,"82826ea1-2913-4772-9a1e-8a95b38fada6","BootNotification",{"reason":"PowerUp","chargingStation":{"vendorName":"EVBox","model":"Livo","firmwareVersion":"v5.24.0;v1.46.1","serialNumber":"oVUEYQCw8pArNfVvp4SB72bw3"}}]
2024-12-17 12:07:57.617 DEBUG (MainThread) [custom_components.ocpp] Updating device info Livo: {'vendor_name': 'EVBox', 'model': 'Livo', 'firmware_version': 'v5.24.0;v1.46.1', 'serial_number': 'oVUEYQCw8pArNfVvp4SB72bw3'}
2024-12-17 12:07:57.629 INFO (MainThread) [ocpp] EVB-500-019-341: send [3,"82826ea1-2913-4772-9a1e-8a95b38fada6",{"currentTime":"2024-12-17T11:07:57.617135+00:00","interval":10,"status":"Accepted"}]
2024-12-17 12:07:57.714 DEBUG (MainThread) [custom_components.ocpp] Connection closed to 'EVB-500-019-341': no close frame received or sent
2024-12-17 12:07:57.714 INFO (MainThread) [custom_components.ocpp] Charger EVB-500-019-341 disconnected from 0.0.0.0:9123.
2024-12-17 12:07:59.630 INFO (MainThread) [ocpp] EVB-500-019-341: send [2,"e812e79a-559b-40bb-9328-4b2974f77606","GetBaseReport",{"requestId":1,"reportBase":"FullInventory"}]
File "/config/custom_components/ocpp/chargepoint.py", line 332, in post_connect
File "/config/custom_components/ocpp/chargepoint.py", line 266, in fetch_supported_features
File "/config/custom_components/ocpp/ocppv201.py", line 206, in get_supported_features
File "/config/custom_components/ocpp/ocppv201.py", line 126, in _get_inventory
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 404, in call
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 457, in _send
raspberrypivijf:/config# cat home-assistant.log | grep ocpp |

more
2024-12-17 11:16:04.218 WARNING (SyncWorker_0) [homeassistant.loader] We found a custom integration ocpp which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you experience issues with Home Assistant
2024-12-17 11:16:06.994 WARNING (MainThread) [homeassistant.util.loop] Detected blocking call to load_cert_chain with args (<ssl.SSLContext object at 0x7ffefd2f9250>, '/config/fullchain.pem') inside the event loop by custom integration 'ocpp' at custom_components/ocpp/api.py, line 104: self.ssl_context.load_cert_chain( (offender: /config/custom_components/ocpp/api.py, line 104: self.ssl_context.load_cert_chain(), please create a bug report at https://github.com/lbbrhzn/ocpp/issues
File "/config/custom_components/ocpp/init.py", line 71, in async_setup_entry
File "/config/custom_components/ocpp/api.py", line 113, in create
File "/config/custom_components/ocpp/api.py", line 104, in init
2024-12-17 11:19:49.202 WARNING (MainThread) [custom_components.ocpp] Skipping websocket subprotocol validation
2024-12-17 11:19:49.423 INFO (MainThread) [ocpp] EVB-500-019-341: receive message [2,"1d58f42a-be8c-49ca-a456-eeefcc58e01c","BootNotification",{"reason":"PowerUp","chargingStation":{"vendorName":"EVBox","model":"Livo","firmwareVersion":"v5.24.0;v1.46.1","serialNumber":"oVUEYQCw8pArNfVvp4SB72bw3"}}]
2024-12-17 11:19:49.427 WARNING (MainThread) [homeassistant.util.loop] Detected blocking call to open with args ('/usr/local/lib/python3.13/site-packages/ocpp/v201/schemas/BootNotificationRequest.json', 'r') inside the event loop by custom integration 'ocpp' at custom_components/ocpp/chargepoint.py, line 514: await super()._handle_call(msg) (offender: /usr/local/lib/python3.13/site-packages/ocpp/messages.py, line 164: with open(path, "r", encoding="utf-8-sig") as f:), please create a bug report at https://github.com/lbbrhzn/ocpp/issues
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 238, in start
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 261, in route_message
File "/config/custom_components/ocpp/chargepoint.py", line 514, in _handle_call
2024-12-17 11:19:49.439 INFO (MainThread) [ocpp] EVB-500-019-341: send [3,"1d58f42a-be8c-49ca-a456-eeefcc58e01c",{"currentTime":"2024-12-17T10:19:49.428805+00:00","interval":10,"status":"Accepted"}]
2024-12-17 11:19:51.437 INFO (MainThread) [ocpp] EVB-500-019-341: send [2,"03758573-281e-4b15-b4c6-e9c9b9ba2bf2","GetBaseReport",{"requestId":1,"reportBase":"FullInventory"}]
File "/config/custom_components/ocpp/chargepoint.py", line 332, in post_connect
File "/config/custom_components/ocpp/chargepoint.py", line 266, in fetch_supported_features
File "/config/custom_components/ocpp/ocppv201.py", line 206, in get_supported_features
File "/config/custom_components/ocpp/ocppv201.py", line 126, in _get_inventory
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 404, in call
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 457, in _send
2024-12-17 12:07:57.451 WARNING (MainThread) [custom_components.ocpp] Skipping websocket subprotocol validation
2024-12-17 12:07:57.451 INFO (MainThread) [custom_components.ocpp] Charger websocket path=/EVB-500-019-341
2024-12-17 12:07:57.451 INFO (MainThread) [custom_components.ocpp] Charger EVB-500-019-341 reconnected to 0.0.0.0:9123.
2024-12-17 12:07:57.452 DEBUG (MainThread) [custom_components.ocpp] Reconnect websocket to EVB-500-019-341
2024-12-17 12:07:57.616 INFO (MainThread) [ocpp] EVB-500-019-341: receive message [2,"82826ea1-2913-4772-9a1e-8a95b38fada6","BootNotification",{"reason":"PowerUp","chargingStation":{"vendorName":"EVBox","model":"Livo","firmwareVersion":"v5.24.0;v1.46.1","serialNumber":"oVUEYQCw8pArNfVvp4SB72bw3"}}]
2024-12-17 12:07:57.617 DEBUG (MainThread) [custom_components.ocpp] Updating device info Livo: {'vendor_name': 'EVBox', 'model': 'Livo', 'firmware_version': 'v5.24.0;v1.46.1', 'serial_number': 'oVUEYQCw8pArNfVvp4SB72bw3'}
2024-12-17 12:07:57.629 INFO (MainThread) [ocpp] EVB-500-019-341: send [3,"82826ea1-2913-4772-9a1e-8a95b38fada6",{"currentTime":"2024-12-17T11:07:57.617135+00:00","interval":10,"status":"Accepted"}]
2024-12-17 12:07:57.714 DEBUG (MainThread) [custom_components.ocpp] Connection closed to 'EVB-500-019-341': no close frame received or sent
2024-12-17 12:07:57.714 INFO (MainThread) [custom_components.ocpp] Charger EVB-500-019-341 disconnected from 0.0.0.0:9123.
2024-12-17 12:07:59.630 INFO (MainThread) [ocpp] EVB-500-019-341: send [2,"e812e79a-559b-40bb-9328-4b2974f77606","GetBaseReport",{"requestId":1,"reportBase":"FullInventory"}]
File "/config/custom_components/ocpp/chargepoint.py", line 332, in post_connect
File "/config/custom_components/ocpp/chargepoint.py", line 266, in fetch_supported_features
File "/config/custom_components/ocpp/ocppv201.py", line 206, in get_supported_features
File "/config/custom_components/ocpp/ocppv201.py", line 126, in _get_inventory
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 404, in call
File "/usr/local/lib/python3.13/site-packages/ocpp/charge_point.py", line 457, in _send

@drc38
Copy link
Collaborator

drc38 commented Dec 18, 2024

In const.py try changing DEFAULT_SUBPROTOCOL = "ocpp1.6,ocpp2.0.1" with DEFAULT_SUBPROTOCOL = "ocpp1.6"

@abko
Copy link
Author

abko commented Dec 18, 2024

Thanks @drc38. I’ll try it as soon as I am at home. Note the charger only supports 2.01, so I will try that.

@drc38
Copy link
Collaborator

drc38 commented Dec 18, 2024

Thanks @drc38. I’ll try it as soon as I am at home. Note the charger only supports 2.01, so I will try that.

If it only supports 2.0.1 then ignore my comment above, I thought it was perhaps selecting the wrong protocol. I have no experience with 2.0.1, @ars3niy may have some suggestions on why it's not working.

@scauwe
Copy link

scauwe commented Jan 28, 2025

Can this be a duplicate of #1503 ? I noticed you also received the BootNotification multiple times.
Difference is that in your case, GetBaseReport is send by the OCPP server to the client. For me, it was GetConfiguration. I'm on ocpp1.6, which can explain that difference. The workaround I found is independent of the OCPP version.

@ars3niy
Copy link
Contributor

ars3niy commented Jan 29, 2025

Looking at the log, on the first attempt (at 11:19:49) HomeAssistant sends to the charger BootNotification response and 2 seconds later GetBaseReport request, and then nothing ever happens.

Strictly speaking, that 2-second delay is wrong but it comes from OCPP 1.6 implementation. What the OCPP integration really should do instead is, respond to first boot notification with status Pending, then do all the GetBaseReport and SetVariables stuff (or the equivalent with OCPP 1.6) and only then respond to the next BootNotification with Accepted. Also TriggerMessage a boot notification for good measure, to make sure it won't have to wait long.

From what I can tell, this part of cold boot sequence is generally similar for OCPP 1.6 and 2.0, the exact messages differ but their meaning is overall the same.

As it is, at least in OCPP 2.0.1 an Accepted BootNotification response should trigger StatusNotification response request from the charger (and on the charger I tested with, the 2-second delay was enough to finish the entire cold boot sequence). If then this charger receives GetBaseReport before it did status notifications then I dunno, maybe it will misbehave.

If instead the first BootNotification response is Pending, the charger must be able to receive the next request immediately with no arbitrary delay at all. The charger can take a few seconds to respond, that's fine, but CSMS should not need to wait.

@ars3niy
Copy link
Contributor

ars3niy commented Jan 29, 2025

@drc38

I have no experience with 2.0.1

Well, let me give you some :)

There are still configuration parameters but they are called OCPP variables. Each still has a key and a value; value is a string but they also have types so it can be string representation of an integer or an enum or a comma-separated list. And the key is a pretty long tuple: component name (string), optional component instance (string), optional power supply (a.k.a. EVSE) id (integer), optional connector id within the EVSE (integer), variable name (string), optional variable instance (string); so component and variable name are mandatory rest are optional.

There are four message types for working with these OCPP variables. The first two, GetVariables and SetVariables, work just as you'd expect: they contain list of keys (get) or key-value tuples (set), response contains list of key + result code + value tuples (get) or just key + result code (set). Despite the name, some variables are read-only (such as various statuses) or even completely constant. A few (various passwords) are write-only.

The third one is GetCustomReport, it is for stuff like getting all variables with a given component name (and any variable name). It is not used here.

The fourth one is GetBaseReport. The request contains one of three possible options: ConfigurationInventory, FullInventory or SummaryInventory. Summary inventory is not required to be implemented by chargers and can be ignored. Configuration inventory returns all writable variables (their keys, values if not write-only, and some additional metadata). Full inventory returns a similar list but also including read-only variables, and that's the useful one. For example, there are always per-connector variables with EVSE and connector id in their key (such as variables for connector type), so by looking at this result you can tell how many connectors the charger has. The above-mentioned metadata also contains list of possible values for all enums, and that's how CSMS gets to know which measurands the charger supports because there are standardised enum-type variables for those.

Response to GetBaseReport does not contain that list of variables: it's merely an acknowledgement, the variables are then sent in one or more subsequent NotifyReport requests from the charger, with machinery in place to match those to the GetBaseReport that caused them and also tell which one is the last in case there are multiple. This is because there is a ton of variables, so chargers can split them between several messages if they want to, rather than be forced to send one miles-long response.

A note about EVSE: if there are two connectors on the same EVSE then if any one is used, the other becomes unavailable, i.e. a vehicle on one connector hogs the whole power supply. The only time there will be two connectors on same EVSE, that I know of, is on DC charging stations with ChaDeMo which will have a ChaDeMo and a CCS connector on the same power supply. So not going to happen on home chargers, and even on public chargers it's gradually going away.

Hopefully this makes it more clear how cold boot sequence should work. Charger sends boot notification, CSMS responds with Pending (that one also exists in OCPP 1.6), then sends GetBaseReport so it knows how many connectors there are, which measurands are supported, maybe some other things, then SetVariables to send standard settings, then TriggerMessage for a boot notification (that one also exists in OCPP 1.6) and to that boot notification it responds with Accepted. After that the charger is supposed to send StatusNotification for every connector and once all those are responded to, cold boot is complete and "normal operation is resumed" as the standard puts it.

@drc38
Copy link
Collaborator

drc38 commented Jan 29, 2025

Thanks that's really useful, quite a different messaging approach from 1.6

@scauwe
Copy link

scauwe commented Jan 29, 2025

Where did you find info on the cold boot sequence? I searched like crazy for it (for occp 1.6), but found nothing. The closest I got was that you should not send a message if the previous message was not yet answered or it timed out (in other words: no parallel messages should be sent). But given the 'or timed out', even this is still vague.

I am also unable to find the sequence you describe about first answering 'Pending', then get some administrative tasks done, and at the end trigger a boot notification and answering 'Accepted'. Where did you find that boot sequence (or is this only in 2.0.1)?

@ars3niy
Copy link
Contributor

ars3niy commented Jan 29, 2025

Where did you find info on the cold boot sequence?

Mostly from OCPP 2.0.1, which is what this particular issue is about. As for your charger, I'm not so sure. OCPP 1.6 still has the Pending status but seems to lack clear description of cold boot sequence.

@ars3niy
Copy link
Contributor

ars3niy commented Jan 29, 2025

Oh and by the way:

I searched like crazy for it ... but found nothing. The closest I got was ... But ... even this is still vague.

Welcome to my life :) I'm doing this for a living.

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

4 participants