#!/usr/bin/env python3 # by Luis Gonzalez https://domotica.solar import re import datetime import time def influx(measurements): try: influx_client.write_points(measurements) except Exception as e: print('Failed to write to influxdb: ', e) def charge_battery(battery, power_line, upto,from_net): #upto battery percentage upper limit, #from_net charge from net if(battery['max']==0): if(power_line<0): battery['net_usage'] = 0 battery['net_delivery'] = -power_line else: battery['net_usage'] = power_line battery['net_delivery'] = 0 battery['level']=0 battery['charge_power']=0 battery['discharge_power']=0 battery['net'] = power_line else: if(from_net==1): max_watt_avail=battery['max_distributor_power']-power_line elif(power_line<0): max_watt_avail=-1*power_line else: max_watt_avail=0 if(battery['max_charge_power'] (battery['max']*upto/100)): #not enough space on battery, delivering to net battery['charge_power'] = 0 if(power_line<0): battery['net_usage'] = 0 battery['net_delivery'] = power_line else: battery['net_usage'] = power_line battery['net_delivery'] = 0 battery['net'] = power_line battery['charge_power']=0 else: #enough space on battery, charging battery battery['level'] = battery['level'] + new_power_line / battery['power_sample_rate'] battery['charge_power'] = new_power_line if(power_line+new_power_line<0): # too much panel energy battery['net_usage'] = 0 battery['net_delivery'] = (power_line+new_power_line)*-1 battery['net'] = power_line+new_power_line else: battery['net_usage'] = power_line+new_power_line battery['net_delivery'] = 0 battery['net'] = power_line+new_power_line battery['discharge_power']=0 def discharge_battery(battery, power_line, upto): exc_power_line=0 if(battery['max_discharge_power'] 0: discharge_battery(battery, power_line, 0) else: #reverse power_line charge_battery(battery, power_line, 100,0) elif (mode==1): charge_battery(battery, power_line, upto,1) elif (mode==2): # discharge mode if power_line > 0: discharge_battery(battery, power_line, upto) else: #reverse power_line charge_battery(battery, power_line, 100,0) if (battery['max']==0): battery['level_percentage']=0 else: battery['level_percentage']=battery['level']/battery['max']*100 return battery def general(battery,influx_client,periods,starttime,endtime,cache_size): measurements = [] #delete serie if exists result = influx_client.query('delete from "battery' + battery['label'] + '"') query = "select * from " + battery['influx_meassurement'] + " where time >= '" + format(starttime) + "' and time < '" + format(endtime) + "' order by time;"; print(query) result = influx_client.query(query) points = result.get_points() points2 = result.get_points() #aux function calculate percentage done points_size=len(list(points2)) #obtain info from solar power if "label_solar_power" in battery: query = "select * from " + battery['label_solar_power'] + " where time >= '" + format(starttime) + "' and time < '" + format(endtime) + "' order by time;"; print(query) result_solar = influx_client.query(query) points_solar = result_solar.get_points() iteracion_puntos_solar = iter(points_solar); #obtain diferents labels from periods j=0 different_periods=[] while j=periods[j]['start'] and fecha.hour=periods[j]['start'] or fecha.hour0: #insert new value fields['solar_power']=aux['value']*battery["solar_power_multiplier"] #calculate new powerline difference_power=fields['solar_power']-aux['value'] point['value']=point['value']-difference_power battery_management(battery,point['value'],periods[period_int]['mode'],periods[period_int]['limit']) # knowing the period fill the data #first fill for x in different_periods: fields["net_usage_" + x]=float(0) fields["net_delivery_" + x]=float(0) fields['net_usage_' + period]=float(battery['net_usage']) fields['net_delivery_' + period]=float(battery['net_delivery']) fields["net_usage"]=float(battery['net_usage']) fields["net_delivery"]=float(battery['net_delivery']) fields["level_percentage"]=float(battery['level_percentage']) battery['net']=battery['net_usage']-battery['net_delivery'] fields["net"]=float(battery['net']) fields["tramo"]=period fields['charge_power']=float(battery['charge_power']) fields['discharge_power']=float(battery['discharge_power']) i+=1 battery['net']=battery['net_usage']-battery['net_delivery'] if i==cache_size: print("Punto=>" + format(point['time']) + " " + format(point['value']) + "W Period=" + format(period) + " Percentage=" + '{:04.1f}%'.format(jobdone)) i=0 measurements.append({ "measurement": "battery" + battery['label'], "time": point['time'], "fields": fields, }) if len(measurements) > cache_size: influx_client.write_points(measurements) print(".") measurements = [] influx_client.write_points(measurements)