def _get_reading(self, record_id): response = self._send_request(3, _READ_RECORD_REQUEST, {'record_id': record_id}, _READ_RECORD_RESPONSE) return common.GlucoseReading(response.timestamp, float(response.value), meal=response.meal)
def get_readings(self): # 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?'): parsed_record = _parse_record(record, _HISTORY_ENTRY_MAP) 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)', measure_method=common.MeasurementMethod.CGM, 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?'): reading = _parse_arresult(record) if reading: yield reading
def get_readings(self) -> Generator[common.AnyReading, None, None]: # First of all get the usually longer list of sensor readings, and # convert them to Readings objects. for record in self._session.query_multirecord(b"$history?"): parsed_record = _parse_record(record, _HISTORY_ENTRY_MAP) 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)", measure_method=common.MeasurementMethod.CGM, 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._session.query_multirecord(b"$arresult?"): logging.debug(f"Retrieved arresult: {record!r}") reading = _parse_arresult(record) if reading: yield reading
def get_readings(self): """Iterates over the reading values stored in the glucometer. Args: unit: The glucose unit to use for the output. Yields: A tuple (date, value) of the readings in the glucometer. The value is a floating point in the unit specified; if no unit is specified, the default unit in the glucometer will be used. Raises: exceptions.InvalidResponse: if the response does not match what expected. """ for line in self.device_results_: value = line['value'] day = line['day'] month = line['month'] year = line['year'] hour = line['hour'] minute = line['minute'] timestamp = line['timestamp'] # fixme # The reading, if present, is always in mg/dL even if the glucometer is # set to mmol/L. yield common.GlucoseReading(timestamp, value)
def get_readings(self): for record in self._get_records_reader(): if record[_RESULT_CSV_KEY] is None: continue yield common.GlucoseReading( self._extract_datetime(record), common.convert_glucose_unit(float(record[_RESULT_CSV_KEY]), _UNIT_MAP[record[_UNIT_CSV_KEY]]), meal=self._extract_meal(record))
def test_minimal(self): reading = common.GlucoseReading(TEST_DATETIME, 100) self.assertEqual( reading.as_csv(common.Unit.MG_DL), '"2018-01-01 00:30:45","100.00","","blood sample",""', ) self.assertEqual( len(list(csv.reader([reading.as_csv(common.Unit.MG_DL)]))[0]), CSV_FIELD_COUNT, )
def get_readings(self): """ Get reading dump from download data mode(all readings stored) This meter supports only blood samples """ for parsed_record in self._get_multirecord(): yield common.GlucoseReading( _extract_timestamp(parsed_record), int(parsed_record['value']), comment=parsed_record['markers'], measure_method=common.MeasurementMethod.BLOOD_SAMPLE)
def _get_reading(self, record_id): response = self._send_request(_READ_RECORD_REQUEST, {'record_id': record_id}, _READING_RESPONSE) if response.control_test: logging.debug('control solution test, ignoring.') return None return common.GlucoseReading(response.timestamp, float(response.value), meal=response.meal)
def get_readings(self): count_response = self._get_reading(_INVALID_RECORD) record_count, = _STRUCT_RECORDID.unpack_from(count_response.data, 2) for record_id in range(record_count): record_response = self._get_reading(record_id) timestamp = _convert_timestamp(record_response.data[2:6]) value, = _STRUCT_TIMESTAMP.unpack_from(record_response.data, 6) yield common.GlucoseReading(timestamp, float(value))
def _get_reading(self, record_id): _, reading_date_message = self._send_command(_GET_READING_DATETIME, _select_record(record_id)) reading_date = _parse_datetime(reading_date_message) _, reading_value_message = self._send_command( _GET_READING_VALUE, _select_record(record_id)) reading_value = _READING_VALUE_STRUCT.parse(reading_value_message) return common.GlucoseReading(reading_date, reading_value.value, meal=reading_value.meal)
def get_readings(self): count = self.wait_and_ready() for _ in range(count): self.send_message(_FETCH_MESSAGE) message = self.read_message() r = _READING.parse(message) logging.debug('received reading: %r', r) yield common.GlucoseReading(datetime.datetime( 2000 + r.year, r.month, r.day, r.hour, r.minute), r.value, meal=r.meal)
def get_readings(self): count = self.wait_and_ready() for _ in range(count): self.send_packet(_FETCH_PACKET) rpkt = self.read_packet() r = parse_reading(rpkt) meal = _MEAL_FLAG[r.meal_flag] yield common.GlucoseReading( datetime.datetime( 2000 + r.year, r.month, r.day, r.hour, r.minute), r.value, meal=meal)
def get_readings(self) -> Generator[common.AnyReading, None, None]: for record in self._get_records_reader(): if record[_RESULT_CSV_KEY] is None: continue yield common.GlucoseReading( self._extract_datetime(record), common.convert_glucose_unit( float(record[_RESULT_CSV_KEY]), _UNIT_MAP[record[_UNIT_CSV_KEY]], common.Unit.MG_DL, ), meal=self._extract_meal(record), )
def get_readings(self): """Iterate through the reading records in the device.""" for record in self._get_multirecord(b'$result?'): if not record or record[0] != _TYPE_GLUCOSE_READING: continue # Build a reading object by parsing each of the entries in the CSV # as integers. raw_reading = _InsulinxReading._make([int(v) for v in record]) timestamp = datetime.datetime(raw_reading.year + 2000, raw_reading.month, raw_reading.day, raw_reading.hour, raw_reading.minute) yield common.GlucoseReading(timestamp, raw_reading.value)
def _get_reading(self, record_number): request = (_READ_RECORD_REQUEST_PREFIX + _STRUCT_RECORDID.pack(record_number) + _READ_RECORD_REQUEST_SUFFIX) response = self._send_message(request, 3) if response[0:2] != b'\x04\06': raise lifescan.MalformedCommand( 'invalid response, expected 04 06, received %02x %02x' % (response[0], response[1])) (unused_const1, unused_const2, unused_counter, unused_const3, unused_counter2, timestamp, value, meal_flag, unused_const4, unused_flags, unused_const5, unused_const6) = _STRUCT_RECORD.unpack(response) return common.GlucoseReading(_convert_timestamp(timestamp), float(value), meal=_MEAL_CODES[meal_flag])
def get_readings(self): """Iterates over the reading values stored in the glucometer. Args: unit: The glucose unit to use for the output. Yields: A tuple (date, value) of the readings in the glucometer. The value is a floating point in the unit specified; if no unit is specified, the default unit in the glucometer will be used. Raises: exceptions.InvalidResponse: if the response does not match what expected. """ self._send_command('DMP') data = self.serial_.readlines() header = data.pop(0).decode('ascii') match = _DUMP_HEADER_RE.match(header) if not match: raise exceptions.InvalidResponse(header) count = int(match.group(1)) assert count == len(data) for line in data: line = _validate_and_strip_checksum(line.decode('ascii')) match = _DUMP_LINE_RE.match(line) if not match: raise exceptions.InvalidResponse(line) line_data = match.groupdict() date = _parse_datetime(line_data['datetime']) meal = _MEAL_CODES[line_data['meal']] comment = _COMMENT_CODES[line_data['comment']] # OneTouch2 always returns the data in mg/dL even if the glucometer is set # to mmol/L, so there is no conversion required. yield common.GlucoseReading(date, float(line_data['value']), meal=meal, comment=comment)
def get_readings(self) -> Generator[common.AnyReading, None, None]: """Iterates over the reading values stored in the glucometer. Args: unit: The glucose unit to use for the output. Yields: A GlucoseReading object representing the read value. Raises: exceptions.InvalidResponse: if the response does not match what expected. """ self._send_command("DMP") data = self.serial_.readlines() header = data.pop(0).decode("ascii") match = _DUMP_HEADER_RE.match(header) if not match: raise exceptions.InvalidResponse(header) count = int(match.group(1)) assert count == len(data) for line in data: line = _validate_and_strip_checksum(line.decode("ascii")) match = _DUMP_LINE_RE.match(line) if not match: raise exceptions.InvalidResponse(line) line_data = match.groupdict() date = _parse_datetime(line_data["datetime"]) meal = _MEAL_CODES[line_data["meal"]] comment = _COMMENT_CODES[line_data["comment"]] # OneTouch2 always returns the data in mg/dL even if the glucometer # is set to mmol/L, so there is no conversion required. yield common.GlucoseReading(date, float(line_data["value"]), meal=meal, comment=comment)
def get_readings(self) -> Generator[common.AnyReading, None, None]: for reading in self._get_raw_readings(): if reading.reading_type != "Glu": logging.warning( f"Unsupported reading type {reading.reading_type!r}. Please file an issue at https://github.com/glucometers-tech/glucometerutils/issues" ) continue mgdl_value = common.convert_glucose_unit( reading.value, from_unit=reading.unit, to_unit=common.Unit.MG_DL, ) yield common.GlucoseReading( reading.timestamp, mgdl_value, meal=reading.meal, comment=reading.comment, )
def get_readings(self) -> Generator[common.AnyReading, None, None]: count = self.wait_and_ready() for _ in range(count): self.send_message(_FETCH_MESSAGE) message = self.read_message() reading = _READING.parse(message) logging.debug("received reading: %r", reading) yield common.GlucoseReading( datetime.datetime( 2000 + reading.year, reading.month, reading.day, reading.hour, reading.minute, ), reading.value, meal=reading.meal, )
def _get_reading(self, record_id: int) -> common.GlucoseReading: response = self._send_request(_READ_RECORD_REQUEST, {"record_id": record_id}, _READING_RESPONSE) return common.GlucoseReading(response.timestamp, float(response.value))
def test_csv(self, kwargs_dict, expected_csv): reading = common.GlucoseReading(self.TEST_DATETIME, 100, **kwargs_dict) self.assertEqual(reading.as_csv(common.Unit.MG_DL), expected_csv)
def test_value(self, unit, expected_value): reading = common.GlucoseReading(self.TEST_DATETIME, 100) self.assertAlmostEqual(reading.get_value_as(unit), expected_value, places=2)
def test_minimal(self): reading = common.GlucoseReading(self.TEST_DATETIME, 100) self.assertEqual( reading.as_csv(common.Unit.MG_DL), '"2018-01-01 00:30:45","100.00","","blood sample",""')
def get_readings(self) -> Generator[common.AnyReading, None, None]: """Iterates over the reading values stored in the glucometer. Args: unit: The glucose unit to use for the output. Yields: A tuple (date, value) of the readings in the glucometer. The value is a floating point in the unit specified; if no unit is specified, the default unit in the glucometer will be used. Raises: exceptions.InvalidResponse: if the response does not match what ' expected. """ data = self._send_command("xmem") # The first line is empty, the second is the serial number, the third # the version, the fourth the current time, and the fifth the record # count.. The last line has a checksum and the end. count = int(data[4]) if count != (len(data) - 6): raise exceptions.InvalidResponse("\n".join(data)) # Extract the checksum from the last line. checksum_match = _CHECKSUM_RE.match(data[-1]) if not checksum_match: raise exceptions.InvalidResponse("\n".join(data)) expected_checksum = int(checksum_match.group("checksum"), 16) # exclude the last line in the checksum calculation, as that's the # checksum itself. The final \r\n is added separately. calculated_checksum = sum(ord(c) for c in "\r\n".join(data[:-1])) + 0xD + 0xA if expected_checksum != calculated_checksum: raise exceptions.InvalidChecksum(expected_checksum, calculated_checksum) for line in data[5:-1]: match = _READING_RE.match(line) if not match: raise exceptions.InvalidResponse(line) if match.group("type") != "G": logging.warning("Non-glucose readings are not supported, ignoring.") continue if match.group("reading") == "HI ": value = float("inf") else: value = float(match.group("reading")) day = int(match.group("day")) month = _MONTH_MATCHES[match.group("month")] year = int(match.group("year")) hour, minute = map(int, match.group("time").split(":")) timestamp = datetime.datetime(year, month, day, hour, minute) # The reading, if present, is always in mg/dL even if the glucometer # is set to mmol/L. yield common.GlucoseReading(timestamp, value)
def get_readings(self): """Iterates over the reading values stored in the glucometer. Args: unit: The glucose unit to use for the output. Yields: A tuple (date, value) of the readings in the glucometer. The value is a floating point in the unit specified; if no unit is specified, the default unit in the glucometer will be used. Raises: exceptions.InvalidResponse: if the response does not match what expected. """ data = self._send_command('xmem') # The first line is empty, the second is the serial number, the third the # version, the fourth the current time, and the fifth the record count.. The # last line has a checksum and the end. count = int(data[4]) if count != (len(data) - 6): raise exceptions.InvalidResponse('\n'.join(data)) # Extract the checksum from the last line. checksum_match = _CHECKSUM_RE.match(data[-1]) if not checksum_match: raise exceptions.InvalidResponse('\n'.join(data)) expected_checksum = int(checksum_match.group('checksum'), 16) # exclude the last line in the checksum calculation, as that's the checksum # itself. The final \r\n is added separately. calculated_checksum = sum(ord(c) for c in '\r\n'.join(data[:-1])) + 0xd + 0xa if expected_checksum != calculated_checksum: raise exceptions.InvalidChecksum(expected_checksum, calculated_checksum) for line in data[5:-1]: match = _READING_RE.match(line) if not match: raise exceptions.InvalidResponse(line) if match.group('type') != 'G': logging.warning( 'Non-glucose readings are not supported, ignoring.') continue if match.group('reading') == 'HI ': value = float("inf") else: value = float(match.group('reading')) day = int(match.group('day')) month = _MONTH_MATCHES[match.group('month')] year = int(match.group('year')) hour, minute = map(int, match.group('time').split(':')) timestamp = datetime.datetime(year, month, day, hour, minute) # The reading, if present, is always in mg/dL even if the glucometer is # set to mmol/L. yield common.GlucoseReading(timestamp, value)