comparison py/sensor_ds18b20.py @ 527:dd8895652485

porting to asyncio
author Matt Johnston <matt@ucc.asn.au>
date Fri, 20 Mar 2015 20:12:25 +0800
parents 0b5ff341d124
children 185621f47040
comparison
equal deleted inserted replaced
526:1f25c9d97111 527:dd8895652485
1 #!/usr/bin/env python2.7 1 #!/usr/bin/env python2.7
2 2
3 import os 3 import os
4 import re 4 import re
5 5 import asyncio
6 import gevent 6 import concurrent.futures
7 import gevent.threadpool
8 7
9 import config 8 import config
10 from utils import D,L,W,E,EX 9 from utils import D,L,W,E,EX
11 10
12 class DS18B20s(gevent.Greenlet): 11 class DS18B20s(object):
13 12
14 THERM_RE = re.compile('.* YES\n.*t=(.*)\n', re.MULTILINE) 13 THERM_RE = re.compile('.* YES\n.*t=(.*)\n', re.MULTILINE)
15 14
16 def __init__(self, server): 15 def __init__(self, server):
17 gevent.Greenlet.__init__(self)
18 self.server = server 16 self.server = server
19 self.readthread = gevent.threadpool.ThreadPool(1) 17 self.readthread = concurrent.futures.ThreadPoolExecutor(max_workers=1)
20 self.master_dir = config.SENSOR_BASE_DIR 18 self.master_dir = config.SENSOR_BASE_DIR
21 19
20 @asyncio.coroutine
22 def do(self): 21 def do(self):
23 vals = {} 22 vals = {}
24 for n in self.sensor_names(): 23 for n in self.sensor_names():
25 value = self.do_sensor(n) 24 value = yield from self.do_sensor(n)
26 if value is not None: 25 if value is not None:
27 vals[n] = value 26 vals[n] = value
28 27
29 itemp = self.do_internal() 28 itemp = self.do_internal()
30 if itemp: 29 if itemp:
31 vals['internal'] = itemp 30 vals['internal'] = itemp
32 31
33 self.server.add_reading(vals) 32 self.server.add_reading(vals)
34 33
35 def _run(self): 34 @asyncio.coroutine
35 def run(self):
36 while True: 36 while True:
37 self.do() 37 yield from self.do()
38 self.server.sleep(config.SENSOR_SLEEP) 38 yield from self.server.sleep(config.SENSOR_SLEEP)
39 39
40 @asyncio.coroutine
40 def read_wait(self, f): 41 def read_wait(self, f):
41 # handles a blocking file read with a gevent threadpool. A 42 # handles a blocking file read with a threadpool. A
42 # real python thread performs the read while other gevent 43 # real python thread performs the read while other
43 # greenlets keep running. 44 # asyncio tasks keep running.
44 # the ds18b20 takes ~750ms to read, which is noticable 45 # the ds18b20 takes ~750ms to read, which is noticable
45 # interactively. 46 # interactively.
46 return self.readthread.apply(f.read) 47 loop = asyncio.get_event_loop()
48 yield from loop.run_in_executor(self.readthread, f.read)
47 49
50 @asyncio.coroutine
48 def do_sensor(self, s, contents = None): 51 def do_sensor(self, s, contents = None):
49 """ contents can be set by the caller for testing """ 52 """ contents can be set by the caller for testing """
50 try: 53 try:
51 if contents is None: 54 if contents is None:
52 fn = os.path.join(self.master_dir, s, 'w1_slave') 55 fn = os.path.join(self.master_dir, s, 'w1_slave')
53 f = open(fn, 'r') 56 f = open(fn, 'r')
54 contents = self.read_wait(f) 57 contents = yield from self.read_wait(f)
55 58
56 match = self.THERM_RE.match(contents) 59 match = self.THERM_RE.match(contents)
57 if match is None: 60 if match is None:
58 D("no match") 61 D("no match")
59 return None 62 return None