jbuehl/solaredge

Battery and metering support?

Closed this issue · 6 comments

My SolarEdge inverter has a Tesla powerwall attached and apparently also provides metering data. It looks like there is no support for these in this package, would it be possible add it (short of my hacking into in the code and submitting a PR)?

Here is what I'm seeing from my data collection script that can't be parsed:

ERROR: Unable to process batteries_0x0030 data! ({u'7F15397E': {u'T16H0013143\x00': {u'batteryId': u'T16H0013143\x00', u'seId': u'7F15397E', u'TotalEnergyOut': 12792, u'devLen': 86, u'EOut': 0, u'TotalEnergyIn': 11668, u'BattCapacityActual': 6376.0, u'AlwaysZero_66_float': 0.0, u'Date': u'2017-07-05', u'HexConst_56': u'ff ff 7f ff', u'AlwaysZero_48_float': 0.0, u'HexConst_52': u'ff ff 7f ff', u'EIn': 4, u'Temp': 23.0, u'Interval': 300, u'AlwaysZero_70_float': 0.0, u'seType': u'0x0030', u'Time': u'13:09:36', u'Idc': 0.0, u'BattCharge': 263.0, u'AlwaysZero_40_float': 0.0, u'BattChargingStatus': 6, u'BattCapacityNom': 6400.0, u'Vdc': 358.29998779296875, u'dateTime': 1499285376, u'devType': u'batteries_0x0030'}}})
ERROR: Unable to process meters_0x0022 data! ({u'7F15397E': {u'8_MostlyZeroes': {u'TotalE2Grid': 0, u'AlwaysZero_off34_int2': 0, u'seId': u'7F15397E', u'P2X': 0.0, u'Flag_off20_hex': u'00 80', u'devLen': 58, u'Flag_off28_hex': u'00 80', u'E2X': 0, u'PfromX': nan, u'TotalEfromGrid': 0, u'Date': u'2017-07-05', u'Totaloff22_int4': 0, u'Totaloff30_int4': 0, u'Interval': 300, u'EfromX': 0, u'seType': u'0x0022', u'Time': u'13:09:36', u'Flag_off12_hex': u'00 80', u'onlyIntervalData': 1, u'dateTime': 1499285376, u'AlwaysZero_off26_int2': 0, u'AlwaysZero_off10_int2': 0, u'devType': u'meters_0x0022', u'Flag_off36_hex': u'00 80', u'AlwaysZero_off18_int2': 0, u'recType': 8}, u'7_Battery': {u'TotalE2Grid': 0, u'AlwaysZero_off34_int2': 0, u'seId': u'7F15397E', u'P2X': 0.0, u'Flag_off20_hex': u'00 80', u'devLen': 58, u'Flag_off28_hex': u'00 80', u'E2X': 0, u'PfromX': nan, u'TotalEfromGrid': 0, u'Date': u'2017-07-05', u'Totaloff22_int4': 0, u'Totaloff30_int4': 0, u'Interval': 300, u'EfromX': 0, u'seType': u'0x0022', u'Time': u'13:09:36', u'Flag_off12_hex': u'00 80', u'onlyIntervalData': 1, u'dateTime': 1499285376, u'AlwaysZero_off26_int2': 0, u'AlwaysZero_off10_int2': 0, u'devType': u'meters_0x0022', u'Flag_off36_hex': u'00 80', u'AlwaysZero_off18_int2': 0, u'recType': 7}}})
ERROR: Unable to process meters_0x0022 data! ({u'7F15397E': {u'9_PVProduction': {u'TotalE2Grid': 0, u'AlwaysZero_off34_int2': 0, u'seId': u'7F15397E', u'P2X': 7061.0, u'Flag_off20_hex': u'00 80', u'devLen': 58, u'Flag_off28_hex': u'00 80', u'E2X': 591, u'PfromX': nan, u'TotalEfromGrid': 0, u'Date': u'2017-07-05', u'Totaloff22_int4': 0, u'Totaloff30_int4': 0, u'Interval': 300, u'EfromX': 0, u'seType': u'0x0022', u'Time': u'13:09:36', u'Flag_off12_hex': u'00 80', u'onlyIntervalData': 1, u'dateTime': 1499285376, u'AlwaysZero_off26_int2': 0, u'AlwaysZero_off10_int2': 0, u'devType': u'meters_0x0022', u'Flag_off36_hex': u'00 80', u'AlwaysZero_off18_int2': 0, u'recType': 9}}})

That was recently addressed. See issues #14 and #22. I thought that support for those devices was included.

Hi @sjthespian,

I'm not sure which data collection script is giving you that error message, but on a quick glance, the data that your script says cannot be parsed are actually the (already parsed) json output produced by semonitor when it processes/parses messages sent from the inverter to the solaredge website. ie the package does support deciphering the Tesla powerwall and metering data messages, and that is the output you are seeing.

You can find more documentation (in a fair bit of technical detail) about how that parsing occurs by looking at README.ParseDevice.md

Probably of more use to you, you can find out more about each of those fields by running the following short piece of python code

from seDataDevices import ParseDevice
print ParseDevice.itemDefs()

Hope that helps

Hi @sjthespian

Just had another thought. The json output, when read into python, appears as a (nested) dictionary of dictionaries structure. It may be that your script needs to unwrap this into a sequence of simple dictionaries, for example by iterating over it.

To do this in your own python code, you can use the unwrap_metricsDict method that is part of ParseDevices. That is explained with an example towards the bottom of README.ParseDevices.md (although rereading that now, after not looking at it for a while I must confess there is a fair bit to learn about before it will make complete sense).

Alternatively you can convert the output to a set of csv files (via the se2csv.py script).

Good luck.

I'm an idiot -- that's coming from my own code! :-) I wrote a bit of code to take the output of semonitor.py and feed it to influxdb. It looks like I didn't add support for battery or metering since I didn't know it existed at the time (my battery was just finally enabled last week).

Thanks for the feedback, I'm off to update the code to add support and then add the data to my grafana dashboard. If you think there would be interest, I can submit a pull request for my script.

Just as an FYI, there's one bit of ugliness (imho) with the battery and meter data. The data type has a hex value appended to it, which is going to make it a bit more work to parse. Rather than getting a batteries dict like I get for inverters, the key is batteries_0x0030.

Hi @sjthespian,

Glad you got this sorted out. IMHO semonitor is a pretty impressive piece of software - major credits to jbuehl!

I'll leave the owner (jbuehl) to reply re the pull request for your influxdb script.

I pipe my data to grafana via a graphite database, and use se2graphite.py (well actually I've updated to pickle2graphite.py now) to send the json output from semonitor to graphite's (carbon) listener port. I don't know what format influxdb needs, but the code in those 2 python scripts automatically copes with whatever dictionary names semonitor throws at it, now or in the future.

I do agree the names are a bit ugly, but it was so useful - when I was trying to decipher which solaredge messages reported what data in which field - to be absolutely certain which message I was looking at that I hadn't the heart to change it once I finished. If you want to tidy up the names to something more aesthetic, there are only a couple of lines in seDataDevices.py you'd have to tweak. In the definition of the ParseDevice_0x0022 subclass, just change to definition of the variable _devType (see excerpt below) to a name you would like, and likewise in ParseDevice_0x0030. I'm 99.9% sure everything will still work without any hiccups (unless you say duplicate a dictionary name that already exists, like inverter!)

class ParseDevice_0x0022(ParseDevice) :

    snip

    _dev =  0x0022
    _devName = 'meters'
    _devType = '{}_{:#06x}'.format(_devName, _dev)