Emoncms Demand Shaper module

emonPI SD card image on Rasp PI 2B

Ok, sometimes an issue with the service not running properly on other bases.

Ah, think i’ve spotted it - my SD reports emonSD-30Oct18 when I log in, and the website says emonSD-17Oct19 or newer.

Damn, didn’t realise you dropped support for PI2 either :frowning:

No works fine, just edit the config.txt file. I run it on a PiZero.

Just a note, the instructions mention removing both of these values…


although on the emonSD-17Oct19 (Stable) image, “arm_freq_min” doesn’t exist in the file.

1 Like

I just comment them out and let the Pi find its own base freq.

Hi Trystan.
Trust all is well with you .
I have been using the demand shaper for real for the last two weeks and it has been working well
I have been using ok to interrupt. And this has been working fine for me . Can you tell me what the issue is with using this as I see many post saying not to use it. But I can not see why I am basing my charge on time to completion. As not able to get battery %. Easy from my car

I have been trying the new beta V3.3. For esp32
But I am having problems with this I have posted this for Glyn . To look at

I was wondering if you had thought anymore on looking at the status from the charger to know when car was plugged in to calculate the demand shaper time slots from that point ?

Also when I get settings mismatch. Is this due to the settings being changed in the evse charger by something other than the demand shaper .

Cheers. Bill

@jpalo, looking at your implementation noticed that you use expectra.se API instead of using Nordpool data. I know that free Nordpool api requires you go to have a TCO which we as consumers dont have but there is alternative method of getting the data like this one which I have used: https://github.com/samuelmr/nordpool-node/blob/master/lib/prices.js

I am just curious as expectra.se does not really advertise this API ?

@PetriK, extracting prices from Nordpool’s website is not allowed according to their ToS (that’s what all the github projects do), that’s why Expektra API is used.

From Nordpool site:
Automatic extraction of data from this website and/or use for commercial purposes is strictly prohibited under Nord Pool’s terms & conditions. For more information regarding data usage, contact [email protected].
Nord Pool does not permit automatic extraction of data or other usage that reduces the performance of the website. Any such extraction or usage will lead to the user being blocked from the website without further notice.

From Expektra feed:
You need an access token in order to use this service. If you don’t have an access token or you have other questions, send and email to [email protected].
This service may be used only by individuals and organizations in non-commercial purpose and it is not permitted to redistribute this data.
This service is provided by Expektra www.expektra.se

Excellent, I will revert using expektra.se for real time cost calculations, time permitting … Thank you !

I am helping a friend with his smart plugs. Is the precompiled firmware up to date and compatible with the latest stable branch of the demand shaper? I am getting “settings mismatch” for any “smart” periods scheduled via the demand shaper on EmonESP v2.3.0 ref link below (22 Nov 2019), and setup issues with EmonESP v3.0.0 ref second link below (also 22 Nov 2019). Is there something in the Demand Shaper master branch required to work with the latest EmonESP firmware?


Well done, Trystan!

We’re on Agile at home and schedule the charging of our EV and the Sunamp heat battery to make the most of this. The Emoncms app is very useful to do this manually. I’d like to link in to the [regional] grid carbon intensity forecast too.

We’re also on the non-domestic version of Agile for the EV car club and want to set up a system to schedule charge with the low-intensity or cheap times. Is there a link to Myenergi Zappi & Eddi?


Well done - I really get a lot out of the work you do. Thank you. I have a question
Regarding the demand shaper for OpenEVSE, is there a way to change to a different MQTT broker? I’d like to switch it to use the one on my Home Assistant machine (which is where I have my OpenEVSE and a million other things posting)

Andy B

Quick answer is yes. I have my mqtt broker on a different pi.
You have to set emoncms to use the different broker.

I’ve read through the thread, and am not sure what triggers a recalc / reschedule for OPENEVSE - other than revisiting the demand shaper page and ‘forcing’ an update.

Similar to the question Paul Sargent asked in Feb, if I charge my car overnight, then use during the day, how does the next charging session schedule get set?

I’m an Octopus Agile customer, so does the availability of the next days schedule trigger something, or the SoC for the vehicle?



Yes - it’s a pain having to go to the Demand Shaper webpage to set things up every evening.
I’ve just completed a Python script that runs as a cronjob before midnight that does the set up without any human intervention.
It seems to be working OK:

 # PURPOSE ...
# To be run as a cronjob just prior to midnight
# To set up the Demand Shaper parameters
# AND finally - Regardless of whether the EV is connected - to switch openEVSE from DISABLED state to WAITING state

# ---------------------------------------------

import requests, json, os, time

# Emoncms server configuration ...
emoncms_apikey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"   # Use appropriate key
emoncms_server = ""

# Get the Demand Shaper data ...

params = (
    ('device', 'openevse'),
    ('apikey', emoncms_apikey)

reply = requests.get(emoncms_server+"/demandshaper/get", params=params)
jsonstr = reply.text.rstrip()
ds_data = json.loads(jsonstr)

print(reply.status_code)    # Debugging only
print (ds_data)             # Debugging only

# Demand Shaper modes ...
# divert_mode = 1 = ECO mode ON
# divert_mode = 2 = ECO mode OFF
# Other modes: 'smart'  'off'  'on'  'timer'

# Extract relevant data from the json
# The following section for debugging only ...

data1 = ds_data['schedule']['settings']['ctrlmode']
data2 = ds_data['schedule']['settings']['on_completion']
data3 = ds_data['schedule']['settings']['target_soc']
data4 = ds_data['schedule']['settings']['divert_mode']

print (data1)
print (data2)  
print (data3)
print (data4)

# End of above debugging section


# Fixed parameters ...
ds_data['schedule']['settings']['ctrlmode'] = 'off'   # Set to 'off' to initialise - will be later reset to 'smart'
ds_data['schedule']['settings']['on_completion'] = 'smart'
ds_data['schedule']['settings']['divert_mode'] = 1
ds_data['schedule']['settings']['battery_capacity'] = 75   # kWh ... depends on EV
ds_data['schedule']['settings']['charge_rate'] = 6.9       # A ... for a single phase openEVSE charger

# ===================================================================
# Dependent on the Season and the need to leave 'space' in the EV battery for next days ANTICIPATED charge from excess solar gen
# Max is 0.9 - recognises the limit set to conserve battery life
# WINTER season = 0.9
# MID season = ???
# POOL season = ???

ds_data['schedule']['settings']['target_soc'] = 0.9 

# ===================================================================
print (ds_data)            # Debugging only

# Now save the changed parameters ...
reply = requests.post(emoncms_server+"/demandshaper/save", params=params, data={'schedule':json.dumps(ds_data['schedule'])})

print (data1)    # Debugging only
print (data2)    # Debugging only  
print (data3)    # Debugging only
print (data4)    # Debugging only

print(reply.status_code)     # Debugging only
print(reply.text)            # Debugging only

# Set up openEVSE ...
# Switch Divert Mode (> Normal Fast then > ECO mode) in order to change openEVSE from DISABLED to the WAITING State

os.system("mosquitto_pub -h localhost -r -u emonpi -P emonpimqtt2016 -t emon/openevse/divertmode/set -m 1")    # Note:  -r  to retain message
os.system("mosquitto_pub -h localhost -r -u emonpi -P emonpimqtt2016 -t emon/openevse/divertmode/set -m 2")    # Note:  -r  to retain message

# FINALLY switch Demand Shaper to 'smart' to activate overnight charging ...
ds_data['schedule']['settings']['ctrlmode'] = 'smart'

# And save the changed parameter ...
reply = requests.post(emoncms_server+"/demandshaper/save", params=params, data={'schedule':json.dumps(ds_data['schedule'])})

print (ds_data)             # Debugging only
print(reply.status_code)    # Debugging only
print(reply.text)           # Debugging only

The script runs on a Raspberry Pi running the latest image updated to ver 10.2.6.
It’s a Tesla EV and single phase openEVSE charger up dated with the latest wireless card.
This may be of interest …

Thanks - I’ll give it a whirl, see if I can use for my purpose.

Hopefully this functionality will become baked in, as ideally unless you are purposefully changing some parameters, the option to setup and forget would be great.


@johnbanks looks to be up and running for me, much appreciated (I’ve set the cron at 20:00).

I also use home assistant to enable pre conditioning using google home, and when I do that I enable the charger so I pre condition from mains rather than battery while at home, I think your script will also cope with that.

Thanks again :slight_smile:


The script above has been working for me and @danfulton.

However on Tuesday evening I had a problem …
The script ran per cronjob but when I checked the webpage for Demand Shaper, the red bars were not showing to indicate that a charge was scheduled.

I then ran the script in an SSH terminal - the script ran without error – but still no red bars.

I had to manually turn Demand Shaper OFF and then manually turn it back to SMART to get the red bars.

But this is exactly what the script tries to achieve and the json printout indicated that the ctrlmode was set to ‘smart’:

{'schedule': {'settings': {'device': 'openevse', 'device_type': 'openevse', 'device_name': 'openevse', 'ctrlmode': 'smart', 'period': 4.021739130434782, 'end': 8, 'end_timestamp': 1609920000, 'interruptible': 0, 'runone': 0, 'on_completion': 'smart', 'forecast_config': [{'name': 'octopusagile', 'weight': 1, 'gsp_id': 'H'}], 'forecast_units': 'generic', 'timer': [{'start': 0, 'end': 0}, {'start': 0, 'end': 0}], 'ip': '', 'soc_source': 'input', 'battery_capacity': 75, 'charge_rate': 6.9, 'target_soc': 0.9, 'current_soc': 0.53, 'balpercentage': 0.9, 'baltime': 2, 'car_economy': 3.4, 'charge_energy': 27.75, 'charge_distance': 94.3, 'distance_units': 'miles', 'ovms_vehicleid': '', 'ovms_carpass': '', 'divert_mode': 1}, 'runtime': {'started': True, 'periods': [{'start': [1609896600, 1.5], 'end': [1609911078, 5.517]}], 'timeleft': 0}}}


{"success":true,"message":"Saved to disk"}

In another related Forum posting …

… you indicated that:

It may take until the next SOC auto update for the changes to take effect, up to 10 mins.

Would you please explain in a bit more detail how this aspect of Demand Shaper works.

Is the SOC you refer to the actual then SOC of the EV or is it the target SOC you want to achieve?

Is there a way to force the update you refer to? I could incorporate this into the script.

Your advice would be most welcome - thx


I spent more hours on this last evening (Sun).

Re openEVSE, it can be controlled/adjusted via the webpage and RAPI commands. I can also replicate any of these commands/adjustments in a bash or Python script. (In the late evening openEVSE needs to be in the Waiting state).

Turning now to Demand Shaper. Initially the webpage showed that SMART was set and the light green bar indicated the EV could accept a charge. But there were no red bars on the histogram indicating when this charge would happen overnight.

From the Demand Shaper webpage, it was possible to get the red charging bars by clicking on OFF then clicking back to SMART.

The challenge is – how to replicate this via bash or Python commands?

I can access and change the json with the Demand Shaper controlling parameters via a Python script or commands in a terminal but the webpage does not change even if it is refreshed. There are no red bars.

I also tried stopping & starting the Demand Shaper service before/after making the json changes but still no red bars.

I went to bed and this morning (Mon) checked what had happened overnight. The EV had NOT charged and I concluded: no red bars then no charge which seemed logical.

However, a new histogram was now in view on the Demand Shaper webpage. And lo & behold there were red charging bars! The charge I was failing to initiate on Sun evening for the early hours of Mon was now scheduled for the early hours of Tues without any interventions from me (apart from browsing to the webpage).

I am at a loss. We do need the help & expertise of @TrystanLea.

I’ll leave things as they are now (Mon evening) and see what happens overnight.