TimSoethout / goodwe-sems-home-assistant

Sensor for Home Assistant pulling data from the GoodWe SEMS API for solar panel production metrics.
84 stars 34 forks source link

Expose "powerflow" metrics: real time power import / export in watts #92

Open IsaacInsoll opened 8 months ago

IsaacInsoll commented 8 months ago

IMG_9503

I installed this integration yesterday and it’s great! I can see energy produced by solar and the import and export kWh values.

SEMS portal also has this real time power graph showing what is current being generated, whole home consumption and feed in/out in watts.

I can see the realtime solar production, is there a way to see these other two values so I can make a real time power chart?

thanks 😀

TimSoethout commented 8 months ago

Good idea. Maybe you can pull out the values using template sensors as mentioned in the readme? Or wait on #91 that might also solve this.

IsaacInsoll commented 8 months ago

I didn’t think templates would work because when I inspect the HomeKit device in the settings page I can’t see the raw power values there plus I didn’t see much in terms of templates that measure in watts (not watt hours) on the homepage.

I’ll have more of a play with it and see if I can work it out. Thank you

On Tue, 7 Nov 2023 at 05:46, Tim Soethout @.***> wrote:

Good idea. Maybe you can pull out the values using template sensors as mentioned in the readme? Or wait on #91 https://github.com/TimSoethout/goodwe-sems-home-assistant/pull/91 that might also solve this.

— Reply to this email directly, view it on GitHub https://github.com/TimSoethout/goodwe-sems-home-assistant/issues/92#issuecomment-1796195598, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHJQ7EEA457I3VEIQ2KDKADYDE47VAVCNFSM6AAAAAA7AA4S7CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTOOJWGE4TKNJZHA . You are receiving this because you authored the thread.Message ID: @.***>

TimSoethout commented 8 months ago

Yes, it can only work if the value is present in the attributes of the inverter. Maybe we need to fetch it from another API call?

IsaacInsoll commented 8 months ago

Awesome. Is there anything I can do to help with that? Like provide a certain log or something?

I’ve got a bit of programming experience but haven’t done anything with SEMS or HA before

On Tue, 7 Nov 2023 at 05:50, Tim Soethout @.***> wrote:

Yes, it can only work if the value is present in the attributes of the inverter. Maybe we need to fetch it from another API call?

— Reply to this email directly, view it on GitHub https://github.com/TimSoethout/goodwe-sems-home-assistant/issues/92#issuecomment-1796225824, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHJQ7EGPKM55HMSW2IWEAS3YDE5OPAVCNFSM6AAAAAA7AA4S7CVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTOOJWGIZDKOBSGQ . You are receiving this because you authored the thread.Message ID: @.***>

TimSoethout commented 8 months ago

You can try using the web portal, and looking at the web inspector for the network calls. Which API call contains the values you're looking for?

IsaacInsoll commented 8 months ago

Heres the UI: image This is the request as a fetch:

fetch("https://au.semsportal.com/api/v2/PowerStation/GetPowerflow", {
  "headers": {
    "accept": "application/json, text/javascript, */*; q=0.01",
    "accept-language": "en-US,en;q=0.9",
    "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
    "neutral": "0",
    "sec-ch-ua": "\"Google Chrome\";v=\"119\", \"Chromium\";v=\"119\", \"Not?A_Brand\";v=\"24\"",
    "sec-ch-ua-mobile": "?0",
    "sec-ch-ua-platform": "\"Windows\"",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-site",
    "token": "<redacted-by-isaac>"
  },
  "referrer": "https://semsportal.com/",
  "referrerPolicy": "strict-origin-when-cross-origin",
  "body": "PowerStationId=<redacted-by-isaac>",
  "method": "POST",
  "mode": "cors",
  "credentials": "omit"
});

which returns:

{
  "language": "en",
  "function": null,
  "hasError": false,
  "msg": "success",
  "code": "0",
  "data": {
    "hasGenset": false,
    "hasMoreInverter": true,
    "hasPowerflow": true,
    "powerflow": {
      "pv": "5001W",
      "pvStatus": -1,
      "bettery": "0W",
      "betteryStatus": 0,
      "betteryStatusStr": null,
      "load": "825W",
      "loadStatus": -1,
      "grid": "4176W",
      "soc": 0,
      "socText": "0%",
      "hasEquipment": true,
      "gridStatus": -1,
      "isHomKit": false,
      "isBpuAndInverterNoBattery": false,
      "isMoreBettery": true,
      "genset": "0W",
      "gensetStatus": 0,
      "gridGensetStatus": 0
    },
    "hasGridLoad": true,
    "isParallelInventers": false,
    "isEvCharge": false,
    "evCharge": null
  },
  "components": {
    "para": "{\"model\":{\"PowerStationId\":\"<redacted-by-isaac>\"}}",
    "langVer": 195,
    "timeSpan": 24,
    "api": "http://au.semsportal.com:82/api/v2/PowerStation/GetPowerflow",
    "msgSocketAdr": null
  }
}

And the reason I think we need this is because I can't currently see these power values in the integration (i can only see kwh energy values): image

So I'd love to be able to expose grid and load from data.powerflow. I'm not sure if pv matches exactly the value we already have for that or if it's different, but might as well expose that too so we have all 3 values to make this chart from the same 'source'

I'm not sure on how to make the changes as I've never done python before but I'm very happy to test this if you can make the changes. Or if you have some basic guidance on the correct way to implement this at a high level then I'm sure I can code something up over the next week.

IsaacInsoll commented 8 months ago

Hi, I just checked out your code to figure out which endpoint you are using, then I queried that endpoint to see if it already has the data we need. Good news, it's in there, so this should be an 'easy' job. The data is under data.powerflow: load and grid (and pv but i can already "see" that one in your integration) Notably it's a string with (W) suffix rather than a 'real' number.

image
IsaacInsoll commented 8 months ago

I noticed that I didn't have a serial number for homeKit so that was causing the third entity not to show up. In sensor.py I added a few lines:

           if hasPowerflow:
                if hasEnergeStatisticsCharts:
                    StatisticsCharts = { f"Charts_{key}": val for key, val in result["energeStatisticsCharts"].items() }
                    StatisticsTotals = { f"Totals_{key}": val for key, val in result["energeStatisticsTotals"].items() }
                    powerflow = { **result["powerflow"],  **StatisticsCharts, **StatisticsTotals }
                else:
                    powerflow = result["powerflow"]

                powerflow["sn"] = result["homKit"]["sn"]

                #isaac start
                if powerflow["sn"] is None:
                    powerflow["sn"] = "GW-HOMEKIT-NO-SERIAL"
                #isaac end

                #_LOGGER.debug("homeKit sn: %s", result["homKit"]["sn"])
                # This seems more accurate than the Chart_sum
                powerflow["all_time_generation"] = result["kpi"]["total_power"]

                data["homeKit"] = powerflow

directly edited on my live machine then restarted Home Assistant, and now the mystical third entity is there. So I'd say the real fault is incorrect handling of devices with no serial number. Just to confirm: this is the 'Smart Meter' not the 'HomeKit' so that's why it might not be registering a serial number even though it's got all the same data.

image

I'm not going to make a PR because I just hacked this in and presume you might have a better way you want to handle it.