summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@jerkface.net>2017-01-27 07:55:49 +0000
committerAndrew Cady <d@jerkface.net>2017-01-27 07:55:49 +0000
commit1dbf49a63d126e63e15d5e426e1faf2140b97c5d (patch)
treee89d9f8e515b1f2857b1367bedbab8b9090a514f
parentc60a203b350272c08d7bcc0d31bce43e7cd825db (diff)
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.
-rw-r--r--dexcom_reader/dexcom_dumper.py109
1 files 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):
81 now = dr.ReadSystemTime() 81 now = dr.ReadSystemTime()
82 return t.system_time > now - timedelta(minutes=5) 82 return t.system_time > now - timedelta(minutes=5)
83 83
84def print_verbose(s): 84def print_verbose(s, newline=True):
85 global VERBOSE 85 global VERBOSE
86 if VERBOSE: 86 if VERBOSE:
87 stderr.write('%s\n' % str(s)) 87 stderr.write('%s%s' % (str(s), '\n' if newline else ''))
88 88
89def read_recent_egv_data(): 89def read_recent_egv_data():
90 try: 90 global dr
91 r = dr.ReadRecords('EGV_DATA', 1)[-1] 91 try:
92 if recent(r) and not r.is_special and not r.display_only: 92 now = dr.ReadSystemTime()
93 return r 93 r = dr.ReadRecords('EGV_DATA', 1)[-1]
94 else: 94 if recent(r) and not r.is_special and not r.display_only:
95 return None 95 return (r, now)
96 except ValueError as v: 96 else:
97 if (v.args[0] == 'Attempting to use a port that is not open'): 97 return (None, now)
98 return False 98 except ValueError as v:
99 else: 99 if (v.args[0] != 'Attempting to use a port that is not open'):
100 print_verbose(v) 100 print_verbose(v)
101 return None 101 dr = get_dexcom_reader()
102 except: 102 except:
103 print_verbose(sys.exc_info) 103 print_verbose(sys.exc_info())
104 return None 104 return (None, None)
105 105
106def time_fmt(t): 106def time_fmt(t):
107 global HUMAN 107 global HUMAN
@@ -128,10 +128,20 @@ def sleep_verbose(n):
128 print_verbose('sleep(%d)' % n) 128 print_verbose('sleep(%d)' % n)
129 sleep(n) 129 sleep(n)
130 130
131imported_requests = None
132def import_requests():
133 global imported_requests
134 if not imported_requests:
135 print_verbose("Loading 'requests' HTTP client library... ", newline=False)
136 import requests
137 print_verbose("done.")
138 imported_requests = requests
139 return imported_requests
140
131def POST(path, json_str): 141def POST(path, json_str):
132 msg = None 142 msg = None
133 try: 143 try:
134 import requests 144 requests = import_requests()
135 resp = requests.post(HOST + path, data=json_str, 145 resp = requests.post(HOST + path, data=json_str,
136 headers={'Content-type': 'application/json'}) 146 headers={'Content-type': 'application/json'})
137 msg = resp.text 147 msg = resp.text
@@ -149,9 +159,7 @@ def send_ping(now):
149 159
150def print_cgm_bg(now, r): 160def print_cgm_bg(now, r):
151 if HOST: 161 if HOST:
152 r.trend_arrow.replace('45_', 'DIAGONAL_', 1) 162 remote_update('EGV_DATA')
153 if not r.is_special:
154 POST('/egv_data', toJSON(r))
155 send_ping(now) 163 send_ping(now)
156 return 164 return
157 elif JSON: 165 elif JSON:
@@ -163,61 +171,50 @@ def print_cgm_bg(now, r):
163def poll(): 171def poll():
164 print_localtime('dexcom_dumper started') 172 print_localtime('dexcom_dumper started')
165 while True: 173 while True:
166 r = read_recent_egv_data() 174 (r, now) = read_recent_egv_data()
167 if r is None: 175 if now is None:
168 connected(True)
169 if HOST:
170 now = dr.ReadSystemTime()
171 send_ping(now)
172 sleep_verbose(10)
173 elif r is False:
174 connected(False) 176 connected(False)
175 sleep_verbose(10) 177 sleep_verbose(10)
178 elif r is None:
179 connected(True)
180 send_ping(now)
181 sleep_verbose(10)
176 else: 182 else:
177 now = dr.ReadSystemTime() 183 connected(True)
178 print_cgm_bg(now, r) 184 print_cgm_bg(now, r)
179 next_reading = (r.system_time - now + timedelta(minutes=5, seconds=2)).total_seconds() 185 next_reading = (r.system_time - now + timedelta(minutes=5, seconds=2)).total_seconds()
180 if (next_reading > 0): 186 if (next_reading > 0):
181 sleep_verbose(next_reading) 187 sleep_verbose(next_reading)
182 188
183def since(when, rectype='EGV_DATA'): 189def since(when, rectype):
184 return reversed(list(takewhile(lambda r: r.system_time > when, dr.iter_records(rectype)))) 190 filt = lambda r: (r.system_time > when) if when else True
191 return reversed(list(takewhile(filt, dr.iter_records(rectype))))
185 192
186def parsetime(s): 193def parsetime(s):
187 return datetime.strptime(s, "%Y-%m-%dT%H:%M:%SZ") 194 return datetime.strptime(s, "%Y-%m-%dT%H:%M:%SZ")
188 195
189def test(): 196def remote_update(rectype):
190 now = dr.ReadSystemTime() 197 requests = import_requests()
191 POST('/ping', toJSON(now)) 198 url_path = '/' + rectype
192 199
193 import requests 200 resp = requests.get(HOST + url_path + '/1')
194 rectype = 'EGV_DATA'
195 resp = requests.get(HOST + '/egv_data/1')
196 resp.raise_for_status() 201 resp.raise_for_status()
197 rs = None 202 when = None
198 if len(resp.json()): 203 if len(resp.json()):
199 when = parsetime(resp.json()[0]['contents']['system_time']) 204 when = parsetime(resp.json()[0]['contents']['system_time'])
200 print when 205 print_verbose("Latest record on server: %s" % when.isoformat())
201 rs = list(since(when, rectype))
202 else:
203 #rs = list(reversed(list(dr.iter_records(rectype))))
204 now = dr.ReadSystemTime()
205 when = now - timedelta(days=5)
206 rs = list(since(when, rectype))
207 206
208 print len(rs) 207 rs = list(since(when, rectype))
209 print POST('/egv_datas', toJSON(rs)) 208 if len(rs):
209 print_verbose("Sending %d record%s... " % (len(rs), '' if len(rs) == 1 else 's'), newline=False)
210 print_verbose("done. (Result: %s)" % POST(url_path, toJSON(rs)))
210 211
211def test0(): 212def test():
212 now = dr.ReadSystemTime() 213 remote_update('EGV_DATA')
213 POST('/ping', toJSON(now))
214 214
215def test0():
215 for t in parseable_record_types(): 216 for t in parseable_record_types():
216 rs = dr.ReadRecords(t, 1) 217 remote_update(t)
217 if not rs:
218 continue
219 r=rs[-1]
220 print toJSON([t,r])
221 218
222class JSON_Time(json.JSONEncoder): 219class JSON_Time(json.JSONEncoder):
223 def default(self, o): 220 def default(self, o):