Пример #1
0
def get_settings_batteries(batterylist, interval, mysql=False):
    dt = parser.parse(gridlabd.get_global('clock'))  #Better: getstart time!
    #prev_timedate = dt - timedelta(minutes=interval/60)
    #Prepare dataframe to save settings and current state
    cols_battery = [
        'battery_name', 'house_name', 'SOC_min', 'SOC_max', 'i_max', 'u_max',
        'efficiency', 'SOC_t', 'active_t-1', 'active_t', 'threshold_sell',
        'threshold_buy'
    ]
    df_battery = pandas.DataFrame(columns=cols_battery)
    for battery in batterylist:
        battery_obj = gridlabd.get_object(battery)
        house_name = 'GLD_' + battery[8:]
        #Fills TABLE market_appliances
        SOC_min = float(battery_obj['reserve_state_of_charge'])  #in %
        SOC_max = float(
            battery_obj['battery_capacity']) / 1000  #Wh in Gridlabd -> kWh
        str_i_max = battery_obj['I_Max'].replace('-', '+')
        i_max = str_i_max.split('+')[1]
        u_max = float(battery_obj['V_Max']) * float(
            i_max) / 1000  #W -> kW #better inverter?
        eff = float(battery_obj['base_efficiency'])
        #Fills TABLE market_appliance_meter
        SOC_0 = float(battery_obj['state_of_charge']) * SOC_max
        df_battery = df_battery.append(pandas.Series([
            battery, house_name, SOC_min, SOC_max, i_max, u_max, eff, SOC_0, 0,
            0, 0.0, 0.0
        ],
                                                     index=cols_battery),
                                       ignore_index=True)
    df_battery.set_index('battery_name', inplace=True)
    return df_battery
Пример #2
0
def get_settings_EVs_rnd(EVlist, interval, mysql=False):
    cols_EV = [
        'EV_name', 'house_name', 'SOC_max', 'i_max', 'v_max', 'u_max',
        'efficiency', 'charging_type', 'k', 'soc_t', 'SOC_t', 'connected',
        'next_event', 'active_t-1', 'active_t'
    ]
    df_EV = pandas.DataFrame(columns=cols_EV)
    start_time = dt_sim_time = parser.parse(
        gridlabd.get_global('clock')).replace(tzinfo=None)
    for EV in EVlist:
        house_name = 'GLD_' + EV[3:]
        EV_obj = gridlabd.get_object(EV)
        #Determine some values
        v_max = float(EV_obj['V_Max'])  #keep v_max constant for now
        SOC_max = np.random.choice(list_SOC)  #in kWh
        gridlabd.set_value(EV, 'battery_capacity', str(SOC_max * 1000))
        u_max = np.random.choice(list_u)  #in kW
        i_max = 1000 * u_max / v_max
        gridlabd.set_value(EV, 'I_Max', str(i_max))
        eff = float(EV_obj['base_efficiency'])
        charging_type = EV_obj['charging_type']
        k = float(EV_obj['k'])  #no market: always highest wllingsness to pay
        #Randomly generate SOC at midnight
        soc_t = np.random.uniform(0.2, 0.8)  #relative soc
        soc_t = soc_t + (
            1. - soc_t
        ) / 2.  #No EV connected yet - at midnight, initialize with 50% charged already
        gridlabd.set_value(EV, 'state_of_charge', str(soc_t))
        SOC_t = soc_t * SOC_max
        connected = 1

        #Set EV
        gridlabd.set_value(EV, 'generator_status', 'ONLINE')
        #gridlabd.set_value(EV,'state_of_charge',str(next_soc))
        #gridlabd.set_value(EV,'battery_capacity',str(next_socmax*1000))
        #i_max = 1000*next_u/df_EV_state['v_max'].loc[EV]
        #gridlabd.set_value(EV,'I_Max',str(i_max))
        gridlabd.set_value(EV, 'P_Max', str(u_max * 1000))
        gridlabd.set_value(EV, 'E_Max', str(u_max * 1000 * 1))
        EV_inv = 'EV_inverter' + EV[2:]
        #import pdb; pdb.set_trace()
        gridlabd.set_value(EV_inv, 'rated_power', str(1.2 * u_max * 1000))
        gridlabd.set_value(EV_inv, 'rated_battery_power',
                           str(1.2 * u_max * 1000))
        #import pdb; pdb.set_trace()

        next_event = start_time + pandas.Timedelta(
            hours=np.random.choice(dep_hours),
            minutes=np.random.choice(range(60)))  #Next event: disconnection
        #Save
        df_EV = df_EV.append(pandas.Series([
            EV, house_name, SOC_max, i_max, v_max, u_max, eff, charging_type,
            k, soc_t, SOC_t, connected, next_event, 0, 0
        ],
                                           index=cols_EV),
                             ignore_index=True)
    df_EV.set_index('EV_name', inplace=True)
    #Maybe drop all columns which are not used in this glm
    #import pdb; pdb.set_trace()
    return df_EV
Пример #3
0
def get_settings_houses(houselist,interval,mysql=False):
	dt = parser.parse(gridlabd.get_global('clock')) #Better: getstart time!
	prev_timedate = dt - timedelta(minutes=interval/60)
	#Prepare dataframe to save settings and current state
	cols_market_hvac = ['house_name','appliance_name','k','T_min','T_max','P_heat','P_cool','heating_setpoint','cooling_setpoint','air_temperature','active']
	df_market_hvac = pandas.DataFrame(columns=cols_market_hvac)
	#cols_market_hvac_meter = ['system_mode','av_power','active','timedate','appliance_id']
	#df_market_hvac_meter = pandas.DataFrame(columns=cols_market_hvac_meter)
	#Iterate through all houses and collect characteristics relevant for bidding
	for house in houselist:            
		#Table with all relevant settings
		house_obj = gridlabd.get_object(house)
		k = float(house_obj['k'])
		T_min = float(house_obj['T_min'])
		T_max = float(house_obj['T_max'])
		heat_q = float(house_obj['heating_demand']) #heating_demand is in kW
		hvac_q = float(house_obj['cooling_demand']) #cooling_demand is in kW
		heating_setpoint = float(house_obj['heating_setpoint'])
		cooling_setpoint = float(house_obj['cooling_setpoint'])
		T_air = float(house_obj['air_temperature'])
		df_market_hvac = df_market_hvac.append(pandas.Series([house,'HVAC_'+house[4:],k,T_min,T_max,heat_q,hvac_q,heating_setpoint,cooling_setpoint,T_air,0],index=cols_market_hvac),ignore_index=True)          
		#DB structure according to AWS structure
		
		#if mysql:
		#	mysql_functions.set_values('market_houses', '(house_name)',(house,))
		#	mysql_functions.set_values('market_HVAC', '(house_name,appliance_name,k,T_min,T_max,P_heat,P_cool)',(house,'HVAC_'+house[4:],k,T_min,T_max,heat_q,hvac_q,))
		#	mysql_functions.set_values('market_HVAC_meter', '(system_mode,av_power,heating_setpoint,cooling_setpoint,active,timedate,appliance_id)',('OFF',0.0,heating_setpoint,cooling_setpoint,0,prev_timedate,int(house.split('_')[-1]),))           
	
	#df_market_hvac.to_sql('market_HVAC',mycursor,if_exists='append') #, flavor='mysql')
	#Index = house_number
	df_market_hvac.index = df_market_hvac.index + 1
	return df_market_hvac
Пример #4
0
def on_sync(t):
    """GridLAB-D synchronization event handler

    Parameter:
        t (int): target timestamp

    Return:
        int: timestamp of next desired sync event call
    """
    global property_list
    global limit_list

    # get the current timestamp in human readable form
    dt = datetime.datetime.fromtimestamp(t)
    gridlabd.debug(f"*** onsync({dt}) ***")

    # determine whether a violation has occurred
    violation_active = int(gridlabd.get_global("powerflow::violation_active"))
    if violation_active:
        gridlabd.debug(f"{dt}: violation detected (violation_active={violation_active})")

    # start by assuming there's nothing left to do with the property being considered
    done = None

    # if there's still a property to consider
    if property_list:

        # get the object name of the property to consider (the first one in the list of keys
        objname = list(property_list.keys())[0]
        gridlabd.debug(f"{dt}: updating {objname}")
        if objname not in limit_list:
            limit_list[objname] = {}

        # get the properties being considered for this object
        proplist = property_list[objname]

        # if the property list is non-empty
        if proplist:

            # for each property in the object's property list
            for propname, specs in proplist.items():
                if propname not in limit_list[objname]:
                    limit_list[objname][propname] = {}

                # get the property name and the property's original value
                prop = specs[0]
                base = specs[1]
                limit = specs[2]

                # if the original value is zero
                if base.real == 0.0:

                    # consider property by fixed increment specified by delta and reactive_ratio
                    value = prop.get_value() - complex(delta,delta*reactive_ratio)

                # original value is non-zero
                else:

                    # consider property by relative increments specified by delta
                    value = prop.get_value() - base/base.real*delta

                # if a violation has occurred
                if violation_active:
                    gridlabd.debug(f"{dt}: resetting {objname}.{propname} to base {base}")

                    # reset the property to its original value
                    prop.set_value(base)

                    # record the load limit
                    if not objname in limit_list.keys() or not propname in limit_list[objname].keys():
                        load_limit = base - value
                        limit_list[objname][propname] = {
                            "timestamp" : str(datetime.datetime.fromtimestamp(t)), 
                            "real" : load_limit.real, 
                            "reactive" : load_limit.imag}
                    limit_list[objname][propname]["violation"] = gridlabd.get_value(objname,"violation_detected")

                    # flag that processing is done
                    done = objname

                # if the maximum solar limit is reached
                elif power_limit and value.real < power_limit and limit == "POWER":
                    gridlabd.debug(f"{dt}: power limit reach for {objname}.{propname} = {value}")

                    # reset the property to its original value
                    prop.set_value(base)

                    # record the load limit
                    if not objname in limit_list.keys() or not propname in limit_list[objname].keys():
                        load_limit = base - value
                        limit_list[objname][propname] = {
                            "timestamp" : str(datetime.datetime.fromtimestamp(t)), 
                            "real" : load_limit.real, 
                            "reactive" : load_limit.imag}
                    limit_list[objname][propname]["violation"] = "POWERLIMIT"

                    # flag that processing is done
                    done = objname

                # if the maximum solar limit is reached
                elif voltage_limit and base.real != 0.0 and abs((value.real-base.real)/base.real) > voltage_limit and limit == "VOLTAGE":
                    gridlabd.debug(f"{dt}: power deviation limit reach for {objname}.{propname} = {value}")

                    # reset the property to its original value
                    prop.set_value(base)

                    # record the load limit
                    if not objname in limit_list.keys() or not propname in limit_list[objname].keys():
                        load_limit = base - value
                        limit_list[objname][propname] = {
                            "timestamp" : str(datetime.datetime.fromtimestamp(t)), 
                            "real" : load_limit.real, 
                            "reactive" : load_limit.imag}
                    limit_list[objname][propname]["violation"] = "VOLTAGELIMIT"

                    # flag that processing is done
                    done = objname


                # if no violation has occurred
                else:
                    gridlabd.debug(f"{dt}: updating {objname}.{propname} = {value}")

                    # set the new value of the property
                    prop.set_value(value)

                    # compute the load limit implied by this value
                    load_limit = base - value

                    # record the load limit
                    limit_list[objname][propname] = {
                        "timestamp":str(datetime.datetime.fromtimestamp(t)), 
                        "real":load_limit.real, 
                        "reactive":load_limit.imag,
                        "violation" : "NONE"
                        }

        # the property list is empty
        else:

            # flag that processing is done
            done = objname


        # if done
        if done:
            gridlabd.debug(f"{dt}: finished with {objname}")

            # if property list is empty
            if proplist == {}:

                # remove the object from the list of properties to consider
                del property_list[objname]

            # the property list is not empty
            else:

                # clear the property list (this will allow an extra solver iteration to clear the violation)
                property_list[objname] = {}

            # if the property list is non-empty
            if property_list:
                gridlabd.debug(f"{dt}: next is {list(property_list.keys())[0]}")

        # if a violation occurred
        if violation_active:

            # clear the violation
            gridlabd.debug(f"{dt}: clearing violation")
            gridlabd.set_global("powerflow::violation_active","0")

        # wait 1 minute for controls to settle before trying the next value
        tt = t+60
        gridlabd.debug(f"updating to {datetime.datetime.fromtimestamp(tt)}")
        return tt

    # no objects or properties left to consider
    else:

        # nothing left to do
        gridlabd.debug(f"updating to NEVER")
        return gridlabd.NEVER
Пример #5
0
def on_init(t):
    """GridLAB-D initialization event handler

    Parameter:
        t (int): initial timestamp

    Return:
        bool: success (True) or failure (False)
    """
    global output_folder
    global object_list
    global target_properties

    # get the output folder name from the global variable list
    output_folder = gridlabd.get_global("OUTPUT")

    # if none is defined
    if not output_folder:

        # use the current working direction
        output_folder = "."

    # if objects to consider are not specified
    if not object_list:

        # use list of all objects
        object_list = gridlabd.get("objects")

    # for each object in the object list
    for objname in object_list:

        # the object's class
        classname = gridlabd.get_value(objname,"class")

        # if the class is listed among the targets
        for classname, target_list in target_properties.items():

            # get the object's data
            objdata = gridlabd.get_object(objname)

            # if the object has phase data
            if "phases" in objdata.keys():

                # get the object's class structure
                classdata = gridlabd.get_class(classname)

                # for each property in the class's target property list
                for property_name, limittype in target_list.items():

                    # get the property pattern to use, and replace phase information pattern, if any
                    pattern = property_name.replace("{phases}",f"[{objdata['phases']}]")

                    # for each property in the class
                    for propname in classdata.keys():

                        # if the property matches the pattern
                        if re.match(pattern,propname):

                            # add the property to the list of properties to consider
                            add_property(objname,propname,limittype,nonzero=False)

    # successfully initialized
    return True
Пример #6
0
# construct the command line (gridlabd hasn't started yet)
gridlabd.command('example.glm')

# start gridlabd and wait for it to complete
gridlabd.start('wait')

# send the final model state to a file
gridlabd.save('done.json')

#
# Part 2 - plot the results
#

# gather the results collected by on_term
t = np.array(gridlabd.result["t"])
t = t - t[0]
x = np.array(gridlabd.result["x"])

# plot the result
plt.figure()
plt.plot(t / 3600.0, x, label=gridlabd.graph_label)
plt.xlabel(gridlabd.graph_xlabel)
plt.ylabel(gridlabd.graph_ylabel)
plt.grid()
plt.legend()
modelname = gridlabd.get_global("modelname")
title_name = gridlabd.graph_title
plt.title(title_name)
plt.savefig(modelname.replace(".glm", ".png"))
Пример #7
0
def compute_bill(gridlabd, **kwargs):

    global csvwriter
    verbose = gridlabd.get_global("verbose") == "TRUE"
    global csvfile

    # get data
    classname = kwargs['classname']
    id = kwargs['id']
    data = kwargs['data']
    bill_name = f"{classname}:{id}"
    bill = gridlabd.get_object(bill_name)
    bill_name = bill["name"]
    baseline = to_float(bill["baseline_demand"])
    tariff = gridlabd.get_object(bill["tariff"])
    meter = gridlabd.get_object(bill["meter"])
    energy = to_float(meter["measured_real_energy"]) / 1000  # units in kW

    # get duration
    clock = to_datetime(gridlabd.get_global('clock'), '%Y-%m-%d %H:%M:%S %Z')

    if not "lastreading" in data.keys():
        duration = timedelta(0)
    else:
        duration = clock - data["lastreading"]
    data["lastreading"] = clock
    billing_days = (duration.total_seconds() / 86400)  # seconds in a day

    # compute energy usage
    if not "lastenergy" in data.keys():
        usage = 0.0
    else:
        usage = energy - data["lastenergy"]
    data["lastenergy"] = energy

    # calculate bill
    tariff_name = tariff["name"]
    meter_name = meter["name"]
    if verbose:
        gridlabd.output(
            f"Bill '{bill_name}' for meter '{meter_name}' on tariff '{tariff_name}' at time '{clock}':"
        )
        gridlabd.output(f"  Billing days..... %5.0f    days" % (billing_days))
        gridlabd.output(f"  Meter reading.... %7.1f  kWh" % (energy))
    if baseline == 0.0:
        if verbose:
            gridlabd.output(f"  Energy usage..... %7.1f  kWh" % (usage))
        charges = usage * to_float(tariff["energy_charge_base"])
    else:
        tier1 = min(usage, baseline * billing_days)
        tier2 = min(usage - tier1, baseline * billing_days * 4)
        tier3 = usage - tier1 - tier2
        if verbose:
            gridlabd.output(f"  Tier 1 usage..... %7.1f  kWh" % (tier1))
            if tier2 > 0:
                gridlabd.output(f"  Tier 2 usage..... %7.1f  kWh" % (tier2))
            if tier3 > 0:
                gridlabd.output(f"  Tier 3 usage..... %7.1f  kWh" % (tier3))
        charges = tier1 * to_float(
            tariff["energy_charge_base"]) + tier2 * to_float(
                tariff["energy_charge_100"]) + tier3 * to_float(
                    tariff["energy_charge_400"])

    # apply discount, if any
    discount = to_float(tariff["discount"])
    if discount > 0:
        charges -= usage * discount

    # apply daily minimum
    minimum = to_float(tariff["minimum_daily_charge"])
    if charges < minimum * billing_days:
        charges = minimum * billing_days
    if verbose:
        gridlabd.output(f"  Energy charges... %8.2f US$" % (charges))

    # output billing record only if charges are non-zero
    if charges > 0:
        csvwriter.writerow([
            clock.strftime('%Y-%m-%d'), meter_name, tariff_name,
            int(billing_days),
            round(usage, 1), 0,
            round(charges, 2)
        ])
        csvfile.flush()

    # update billing data
    gridlabd.set_value(bill_name, "total_bill",
                       str(to_float(bill["total_bill"]) + charges))
    gridlabd.set_value(bill_name, "billing_days", str(billing_days))
    gridlabd.set_value(bill_name, "energy_charges",
                       str(to_float(bill["energy_charges"]) + charges))
    gridlabd.set_value(bill_name, "total_charges",
                       str(to_float(bill["total_charges"]) + charges))