From e6d903b2572ec8a6316ccc318fa2800d9d85904d Mon Sep 17 00:00:00 2001 From: Ben West Date: Sun, 29 May 2016 12:32:10 -0700 Subject: [PATCH 1/8] release dexcom_reader 0.1.9 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 981d5cc..760bb72 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.9', # http://semver.org/ description='Audit, and inspect data from Dexcom G4.', long_description=readme(), author="Will Nowak", From 77cb93fbaf6f5e3bbf00e14a9e8d35927bc0ade0 Mon Sep 17 00:00:00 2001 From: Ben West Date: Sun, 29 May 2016 12:33:39 -0700 Subject: [PATCH 2/8] stub out dev area post release 0.1.9 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 760bb72..928472b 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def readme(): return f.read() setup(name='dexcom_reader', - version='0.1.9', # http://semver.org/ + version='0.1.10-dev', # http://semver.org/ description='Audit, and inspect data from Dexcom G4.', long_description=readme(), author="Will Nowak", From fe8929c2823224b4fa32e547b80672a0fb47f442 Mon Sep 17 00:00:00 2001 From: Ben West Date: Sun, 5 Jun 2016 16:36:37 -0700 Subject: [PATCH 3/8] ditch installing to /etc/udev/rules.d on install Causes issues in virtualenv based environments like readthedocs. --- setup.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 928472b..eb01455 100644 --- a/setup.py +++ b/setup.py @@ -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, From a907db7671f27c91c72a1919477621ac81764458 Mon Sep 17 00:00:00 2001 From: Ben West Date: Sun, 5 Jun 2016 16:41:15 -0700 Subject: [PATCH 4/8] release dexcom_reader 0.1.10 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index eb01455..ccd42b5 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ def readme(): return f.read() setup(name='dexcom_reader', - version='0.1.10-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", From 9280b87b68f9eeaf22b6e0326eede8334e12ae9a Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Mon, 26 Dec 2016 17:20:29 -0500 Subject: [PATCH 5/8] new ReadRecords() parameter specifies number of pages of records to read --- dexcom_reader/readdata.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dexcom_reader/readdata.py b/dexcom_reader/readdata.py index 0f20e71..d60188b 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 From 2191eb46e95577202a6231723f729ac56652cce6 Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Mon, 26 Dec 2016 17:20:59 -0500 Subject: [PATCH 6/8] readdata.py supports --g5 and --g4 options --- dexcom_reader/readdata.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/dexcom_reader/readdata.py b/dexcom_reader/readdata.py index d60188b..5e2436b 100644 --- a/dexcom_reader/readdata.py +++ b/dexcom_reader/readdata.py @@ -332,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() From 576680f0f82ca5bb099b0c94ee8e081f98b3e0a2 Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Mon, 26 Dec 2016 17:21:19 -0500 Subject: [PATCH 7/8] new command: dexcom_dumper.py --- dexcom_reader/dexcom_dumper.py | 44 ++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 dexcom_reader/dexcom_dumper.py 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 From 8430d28295cc18fc32a86f344ab9bdcbe85cc402 Mon Sep 17 00:00:00 2001 From: Andrew Cady Date: Mon, 26 Dec 2016 17:55:12 -0500 Subject: [PATCH 8/8] update README with example of dexcom_dumper.py --- README.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 10 deletions(-) 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