Example #1
0
 def __init__(self,
              current_battery_percentage=100.0,
              battery_capacity=5.0,
              charging_rate=1.0):
     #super(Battery, self).__init__()
     self.current_battery_percentage = current_battery_percentage
     self.battery_capacity = battery_capacity
     self.charging_rate = charging_rate
     self.mean_battery = 50
     self.variance_battery = 0
     # self.min_mean_battery = 999999.9
     # self.max_mean_battery = -999999.9
     # self.min_variance_battery = 999999.9
     # self.max_variance_battery = -999999.9
     self.mean_battery_bounds = Bounds()
     self.variance_battery_bounds = Bounds(reset_count=300)
Example #2
0
    def __init__(self, centroids):
        self.centroids = centroids
        Centroid.centroids = centroids

        Bounds(centroids)

        Border.reset()  # starting over each frame
        Centroid.reset()  # starting over each frame

        l = len(Centroid.centroids)

        for n1 in range(1, len(Centroid.centroids)):
            print '%i/%i' % (n1, l)
            c1 = Centroid.centroids[n1]
            # dist-sort, & break when c1 in enclosed
            others = DistSort(c1, [Centroid.centroids[n2] for n2 in range(n1)])
            B = []
            for c2 in others:
                b = Border(c1, c2)
                for bb in B:
                    if bb.nIntersects < 2:
                        i = b.validate_BorderBorderIntersectPoint(bb)
                        if i and b.nIntersects == 2:
                            break
                B.append(b)
                if {bb.nIntersects for bb in B} == {2}:
                    break

        for c in Centroid.centroids:
            if not c.isClosed:
                c.addCornerVert()
Example #3
0
 def __init__(self, loads = None):
     if loads is None:
         loads = []
     self.loads = loads
     self.num_loads = 0
     self.current_demand = 0.0
     self.demands = []
     # self.min_demand = 999999.0
     # self.max_demand = 0.0
     self.demand_bounds = Bounds()
Example #4
0
    def __init__(self, sourceID = None, capacity = 10000.0, current_price = 0.0, with_agent = False, look_ahead = 1):

        super().__init__()

        if sourceID is None:
            sourceID = Source.num_sources

        self.sourceID = sourceID
        self.supply_capacity = capacity        # MW
        self.current_price = current_price
        self.prices = []
        self.with_agent = with_agent
        self.look_ahead = look_ahead
        self.price_bounds = Bounds()
        # self.min_price = 100000.0
        # self.future_max = 0.0
        # self.future_min = 999999.9
        # self.update_count = 0
        # self.max_price = 0.0
        self.dumb_load_range = DemandRange(0.0,0.0)
        Source.num_sources +=1
Example #5
0
    def __init__(self, demand_ranges = None, batteryParams = None, loadID = None, with_agent=False, look_ahead = 1):
        if loadID is None:
            loadID = Load.num_loads
        Load.num_loads += 1
        if demand_ranges is None:                       #Because http://docs.python-guide.org/en/latest/writing/gotchas/
            if self.RANDOMIZE_DEMANDS:
                demand_ranges = [[DemandRange.default_lower_bound,DemandRange.default_upper_bound]] * 288
            else:
                demand_ranges = []
                with open(self.csv_input_file, 'r') as csv_file:
                    reader = csv.reader(csv_file)
                    for line in reader:
                        try:
                            _demands = None
                            # ignore initial lines of csv file
                            if line[0].startswith("#") or len(line)<2:
                                next(reader)
                                continue
                        except IndexError:
                            _demands = [[float(val) for val in value] for value in reader]  # [0] is lower bounds, [1] is upper bounds
                            print(len(_demands), len(_demands[0]), len(_demands[1]))
                    if _demands is None or len(_demands) != 2 or len(_demands[0]) != 288 or len(_demands[1]) != 288:
                        raise AssertionError("Expected timestep size of 5 mins. Data doesn't match.")
                    for i in range(len(_demands[0])):
                        demand_ranges.append([_demands[0][i], _demands[1][i]])

        if batteryParams is None:
            batteryParams = {}

        self.demand_ranges = []
        for demand_range in demand_ranges:
            self.demand_ranges.append(DemandRange(float(demand_range[0]), float(demand_range[1])))

        self.battery = Battery(**batteryParams)
        self.demands = list()
        self.loadID = loadID
        self.with_agent = with_agent
        self.costs = list()
        self.look_ahead = look_ahead
        self.demand_bounds = Bounds()
Example #6
0
class Battery(object):
    """
    Member Variables
        CurrentBatteryPercentage - FLOAT value from 0 to 100
        Battery Capacity - Total energy it can store - FLOAT value in kWh
        Update Battery Percentage - takes current energy demand and suitably updates battery percentage
        Charging rate kW
    Member functions
        Getters and Setters and Constructor

    """
    HISTORY_FACTOR = .999  # as ln(.9)/ln(.01) ~= 44

    def __init__(self,
                 current_battery_percentage=100.0,
                 battery_capacity=5.0,
                 charging_rate=1.0):
        #super(Battery, self).__init__()
        self.current_battery_percentage = current_battery_percentage
        self.battery_capacity = battery_capacity
        self.charging_rate = charging_rate
        self.mean_battery = 50
        self.variance_battery = 0
        # self.min_mean_battery = 999999.9
        # self.max_mean_battery = -999999.9
        # self.min_variance_battery = 999999.9
        # self.max_variance_battery = -999999.9
        self.mean_battery_bounds = Bounds()
        self.variance_battery_bounds = Bounds(reset_count=300)

    def get_battery_bounds(self):
        return [
            self.mean_battery_bounds.get_bounds(),
            self.variance_battery_bounds.get_bounds()
        ]

    def update_battery_bounds(self, mean, var):
        # self.min_mean_battery = min(mean, self.min_mean_battery)
        # self.max_mean_battery = max(mean, self.max_mean_battery)
        # self.min_variance_battery = min(var, self.min_variance_battery)
        # self.max_variance_battery = max(var, self.max_variance_battery)
        self.mean_battery_bounds.update_bounds(mean)
        self.variance_battery_bounds.update_bounds(math.pow(var, 0.5))

    def get_current_battery_percentage(self):
        return self.current_battery_percentage

    def set_current_battery_percentage(self, current_battery_percentage):
        self.current_battery_percentage = min(
            100, max(0, current_battery_percentage))
        self.mean_battery += (1 - self.HISTORY_FACTOR) * (
            current_battery_percentage - self.mean_battery)
        self.variance_battery += (1 - self.HISTORY_FACTOR) * (
            (current_battery_percentage - self.mean_battery)**2 -
            self.variance_battery)
        self.update_battery_bounds(self.mean_battery, self.variance_battery)

    def update_battery_percentage(self, energy_demand):
        self.current_battery_percentage -= (
            (energy_demand / self.battery_capacity) * 100)

    def get_battery_capacity(self):
        return self.battery_capacity

    def get_charging_rate(self):
        return self.charging_rate

    def set_charging_rate(self, charging_rate):
        self.charging_rate = charging_rate

    def get_battery_reward_factor(self):
        return 0.5 / (1 + math.exp(
            (-self.current_battery_percentage + 40) / 10)) + 1

    def get_mean_battery(self):
        return self.mean_battery

    def get_variance_battery(self):
        return math.pow(self.variance_battery, 0.5)
Example #7
0
class Source(DemandManager):


    num_sources = 0
    action_space = [0,1,2,3,4]
    base_pricing_constant = 10.0
    action_price_map = {0:1.0, 1:0.7, 2:0.3, 3:1.5, 4: 2.5}
    no_agent_action = 0

    def __init__(self, sourceID = None, capacity = 10000.0, current_price = 0.0, with_agent = False, look_ahead = 1):

        super().__init__()

        if sourceID is None:
            sourceID = Source.num_sources

        self.sourceID = sourceID
        self.supply_capacity = capacity        # MW
        self.current_price = current_price
        self.prices = []
        self.with_agent = with_agent
        self.look_ahead = look_ahead
        self.price_bounds = Bounds()
        # self.min_price = 100000.0
        # self.future_max = 0.0
        # self.future_min = 999999.9
        # self.update_count = 0
        # self.max_price = 0.0
        self.dumb_load_range = DemandRange(0.0,0.0)
        Source.num_sources +=1

    def reset_day(self):
        super().reset_day(self.look_ahead)
        if len(self.prices)>0:
            self.current_price = self.prices[-1]

        self.prices = get_last_k(self.prices, self.look_ahead)

    def step(self, action=None):

        if action is None:
            action = Source.no_agent_action

        # if not self.with_agent:
        #     action = Source.no_agent_action

        if action not in Source.action_space:
            raise AssertionError("Not a valid action")

        self.prices.append(self.calculate_base_price() * 1.0 * Source.action_price_map.get(action))
        # print('priced %f times original price with action %d' % (Source.action_price_map[action], action))
        self.current_price = self.prices[-1]
        self.price_bounds.update_bounds(self.current_price)
        self.demand_bounds.update_bounds(self.current_demand)
        return self.get_previous_price() * super().get_current_demand()


    def calculate_base_price(self):

        if self.get_current_demand()< 0.9*self.supply_capacity:
            return Source.base_pricing_constant * super().get_previous_demand() / self.num_loads
        else:
            return 1 * Source.base_pricing_constant * super().get_previous_demand() / self.num_loads

    def set_look_ahead(self, look_ahead):
        self.look_ahead = look_ahead

    def get_look_ahead(self):
        return self.look_ahead

    def get_prices(self):
        return self.prices

    def get_current_price(self):
        return self.current_price

    def get_previous_price(self):
        if len(self.prices)<2:
            return 0.0
        else:
            return self.prices[-2]

    def is_with_agent(self):
        return self.with_agent

    def get_supply_capacity(self):
        return self.supply_capacity

    def add_load(self,loadID):
        flag = super().add_load(loadID)
        if flag:
            print('Load %d successfully linked to source %d' % (loadID, self.sourceID))
        else:
            print('Load %d already handled by source %d' % (loadID, self.sourceID))

    def remove_load(self, loadID):
        flag = super().remove_load(loadID)
        if flag:
            print('Load %d successfully removed from source %d' % (loadID, self.sourceID))
        else:
            print('Load %d is not handled by source %d' % (loadID, self.sourceID))

    def sample_action(self):
        return Source.action_space[randint(0,len(Source.action_space))]

    # def update_price_bounds(self,price):
    #     if not price <= 0:
    #         self.future_min = min(self.future_min, price)
    #     self.future_max = max(self.future_max, price)
    #     self.update_count+=1
    #     if self.update_count+1 % 1000 == 0:
    #         self.update_count = 0
    #         self.min_price = self.future_min
    #         self.max_price = self.future_max
    #         self.future_max = 0.0
    #         self.future_min = 99999.9
    #
    # def get_price_bounds(self):
    #     return [self.min_price, self.max_price]

    def add_dumb_load_range(self, lowerbound, upperbound):
        self.dumb_load_range.set_lower_bound(self.dumb_load_range.get_lower_bound()+lowerbound)
        self.dumb_load_range.set_upper_bound(self.dumb_load_range.get_upper_bound()+upperbound)

    def remove_dumb_load_range(self, lowerbound, upperbound):
        self.dumb_load_range.set_lower_bound(self.dumb_load_range.get_lower_bound()-lowerbound)
        self.dumb_load_range.set_upper_bound(self.dumb_load_range.get_upper_bound()-upperbound)

    def add_dumb_loads(self,n=None, ranges = None):
        if n is None:
            for demandrange in ranges:
                self.add_dumb_load_range(demandrange[0], demandrange[1])
            self.num_loads+=len(ranges)
            return

        if ranges is None:
            ranges = [[DemandRange.default_lower_bound, DemandRange.default_upper_bound]]

        numranges = len(ranges)
        for i in range(n):
            if i < numranges:
                self.add_dumb_load_range(ranges[i][0], ranges[i][1])
            else:
                self.add_dumb_load_range(ranges[-1][0], ranges[-1][1])
        self.num_loads += n
Example #8
0
 def addDigit(self, unit, lowerBound, upperBound):
     # assert type(unit) is FloatType, "unit is not a float" + str(unit)
     self.digits[unit] = Bounds(lowerBound, upperBound)
Example #9
0
class Load(object):
    """
    Member Variables
        Demand ranges throughout the day (Array of DemandRange objects)
        Battery Object
        DailyDemandCurve - stores demand generated so far during the day
        LoadID
        WithAgent - boolean indicating presence of agent
    Member Functions
        Getters and Setters and Constructor
        GenerateDemandAndUpdateCurve(action)
        ResetDay()
        CalculateReward()
        Daily demand analytics and visualization functions

    Time of day -
        value from 0 to 287 (5 min intervals for 24 hours)

    Actions
        0-SB,SC
        1-SC
        2-BC
    """
    # global num_loads
    num_loads = 0
    default_timestep_size = 5.0
    action_space = [0,1,2]
    no_agent_action = 1

    RANDOMIZE_DEMANDS = True
    csv_input_file = "household_demand_2.csv"
    THRESHOLD = 5


    def __init__(self, demand_ranges = None, batteryParams = None, loadID = None, with_agent=False, look_ahead = 1):
        if loadID is None:
            loadID = Load.num_loads
        Load.num_loads += 1
        if demand_ranges is None:                       #Because http://docs.python-guide.org/en/latest/writing/gotchas/
            if self.RANDOMIZE_DEMANDS:
                demand_ranges = [[DemandRange.default_lower_bound,DemandRange.default_upper_bound]] * 288
            else:
                demand_ranges = []
                with open(self.csv_input_file, 'r') as csv_file:
                    reader = csv.reader(csv_file)
                    for line in reader:
                        try:
                            _demands = None
                            # ignore initial lines of csv file
                            if line[0].startswith("#") or len(line)<2:
                                next(reader)
                                continue
                        except IndexError:
                            _demands = [[float(val) for val in value] for value in reader]  # [0] is lower bounds, [1] is upper bounds
                            print(len(_demands), len(_demands[0]), len(_demands[1]))
                    if _demands is None or len(_demands) != 2 or len(_demands[0]) != 288 or len(_demands[1]) != 288:
                        raise AssertionError("Expected timestep size of 5 mins. Data doesn't match.")
                    for i in range(len(_demands[0])):
                        demand_ranges.append([_demands[0][i], _demands[1][i]])

        if batteryParams is None:
            batteryParams = {}

        self.demand_ranges = []
        for demand_range in demand_ranges:
            self.demand_ranges.append(DemandRange(float(demand_range[0]), float(demand_range[1])))

        self.battery = Battery(**batteryParams)
        self.demands = list()
        self.loadID = loadID
        self.with_agent = with_agent
        self.costs = list()
        self.look_ahead = look_ahead
        self.demand_bounds = Bounds()
        # self.min_demand = 999999.0
        # self.max_demand = 0.0

        # for key in params:
        #     setattr(self,key,params[key])

    def step(self, timestep, timestep_size= default_timestep_size, action=None):
        """timestep_size is in minutes"""
        # if not self.with_agent:
        #     action = Load.no_agent_action

        if action is None:
            action = Load.no_agent_action

        if action not in Load.action_space:
            raise AssertionError("Not a valid action")

        timestep = normalize_timestep(timestep, timestep_size, Load.default_timestep_size)
        penalty_factor = 0

        if action == 0:
            #checks
            self.demands.append(self.demand_ranges[timestep].generate_demand())

            battery_percentage_increase = ((self.battery.get_charging_rate()*(timestep_size/60.0))/self.battery.get_battery_capacity()) * 100.0
            new_battery_percentage_increase = min(battery_percentage_increase, 100.0 - self.battery.get_current_battery_percentage())
            self.battery.set_current_battery_percentage(self.battery.get_current_battery_percentage()+new_battery_percentage_increase)
            self.demand_bounds.update_bounds(self.demands[-1])
            penalty_factor = 5*(battery_percentage_increase-new_battery_percentage_increase)/battery_percentage_increase
            # if self.battery.current_battery_percentage >100.0- self.THRESHOLD:
            #     penalty_factor = 5 * (self.THRESHOLD + self.battery.current_battery_percentage - 100.0) / self.THRESHOLD

            return [self.demands[-1], (self.battery.get_battery_capacity() * new_battery_percentage_increase/100)*60 / timestep_size, penalty_factor]
        elif action == 1:
            #checks
            self.demands.append(self.demand_ranges[timestep].generate_demand())
            self.demand_bounds.update_bounds(self.demands[-1])
            return [self.demands[-1], 0, penalty_factor]

        elif action == 2:
            #checks
            self.demands.append(self.demand_ranges[timestep].generate_demand())
            battery_percentage_decrease = ((self.demands[-1]*(timestep_size/60.0))/self.battery.get_battery_capacity()) * 100.0
            new_battery_percentage_decrease = min(battery_percentage_decrease, self.battery.get_current_battery_percentage())
            self.battery.set_current_battery_percentage(self.battery.get_current_battery_percentage() - new_battery_percentage_decrease)
            # controllable = battery_percentage_decrease* self.battery.get_battery_capacity()*60/ (timestep_size*100)
            uncontrollable = - new_battery_percentage_decrease* self.battery.get_battery_capacity()*60/ (timestep_size*100)
            # self.demands.append((battery_percentage_decrease - new_battery_percentage_decrease) * self.battery.get_battery_capacity()*60/ (timestep_size*100))
            self.demand_bounds.update_bounds(self.demands[-1])
            penalty_factor = 5*(battery_percentage_decrease-new_battery_percentage_decrease)/battery_percentage_decrease
            # if self.battery.current_battery_percentage < self.THRESHOLD:
            #     penalty_factor = 5 * (self.THRESHOLD - self.battery.current_battery_percentage) / self.THRESHOLD

            return [self.demands[-1], uncontrollable,penalty_factor] # *2 is penalty for discharging battery to 0%
        else:
            raise AssertionError("I don't know why this is happening")

    # def update_demand_bounds(self, demand):
    #     if not demand <= 0:
    #         self.min_demand = min(self.min_demand, demand)
    #     self.max_demand = max(self.max_demand, demand)
    #
    # def get_demand_bounds(self):
    #     return [self.min_demand, self.max_demand]

    def get_demand_ranges(self):
        return self.demand_ranges

    def get_battery(self):
        return self.battery

    def get_demands(self):
        return self.demands

    def get_loadID(self):
        return self.loadID

    def is_with_agent(self):
        return self.with_agent

    def get_costs(self):
        return self.get_costs

    def set_demand_ranges(self, demand_ranges):
        self.demand_ranges = demand_ranges

    def set_battery(self, battery):
        self.battery = battery

    def set_loadID(self, loadID):
        self.loadID = loadID

    def set_demands(self, demands):
        self.demands = demands

    def set_with_agent(self, with_agent):
        self.with_agent = with_agent

    def set_costs(self, costs):
        self.costs = costs

    def reset_day(self, battery_reset = False):
        self.demands = get_last_k(self.demands, self.look_ahead)
        self.costs = get_last_k(self.costs, self.look_ahead)
        if battery_reset is True:
            self.battery.set_current_battery_percentage(100*random())
        elif isinstance(battery_reset,int) or isinstance(battery_reset, float):
            self.battery.set_current_battery_percentage(battery_reset)

    def set_look_ahead(self, look_ahead):
        self.look_ahead = look_ahead

    def get_look_ahead(self):
        return self.look_ahead

    def sample_action(self):
        return Load.action_space[randint(0,len(Load.action_space))]