My Solar PV Battery app

good point, sounds like we need a limit by feed value process then, i will take a look at this later today, thanks

Awesome!! So glad to see this. Just wanted to say that :-). It looks great!

1 Like

Thanks @mattjgalloway!

If you’re running a tesla powerwall/gateway you can get most/all the feeds from the tesla API. How I did it is in this thread: Powerwall API help - #42 by miker - lots of help from others!


Sorry for the delay in replying. This is not very pretty, but I hope it will work …

Absolutely awesome @TrystanLea, thankyou.

For anyone not an expert (like me) who needs a simple and low effort way to get the Powerwall state-of-charge (SOC) into emonCMS - there are many, many other and more elegant ways, NodeRed, MQQT etc including those in @miker’s thread (see above) - but if you aren’t familiar with any of these and don’t want to learn right now because you just want to get it working, this might be just up your street.

You’ll need to know how to to ssh into your emonpi, and some Linux command line basics only.


  1. Create a python script (8 lines, below) to execute on the emonpi, to fetch the Powerwall SOC and send it to emonCMS.
  2. Create a crontab entry to automatically run the script every minute.


  1. ssh in to emonpi as user pi. Create a python script using your favourite Linux editor (nano is easiest) called, say, in your home directory (/home/pi) with these contents <credit to @TrystanLea for this>:
import urllib2, json
# 1. Fetch data from API 1
response = urllib2.urlopen('http://URL_OF_YOUR_POWERWALL/api/system_status/soe')
jsonstr =
data = json.loads(jsonstr)
soc = data['percentage']
# 2. Post data onwards to API 2
response = urllib2.urlopen('http://URL_OF_YOUR_EMONPI/input/post?node=powerwall&data=soc:'+str(soc)+'&apikey=YOUR_API_KEY')

EmonCMS will automagically create a new feed powerwall:soc if it does not already exist (thanks @TrystanLea).

You should try running it from the shell:

[email protected]: python

but you may get an error, as I did, something like:

urllib2.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:727)>

To circumvent this problem (google it if you want to find out more…) use this command instead:

[email protected]: PYTHONHTTPSVERIFY=0 python

You should be able to see the Input and Feed refreshed in emonCMS. If so, move on. Otherwise you need to find out why it’s not working. You can add print statements to the python script e.g print “hello” or print soc to help.
3. Create a crontab entry to run this script every minute. If you need more info type man crontab and/or man 5 crontab to get more info, or google it.

[email protected]: crontab -e

It will take you into a nano edit of the crontab file, which has prefilled guide comments in it. Add the following lines to the end of the file:

* * * * * PYTHONHTTPSVERIFY=0 /usr/bin/python /home/pi/

Make sure there is a newline at the end of the file, else it will fail to work.
When you exit the editor it will automatically try to add your cron job and tell you if it succeeded. If it did, then that’s it, you’re done.
I hope.


Thankyou for sharing @PeteF that’s great!

You should not need that step


should work just fine and create a new input for you.

thanks @haffle, thinking about it we should be able to use the limit by input process in your case as well, just the other way around so after process 20 add:

  • max_inp (max by input) and chose the solar generation input.
  • Log to feed: solar_direct
  • Power to kWh: solar_direct_kwh

I think that works: If household consumption is say 200W and solar is 1000W, solar_direct will be 200W, if household consumption is 200W and solar 100W the limit by input will make solar_direct 100W as well.

Hi @TrystanLea, thanks for creating this. I ran a full update to get the App installed, but I couldn’t get it to display any datam even using feeds that I know have data. Then I logged out and back in again, and now I see data D’oh! Will now continue to configure the remaining feeds. Huge thanks for creating this, which should save me a heap of time and effort to do something similar.

Trystan, newbie here.

Is this run once to create the input ‘soc’ or is it added to PeteF ’ s getsoc.pi script ?

ps I got my Powerwall 2 installed 3 days ago and just found this Excellent App. when searching for home battery additions to Emoncms.

Good morning @Wirrunna. I have updated my post to reflect @TrystanLea’s very handy tip. It’s only 2 steps now :slight_smile:
I hope it works for you!

This only needs to be ran as part of the script, it automatically creates the input as the data comes in :slight_smile:

This app is working well :slight_smile:

our solor production feed is direct information from the inverters. they are some losses in the inverter and when the calculation is performed its showing export to the grid. is they anyway around this or a calculation on feed?

Hello @Pukka you could apply a loss factor to the input from the inverter, e.g multiply by 0.95 before recording it to a feed? Is it the solar production on the DC side and the inverter doesnt give AC output?

Hi @TrystanLea We have a hybrid inverter and data is being collected via ModBus. so we get lots of information about the solar including temps. I will have a look at creating a feed with a loss just need to have a look and workout the factor.

1 Like

Are you using the EmonHub ModBus interfacer @Pukka out of interest what is the inverter model that you are fetching the data from?

Hi Trystan,

That is very helpful thank you.

I used your process and it works (I had to flip the CT clamp)

So right now in my Dashboard I have it like this

Moixa do not currently publish API’s they are working on a number of improvements to the software / App etc.

So if you could make the Battery SOC optional that would help me out, and probably others.

Many thanks


1 Like

Hi @TrystanLea

I am using Solution: Reading Solax SK-SU5000(E) inverters & SDM630V2 Modbus Power Meters

Its a solax SU5000

1 Like

Running your script almost works, it gets the SOC as evidenced by the print soc , but fails on the last line -

import urllib2, json

1. Fetch data from API 1

response = urllib2.urlopen(‘powerwall ip address/api/system_status/soe’)
jsonstr =
data = json.loads(jsonstr)
soc = data[‘percentage’]
print soc

2. Post data onwards to API 2

response = urllib2.urlopen(‘’+str(soc)+’&apikey=cf146a3b6a83a71fd93a1f5daa598f88’)

Traceback (most recent call last):
File “”, line 9, in
response = urllib2.urlopen(‘’+str(soc)+’&apikey=cf146a3b6a83a71fd93a1f5daa598f88’)
File “/usr/lib/python2.7/”, line 154, in urlopen
return, data, timeout)
File “/usr/lib/python2.7/”, line 435, in open
response = meth(req, response)
File “/usr/lib/python2.7/”, line 548, in http_response
‘http’, request, response, code, msg, hdrs)
File “/usr/lib/python2.7/”, line 473, in error
return self._call_chain(*args)
File “/usr/lib/python2.7/”, line 407, in _call_chain
result = func(*args)
File “/usr/lib/python2.7/”, line 556, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 404: Not Found
[email protected]:~ $

Emoncms is running on a Rpi on its own being fed by Iotawatt.

To get My Solar PV Battery app going I have substituted different feed that is usually zero.

We should have an alternative using EmonHub running very soon @Wirrunna, it would be great if you would be happy to help us test here Fetch Tesla Power Wall State of charge using EmonHub - #21 by TrystanLea