diff options
Diffstat (limited to 'glucometerutils/drivers/fslibre.py')
-rw-r--r-- | glucometerutils/drivers/fslibre.py | 184 |
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") |