summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--glucometerutils/drivers/fslibre.py73
2 files changed, 75 insertions, 0 deletions
diff --git a/README b/README
index c635bba..050dcaa 100644
--- a/README
+++ b/README
@@ -27,6 +27,7 @@ information on each of the devices.
| LifeScan | OneTouch Verio (USB) | `otverio2015` |
| LifeScan | OneTouch Select Plus | `otverio2015` |
| Abbott | FreeStyle InsuLinx | `fsinsulinx` |
+| Abbott | FreeStyle Libre | `fslibre` |
| Abbott | FreeStyle Optium | `fsoptium` |
| Abbott | FreeStyle Precision Neo | `fsprecisionneo` |
| Roche | Accu-Chek Mobile | `accuchek_reports` |
@@ -40,6 +41,7 @@ information on each of the devices.
| `otultraeasy` | serialno, swver, unit | get and set | not supported by device | yes |
| `otverio2015` | serialno, swver | get and set | no | yes |
| `fsinsulinx` | serialno, swver | get and set | no | not supported by device |
+| `fslibre` | serialno, swver | get and set | yes | not supported by device |
| `fsoptium` | serialno, swver, unit | get and set | not supported by device | not supported by device |
| `fsprecisionneo` | serialno, swver | get and set | not supported by device | not supported by device |
| `accuchek_reports` | serialno, unit | no | yes | not supported by device |
diff --git a/glucometerutils/drivers/fslibre.py b/glucometerutils/drivers/fslibre.py
new file mode 100644
index 0000000..c213ccd
--- /dev/null
+++ b/glucometerutils/drivers/fslibre.py
@@ -0,0 +1,73 @@
+# -*- coding: utf-8 -*-
+"""Driver for FreeStyle Libre CGM devices."""
+
+__author__ = 'Diego Elio Pettenò'
+__email__ = 'flameeyes@flameeyes.eu'
+__copyright__ = 'Copyright © 2017, Diego Elio Pettenò'
+__license__ = 'MIT'
+
+import datetime
+
+from glucometerutils import common
+from glucometerutils.support import freestyle
+
+# Fields of the records returned by $history?
+# Tuple of pairs of idx and field name
+_HISTORY_ENTRY_MAP = (
+ (2, 'month'),
+ (3, 'day'),
+ (4, 'year'), # 2-digits
+ (5, 'hour'),
+ (6, 'minute'),
+ (7, 'second'),
+ (13, 'value'),
+ (15, 'errors'),
+)
+
+
+class Device(freestyle.FreeStyleHidDevice):
+ """Glucometer driver for FreeStyle Libre devices."""
+
+ def get_meter_info(self):
+ """Return the device information in structured form."""
+ return common.MeterInfo(
+ 'FreeStyle Libre',
+ serial_number=self.get_serial_number(),
+ version_info=(
+ 'Software version: ' + self._get_version(),),
+ native_unit=self.get_glucose_unit())
+
+ def get_serial_number(self):
+ """Overridden function as the command is not compatible."""
+ return self._send_text_command(b'$sn?').rstrip('\r\n')
+
+ def get_glucose_unit(self):
+ """Returns the glucose unit of the device."""
+ # TODO(Flameeyes): figure out how to identify the actual unit on the
+ # device.
+ return common.UNIT_MGDL
+
+ def get_readings(self):
+ for record in self._get_multirecord(b'$history?'):
+ if not record:
+ continue
+
+ parsed_record = {
+ key: int(record[idx])
+ for idx, key in _HISTORY_ENTRY_MAP
+ }
+
+ if parsed_record['errors'] != 0:
+ # The reading is considered invalid, so ignore it.
+ continue
+
+ timestamp = datetime.datetime(
+ parsed_record['year'] + 2000,
+ parsed_record['month'],
+ parsed_record['day'],
+ parsed_record['hour'],
+ parsed_record['minute'],
+ parsed_record['second'])
+
+ yield common.Reading(timestamp, parsed_record['value'],
+ comment='(Sensor)')