File: processes.txt

package info (click to toggle)
python-simpy 2.3.1%2Bdfsg-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,864 kB
  • sloc: python: 11,171; makefile: 143
file content (155 lines) | stat: -rw-r--r-- 4,306 bytes parent folder | download | duplicates (5)
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
# coding=utf8
"""
This file contains classes for simulating, controlling and observing a fridge.

@author: Stefan Scherfke
@contact: stefan.scherfke at uni-oldenburg.de
"""

from math import exp
import logging
import random

from SimPy.Simulation import Process, Simulation, \
		activate, hold, initialize, now, simulate

log = logging.getLogger('Processes')

class Fridge(Process):
	"""
	This class represents a simulated fridge.

	It's temperature T for and equidistant series of time steps is computed by
	$T_{i+1} = \epsilon \cdot T_i + (1 - \epsilon) \cdot \left(T^O - \eta
	\cdot \frac{q_i}{A}\right)$ with $\epsilon = e^{-\frac{\tau A}{m_c}}$.
	"""

	def __init__(self, sim, T_O = 20.0, A = 3.21, m_c = 15.97, tau = 1.0/60,
				  eta = 3.0, q_i = 0.0, q_max = 70.0,
				  T_i = 5.0, T_range = [5.0, 8.0], noise = False):
		"""
		Init all required variables.

		@param sim:       The SimPy simulation this process belongs to
		@type sim:        SimPy.Simulation
		@param T_O:       Outside temperature
		@param A:         Insulation
		@param m_c:       Thermal mass/thermal storage capacity
		@param tau:       Time span between t_i and t_{i+1}
		@param eta:       Efficiency of the cooling device
		@param q_i:       Initial/current electrical power
		@param q_max:     Power required during cool-down
		@param T_i:       Initial/current temperature
		@param T_range:   Allowed range for T_i
		@param noise:     Add noise to the fridge's parameters, if True
		@type noise:      bool
		"""
		Process.__init__(self, sim = sim)
		self.T_O = T_O
		self.A = A
		self.m_c = random.normalvariate(20, 4.5) if noise else m_c
		self.tau = tau
		self.eta = eta
		self.q_i = q_i
		self.q_max = q_max
		self.T_i = random.uniform(T_range[0], T_range[1]) if noise else T_i
		self.T_range = T_range

	def run(self):
		"""
		Calculate the fridge's temperature for the current time step.
		"""
		while True:
			epsilon = exp(-(self.tau * self.A) / self.m_c)
			self.T_i = epsilon * self.T_i + (1 - epsilon) \
					* (self.T_O - self.eta * (self.q_i / self.A))
			if self.T_i >= self.T_range[1]:
				self.q_i = self.q_max         # Cool down
			elif self.T_i <= self.T_range[0]:
				self.q_i = 0.0                # Stop cooling
			log.debug('T_i: %2.2f°C at %.2f' % (self.T_i, self.sim.now()))
			yield hold, self, self.tau

	def coolDown(self):
		"""
		Start cooling down now!
		"""
		self.q_i = self.q_max


class FridgeObserver(Process):
	"""
	This process observes the temperature and power consumption of a set of
	fridges.
	"""

	def __init__(self, sim, fridges, tau, aggSteps):
		"""
		Init the observer.

		@param sim: The SimPy simulation this process belongs to
		@type sim:  SimPy.Simulation
		@param fridges: A list of fridges to be observed
		@type fridges: tuple of Fridge
		@param tau: Time interval for observations
		@type tau: float
		@param aggSteps: Specifies after how many timesteps tau the collected
		                 data is aggregated and stored.
		@type aggSteps: int
		"""
		Process.__init__(self, sim = sim)
		self._fridges = fridges
		self._tau = tau
		self._aggSteps = aggSteps
		self._data = []

	def run(self):
		"""
		Start observation
		"""
		aggSteps = 0
		consumption = 0
		lastProgUpdate = 0
		while True:
			prog = self.sim.now() * 100 / self.sim._endtime
			if int(prog) > lastProgUpdate:
				log.info('Progress: %d%%' % prog)
				lastProgUpdate = prog
			if (aggSteps >= self._aggSteps):
				log.debug('Aggregating at %.2f' % self.sim.now())
				self._data.append(consumption/self._aggSteps)
				consumption = 0
				aggSteps = 0

			for fridge in self._fridges:
				consumption += fridge.q_i
			aggSteps += 1
			yield hold, self, self._tau

	def getData(self):
		"""
		Return the collected data

		@return: a list with the collected data
		"""
		return self._data


if __name__ == '__main__':
	logging.basicConfig(
			level = logging.DEBUG,
			format = '%(levelname)-8s %(asctime)s %(name)s: %(message)s')

	tau = 1./60 # Step size 1min
	aggSteps = 15 # Aggregate consumption in 15min blocks
	params = {'tau': tau}

	sim = Simulation()

	fridge = Fridge(sim, **params)
	observer = FridgeObserver(sim, [fridge], tau, aggSteps)

	sim.activate(fridge, fridge.run(), at = 0)
	sim.activate(observer, observer.run(), at = 0)
	sim.simulate(until = 4 + tau)
	print observer.getData()