-
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
🔌 🕐 Experiment with an end to end demo of departure time #64
Comments
Note that these are still very simple scenarios that are primarily focused on the communication between the station and the car. Concretely, the following scenarios are out of scope:
There are lots of cool things we can do in terms of renegotiation and I fully agree that is where the power in smart charging is. But we are going to take one step at a time and bring in more and more complex functionality into the demo over time, involving the community, and making sure that it is consistent with what stakeholders expect. Note the final scenario here, where the EVSE is not able to meet the requested schedule - is that what we want the EVSE to return? The goal of these initial demos is to build interest and engagement and help spearhead those conversations. |
From a technical perspective, this demo boils down to the following technical tasks:
We will update this issue with progress as we work on these tasks |
Looking through the patches that I slapped together quickly, the callback in the core module that handles the set limits or charge profile calls from the CSMS is in
Couple of other notes:
Going to focus on the EVSE manager's
|
That looks like it calls through to the so here's where the ISO messages are sent out it's a little bit complex, and it looks like we only populate one PMaxSchedule!!
Need to add more logs to figure out what is going in here for our current working scenario, and then how we can extend it going forward.... |
Tracing through the repos to see where we'll need to add It seems there are three variations of the
Tracing through now to see exactly when these EVChargeParameterTypes are used, should shed some light on exactly where changes are needed |
ok so the What I see is that there is a MQTT message to set the limits.
In the EVSE manager, I see
I do note
commented in some logs from the energy manager, let's see how the clamping actually gets passed through... |
Tracethrough for a single schedule
Multi schedule
Fails with
|
New multi-schedule with multiple periods in the day
But now the limits are set to 0A. Why? It looks like it finds the correct period. I bet it is because the current is below the min (should add logs to verify). But for now, we can just bump up the amps.... |
Bumping up the amps by x 10, we get the correct limits, but the last period is the one that is valid.
Let's adjust the start time so that we can have multiple future schedules
Now to plug in the car again
Again, we get a single SA schedule with 6900W for one day (86400 duration). |
Keeping a tally of the locations I'll need to add DepartureTime. First, just consolidating the iso requirements for my ease of reading... 15118-2 `DepartureTime` requirements
Where implementation is needed:
Constraints:
With the info above, it seems we need to send & handle the DepartureTime whenever a ChargeParameterDiscoverReq is being sent. As I understand it, this will occur (i) when a new session has been started, and (ii) when a session has been resumed after a pause. Now to hunt down these occurrences in PyEVJosev and JsEvManager. At a glance, the JsEvManager changes seem like they will be somewhat straightforward... |
Changing the defaults in
Pnc is now stuck in Authorization Req/Res
Even after reverting changes. Restarting even further after saving a patch with the logs |
Starting with
From what I can gather, the mutation of variables like |
Restarted everything. It works again. For the record, and to help in debugging again, here's what a successful auth *should* look like
Making the pyjosev changes without adding any other logs
|
I note that the construction of the charge parameter discovery request/response also has some SA schedule creation
But the current message doesn't seem to use that so we will ignore for simplicity |
Still getting used to the Node-RED workflow, setting up the message flow -- writing these notes down mostly for my own understanding... As I understand it, the Buffer sim commands function node takes the inputs from each of the input nodes, and adjusts the payload according to the topic. Screenshot of nodes, example codeif (msg.topic.indexOf('sim_commands') > -1) {
const s = msg.payload.split('#');
flow.set('sim_commands_start', s[0]);
// the code continues... After some searching, it seems the This leads me to the question: do I even need to filter through the buffer?? For example, the values set by the MaxCurrentSlider aren't being filtered. I'm going to just assume we don't have to filter it for now, I think that should be OK... |
Aha! It looks like the pyjosev library is in two locations
I have been editing the one in Trying to modify an existing log to see which one is loaded (modifying the one in
Let's make sure that the loggers are set up in the same way... |
I might have made changes in the SECC implementation of pyjosev, which is unused in EVerest.
Bingo!
Now, we set our charging profile
And now we plug in the car, and we send the correct request, but the response still has only one SASchedule, which is 6900W for the entire day ("duration":86400).
|
So it is fairly clear that the current ISO 15118-2 implementation does not work the way we had hoped in Concretely, the EVSE does not send a list of SASchedules; it only sends a single SASchedule that corresponds to the current limits. When the EVSE sent the To run some numbers:
So basically, departure time does not work, and we only send a single SA Schedule as I had speculated from the code earlier. Not sure if it is super easy to fix this, but I have the afternoon to try! |
Parsing the syntax & design behind the MQTT routes... My current understanding is that the DepartureTime should be send via the |
First, where is the limit computation coming from? It is
ah
updating the power limits in #64 (comment)
Next question: why are we not handling the departure time correctly, and why are we returning exactly one SASchedule? |
Confirmed that the return SASchedules (EVSE -> car) are created in the
|
So achieving our original goals, with multiple SASchedules is going to be fairly complex. Given the short timeframe, let us at least try for a much simpler option in with there is a single charging profile set, but the user specifies a departure time and energy need, and we spread the energy out over the entire charging period. |
It seems that once you add a command to So, we need to finally answer the question: How do we add commands to the message? Looking at the Buffer sim commands function node's code: if (msg.topic.indexOf('sim_commands') > -1) {
const s = msg.payload.split('#');
flow.set('sim_commands_start', s[0]);
flow.set('sim_commands_stop', s[1]);
flow.set('sim_commands_pause', s[2]);
flow.set('sim_commands_resume', s[3]);
}
// Code continues... We can use the default injection to understand exactly how the payload is generated. The following string...
Assigns itself to each of the sim commands, as follows...
Ah, that makes more sense -- we set a series of commands for each possible method of interacting with the simulation loop! Cool. Know this, we finally have some steps to move forward:
|
Ok, so I can confirm that I can read the values correctly in the ISO server code,
now to actually use the departure time and requested energy... |
First design hiccup: We cannot simply pipe the
Solution: We still need have the *Caveat: I think this part of the function will behave quite similar to the simulation selection. That is, the change will be fed into the buffer, but the message will not propagate through to the mqtt server (This is because should only send departure time during a Start or Resume vent) |
So I am not quite sure how we go from a complex set of schedule periods to a single limit.
If I can figure out how to pass this through, we might be able to do a better demo. None of them are valid
Day switched over (in UTC), but the timer doesn't seem to be recalculating
Resending the setChargingProfile, the limits are now clamped, but there is still only one limit from the energy manager
|
Will we need a separate command to clear the departureTime once it's sent? Or will re-starting (resuming) without the command sufficient? For now, let's assume we have to delete the command. With some initial futzing, this has proven to be somewhat non trivial. Below is my exploration of this first approach. Method: Command Insertion / DeletionFirst, we define a command insertion as changing a string as follows: // Old Command List: sleep 1;iso_wait_slac_matched;iso_start_v2g_session externalpayment,ac;iso_wait_pwr_ready;iso_draw_power_regulated 16,3;sleep 36000
flow.set('sim_commands_start', flow.get('sim_commands_start').splice(2, 0, 'iso_set_departure_time'));
// New Command List: sleep 1;iso_wait_slac_matched; iso_set_departure_time; iso_start_v2g_session externalpayment,ac;iso_wait_pwr_ready;iso_draw_power_regulated 16,3;sleep 36000
To pick apart my thought process, let's draw up a truth table:
Likewise, as defined above, we need to account for the profile reset. Let's assume we've re-set the profile, and are now checking whether or not the user has defined a departureTime. Drawing up another table...
Well, after drafting that up, I think it's time to take a step back: we can do better. Instead of removing or adding the commands (which starts to add complications), what happens if we simply mutate the value within the command? Let's re-do the truth tables from my first attempt User Inputs new Departure Time
Phew!! I was really gilding the lily with the first approach -- this is way simpler. To summarize: Going forward, each "simulation profile" will have a |
Yay! with some fairly obvious changes, this now works!
However, the |
Progress! Modifying To recap the status of the integration:
Fingers crossed these last two will be it! |
I would not expect that you need to change any of the SECC code. I didn't have to change any of it when I set the departure time by editing files. |
That was my assumption as well -- I'm somewhat unsure as to why this issue was happening, but I think I've solved it. Changing only |
DepartureTime is already handled in this datatypes file, so I believe we don't need to focus there. |
I was so sure I was missing something on the iso15118 side of things, I forgot to really trace through As currently written, we're trying to gather the departure time as follows: def _handler_start_charging(self, args) -> bool:
log.info(str(args))
self._es.EnergyTransferMode = args['EnergyTransferMode']
self._es.DepartureTime = args['DepartureTime']
self._es.EAmount = args['EAmount'
# .. Having added this log, we find that the args are:
Can't exactly fetch what isn't there... Let's see where the args is set |
Ok, tracing the code:
I'll keep going from here, but it feels like I'm starting to lose the forest for the trees. I just can't find where the |
Aha! I had been confused as to the relationship between JsEvManager and PyJosEv until now -- I suppose that is because I didn't read through |
Making the aforementioned changes, we can now the default in
|
It seems the order of our commands is slightly out-of-wack... Looking at the logs: The values are being sent to EDIT: Yup, that seems to have been the issue. Looking at the order of commands... |
Success!! Just needed to deploy the flow changes, and that was the final piece. Will edit this comment with videos of the changes in each permutation, and then include the files / how to run after. Screen Captures BelowPhotos of runtime behaviorFields Empty: DefaultsV1.mp4Departure Time Only2.mp4DepartureTime & EAmount: Low DT3.mp4DepartureTime & EAmount: High DT (Adjusts power draw)4.mp4 |
Working on reproducibility now -- the above videos show it running, currently attempting to add the files to a fresh install & make the demo run smoothly. Will update with instructions once I have a reproducible demo! EDIT: The demo is reproducible! Small hitch -- on a fresh reproduction, the empty DT / EAmount result in a failure to get past the "PrepareCharging" phase (This seems to be due to the null values I was using as default, that I forgot to change). Will fix this, then include files + demo instructions, |
you should submit a PR to the demo repo with the patches to the files that you changed so we have a working demo again. And then we can submit PRs to the core repos and involve the community in how best to implement this (and similar changes) But for today afternoon, you can demo from your laptop 😄 |
Now that we have a working demo, we can pivot to incorporating the # Adding a -v for debugging...
curl -v -X POST \
"http://localhost:9410/api/v0/cs/${CS}/setchargingprofile" \
-H "Content-Type: application/json" \
-d "$JSON_DATA" Shows us that the issue is indeed with the post. Running the script with one of our Charging Profiles (with a properly adjusted timestamp), we get the following output:
Re-reading and better understanding the curl output, the POST seems to have successfully created the file.. So, why isn't the profile change not being shown? |
Wait, this is using |
Demos are now working with a default values {EA=60, DepartureTime=86400}. Now, the twist is making DepartureTime (DT) optional, as per [V2G2-361]. To do this, we need to:
Once these are (i) implemented and (ii) confirmed to be working, the plan is to:
After these are done, we can move forward with updating the demo. *Merging the demo to the main branches may be tricky, because I believe our PaymentMethod strategy in our demo differs from what is currently implemented (link to relevant discussion). Will cross that bridge when we come to it! |
Taking some time to clean up my code and refactor while making these changes. We have a design decision to make: When should we filter out an empty DepartureTime? My first though was to do so in the |
Ah - it seems that passing in the Since this is functionally what we want, and we want a working demo up asap 'll go ahead and commit the image to ghcr. Aside: I'm not 100% satisfied with our working solution. Per [V2G2-361] of ISO 15118-2, DepartureTime is an optional extension of the Perhaps I'm splitting hairs, but I think our implementation should hug as closely to the spec as possible. This is fine for a hack-y proof of concept, but I think we should re-factor this to better match the spec. I've got some thoughts on how we'd do so, but I can save that for the PR discussion (this issue has gotten quite bulky as is!) |
I've got an image successfully build, but am running into some hiccups adding it to the demo's |
@the-bay-kay this is almost certainly a permissions issue. Since this is a temporary stage anyway, you can just make your package be public and point to it. We can then fix the permissions before the final version. |
The latest image can be found here -- just tested with a completely fresh install, seems to work perfectly! Will push the changes to |
@shankari the PR for these changes has been made! Will start moving these changes into individual demo-wrapup PRs, as we did with the initial CharIn changes. |
@the-bay-kay we probably want to move on to the full demo before that for two reasons:
|
We now have a demo of the departure time using the |
Let's try to build on #44 to include departure time.
EDIT: Simplified scenarios with a single SASchedule. More complex schedules are tracked in #68
High level scenario using AC L2:
pmax = 5312, max current = 7A, duration = 16 hourspmax (float) = 5312.5 (ceil: 5313), max_current = 7.7 (ceil 8), 15.998 hours (ceil 16).[1] This is a real-life example from our recent trip to Arcata. We got to the hotel at around 8pm with a Tesla that was almost empty. We wanted to walk to a concert the next morning (9am - 11am) and then leave at noon rather than deal with parking at the concert venue. The hotel had validated parking in the public lot, but the charger was not smart, and there was no communication between the network and the hotel - the validated permit was a piece of paper to put on the windshield. So we got a notification at around 6am indicating that we would start getting charged for parking since the charging was complete. In this case, the fast charging was actually bad - my husband had to run down to the lot and move the car right after he woke up.
The text was updated successfully, but these errors were encountered: