summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2017-04-08 16:16:51 -0400
committerAndrew Cady <d@jerkface.net>2017-04-08 16:16:51 -0400
commit572aad546bb8ee9ccd095a2098e1b292176c53da (patch)
treee5b0dc38abfd61cc128b94e15c05820a45cb7396
parentba6cf9e875f28165fefd447d078771c989289eee (diff)
re-implement polling using "devicer" library
-rw-r--r--dexcom_reader/devicer.py72
-rwxr-xr-xdexcom_reader/dexcom_dumper.py61
2 files changed, 132 insertions, 1 deletions
diff --git a/dexcom_reader/devicer.py b/dexcom_reader/devicer.py
new file mode 100644
index 0000000..79a0a72
--- /dev/null
+++ b/dexcom_reader/devicer.py
@@ -0,0 +1,72 @@
1import pyudev
2import threading
3
4class DevicePoller:
5 def __init__(self, dev):
6 self.device_added = threading.Event()
7 self.device_removed = threading.Event()
8 self.device = dev
9 self.wait_add = self.device_added.wait
10 self.wait_remove = self.device_removed.wait
11 self.have = self.device_added.is_set
12
13 if dev:
14 self.device_added.set()
15
16 def launch_observer(self, monitor, device_match):
17
18 if not monitor:
19 monitor = pyudev.Monitor.from_netlink(pyudev.Context())
20
21 def handle_event(action, device):
22 if action == 'add' and device_match(device):
23 self.device = device
24 self.device_removed.clear()
25 self.device_added.set()
26 elif action == 'remove' and device == self.device:
27 self.device = None
28 self.device_added.clear()
29 self.device_removed.set()
30
31 self.observer = pyudev.MonitorObserver(monitor, handle_event)
32 self.observer.start()
33
34 def stop_observer():
35 self.observer.stop()
36
37def simple_devicer(subsystem, predicate):
38 dev = None
39 context = pyudev.Context()
40 for try_dev in context.list_devices(subsystem=subsystem):
41 if predicate(try_dev):
42 dev = try_dev
43 break
44
45 monitor = pyudev.Monitor.from_netlink(context)
46 monitor.filter_by(subsystem)
47
48 devicer = DevicePoller(dev)
49 devicer.launch_observer(monitor, predicate)
50
51 return devicer
52
53if __name__ == '__main__':
54
55 dexcom_g5_product = '22a3/47/100'
56
57 def is_dexcom_g5(dev):
58 try: return dev.parent.get('PRODUCT') == dexcom_g5_product
59 except: return False
60
61 devicer = simple_devicer('tty', is_dexcom_g5)
62
63 while True:
64 print("waiting for device")
65 devicer.wait_add()
66 while devicer.have():
67 print("poll device {0}".format(devicer.device))
68 print("sleep(5)")
69 if devicer.wait_remove(5):
70 print("device removed")
71
72 devicer.stop_observer()
diff --git a/dexcom_reader/dexcom_dumper.py b/dexcom_reader/dexcom_dumper.py
index be5b0d8..e7db00e 100755
--- a/dexcom_reader/dexcom_dumper.py
+++ b/dexcom_reader/dexcom_dumper.py
@@ -4,6 +4,7 @@ import readdata
4import sys 4import sys
5import json 5import json
6import traceback 6import traceback
7from devicer import simple_devicer
7# import requests # As this takes SEVEN SECONDS, it's delayed until needed 8# import requests # As this takes SEVEN SECONDS, it's delayed until needed
8from sys import stdout, stderr 9from sys import stdout, stderr
9from datetime import timedelta, datetime 10from datetime import timedelta, datetime
@@ -206,6 +207,64 @@ def poll_remote():
206 else: 207 else:
207 sleep_verbose(10) 208 sleep_verbose(10)
208 209
210def poll_remote_redux():
211 (n, r) = remote_update('EGV_DATA')
212 if n is None:
213 return 10
214 else:
215 now = dr.ReadSystemTime()
216 if n == 0:
217 send_ping(now)
218 if r:
219 for t in ['METER_DATA', 'INSERTION_TIME', 'USER_EVENT_DATA']:
220 # TODO: track how long this takes & adjust sleep accordingly
221 try:
222 remote_update(t)
223 except:
224 traceback.print_exc()
225 next_reading = (r.system_time - now + timedelta(minutes=5, seconds=2)).total_seconds()
226 return max(10, next_reading)
227 else:
228 return 10
229
230def poll_redux():
231 poll = poll_remote_redux
232
233 dexcom_g5_product = '22a3/47/100'
234
235 def is_dexcom_g5(dev):
236 try: return dev.parent.get('PRODUCT') == dexcom_g5_product
237 except: return False
238
239 devicer = simple_devicer('tty', is_dexcom_g5)
240
241 while True:
242 try:
243 print_verbose("Waiting for device.")
244 if not devicer.wait_add(600):
245 continue
246 print_verbose("Device found.")
247
248 global dr
249 if dr:
250 dr.Disconnect()
251 dr = readdata.DexcomG5(devicer.device.device_node)
252
253 print("Device opened.")
254 while devicer.have():
255 print_verbose("Polling device.")
256 try:
257 sleeptime = poll()
258 except:
259 sleeptime = 10
260
261 if devicer.wait_remove(sleeptime):
262 print_verbose("Device unplugged.")
263 dr.Disconnect()
264 dr = None
265 except KeyboardInterrupt:
266 break
267
209def poll_stdout(): 268def poll_stdout():
210 (r, now) = read_recent_egv_data() 269 (r, now) = read_recent_egv_data()
211 connected(True) 270 connected(True)
@@ -343,5 +402,5 @@ def toJSON(o):
343{"dump_everything": dump_everything, 402{"dump_everything": dump_everything,
344 "dump_cgm": dump_cgm, 403 "dump_cgm": dump_cgm,
345 "poll": poll, 404 "poll": poll,
346 "test": test, 405 "test": poll_redux,
347}[command]() 406}[command]()