summaryrefslogtreecommitdiffstats
path: root/glucometerutils/drivers/fslibre.py
diff options
context:
space:
mode:
Diffstat (limited to 'glucometerutils/drivers/fslibre.py')
-rw-r--r--glucometerutils/drivers/fslibre.py184
1 files changed, 89 insertions, 95 deletions
diff --git a/glucometerutils/drivers/fslibre.py b/glucometerutils/drivers/fslibre.py
index f1ac525..29e821a 100644
--- a/glucometerutils/drivers/fslibre.py
+++ b/glucometerutils/drivers/fslibre.py
@@ -27,52 +27,47 @@ from glucometerutils.support import freestyle
# Fields of the records returned by both $history and $arresult?
# Tuple of pairs of idx and field name
_BASE_ENTRY_MAP = (
- (0, 'device_id'),
- (1, 'type'),
- (2, 'month'),
- (3, 'day'),
- (4, 'year'), # 2-digits
- (5, 'hour'),
- (6, 'minute'),
- (7, 'second'),
+ (0, "device_id"),
+ (1, "type"),
+ (2, "month"),
+ (3, "day"),
+ (4, "year"), # 2-digits
+ (5, "hour"),
+ (6, "minute"),
+ (7, "second"),
)
# Fields of the records returned by $history?
-_HISTORY_ENTRY_MAP = _BASE_ENTRY_MAP + (
- (13, 'value'),
- (15, 'errors'),
-)
+_HISTORY_ENTRY_MAP = _BASE_ENTRY_MAP + ((13, "value"), (15, "errors"),)
# Fields of the results returned by $arresult? where type = 2
_ARRESULT_TYPE2_ENTRY_MAP = (
- (9, 'reading-type'), # 0 = glucose blood strip,
- # 1 = ketone blood strip,
- # 2 = glucose sensor
- (12, 'value'),
- (15, 'sport-flag'),
- (16, 'medication-flag'),
- (17, 'rapid-acting-flag'), # see _ARRESULT_RAPID_INSULIN_ENTRY_MAP
- (18, 'long-acting-flag'),
- (19, 'custom-comments-bitfield'),
- (23, 'double-long-acting-insulin'),
- (25, 'food-flag'),
- (26, 'food-carbs-grams'),
- (28, 'errors'),
+ (9, "reading-type"), # 0 = glucose blood strip,
+ # 1 = ketone blood strip,
+ # 2 = glucose sensor
+ (12, "value"),
+ (15, "sport-flag"),
+ (16, "medication-flag"),
+ (17, "rapid-acting-flag"), # see _ARRESULT_RAPID_INSULIN_ENTRY_MAP
+ (18, "long-acting-flag"),
+ (19, "custom-comments-bitfield"),
+ (23, "double-long-acting-insulin"),
+ (25, "food-flag"),
+ (26, "food-carbs-grams"),
+ (28, "errors"),
)
_ARRESULT_TIME_ADJUSTMENT_ENTRY_MAP = (
- (9, 'old_month'),
- (10, 'old_day'),
- (11, 'old_year'),
- (12, 'old_hour'),
- (13, 'old_minute'),
- (14, 'old_second'),
+ (9, "old_month"),
+ (10, "old_day"),
+ (11, "old_year"),
+ (12, "old_hour"),
+ (13, "old_minute"),
+ (14, "old_second"),
)
# Fields only valid when rapid-acting-flag is "1"
-_ARRESULT_RAPID_INSULIN_ENTRY_MAP = (
- (43, 'double-rapid-acting-insulin'),
-)
+_ARRESULT_RAPID_INSULIN_ENTRY_MAP = ((43, "double-rapid-acting-insulin"),)
def _parse_record(record, entry_map):
@@ -82,26 +77,25 @@ def _parse_record(record, entry_map):
return {}
try:
- return {
- key: int(record[idx]) for idx, key in entry_map
- }
+ return {key: int(record[idx]) for idx, key in entry_map}
except IndexError:
return {}
-def _extract_timestamp(parsed_record, prefix=''):
+def _extract_timestamp(parsed_record, prefix=""):
"""Extract the timestamp from a parsed record.
This leverages the fact that all the records have the same base structure.
"""
return datetime.datetime(
- parsed_record[prefix + 'year'] + 2000,
- parsed_record[prefix + 'month'],
- parsed_record[prefix + 'day'],
- parsed_record[prefix + 'hour'],
- parsed_record[prefix + 'minute'],
- parsed_record[prefix + 'second'])
+ parsed_record[prefix + "year"] + 2000,
+ parsed_record[prefix + "month"],
+ parsed_record[prefix + "day"],
+ parsed_record[prefix + "hour"],
+ parsed_record[prefix + "minute"],
+ parsed_record[prefix + "second"],
+ )
def _parse_arresult(record):
@@ -112,24 +106,23 @@ def _parse_arresult(record):
# There are other record types, but we don't currently need to expose these.
if not parsed_record:
return None
- elif parsed_record['type'] == 2:
+ elif parsed_record["type"] == 2:
parsed_record.update(_parse_record(record, _ARRESULT_TYPE2_ENTRY_MAP))
- elif parsed_record['type'] == 5:
+ elif parsed_record["type"] == 5:
parsed_record.update(_parse_record(record, _ARRESULT_TIME_ADJUSTMENT_ENTRY_MAP))
return common.TimeAdjustment(
_extract_timestamp(parsed_record),
- _extract_timestamp(parsed_record, 'old_'),
- extra_data={'device_id': parsed_record['device_id']},
+ _extract_timestamp(parsed_record, "old_"),
+ extra_data={"device_id": parsed_record["device_id"]},
)
else:
return None
# Check right away if we have rapid insulin
- if parsed_record['rapid-acting-flag']:
- parsed_record.update(
- _parse_record(record, _ARRESULT_RAPID_INSULIN_ENTRY_MAP))
+ if parsed_record["rapid-acting-flag"]:
+ parsed_record.update(_parse_record(record, _ARRESULT_RAPID_INSULIN_ENTRY_MAP))
- if parsed_record['errors']:
+ if parsed_record["errors"]:
return None
comment_parts = []
@@ -137,68 +130,69 @@ def _parse_arresult(record):
cls = None
value = None
- if parsed_record['reading-type'] == 2:
- comment_parts.append('(Scan)')
+ if parsed_record["reading-type"] == 2:
+ comment_parts.append("(Scan)")
measure_method = common.MeasurementMethod.CGM
cls = common.GlucoseReading
- value = parsed_record['value']
- elif parsed_record['reading-type'] == 0:
- comment_parts.append('(Blood)')
+ value = parsed_record["value"]
+ elif parsed_record["reading-type"] == 0:
+ comment_parts.append("(Blood)")
measure_method = common.MeasurementMethod.BLOOD_SAMPLE
cls = common.GlucoseReading
- value = parsed_record['value']
- elif parsed_record['reading-type'] == 1:
- comment_parts.append('(Ketone)')
+ value = parsed_record["value"]
+ elif parsed_record["reading-type"] == 1:
+ comment_parts.append("(Ketone)")
measure_method = common.MeasurementMethod.BLOOD_SAMPLE
cls = common.KetoneReading
# automatically convert the raw value in mmol/L
- value = freestyle.convert_ketone_unit(parsed_record['value'])
+ value = freestyle.convert_ketone_unit(parsed_record["value"])
else:
# unknown reading
return None
custom_comments = record[29:35]
for comment_index in range(6):
- if parsed_record['custom-comments-bitfield'] & (1 << comment_index):
+ if parsed_record["custom-comments-bitfield"] & (1 << comment_index):
comment_parts.append(custom_comments[comment_index][1:-1])
- if parsed_record['sport-flag']:
- comment_parts.append('Sport')
+ if parsed_record["sport-flag"]:
+ comment_parts.append("Sport")
- if parsed_record['medication-flag']:
- comment_parts.append('Medication')
+ if parsed_record["medication-flag"]:
+ comment_parts.append("Medication")
- if parsed_record['food-flag']:
- if parsed_record['food-carbs-grams']:
- comment_parts.append(
- 'Food (%d g)' % parsed_record['food-carbs-grams'])
+ if parsed_record["food-flag"]:
+ if parsed_record["food-carbs-grams"]:
+ comment_parts.append("Food (%d g)" % parsed_record["food-carbs-grams"])
else:
- comment_parts.append('Food')
+ comment_parts.append("Food")
- if parsed_record['long-acting-flag']:
- if parsed_record['double-long-acting-insulin']:
+ if parsed_record["long-acting-flag"]:
+ if parsed_record["double-long-acting-insulin"]:
comment_parts.append(
- 'Long-acting insulin (%.1f)' %
- (parsed_record['double-long-acting-insulin']/2.))
+ "Long-acting insulin (%.1f)"
+ % (parsed_record["double-long-acting-insulin"] / 2.0)
+ )
else:
- comment_parts.append('Long-acting insulin')
+ comment_parts.append("Long-acting insulin")
- if parsed_record['rapid-acting-flag']:
+ if parsed_record["rapid-acting-flag"]:
# provide default value, as this record does not always exist
# (even if rapid-acting-flag is set)
- if parsed_record.get('double-rapid-acting-insulin', 0):
+ if parsed_record.get("double-rapid-acting-insulin", 0):
comment_parts.append(
- 'Rapid-acting insulin (%.1f)' %
- (parsed_record['double-rapid-acting-insulin']/2.))
+ "Rapid-acting insulin (%.1f)"
+ % (parsed_record["double-rapid-acting-insulin"] / 2.0)
+ )
else:
- comment_parts.append('Rapid-acting insulin')
+ comment_parts.append("Rapid-acting insulin")
return cls(
_extract_timestamp(parsed_record),
value,
- comment='; '.join(comment_parts),
+ comment="; ".join(comment_parts),
measure_method=measure_method,
- extra_data={'device_id': parsed_record['device_id']},
+ extra_data={"device_id": parsed_record["device_id"]},
)
@@ -210,16 +204,16 @@ class Device(freestyle.FreeStyleHidDevice):
def get_meter_info(self):
"""Return the device information in structured form."""
return common.MeterInfo(
- 'FreeStyle Libre',
+ "FreeStyle Libre",
serial_number=self.get_serial_number(),
- version_info=(
- 'Software version: ' + self._get_version(),),
+ version_info=("Software version: " + self._get_version(),),
native_unit=self.get_glucose_unit(),
- patient_name=self.get_patient_name())
+ patient_name=self.get_patient_name(),
+ )
def get_serial_number(self):
"""Overridden function as the command is not compatible."""
- return self._send_text_command(b'$sn?').rstrip('\r\n')
+ return self._send_text_command(b"$sn?").rstrip("\r\n")
def get_glucose_unit(self): # pylint: disable=no-self-use
"""Returns the glucose unit of the device."""
@@ -231,27 +225,27 @@ class Device(freestyle.FreeStyleHidDevice):
# First of all get the usually longer list of sensor readings, and
# convert them to Readings objects.
- for record in self._get_multirecord(b'$history?'):
+ for record in self._get_multirecord(b"$history?"):
parsed_record = _parse_record(record, _HISTORY_ENTRY_MAP)
- if not parsed_record or parsed_record['errors'] != 0:
+ if not parsed_record or parsed_record["errors"] != 0:
# The reading is considered invalid, so ignore it.
continue
yield common.GlucoseReading(
_extract_timestamp(parsed_record),
- parsed_record['value'],
- comment='(Sensor)',
+ parsed_record["value"],
+ comment="(Sensor)",
measure_method=common.MeasurementMethod.CGM,
- extra_data={'device_id': parsed_record['device_id']},
+ extra_data={"device_id": parsed_record["device_id"]},
)
# Then get the results of explicit scans and blood tests (and other
# events).
- for record in self._get_multirecord(b'$arresult?'):
+ for record in self._get_multirecord(b"$arresult?"):
reading = _parse_arresult(record)
if reading:
yield reading
def zero_log(self):
- self._send_text_command(b'$resetpatient')
+ self._send_text_command(b"$resetpatient")