diff options
author | Ben West <bewest@gmail.com> | 2016-05-28 12:33:34 -0700 |
---|---|---|
committer | Ben West <bewest@gmail.com> | 2016-05-28 12:33:34 -0700 |
commit | 576055c91970b6e15e08bb8905c4198ee57aedd8 (patch) | |
tree | 274ce4874b577b7f7991cd1afcee664c5898e9b2 | |
parent | cf10d70fe0c724286d6e84c869d63eefd077e331 (diff) | |
parent | ea9d852533facf323f251196821c7346e743074c (diff) |
Merge pull request #6 from openaps/wip/g5
Wip/g5
-rw-r--r-- | dexcom_reader/database_records.py | 22 | ||||
-rw-r--r-- | dexcom_reader/readdata.py | 26 |
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 | ||
114 | class G5InsertionRecord (InsertionRecord): | ||
115 | FORMAT = '<3Ic10BH' | ||
112 | 116 | ||
113 | class Calibration(GenericTimestampedRecord): | 117 | class 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 | ||
189 | class LegacyCalibration (Calibration): | ||
190 | @classmethod | ||
191 | def _ClassSize(cls): | ||
192 | |||
193 | return cls.LEGACY_SIZE | ||
194 | |||
185 | 195 | ||
186 | class SubCal (GenericTimestampedRecord): | 196 | class 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 | ||
232 | class G5MeterRecord (MeterRecord): | ||
233 | FORMAT = '<2IHI5BH' | ||
222 | 234 | ||
223 | class EventRecord(GenericTimestampedRecord): | 235 | class 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 | |||
332 | class 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 | ||
317 | class 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 | |||
327 | def GetDevice (port, G5=False): | ||
328 | if G5: | ||
329 | return DexcomG5(port) | ||
330 | return Dexcom(port) | ||
313 | 331 | ||
314 | if __name__ == '__main__': | 332 | if __name__ == '__main__': |
315 | Dexcom.LocateAndDownload() | 333 | Dexcom.LocateAndDownload() |