summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen West <bewest@gmail.com>2016-05-28 12:33:34 -0700
committerBen West <bewest@gmail.com>2016-05-28 12:33:34 -0700
commit576055c91970b6e15e08bb8905c4198ee57aedd8 (patch)
tree274ce4874b577b7f7991cd1afcee664c5898e9b2
parentcf10d70fe0c724286d6e84c869d63eefd077e331 (diff)
parentea9d852533facf323f251196821c7346e743074c (diff)
Merge pull request #6 from openaps/wip/g5
Wip/g5
-rw-r--r--dexcom_reader/database_records.py22
-rw-r--r--dexcom_reader/readdata.py26
2 files changed, 43 insertions, 5 deletions
diff --git a/dexcom_reader/database_records.py b/dexcom_reader/database_records.py
index 6d5b37b..9274d24 100644
--- a/dexcom_reader/database_records.py
+++ b/dexcom_reader/database_records.py
@@ -103,12 +103,16 @@ class InsertionRecord(GenericTimestampedRecord):
103 def session_state(self): 103 def session_state(self):
104 states = [None, 'REMOVED', 'EXPIRED', 'RESIDUAL_DEVIATION', 104 states = [None, 'REMOVED', 'EXPIRED', 'RESIDUAL_DEVIATION',
105 'COUNTS_DEVIATION', 'SECOND_SESSION', 'OFF_TIME_LOSS', 105 'COUNTS_DEVIATION', 'SECOND_SESSION', 'OFF_TIME_LOSS',
106 'STARTED', 'BAD_TRANSMITTER', 'MANUFACTURING_MODE'] 106 'STARTED', 'BAD_TRANSMITTER', 'MANUFACTURING_MODE',
107 'UNKNOWN1', 'UNKNOWN2', 'UNKNOWN3', 'UNKNOWN4', 'UNKNOWN5',
108 'UNKNOWN6', 'UNKNOWN7', 'UNKNOWN8']
107 return states[ord(self.data[3])] 109 return states[ord(self.data[3])]
108 110
109 def __repr__(self): 111 def __repr__(self):
110 return '%s: state=%s' % (self.display_time, self.session_state) 112 return '%s: state=%s' % (self.display_time, self.session_state)
111 113
114class G5InsertionRecord (InsertionRecord):
115 FORMAT = '<3Ic10BH'
112 116
113class Calibration(GenericTimestampedRecord): 117class Calibration(GenericTimestampedRecord):
114 FORMAT = '<2Iddd3cdb' 118 FORMAT = '<2Iddd3cdb'
@@ -182,6 +186,12 @@ class Calibration(GenericTimestampedRecord):
182 def crc(self): 186 def crc(self):
183 return struct.unpack('H', self.raw_data[-2:])[0] 187 return struct.unpack('H', self.raw_data[-2:])[0]
184 188
189class LegacyCalibration (Calibration):
190 @classmethod
191 def _ClassSize(cls):
192
193 return cls.LEGACY_SIZE
194
185 195
186class SubCal (GenericTimestampedRecord): 196class SubCal (GenericTimestampedRecord):
187 FORMAT = '<IIIIc' 197 FORMAT = '<IIIIc'
@@ -219,6 +229,8 @@ class MeterRecord(GenericTimestampedRecord):
219 def __repr__(self): 229 def __repr__(self):
220 return '%s: Meter BG:%s' % (self.display_time, self.meter_glucose) 230 return '%s: Meter BG:%s' % (self.display_time, self.meter_glucose)
221 231
232class G5MeterRecord (MeterRecord):
233 FORMAT = '<2IHI5BH'
222 234
223class EventRecord(GenericTimestampedRecord): 235class EventRecord(GenericTimestampedRecord):
224 # sys_time,display_time,glucose,meter_time,crc 236 # sys_time,display_time,glucose,meter_time,crc
@@ -316,3 +328,11 @@ class EGVRecord(GenericTimestampedRecord):
316 else: 328 else:
317 return '%s: CGM BG:%s (%s) DO:%s' % (self.display_time, self.glucose, 329 return '%s: CGM BG:%s (%s) DO:%s' % (self.display_time, self.glucose,
318 self.trend_arrow, self.display_only) 330 self.trend_arrow, self.display_only)
331
332class G5EGVRecord (EGVRecord):
333 FORMAT = '<2IHBBBBBBBBBcBH'
334 @property
335 def full_trend(self):
336 return self.data[12]
337
338
diff --git a/dexcom_reader/readdata.py b/dexcom_reader/readdata.py
index 5e91499..0f20e71 100644
--- a/dexcom_reader/readdata.py
+++ b/dexcom_reader/readdata.py
@@ -266,17 +266,21 @@ class Dexcom(object):
266 for x in xrange(header[1]): 266 for x in xrange(header[1]):
267 yield record_type.Create(data, x) 267 yield record_type.Create(data, x)
268 268
269 def ParsePage(self, header, data): 269 PARSER_MAP = {
270 record_type = constants.RECORD_TYPES[ord(header[2])]
271 revision = int(header[3])
272 generic_parser_map = {
273 'USER_EVENT_DATA': database_records.EventRecord, 270 'USER_EVENT_DATA': database_records.EventRecord,
274 'METER_DATA': database_records.MeterRecord, 271 'METER_DATA': database_records.MeterRecord,
275 'CAL_SET': database_records.Calibration, 272 'CAL_SET': database_records.Calibration,
273 # 'CAL_SET': database_records.Calibration,
276 'INSERTION_TIME': database_records.InsertionRecord, 274 'INSERTION_TIME': database_records.InsertionRecord,
277 'EGV_DATA': database_records.EGVRecord, 275 'EGV_DATA': database_records.EGVRecord,
278 'SENSOR_DATA': database_records.SensorRecord, 276 'SENSOR_DATA': database_records.SensorRecord,
279 } 277 }
278 def ParsePage(self, header, data):
279 record_type = constants.RECORD_TYPES[ord(header[2])]
280 revision = int(header[3])
281 generic_parser_map = self.PARSER_MAP
282 if revision < 2 and record_type == 'CAL_SET':
283 generic_parser_map.update(CAL_SET=database_records.LegacyCalibration)
280 xml_parsed = ['PC_SOFTWARE_PARAMETER', 'MANUFACTURING_DATA'] 284 xml_parsed = ['PC_SOFTWARE_PARAMETER', 'MANUFACTURING_DATA']
281 if record_type in generic_parser_map: 285 if record_type in generic_parser_map:
282 return self.GenericRecordYielder(header, data, 286 return self.GenericRecordYielder(header, data,
@@ -310,6 +314,20 @@ class Dexcom(object):
310 records.extend(self.ReadDatabasePage(record_type, x)) 314 records.extend(self.ReadDatabasePage(record_type, x))
311 return records 315 return records
312 316
317class DexcomG5 (Dexcom):
318 PARSER_MAP = {
319 'USER_EVENT_DATA': database_records.EventRecord,
320 'METER_DATA': database_records.G5MeterRecord,
321 'CAL_SET': database_records.Calibration,
322 'INSERTION_TIME': database_records.G5InsertionRecord,
323 'EGV_DATA': database_records.G5EGVRecord,
324 'SENSOR_DATA': database_records.SensorRecord,
325 }
326
327def GetDevice (port, G5=False):
328 if G5:
329 return DexcomG5(port)
330 return Dexcom(port)
313 331
314if __name__ == '__main__': 332if __name__ == '__main__':
315 Dexcom.LocateAndDownload() 333 Dexcom.LocateAndDownload()