diff options
-rw-r--r-- | glucometerutils/drivers/fsoptium.py | 16 | ||||
-rw-r--r-- | glucometerutils/drivers/otultra2.py | 16 | ||||
-rw-r--r-- | glucometerutils/drivers/otultraeasy.py | 17 | ||||
-rw-r--r-- | glucometerutils/drivers/sdcodefree.py | 19 | ||||
-rw-r--r-- | glucometerutils/support/serial.py | 66 |
5 files changed, 85 insertions, 49 deletions
diff --git a/glucometerutils/drivers/fsoptium.py b/glucometerutils/drivers/fsoptium.py index a380c96..d1b5f24 100644 --- a/glucometerutils/drivers/fsoptium.py +++ b/glucometerutils/drivers/fsoptium.py @@ -15,10 +15,9 @@ import datetime import logging import re -import serial - from glucometerutils import common from glucometerutils import exceptions +from glucomterutils.support import serial _CLOCK_RE = re.compile( @@ -77,16 +76,9 @@ def _parse_clock(datestr): return datetime.datetime(year, month, day, hour, minute, second) -class Device(object): - def __init__(self, device): - if not device: - logging.info('No --device parameter provided, looking for default cable.') - device = 'hwgrep://1a61:3420' - - self.serial_ = serial.serial_for_url( - device, baudrate=19200, bytesize=serial.EIGHTBITS, - parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, - timeout=1, xonxoff=True, rtscts=False, dsrdtr=False, writeTimeout=None) +class Device(serial.SerialDevice): + BAUDRATE = 19200 + DEFAULT_CABLE_ID = '1a61:3420' def _send_command(self, command): cmd_bytes = bytes('$%s\r\n' % command, 'ascii') diff --git a/glucometerutils/drivers/otultra2.py b/glucometerutils/drivers/otultra2.py index 28a4771..8e33ea5 100644 --- a/glucometerutils/drivers/otultra2.py +++ b/glucometerutils/drivers/otultra2.py @@ -10,11 +10,10 @@ import datetime import logging import re -import serial - from glucometerutils import common from glucometerutils import exceptions from glucometerutils.support import lifescan +from glucometerutils.support import serial # The following two hashes are taken directly from LifeScan's documentation _MEAL_CODES = { @@ -123,16 +122,9 @@ def _parse_datetime(response): return datetime.datetime(2000 + year, month, day, hour, minute, second) -class Device(object): - def __init__(self, device): - if not device: - logging.info('No --device parameter provided, looking for default cable.') - device = 'hwgrep://067b:2303' - - self.serial_ = serial.serial_for_url( - device, baudrate=9600, bytesize=serial.EIGHTBITS, - parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, - timeout=1, xonxoff=False, rtscts=False, dsrdtr=False, writeTimeout=None) +class Device(serial.SerialDevice): + BAUDRATE = 9600 + DEFAULT_CABLE_ID = '067b:2303' # Generic PL2303 cable. def connect(self): return diff --git a/glucometerutils/drivers/otultraeasy.py b/glucometerutils/drivers/otultraeasy.py index 2976b9e..31b719f 100644 --- a/glucometerutils/drivers/otultraeasy.py +++ b/glucometerutils/drivers/otultraeasy.py @@ -13,11 +13,10 @@ import re import struct import time -import serial - from glucometerutils import common from glucometerutils import exceptions from glucometerutils.support import lifescan +from glucometerutils.support import serial _STX = 0x02 _ETX = 0x03 @@ -176,16 +175,12 @@ class _Packet(object): return self.cmd[_IDX_DATA:_IDX_ETX] -class Device(object): +class Device(serial.SerialDevice): + BAUDRATE = 9600 + DEFAULT_CABLE_ID = '067b:2303' # Generic PL2303 cable. + def __init__(self, device): - if not device: - logging.info('No --device parameter provided, looking for default cable.') - device = 'hwgrep://067b:2303' - - self.serial_ = serial.serial_for_url( - device, baudrate=9600, bytesize=serial.EIGHTBITS, - parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, - timeout=1, xonxoff=False, rtscts=False, dsrdtr=False, writeTimeout=None) + super(Device, self).__init__(device) self.sent_counter_ = False self.expect_receive_ = False diff --git a/glucometerutils/drivers/sdcodefree.py b/glucometerutils/drivers/sdcodefree.py index 0cd0b28..9aeb653 100644 --- a/glucometerutils/drivers/sdcodefree.py +++ b/glucometerutils/drivers/sdcodefree.py @@ -15,10 +15,9 @@ import operator import struct import time -import serial - from glucometerutils import common from glucometerutils import exceptions +from glucometerutils.support import serial _STX = 0x53 # Not really 'STX' _ETX = 0xAA # Not really 'ETX' @@ -64,18 +63,10 @@ def parse_reading(msgdata): def xor_checksum(msg): return functools.reduce(operator.xor, msg) -class Device(object): - def __init__(self, device): - if not device: - logging.info( - 'No --device parameter provided, looking for default cable.') - device = 'hwgrep://10c4:ea60' - - self.serial_ = serial.serial_for_url( - device, baudrate=38400, bytesize=serial.EIGHTBITS, - parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, - timeout=300, xonxoff=False, rtscts=False, dsrdtr=False, - writeTimeout=None) +class Device(serial.SerialDevice): + BAUDRATE = 38400 + DEFAULT_CABLE_ID = '10c4:ea60' # Generic cable. + TIMEOUT = 300 # We need to wait for data from the device. def read_packet(self): preamble = self.serial_.read(3) diff --git a/glucometerutils/support/serial.py b/glucometerutils/support/serial.py new file mode 100644 index 0000000..84bae87 --- /dev/null +++ b/glucometerutils/support/serial.py @@ -0,0 +1,66 @@ +"""Common routines and base driver class for serial-based meters. +""" + +__author__ = 'Diego Elio Pettenò' +__email__ = 'flameeyes@flameeyes.eu' +__copyright__ = 'Copyright © 2017, Diego Elio Pettenò' +__license__ = 'MIT' + +import logging + +import serial + +from glucometerutils import exceptions + + +class SerialDevice(object): + """A Serial-connected glucometer driver base. + + This class does not implement an actual driver by itself, but provides an + easier access to the boilerplate code required for pyserial. + + This helper assumes that communication happens on a standard 8n1 + configuration, with variable baudrate and no hardware flow control. + + The actual drivers should set the following parameters: + + BAUDRATE: (int) the speed the serial port should be opened at. + DEFAULT_CABLE_ID: (string) USB Vendor/Product ID pair, in format + abcd:abcd, of the default cable for the meter, in case the user + didn't pass an explicit device driver. + + Optional parameters available: + + TIMEOUT: (float, default: 1) the read timeout in seconds as defined by + pyserial. + + After initialization, the following attributes can be used by the driver: + serial_: (serial.Serial) the open Serial object. + + """ + + BAUDRATE = None + DEFAULT_CABLE_ID = None + + TIMEOUT = 1 + + def __init__(self, device): + assert self.BAUDRATE is not None + + if not device and self.DEFAULT_CABLE_ID: + logging.info( + 'No --device parameter provided, looking for default cable.') + device = 'hwgrep://' + self.DEFAULT_CABLE_ID + + if not device: + raise exceptions.CommandLineError( + 'No --device parameter provided, and no default cable known.') + + self.serial_ = serial.serial_for_url( + device, + baudrate=self.BAUDRATE, + timeout=self.TIMEOUT, + writeTimeout=None, + bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, + stopbits=serial.STOPBITS_ONE, + xonxoff=True, rtscts=False, dsrdtr=False) |