-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathpersons.py
executable file
·280 lines (222 loc) · 11.7 KB
/
persons.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
#Copyright (C) 2023 University of Twente
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#GNU General Public License for more details.
#You should have received a copy of the GNU General Public License
#along with this program. If not, see <http://www.gnu.org/licenses/>.
from configLoader import *
config = importlib.import_module(cfgFile)
import profilegentools
class Person:
def __init__(self, age):
self.generate(age)
def generate(self, age):
#Variates could also use a gauss distribution, some persons are more predictable than others ;)
self.Age = age
self.WorkdayWakeUp_Avg = profilegentools.gaussMinMax(7*60, 1.5*60)
self.WorkdayWakeUp_Variate = 10
self.WorkdayLeave_Avg = self.WorkdayWakeUp_Avg + profilegentools.gaussMinMax(45, 15)
self.WorkdayLeave_Variate = 10
self.WorkdayArrival_Avg = self.WorkdayLeave_Avg + profilegentools.gaussMinMax(8.5*60, 30)
self.WorkdayArrival_Variate = 15
self.WorkdaySport_Avg = self.WorkdayArrival_Avg + profilegentools.gaussMinMax(2.5*60, 2*60)
self.WorkdaySport_Variate = 15
self.WorkdaySportDuration_Avg = profilegentools.gaussMinMax(1.5*60, 30)
self.WorkdaySportDuration_Variate = 10
self.WorkdayBedTime_Avg = self.WorkdayWakeUp_Avg + profilegentools.gaussMinMax(15.5*60,30)
self.WorkdayBedTime_Variate = 15
self.WorkdayActivities = random.randint(config.personWeekdayActivityChanceMin, config.personWeekdayActivityChanceMax) / 100 #Chance to conduct random activities
self.WeekendWakeUp_Avg = profilegentools.gaussMinMax(9*60, 2*60)
self.WeekendWakeUp_Variate = 20
self.WeekendSport_Avg = profilegentools.gaussMinMax(14*60, 5*60)
self.WeekendSport_Variate = 60
self.WeekendSportDuration_Avg = profilegentools.gaussMinMax(1.5*60, 30)
self.WeekendSportDuration_Variate = 30
self.WeekendBedTime_Avg = profilegentools.gaussMinMax(23*60, 30)
self.WeekendBedTime_Variate = 10
self.WeekendActivities = random.randint(config.personWeekendActivityChanceMin, config.personWeekendActivityChanceMax) / 100
#For a new deepcopy, the following values should be regenerated
self.WorkdaySportday = 1 + random.randint(1,5)
self.WeekendSportday = 6*random.randint(0,1)
self.Workdays = range(1,6)
self.DistanceToWork = 0
self.CookingTime = self.WorkdayArrival_Avg + 30
self.showerMorning = True
self.showerDays = list(range(0, 7))
self.showerDuration = profilegentools.gaussMinMax(8, 3)
# Generate Heat parameters
self.generateHeatParams()
# def generateActivity(self):
# self.WorkdaySportday = 1 + random.randint(1,5)
# self.WeekendSportday = 6 + random.randint(0,1)
def generateWorkdays(self, days):
self.Workdays = random.sample(range(1, 6), days)
def generateHeatParams(self):
# Thermostat setpoint preference
if self.Age > 80:
self.thermostatSetpoint = random.randint(int(21*2), int(24*2)) / 2.0
elif self.Age > 75:
self.thermostatSetpoint = random.randint(int(20.5*2), int(23*2)) / 2.0
elif self.Age > 65:
self.thermostatSetpoint = random.randint(int(20*2), int(22.5*2)) / 2.0
elif self.Age > 50:
self.thermostatSetpoint = random.randint(int(19*2), int(21.5*2)) / 2.0
else:
self.thermostatSetpoint = random.randint(int(18.5*2), int(20.5*2)) / 2.0
# Heat production by person, see ASHRAE chapter 18
self.heatGeneration = 120 # int(130*(92.5)) #Watts. Note that we lack male/female differnce
if self.Age < 15:
self.heatGeneration = 97 # 75% of adule male for children
# Showering schedule
# More info: E.J.M. Blokker, "Stochastic water demand modelling for a better understanding of hydraulics in water distribution networks". PhD Thesis TU Delft, 2010
numOfShowerDays = random.randint(4, 6)
if self.Age > 40:
numOfShowerDays -= max(3, random.randint(1, 2)) #Minum of 3x per week
else:
numOfShowerDays += random.randint(0, 1) # Younger people shower a bit more often
# Now select the days
self.showerDays = random.sample(self.showerDays, numOfShowerDays)
# Preferred shower time:
# 65% showers in the morning:
self.showerMorning = True
r = random.randint(0, 100)
if r >= 65:
self.showerMorning = False
# Shower time, avg = 8 minutes
if self.Age >= 10 and self.Age <= 20:
# Teens shower (much) longer:
self.showerDuration += random.randint(5, 10)
def setActivities(self, workday, weekend):
self.WorkdayActivities = workday
self.WeekendActivities = weekend
def setDistanceToWork(self, distance):
if distance > 5: #Only distance of 5 or more is interesting, the rest is not really of interrest tbh. Bicycle will be used for example
self.DistanceToWork = distance
def simulateWorkday(self, day):
#select variables
eventList = []
self.WorkdayWakeUp = random.randint((self.WorkdayWakeUp_Avg - self.WorkdayWakeUp_Variate), (self.WorkdayWakeUp_Avg + self.WorkdayWakeUp_Variate))
eventList.append(self.WorkdayWakeUp)
self.WorkdayLeave = random.randint((self.WorkdayLeave_Avg - self.WorkdayLeave_Variate), (self.WorkdayLeave_Avg + self.WorkdayLeave_Variate))
eventList.append(self.WorkdayLeave)
self.WorkdayArrival = random.randint((self.WorkdayArrival_Avg - self.WorkdayArrival_Variate), (self.WorkdayArrival_Avg + self.WorkdayArrival_Variate))
eventList.append(self.WorkdayArrival)
if ((day%7) == self.WorkdaySportday):
#Today this person will go to sport or have an activity. Times are synchronized to keep it easy
self.WorkdayActivity = random.randint((self.WorkdaySport_Avg - self.WorkdaySport_Variate), (self.WorkdaySport_Avg + self.WorkdaySport_Variate))
eventList.append(self.WorkdayActivity)
self.WorkdayActivityEnd = self.WorkdayActivity + random.randint((self.WorkdaySportDuration_Avg - self.WorkdaySportDuration_Variate), (self.WorkdaySportDuration_Avg + self.WorkdaySportDuration_Variate))
eventList.append(self.WorkdayActivityEnd)
elif (random.random() < self.WorkdayActivities):
self.WorkdayActivity = random.randint((self.WorkdaySport_Avg - self.WorkdaySport_Variate), (self.WorkdaySport_Avg + self.WorkdaySport_Variate))
eventList.append(self.WorkdayActivity)
self.WorkdayActivityEnd = self.WorkdayActivity + random.randint((self.WorkdaySportDuration_Avg - self.WorkdaySportDuration_Variate), (self.WorkdaySportDuration_Avg + self.WorkdaySportDuration_Variate))
eventList.append(self.WorkdayActivityEnd)
self.WorkdayBedTime = min(1439, random.randint((self.WorkdayBedTime_Avg - self.WorkdayBedTime_Variate), (self.WorkdayBedTime_Avg + self.WorkdayBedTime_Variate)))
eventList.append(self.WorkdayBedTime)
active = 0 #start asleep
activeList = []
for minute in range(0,1440):
if minute in eventList:
active = 1 - active
activeList.append(active)
assert((len(eventList)%2)==0)
assert(self.WorkdayBedTime<1440)
return activeList
def simulateWeekend(self, day):
#select variables
eventList = []
#basically this simulates a free day. On normal days one will wake up more early
if((day%7)==0 or (day%7)==6):
self.WeekendWakeUp = random.randint((self.WeekendWakeUp_Avg - self.WeekendWakeUp_Variate), (self.WeekendWakeUp_Avg + self.WeekendWakeUp_Variate))
else:
#Day off, get out of bed earlier
self.WeekendWakeUp = random.randint((self.WeekendWakeUp_Avg - self.WeekendWakeUp_Variate - 60), (self.WeekendWakeUp_Avg + self.WeekendWakeUp_Variate - 60))
eventList.append(self.WeekendWakeUp)
if (((day%7) == self.WeekendSportday)):
#Today this person will go to sport or have an activity. Times are synchronized to keep it easy
self.WeekendActivity = random.randint((self.WeekendSport_Avg - self.WeekendSport_Variate), (self.WeekendSport_Avg + self.WeekendSport_Variate))
eventList.append(self.WeekendActivity)
self.WeekendActivityEnd = self.WeekendActivity + random.randint((self.WeekendSportDuration_Avg - self.WeekendSportDuration_Variate), (self.WeekendSportDuration_Avg + self.WeekendSportDuration_Variate))
eventList.append(self.WeekendActivityEnd)
elif ((day%7) == self.WorkdaySportday):
#Today this person will go to sport or have an activity. Times are synchronized to keep it easy
self.WorkdayActivity = random.randint((self.WorkdaySport_Avg - self.WorkdaySport_Variate), (self.WorkdaySport_Avg + self.WorkdaySport_Variate))
eventList.append(self.WorkdayActivity)
self.WorkdayActivityEnd = self.WorkdayActivity + random.randint((self.WorkdaySportDuration_Avg - self.WorkdaySportDuration_Variate), (self.WorkdaySportDuration_Avg + self.WorkdaySportDuration_Variate))
eventList.append(self.WorkdayActivityEnd)
elif (random.random() < self.WeekendActivities):
duration = random.randint(90,8*60)
if duration > 6*60:
#all-day event
if random.randint(0,1) == 0: #Note: For retired people we might need to add a restriction here
self.WeekendActivity = self.WeekendWakeUp + random.randint(60,90)
else:
self.WeekendActivity = random.randint(13*60,15*60)
elif duration > 3*60:
#Afternoon activity
self.WeekendActivity = random.randint(14*60,15*60)
elif random.randint(0,1) == 0:
#Morning event
self.WeekendActivity = self.WeekendWakeUp + random.randint(60,90)
else:
#night event
self.WeekendActivity = random.randint(20*60,21*60)
eventList.append(self.WeekendActivity)
self.WeekendActivityEnd = self.WeekendActivity + duration
eventList.append(self.WeekendActivityEnd)
self.WeekendBedTime = random.randint((self.WeekendBedTime_Avg - self.WeekendBedTime_Variate), (self.WeekendBedTime_Avg + self.WeekendBedTime_Variate))
eventList.append(self.WeekendBedTime)
active = 0 #start asleep
activeList = []
for minute in range(0,1440):
if minute in eventList:
active = 1 - active
activeList.append(active)
assert((len(eventList)%2)==0)
assert(self.WeekendBedTime<1440)
return activeList
def simulate(self, day):
if (day%7) in self.Workdays:
if((day%7)==0 or (day%7)==6 or random.randint(0,(100-len(self.Workdays)*10))==0):
return self.simulateWeekend(day)
else:
return self.simulateWorkday(day)
else:
return self.simulateWeekend(day)
class PersonWorker(Person):
def __init__(self, age):
self.generate(age)
if age>55 or random.randint(0,2)==0: #Older people can get a day off sometimes, such as BAPO in the education. Furthermore 33% has a home working day: http://www.kamer033.nl/nieuws/in-8-tips-een-productieve-thuiswerkdag/
self.generateWorkdays(4)
else:
self.generateWorkdays(5)
class PersonParttimeWorker(Person):
def __init__(self, age):
self.generate(age)
self.generateWorkdays(random.randint(2,3))
class PersonStudent(Person):
def __init__(self, age):
self.generate(age)
self.WorkdayArrival_Avg = self.WorkdayLeave_Avg + profilegentools.gaussMinMax(7*60, 30)
if(age < 16):
self.WorkdayBedTime_Avg = profilegentools.gaussMinMax((23-(16-age)*0.25)*60, 30)
self.WeekendBedTime_Avg = profilegentools.gaussMinMax((23-(16-age)*0.25)*60, 30)
self.WorkdaySport_Avg = profilegentools.gaussMinMax(19*60, 1*60)
class PersonJobless(Person):
def __init__(self, age):
self.generate(age)
self.generateWorkdays(0)
class PersonRetired(Person):
def __init__(self, age):
self.generate(age)
self.generateWorkdays(0)
self.WeekendWakeUp_Avg = profilegentools.gaussMinMax(8.5*60, 1*60)
self.WeekendActivities = 0.7 - (0.03*(age-65))
self.WorkdayBedTime_Avg = profilegentools.gaussMinMax((23-(age-65)*0.15)*60, 30)
self.WeekendBedTime_Avg = profilegentools.gaussMinMax((23-(age-65)*0.15)*60, 30)