diff --git a/README.md b/README.md index 9cb44c3..eb3cbb6 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,54 @@ connected to a computer with USB. Out of the box dumps data like: -% python readdata.py -Found Dexcom G4 Receiver S/N: SMXXXXXXXX -Transmitter paired: 6XXXXX -Battery Status: CHARGING (83%) - Record count: - - Meter records: 340 - - CGM records: 3340 - - CGM commitable records: 3340 - - Event records: 15 - - Insertion records: 4 + % python readdata.py + Found Dexcom G4 Receiver S/N: SMXXXXXXXX + Transmitter paired: 6XXXXX + Battery Status: CHARGING (83%) + Record count: + - Meter records: 340 + - CGM records: 3340 + - CGM commitable records: 3340 + - Event records: 15 + - Insertion records: 4 + +Or like: + + % python dexcom_reader/dexcom_dumper.py --g5 -n2 + 2016-12-26 15:47:47: CGM BG:133 (FLAT) DO:False + 2016-12-26 15:52:45: CGM BG:127 (FLAT) DO:False + 2016-12-26 15:57:44: CGM BG:120 (FLAT) DO:False + 2016-12-26 16:02:44: CGM BG:116 (45_DOWN) DO:False + 2016-12-26 16:07:44: CGM BG:112 (45_DOWN) DO:False + 2016-12-26 16:12:44: CGM BG:113 (FLAT) DO:False + 2016-12-26 16:17:45: CGM BG:109 (FLAT) DO:False + 2016-12-26 16:22:51: CGM BG:102 (FLAT) DO:False + 2016-12-26 16:27:44: CGM BG:92 (45_DOWN) DO:False + 2016-12-26 16:32:44: CGM BG:86 (45_DOWN) DO:False + 2016-12-26 16:37:44: CGM BG:75 (45_DOWN) DO:False + 2016-12-26 16:42:44: CGM BG:63 (SINGLE_DOWN) DO:False + 2016-12-26 16:47:44: CGM BG:55 (SINGLE_DOWN) DO:False + 2016-12-26 16:52:44: CGM BG:52 (45_DOWN) DO:False + 2016-12-26 16:57:44: CGM BG:53 (FLAT) DO:False + 2016-12-26 17:02:44: CGM BG:60 (FLAT) DO:False + 2016-12-26 17:07:44: CGM BG:85 (SINGLE_UP) DO:False + 2016-12-26 17:12:44: CGM BG:107 (DOUBLE_UP) DO:False + 2016-12-26 17:17:44: CGM BG:121 (DOUBLE_UP) DO:False + 2016-12-26 17:22:44: CGM BG:131 (DOUBLE_UP) DO:False + 2016-12-26 17:27:45: CGM BG:144 (SINGLE_UP) DO:False + 2016-12-26 17:32:44: CGM BG:149 (45_UP) DO:False + 2016-12-26 17:37:44: CGM BG:153 (45_UP) DO:False + 2016-12-26 17:42:52: CGM BG:165 (45_UP) DO:False + 2016-12-26 17:47:55: CGM BG:176 (45_UP) DO:False + +See also: + + % python dexcom_reader/dexcom_dumper.py --help + Usage: dexcom_dumper.py [options] + + Options: + -h, --help show this help message and exit + --g4 use Dexcom G4 instead of Dexcom G5 + --g5 use Dexcom G5 instead of Dexcom G4 + -a, --all dump all available records + -n NUM_RECORDS number of pages of CGM records to display diff --git a/dexcom_reader/dexcom_dumper.py b/dexcom_reader/dexcom_dumper.py new file mode 100644 index 0000000..f0bac36 --- /dev/null +++ b/dexcom_reader/dexcom_dumper.py @@ -0,0 +1,44 @@ +import constants +import readdata + +from optparse import OptionParser + +G5_IS_DEFAULT = True +DEFAULT_PAGE_COUNT = 2 + +parser = OptionParser() +parser.add_option("--g4", action="store_false", dest="g5", default=G5_IS_DEFAULT, help="use Dexcom G4 instead of Dexcom G5") +parser.add_option("--g5", action="store_true", dest="g5", default=G5_IS_DEFAULT, help="use Dexcom G5 instead of Dexcom G4") +parser.add_option("-a", "--all", action="store_true", dest="dump_everything", default=False, help="dump all available records") +parser.add_option("-n", type="int", dest="num_records", default=DEFAULT_PAGE_COUNT, help="number of pages of CGM records to display") + +(options, args) = parser.parse_args() + +def get_dexcom_reader(): + if options.g5: + dd = readdata.DexcomG5.FindDevice() + return readdata.DexcomG5(dd) + else: + dd = readdata.Dexcom.FindDevice() + return readdata.Dexcom(dd) + +dr = get_dexcom_reader() + +if options.dump_everything: + +# record_types = ['METER_DATA', 'INSERTION_TIME', 'USER_EVENT_DATA', 'CAL_SET', 'SENSOR_DATA'] + + unparseable = ['FIRMWARE_PARAMETER_DATA', 'RECEIVER_LOG_DATA', 'USER_SETTING_DATA', 'MAX_VALUE'] + parsed_to_xml = ['MANUFACTURING_DATA', 'PC_SOFTWARE_PARAMETER'] + skip = unparseable + parsed_to_xml + ['EGV_DATA'] + record_types = filter(lambda v: not v in skip, constants.RECORD_TYPES) + + for t in record_types: + print t + ":" + for r in dr.ReadRecords(t): + print r + +cgm_records = dr.ReadRecords('EGV_DATA', 0 if options.dump_everything else options.num_records) +for cr in cgm_records: + if not cr.display_only: + print cr diff --git a/dexcom_reader/readdata.py b/dexcom_reader/readdata.py index 0f20e71..5e2436b 100644 --- a/dexcom_reader/readdata.py +++ b/dexcom_reader/readdata.py @@ -303,13 +303,15 @@ def iter_records (self, record_type): for record in records: yield record - def ReadRecords(self, record_type): + def ReadRecords(self, record_type, n=0): records = [] assert record_type in constants.RECORD_TYPES page_range = self.ReadDatabasePageRange(record_type) start, end = page_range if start != end or not end: end += 1 + if n>0 and end - n > start: + start = end - n for x in range(start, end): records.extend(self.ReadDatabasePage(record_type, x)) return records @@ -330,4 +332,18 @@ def GetDevice (port, G5=False): return Dexcom(port) if __name__ == '__main__': - Dexcom.LocateAndDownload() + + from optparse import OptionParser + + G5_IS_DEFAULT = False + + parser = OptionParser() + parser.add_option("--g4", action="store_false", dest="g5", default=G5_IS_DEFAULT, help="use Dexcom G4 instead of Dexcom G5") + parser.add_option("--g5", action="store_true", dest="g5", default=G5_IS_DEFAULT, help="use Dexcom G5 instead of Dexcom G4") + + (options, args) = parser.parse_args() + + if options.g5: + DexcomG5.LocateAndDownload() + else: + Dexcom.LocateAndDownload() diff --git a/setup.py b/setup.py index 981d5cc..ccd42b5 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def readme(): return f.read() setup(name='dexcom_reader', - version='0.1.9-dev', # http://semver.org/ + version='0.1.10', # http://semver.org/ description='Audit, and inspect data from Dexcom G4.', long_description=readme(), author="Will Nowak", @@ -35,7 +35,9 @@ def readme(): 'dexcom_reader': ['etc/udev/rules.d/*'] }, data_files = [ - ('/etc/udev/rules.d', ['dexcom_reader/etc/udev/rules.d/80-dexcom.rules'] ), + # installing to system locations breaks things for virtualenv based + # environments. + # ('/etc/udev/rules.d', ['dexcom_reader/etc/udev/rules.d/80-dexcom.rules'] ), ], zip_safe=False,