Skip to content

Commit cf10d70

Browse files
committed
support fetching cal_set
Many thanks to @LorelaiL for putting up with some my remedial questions.
1 parent ff9e632 commit cf10d70

File tree

2 files changed

+91
-3
lines changed

2 files changed

+91
-3
lines changed

dexcom_reader/database_records.py

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,99 @@ def __repr__(self):
111111

112112

113113
class Calibration(GenericTimestampedRecord):
114+
FORMAT = '<2Iddd3cdb'
115+
# CAL_FORMAT = '<2Iddd3cdb'
116+
FIELDS = [ 'slope', 'intercept', 'scale', 'decay', 'numsub', 'raw' ]
114117
@property
115-
def raw(self):
116-
return binascii.hexlify(bytearray(self.data))
118+
def raw (self):
119+
return binascii.hexlify(self.raw_data)
120+
@property
121+
def slope (self):
122+
return self.data[2]
123+
@property
124+
def intercept (self):
125+
return self.data[3]
126+
@property
127+
def scale (self):
128+
return self.data[4]
129+
@property
130+
def decay (self):
131+
return self.data[8]
132+
@property
133+
def numsub (self):
134+
return int(self.data[9])
117135

118136
def __repr__(self):
119137
return '%s: CAL SET:%s' % (self.display_time, self.raw)
120138

139+
LEGACY_SIZE = 148
140+
REV_2_SIZE = 249
141+
@classmethod
142+
def _ClassSize(cls):
143+
144+
return cls.REV_2_SIZE
145+
146+
@classmethod
147+
def Create(cls, data, record_counter):
148+
offset = record_counter * cls._ClassSize()
149+
cal_size = struct.calcsize(cls.FORMAT)
150+
raw_data = data[offset:offset + cls._ClassSize()]
151+
152+
cal_data = data[offset:offset + cal_size]
153+
unpacked_data = cls._ClassFormat().unpack(cal_data)
154+
return cls(unpacked_data, raw_data)
155+
156+
def __init__ (self, data, raw_data):
157+
self.page_data = raw_data
158+
self.raw_data = raw_data
159+
self.data = data
160+
subsize = struct.calcsize(SubCal.FORMAT)
161+
offset = self.numsub * subsize
162+
calsize = struct.calcsize(self.FORMAT)
163+
caldata = raw_data[:calsize]
164+
subdata = raw_data[calsize:calsize + offset]
165+
crcdata = raw_data[calsize+offset:calsize+offset+2]
166+
167+
subcals = [ ]
168+
for i in xrange(self.numsub):
169+
offset = i * subsize
170+
raw_sub = subdata[offset:offset+subsize]
171+
sub = SubCal(raw_sub, self.data[1])
172+
subcals.append(sub)
173+
174+
self.subcals = subcals
175+
176+
self.check_crc()
177+
def to_dict (self):
178+
res = super(Calibration, self).to_dict( )
179+
res['subrecords'] = [ sub.to_dict( ) for sub in self.subcals ]
180+
return res
181+
@property
182+
def crc(self):
183+
return struct.unpack('H', self.raw_data[-2:])[0]
184+
185+
186+
class SubCal (GenericTimestampedRecord):
187+
FORMAT = '<IIIIc'
188+
BASE_FIELDS = [ ]
189+
FIELDS = [ 'entered', 'meter', 'sensor', 'applied', ]
190+
def __init__ (self, raw_data, displayOffset=None):
191+
self.raw_data = raw_data
192+
self.data = self._ClassFormat().unpack(raw_data)
193+
self.displayOffset = displayOffset
194+
@property
195+
def entered (self):
196+
return util.ReceiverTimeToTime(self.data[0])
197+
@property
198+
def meter (self):
199+
return int(self.data[1])
200+
@property
201+
def sensor (self):
202+
return int(self.data[2])
203+
@property
204+
def applied (self):
205+
return util.ReceiverTimeToTime(self.data[3])
206+
121207
class MeterRecord(GenericTimestampedRecord):
122208
FORMAT = '<2IHIH'
123209
FIELDS = ['meter_glucose', 'meter_time' ]

dexcom_reader/readdata.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ def ReadDatabasePage(self, record_type, page):
251251
assert ord(packet.command) == 1
252252
# first index (uint), numrec (uint), record_type (byte), revision (byte),
253253
# page# (uint), r1 (uint), r2 (uint), r3 (uint), ushort (Crc)
254-
header_format = '<2I2c4IH'
254+
header_format = '<2IcB4IH'
255255
header_data_len = struct.calcsize(header_format)
256256
header = struct.unpack_from(header_format, packet.data)
257257
header_crc = crc16.crc16(packet.data[:header_data_len-2])
@@ -268,9 +268,11 @@ def GenericRecordYielder(self, header, data, record_type):
268268

269269
def ParsePage(self, header, data):
270270
record_type = constants.RECORD_TYPES[ord(header[2])]
271+
revision = int(header[3])
271272
generic_parser_map = {
272273
'USER_EVENT_DATA': database_records.EventRecord,
273274
'METER_DATA': database_records.MeterRecord,
275+
'CAL_SET': database_records.Calibration,
274276
'INSERTION_TIME': database_records.InsertionRecord,
275277
'EGV_DATA': database_records.EGVRecord,
276278
'SENSOR_DATA': database_records.SensorRecord,

0 commit comments

Comments
 (0)