summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--glucometerutils/drivers/fsoptium.py16
-rw-r--r--glucometerutils/drivers/otultra2.py16
-rw-r--r--glucometerutils/drivers/otultraeasy.py17
-rw-r--r--glucometerutils/drivers/sdcodefree.py19
-rw-r--r--glucometerutils/support/serial.py66
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)