Mercurial > templog
annotate py/sensor_ds18b20.py @ 540:0f665a84b581
gevent doesn't work well with subprocess
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sun, 10 May 2015 21:13:49 +0800 |
parents | 5201f441bf4a |
children | 659953f2ee03 |
rev | line source |
---|---|
439 | 1 #!/usr/bin/env python2.7 |
2 | |
448
fe729664a5e6
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
447
diff
changeset
|
3 import os |
fe729664a5e6
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
447
diff
changeset
|
4 import re |
527 | 5 import asyncio |
6 import concurrent.futures | |
448
fe729664a5e6
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
447
diff
changeset
|
7 |
443 | 8 import config |
448
fe729664a5e6
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
447
diff
changeset
|
9 from utils import D,L,W,E,EX |
443 | 10 |
527 | 11 class DS18B20s(object): |
443 | 12 |
13 THERM_RE = re.compile('.* YES\n.*t=(.*)\n', re.MULTILINE) | |
439 | 14 |
443 | 15 def __init__(self, server): |
16 self.server = server | |
527 | 17 self.readthread = concurrent.futures.ThreadPoolExecutor(max_workers=1) |
447 | 18 self.master_dir = config.SENSOR_BASE_DIR |
443 | 19 |
527 | 20 @asyncio.coroutine |
449
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
21 def do(self): |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
22 vals = {} |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
23 for n in self.sensor_names(): |
527 | 24 value = yield from self.do_sensor(n) |
449
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
25 if value is not None: |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
26 vals[n] = value |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
27 |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
28 itemp = self.do_internal() |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
29 if itemp: |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
30 vals['internal'] = itemp |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
31 |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
32 self.server.add_reading(vals) |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
33 |
527 | 34 @asyncio.coroutine |
35 def run(self): | |
443 | 36 while True: |
527 | 37 yield from self.do() |
38 yield from self.server.sleep(config.SENSOR_SLEEP) | |
443 | 39 |
527 | 40 @asyncio.coroutine |
447 | 41 def read_wait(self, f): |
527 | 42 # handles a blocking file read with a threadpool. A |
43 # real python thread performs the read while other | |
44 # asyncio tasks keep running. | |
447 | 45 # the ds18b20 takes ~750ms to read, which is noticable |
46 # interactively. | |
527 | 47 loop = asyncio.get_event_loop() |
48 yield from loop.run_in_executor(self.readthread, f.read) | |
439 | 49 |
527 | 50 @asyncio.coroutine |
447 | 51 def do_sensor(self, s, contents = None): |
52 """ contents can be set by the caller for testing """ | |
443 | 53 try: |
54 if contents is None: | |
447 | 55 fn = os.path.join(self.master_dir, s, 'w1_slave') |
443 | 56 f = open(fn, 'r') |
527 | 57 contents = yield from self.read_wait(f) |
448
fe729664a5e6
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
447
diff
changeset
|
58 |
443 | 59 match = self.THERM_RE.match(contents) |
60 if match is None: | |
448
fe729664a5e6
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
447
diff
changeset
|
61 D("no match") |
443 | 62 return None |
448
fe729664a5e6
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
447
diff
changeset
|
63 temp = int(match.groups(1)[0]) / 1000.0 |
474 | 64 if temp > 80: |
65 E("Problem reading sensor '%s': %f" % (s, temp)) | |
66 return None | |
448
fe729664a5e6
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
447
diff
changeset
|
67 return temp |
529 | 68 except Exception as e: |
443 | 69 EX("Problem reading sensor '%s': %s" % (s, str(e))) |
70 return None | |
439 | 71 |
449
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
72 def do_internal(self): |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
73 try: |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
74 return int(open(config.INTERNAL_TEMPERATURE, 'r').read()) / 1000.0 |
529 | 75 except Exception as e: |
449
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
76 EX("Problem reading internal sensor: %s" % str(e)) |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
77 return None |
e99559bf188f
internal temperature sensor
Matt Johnston <matt@ucc.asn.au>
parents:
448
diff
changeset
|
78 |
443 | 79 |
80 def sensor_names(self): | |
81 """ Returns a sequence of sensorname """ | |
447 | 82 slaves_path = os.path.join(self.master_dir, "w1_master_slaves") |
477 | 83 contents = open(slaves_path, 'r').read() |
84 if 'not found' in contents: | |
85 E("No W1 sensors found") | |
86 return [] | |
87 names = contents.split() | |
448
fe729664a5e6
working better. logging works properly, cleanup fridge.off() happens.
Matt Johnston <matt@ucc.asn.au>
parents:
447
diff
changeset
|
88 return names |
439 | 89 |
90 def wort_name(self): | |
443 | 91 return config.WORT_NAME |
439 | 92 |
93 def fridge_name(self): | |
443 | 94 return config.FRIDGE_NAME |