summaryrefslogtreecommitdiffstats
path: root/glucometerutils
diff options
context:
space:
mode:
authorDiego Elio Pettenò <flameeyes@flameeyes.eu>2017-12-28 22:06:51 +0100
committerDiego Elio Pettenò <flameeyes@flameeyes.eu>2017-12-28 22:06:51 +0100
commit475fceae1d436bd6ecdc9aa465e204dec94c0fc9 (patch)
tree40e79879a9d0083ece96cecefdb9c7c61fc886f7 /glucometerutils
parentRemove misleading MANIFEST template. (diff)
downloadglucometerutils-475fceae1d436bd6ecdc9aa465e204dec94c0fc9.tar
glucometerutils-475fceae1d436bd6ecdc9aa465e204dec94c0fc9.tar.gz
glucometerutils-475fceae1d436bd6ecdc9aa465e204dec94c0fc9.tar.bz2
glucometerutils-475fceae1d436bd6ecdc9aa465e204dec94c0fc9.tar.lz
glucometerutils-475fceae1d436bd6ecdc9aa465e204dec94c0fc9.tar.xz
glucometerutils-475fceae1d436bd6ecdc9aa465e204dec94c0fc9.tar.zst
glucometerutils-475fceae1d436bd6ecdc9aa465e204dec94c0fc9.zip
Diffstat (limited to 'glucometerutils')
-rwxr-xr-xglucometerutils/glucometer.py147
1 files changed, 147 insertions, 0 deletions
diff --git a/glucometerutils/glucometer.py b/glucometerutils/glucometer.py
new file mode 100755
index 0000000..cd2331c
--- /dev/null
+++ b/glucometerutils/glucometer.py
@@ -0,0 +1,147 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+"""Utility to manage glucometers' data."""
+
+__author__ = 'Diego Elio Pettenò'
+__email__ = 'flameeyes@flameeyes.eu'
+__copyright__ = 'Copyright © 2013-2017, Diego Elio Pettenò'
+__license__ = 'MIT'
+
+import argparse
+import importlib
+import inspect
+import logging
+import sys
+
+from glucometerutils import common
+from glucometerutils import exceptions
+
+def main():
+ if sys.version_info < (3, 4):
+ raise Exception(
+ 'Unsupported Python version, please use at least Python 3.4')
+
+ parser = argparse.ArgumentParser()
+ subparsers = parser.add_subparsers(dest="action")
+
+ parser.add_argument(
+ '--driver', action='store', required=True,
+ help='Select the driver to use for connecting to the glucometer.')
+ parser.add_argument(
+ '--device', action='store', required=False,
+ help=('Select the path to the glucometer device. Some devices require this '
+ 'argument, others will try autodetection.'))
+
+ parser.add_argument(
+ '--vlog', action='store', required=False, type=int,
+ help=('Python logging level. See the levels at '
+ 'https://docs.python.org/3/library/logging.html#logging-levels'))
+
+ subparsers.add_parser(
+ 'help', help=('Display a description of the driver, including supported '
+ 'features and known quirks.'))
+ subparsers.add_parser(
+ 'info', help='Display information about the meter.')
+ subparsers.add_parser(
+ 'zero', help='Zero out the data log of the meter.')
+
+ parser_dump = subparsers.add_parser(
+ 'dump', help='Dump the readings stored in the device.')
+ parser_dump.add_argument(
+ '--unit', action='store',
+ choices=[unit.value for unit in common.Unit],
+ help='Select the unit to use for the dumped data.')
+ parser_dump.add_argument(
+ '--sort-by', action='store', default='timestamp',
+ choices=common._ReadingBase._fields,
+ help='Field to order the dumped data by.')
+ parser_dump.add_argument(
+ '--with-ketone', action='store_true', default=False,
+ help='Enable ketone reading if available on the glucometer.')
+
+ parser_date = subparsers.add_parser(
+ 'datetime', help='Reads or sets the date and time of the glucometer.')
+ parser_date.add_argument(
+ '--set', action='store', nargs='?', const='now', default=None,
+ help='Set the date rather than just reading it from the device.')
+
+ args = parser.parse_args()
+
+ logging.basicConfig(level=args.vlog)
+
+ try:
+ driver = importlib.import_module('glucometerutils.drivers.' + args.driver)
+ except ImportError as e:
+ logging.error(
+ 'Error importing driver "%s", please check your --driver parameter:\n%s',
+ args.driver, e)
+ return 1
+
+ # This check needs to happen before we try to initialize the device, as the
+ # help action does not require a --device at all.
+ if args.action == 'help':
+ print(inspect.getdoc(driver))
+ return 0
+
+ device = driver.Device(args.device)
+
+ device.connect()
+ device_info = device.get_meter_info()
+
+ try:
+ if args.action == 'info':
+ try:
+ time_str = device.get_datetime()
+ except NotImplementedError:
+ time_str = 'N/A'
+ print("{device_info}Time: {time}".format(
+ device_info=str(device_info), time=time_str))
+ elif args.action == 'dump':
+ unit = args.unit
+ if unit is None:
+ unit = device_info.native_unit
+
+ readings = device.get_readings()
+
+ if not args.with_ketone:
+ readings = (reading for reading in readings
+ if not isinstance(reading, common.KetoneReading))
+
+ if args.sort_by is not None:
+ readings = sorted(
+ readings, key=lambda reading: getattr(reading, args.sort_by))
+
+ for reading in readings:
+ print(reading.as_csv(unit))
+ elif args.action == 'datetime':
+ if args.set == 'now':
+ print(device.set_datetime())
+ elif args.set:
+ try:
+ from dateutil import parser as date_parser
+ new_date = date_parser.parse(args.set)
+ except ImportError:
+ logging.error(
+ 'Unable to import module "dateutil", please install it.')
+ return 1
+ except ValueError:
+ logging.error('%s: not a valid date', args.set)
+ return 1
+ print(device.set_datetime(new_date))
+ else:
+ print(device.get_datetime())
+ elif args.action == 'zero':
+ confirm = input('Delete the device data log? (y/N) ')
+ if confirm.lower() in ['y', 'ye', 'yes']:
+ device.zero_log()
+ print('\nDevice data log zeroed.')
+ else:
+ print('\nDevice data log not zeroed.')
+ return 1
+ else:
+ return 1
+ except exceptions.Error as err:
+ print('Error while executing \'%s\': %s' % (args.action, str(err)))
+ return 1
+
+ device.disconnect()