Skip to content
View in the app

A better way to browse. Learn more.

Power Forum - Renewable Energy Discussion

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Raw access to Growatt Inverter Data

Featured Replies

Hi ZhanQui !

I'm trying your trick, I see the "History data" button but nothing happens when I click it. I guess the problem is I've lost the connection with de Inversor right now, I'm going to try it when I connect again the wifi.

Regards,

Umel

  • Replies 94
  • Views 55.8k
  • Created
  • Last Reply

Top Posters In This Topic

Most Popular Posts

  • A couple of weeks on, and I'm reporting on my findings to date.  There appear to be three options 1. query locally via direct cable - reports of the software for this as sketchy at best. 2.

  • Antonio de Sa
    Antonio de Sa

    Herewith dashboard of my two Growatt custom made monitoring system for this month, as @zsde explains there is a slight discrepancy in the measurements maybe due to calibration and small losses, in my

  • Hello from Australia, This thread has been very useful, so I thought I would share something i just discovered.  I have also had the issues with exporting data from the growatt web page, and I

Posted Images

On 2022/05/03 at 6:23 PM, L_D said:

There is nothing in my /home/Growatt output folder because the script stopped with the NonType error in my earlier post.

I changed line 11-15 as per your script instruction.

 

image.thumb.png.15f849aa12e1418798754cce3de22d13.png

Where can I find the complete source for this script? It might save me a lot of time in accessing the data for my inverter from the server. Thank you - Rowan

  • 2 weeks later...
On 2022/06/21 at 2:58 PM, Mike_C said:

Thanks for this - I found it very helpful. I also found the comments in the "growattServer/__init__.py script useful, too.

Like many others I was getting the "None" type error because many of the "mix_***" functions simply return "None".

I also had to change the url with "api.server_url = 'https://server.growatt.com/'" to get login to work.

I use the flowing code to get the Year-by-month, Month-by-day and Day-by-5-min-time slot data using the "api.dashboard_data" function.

Here's the code extract to achieve this:

hour_data = api.dashboard_data(plant_id, growattServer.Timespan.hour,  dayToProcess)
day_data  = api.dashboard_data(plant_id, growattServer.Timespan.day,   dayToProcess)
mon_data  = api.dashboard_data(plant_id, growattServer.Timespan.month, dayToProcess)

# deal with month = year-to-date data
print("\nYear-to-date,\n")
month = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]
headers = "\nMonth, "
for key_value in mon_data:
    if key_value == 'keyNames':
        for i in range(4):
            headers = headers + mon_data['keyNames'][i] +", "
    elif key_value != 'chartData': 
        print(key_value + " :, " + mon_data[key_value])

print(headers)

monchartData = mon_data['chartData']

for i in range(len(monchartData['ppv'])):
    print(month[i] + ", " + str(monchartData['ppv'][i]) + ", "\
          + str(monchartData['sysOut'][i]) + ", "\
              + str(monchartData['userLoad'][i]) + ", "\
                  + str(monchartData['pacToUser'][i]))

# deal with day = month-to-date data
print("\nMonth-to-date,\n")
headers = "\nDate, "
for key_value in day_data:
    if key_value == 'keyNames':
        for i in range(4):
            headers = headers + day_data['keyNames'][i] +", "
    elif key_value != 'chartData': 
        print(key_value + " :, " + day_data[key_value])

print(headers)

daychartData = day_data['chartData']

for i in range(len(daychartData['ppv'])):
    print(str(i+1) + ", " + str(daychartData['ppv'][i]) + ", "\
          + str(daychartData['sysOut'][i]) + ", "\
              + str(daychartData['userLoad'][i]) + ", "\
                  + str(daychartData['pacToUser'][i]))

        
# deal with 'hour' data - actually 5-minute periods
print("\nDaily data,\n")
headers = "\nTime, "
for key_value in hour_data:
    if key_value == 'keyNames':
        for i in range(4):
            headers = headers + hour_data['keyNames'][i] +", "
    elif key_value != 'chartData': 
        print(key_value + " :, " + hour_data[key_value])
     
print(headers)

hourchartData = hour_data['chartData']

for time_entry, data_points in hourchartData.items():
    print(time_entry + ", " + str(round(float(data_points['ppv']),2)) + ", " \
          + str(round(float(data_points['sysOut']),2)) + ", " \
              + str(round(float(data_points['userLoad']),2)) + ", " \
                  + str(round(float(data_points['pacToUser']),2)) )

I used "print" statements  whilst experimenting but it's a simple process to replace these with <file-handle>.write statements - just need to remember to add a trailing "\n".

I realise that the "str(......)" functions in most of the the above code are in fact redundant - I'm a newbie to python is my excuse.

I attach an excel spreadsheet showing the three lots of data from my system for yesterday.

The sharp-eyed among you will notice that I'm getting very little from my battery. This system was only installed last week and has not worked properly in this respect. I've now asked the supplier to either replace it with something that does work, preferably from another manufacturer,  or else remove it - so it looks like my work on this will be in vain unless someone else can make use of it.

growatt-dashboard-charts-20230815.xlsx

  • 2 weeks later...

Hello,

I also try to use this script but cannot pass the login phase:

dayToProcess is: 2023-08-25
Traceback (most recent call last):
  File "/home/growatt/./processToFiles.py", line 37, in <module>
    login_response = api.login(user_name, user_pass)
  File "/home/growatt/.local/lib/python3.9/site-packages/growattServer/__init__.py", line 131, in login
    response = self.session.post(self.get_url('newTwoLoginAPI.do'), data={
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 590, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 662, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/hooks.py", line 31, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
  File "/home/growatt/.local/lib/python3.9/site-packages/growattServer/__init__.py", line 41, in <lambda>
    'response': lambda response, *args, **kwargs: response.raise_for_status()
  File "/usr/lib/python3/dist-packages/requests/models.py", line 943, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 405 Client Error: Not Allowed for url: https://server-api.growatt.com/newTwoLoginAPI.do

 

I also changed the API url to "https://server.growatt.com" and got similar error:

dayToProcess is: 2023-08-25
Traceback (most recent call last):
  File "/home/growatt/./processToFiles.py", line 37, in <module>
    login_response = api.login(user_name, user_pass)
  File "/home/growatt/.local/lib/python3.9/site-packages/growattServer/__init__.py", line 131, in login
    response = self.session.post(self.get_url('newTwoLoginAPI.do'), data={
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 590, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 662, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/hooks.py", line 31, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
  File "/home/growatt/.local/lib/python3.9/site-packages/growattServer/__init__.py", line 41, in <lambda>
    'response': lambda response, *args, **kwargs: response.raise_for_status()
  File "/usr/lib/python3/dist-packages/requests/models.py", line 943, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://server.growatt.com/newTwoLoginAPI.do
 

10 minutes ago, gmt77 said:

Hello,

I also try to use this script but cannot pass the login phase:

dayToProcess is: 2023-08-25
Traceback (most recent call last):
  File "/home/growatt/./processToFiles.py", line 37, in <module>
    login_response = api.login(user_name, user_pass)
  File "/home/growatt/.local/lib/python3.9/site-packages/growattServer/__init__.py", line 131, in login
    response = self.session.post(self.get_url('newTwoLoginAPI.do'), data={
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 590, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 662, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/hooks.py", line 31, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
  File "/home/growatt/.local/lib/python3.9/site-packages/growattServer/__init__.py", line 41, in <lambda>
    'response': lambda response, *args, **kwargs: response.raise_for_status()
  File "/usr/lib/python3/dist-packages/requests/models.py", line 943, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 405 Client Error: Not Allowed for url: https://server-api.growatt.com/newTwoLoginAPI.do

 

I also changed the API url to "https://server.growatt.com" and got similar error:

dayToProcess is: 2023-08-25
Traceback (most recent call last):
  File "/home/growatt/./processToFiles.py", line 37, in <module>
    login_response = api.login(user_name, user_pass)
  File "/home/growatt/.local/lib/python3.9/site-packages/growattServer/__init__.py", line 131, in login
    response = self.session.post(self.get_url('newTwoLoginAPI.do'), data={
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 590, in post
    return self.request('POST', url, data=data, json=json, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 542, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python3/dist-packages/requests/sessions.py", line 662, in send
    r = dispatch_hook('response', hooks, r, **kwargs)
  File "/usr/lib/python3/dist-packages/requests/hooks.py", line 31, in dispatch_hook
    _hook_data = hook(hook_data, **kwargs)
  File "/home/growatt/.local/lib/python3.9/site-packages/growattServer/__init__.py", line 41, in <lambda>
    'response': lambda response, *args, **kwargs: response.raise_for_status()
  File "/usr/lib/python3/dist-packages/requests/models.py", line 943, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://server.growatt.com/newTwoLoginAPI.do
 

I had this problem starting a couple of days ago, too. I resolved it by ensuring I had these two statements BEFORE calling api.login:

api            = growattServer.GrowattApi(True,"newname")
api.server_url = 'https://server.growatt.com/'

This sets up a new UserAgent for each login - could it be that Growatt have blocked the default UA?

Thank you @maptin for helping me fixing the login.

Looking into API documentation (growattServer · PyPI) I see:

api = growattServer.GrowattApi() # The default way to initialise

api = growattServer.GrowattApi(True) # Adds a randomly generated User ID to the default User-Agent

api = growattServer.GrowattApi(False, "my_user_agent_value") # Overrides the default and uses "my_user_agent_value" in the User-Agent header

My expectation was to use False, not True when you have 2 parameters. But it work as you described ;)

Now I am getting the 'NoneType' errors as you described. Hope the figure out how to solve them.

53 minutes ago, gmt77 said:

Thank you @maptin for helping me fixing the login.

Looking into API documentation (growattServer · PyPI) I see:

api = growattServer.GrowattApi() # The default way to initialise

api = growattServer.GrowattApi(True) # Adds a randomly generated User ID to the default User-Agent

api = growattServer.GrowattApi(False, "my_user_agent_value") # Overrides the default and uses "my_user_agent_value" in the User-Agent header

My expectation was to use False, not True when you have 2 parameters. But it work as you described ;)

Now I am getting the 'NoneType' errors as you described. Hope the figure out how to solve them.

I found using either "True" of "False" with a "my_user_agent_value" string seems to work. "True" will append a random string of decimal digits after the "my_user_agent_value" string whereas "False" just uses the string as is.

I think the most useful info is available from api.dashboard_data(...) which seems to be working OK. I'd appreciate any input from others who are more experienced to understand why mix and tlx don't seem to work - maybe because I'm not passing the correct info as parameters?

On 2022/05/01 at 11:32 PM, Mike_C said:

My overdue update of #3.  I have found it to be stable enough / gives me what I want that I have not explored option #2 at all.

I have found that growattServer 1.2.0 to be the best for my needs.

It can be installed via:

pip install growattServer

Details can be found here: https://pypi.org/project/growattServer

I have no affiliation to this project; I am just one customer / user that has found it to give me what I need.

 

I have this running on an m1 mac and have attached my python3 script.  I can't comment on how easier it is to translate this to windows / linux (if any 'translation' is needed at all).  Either way, before running, complete the set up variables configuration (line 11 to 15).

 

To run (based on today’s date) :

python3 ./processToFiles.py

To run (based on YYYY-MM-DD) provide three separate parameters :

python3 ./processToFiles.py YYYY MM DD

 

The files generated are a combination of direct API call output and some calculated values.

A summary csv is generated detailing (and this is how I think about energy created / used):

  • Solar (PV) to battery (i.e. stored)
  • Solar (PV) to user (i.e. used at time of generation)
  • Solar (PV) to grid (i.e. exported)
  • Battery to user (i.e. used post generation)
  • Grid to battery (should be close to zero but fluctuates)
  • Grid to User (imported energy)

 

I then compare this CSV in Excel to that provided by my energy provider - i.e. exported and imported values.

 

processToFiles.py 11.16 kB · 79 downloads

Maybe @Mike_C as the author of the script can help us with the not working mix calls

  • 1 month later...

The success rate with the python script has recently (since mid Sep 2023) degraded significantly.  I also notice that the iOS app and the website are both rather slow or have a high failure rate - at login and/or to display data.

I have migrated to a node / javascript implementation I found.  It's one login, one method call and one logout.

It can be found here: https://github.com/PLCHome/growatt/tree/master

I've created a simple docker container from alpine (utilising this to isolate from all other things on my server), wrapped some json parsing functionality around the calls (which i've learnt on the go) to perform the same data processing as with the python script.

For me, this appears to be FAR more stable and reliable that the python version and funnily enough the iOS app.  Whilst the iOS app was presening network timeouts, I found this script happily returning the data I needed.

 

Thought I would mention this in this thread if others are still struggling with the python version (which I have stopped using myself).

 

The success rate with the python script has recently (since mid Sep 2023) degraded significantly.  I also notice that the iOS app and the website are both rather slow or have a high failure rate - at login and/or to display data.

I have migrated to a node / javascript implementation I found.  It's one login, one method call and one logout.

It can be found here: https://github.com/PLCHome/growatt/tree/master

I've created a simple docker container from alpine (utilising this to isolate from all other things on my server), wrapped some json parsing functionality around the calls (which i've learnt on the go) to perform the same data processing as with the python script.

For me, this appears to be FAR more stable and reliable that the python version and funnily enough the iOS app.  Whilst the iOS app was presening network timeouts, I found this script happily returning the data I needed.

 

Thought I would mention this in this thread if others are still struggling with the python version (which I have stopped using myself).

Hi Mike,

 

like you I'me getting more and more frustrated with the instability of the Growatt server and the issues with the python scripts not being able to login. I put a fair bit of time to developing versions of your processToFiles.py that would produce CSV files and direct plots using mathplotlib which now appear to be useless! I have emailed the developer of the growattServer module to see if he can throw any light on the login issue. I understand from the company who installed my system that the instability problem with Shinephone and the web access is down to Growatt.

I have been looking into other possible solutions using 3rd party software that will connect to the inverter, either via the Growatt dongle (not found anything yet) or via a serial-usb adapter, replacing the Growatt dongle - Solar Assistant seems to be the most likely but the issue then is the company that installed it won't have access to my data if I need their support, which I did initially because the battery/inverter they originally installed had to be replaced as it wouldn't recharge (I think they simply installed the ct sensors incorrectly but who am I to tell the pros how to do their job?!

I am now interested in your solution using PLCHome - would you be willing to share the json parsing code you developed?

I'm totally new to js but I understand the concept of RTFM (I was an assembler, FORTRAN, C and other high-level languages programmer in a former life) so I'm up for the challenge of getting my head round node/js.

For my part, I'm happy to share my customised python script with anyone who cares to persevere with the growattServer module. I've attached "growatt-plot-dashboard-charts-generic.py" to this reply

growatt-plot-dashboard-charts-generic.py

 

Solar Assistant seems to be the most likely but the issue then is the company that installed it won't have access to my data if I need their support,

Solar assistant allows you to grant view mode via an email address to anyone. So your installer/service provider can monitor all the data and more with SA.

I blanked out my unique URL, but this is the facility in SA where you can invite others as "viewer".

image.thumb.png.d4b23c021fafbd61f35340e7c07f6c32.png

 

Solar assistant allows you to grant view mode via an email address to anyone. So your installer/service provider can monitor all the data and more with SA.

 

Many thanks for this. It may prove to be the way to go but I anticipate they may resist me foisting a different system on them for monitoring and it might just invalidate my warranty. I might still give it a try as I could always reconnect the Growatt dongle if necessary.

I will try with the Node/js option first, if only because it presents me with a new challenge/learning opportunity.

My first little hiccup with Solar Assistant is that, despite buying a license, when installed it tells me I'm on time-limited free trial! It also currently only works

 

Hello from Australia,

This thread has been very useful, so I thought I would share something i just discovered. 
I have also had the issues with exporting data from the growatt web page, and I have resorted to installing homeassistant and letting it use the required API calls to sort me out, which works ok. 

The trick of using the 'older/alternative' URL with plant.do in it works .. sometimes.. as soon as it works out you aren't 'new' it puts you back to the new site. 

I found that you can generate a URL to 'share' your dashboard with others.  It looks very similar to the 'owner' dashboard in most respects, BUT, has the 'History Data' enabled. 

From the main dashboard -> Energy Button

Choose 'Plant Management'
On the far right column, I see 'Operating Tools' and one icon is for 'Share Plant'
On the new window, put in your email address, how long it is effective, and press 'yes' to send yourself the email. 

When you get the email, open the link in a different browser, or an incognito window. It shouldn't need to be logged in. 

Then on the dashboard, when you scroll down to the 'My Photovoltaic Devices' you have the button 'History Data' instead of 'Setting' that you can usually see. 

From here you can export a day of data at a time to an excel file (not great, but, better then nothing.)

Hope this helps someone!

(tested on a SPH5000)

This works for me on my SPA3000 - many thanks! The key part is to open the link in what Safari and Firefox call a Private Window (File/New Private Window)

Despite continued timeouts via the ios app, this implementation seems rocksolid.  I run this every 5 minutes with a crontab in a docker container built on alpine:3.12.4

I honestly found that the "Simple Implementation" section of the github page was all that i needed to get up and running.  Whereas the python script needed multiple calls, this seems to pull everything back in a single call.  This does make it a little trickier to find the data you're after but a bit of 'jq' processing is all it takes to find the path of data you are after.

As requested, I attach the file that i now run.  I've commented it where i think it needs it and added some retry logic for the login and api call.  I don't suggest this is perfect coding as its still rough and ready but working.  I find that calling this every 5 minutes is enough for me to graph in near realtime. The git page details the configuration changes that could be applied; if you are after more historical data, you can change the options={} with options={historyAll:true}.runSolarUpdate_mike.js

6 hours ago, tulamidan said:

I've only had problems with the API so far. When I tried the PLCHome solution it got a lot better. For convenience I've also built a Docker which sends the values via MQTT to my broker (each minute).

If you are interested https://hub.docker.com/r/bbme/growattnpm

Many thanks for this. I need to get my head round Docker, MQTT, etc.

  • 5 months later...
On 2022/05/02 at 2:02 AM, Mike_C said:

My overdue update of #3.  I have found it to be stable enough / gives me what I want that I have not explored option #2 at all.

I have found that growattServer 1.2.0 to be the best for my needs.

It can be installed via:

pip install growattServer

Details can be found here: https://pypi.org/project/growattServer

I have no affiliation to this project; I am just one customer / user that has found it to give me what I need.

 

I have this running on an m1 mac and have attached my python3 script.  I can't comment on how easier it is to translate this to windows / linux (if any 'translation' is needed at all).  Either way, before running, complete the set up variables configuration (line 11 to 15).

 

To run (based on today’s date) :

python3 ./processToFiles.py

To run (based on YYYY-MM-DD) provide three separate parameters :

python3 ./processToFiles.py YYYY MM DD

 

The files generated are a combination of direct API call output and some calculated values.

A summary csv is generated detailing (and this is how I think about energy created / used):

  • Solar (PV) to battery (i.e. stored)
  • Solar (PV) to user (i.e. used at time of generation)
  • Solar (PV) to grid (i.e. exported)
  • Battery to user (i.e. used post generation)
  • Grid to battery (should be close to zero but fluctuates)
  • Grid to User (imported energy)

 

I then compare this CSV in Excel to that provided by my energy provider - i.e. exported and imported values.

 

processToFiles.py 11.16 kB · 98 downloads

hey will you guide me step by step how to do this. I'm new 

  • 3 months later...

Hello all,
I also had the problem that you can only load the PV data from the Growatt server as a graphic. And I haven't found a simple solution.
So I've spent the last few months trying to figure out how to access the Growatt server. Now I've written an app for Android that fetches and saves the data from the Growatt server.
I've published the app in Google's Playstore. Unfortunately it's hard to find. So here are the links.

You can use the trial version to see if it's something for you.
If there's more interest, I'm sure I can make improvements.

more information is available on “www.rexplorer.de”.

Regards

Sorry, now here with the links:

I also had the problem that you can only load the PV data from the Growatt server as a graphic. And I haven't found a simple solution.
So I've spent the last few months trying to figure out how to access the Growatt server. Now I've written an app for Android that fetches and saves the data from the Growatt server.
I've published the app in Google's Playstore. Unfortunately it's hard to find. So here are the links.

Testversion: „Growatt PV Download Std Solar“
https://play.google.com/store/apps/details?id=de.rexplorer.solardatapickerpvgrowatt.Testing

Pro-Version: „Growatt PV Pro Downloader Sola“
https://play.google.com/store/apps/details?id=de.rexplorer.solardatapickerpvgrowatt.Pro

You can use the trial version to see if it's something for you.
If there's more interest, I'm sure I can make improvements.

more information is available on “www.rexplorer.de”.

Regards

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.