changeset 4:32a56dd33e42

- Reduce hystersis down to 0.5C - Properly track stale data (hopefully anyway :) - Check if the monitor thread has died (ie unexpected exception) - Re-work some variable names to be clearer (& add comments)
author darius
date Fri, 28 Sep 2007 13:05:11 +0000
parents 1af7c85d5a0e
children 8d471840b153
files beermon.py
diffstat 1 files changed, 37 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/beermon.py	Mon Sep 24 13:34:47 2007 +0000
+++ b/beermon.py	Fri Sep 28 13:05:11 2007 +0000
@@ -4,7 +4,7 @@
 # Monitor & control fermenter temperature 
 # v1.0
 #
-# $Id: beermon.py,v 1.4 2007/09/24 13:34:47 darius Exp $
+# $Id: beermon.py,v 1.5 2007/09/28 13:05:11 darius Exp $
 #
 # Depends on: Python 2.3 (I think)
 #
@@ -42,10 +42,14 @@
 class ROMReadError(Exception):
     pass
 
+class ThreadDied(Exception):
+    pass
+
 class Control():
     targetTemp = 18
-    hysteresis = 1
+    hysteresis = 0.5
     pollInterval = 30
+    staleDataTime = 30
     
     def __init__(self, m, _log):
         self.m = m
@@ -66,18 +70,23 @@
         log.debug("=== Starting ===")
         log.debug("Fermenter	Fridge	Ambient	State	New State")
         while True:
-            if (self.m.lastUpdate == 0):
-                log.debug("Invalid data")
+            # Check if our monitor thread has died
+            if (not self.m.isAlive()):
+                raise ThreadDied, "Monitor thread has died"
+
+            # Check for stale data
+            if (self.m.lastUpdate[self.m.fermenterId] + self.staleDataTime < time.time()):
+                log.debug("Stale data")
                 self.cv.wait(self.pollInterval)
                 self.m.setState('idle')
                 continue
 
+            # Work out what state we should go into
             nextState = "-"
-
             diff = self.m.temps[self.m.fermenterId] - self.targetTemp
             if (self.m.currState == 'idle'):
                 # If we're idle then only heat or cool if the temperate difference is out of the
-                # hysteresis range
+                # hysteresis band
                 if (abs(diff) > self.hysteresis):
                     if (diff < 0 and self.m.minHeatOffTime + self.m.lastHeatOff < time.time()):
                         nextState = 'heat'
@@ -88,18 +97,21 @@
                 if (diff < 0 and self.m.minCoolOnTime + self.m.lastCoolOn < time.time()):
                     nextState = 'idle'
             elif (self.m.currState == 'heat'):
+                # Ditto
                 if (diff > 0 and self.m.minHeatOnTime + self.m.lastHeatOn < time.time()):
                     nextState = 'idle'
             else:
+                # Not possible..
                 raise KeyError
 
             log.debug("%3.2f   	%3.2f	%3.2f	%s	%s" %
                       (self.m.temps[self.m.fermenterId],
                        self.m.temps[self.m.fridgeId], self.m.temps[self.m.ambientId],
                        self.m.currState, nextState))
+
             if (nextState != "-"):
                 self.m.setState(nextState)
-                
+
             self.cv.wait(self.pollInterval)
             
 
@@ -124,9 +136,16 @@
     minHeatOnTime = 60
     minHeatOffTime = 60
 
+    # Dictionary of sensor IDs & temperatures
     temps = {}
-    lastUpdate = 0
+    # Dictionary of sensor IDs & epoch times
+    lastUpdate = {}
 
+    # List of all device IDs
+    devs = []
+    # List of temperature sensor IDs
+    tempdevs = []
+    
     # Lock to gate access to the comms
     commsLock = None
 
@@ -145,7 +164,7 @@
         self.p.timeout = 3
         self.setspeed()
         self.devs = self.find1wire()
-        self.temps = filter(self.istemp, self.devs)
+        self.tempdevs = filter(self.istemp, self.devs)
 
         self.start()
         
@@ -203,12 +222,14 @@
             return False
 
     def updateTemps(self):
-        tmp = {}
-        for i in self.temps:
-            tmp[i] = float(self.readTemp(i))
-
-        self.temps = tmp
-        self.lastUpdate = time.time()
+        for i in self.tempdevs:
+            try:
+                self.temps[i] = float(self.readTemp(i))
+                self.lastUpdate[i] = time.time()
+            except ROMReadError:
+                # Ignore this - just results in no update reflected by lastUpdate
+                pass
+            
         return(self.temps)
 
     def readTemp(self, id):
@@ -309,7 +330,7 @@
     log = initLog()
 
     log.debug("=== Initing ===")
-    log.debug("$Id: beermon.py,v 1.4 2007/09/24 13:34:47 darius Exp $")
+    log.debug("$Id: beermon.py,v 1.5 2007/09/28 13:05:11 darius Exp $")
 
     m = None
     exitCode = 0