comparison py/tempserver.py @ 228:d9e81a563923

porting to asyncio
author Matt Johnston <matt@ucc.asn.au>
date Fri, 20 Mar 2015 20:12:25 +0800
parents 16a83e2c97a0
children 99255c501e02
comparison
equal deleted inserted replaced
227:efb5cad2e98b 228:d9e81a563923
3 import sys 3 import sys
4 import os 4 import os
5 import logging 5 import logging
6 import time 6 import time
7 import signal 7 import signal
8 import asyncio
8 9
9 import gevent
10 import gevent.monkey
11 import lockfile.pidlockfile 10 import lockfile.pidlockfile
12 import daemon 11 import daemon
13 12
14 import utils 13 import utils
15 from utils import L,D,EX,W 14 from utils import L,D,EX,W
23 class Tempserver(object): 22 class Tempserver(object):
24 def __init__(self): 23 def __init__(self):
25 self.readings = [] 24 self.readings = []
26 self.current = (None, None) 25 self.current = (None, None)
27 self.fridge = None 26 self.fridge = None
28 self._wakeup = gevent.event.Event() 27 self._wakeup = asyncio.Event()
29
30 # don't patch os, fork() is used by daemonize
31 gevent.monkey.patch_all(os=False, thread=False)
32 28
33 def __enter__(self): 29 def __enter__(self):
34 self.params = params.Params() 30 self.params = params.Params()
35 self.fridge = fridge.Fridge(self) 31 self.fridge = fridge.Fridge(self)
36 self.uploader = uploader.Uploader(self) 32 self.uploader = uploader.Uploader(self)
37 self.params.load() 33 self.params.load()
38 self.set_sensors(sensor_ds18b20.DS18B20s(self)) 34 self.set_sensors(sensor_ds18b20.DS18B20s(self))
39 gevent.signal(signal.SIGHUP, self._reload_signal) 35 asyncio.get_event_loop().add_signal_handler(signal.SIGHUP, self._reload_signal)
40 return self 36 return self
41 37
42 def __exit__(self, exc_type, exc_value, traceback): 38 def __exit__(self, exc_type, exc_value, traceback):
43 L("Exiting, cleanup handler"); 39 L("Exiting, cleanup handler");
44 self.fridge.off() 40 self.fridge.off()
48 if self.fridge is None: 44 if self.fridge is None:
49 raise Exception("Tempserver.run() must be within 'with Tempserver() as server'") 45 raise Exception("Tempserver.run() must be within 'with Tempserver() as server'")
50 46
51 # XXX do these go here or in __enter_() ? 47 # XXX do these go here or in __enter_() ?
52 self.start_time = self.now() 48 self.start_time = self.now()
53 self.fridge.start() 49 tasks = (
54 self.sensors.start() 50 self.fridge.run(),
55 self.uploader.start() 51 self.sensors.run(),
56 52 self.uploader.run(),
57 # won't return. 53 )
58 while True: 54 loop = asyncio.get_event_loop()
59 try: 55 try:
60 gevent.sleep(60) 56 loop.run_until_complete(asyncio.wait(tasks))
61 except KeyboardInterrupt: 57 # not reached
62 break 58 except KeyboardInterrupt:
59 pass
63 60
64 def now(self): 61 def now(self):
65 return utils.monotonic_time() 62 return utils.monotonic_time()
66 63
67 def set_sensors(self, sensors): 64 def set_sensors(self, sensors):
95 """ returns (wort_temp, fridge_temp) tuple """ 92 """ returns (wort_temp, fridge_temp) tuple """
96 return self.current 93 return self.current
97 94
98 def sleep(self, timeout): 95 def sleep(self, timeout):
99 """ sleeps for timeout seconds, though wakes if the server's config is updated """ 96 """ sleeps for timeout seconds, though wakes if the server's config is updated """
100 self._wakeup.wait(timeout) 97 asyncio.wait_for(self._wakeup, timeout=timeout)
101 98
102 def _reload_signal(self): 99 def _reload_signal(self):
103 try: 100 try:
104 self.params.load() 101 self.params.load()
105 L("Reloaded.") 102 L("Reloaded.")