-
Notifications
You must be signed in to change notification settings - Fork 0
/
pid.py
160 lines (122 loc) · 4.63 KB
/
pid.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
#!/usr/bin/python3
# """ PID clases configured for the beer and the chamber """
# Import standard libraries ---------------------------------------------------
from simple_pid import PID
# Import application libraries ------------------------------------------------
from logger import BrewfermLogger
import paths
"""
Creates a rotating log
"""
logger = BrewfermLogger('pid.py').getLogger()
# Classes ------------------------------------------------------------
class BeerPID:
def __init__(self, setpoint):
self.sample_time = 60.0 # seconds
# these are defaults that will be
# overwritten by any user stored values
self.kp = paths.default_beerP
self.ki = paths.default_beerI
self.kd = paths.default_beerD
self.setpoint = setpoint
self.pid = PID(
Kp=self.kp,
Ki=self.ki,
Kd=self.kd,
sample_time=2,
output_limits=self.calculate_limits(setpoint),
setpoint=self.setpoint)
logger.info(
'new beer target %s with limits %s',
self.pid.setpoint,
self.pid.output_limits)
def calculate_limits(self, current_temp):
low_limit = self.setpoint - paths.beer_lowlimit_offset
high_limit = self.setpoint + paths.beer_highlimit_offset
if low_limit < paths.beer_lowlimit_low:
low_limit = paths.beer_lowlimit_low
if high_limit > paths.beer_highlimit_high:
high_limit = paths.beer_highlimit_high
return low_limit, high_limit
def update(self, current_temp):
self.pid.output_limits = self.calculate_limits(current_temp)
return self.pid(current_temp)
def change_target(self, setpoint):
if setpoint != self.setpoint:
self.setpoint = setpoint
self.pid.output_limits = self.calculate_limits(setpoint)
self.pid.setpoint = self.setpoint
self.pid._integral = setpoint
self.pid._last_output = setpoint
def get_tuning(self):
try:
x = {}
x['kp'] = self.kp
x['ki'] = self.ki
x['kd'] = self.kd
x['sample_time'] = self.pid.sample_time
return x
except Exception as e:
logger.exception('%s %s', type(e), e)
def set_tuning(self, new_settings):
try:
if new_settings.get('kp') is not None:
self.kp = new_settings['kp']
if new_settings.get('ki') is not None:
self.ki = new_settings['ki']
if new_settings.get('kd') is not None:
self.kd = new_settings['kd']
self.pid.tunings = self.kp, self.ki, self.kd
if new_settings.get('sample_time') is not None:
self.pid.sample_time = new_settings['sample_time']
except Exception as e:
logger.exception('%s %s', type(e), e)
class ChamberPID:
def __init__(self, setpoint):
# these are defaults that will be
# overwritten by any user stored values
self.kp = paths.default_chamberP
self.ki = paths.default_chamberI
self.kd = paths.default_chamberD
self.setpoint = setpoint
self.pid = PID(
Kp=self.kp,
Ki=self.ki,
Kd=self.kd,
sample_time=2,
output_limits=(1, 100),
setpoint=self.setpoint)
self._integral = 50
self._last_output = 50
def update(self, current_temp):
return self.pid(float(current_temp))
def get_tuning(self):
try:
x = {}
x['kp'] = self.kp
x['ki'] = self.ki
x['kd'] = self.kd
x['sample_time'] = self.pid.sample_time
return x
except Exception as e:
logger.exception('%s %s', type(e), e)
def set_tuning(self, new_settings):
try:
if new_settings.get('kp') is not None:
self.kp = new_settings['kp']
if new_settings.get('ki') is not None:
self.ki = new_settings['ki']
if new_settings.get('kd') is not None:
self.kd = new_settings['kd']
self.pid.tunings = self.kp, self.ki, self.kd
if new_settings.get('sample_time') is not None:
self.pid.sample_time = new_settings['sample_time']
except Exception as e:
logger.exception('%s %s', type(e), e)
# main loop here
if __name__ == '__main__':
try:
logger.info("running BrewfermPID module tests")
logger.info("finished BrewfermPID module tests")
except Exception as e:
logger.exception("%s %s", type(e), e)