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