Community
OpenEnergyMonitor

OpenEnergyMonitor Community

Using KNX or EMS for demand shaping?

Tags: #<Tag:0x00007f1be4c69628> #<Tag:0x00007f1be4c693d0> #<Tag:0x00007f1be4c69290> #<Tag:0x00007f1be4c690d8>

Hi all,

I’m getting a Stiebel Eltron heat pump next year, and will be switching to Octopus Agile, so I am looking to control the energy usage so that I can avoid filling the buffer tank or DHW during peak periods, and pro-actively do that during cheaper periods.

Stiebel Eltron heat pumps can have an Internet Service Gateway which has web and mobile apps - which also enables their other Smart Home interfaces, including KNX and EMI.

It doesn’t seem like there are any documented APIs to control this from outside the home, so the “cheap and cheerful” IFTTT approach doesn’t seem like it’s easily accessible, although that might be possible once I get in to the web interface as there must be an API somewhere there… :slight_smile:

Locally, it seems KNX-IP lets you access the SG-Ready value.

EMI is also apparently an open spec, and incidentally is also supported by my Bosch tumble dryer, and I can’t find many links about it besides you can buy a “SMA Sunny Home Manager” which uses EEBus and SEMP to turn a variety of (mostly German) appliances on and off depending on sun/battery/etc status - provided, I assume, those things are also using this system. It seems to work around appliances submitting an energy plan, and the manager guiding when that energy should be used for maximum efficiency.

EMI seems a lot more complex - and as I will have relatively small panels, and big electricity load and battery that will store any excess by itself, I doubt solar optimisation will help much for me compared to just being responsive to agile pricing.

Maybe KNX-IP setting the SG-Ready value is a good place to start and will be sufficient? The modes are 1 = totally off (during peak pricing), 2 = auto, 3 = please use more (during a low price period?), 4 = maximum warp (during plunge pricing). Has anyone looked at this or similar?

Thanks,
Rob

Hello @ramcq and welcome!

Looks like the KNX/IP interface allows you to control quite a bit https://www.stiebel-eltron.co.uk/en/service/smart-home/knx.html, you could probably change either the room or flow temperature set points and reduce these to reduce output during peak?

I dont personally have experience with KNX but it looks like there are a lot of resources for control via OpenHab or NodeRed or libraries available in a number of different programming languages.

Im controlling my Mitsubushi EcoDan but its via simple volts-free contacts and an analog voltage input on the controller to set the desired flow temperature. Id be interested to learn more about how KNX works, perhaps it’s something that could be integrated in future emoncms demandshaper development…

Thanks for the welcome, your reply and looking in to KNX - indeed it seems very powerful for reporting on and fiddling with values in the heat pump. I’m not sure I even need to get into the business of worrying about the set points given the SG-Ready setting (see page 29 of https://www.stiebel-eltron.co.uk/content/dam/ste/cdbassets/current/bedienungs-_u_installationsanleitungen/ISG_KNX_IP__4cee200f-ab01-11e6-81c5-005056a95add.pdf ) gives those four none/auto/more/loads options. To me that makes a little more sense as it would let the other settings prevail - eg never heating the buffer tank if there is no heat demand anticipated due to the program or external weather.

Thanks for the pointers to OpenHab and NodeRed too - I had seen these mentioned elsewhere. Can you expand a little on how I might join together the demand shaping with these - is there a source of events that the demand shaper would export, and then I do something on the other end to respond to the “need more power captain!!” - or is it a matter of patching the demandshaper module to understand a new type of demand it can control, and send the right events out (MQTT?) to have the KNX messages sent?

Your probably best doing this outside of the emoncms demandshaper module for now, perhaps reacting to the agile pricing directly in nodered…

The demandshaper module doesnt cater very well yet for heating control. Whilst I did add a basic heatpump monitor device support to the module, it’s just doing basic on/off and setting the flow temperature not really controlling the heat pump in relation to the agile signal.

Im working on a python script to automate my own heatpump control, and Im just experimenting with reducing the set point through the agile peak at the moment, but its doing that based on a manually set profile (knowing that 4-7 will always be more expensive) at the moment rather than dynamically adjusting in relation to the precise pricing of the agile tariff. I can just set a slightly warmer period say 3-4pm and then reduce the set point after that gradually until 7pm before boosting it back up again after that…
I will share the script when Im a bit further with it, but it is quite specific to my installation I guess…

@borpin and @glyn.hudson may be able to give you some pointers on NodeRed or OpenHab

My go to for home automation is Home Assistant and there is an integration for this make of HP https://www.home-assistant.io/integrations/stiebel_eltron/ - might not be the right model, but if they use a common API it might be OK.

HA has got sophisticated automation mechanism, but less good on the scheduling side. I use a HACS add-in called Schedy to schedule control of the set point temperatures on the climate integration, and then the climate integration controls the actual switching.

I do something similar with HA, AppDaemon4 & Shedy.(hass-apps). For example I control the max/min temperature of the DHW tank depending on time of day - Hotter, and higher minimum during a shower period, cooler rest of day for hot water (more time to recover so can be allowed to get colder) No heating of tank unless UFH lowers the temperature too far.

With those tools, it is very easy to do and to change.

1 Like

I’ve paid the deposit for the battery/solar/ASHP, and have switched to Octopus so I can order a smart meter and then get Agile… I’ve also hooked up my EmonTx so I have some nice graphs of how much my UFH is costing me, although all of my CTs are inside the CU and I don’t have an overall use feed yet. Oops. Anyway - this kit being installed will be months out - but I’ve been having a slow day at work, so I’ve been playing with Node Red as a way to fiddle with some of the APIs. :slight_smile:

I’ve modified https://github.com/JonathanPerkins/octopus-agile-price with some hardcoded thresholds to derive a SG Ready signal (> 15p off, < 8p boost, < 0p force) which seems to be working reasonably well, and I can add a KNX output to it to try and control the heat pump when I have it.

I also realised, reading some other forum threads, that if I (or anything else - eg MyEnergi Zappi) implements Agile responsive loads, I must also change the Tesla Powerwall into backup mode (ie, don’t discharge unless the grid is interrupted) otherwise it will valiantly discharge itself in an attempt to power the shifted loads whenever the Agile price criteria is met. :man_facepalming:

@TrystanLea Do you have any support / plans for controlling batteries in DemandShaper? I guess that would be a relatively easy place for me to start as initially it kind of just needs to be the logical OR of any other demand being switched on, and the Powerwall has a LAN API that can be used to switch modes.

After that I guess if we wanted to roll the heat pump in, assuning KNX behaves, we’d need to teach DemandShaper about devices which weren’t just boolean (to boost the energy usage), as we can also force it off during peak periods and on during plunge pricing.

Great, nice work!

It would be great to add support for batteries but it’s not something Im working on at the moment, @johnbanks did you look at control of the power wall, Im sure there was a discussion about this recently?

@ramcq

Yes – I’ve found PowerWall to be a problem when using Demand Shaper for EV charging.

Instead of charging the EV at cheap night rates, PowerWall discharges to the EV. The solution is to set the Powerall Reserve % to the current % when the EV starts charging starts and then set the Reserve % back to zero when EV charging finishes. This also means the house demand is supplied from the grid during EV charging rather than from PowerWall.

And given it’s the middle of the night, the process needs to be automated.

Per this link, with the latest firmware, accessing PowerWall on the home network to make these changes is no longer possible:

It is necessary to use the API associated with the Tesla Mobile App.

My automate-the-whole-process is still a WIP but these elements are now working:

PYTHON script to get an access token (valid for 45 days):


"""

PURPOSE ...

Get a new Access Token and save it to a file

Access Tokens expire after 45 days

So run this script monthly via crontab -e

Other scripts can read the current Access Token (acc_tok) from the file by including the following lines ...

f = open("/home/pi/ev-charging-scripts/access_token.txt", "r")

acc_tok = f.read()

"""

import requests, json, datetime

from requests.structures import CaseInsensitiveDict

url = "https://owner-api.teslamotors.com/oauth/token"

headers = CaseInsensitiveDict()

headers["Content-Type"] = "application/json"

data = '{"grant_type": "password", "client_id": "81527cff06843c8634fdc09e8ac0abefb46ac849f38fe1e431c2ef2106796384", "client_secret": "c7257eb71a564034f9419ee651c7d0e5f7aa6bfbd18bafb5c5c033b093bb2fa3", "email": "xxxxxxxxxxx", "password": "yyyyyyy"}'

response = requests.post(url, headers=headers, data=data)

if response.status_code in [200]:

token_dict = json.loads(response.text)

for x, y in token_dict.items():

print(x, y)

else:

print(response.status_code)

x = token_dict["created_at"] + token_dict["expires_in"]

date = datetime.datetime.fromtimestamp(x)

print("Valid UNTIL: " + date.strftime('%Y-%m-%d %H:%M:%S'))

# Over-write the access token in a file (access_token.txt) in the SAME directory as this script

f = open("/home/pi/ev-charging-scripts/access_token.txt", "w")

f.write(token_dict["access_token"])

f.close()

Get the energy_site_id which needs to be done just once & noted:


curl --header "Authorization: Bearer xxxxxxxxxxxxxx" -X GET https://owner-api.teslamotors.com/api/1/products

xxxxxxxxxxxxxx = the Access Token ... do: cat /home/pi/ev-charging-scripts/access_token.txt

This provides a wealth of data including:

"energy_site_id": xxxxxxxxxxxxx,

Make a note of it

PYTHON script to set the Reserve % to the current level:


"""

PURPOSE ...

Set the PowerWall Reserve charge to its CURRENT charge %

"""

import requests, json

from requests.structures import CaseInsensitiveDict

# Enter energy_site identifier ...

en_site = "xxxxxxxxxxx" # the energy_site_id

# Get latest Access Token from file

f = open("/home/pi/ev-charging-scripts/access_token.txt", "r")

acc_tok = f.read()

headers = CaseInsensitiveDict()

headers["Accept"] = "application/json"

headers["Authorization"] = "Bearer "+acc_tok

headers["Content-Type"] = "application/json"

# Get CURRENT charge %

url = "https://owner-api.teslamotors.com/api/1/energy_sites/"+en_site+"/live_st$

reply = requests.get(url, headers=headers)

jsonstr = reply.text.rstrip()

reply = json.loads(jsonstr)

curr_percent = reply['response']['percentage_charged']

print(curr_percent)

# Set the PowerWall Reserve charge to its CURRENT charge %

url = "https://owner-api.teslamotors.com/api/1/energy_sites/"+en_site+"/backup"

# data = {"backup_reserve_percent": curr_percent}

resp = requests.post(url, headers=headers, data=json.dumps(data))

print(resp.status_code)

PYTHON script to set the Reserve % back to zero:


"""

PURPOSE ...

To set the PowerWall Reserve charge back to zero - its normal condition

"""

import requests, json

from requests.structures import CaseInsensitiveDict

# Enter energy_site identifier ...

en_site = "xxxxxxxxxxx"

url = "https://owner-api.teslamotors.com/api/1/energy_sites/"+en_site+"/backup"

# Get latest Access Token from file

f = open("/home/pi/ev-charging-scripts/access_token.txt", "r")

acc_tok = f.read()

headers = CaseInsensitiveDict()

headers["Accept"] = "application/json"

headers["Authorization"] = "Bearer "+acc_tok

headers["Content-Type"] = "application/json"

data = {"backup_reserve_percent": 0}

resp = requests.post(url, headers=headers, data=json.dumps(data))

print(resp.status_code)

Note: All the scripts are in the /home/pi/ev-charging-scripts directory

My next step is to incorporate all this into an overall script that can be run as a cronjob sometime after midnight.

I have a single phase OpenEVSE charger and that can be set up using RAPI over MQTT with one exception – the EV charge to level. In my view, it’s smart not to charge the EV to 100% but better to leave ‘space’ for next day’s free solar charge (hopefully). I have an outstanding forum query on this to @ TrystanLea and @glynhudson:

@ramcq – I’m in the market for a 3 phase EV charger and note that you have a Zappi. Does the Zappi have an accessible API?

Hoping some of this may be of help.

Thanks @johnbanks for the very comprehensive and helpful reply!

Very frustrating to learn we’ll not to be able to talk locally to the Powerwall API any longer. If I didn’t need something mounted outdoors I’d be getting something cheaper I think! I find it quite frustrating to have these devices on my LAN that I have to go via the Internet to talk to in a reasonable way - adding additional dependencies and failure modes - or even can’t, just have to use an app. I have a perfectly good CT from Loop which I can’t bring in to Emoncms at the moment because their new devices and apps are not compatible with the old ones, and they’re shutting the old ones off. :confounded:

That said, my preference is that I wouldn’t need to add code/Pi/etc to automate these things at all, and that they would do what I need by design without any additional fragility complexity to support Agile pricing. Considering that one day we might move or rent this house out - or even that my wife needs to operate it without me - having stuff that “just works” and can be understood by an installer / customer support / etc… is beneficial.

I think between the Powerwall, Evohome, heat pump, etc they can probably be configured to do a reasonable job just pretending its a TOU tariff to start with, and aiming them at the cheaper (on average) periods and avoiding the peaks, and then I am going to regard any additional Agile optimization as a bonus/hobby. :slight_smile:

I don’t have a Zappi yet, but it’s a favoured choice of my local YouTube star electrician, and nice that it has PEN fault detection built in. I got a cheap ChargeMaster under the OLEV grant something like 6 or 7 years ago, but I am seeing the benefit of a smart charger once I get my smart meter. It looks like Zappi’s remote API has been partially reverse-engineered. But, given that Zappi can track Agile by itself, provided other things in the house are configured to use the same price thresholds, I didn’t see API access to the charger as a top priority for plumbing in to other home-grown stuff.

Cheers,
Rob