Emoncms Demand Shaper module

Great to hear @kylelamb

Certainly in my case, requesting the SoC is just a case of a REST API call to the BMW servers which cache the latest reported value the car has sent. The car only updates the servers at the end of trips, or about every 5 minutes during charging. You get a charging curve like this. The steps down are at the end of journeys, and the staircase is the charging.

Thereā€™s no way of making the car do an update when it doesnā€™t want to.

Iā€™ve got a some of questions/observations now that Iā€™m up and running:

  • If the EVSE is in the disabled state ($FD) then the demand shaper gives errors. A simple fix I suspect
  • Is the demand shaper using the timers or the energy limiter on the EVSE, or is it just sending it sleep/enable commands? Iā€™m trying to understand how it might interact with someone plugging in and pressing the button on the EVSE to start and things like that.
  • What does ā€œOffā€ mean in the UI? Similar hypotheticals to the last question.

Finally, have you thought at all about allowing power to be switched on for preconditioning on these cold mornings? I expect itā€™s more energy efficient to heat the car/battery from the mains rather than charge the battery and then precondition from the battery given charging losses. It could probably be on minimum current for preconditioning to limit charging at a non-minimum-price time.

1 Like

Thanks @PaulS

Its using the timers, this line in demandshaper_run.php prepares the command to set the timer: demandshaper/demandshaper_run.php at master Ā· emoncms/demandshaper Ā· GitHub

The off state sends the $FS command, hereā€™s the line in the demandshaper_run.php process: demandshaper/demandshaper_run.php at master Ā· emoncms/demandshaper Ā· GitHub

Yes this would be really good to add I agree, I havenā€™t managed to implement it yet, I would also like to add a feature that allows to increase preference for charging closer to end time, so that the battery does not sit at high SOC.

So, if weā€™re using timers then somebody switching the unit from sleeping to active with the push button will get power immediately? Thatā€™s probably a good thing. I just want to be able to explain it to the rest of the household.

The other minor thing was adding a price per kWh along side the price per mile. p/kWh is how public charging is priced, so it makes for a nice comparison. The rest of emoncms talks in p/kWh too.

1 Like

Ideally yes pushing the button would override the timer, Im not 100% that depending on the timing of the button press and the next automated timer update, the timer might not then override the manual user press, it would be good to double check that, Iā€™ve been using the timer exclusively and turning on/off via the demandshaper UI.

Good idea re showing p/kWh as well.

Ok, when it makes sense Iā€™ll have a bit of an experiment with how things interact. If I notice anything surprising Iā€™ll report back. Itā€™s those ā€œIā€™m back, but Iā€™m heading out later. Better give it some juiceā€ moments.

I like the ā€œincrease preference for charging closer to end timeā€ idea too. Not sure how you balance that against price with controls in the UI. Maybe splitting the charge period so you do most at cheap price, and then top it off / precondition just before departure? Not sure that really meets your criteria of not having high SoC too long, or if splitting the charge like that is good for the battery (thermal cycling).

Just throwing around ideas.

1 Like

Thanks @PaulS yes interesting question re thermal cycling, Iā€™ve been splitting the charge this way myself, so I will do 20% to 70% at the best time which might be 2am-4:30am then doing 70%-90% in the hour before departure if I need the higher SOCā€¦ I was thinking of a simple application of a slope to the price forecast that would weight the charging towards the end time but maybe the split charge is betterā€¦ the split charge approach could also fit well with cabin pre-heatā€¦

Hi,

Am looking at altering the code for now to get the SOC of a Zoe from a local mysql instance as I have a Node Red script running obtaining the carā€™s details and giving a UI for the wife, so going to alter it so it puts the % of charge in a sql table.

Just want to check if i alter the ovms routine to return the % SOC that this is going to be included in the scheduler when it runs each 60 mins ?

Meaning it checks the SOC every scheduler run in the service and not just when the frontend UI is open?

Hello @sijones good point! your right the OVMS check is currently only in the UI and needs adding to the automatic reschedule script

1 Like

Iā€™m looking to add Nordpool Spot electricity price into Demand Shaper. I already have my hands on the hourly price JSON and Iā€™m using it in some other implementations of mine. When doing development with latest emoncms (emonSD), should I just link the module folder as instructed in GitHub - emoncms/demandshaper: Appliance, Smartplug, OpenEVSE demand scheduler: Find the best time to run household loads or do I need to uninstall the existing demandshaper somehow, as it is already part of current image? Have programming skills just need a little push to get things started.

Renamed existing demand shaper folder and service file and pulled ones from my forked demand shaper repo to home folder, and created symbolic links. Guess thereā€™s nothing more to thatā€¦

1 Like

That will work, an alternative is to switch the remote url of the demandshaper repository using git but your approach is also fine

1 Like

Also needed to do

mv /opt/emoncms/modules/demandshaper /opt/emoncms/modules/demandshaper_old
ln -s /home/pi/demandshaper /opt/emoncms/modules/demandshaper

as the web interface is calling the /demandshaper/forecast API, i.e., scheduler.php which is located at /opt/emoncms/modules/demandshaper.

Import of prices now work, but Nordpool prices are per hour and there seems to be generic resolution of 1800 or 900 secs in many places. Is the resolution something that should be made signal specific?

The cleanest way to contribute would be to

  1. Fork the DemandShaper GitHub Repository to your own GitHub account.
  2. Create a new Branch based on Master in your fork.
  3. Switch to your repository/branch in the DemandShaper folder.

You can then make the changes (to the local repo), commit them to your GitHub repo (the origin) and once all done create a Pull Request to push those changes to the upstream repository.

Takes a bit of working through to get it right, but once you do it is the easiest way to contribute.

You can then, once the changes are included, switch back to the EmonCMS repo.

Donā€™t worry if you donā€™t get it right first time! :grinning:.

2 Likes

Great @jpalo, the scheduler algorithm should up sample the signal to 900s resultion if less than this. The reason behind this is to allow scheduling a load in 15min blocks, otherwise e.g a ev charge may over or undershoot the target SOC significantly.

The way that works still needs more work so that the schedule period can actually be precise to say the nearest minuteā€¦

2 Likes

Thanks Brian and Trystan!

Initial implementation for the ā€œsmartā€ ctrlmode is here for Finnish region. Chart seems to behave correctly:

But time zones are causing issues, mainly because OpenEVSE seems to take schedules in as HOUR MINUTE and compare that value to the internal time of OpenEVSE, which is basically local time taken from browser.

Now the problem is that it is while Demand Shaper calculates and the hours in JS (in local time) and calls PHP API as these local time start/end hours as parameters, the schedule_smart function in scheduler.php seems to recalculate everything from scratch, and ends up passing the HOUR values to OpenEVSE RAPI in UTC. This means that if OpenEVSE time is in in some other TZ from UTC, start/end times will be off some hours.

This server vs. client time issue can also be seen in some validation error messages in calc_schedule of generic.js:
image

Please let me know if Iā€™ve misunderstood something or missed an essential detail in how Demand Shaper was designed to work with OpenEVSE when it comes to these start/end HOUR values.

You may be right - there have been issues before with TimeZones. First Iā€™d like to confirm what you mean by ā€˜Localā€™ time (and excuse me if Iā€™m teaching you to suck eggs).

A UNIX timestamp (i.e. number of seconds since epoch) is the same, at the same instant, around the globe.

A ā€˜localā€™ time is simply a string representation of that UNIX timestamp if that string includes a timezone in a format the system can recognise such as ISO 8601 - so 1578089647 == 2020-01-03T22:14:07+00:00 == 2020-01-03T17:14:07-05:00

If there is no timezone data, things get tricky for any system.

The data internal to EmonCMS, works on Unix Timestamps, but if the local system has the timezone set, calculations by PHP etc will take that into account if a string is sent rather than a Unix Timestamp.

Avoid thinking of this as a timezone issue, but rather how to get the right Unix Timestamp. Ideally, timestamps should always be sent as an integer.

Also note, Javascript returns timestamps as milliseconds.

Thanks for the clarification, everything seems according to best practices on EmonCMS side, and no worries, the proverb ā€œteaching someone to such eggsā€ was at least new one for me. In Finnish we have similar saying to ā€œnot teach your father toā€¦ā€ well, the f-word, so the one in English is lot more family friendly.

Anyways, by ā€œlocal timeā€ I mainly meant start/end HOUR values OpenEVSE takes in the $ST RAPI command.

It all comes down to that scheduler.php does $periods[] = array("start"=>array($tstart,$start_hour), "end"=>array($tend,$end_hour)); where timestamp is correct, but $start_hour and and $end_hour are in UTC.

Ended up adding localtime handling for $start_hour for openevse devices.

if($device === "openevse") {
    $localtime = localtime($tstart);            
    $start_hour = $localtime[2] + $localtime[1]/60;
}
else{
    $start_hour = $profile[$pos][2];
}
1 Like

thumbsup

Nice work @jpalo, I realise I had a lot of timezone settings hardcoded to the UK, Iā€™ve made a branch with hopefully a fix for this here: https://github.com/emoncms/demandshaper/compare/user_timezone testing here at the moment.