comparison py/fridge.py @ 294:6bacd8ca9f8f

merge
author Matt Johnston <matt@ucc.asn.au>
date Sat, 06 Jul 2019 18:30:25 +0800
parents 6848907f85be
children 6087c692d381
comparison
equal deleted inserted replaced
293:d15dda1b1f76 294:6bacd8ca9f8f
3 3
4 from utils import L,W,E,EX,D 4 from utils import L,W,E,EX,D
5 import config 5 import config
6 6
7 import gpio 7 import gpio
8 import utils
8 9
9 class Fridge(object): 10 class Fridge(object):
10 11
11 OVERSHOOT_MAX_DIV = 1800.0 # 30 mins 12 OVERSHOOT_MAX_DIV = 1800.0 # 30 mins
12 13
13 def __init__(self, server): 14 def __init__(self, server, nowait = False):
14 self.server = server 15 self.server = server
15 self.gpio = gpio.Gpio(config.FRIDGE_GPIO_PIN, "fridge") 16 self.gpio = gpio.Gpio(config.FRIDGE_GPIO_PIN, "fridge")
17 self.integrator = utils.StepIntegrator(self.server.now, self.server.params.overshoot_delay)
16 self.wort_valid_clock = 0 18 self.wort_valid_clock = 0
17 self.fridge_on_clock = 0 19 self.fridge_on_clock = 0
18 self.off() 20 self.off()
21 if nowait:
22 self.fridge_off_clock = 0
19 23
20 def turn(self, value): 24 def turn(self, value):
21 self.gpio.turn(value) 25 self.gpio.turn(value)
26 self.integrator.turn(value)
22 27
23 def on(self): 28 def on(self):
24 self.turn(True) 29 self.turn(True)
25 pass
26 30
27 def off(self): 31 def off(self):
28 self.turn(False) 32 self.turn(False)
29 self.fridge_off_clock = self.server.now() 33 self.fridge_off_clock = self.server.now()
30 34
57 off_time = self.server.now() - self.fridge_off_clock 61 off_time = self.server.now() - self.fridge_off_clock
58 62
59 if wort is not None: 63 if wort is not None:
60 self.wort_valid_clock = self.server.now() 64 self.wort_valid_clock = self.server.now()
61 65
66 self.integrator.set_limit(params.overshoot_delay)
67
62 # Safety to avoid bad things happening to the fridge motor (?) 68 # Safety to avoid bad things happening to the fridge motor (?)
63 # When it turns off don't start up again for at least FRIDGE_DELAY 69 # When it turns off don't start up again for at least FRIDGE_DELAY
64 if not self.is_on() and off_time < config.FRIDGE_DELAY: 70 if not self.is_on() and off_time < config.FRIDGE_DELAY:
65 L("fridge skipping, too early") 71 L("fridge skipping, too early")
66 return 72 return
84 90
85 D("fridge on %s" % self.is_on()) 91 D("fridge on %s" % self.is_on())
86 92
87 if self.is_on(): 93 if self.is_on():
88 turn_off = False 94 turn_off = False
89 on_time = self.server.now() - self.fridge_on_clock 95 on_time = self.integrator.integrate()
96 on_percent = on_time / params.overshoot_delay
90 97
91 overshoot = 0 98 overshoot = params.overshoot_factor * on_percent
92 if on_time > params.overshoot_delay: 99 D("on_time %(on_percent)f, overshoot %(overshoot)f" % locals())
93 overshoot = params.overshoot_factor \
94 * min(self.OVERSHOOT_MAX_DIV, on_time) \
95 / self.OVERSHOOT_MAX_DIV
96 D("on_time %(on_time)f, overshoot %(overshoot)f" % locals())
97 100
98 if not params.nowort and wort is not None: 101 if not params.nowort and wort is not None:
99 if wort - overshoot < params.fridge_setpoint: 102 if wort - overshoot < params.fridge_setpoint:
100 L("wort has cooled enough, %(wort)f" % locals() ) 103 max_div = self.OVERSHOOT_MAX_DIV
104 overshoot_factor = params.overshoot_factor
105 L("wort has cooled enough, %(wort)fº (overshoot %(overshoot)fº = %(overshoot_factor)f * min(%(on_time)f) / %(max_div)f)" % locals() )
101 turn_off = True 106 turn_off = True
102 elif fridge is not None and fridge < fridge_min: 107 elif fridge is not None and fridge < fridge_min:
103 W("fridge off fallback, fridge %(fridge)f, min %(fridge_min)f" % locals()) 108 W("fridge off fallback, fridge %(fridge)f, min %(fridge_min)f" % locals())
104 if wort is None: 109 if wort is None:
105 W("wort has been invalid for %d" % (self.server.now() - self.wort_valid_clock)) 110 W("wort has been invalid for %d" % (self.server.now() - self.wort_valid_clock))