Exemple #1
0
        def receptacles(self):
            '''
            Simulation of the receptacle loads.
            '''

            dataset = ast.literal_eval(
                open(os.path.abspath('Data\\Appliances.py')).read())
            # define number of minutes
            nmin = self.nday * 1440
            # determine all transitions of the appliances depending on the appliance
            # basic properties, ie. stochastic versus cycling power profile
            power = np.zeros(nmin + 1)
            radi = np.zeros(nmin + 1)
            conv = np.zeros(nmin + 1)
            nday = self.nday
            dow = self.dow
            result_n = dict()
            counter = range(len(self.clusters))
            for app in self.apps:
                # create the equipment object with data from dataset.py
                eq = Equipment(**dataset[app])
                r_app = dict()
                n_app = 0
                # loop for all household mmembers
                for i in counter:
                    r_appi, n_appi = eq.simulate(nday, dow, self.clusters[i],
                                                 self.occ[i])
                    r_app = stats.sum_dict(r_app, r_appi)
                    n_app += n_appi
                # and sum
                result_n.update({app: n_app})
                power += r_app['P']
                radi += r_app['QRad']
                conv += r_app['QCon']
            # a new time axis for power output is to be created as a different
            # time step is used in comparison to occupancy
            time = 4 * 60 * 600 + np.arange(0, (nmin + 1) * 60, 60)

            react = np.zeros(nmin + 1)

            result = {
                'time': time,
                'occ': None,
                'P': power,
                'Q': react,
                'QRad': radi,
                'QCon': conv,
                'Wknds': None,
                'mDHW': None
            }

            self.r_receptacles = result
            self.n_receptacles = result_n

            # output ##########################################################
            # only the power load is returned
            load = int(np.sum(result['P']) / 60 / 1000)
            print ' - Receptacle load is %s kWh' % str(load)

            return None
Exemple #2
0
        def receptacles(self):
            '''
            Simulation of the receptacle loads.
            '''

            dataset = ast.literal_eval(open('Appliances.py').read())
            # define number of minutes
            nmin = self.nday * 1440
            # determine all transitions of the appliances depending on the appliance
            # basic properties, ie. stochastic versus cycling power profile
            power = np.zeros(nmin+1)
            radi = np.zeros(nmin+1)
            conv = np.zeros(nmin+1)
            nday = self.nday
            dow = self.dow
            result_n = dict()
            counter = range(len(self.clusters))
            for app in self.apps:
                # create the equipment object with data from dataset.py
                eq = Equipment(**dataset[app])
                r_app = dict()
                n_app = 0
                # loop for all household mmembers
                for i in counter:
                    r_appi, n_appi = eq.simulate(nday, dow, self.clusters[i], self.occ[i])
                    r_app = stats.sum_dict(r_app, r_appi)
                    n_app += n_appi
                # and sum
                result_n.update({app:n_app})
                power += r_app['P']
                radi += r_app['QRad']
                conv += r_app['QCon']
            # a new time axis for power output is to be created as a different
            # time step is used in comparison to occupancy
            time = 4*60*600 + np.arange(0, (nmin+1)*60, 60)
    
            react = np.zeros(nmin+1)

            result = {'time':time, 'occ':None, 'P':power, 'Q':react,
                      'QRad':radi, 'QCon':conv, 'Wknds':None, 'mDHW':None}

            self.r_receptacles = result
            self.n_receptacles = result_n

            # output ##########################################################
            # only the power load is returned
            load = int(np.sum(result['P'])/60/1000)
            print ' - Receptacle load is %s kWh' % str(load)

            return None
        def receptacles(self):
            '''
            Simulation of the receptacle loads.
            '''

            # define number of minutes
            nmin = self.nday * 1440
            # determine all transitions of the appliances depending on the appliance
            # basic properties, ie. stochastic versus cycling power profile
            power = np.zeros(nmin + 1)
            radi = np.zeros(nmin + 1)
            conv = np.zeros(nmin + 1)
            nday = self.nday
            dow = self.dow
            result_n = dict()
            counter = range(len(self.clusters))
            for app in self.apps:
                # create the equipment object with data from dataset.py
                eq = Equipment(**set_appliances[app])
                r_app = dict()
                n_app = 0
                # loop for all household members
                for i in counter:
                    # if appliances are not shared the load of using the appliance can be summed for each householdmember
                    if app in (
                            'CordlessPhone', 'PC'
                    ):  # it is assumed that only the cordlessphone and PC are not shared. Each person in the household (>12) has its own phone or PC.
                        r_appi, n_appi = eq.simulate(nday, dow,
                                                     self.clusters[i],
                                                     self.occ[i])
                        r_app = stats.sum_dict(r_app, r_appi)
                        n_app += n_appi
                    else:
                        # if appliances are shared the load of using the appliance can be maximal the cycle load.
                        # if the appliance is an appliance that is working continously the load is simulated for only 1 person
                        if app in ('FridgeFreezer', 'Refrigerator',
                                   'ChestFreezer', 'UprightFreezer', 'Clock'):
                            if i == 0:
                                r_appi, n_appi = eq.simulate(
                                    nday, dow, self.clusters[i], self.occ[i])
                                r_app = stats.sum_dict(r_app, r_appi)
                                n_app += n_appi
                        # if the appliance is not continously used, but sometimes shared, the cycle load is assigned when minimal one person is using it, when nobody is using it the stanby load is assigned
                        else:
                            r_appi, n_appi = eq.simulate(
                                nday, dow, self.clusters[i], self.occ[i])
                            r_app = stats.sum_dict2(r_app, r_appi)
                            n_app += n_appi
                # and sum
                result_n.update({app: n_app})
                power += r_app['P']
                radi += r_app['QRad']
                conv += r_app['QCon']
            # a new time axis for power output is to be created as a different
            # time step is used in comparison to occupancy
            time = 4 * 60 * 60 + np.arange(0, (nmin + 1) * 60, 60)

            react = np.zeros(nmin + 1)

            result = {
                'time': time,
                'occ': None,
                'P': power,
                'Q': react,
                'QRad': radi,
                'QCon': conv,
                'Wknds': None,
                'mDHW': None
            }

            self.r_receptacles = result
            self.n_receptacles = result_n

            # output ##########################################################
            # only the power load is returned
            load = int(np.sum(result['P']) / 60 / 1000)
            print(' - Receptacle load is %s kWh' % str(load))

            return None
Exemple #4
0
    def simulate(self, nday, dow, clustersList, occ):
        def stochastic_flow(self, nday, dow, clusterList, occ):
            '''
            Simulate hot water tappings based on occupancy and the 
            Markov state-space model of Richardson et al.
            Tapping characteristics are taken from Jordan & Vajen (2001). 
            "Realistic Domestic Hot-water Profiles in Different Time Scales"
            '''
            # parameters ######################################################
            # First we check the required activity and load the respective
            # stats.DTMC file with its data for the "main" occupant, since the merged occupancy is used.
            clusterDict = clusterList[
                0]  # take Dictionary in first element of list (i.e. "main" occupant)
            len_cycle = self.cycle_length
            act = self.activity
            if self.activity not in (
                    'None', 'Presence'
            ):  # get activity probabilities from stats.DTMC file
                actdata = stats.DTMC(clusterDict=clusterDict)
            else:
                actdata = None

            # script ##########################################################
            # a yearly simulation is basic, also in a unittest
            nbin = 144  # steps in occupancy data per day (10min steps)
            nmin = nday * 24 * 60  # number of minutes in total number of days
            to = -1  # time counter for occupancy
            tl = -1  # time counter for flow
            left = -1  # time counter for tapping duration
            n_fl = 0
            flow = np.zeros(nmin + 1)
            for doy, step in itertools.product(range(nday), range(nbin)):
                dow_i = dow[doy]
                to += 1
                for run in range(0, 10):
                    tl += 1
                    # check if this tap is already open
                    if left <= 0:
                        # determine possibilities
                        if self.activity == 'None':
                            prob = 1
                        elif self.activity == 'Presence':
                            prob = 1 if occ[to] == 1 else 0
                        else:
                            occs = 1 if occ[to] == 1 else 0
                            prob = occs * actdata.get_var(dow_i, act, step)
                        # check if there is a statechange in the tap
                        if random.random() < prob * self.cal:
                            n_fl += 1
                            left = random.gauss(len_cycle, len_cycle / 10)
                        flow[tl] += self.standby_flow
                    else:
                        left += -1
                        flow[tl] += self.cycle_flow

            r_fl = {'mDHW': flow}

            return r_fl, n_fl

        def stochastic_load(self, nday, dow, clustersList, occ):
            '''
            Simulate non-cycling appliances based on occupancy and the 
            Markov state-space model of Richardson et al.
            '''
            # parameters ######################################################

            len_cycle = self.cycle_length  # cycle length for this appliance
            act = self.activity  # activity linked to the use of this appliance
            numOcc = len(
                clustersList)  # number of differenc active occupants >12y

            # script ##########################################################
            # a yearly simulation is basic, also in a unittest
            nbin = 144  # steps in occupancy data per day (10min steps)
            nmin = nday * 24 * 60  # number of minutes in total number of days
            n_eq_dur = 0  # number of minutes that the appliance is used
            P = np.zeros(nmin + 1)
            Q = np.zeros(nmin + 1)

            # prefill probabilities for each occupant to perform the activity linked to appliance for entire year
            # make occupancy vector per time step (10-min): if ANY occupant is active (state=1), make aggregate occy=1
            occy = [[1 if occ[i][x] == 1 else 0 for x in range(nday * nbin)]
                    for i in range(numOcc)]  # size numOcc x timesteps in year
            if act == 'None':  # if appliance is linked  to no specific activity (e.g. fridge)
                prob = [[1 for x in range(nday * nbin)] for i in range(numOcc)
                        ]  # activity 'None' always probability=1
            elif act == 'Presence':  # if appliance linked to presence (active occupants): probability =1 when ANYONE is present
                prob = occy
            else:  # appliance linked to specific activity (e.g. "food")
                # get activity probabilities for all occupants from stats.DTMC file
                actdata = [
                    stats.DTMC(clusterDict=clustersList[i])
                    for i in range(numOcc)
                ]
                prob = occy  # just initiate correct size
                to = -1  # time counter for occupancy
                for doy, step in itertools.product(
                        range(nday), range(nbin)):  #loop over year
                    dow_i = dow[doy]  # day of week (Monday=0)
                    to += 1
                    for i in range(
                            numOcc
                    ):  # get probability each occupant is performing the activity related to the appliance
                        prob[i][to] = occy[i][to] * actdata[i].get_var(
                            dow_i, act, step)

            ######################### SIMULATE appliance use
            to = -1  # time counter for occupancy (10min)
            tl = -1  # time counter for load (1min)
            left = [
                -1 for i in range(numOcc)
            ]  # time counter for appliance duration per occupant -> start as not used: -1

            for doy, step in itertools.product(
                    range(nday), range(nbin)):  # loop over 10min steps in year
                dow_i = dow[doy]  # day of week
                to += 1
                # occupancy in 10 min, but for each occupancy step simulate 10 individual minutes for the loads.
                for run in range(10):
                    tl += 1
                    if any(
                            l > 0 for l in left
                    ):  # if any occupant was using the appliance (there was time left[i]>0)
                        P[tl] += self.cycle_power  # assign power used when appliance is working
                        n_eq_dur += 1  # add to counter for number of minutes used in year
                    else:  # if nobody was using it
                        P[tl] += self.standby_power  # assign stand-by power

                    # per occupant, check if they will want to change the state of the appliance
                    for i in range(numOcc):
                        # check if this appliance is being used by occupant i: time left[i]>0
                        if left[i] > 0:
                            left[
                                i] += -1  # count time down until cycle passed (for this occupant)
                        else:  # if it was not used by this occupant: left[i] <= 0
                            # check if there is a state change in the appliance for this occupant
                            if random.random() < prob[i][
                                    to] * self.cal:  # if random number below calibration factor cal* probability of activity: start appliance
                                left[i] = random.gauss(
                                    len_cycle, len_cycle / 10
                                )  # start a cycle of random  duration for this occupant

            r_eq = {
                'P': P,
                'Q': Q,
                'QRad': P * self.frad,
                'QCon': P * self.fconv,
            }

            # n_eq is used in calibration process for value of 'cal'
            if len_cycle != 0:
                n_eq = n_eq_dur / len_cycle  # approximate number of cycles/year (assuming average length: mean of gauss distribution)
            else:
                n_eq = 1e-05  # some appliances don't have number of cycles if they are continuously working (then n_eq is not used)
            return r_eq, n_eq

        def cycle_load(self, nday):
            '''
            Simulate cycling appliances, eg. fridges and freezers based on
            average clycle length and delay between cycles
            '''

            nmin = nday * 24 * 60  # number of minutes in total number of days
            P = np.zeros(nmin + 1)
            Q = np.zeros(nmin + 1)  #currently no data included (remains zero)
            n_eq = 0  # number of cycles for calibration of `cal` parameter of appliance

            # define length of cycles (same for entire year, assumed to depend on appliance)
            len_cycle = random.gauss(self.cycle_length, self.cycle_length / 10)
            # define duration of break between cycles (same for entire year)
            delay = random.gauss(self.delay, self.delay / 10)

            # start as OFF (assumption)
            on = False  #is it ON?
            left = random.gauss(
                delay / 2,
                delay / 4)  # time left until change of state (initiate random)

            for tl in range(nmin + 1):  # loop over every minute of the year
                # if there is time LEFT until change of state, remain as is
                # if time is up, change state:
                if left <= 0:
                    on = not on  # switch to opposite state ON/OFF
                    if on:  # if switched ON
                        n_eq += 1  # add one to cycle counter
                        left = len_cycle  #start counting 1 cycle length
                    else:  # if switched OFF
                        left = delay  #start counting time until next cycle
                # either way, count downt the time until next change of state
                left += -1
                # allocate correct power, depending on current state ON/OFF
                if on:
                    P[tl] = self.cycle_power  # instead of the average consumption, could be sampled from normal distribution as well
                else:
                    P[tl] = self.standby_power

            r_eq = {
                'P': P,
                'Q': Q,
                'QRad': P * self.frad,
                'QCon': P * self.fconv
            }

            return r_eq, n_eq

        # when simulating an equipment object, choose which of following happens:
        if self.type == 'appliance':  #check if the equipment is an appliance instead of tapping point
            if self.activity == 'None':  #cycling loads -> don't depend on occupants
                r_app, n_app = cycle_load(self, nday)
            elif self.name in (
                    'placeholder'
            ):  # For future: if each occupant has her/his own appliance
                # For the moment appliances are assigned to the household such that there is one of each type
                # -> no way many people use their own (That's why there are 3 different TVs)
                r_app = dict()
                n_app = 0
                for i in range(
                        len(clustersList)):  # loop active occupants >12y
                    r_appi, n_appi = stochastic_load(
                        self, nday, dow, [clustersList[i]],
                        [occ[i]])  # we pass a list with one clusterDict
                    r_app = stats.sum_dict(r_app, r_appi)
                    n_app += n_appi
            else:  # other appliances (shared)
                r_app, n_app = stochastic_load(
                    self, nday, dow, clustersList, occ
                )  # we pass a list with all available clusterDicts, as given from plugloads
        else:  # flow-> model is based on total presence: do only once.
            r_app, n_app = stochastic_flow(
                self, nday, dow, clustersList, occ
            )  # we pass a list with one clusterDict, as given from DHW model

        return r_app, n_app