indykoning / PyPi_GrowattServer

MIT License
70 stars 32 forks source link

What is the best way to get historical data? #27

Open jbrinchmann opened 2 years ago

jbrinchmann commented 2 years ago

Hi, thanks very much for a very useful package!

I was wondering what the best way is to get historical data - I would like to get consumption over the last 24 hours, say, at e.g. 30 min result. I have a simple system with a single inversor and no batteries (for now). I had thought that perhaps I could use something like

dashboard_data = api.dashboard_data(<ID>, timespan=growattServer.Timespan['day'])

but for me at least this gives a chartData with no useful information.

gconceicao commented 2 years ago

To me as well

I am using the command Dash_board_response = api.dashboard_data(plant_id, timespan=growattServer.Timespan['day'],date= datetime.datetime(2022,3,1))

The dash board of the inverter plant has a chart information with all days filled.

The python response is always as line below: CHART: {'ratio2': '0%', 'ratio1': '0%', 'photovoltaic': '0kWh', 'chartData': {'pacToUser': [], 'sysOut': [], 'userLoad': [], 'ppv': []}, 'echargeToat': '0kWh', 'etouser': '0kWh', 'ratio6': '0%', 'ratio5': '0%', 'ratio4': '0%', 'ratio3': '0%', 'eChargeToday2Echarge1': '0kWh', 'echarge1': '0kWh', 'eChargeToday2': '0kWh', 'eCharge': '0kWh', 'eAcCharge': '0kWh', 'elocalLoad': '0kWh', 'eChargeToday1': '0kWh', 'chartDataUnit': 'kWh', 'keyNames': [None, None, None, None]}

image

jkkataja commented 1 year ago

👋 also thinking on how to export data from the servers to my local SQL for long term storage + data manipulation

Using api.plant_detail looks promising (extra ugly first round fiddling code):

    print("day:")
    print(api.plant_detail(plant, timespan=growattServer.Timespan['day']))
    print("month:")
    print(api.plant_detail(plant, timespan=growattServer.Timespan['month']))

Result:

day:
{'plantData': {'plantMoneyText': '<redact> (€)', 'plantName': '<redact>', 'plantId': '<redact>, 'currentEnergy': '16.4 kWh'}, 'data': {'15:00': '1343.78', '05:00': '46.93', '18:30': '516.93', '11:30': '573.9', '12:00': '2266.17', '21:30': '0', '20:30': '96.87', '07:30': '907.38', '08:30': '1527.53', '17:30': '776.07', '10:30': '589.92', '09:00': '1640.9', '03:00': '0', '14:00': '950.27', '16:00': '790.6', '13:30': '1830.95', '02:00': '0', '01:00': '0', '12:30': '2271.38', '19:30': '326.95', '04:00': '49.98', '22:00': '0', '15:30': '1857.23', '06:30': '445.02', '07:00': '1431.83', '19:00': '398.65', '05:30': '58.45', '10:00': '2007.62', '17:00': '786.78', '09:30': '1525.33', '21:00': '0', '08:00': '1277.32', '03:30': '0', '11:00': '485.75', '18:00': '800.3', '14:30': '1473.92', '20:00': '127.55', '01:30': '0', '04:30': '41', '06:00': '167.3', '13:00': '1537.75', '00:30': '0', '16:30': '1595.12', '02:30': '0'}, 'success': True}
month:
{'plantData': {'plantMoneyText': '<redact> (€)', 'plantName': '<redact>', 'plantId': '<redact>', 'currentEnergy': '150.3 kWh'}, 'data': {'19': '0.0', '17': '0.0', '18': '0.0', '15': '16.4', '16': '0.0', '13': '6.5', '14': '21.3', '11': '17.1', '12': '12.3', '21': '0.0', '20': '0.0', '08': '25.7', '09': '15.5', '04': '0.0', '22': '0.0', '05': '0.0', '23': '0.0', '06': '0.0', '24': '0.0', '25': '0.0', '07': '11', '26': '0.0', '27': '0.0', '01': '0.0', '02': '0.0', '28': '0.0', '03': '0.0', '29': '0.0', '10': '24.5', '30': '0.0', '31': '0.0'}, 'success': True}

The granularity seems to be lacking though, I have the collector set in the default 5min interval (didn't find a simple way to change the collection cycle to 1min) so would be nice to be able to get the whole set for a day.

christian-5-28 commented 1 year ago

Hi @jbrinchmann,

If you still didn't solve this, I suggest you to use the "mix_detail" function. It will return a json object with the correct chart data with a 5 min interval. The function you want to you is this one:

mix_detail_json = api.mix_detail(device_sn, plant_id, growattServer.Timespan.hour, date)

the chart data is accessible with the key "chartData": mix_detail_json['chartData']

Below you can find a quick wrapper function I made to create a pandas dataframe with the chart data and their conversion to their KW consumption per each 5-minute data point, I hope it can be useful for you and other users:

import pandas as pd

def retrieve_energy_data(date, device_sn, plant_id):

    # collecting the chart data for a specific date
    mix_detail_json = api.mix_detail(device_sn, plant_id, growattServer.Timespan.hour, date)

    # preparing the dictionary to create the pandas dataframe
    daily_inverter_dict = {}
    daily_inverter_dict['time'] = []
    daily_inverter_dict['ppv'] = []
    daily_inverter_dict['sysOut'] = []
    daily_inverter_dict['pacToGrid'] = []
    daily_inverter_dict['pdischarge'] = []
    daily_inverter_dict['pacToUser'] = []

    for k, v in mix_detail_json['chartData'].items():

        # storing the time values
        daily_inverter_dict['time'].append(str(date) + ' ' + k)

        # storing in the dictionary the plant production/consumption values
        [daily_inverter_dict[key].append(value) for key, value in v.items()]

    # creating the pandas dataframe
    daily_df = pd.DataFrame.from_dict(daily_inverter_dict)

    # reordering by datetime column
    daily_df.time = pd.to_datetime(daily_df.time)
    daily_df = daily_df.sort_values('time')

    # rename columns to more understandable names
    daily_df.rename(columns={'pacToGrid': 'exported_to_grid',
                             'ppv': 'solar',
                             'sysOut': 'load_consumption',
                             'pdischarge': 'from_battery',
                             'pacToUser': 'imported_from_grid'}, inplace=True)

    # computing the real kW consumption per 5-minute interval
    # main hypothesis is that the kWh is constant in the 5-minute intervals
    for col in daily_df.drop(columns='time').columns:

        # converting the values to float
        daily_df[col] = daily_df[col].astype(float)

        # converting the kWh to the 5-min interval
        daily_df[col + '_minutes'] = daily_df[col] * (5/60)

    # computing the self consumption values 
    daily_df['self_consumption_minutes'] = daily_df['load_consumption_minutes'] - daily_df['imported_from_grid_minutes']

    return daily_df
codac commented 1 year ago

Hi guys, I'm trying to get the historical data of my Growatt 600 TL-X. Therefor I use the following two api calls: api.tlx_data(tlx_id, date) Get some basic data of a specific date for the tlx type inverter. Result: The Watt output for every 5 minutes for a spicific day, even in the past.

'2022-11-06 11:15': 386,
'2022-11-06 11:30': 623.2000122070312,
'2022-11-06 11:35': 623.7000122070312,
'2022-11-06 11:40': 624.2999877929688,
'2022-11-06 11:45': 622.7000122070312,
'2022-11-06 11:50': 621.7666625976562,
'2022-11-06 11:55': 619.933349609375,
'2022-11-06 12:00': 621.933349609375,
'2022-11-06 12:05': 622.2666625976562,
'2022-11-06 12:10': 622.6000366210938,
'2022-11-06 12:15': 621.7000122070312,
'2022-11-06 12:20': 620.8500366210938,
'2022-11-06 12:25': 621.7000122070312,
'2022-11-06 12:30': 621.7333374023438,

and so on...

api.tlx_detail(tlx_id) Get detailed data on a tlx type inverter. Result: All the values available, but only for todays day. This is just a part of all values:

                'pac': 0.0,
                'pac1': 0.0,
                'pac2': 0.0,
                'pac3': 0.0,
                'pacToGridTotal': 0.0,
                'pacToLocalLoad': 0.0,
                'pacToUserTotal': 0.0,
                'pacr': 0.0,
                'pex1': 0.0,
                'pex2': 0.0,
                'pf': 0.0,
                'ppv': 0.0,
                'ppv1': 0.0,
                'ppv2': 0.0,
                'ppv3': 0.0,
                'ppv4': 0.0,
                'pself': 0.0,
                'psystem': 0.0,
                'realOPPercent': 0,
                'serialNum': None,
                'status': 0,
                'statusText': 'Standby',
                'sysFaultWord': 0,
                'sysFaultWord1': 0,
                'sysFaultWord2': 0,
                'sysFaultWord3': 0,
                'sysFaultWord4': 0,
                'sysFaultWord5': 0,
                'sysFaultWord6': 0,
                'sysFaultWord7': 0,
                'temp1': 0.0,
                'temp2': 0.0,
                'temp3': 0.0,
                'temp4': 0.0,
                'temp5': 0.0,

I would like to get the api.tlx_detail(tlx_id) but for historic dates. Is there any chance to get those values?

vonpupp commented 8 months ago

Hi @jbrinchmann,

If you still didn't solve this, I suggest you to use the "mix_detail" function. It will return a json object with the correct chart data with a 5 min interval. The function you want to you is this one:

mix_detail_json = api.mix_detail(device_sn, plant_id, growattServer.Timespan.hour, date)

the chart data is accessible with the key "chartData": mix_detail_json['chartData']

This doesn't seem to be working for me. Is anyone else having problems to access the mix_detail? I am unable to retrieve the historic data out of the API.

Could anyone point me into the right direction, please? Thanks.