Example #1
0
    def wait_and_ready(self):
        challenge = self.serial_.read(1)

        # The first packet read may have a prefixed zero, it might be a bug in
        # the cp210x driver or device, but discard it if found.
        if challenge == b'\0':
            challege = self.serial_.read(1)
            if challenge != b'\x53':
                raise exceptions.ConnectionFailed(
                    message='Unexpected starting bytes %r' % challenge)

        challenge += self.serial_.read(6)

        if challenge != _CHALLENGE_PACKET_FULL:
            raise exceptions.ConnectionFailed(
                message='Unexpected challenge %r' % challenge)

        self.send_packet(_RESPONSE_PACKET)

        # The first packet only contains the counter of how many readings are
        # available.
        first_packet = self.read_packet()

        count = _STRUCT_READINGS_COUNT.unpack_from(first_packet, 1)

        return count[0]
    def wait_and_ready(self):
        challenge = self.serial_.read(1)

        # The first packet read may have a prefixed zero, it might be a bug in
        # the cp210x driver or device, but discard it if found.
        if challenge == b'\0':
            logging.debug('spurious null byte received')
            challege = self.serial_.read(1)
            if challenge != b'\x53':
                raise exceptions.ConnectionFailed(
                    message='Unexpected starting bytes %r' % challenge)

        challenge += self.serial_.read(6)

        if challenge != _CHALLENGE_PACKET_FULL:
            raise exceptions.ConnectionFailed(
                message='Unexpected challenge %r' % challenge)

        logging.debug('challenge packet received: %s',
                      binascii.hexlify(challenge))

        self.send_message(_RESPONSE_MESSAGE)

        # The first packet only contains the counter of how many readings are
        # available.
        first_message = _FIRST_MESSAGE.parse(self.read_message())
        logging.debug('received first message: %r', first_message)

        return first_message.count
Example #3
0
    def __init__(self, device):
        # type: (Optional[Text]) -> None
        if None in (self.USB_VENDOR_ID, self.USB_PRODUCT_ID) and not device:
            raise exceptions.CommandLineError(
                '--device parameter is required, should point to a /dev/hidraw '
                'device node representing the meter.')

        # If the user passed a device path that does not exist, raise an
        # error. This is to avoid writing to a file instead of to a device node.
        if device and not os.path.exists(device):
            raise exceptions.ConnectionFailed(
                message='Path %s does not exist.' % device)

        # If the user passed a device, try opening it.
        if device:
            self.handle_ = open(device, 'w+b')  # type: Optional[BinaryIO]
        else:
            self.handle_ = None
            logging.info(
                'No --device parameter provided, using hidapi library.')
            try:
                import hid
                self.hidapi_handle_ = hid.device()
                self.hidapi_handle_.open(self.USB_VENDOR_ID,
                                         self.USB_PRODUCT_ID)
            except ImportError:
                raise exceptions.ConnectionFailed(
                    message='Missing requied "hidapi" module.')
            except OSError as e:
                raise exceptions.ConnectionFailed(
                    message='Unable to connect to meter: %s.' % e)
Example #4
0
    def wait_and_ready(self) -> int:

        challenge = b"\0"
        while challenge == b"\0":
            challenge = self.serial_.read(1)

            # The first packet read may have a prefixed zero, it might be a bug
            # in the cp210x driver or device, but discard it if found.
            if challenge == b"\0":
                logging.debug("spurious null byte received")
                continue
            if challenge != b"\x53":
                raise exceptions.ConnectionFailed(
                    message=f"Unexpected starting bytes {challenge!r}")

        challenge += self.serial_.read(6)

        if challenge != _CHALLENGE_PACKET_FULL:
            raise exceptions.ConnectionFailed(
                message=f"Unexpected challenge {challenge!r}")

        logging.debug("challenge packet received: %s",
                      binascii.hexlify(challenge))

        self.send_message(_RESPONSE_MESSAGE)

        # The first packet only contains the counter of how many readings are
        # available.
        first_message = _FIRST_MESSAGE.parse(self.read_message())
        logging.debug("received first message: %r", first_message)

        return first_message.count
Example #5
0
    def __init__(
        self,
        usb_id: Optional[Tuple[int, int]],
        device: Optional[str],
        timeout_ms: int = 0,
    ) -> None:
        """Construct a new session object.

        Args:
          usb_id: Optional pair of vendor_id and product_id for the session.
            This is required to use the hidapi library.
          device: Optional path to Linux hidraw-style device path. If not provided,
            usb_id needs to be provided instead.
          timeout_ms: Timeout in milliseconds for read operations. Only relevant when
            using hidapi library.
        """

        self._timeout_ms = timeout_ms

        if not usb_id and not device:
            raise exceptions.CommandLineError(
                "--device parameter is required, should point to a /dev/hidraw "
                "device node representing the meter.")

        # If the user passed a device path that does not exist, raise an
        # error. This is to avoid writing to a file instead of to a device node.
        if device and not os.path.exists(device):
            raise exceptions.ConnectionFailed(
                message=f"Path {device} does not exist.")

        # If the user passed a device, try opening it.
        if device:
            self.handle_ = open(device, "w+b")  # type: Optional[BinaryIO]
        else:
            self.handle_ = None
            logging.info(
                "No --device parameter provided, using hidapi library.")
            try:
                import hid

                assert usb_id
                vendor_id, product_id = usb_id
                self.hidapi_handle_ = hid.device()
                self.hidapi_handle_.open(vendor_id, product_id)
            except ImportError:
                raise exceptions.ConnectionFailed(
                    message='Missing requied "hidapi" module.')
            except OSError as e:
                raise exceptions.ConnectionFailed(
                    message=f"Unable to connect to meter: {e}.")
Example #6
0
    def connect(self):
        response_command, message = self._send_command(_CONNECT_REQUEST,
                                                       validate_response=False)
        if response_command not in _VALID_CONNECT_RESPONSE:
            raise exceptions.ConnectionFailed(
                'Invalid response received: %2x %r' %
                (response_command, message))

        _, model_message = self._send_command(_GET_MODEL)
        try:
            _MODEL_STRUCT.parse(model_message)
        except construct.ConstructError:
            raise exceptions.ConnectionFailed('Invalid model identified: %r' %
                                              model_message)
Example #7
0
 def connect(self):
     inq = self.scsi_.inquiry()
     logging.debug('Device connected: %r', inq.result)
     vendor = inq.result['t10_vendor_identification'][:32]
     if vendor != b'LifeScan':
         raise exceptions.ConnectionFailed(
             'Device %s is not a LifeScan glucometer.' % self.device_name_)
    def __init__(self, device):
        report_files = glob.glob(os.path.join(device, '*', 'Reports', '*.csv'))
        if not report_files:
            raise exceptions.ConnectionFailed(
                'No report file found in path "%s".' % reports_path)

        self.report_file = report_files[0]
 def connect(self) -> None:
     inq = self.scsi_.inquiry()
     logging.debug("Device connected: %r", inq.result)
     vendor = inq.result["t10_vendor_identification"][:32]
     if vendor != b"LifeScan":
         raise exceptions.ConnectionFailed(
             f"Device {self.device_name_} is not a LifeScan glucometer.")
Example #10
0
 def connect(self):
     """Open connection to the device, starting the knocking sequence."""
     self._send_command(_INIT_COMMAND, b'')
     response = self._read_response()
     if not _is_init_reply(response):
         raise exceptions.ConnectionFailed(
             'Connection error: unexpected message %02x:%s' %
             (response[0], response[1].hex()))
Example #11
0
 def connect(self):
     """Open connection to the device, starting the knocking sequence."""
     self.send_command(_INIT_COMMAND, b"")
     response = self.read_response()
     if not _is_init_reply(response):
         raise exceptions.ConnectionFailed(
             f"Connection error: unexpected message %{response[0]:02x}:{response[1].hex()}"
         )
Example #12
0
    def connect(self) -> None:
        response_command, message = self._send_command(_CONNECT_REQUEST,
                                                       validate_response=False)
        if response_command not in _VALID_CONNECT_RESPONSE:
            raise exceptions.ConnectionFailed(
                f"Invalid response received: {response_command:02x} {message!r}"
            )

        self._get_model()
Example #13
0
    def __init__(self, device):
        if not device:
            raise exceptions.CommandLineError(
                '--device parameter is required, should point to /dev/hidraw '
                'for the meter')

        if not os.path.exists(device):
            raise exceptions.ConnectionFailed(
                message='Path %s does not exist.' % device)
        self.handle_ = open(device, 'w+b')
Example #14
0
    def _get_model(self) -> str:
        _, model_message = self._send_command(_GET_MODEL)
        try:
            result = _MODEL_STRUCT.parse(model_message)
        except construct.ConstructError as e:
            raise exceptions.ConnectionFailed(
                f"Invalid model response: {model_message!r}") from e

        # The model number is presented as BCD (Binary Coded Decimal).
        model_number = hex(result.model)[2:]

        return f"TD-{model_number}"
Example #15
0
    def __init__(self, device):
        if not device or not os.path.isdir(device):
            raise exceptions.CommandLineError(
                '--device parameter is required, should point to mount path for the '
                'meter.')

        report_files = glob.glob(os.path.join(device, '*', 'Reports', '*.csv'))
        if not report_files:
            raise exceptions.ConnectionFailed(
                'No report file found in path "%s".' % reports_path)

        self.report_file = report_files[0]
Example #16
0
    def __init__(self, device: Optional[str]) -> None:
        if not device or not os.path.isdir(device):
            raise exceptions.CommandLineError(
                "--device parameter is required, should point to mount path "
                "for the meter.")

        reports_path = os.path.join(device, "*", "Reports", "*.csv")
        report_files = glob.glob(reports_path)
        if not report_files:
            raise exceptions.ConnectionFailed(
                f'No report file found in path "{reports_path}".')

        self.report_file = report_files[0]
Example #17
0
 def __init__(
     self,
     product_id: int,
     device_path: Optional[str],
     text_cmd: int = 0x60,
     text_reply_cmd: int = 0x60,
 ) -> None:
     super().__init__(device_path)
     try:
         self._session = freestyle_hid.Session(
             product_id,
             pathlib.Path(device_path) if device_path else None,
             text_cmd,
             text_reply_cmd,
         )
     except Exception as e:
         raise exceptions.ConnectionFailed(str(e))
Example #18
0
    def _fetch_device_information(self) -> None:
        data = self._send_command("colq")

        for line in data:
            parsed_line = line.split("\t")

            if parsed_line[0] == "S/N:":
                self.device_serialno_ = parsed_line[1]
            elif parsed_line[0] == "Ver:":
                self.device_version_ = parsed_line[1]
                if parsed_line[2] == "MMOL":
                    self.device_glucose_unit_ = common.Unit.MMOL_L
                else:  # I only have a mmol/l device, so I can't be sure.
                    self.device_glucose_unit_ = common.Unit.MG_DL
            # There are more entries: Clock, Market, ROM and Usage, but we don't
            # care for those here.
            elif parsed_line[0] == "CMD OK":
                return

        # I have not figured out why this happens, but sometimes it's echoing
        # back the commands and not replying to them.
        raise exceptions.ConnectionFailed()
Example #19
0
    def _fetch_device_information(self):
        data = self._send_command('colq')

        for line in data:
            parsed_line = line.split('\t')

            if parsed_line[0] == 'S/N:':
                self.device_serialno_ = parsed_line[1]
            elif parsed_line[0] == 'Ver:':
                self.device_version_ = parsed_line[1]
                if parsed_line[2] == 'MMOL':
                    self.device_glucose_unit_ = common.UNIT_MMOLL
                else:  # I only have a mmol/l device, so I can't be sure.
                    self.device_glucose_unit_ = common.UNIT_MGDL
            # There are more entries: Clock, Market, ROM and Usage, but we don't care
            # for those here.
            elif parsed_line[0] == 'CMD OK':
                return

        # I have not figured out why this happens, but sometimes it's echoing back
        # the commands and not replying to them.
        raise exceptions.ConnectionFailed()
Example #20
0
 def __init__(self, device):
     if not os.path.exists(device):
         raise exceptions.ConnectionFailed(
             message='Path %s does not exist.' % device)
     self.handle_ = open(device, 'w+b')
Example #21
0
 def connect(self) -> None:
     """Open connection to the device, starting the knocking sequence."""
     try:
         self._session.connect()
     except Exception as e:
         raise exceptions.ConnectionFailed(str(e))