Pages

Monday, 1 June 2015

Capturing Solar Generation Data from the GoodWe Portal.

We recently had a solar PV system installed on our roof and I wanted to capture the amount of energy being generated into our Domoticz console. Now Domoticz has a hardware option to capture such data from the Solaredge system. I personally cannot vouch for how well that works as unfortunately we have a GoodWe inverter so our generation data goes into the http://www.goodwe-power.com/ portal and not the Solaredge system. Am I jealous? Well maybe a little, the solaredge portal looks rather slick compared to the GoodWe system.

Anyway if the data is online somewhere it can be captured so that is what I set out to do. It didn't take much work in the end. I poked around on the website for a little while and looked for any clues that may indicate an API of some description but these searches turned up very little.

What I did find was that GoodWe have their own android app (com.goodwe.EzManage.apk) for monitoring the generation data. I managed to download the .apk, extract it a and began to poke around inside. Within that apk I managed to find a list of strings;

http://goodwe-power.com
http://www.goodwe-power.com
http://www.goodwe-power.com/goodwe/Mobile
http://www.goodwe-power.com/goodwe/Mobile/GetAddress
http://www.goodwe-power.com/goodwe/Mobile/GetInventerDetail?inventerSN=
http://www.goodwe-power.com/goodwe/Mobile/GetMyPowerStationById?stationId=
http://www.goodwe-power.com/goodwe/Mobile/GetMyPowerStationByUser?userName=
http://www.goodwe-power.com/goodwe/Mobile/GetMyPowerStationByUserForES?username=
http://www.goodwe-power.com/goodwe/Mobile/GetPacLineChart?stationId=
http://www.goodwe-power.com/goodwe/Mobile/GetPowerBarChart?stationId=
http://www.goodwe-power.com/goodwe/Mobile/GetPowerBarChartForES?stationId=
http://www.goodwe-power.com/goodwe/Mobile/GetSOCLineChart?stationId=
http://www.goodwe-power.com/goodwe/Mobile/Login?username=

These strings were instantly recognisable as REST endpoints so I logged into the portal and grabbed my station ID from the url and gave the GetMyPowerStationById endpoint a try using the following format.

www.goodwe-power.com/Mobile/GetMyPowerStationById?stationID=63cd46b8--9999-99aa-188b5690238b

This is what I got back;

{
    "curpower": "0.000kW",
    "capacity": "3.000kW",
    "percent": "0",
    "status": "Offline",
    "createdate": "2015-05-28",
    "eday": "0.0kWh",
    "etotal": "26.6kWh",
    "income": "£0.00",
    "totalincome": "£3.46",
    "co2reduce": "0.000",
    "totalco2reduce": "0.010",
    "treesaved": "0.000",
    "totaltreesaved": "0.080"
}

Now those people that know me will know I am no Java programmer but even I recognised that as a JSON object. Just to check I fed it into the JSON validator at http://jsonlint.com/ and my suspicion was confirmed. 

Now I was a little disconcerted that I was able to pull the information so easily without even having to authenticate in any way with the GoodWe portal but at least it would make this a lot easier. I now had a way of getting the data I needed from the portal. Now I just needed to get it into my Domoticz system.

Domoticz has an events system that is powered by Lua scripts. I won't go into the pains I worked through learning how to put together my first Lua script. Lua is fairly well documented elsewhere but what it boiled down to was this. 

1. I needed to make a call to the URL and capture the string returned.
2. I then needed to cast this string into a JSON object for easier access.
3. Next I need to pull the information I want to capture from the JSON object.
4. Finally I needed to put that information into Domoticz.

Suffice it to say that every step was painful for the inexperienced Lua scriptwriter that I am. However with the help of my good friend google. This is what I came up with I hope it is of some help to someone else out there.

-- Script to pull GoodWe power generation data into Domoticz
-- Written by M Grimwade 2015

-- Function to update a Domoticz sensor object
function update(device, id, power, energy)
      commandArray[1] = {['UpdateDevice'] = id .. "|0|" .. energy}
   return
end

-- Command array to populate with Domoticz instructions
commandArray = {}

-- The switch ID of my device in Domoticz
switchIdx = 50

-- Load the JSON Lua module
JSON = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")()

-- Reference the HTTP module enabling web calls
http = require 'socket.http'

-- Perform an HTTP request to get the raw string from the REST endpoint
html = http.request 'http://www.goodwe-power.com/Mobile/GetMyPowerStationByUser?username=mGrimwade'

-- Decode the JSON formatted string to a Lua table
local t = JSON:decode(html)

-- Pull out the sub table containing the data from the main table
local t2 = t[1]

-- Get the currentPower value from the sub table into a string
local currentPowerStr = t2.currentPower

-- Check the length of that string
local currentPowerLen = string.len(currentPowerStr)

-- Trim off the Kwh from the string and cast it to an integer
local currentPowerKwVal = tonumber(string.sub(currentPowerStr,1,currentPowerLen-2))

-- Multiply the Kwh value to get the wh value
local currentPowerWVal = currentPowerKwVal * 1000

-- Call the update function to add the data to Domoticz
update("Usage", switchIdx, currentPowerWVal, currentPowerWVal)

return commandArray




44 comments:

  1. Excellent work! I have been trying to wireshark the packets inverter is sending to goodwe but ended up doing it this way as well. Are your daily and accumulated kWh values updating correctly in domoticz?

    ReplyDelete
  2. Thank you. Yeah they're updating just fine with that script. Hope it was of use to you.

    ReplyDelete
  3. Thanx Mike,

    I'm new to script editing. I also have a goodwe transformer and would like to add its output to domoticz.
    What I dont understand is which data in the script above is a variable. Is it possible to mark the parts in the script which wil be different for my transformer. I succeeded in getting the rest endpoint. Thank you. Han

    ReplyDelete
  4. kirepudsje at gmail dot com11 March 2016 at 10:18

    Thanks for the info.
    I have also been trying to obtain historic data.
    The following is a linux bash script to obtain all data from a given date range.

    #!/bin/bash
    # Kire Pudsje, march 2016
    USERNAME=xxx
    PASSWORD=xxx
    STATIONID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
    OUTFILE=out.csv
    # Note: end date not inclusive
    STARTDATE=2016-01-01
    ENDDATE=2016-03-11

    echo -n ",00:00" > ${OUTFILE}
    TIME="00:10"
    while [ "${TIME}" != "00:00" ]; do
    echo -n ",$TIME" >> ${OUTFILE}
    TIME=$(date -ud "${TIME} UTC + 10 min" "+%R")
    done
    echo ",24:00" >> ${OUTFILE}

    wget -q --save-cookies goodwe_cookies.txt --keep-session-cookies --post-data "user=${USERNAME}&password=${PASSWORD}" http://www.goodwe-power.com/PowerStationPlatform/PowerStationReport/Index?ID=${STATIONID} -O /dev/null

    DATE=${STARTDATE}
    while [ "${DATE}" != "${ENDDATE}" ]; do
    echo Obtaining data from ${DATE}
    wget -q --load-cookies goodwe_cookies.txt --keep-session-cookies --referer "http://www.goodwe-power.com/PowerStationPlatform/PowerStationReport/Index?ID=${STATIONID}" --post-data "PowerStationID=${STATIONID}&PacDateType=0&PacDateStart=${DATE}" http://www.goodwe-power.com/PowerStationPlatform/PowerStationReport/PacQueryTypeChanged -O goodwe_data
    echo -n ${DATE}, >> ${OUTFILE}
    grep -o -E '"PacYAxis":"[^"]*"' goodwe_data | sed -e 's/"PacYAxis":"\(.*\)"/\1/' >> ${OUTFILE}
    DATE=$(date -I -d "${DATE} + 1 day")
    done
    rm goodwe_data goodwe_cookies.txt

    ReplyDelete
    Replies
    1. I modified the script to make it work on Mac (date-function is different). Pls find below the modified script:

      #!/bin/bash
      # Kire Pudsje, march 2016
      # Heini Withagen, Mac compatible march 2016
      USERNAME=xxxxxxx
      PASSWORD=xxxxxxx
      STATIONID=xxxxxxxxx
      OUTFILE=out.csv
      # Note: end date not inclusive
      STARTDATE=2016-03-01
      ENDDATE=2016-03-15

      echo -n ",00:00" > ${OUTFILE}
      TIME="00:10"
      while [ "${TIME}" != "00:00" ]; do
      echo -n ",$TIME" >> ${OUTFILE}
      TIME=$(date -j -f %R -v+10M ${TIME} "+%R")
      done
      echo ",24:00" >> ${OUTFILE}

      wget -q --save-cookies goodwe_cookies.txt --keep-session-cookies --post-data "user=${USERNAME}&password=${PASSWORD}" http://www.goodwe-power.com/PowerStationPlatform/PowerStationReport/Index?ID=${STATIONID} -O /dev/null

      DATE=${STARTDATE}
      while [ "${DATE}" != "${ENDDATE}" ]; do
      echo Obtaining data from ${DATE}
      wget -q --load-cookies goodwe_cookies.txt --keep-session-cookies --referer "http://www.goodwe-power.com/PowerStationPlatform/PowerStationReport/Index?ID=${STATIONID}" --post-data "PowerStationID=${STATIONID}&PacDateType=0&PacDateStart=${DATE}" http://www.goodwe-power.com/PowerStationPlatform/PowerStationReport/PacQueryTypeChanged -O goodwe_data
      echo -n ${DATE}, >> ${OUTFILE}
      grep -o -E '"PacYAxis":"[^"]*"' goodwe_data | sed -e 's/"PacYAxis":"\(.*\)"/\1/' >> ${OUTFILE}
      DATE=$(date -j -f %Y-%m-%d -v+1d ${DATE} +%Y-%m-%d)
      done
      rm goodwe_data goodwe_cookies.txt

      Delete
  5. Hi! I got a goodwe installation since a few days and I tried this on my Synology NAS with Domoticz installed. I have no idea where i can get the socket.http module files for getting this to work.

    ReplyDelete
    Replies
    1. http://w3.impa.br/~diego/software/luasocket/http.html

      Delete
  6. Hi! Did you first create virtual devices voor the Goodwe?
    I miss that part. You say that:
    -- The switch ID of my device in Domoticz
    switchIdx = 50
    But I cannot see where this comes from.
    Could you please explain this tot me?

    ReplyDelete
    Replies
    1. I made a dummy with a virtual switch. The IDX of the newly created virtual switch needs to put in the script mentioned above.

      Delete
  7. Hi, I setup a goodwe inverter in Domoticz on my Pi Zero with the built-in GoodWe hardware. It just gets data at 1.57 a.m, 2 days in a row. No real time data. Any idea?

    ReplyDelete
  8. Looks nice. Was looking for something like this, because the api isn't working anymore in Domoticz.
    Do you have the script working with the new portal? I don't think the url is enough. Do you know is there a way to read it directly from the inverter?

    ReplyDelete
  9. Buy solar systems & led lights for residential & commercial areas top brand company at affordable prices. Choose from solar panels, solar inverters, solar batteries, solar charge controllers, solar street light to solar installation kit. branded products, lowest price, assured delivery with in 3 to 5 days. Reduce your Electricity Bill and Save Money with
    adityasolars.com HURRY :) You can order online at leduncle.com Contact:- customer@leduncle.com | +91 78275 91463

    ReplyDelete
  10. 870DBLaura56A2015 April 2024 at 08:56

    692F8
    ----
    ----
    ----
    ----
    ----
    ----
    ----
    matadorbet
    ----

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete