# HG changeset patch # User Matt Johnston # Date 1447250318 -28800 # Node ID af924d27140f624c3dbda26ad459e265f697cc12 # Parent 11cebd6f0bfbbd344f51438f0f11180e26a521c6 scale integrate by delay time namedtuple for StepIntegrator diff -r 11cebd6f0bfb -r af924d27140f py/fridge.py --- a/py/fridge.py Wed Nov 11 00:20:20 2015 +0800 +++ b/py/fridge.py Wed Nov 11 21:58:38 2015 +0800 @@ -92,10 +92,10 @@ if self.is_on(): turn_off = False - on_time = self.server.now() - self.fridge_on_clock + on_percent = self.integrator.integrate() / params.overshoot_delay - overshoot = params.overshoot_factor * self.integrator.integrate() - D("on_time %(on_time)f, overshoot %(overshoot)f" % locals()) + overshoot = params.overshoot_factor * on_percent + D("on_time %(on_percent)f, overshoot %(overshoot)f" % locals()) if not params.nowort and wort is not None: if wort - overshoot < params.fridge_setpoint: diff -r 11cebd6f0bfb -r af924d27140f py/utils.py --- a/py/utils.py Wed Nov 11 00:20:20 2015 +0800 +++ b/py/utils.py Wed Nov 11 21:58:38 2015 +0800 @@ -7,6 +7,7 @@ import binascii import json import datetime +import collections D = logging.debug L = logging.info @@ -172,6 +173,7 @@ else: D(msg) +Period = collections.namedtuple('Period', 'start end') class StepIntegrator(object): """ Takes on/off events and a monotonically increasing timefn. Returns the integral @@ -210,7 +212,7 @@ 0 """ def __init__(self, timefn, limittime): - # _on_periods is a list of [[start, end]]. End is None if still on + # _on_periods is a list of [period]. End is None if still on self._on_periods = [] self._timefn = timefn self._limittime = limittime @@ -219,28 +221,28 @@ if self._limittime == limittime: return self._limittime = limittime - self.trim() + self._trim() def turn(self, value): if not self._on_periods: if value: - self._on_periods.append([self._timefn(), None]) + self._on_periods.append(Period(self._timefn(), None)) return # state hasn't changed - on_now = (self._on_periods[-1][1] is None) + on_now = (self._on_periods[-1].end is None) if value == on_now: return if value: - self._on_periods.append([self._timefn(), None]) + self._on_periods.append(Period(self._timefn(), None)) else: - self._on_periods[-1][1] = self._timefn() + self._on_periods[-1] = self._on_periods[-1]._replace(end = self._timefn()) def _trim(self): begin = self._timefn() - self._limittime # shortcut, first start is after begin - if not self._on_periods or self._on_periods[0][0] >= begin: + if not self._on_periods or self._on_periods[0].start >= begin: return new_periods = [] @@ -248,11 +250,11 @@ if s == e: continue elif s >= begin: - new_periods.append([s,e]) + new_periods.append(Period(s,e)) elif e is not None and e < begin: continue else: - new_periods.append([begin, e]) + new_periods.append(Period(begin, e)) self._on_periods = new_periods def integrate(self):