def stochastic_flow(self, nday, dow, clusterDict, occ): ''' Simulate non-cycling appliances based on occupancy and the model and Markov state-space of Richardson et al. ''' # parameters ###################################################### # First we check the required activity and load the respective # stats.DTMC file with its data. len_cycle = self.cycle_length act = self.activity if self.activity not in ('None', 'Presence'): actdata = stats.DTMC(clusterDict=clusterDict) else: actdata = None # script ########################################################## # a yearly simulation is basic, also in a unittest nbin = 144 minutes = nday * 1440 to = -1 # time counter for occupancy tl = -1 # time counter for load left = -1 # time counter for appliance duration n_fl = 0 flow = np.zeros(minutes + 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 appliance is already on 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 appliance 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 = { 'time': time, 'occ': None, 'P': None, 'Q': None, 'QRad': None, 'QCon': None, 'Wknds': None, 'mDHW': flow } return r_fl, n_fl
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