From 1dbf49a63d126e63e15d5e426e1faf2140b97c5d Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Fri, 27 Jan 2017 07:55:49 +0000 Subject: Use synchronization instead of pushing updates When a BG reading needs to be pushed, the server is contacted to determine the latest BG reading it has. Then the Dexcom is queried to find all readings since that latest one. This could be made more efficient by avoiding double-querying the Dexcom. --- dexcom_reader/dexcom_dumper.py | 109 ++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 56 deletions(-) diff --git a/dexcom_reader/dexcom_dumper.py b/dexcom_reader/dexcom_dumper.py index 2694b83..f4cf7c5 100644 --- a/dexcom_reader/dexcom_dumper.py +++ b/dexcom_reader/dexcom_dumper.py @@ -81,27 +81,27 @@ def recent(t): now = dr.ReadSystemTime() return t.system_time > now - timedelta(minutes=5) -def print_verbose(s): +def print_verbose(s, newline=True): global VERBOSE if VERBOSE: - stderr.write('%s\n' % str(s)) + stderr.write('%s%s' % (str(s), '\n' if newline else '')) def read_recent_egv_data(): - try: - r = dr.ReadRecords('EGV_DATA', 1)[-1] - if recent(r) and not r.is_special and not r.display_only: - return r - else: - return None - except ValueError as v: - if (v.args[0] == 'Attempting to use a port that is not open'): - return False - else: - print_verbose(v) - return None - except: - print_verbose(sys.exc_info) - return None + global dr + try: + now = dr.ReadSystemTime() + r = dr.ReadRecords('EGV_DATA', 1)[-1] + if recent(r) and not r.is_special and not r.display_only: + return (r, now) + else: + return (None, now) + except ValueError as v: + if (v.args[0] != 'Attempting to use a port that is not open'): + print_verbose(v) + dr = get_dexcom_reader() + except: + print_verbose(sys.exc_info()) + return (None, None) def time_fmt(t): global HUMAN @@ -128,10 +128,20 @@ def sleep_verbose(n): print_verbose('sleep(%d)' % n) sleep(n) +imported_requests = None +def import_requests(): + global imported_requests + if not imported_requests: + print_verbose("Loading 'requests' HTTP client library... ", newline=False) + import requests + print_verbose("done.") + imported_requests = requests + return imported_requests + def POST(path, json_str): msg = None try: - import requests + requests = import_requests() resp = requests.post(HOST + path, data=json_str, headers={'Content-type': 'application/json'}) msg = resp.text @@ -149,9 +159,7 @@ def send_ping(now): def print_cgm_bg(now, r): if HOST: - r.trend_arrow.replace('45_', 'DIAGONAL_', 1) - if not r.is_special: - POST('/egv_data', toJSON(r)) + remote_update('EGV_DATA') send_ping(now) return elif JSON: @@ -163,61 +171,50 @@ def print_cgm_bg(now, r): def poll(): print_localtime('dexcom_dumper started') while True: - r = read_recent_egv_data() - if r is None: - connected(True) - if HOST: - now = dr.ReadSystemTime() - send_ping(now) - sleep_verbose(10) - elif r is False: + (r, now) = read_recent_egv_data() + if now is None: connected(False) sleep_verbose(10) + elif r is None: + connected(True) + send_ping(now) + sleep_verbose(10) else: - now = dr.ReadSystemTime() + connected(True) print_cgm_bg(now, r) next_reading = (r.system_time - now + timedelta(minutes=5, seconds=2)).total_seconds() if (next_reading > 0): sleep_verbose(next_reading) -def since(when, rectype='EGV_DATA'): - return reversed(list(takewhile(lambda r: r.system_time > when, dr.iter_records(rectype)))) +def since(when, rectype): + filt = lambda r: (r.system_time > when) if when else True + return reversed(list(takewhile(filt, dr.iter_records(rectype)))) def parsetime(s): return datetime.strptime(s, "%Y-%m-%dT%H:%M:%SZ") -def test(): - now = dr.ReadSystemTime() - POST('/ping', toJSON(now)) +def remote_update(rectype): + requests = import_requests() + url_path = '/' + rectype - import requests - rectype = 'EGV_DATA' - resp = requests.get(HOST + '/egv_data/1') + resp = requests.get(HOST + url_path + '/1') resp.raise_for_status() - rs = None + when = None if len(resp.json()): when = parsetime(resp.json()[0]['contents']['system_time']) - print when - rs = list(since(when, rectype)) - else: - #rs = list(reversed(list(dr.iter_records(rectype)))) - now = dr.ReadSystemTime() - when = now - timedelta(days=5) - rs = list(since(when, rectype)) + print_verbose("Latest record on server: %s" % when.isoformat()) - print len(rs) - print POST('/egv_datas', toJSON(rs)) + rs = list(since(when, rectype)) + if len(rs): + print_verbose("Sending %d record%s... " % (len(rs), '' if len(rs) == 1 else 's'), newline=False) + print_verbose("done. (Result: %s)" % POST(url_path, toJSON(rs))) -def test0(): - now = dr.ReadSystemTime() - POST('/ping', toJSON(now)) +def test(): + remote_update('EGV_DATA') +def test0(): for t in parseable_record_types(): - rs = dr.ReadRecords(t, 1) - if not rs: - continue - r=rs[-1] - print toJSON([t,r]) + remote_update(t) class JSON_Time(json.JSONEncoder): def default(self, o): -- cgit v1.2.3