Mercurial > templog
comparison py/fridge.py @ 443:bca470d153fd
a bit more, and some tests
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Mon, 26 Nov 2012 23:21:03 +0800 |
parents | 02318c9660cd |
children | 6517ddee3187 |
comparison
equal
deleted
inserted
replaced
442:02318c9660cd | 443:bca470d153fd |
---|---|
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 from utils import L,W,E | 2 from utils import L,W,E,EX |
3 import config | 3 import config |
4 import gevent | |
4 | 5 |
5 class Fridge(object): | 6 class Fridge(gevent.Greenlet): |
6 | 7 |
7 OVERSHOOT_MAX_DIV = 1800.0 # 30 mins | 8 OVERSHOOT_MAX_DIV = 1800.0 # 30 mins |
8 FRIDGE_AIR_MIN_RANGE = 4 # ºC | 9 FRIDGE_AIR_MIN_RANGE = 4 # ºC |
9 FRIDGE_AIR_MAX_RANGE = 4 | 10 FRIDGE_AIR_MAX_RANGE = 4 |
10 | 11 |
11 def __init__(self): | 12 def __init__(self, server): |
13 gevent.Greenlet.__init__(self) | |
14 self.server = server | |
12 self.setup_gpio() | 15 self.setup_gpio() |
13 self.wort_valid_clock = 0 | 16 self.wort_valid_clock = 0 |
14 self.fridge_on_clock = 0 | 17 self.fridge_on_clock = 0 |
15 self.fridge_off_clock = 0 | 18 self.fridge_off_clock = 0 |
16 | 19 |
43 if buf != '1': | 46 if buf != '1': |
44 E("Bad value read from gpio '%s': '%s'" | 47 E("Bad value read from gpio '%s': '%s'" |
45 % (self.value_file.name, buf)) | 48 % (self.value_file.name, buf)) |
46 return True | 49 return True |
47 | 50 |
48 def run(self, server): | 51 # greenlet subclassed |
49 | 52 def _run(self): |
50 while True: | 53 while True: |
51 self.do(server) | 54 self.do() |
52 gevent.sleep(config.FRIDGE_SLEEP) | 55 gevent.sleep(config.FRIDGE_SLEEP) |
53 | 56 |
54 def do(self, server): | 57 def do(self) |
55 """ this is the main fridge control logic """ | 58 """ this is the main fridge control logic """ |
56 wort, fridge, ambient = server.current_temps() | 59 wort, fridge = self.server.current_temps() |
57 | 60 |
58 fridge_min = params.fridge_setpoint - self.FRIDGE_AIR_MIN_RANGE | 61 fridge_min = params.fridge_setpoint - self.FRIDGE_AIR_MIN_RANGE |
59 fridge_max = params.fridge_setpoint + self.FRIDGE_AIR_MAX_RANGE | 62 fridge_max = params.fridge_setpoint + self.FRIDGE_AIR_MAX_RANGE |
60 | 63 |
61 wort_max = params.fridge_setpoint + params.fridge_difference | 64 wort_max = params.fridge_setpoint + params.fridge_difference |
62 | 65 |
63 off_time = server.now() - self.fridge_off_clock | 66 off_time = self.server.now() - self.fridge_off_clock |
64 | 67 |
65 if off_time < config.FRIDGE_DELAY: | 68 if off_time < config.FRIDGE_DELAY: |
66 L("fridge skipping, too early") | 69 L("fridge skipping, too early") |
67 return | 70 return |
68 | 71 |
69 # handle broken wort sensor | 72 # handle broken wort sensor |
70 if wort is not None: | 73 if wort is not None: |
71 self.wort_valid_clock = server.now() | 74 self.wort_valid_clock = self.server.now() |
72 else: | 75 else: |
73 W("Invalid wort sensor") | 76 W("Invalid wort sensor") |
74 invalid_time = server.now() - self.wort_valid_clock | 77 invalid_time = self.server.now() - self.wort_valid_clock |
75 if invalid_time < config.FRIDGE_WORT_INVALID_TIME: | 78 if invalid_time < config.FRIDGE_WORT_INVALID_TIME: |
76 W("Has only been invalid for %d, waiting" % invalid_time) | 79 W("Has only been invalid for %d, waiting" % invalid_time) |
77 return | 80 return |
78 | 81 |
79 if fridge is None: | 82 if fridge is None: |
80 W("Invalid fridge sensor") | 83 W("Invalid fridge sensor") |
81 | 84 |
82 if self.is_on(): | 85 if self.is_on(): |
83 turn_off = False | 86 turn_off = False |
84 on_time = server.now() - self.fridge_on_clock | 87 on_time = self.server.now() - self.fridge_on_clock |
85 | 88 |
86 overshoot = 0 | 89 overshoot = 0 |
87 if on_time > params.overshoot_delay: | 90 if on_time > params.overshoot_delay: |
88 overshoot = params.overshoot_factor \ | 91 overshoot = params.overshoot_factor \ |
89 * min(self.OVERSHOOT_MAX_DIV, on_time) \ | 92 * min(self.OVERSHOOT_MAX_DIV, on_time) \ |
94 if (wort - overshoot) < params.fridge_setpoint: | 97 if (wort - overshoot) < params.fridge_setpoint: |
95 L("wort has cooled enough") | 98 L("wort has cooled enough") |
96 turn_off = True | 99 turn_off = True |
97 else: | 100 else: |
98 # wort sensor is broken | 101 # wort sensor is broken |
99 if fridge is not None and last_fridge < fridge_min: | 102 if fridge is not None and fridge < fridge_min: |
100 W("fridge off fallback") | 103 W("fridge off fallback") |
101 turn_off = True | 104 turn_off = True |
102 | 105 |
103 if turn_off: | 106 if turn_off: |
104 L("Turning fridge off") | 107 L("Turning fridge off") |
105 self.off() | 108 self.off() |
106 self.fridge_off_clock = server.now() | 109 self.fridge_off_clock = self.server.now() |
107 | 110 |
108 else: | 111 else: |
109 # fridge is off | 112 # fridge is off |
110 turn_on = False | 113 turn_on = False |
111 if wort is not None: | 114 if wort is not None: |
119 turn_on = True | 122 turn_on = True |
120 | 123 |
121 if turn_on: | 124 if turn_on: |
122 L("Turning fridge on") | 125 L("Turning fridge on") |
123 self.on() | 126 self.on() |
124 fridge_on_clock = server.now() | 127 fridge_on_clock = self.server.now() |