-
Notifications
You must be signed in to change notification settings - Fork 21
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
❇️ Smart charging demo at CharIN #44
Comments
@drmrd @the-bay-kay @Giavotto @louisg1337 based on the discussion today, I think that this is the list of questions that we need to answer before the demo. At least a one of them will result in fallback plans, and I think there are at least two tasks for the OCPP smart charging implementation in here. Please let me know if I missed anything, and we can divvy up the tasks between NREL and AFS To figure out whether we can do this demo, we need to determine the following:
|
If Departure Time is omitted and the EVSE is attempting to run a smart charging session according to K15, the EVSE should provide a schedule greater than or equal to 24 hours. Check out [V2G2-304]: |
I read V2G2-303, should have gone on to V2G2-304 😄 |
|
It looks like ISO 151180-2 is at least sending the correct messages - I see a ChargeParameterDiscovery Req/Res pair
To see what is in the message, we can look at the code, or pull in the EXI message logging from the ISO 15118-2 DC demo, or see if we can enable EXI logging/decoding through EVerest @louisg1337 On the OCPP side, though, it looks like the sequence is
There is no NotifyXXX message sent, and no ChargingProfile set from the CSMS. @drmrd @Giavotto @louisg1337
@louisg1337 can you figure out what is in the current EXI messages for @shankari will send out a message to Citrine about their smart charging support and potential for hacking |
The current EXI messages are logged at |
OpenChargingCloud CSMSOCPP 2.0.1
OCPP 2.1 |
Even though CitrineOS lacks some features that we want, they at least have some way to set a charging profile and it seems like it can be set using a REST API. |
@louisg1337 couple of notes:
|
Actually, I take my comments about Citrine back - it looks like it does expose
However, the implementation still seems to be a NOP - I don't see anything being done there other than logging the message. It would be good to test out invoking calls from that endpoint and see if it actually makes it to the station. |
We are going to try to see if the calls are sent to the station. However, citrine currently doesn't support PnC (related PR: citrineos/citrineos-core#100). However, it also doesn't appear to support security profile 3
I don't see any mention of a TLS connection; only regular TCP. This means that EVerest has to communicate with it using security profile 1. In SP1, everest is configured to connect to port 80 with the password |
Since CitrineOS doesn't support SP3, and the open PR doesn't seem to add it either, briefly looking at what it would take to add this in MaEVe. It doesn't look too bad. I assume we are going for:
To have the |
I checked the logs and can verify that the messages from the charging station are being received through MQTT (more formally Charge Station -> websocket -> gateway -> mqtt -> manager). Checking |
From @louisg1337,
When looking at the API endpoints (http://localhost:8080/docs/ if you have Citrine running) he didn't see BasicAuthPassword anywhere. Further updates about this in the PR #45 |
I have the station connecting to the CSMS, but can't figure out how to add auth tokens. Once those are added, we should be able to charge. @louisg1337 can you try to build on this demo by setting the charging profile on the station? If it is easy, you could also figure out how to actually add new tokens to the CSMS. After that, thought, we should switch to MaEVe since I am not sure if Citrine supports SP3 |
@shankari CitrineOS has supported SP3 since the first full release in January, since SP3 is a part of the Advanced Security use cases. The System Configuration object contains the fields needed to provide keys & certificates for tls/mtls. We added additional documentation to help describe these fields, which you can find here. If you're having difficulty figuring out how CitrineOS supports a use case from one of its currently supported certification profiles, please reach out on Github or Discord. CitrineOS currently supports Core; Advanced Security; Advanced User Interface; Advanced Device Management; and, with the open PRs you linked, ISO15118. |
@thanaParis thank you for the quick response. It is great to hear that Citrine supports SP3. I think that what we are struggling with is that the documentation is not very clear, at least compared to MaEVe, and given the short time frame, we need to make a decision on which CSMS we should try to integrate with. For example, you say that CitrineOS supports SP3, but the documentation just says the following:
which port should we use for SP3? It is not clear. For the record, I tried to connect to both 8081 and 8082 using In contrast, MaEVe's documentation says:
Even with the documentation that you linked to, it is not clear what we need to do to enable SP3.
What do you mean by "the hostname for the websocket server"? You will presumably listen to 0.0.0.0, and the websocket connection will be initiated by the client running on the station. So which server hostname do we need to specify? We understand that we can get help on Discord or on GitHub, but they are slower - we have to formulate the question and wait for an answer. It is a lot easier if we can use the documentation directly at least for these basic steps and then reach out to the Discord/GitHub for more complex changes. To streamline this process, would you be open to modifying the "single line demos" that we have in this repo to showcase how to connect via SP1, SP2 and SP3, similar to #45? We have the certificates created, and they work with MaEVe - you can run If you could get Citrine to the same level, we could figure out what changes we need for the smart charging demo. |
@louisg1337 wrt looking at the ISO 15118-2 messages, I don't know if you saw https://lists.lfenergy.org/g/everest/message/1538 |
@louisg1337, great job on #45! While we working on review and merge that PR, and @thanaParis and CitrineOS take a look at the issue with the tokens, I would like to return to Can you try to invoke |
Exploring
I followed this through to the source code. The car simulator requires
The
or
pyjosev includes the python libraries from https://github.com/EVerest/ext-switchev-iso15118 we ask for 1 WH with a departure time of 0 and a bunch of other statically configured values. |
Although it looks like there are other, more complex schedules defined here as well with departure times and targetSoC. Next steps for mucking around with the EV SIL:
|
The more complex schedules are for -20 - they create |
Here's the call stack:
|
The
which is called right after we register the commands
and the simulator reads the values from the state
and uses it to
|
So for the SIL demo, I think we can do the following: No changes
WIth changes
We should then be able to experiment with other scenarios around power requests and/or departure times |
wrt viewing the messages so that we can see what is being sent and received, we cannot use wireshark just yet because the communication is between two modules in the same manager code. However, we can get the EXI messages using the logs and try to decode them. From #44 (comment), there is an online decoder or we can use At least for cbiexigen and the online decoder, we need the schemas:
EDIT: there are schemas here https://github.com/FlUxIuS/V2Gdecoder/tree/master/schemas. Notably @drmrd bumping this up again to see if you can provide a link to the EXI decode tool that you used in the initial set of demos. |
Unfortunately it seems like
Looking at the errors specifically, |
@louisg1337 the Can you provide additional details? How did you invoke the swagger call? What were the logs on Citrine? What were the logs on EVerest? Did you check the OCCP message logs on EVerest? If you add additional logs to |
@louisg1337 I think it would be worthwhile to fix the logging so that it is clear. We shouldn't expect that everybody pokes through the code to understand which layer has not implemented the function. Isn't it possible to change the error to say something like 🚧 Will mark this at TODO for now. 🚧 ; we should file a separate issue in Citrine and potentially contribute a fix |
Thanks to @barsnick, after adding some additional zeros at the end of the EXI message (now it is ChargeParameterDiscoveryRes<?xml version="1.0" encoding="UTF-8"?><ns7:V2G_Message xmlns:ns7="urn:iso:15118:2:2013:MsgDef" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns3="http://www.w3.org/2001/XMLSchema" xmlns:ns4="http://www.w3.org/2000/09/xmldsig#" xmlns:ns5="urn:iso:15118:2:2013:MsgBody" xmlns:ns6="urn:iso:15118:2:2013:MsgDataTypes" xmlns:ns8="urn:iso:15118:2:2013:MsgHeader">
<ns7:Header><ns8:SessionID>ED9AE77E6FFFEE3E</ns8:SessionID></ns7:Header>
<ns7:Body><ns5:ChargeParameterDiscoveryRes>
<ns5:ResponseCode>OK</ns5:ResponseCode>
<ns5:EVSEProcessing>Finished</ns5:EVSEProcessing>
<ns6:SAScheduleList>
<ns6:SAScheduleTuple>
<ns6:SAScheduleTupleID>1</ns6:SAScheduleTupleID>
<ns6:PMaxSchedule>
<ns6:PMaxScheduleEntry>
<ns6:RelativeTimeInterval><ns6:start>0</ns6:start><ns6:duration>86400</ns6:duration></ns6:RelativeTimeInterval>
<ns6:PMax><ns6:Multiplier>0</ns6:Multiplier><ns6:Unit>W</ns6:Unit><ns6:Value>22080</ns6:Value></ns6:PMax>
</ns6:PMaxScheduleEntry>
</ns6:PMaxSchedule>
</ns6:SAScheduleTuple>
</ns6:SAScheduleList>
<ns6:AC_EVSEChargeParameter>
<ns6:AC_EVSEStatus>
<ns6:NotificationMaxDelay>0</ns6:NotificationMaxDelay>
<ns6:EVSENotification>None</ns6:EVSENotification>
<ns6:RCD>false</ns6:RCD>
</ns6:AC_EVSEStatus>
<ns6:EVSENominalVoltage>
<ns6:Multiplier>-1</ns6:Multiplier><ns6:Unit>V</ns6:Unit><ns6:Value>0</ns6:Value>
</ns6:EVSENominalVoltage>
<ns6:EVSEMaxCurrent>
<ns6:Multiplier>-3</ns6:Multiplier><ns6:Unit>h</ns6:Unit><ns6:Value>0</ns6:Value>
</ns6:EVSEMaxCurrent>
</ns6:AC_EVSEChargeParameter>
</ns5:ChargeParameterDiscoveryRes></ns7:Body></ns7:V2G_Message> |
It is not clear why the EVSE is giving 22080 W at 0V and 0A. The |
@shankari I've had somewhat mixed results -- I've got the linuxserver wireshark container (docs) running, but there seem to be some issues with its interraction with WSL-2. Below are some notes on the setup, and where how I'm working to fix it and get it running! The Setup: WSL 2 on Windows 10Because I do not currently have access to my personal linux machine, and the demos do not work with my NREL laptop's M1-Chip (link), I'm running the docker image with the following setup on another personal computer: With this, I have successfully been able to spin up the cert demos with wireshark running in the background... But, when I attempt to connect to the wireshark application (docs) via 127.0.0.1:3000, 3001, or any similar port / url combo, it fails to connect... The IssueWhen inspecting the docker container, we get the following error: Of note is the line Solutions:It seems that, like with the M1 Chip, there's some inherent issues to the WSL approach -- adding wireshark appears to work otherwise! I'm currently getting VMWare Workstation 17 set up on this machine, and will report back once I run tests on a full Linux machine. For those curious, the wireshark addition to services:
# Other servces ...
wireshark:
image: lscr.io/linuxserver/wireshark:latest
container_name: wireshark |
You haven't exposed the appropriate port from the wireshark container. |
Current shouldn't have the unit "hours". 😉 |
Before going a lot further, let's test the other combinations (AC ISO 15118 + EIM, DC ISO 15118 + EIM and DC ISO 15118 + PnC). We will need to use at least the first two to test the HIL since we are not sure how to install certs on the vector ECCU. AC ISO 15118-2 with EIM
How does the car send this message? It would be super helpful to be able to see EXI decoded messages. Fortunately, by turning on debug logging for the car module, we are able to see all messages
So the server supports both
And we have
When we use a HIL EVCC, of course, it will only accept EIM, so we don't need to worry about this car simulator implementation just yet. But just for my own edification, I looked at how the energy mode is handled, and the answer is that it is read from the session,
which is in turn read from the state
I think that if we plumb that through, we should be able to handle this properly |
MaEVe ExplorationAPI Request The goal we had in mind was to see whether or not calling the
I have not observed Code Tracing After observing the above, I also wanted to trace through the MaEVe code to get a better understanding of how the API calls tracing, specifically triggers...
Note When I was tracing the code, the "calls made internally" section is how I originally thought Calls made internally (i.e.
|
MaEVe
|
@louisg1337 yes, |
To follow up on #44 (comment), I tried adding a new manager, hooking up the second connector to it, and expanding the options in the node-red dropdown. The new config and new node-red are attached.
new config file:
new nodered file
However, several of the combinations failed with weird errors. For example, the AC EIM test failed because the manager reported that only the We need to investigate this further, but for now, since the HIL demo runs on hardware with a single port , let's have stwo separate configs (AC and DC) and two separate nodered files (AC and DC). |
- Use a nodered flow that only supports AC ISO 15118-2 EIM and PnC - Patch SwitchEV to plumb through the payment option to the ISO 15118 library by following the EnergyTransfer route EVerest#44 (comment) https://lfenergy.zulipchat.com/#narrow/stream/417677-EVerest.3A-Car-com.2E/topic/.E2.9C.94.20Update.20Node-red.20flows.20because.20of.20JsEvManager.20commit/near/443617217 - Enable `iso15118car` debug logging so that we can see the decoded EXI messages in the absence of https://lfenergy.zulipchat.com/#narrow/stream/417677-EVerest.3A-Car-com.2E/topic/EXI.20V2G.20Decoder.20Recommendations/near/442318988 - disable the maeve patches to remove the LB since it is already removed in the updated branch Testing done: ``` patching file docker-compose.yml Patching the CSMS to enable local mo root patching file 'config/manager/config.toml' Patching the CSMS to enable local mo root patching file 'manager/handlers/ocpp201/authorize.go' Starting the CSMS ``` ``` [+] Running 4/4 ✔ Container maeve-csms-firestore-1 Running 0.0s ✔ Container maeve-csms-mqtt-1 Healthy 0.1s ✔ Container maeve-csms-manager-1 Healthy 0.2s ✔ Container maeve-csms-gateway-1 Started 0.2s Waiting 5s for CSMS to start... MaEVe CSMS started, adding charge station with Security Profile 3 (note: profiles in MaEVe start with 0 so SP-2 == OCPP SP-3) Charge station added, adding user token API calls to CSMS finished, starting EVerest... ``` ``` ✔ Network everest-ac-demo_default Created 0.1s ✔ Container everest-ac-demo-mqtt-server-1 Healthy 0.1s ✔ Container everest-ac-demo-nodered-1 Healthy 0.2s ✔ Container everest-ac-demo-manager-1 Healthy 0.1s Successfully copied 60.9kB to everest-ac-demo-nodered-1:/config/config-sil-two-evse-flow.json everest-ac-demo-nodered-1 Successfully copied 6.66kB to everest-ac-demo-manager-1:/ext/source/config/config-sil-ocpp201-pnc.yaml Successfully copied 8.19kB to everest-ac-demo-manager-1:/tmp/ Successfully copied 3.58kB to everest-ac-demo-manager-1:/ext/source/build/dist/etc/everest/default_logging.cfg fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/edge/testing/x86_64/APKINDEX.tar.gz (1/1) Installing patch (2.7.6-r9) Executing busybox-1.35.0-r29.trigger OK: 1379 MiB in 230 packages patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/controller/interface.py patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/controller/simulator.py patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/states/iso15118_2_states.py Successfully copied 29.2kB to everest-ac-demo-manager-1:/ext/source/build ``` ``` 2024-06-09 19:41:31.667368 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"04337FC4777FB77D"},"Body":{"ServiceDiscoveryRes":{"ResponseCode":"OK","PaymentOptionList":{"PaymentOption":["ExternalPayment","Contract"]},"ChargeService":{"ServiceID":1,"ServiceCategory":"EVCharging","FreeService":false,"SupportedEnergyTransferMode":{"EnergyTransferMode":["AC_single_phase_core","AC_three_phase_core"]}},"ServiceList":{"Service":[{"ServiceID":2,"ServiceName":"Certificate","ServiceCategory":"ContractCertificate","FreeService":true}]}}}}} 2024-06-09 19:41:31.670311 [WARN] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: V2G_PAYMENT: in function read value from state AuthEnum.PNC_V2 2024-06-09 19:41:31.671413 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "04337FC4777FB77D"}, "Body": {"PaymentServiceSelectionReq": {"SelectedPaymentOption": "Contract", "SelectedServiceList": {"SelectedService": [{"ServiceID": 1}]}}}}} 2024-06-09 19:41:34.155595 [INFO] ocpp:OCPP201 :: CSMS certificate status: Accepted 2024-06-09 19:41:34.159815 [INFO] auth:Auth :: Providing authorization to connector#1 2024-06-09 19:41:35.873697 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "04337FC4777FB77D"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 0, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-06-09 19:41:36.948664 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"04337FC4777FB77D"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":22080}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":320}}}}}} ```
- Use a nodered flow that only supports AC ISO 15118-2 EIM and PnC - Patch SwitchEV to plumb through the payment option to the ISO 15118 library by following the EnergyTransfer route EVerest#44 (comment) https://lfenergy.zulipchat.com/#narrow/stream/417677-EVerest.3A-Car-com.2E/topic/.E2.9C.94.20Update.20Node-red.20flows.20because.20of.20JsEvManager.20commit/near/443617217 - Enable `iso15118car` debug logging so that we can see the decoded EXI messages in the absence of https://lfenergy.zulipchat.com/#narrow/stream/417677-EVerest.3A-Car-com.2E/topic/EXI.20V2G.20Decoder.20Recommendations/near/442318988 - disable the maeve patches to remove the LB since it is already removed in the updated branch Testing done: ``` patching file docker-compose.yml Patching the CSMS to enable local mo root patching file 'config/manager/config.toml' Patching the CSMS to enable local mo root patching file 'manager/handlers/ocpp201/authorize.go' Starting the CSMS ``` ``` [+] Running 4/4 ✔ Container maeve-csms-firestore-1 Running 0.0s ✔ Container maeve-csms-mqtt-1 Healthy 0.1s ✔ Container maeve-csms-manager-1 Healthy 0.2s ✔ Container maeve-csms-gateway-1 Started 0.2s Waiting 5s for CSMS to start... MaEVe CSMS started, adding charge station with Security Profile 3 (note: profiles in MaEVe start with 0 so SP-2 == OCPP SP-3) Charge station added, adding user token API calls to CSMS finished, starting EVerest... ``` ``` ✔ Network everest-ac-demo_default Created 0.1s ✔ Container everest-ac-demo-mqtt-server-1 Healthy 0.1s ✔ Container everest-ac-demo-nodered-1 Healthy 0.2s ✔ Container everest-ac-demo-manager-1 Healthy 0.1s Successfully copied 60.9kB to everest-ac-demo-nodered-1:/config/config-sil-two-evse-flow.json everest-ac-demo-nodered-1 Successfully copied 6.66kB to everest-ac-demo-manager-1:/ext/source/config/config-sil-ocpp201-pnc.yaml Successfully copied 8.19kB to everest-ac-demo-manager-1:/tmp/ Successfully copied 3.58kB to everest-ac-demo-manager-1:/ext/source/build/dist/etc/everest/default_logging.cfg fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/edge/testing/x86_64/APKINDEX.tar.gz (1/1) Installing patch (2.7.6-r9) Executing busybox-1.35.0-r29.trigger OK: 1379 MiB in 230 packages patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/controller/interface.py patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/controller/simulator.py patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/states/iso15118_2_states.py Successfully copied 29.2kB to everest-ac-demo-manager-1:/ext/source/build ``` ``` 2024-06-09 19:41:31.667368 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"04337FC4777FB77D"},"Body":{"ServiceDiscoveryRes":{"ResponseCode":"OK","PaymentOptionList":{"PaymentOption":["ExternalPayment","Contract"]},"ChargeService":{"ServiceID":1,"ServiceCategory":"EVCharging","FreeService":false,"SupportedEnergyTransferMode":{"EnergyTransferMode":["AC_single_phase_core","AC_three_phase_core"]}},"ServiceList":{"Service":[{"ServiceID":2,"ServiceName":"Certificate","ServiceCategory":"ContractCertificate","FreeService":true}]}}}}} 2024-06-09 19:41:31.670311 [WARN] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: V2G_PAYMENT: in function read value from state AuthEnum.PNC_V2 2024-06-09 19:41:31.671413 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "04337FC4777FB77D"}, "Body": {"PaymentServiceSelectionReq": {"SelectedPaymentOption": "Contract", "SelectedServiceList": {"SelectedService": [{"ServiceID": 1}]}}}}} 2024-06-09 19:41:34.155595 [INFO] ocpp:OCPP201 :: CSMS certificate status: Accepted 2024-06-09 19:41:34.159815 [INFO] auth:Auth :: Providing authorization to connector#1 2024-06-09 19:41:35.873697 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "04337FC4777FB77D"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 0, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-06-09 19:41:36.948664 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"04337FC4777FB77D"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":22080}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":320}}}}}} ``` Signed-off-by: Shankari <k.shankari@ee.doe.gov>
- Use a nodered flow that only supports AC ISO 15118-2 EIM and PnC - Patch SwitchEV to plumb through the payment option to the ISO 15118 library by following the EnergyTransfer route EVerest#44 (comment) https://lfenergy.zulipchat.com/#narrow/stream/417677-EVerest.3A-Car-com.2E/topic/.E2.9C.94.20Update.20Node-red.20flows.20because.20of.20JsEvManager.20commit/near/443617217 - Enable `iso15118car` debug logging so that we can see the decoded EXI messages in the absence of https://lfenergy.zulipchat.com/#narrow/stream/417677-EVerest.3A-Car-com.2E/topic/EXI.20V2G.20Decoder.20Recommendations/near/442318988 - disable the maeve patches to remove the LB since it is already removed in the updated branch Testing done: ``` patching file docker-compose.yml Patching the CSMS to enable local mo root patching file 'config/manager/config.toml' Patching the CSMS to enable local mo root patching file 'manager/handlers/ocpp201/authorize.go' Starting the CSMS ``` ``` [+] Running 4/4 ✔ Container maeve-csms-firestore-1 Running 0.0s ✔ Container maeve-csms-mqtt-1 Healthy 0.1s ✔ Container maeve-csms-manager-1 Healthy 0.2s ✔ Container maeve-csms-gateway-1 Started 0.2s Waiting 5s for CSMS to start... MaEVe CSMS started, adding charge station with Security Profile 3 (note: profiles in MaEVe start with 0 so SP-2 == OCPP SP-3) Charge station added, adding user token API calls to CSMS finished, starting EVerest... ``` ``` ✔ Network everest-ac-demo_default Created 0.1s ✔ Container everest-ac-demo-mqtt-server-1 Healthy 0.1s ✔ Container everest-ac-demo-nodered-1 Healthy 0.2s ✔ Container everest-ac-demo-manager-1 Healthy 0.1s Successfully copied 60.9kB to everest-ac-demo-nodered-1:/config/config-sil-two-evse-flow.json everest-ac-demo-nodered-1 Successfully copied 6.66kB to everest-ac-demo-manager-1:/ext/source/config/config-sil-ocpp201-pnc.yaml Successfully copied 8.19kB to everest-ac-demo-manager-1:/tmp/ Successfully copied 3.58kB to everest-ac-demo-manager-1:/ext/source/build/dist/etc/everest/default_logging.cfg fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/edge/testing/x86_64/APKINDEX.tar.gz (1/1) Installing patch (2.7.6-r9) Executing busybox-1.35.0-r29.trigger OK: 1379 MiB in 230 packages patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/controller/interface.py patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/controller/simulator.py patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/states/iso15118_2_states.py Successfully copied 29.2kB to everest-ac-demo-manager-1:/ext/source/build ``` ``` 2024-06-09 19:41:31.667368 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"04337FC4777FB77D"},"Body":{"ServiceDiscoveryRes":{"ResponseCode":"OK","PaymentOptionList":{"PaymentOption":["ExternalPayment","Contract"]},"ChargeService":{"ServiceID":1,"ServiceCategory":"EVCharging","FreeService":false,"SupportedEnergyTransferMode":{"EnergyTransferMode":["AC_single_phase_core","AC_three_phase_core"]}},"ServiceList":{"Service":[{"ServiceID":2,"ServiceName":"Certificate","ServiceCategory":"ContractCertificate","FreeService":true}]}}}}} 2024-06-09 19:41:31.670311 [WARN] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: V2G_PAYMENT: in function read value from state AuthEnum.PNC_V2 2024-06-09 19:41:31.671413 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "04337FC4777FB77D"}, "Body": {"PaymentServiceSelectionReq": {"SelectedPaymentOption": "Contract", "SelectedServiceList": {"SelectedService": [{"ServiceID": 1}]}}}}} 2024-06-09 19:41:34.155595 [INFO] ocpp:OCPP201 :: CSMS certificate status: Accepted 2024-06-09 19:41:34.159815 [INFO] auth:Auth :: Providing authorization to connector#1 2024-06-09 19:41:35.873697 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "04337FC4777FB77D"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 0, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-06-09 19:41:36.948664 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"04337FC4777FB77D"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":22080}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":320}}}}}} ``` Signed-off-by: Shankari <k.shankari@ee.doe.gov>
For the record, we have also now plumbed through setChargingProfile support in MaEVe so that we can showcase PnC with SmartCharging (at least in the SIL, and even in the HIL if we can get the certs configured correctly). And have cleaned up the demo to support both PnC and EIM with ISO 15118. The NREL HIL we will use only supports EIM, and this also gives us flexibility during the testival. Both Louis and I have verified that we can run it successfully to the level that the charge session starts; setChargingProfile, of course, is still unimplemented. |
We also need to be able to limit the power for testing at NREL (and potentially elsewhere). Now, we would do this using the micromegawatt charger BSP https://lfenergy.zulipchat.com/#narrow/stream/417678-EVerest.3A-Framework-.26-Tools/topic/Configuring.20the.20uMWC/near/442699434 But the version of everest currently installed on the uMWC is older and does not support that config option. We are trying the
|
@couryrr-afs has created an updated image, but it is built off the current head. So we need to address the simulator and node-red changes that were introduced in the interim. These are primarily:
Given that none of these are related to certs and it would be desirable to demo PnC and smart charging together, let's try to fix these three issues tonight and focus on getting SP3 MaEVe to work. |
This is no longer required given 3372b2b And it can potentially break given EVerest#44 (comment) given that our simulator has a single port, let's restore to simplicity Signed-off-by: Shankari <k.shankari@ee.doe.gov>
- Use a nodered flow that only supports AC ISO 15118-2 EIM and PnC - Patch SwitchEV to plumb through the payment option to the ISO 15118 library by following the EnergyTransfer route EVerest#44 (comment) https://lfenergy.zulipchat.com/#narrow/stream/417677-EVerest.3A-Car-com.2E/topic/.E2.9C.94.20Update.20Node-red.20flows.20because.20of.20JsEvManager.20commit/near/443617217 - Enable `iso15118car` debug logging so that we can see the decoded EXI messages in the absence of https://lfenergy.zulipchat.com/#narrow/stream/417677-EVerest.3A-Car-com.2E/topic/EXI.20V2G.20Decoder.20Recommendations/near/442318988 - disable the maeve patches to remove the LB since it is already removed in the updated branch Testing done: ``` patching file docker-compose.yml Patching the CSMS to enable local mo root patching file 'config/manager/config.toml' Patching the CSMS to enable local mo root patching file 'manager/handlers/ocpp201/authorize.go' Starting the CSMS ``` ``` [+] Running 4/4 ✔ Container maeve-csms-firestore-1 Running 0.0s ✔ Container maeve-csms-mqtt-1 Healthy 0.1s ✔ Container maeve-csms-manager-1 Healthy 0.2s ✔ Container maeve-csms-gateway-1 Started 0.2s Waiting 5s for CSMS to start... MaEVe CSMS started, adding charge station with Security Profile 3 (note: profiles in MaEVe start with 0 so SP-2 == OCPP SP-3) Charge station added, adding user token API calls to CSMS finished, starting EVerest... ``` ``` ✔ Network everest-ac-demo_default Created 0.1s ✔ Container everest-ac-demo-mqtt-server-1 Healthy 0.1s ✔ Container everest-ac-demo-nodered-1 Healthy 0.2s ✔ Container everest-ac-demo-manager-1 Healthy 0.1s Successfully copied 60.9kB to everest-ac-demo-nodered-1:/config/config-sil-two-evse-flow.json everest-ac-demo-nodered-1 Successfully copied 6.66kB to everest-ac-demo-manager-1:/ext/source/config/config-sil-ocpp201-pnc.yaml Successfully copied 8.19kB to everest-ac-demo-manager-1:/tmp/ Successfully copied 3.58kB to everest-ac-demo-manager-1:/ext/source/build/dist/etc/everest/default_logging.cfg fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/main/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/v3.17/community/x86_64/APKINDEX.tar.gz fetch https://dl-cdn.alpinelinux.org/alpine/edge/testing/x86_64/APKINDEX.tar.gz (1/1) Installing patch (2.7.6-r9) Executing busybox-1.35.0-r29.trigger OK: 1379 MiB in 230 packages patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/controller/interface.py patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/controller/simulator.py patching file source/build/dist/libexec/everest/3rd_party/josev/iso15118/evcc/states/iso15118_2_states.py Successfully copied 29.2kB to everest-ac-demo-manager-1:/ext/source/build ``` ``` 2024-06-09 19:41:31.667368 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"04337FC4777FB77D"},"Body":{"ServiceDiscoveryRes":{"ResponseCode":"OK","PaymentOptionList":{"PaymentOption":["ExternalPayment","Contract"]},"ChargeService":{"ServiceID":1,"ServiceCategory":"EVCharging","FreeService":false,"SupportedEnergyTransferMode":{"EnergyTransferMode":["AC_single_phase_core","AC_three_phase_core"]}},"ServiceList":{"Service":[{"ServiceID":2,"ServiceName":"Certificate","ServiceCategory":"ContractCertificate","FreeService":true}]}}}}} 2024-06-09 19:41:31.670311 [WARN] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: V2G_PAYMENT: in function read value from state AuthEnum.PNC_V2 2024-06-09 19:41:31.671413 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "04337FC4777FB77D"}, "Body": {"PaymentServiceSelectionReq": {"SelectedPaymentOption": "Contract", "SelectedServiceList": {"SelectedService": [{"ServiceID": 1}]}}}}} 2024-06-09 19:41:34.155595 [INFO] ocpp:OCPP201 :: CSMS certificate status: Accepted 2024-06-09 19:41:34.159815 [INFO] auth:Auth :: Providing authorization to connector#1 2024-06-09 19:41:35.873697 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Message to encode (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message": {"Header": {"SessionID": "04337FC4777FB77D"}, "Body": {"ChargeParameterDiscoveryReq": {"RequestedEnergyTransferMode": "AC_three_phase_core", "AC_EVChargeParameter": {"DepartureTime": 0, "EAmount": {"Value": 60, "Multiplier": 0, "Unit": "Wh"}, "EVMaxVoltage": {"Value": 400, "Multiplier": 0, "Unit": "V"}, "EVMaxCurrent": {"Value": 32000, "Multiplier": -3, "Unit": "A"}, "EVMinCurrent": {"Value": 10, "Multiplier": 0, "Unit": "A"}}}}}} 2024-06-09 19:41:36.948664 [DEBG] iso15118_car pybind11_init_everestpy(pybind11::module_&)::<lambda(const std::string&)> :: Decoded message (ns=urn:iso:15118:2:2013:MsgDef): {"V2G_Message":{"Header":{"SessionID":"04337FC4777FB77D"},"Body":{"ChargeParameterDiscoveryRes":{"ResponseCode":"OK","EVSEProcessing":"Finished","SAScheduleList":{"SAScheduleTuple":[{"SAScheduleTupleID":1,"PMaxSchedule":{"PMaxScheduleEntry":[{"RelativeTimeInterval":{"start":0,"duration":86400},"PMax":{"Multiplier":0,"Unit":"W","Value":22080}}]}}]},"AC_EVSEChargeParameter":{"AC_EVSEStatus":{"NotificationMaxDelay":0,"EVSENotification":"None","RCD":false},"EVSENominalVoltage":{"Multiplier":-1,"Unit":"V","Value":2300},"EVSEMaxCurrent":{"Multiplier":-1,"Unit":"A","Value":320}}}}}} ``` Signed-off-by: Shankari <k.shankari@ee.doe.gov> Signed-off-by: the-bay-kay <katie.risc@gmail.com>
@couryrr-afs @drmrd I am a bit confused about the version of libocpp in the docker image that @couryrr-afs created.
However, this is generating several changes that I definitely did not make - including several changes in OCPP 1.6 diff -r -uw lib/ocpp/common/database/database_connection.cpp /tmp/create_patches/libocpp/lib/ocpp/common/database/database_connection.cpp
--- lib/ocpp/common/database/database_connection.cpp 2024-06-12 08:52:38
+++ /tmp/create_patches/libocpp/lib/ocpp/common/database/database_connection.cpp 2024-06-11 14:29:41
@@ -63,6 +63,7 @@
// Add special exception for databases in ram; we don't need to create a path for them
if (this->database_file_path.string().find(":memory:") == std::string::npos and
+ this->database_file_path.string().find("mode=memory") == std::string::npos and
!fs::exists(this->database_file_path.parent_path())) {
fs::create_directories(this->database_file_path.parent_path());
}
diff -r -uw lib/ocpp/common/websocket/websocket_libwebsockets.cpp /tmp/create_patches/libocpp/lib/ocpp/common/websocket/websocket_libwebsockets.cpp
--- lib/ocpp/common/websocket/websocket_libwebsockets.cpp 2024-06-12 08:52:38
+++ /tmp/create_patches/libocpp/lib/ocpp/common/websocket/websocket_libwebsockets.cpp 2024-06-11 14:29:41
@@ -208,7 +208,7 @@
WebsocketTlsTPM::WebsocketTlsTPM(const WebsocketConnectionOptions& connection_options,
std::shared_ptr<EvseSecurity> evse_security) :
- WebsocketBase(), evse_security(evse_security) {
+ WebsocketBase(), evse_security(evse_security), stop_deferred_handler(false) { I double checked the code and:
So it seems pretty clear that the container does not seem to have pulled from the correct branch, and I wonder if this is the cause of the demo issues we have had. I am going to switch back to main and find the diffs and see if they are more meaningful. But somebody needs to check the resulting container and verify that the correct code is actually in place. EDIT: There are also significant differences from main. I don't know where this branch came from. So I will cherry-pick my changes only as a patch. EDIT: Spun up a new container, copied out the libocpp and used |
At this point, the SIL demo works for me although it is definitely "patchy" 🩹 Then we need to start the long and tedious process of incorporating the patches in actual code and backing them out of the demo script. In the meanwhile, I will move on to the HIL 🤞 |
Glad this is coming together @shankari! I'm working on a patch this morning for the 1ph vs. 3ph issue we encountered when running E2E yesterday. I'll reach out or come find you if I have build questions. |
@shankari: I haven't been able to test that this actually works E2E, but the following (very hacky) patch for everest-core should™: diff --git a/modules/EvseManager/EvseManager.cpp b/modules/EvseManager/EvseManager.cpp
index 8f8cd979..19df5119 100644
--- a/modules/EvseManager/EvseManager.cpp
+++ b/modules/EvseManager/EvseManager.cpp
@@ -1045,6 +1045,7 @@ bool EvseManager::updateLocalEnergyLimit(types::energy::ExternalLimits l) {
updateLocalMaxWattLimit(get_powersupply_capabilities().max_export_power_W);
}
} else {
+ EVLOG_info << "Setting the following external limits on energy node" << l;
// apply external limits if they are lower
local_energy_limits = l;
}
diff --git a/modules/OCPP201/OCPP201.cpp b/modules/OCPP201/OCPP201.cpp
index ca859750..833ed213 100644
--- a/modules/OCPP201/OCPP201.cpp
+++ b/modules/OCPP201/OCPP201.cpp
@@ -583,13 +583,18 @@ void OCPP201::set_external_limits(const std::map<int32_t, ocpp::v201::CompositeS
types::energy::LimitsReq limits_req;
const auto timestamp = start_time.to_time_point() + std::chrono::seconds(period.startPeriod);
schedule_req_entry.timestamp = ocpp::DateTime(timestamp).to_rfc3339();
+ auto limit = period.limit;
if (schedule.chargingRateUnit == ocpp::v201::ChargingRateUnitEnum::A) {
- limits_req.ac_max_current_A = period.limit;
if (period.numberPhases.has_value()) {
limits_req.ac_max_phase_count = period.numberPhases.value();
+ // Hack to address single phase AC charging
+ if (period.numberPhases.value() == 1) {
+ limit *= 3;
+ }
}
+ limits_req.ac_max_current_A = limit;
} else {
- limits_req.total_power_W = period.limit;
+ limits_req.total_power_W = limit;
}
schedule_req_entry.limits_to_leaves = limits_req;
schedule_import.push_back(schedule_req_entry);
It'd also be worth testing if AC 3ph or DC profiles work as expected. The main issue here is that we have yet to work through the card that addresses power limit calculations, since it requires adding plumbing in everest-core: https://github.com/US-JOET/base-camp/issues/111 |
@drmrd As I indicated, I am busy with setting up HIL. Can AFS please make all the changes and test them so that I can have a good build to put on the HIL? I am also fine with skipping the hack if it works for AC 3-phase, but I would like that to be tested, and the appropriate config provided to me. |
The smart charging demo works with multiple patches and will be demoed at the JO All-Hands in the next couple of works. |
In a few short weeks, we are going to try to pull together a demo for CharIN, to be held in Cleveland from June 11-14. Given that we have been working on smart charging recently, the goal is to try and demo basic, end to end smart charging.
So this flow diagram:
The text was updated successfully, but these errors were encountered: