-
Notifications
You must be signed in to change notification settings - Fork 22
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
↔️ 💩 K12/K14 (if possible): hack together a hook up of the external charging limit from the UI to the CSMS #101
Comments
The slider sends an MQTT message
which calls
which calls
Not sure how/where this is stored.
and it may still do that, but it is not a direct call since the subscribe callback invokes |
With some more logging, we see that, consistent with #92,
Moving the slider sets the current limit until it is reset.
The reset must happen from |
Logs from the reset
|
However, the
So the next steps should be:
@Abby-Wheelis for visibility |
The computation for the composite schedule reads all valid profiles and iterates through them. So we should be able to call The CSMS response to |
The value from the CSMS is set using (effectively)
Presumably we will not want to call |
So I believe that the internal MQTT communication is through "interfaces", defined in The OCPP module defines 5 interfaces
However, checking the interfaces, I don't see any option to receive a charging profile in any of those interfaces. https://github.com/EVerest/everest-core/blob/main/interfaces/ocpp.yaml I think we will want to essentially plumb through a |
For an example of calling methods in other modules, https://github.com/EVerest/everest-core/tree/3401718254fc6ac2c6e741c5b9db83b5bbc80dc6/modules/OCPPExtensionExample seems like a good, simple example that calls OCPP. We will need to add OCPP as a dependency into one of the other modules to call this method. I think that, at least for a first pass, it makes sense that we should call this directly from While this is a first pass/hack, there might be better options and we should discuss this with the community for longer-term planning. This would involve adding the new dependency to |
Actually, I take this back. I think it might be better to hook it up to the "API" module. In the real world, it is not clear how the EMS signals will come in to EVerest, but it makes more sense that it would be through an "API" module instead of the "EnergyManager" module. The "API" module already depends on both EVSEManager and OCPP, so we would not have to complicate the dependency chain further. And it is designed for "exposing some internal functionality on an external MQTT connection". So it should have access to MQTT. Let's see if we can listen to the same node-red message in API and republish it (that's sort of the point of pub-sub in the first place). |
Ah, it looks like this will be good - EVSE manager listens to these commands
And "API" listens to them too, including to
|
The note for
This was refactored two months ago, so is not in the latest stable release from Sept ( The copy that we have checked out also has a We need to see if the community agrees! |
Naive change is not doing anything.
But
Let's add some logs to understand further |
Having issues recompiling with the changes. Notably, when I tried to call
This failed because |
Running into mismatch in function signatures, but they look identical to me!
is
|
I temporarily changed the definition of set_charging_profile to take no arguments and return a boolean,
After changing the hpp file, I get
so the original mismatch must have been between hpp and cpp. Making the same changes to the cpp, I still get the error. This is a weird issue in the cpp and I just have to poke at it until it works. |
Ah it is because we have an implementation in the OCPP201 module, but not the OCPP module. Adding it to both, with the 1.6 implementation as a NOP. |
wrt #101 (comment) the reason is because the format of the message is different.
Switching to the new message format, it werks!
Although the resetting is still happening. Let's just quickly add the call from the API to the |
Although the API could use the OCPP module, the config we were using did not have it as a dependency.
The API then calls the EVSE manager to set the limit to 7.6
And then we receive a
I haven't populated the @Abby-Wheelis this is all yours now! |
I have attached patches of the changes that I have made so far. The changes were to:
I have attached:
I described them instead of just checking them in and creating a PR because:
@Abby-Wheelis LMK if you need any additional support |
Note that, instead of creating the along with the
|
After applying the patches, I tried to build, but there were error messages during the build. It still seemed to complete the build, just slowly. Are these errors normal?
|
@Abby-Wheelis given that the process was terminated, it looks like you just might not have enough memory. When I tried to build, the process terminated at 16GB but completed at 24GB RAM. I also have 250 GB disk allocated to docker, although I didn't try changing that slowly, so you probably don't need that much. |
My personal laptop that I'm testing on right now only has 8GB of memory, so that could be the issue! |
I bumped it from 6 (what it was set to) to 8 and still see the errors, I can try on my work laptop next |
I am able to get a charging session to start, and when I move the slider there is a change in the charging behavior, but it is still only temporary, which is to be expected:
I'm also a little worried that I'm not seeing the right logging messages, which makes me think that a) I applied the patches wrong or b) since the build is failing it is just defaulting to some older version. The first spot I see room for error on the patches with is the nodered changes, which I'm not sure at all if I got right, and if the signal is never sent, then none of the resulting changes will happen, regardless of if the patches are implemented. I'm also seeing lots of errors from OCPP about timeout and failed connection, so I need to figure out what has gone wrong there. |
These are the repeated OCPP errors that I see:
These could very likely be related to the fact that OCPP is one of the sources of build/compile errors, so it could just BE broken on this installation. In my Docker Desktop, 3/4 Maeve containers are down, and will not start up from the UI an don't start when I start up the manager, either, so that's very likely the problem - if one piece isn't running they surely can't contact each other. I can try wiping and rebuilding, but it seems the real problem is my tech limits... |
Trying on my work laptop again, and the build process fails in the same way it does on my personal computer with the process being terminated, and my resources are as high as they go. |
Now I have a loaner laptop with some more resources and can build, slowly. I changed the number of jobs to run in parallel to 1 I am seeing the new log messages when I move the slider now! So it seems that the API module is recieving the message from MQTT when I move the slider.
The next task is making sure that the limit sticks around. @shankari do you have any more patches that you've made or should I proceed with what you posted here? |
@Abby-Wheelis no additional patches, sorry. have been busy with other tasks. You should proceed with what I have posted. Just to clarify: the logs above just show that the change makes it to the EVSE manager. We need to make sure that it makes it through from the EVSE manager to the OCPP module so that we can save it as part of the charging profiles, and send it up to the CSMS. That is the log line
I think you are not seeing that because ocpp is not configured as a "connection" to the API module, so the value from the slider will still be
You need to edit the config.yaml per #101 (comment) |
We don't have a local controller in the demo - only a station talking directly to the CSMS. So what we really need is K12 and if possible, K11. |
A couple of UI updates to enable resetting the limit. This includes the change to send the limit (8 in #101 (comment)). config-sil-iso15118-ac-flow.json In the slider element in the nodered flow, there is a checkbox for "pass input msg into output" and leaving that unchecked should keep resetting the slider from sending out the limit as 16, but that behavior is something to watch for, it was a little buggy when I was testing, and hard to test since the limit still resets regularly. |
Quick update: I think I have everything hooked up now!
However it is still not working as intended because of the following issues
Logs from a single adjustment of the slider below the foldWe first receive a
Then we receive a
However, it doesn't show up in the next composite schedule computed
|
This is because the composite schedule is apparently invalid
The periodic call is from the OCPP module -> charge point's |
So this is a bit weird. We do validate the profile before we save it, and it is valid then
But it is apparently not valid when we use it to compute the composite schedule
In the second case, we error out after So it is probably that the |
Aha! The code for `verify_no_conflicting_external_constraints_id` fails if there is an external constraints profile with the same ID as the one being validated.ProfileValidationResultEnum
SmartChargingHandler::verify_no_conflicting_external_constraints_id(const ChargingProfile& profile) const {
auto result = ProfileValidationResultEnum::Valid;
auto conflicts_stmt =
this->database_handler.new_statement("SELECT PROFILE FROM CHARGING_PROFILES WHERE ID = @profile_id AND "
"CHARGING_PROFILE_PURPOSE = 'ChargingStationExternalConstraints'");
conflicts_stmt->bind_int("@profile_id", profile.id);
if (conflicts_stmt->step() == SQLITE_ROW) {
result = ProfileValidationResultEnum::ExistingChargingStationExternalConstraints;
}
return result; So it is guaranteed to fail while validating an external constraints profile. So, as written, `validate_profile` will fail for all external constraint profiles, which contradicts this comment at the end result = verify_no_conflicting_external_constraints_id(profile);
if (result != ProfileValidationResultEnum::Valid) {
return result;
}
...
switch (profile.chargingProfilePurpose) {
...
case ChargingProfilePurposeEnum::ChargingStationExternalConstraints:
// TODO: How do we check this? We shouldn't set it in
// `SetChargingProfileRequest`, but that doesn't mean they're always
// invalid. K01.FR.05 is the only thing that seems relevant.
result = ProfileValidationResultEnum::Valid;
break;
} I am not sure why this was added, working around it by only invoking UPDATE: That worked!
|
Next, we want to verify that this is actually sent to the CSMS. I don't see a timeout for the Let's verify this by:
|
MaEVe MQTT shows that it receives this message
but then it fails with a
Let's try to add a simple implementation so we can make sure that we are at least fully implemented end-to-end on our side including receiving the response properly. |
wrt:
from the details in #101 (comment) After reinstating, we get the same `NotImplemented` for `set_current_limit` as well
|
I have now plumbed through the code needed to implement I do want to document the process for testing out changes to MaEVe, since within NREL, we have issues with SSL certs while trying to download go modules. The steps are:
I'm going to check this code in now, though, so we will build new images for the demo/testing. |
So that we can finish testing the EVerest changes in EVerest/everest-demo#101 end-to-end I have not yet plumbed through the changes to `clear_charging_limit` but they should be fairly simple, and I can leave them as an exercise for @Abby-Wheelis Outline of changes: - add `notify_charging_limit` to the `CallMap`, and have it redirect to the `notify_charging_limit_handler` - add a handler for the `notify_charging_limit` - add classes for the request and response that we can use in the handler Testing done: Without this change: EVerest/everest-demo#101 (comment) With this change: ``` 2025-01-27 02:36:16.234166 [INFO] ocpp:OCPP201 :: Received internal set_charging_limit: for 1 with purpose 15 2025-01-27 02:36:16.234471 [INFO] ocpp:OCPP201 :: SHANKARI: Invoking validate_and_add_profile with 1 and source EMS 2025-01-27 02:36:16.234598 [INFO] evse_manager_1: :: set_max_current (14, 2025-01-27 02:36:26.094000000) called 2025-01-27 02:36:16.234517 [INFO] ocpp:OCPP201 :: SHANKARI: invoked validate_profile for evse_id: 1 and profile { "chargingProfileKind": "Absolute", "chargingProfilePurpose": "ChargingStationExternalConstraints", "chargingSchedule": [ { "chargingRateUnit": "A", "chargingSchedulePeriod": [ { "limit": 15.0, "startPeriod": 0 } ], "duration": 86400, "id": 0, "startSchedule": "2025-01-27T02:36:16.234Z" } ], "id": 398, "stackLevel": 10 } 2025-01-27 02:36:16.234902 [INFO] ocpp:OCPP201 :: SHANKARI: after validating file request source 2025-01-27 02:36:16.234926 [INFO] ocpp:OCPP201 :: SHANKARI: after validating conflicting external constraints 2025-01-27 02:36:16.235939 [INFO] ocpp:OCPP201 :: SHANKARI: before validating by purpose 2025-01-27 02:36:16.235974 [INFO] ocpp:OCPP201 :: SHANKARI: should return valid here! 2025-01-27 02:36:16.235986 [INFO] ocpp:OCPP201 :: SHANKARI: result for 1 is Valid 2025-01-27 02:36:16.236010 [INFO] ocpp:OCPP201 :: SHANKARI: Modifying database 2025-01-27 02:36:16.243501 [INFO] ocpp:OCPP201 :: Returning from on_charging_limit_set with 1 and status Accepted ``` ``` {"type":2,"action":"NotifyChargingLimit","id":"feda7835-c7d5-4717-8df6-79cdc5b17e9c","request":{"chargingLimit":{"chargingLimitSource":"EMS"},"chargingSchedule":[{"chargingRateUnit":"A","chargingSchedulePeriod":[{"limit":15.0,"startPeriod":0}],"duration":86400,"id":0,"startSchedule":"2025-01-27T02:36:16.234Z"}],"evseId":1}} {"type":3,"action":"NotifyChargingLimit","id":"feda7835-c7d5-4717-8df6-79cdc5b17e9c","response":{}} ```
New tasks:
|
Works! Although because I implement it by clearing all profiles, the max current only changes when the composite schedules are next computed. Would be good to change that, but it seems non-obvious from an architectural perspective, and probably needs coordination with the community. Concretely, we want to reset to the default hw capability, but:
I think I am going to work around this by having the clear command send the max limit for now |
For "publish images and generate patches so we can submit PRs down the road", I have committed all the relevant containers, and will switch docker-compose to use them for now. I am also uploading the patches that I am aware of before I delete the containers and test after re-creating them. These are the same patches as #101 (comment)
|
…hanges Changes: - EVerest manager uses the changes to receive a limit through the API, pass it through to the OCPP module, store it in the database and use it to influence the power limits - Node-red sends the correct MQTT messages - MaEVe manager has an NOP implementation of notify limit The actual changes/patches are listed here and will need to be merged in one step at a time EVerest#101 (comment) Testing done: ``` $ bash demo-iso15118-2-ocpp-201.sh -1 -r $(pwd) -m $ docker exec -it everest-ac-demo-manager-1 /bin/bas (container) $ sh /ext/build/run-scripts/run-sil-ocpp201-pnc.sh ``` Then - moved the slider to various points, the max current changed - plugged in car, handshake was successful - moved the slider while the car was plugged in, max current changed and power drawn changed - cleared limit, max current went to 16 and max power went to 11kW Signed-off-by: Shankari <[email protected]>
…hanges Changes: - EVerest manager uses the changes to receive a limit through the API, pass it through to the OCPP module, store it in the database and use it to influence the power limits - Node-red sends the correct MQTT messages - MaEVe manager has an NOP implementation of notify limit The actual changes/patches are listed here and will need to be merged in one step at a time EVerest#101 (comment) Testing done: ``` $ bash demo-iso15118-2-ocpp-201.sh -1 -r $(pwd) -m $ docker exec -it everest-ac-demo-manager-1 /bin/bas (container) $ sh /ext/build/run-scripts/run-sil-ocpp201-pnc.sh ``` Then - moved the slider to various points, the max current changed - plugged in car, handshake was successful - moved the slider while the car was plugged in, max current changed and power drawn changed - cleared limit, max current went to 16 and max power went to 11kW Signed-off-by: Shankari <[email protected]>
@Abby-Wheelis I think this is at a reasonable point for you to take over. IMHO, next step is:
If time permits:
At that point, I think we can close this issue. We need to figure out what is going on with the rebuilt images, submit patches as a PR etc but those can be tracked in separate issues. |
Testing done: error: Tried again, did not fail, but did take FOREVER and eventually stall out Kept trying, got on a faster network have the manager running!
Could be because I stopped / restarted the pull so many times? Maybe I need to start over with a clean slate (on the faster network) |
@Abby-Wheelis actual next steps:
Right now, in the
where
and then we replace the localhost with the CSMS URL
So I think what we need is a It's really just a simpler script and some instructions. We may want to start MaEVe or Citrine or MobilityHouse separately and then run the new script to confirm that everything works (https://github.com/EVerest/libocpp/?tab=readme-ov-file#csms-compatibility-ocpp-201) |
PR #107 is open to handle the first task listed above. |
@Abby-Wheelis even after switching to single phase, the max power is 10.5 kW, which is what I remember seeing with the three phase as well. Is there anything else we need to change/fix to make the math work? |
I'll look into it! That is the value I remember as well |
Updates:
Heading home, but will pick back up when I get there to:
|
I made a mistake in the PR I submitted earlier, #108 is a revision which fixes my error. |
This looks right - 230V x 16A = 3.68kW, that's just not what we see on the meter ... Update: so the value in the meter comes from Also published to here in the EvseManager, with a value I also don't fully understand. It looks like both come from the sum of (L1, L2, L3) power / 1000 ... I'm just not sure why Putting a pin in this to get the external csms script out and tested, will continue in #105 when I have the time. |
There is a new testival coming up, which means a new demo that we will try to work towards.
The goal of this demo is:
Example logs for overridden power
Ideally, we will be able to specify the time for which the new current limit is active, have that be part of the composite schedule and have it be reported back to the CSMS using
NotifyChargingLimitRequest
as specified in K14.Let's see how complicated this will be to hack together, and whether we can get it done in the next month or so.
The text was updated successfully, but these errors were encountered: