Mercurial > templog
comparison py/sensor_ds18b20.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 | 185621f47040 |
comparison
equal
deleted
inserted
replaced
227:efb5cad2e98b | 228:d9e81a563923 |
---|---|
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 |