# ***************************************************************************** # 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 2 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, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Module authors: # Markus Zolliker # Jael Celia Lorenzana # ***************************************************************************** """PI control for furnance""" import time from frappy.core import Writable, Attached, Parameter, FloatRange, Readable, BoolType, ERROR, IDLE class PI(Writable): input = Attached(Readable, 'the input module') output = Attached(Writable, 'the output module') relais = Attached(Writable, 'the interlock relais') p = Parameter('proportional term', FloatRange(0), readonly=False) i = Parameter('integral term', FloatRange(0), readonly=False) control_active = Parameter('control flag', BoolType(), readonly=False, default=False) value = Parameter(unit='degC') _lastdiff = None _lasttime = 0 def doPoll(self): super().doPoll() if not self.control_active: return self.value = self.input.value self.status = IDLE, 'controlling' now = time.time() deltat = min(10, now-self._lasttime) self._lasttime = now diff = self.target - self.value if self.value > 300: self.write_control_active(False) return if self._lastdiff is None: self._lastdiff = diff deltadiff = diff - self._lastdiff self._lastdiff = diff output = self.output.target output += self.p * deltadiff + self.i * deltat * diff if output > 100: output = 100 elif output < 0: output = 0 self.output.write_target(output) def write_control_active(self, value): if not value: self.output.write_target(0) def write_target(self, value): self.control_active = True self.relais.write_target(1)