changeset 272:af924d27140f

scale integrate by delay time namedtuple for StepIntegrator
author Matt Johnston <matt@ucc.asn.au>
date Wed, 11 Nov 2015 21:58:38 +0800
parents 11cebd6f0bfb
children 74c3ae4e3307
files py/fridge.py py/utils.py
diffstat 2 files changed, 14 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- 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:
--- 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):