[IMP] hw_scale: allow third party USB to serial interfaces

We support the Mettler Toledo scales which have their own built-in USB
to serial interface. Due to continuing issues with that built-in
interface we will also support the scale configured in raw RS-232 mode
which seems to be more reliable.

This means that in order to connect the scale you'll need a third party
USB to serial interface (unless you have built-in serial interfaces, but
the POSBox doesn't).

The main difficulty this poses is that using this approach we cannot use
the name of the interface to find the device. When using the built-in
interface of the scale the interface would identify with an ID
containing 'mettler' and 'toledo'. When using a third party interface
the ID will instead contain information about the third party
interface. To fix this we use a probe-based approach, probing every
available serial interface until we find one that returns a response to
our probe. This approach will work with both third party interfaces and
the built-in interface of the scale.

Contrary to probe-based approach used in hw_blackbox_be this one is
slightly more complicated because hw_scale is written in such a way that
it is 'plug and play', which means that as long as the module is running
it will continually try to find a scale. This is fine, but we don't want
to keep sending probes to eg. Fiscal Data Modules, which could lead to
issues. Therefore we will only probe every device once. When we lose an
existing, confirmed connection to a scale we will however keep retrying
to connect to that particular device.
This commit is contained in:
Joren Van Onder 2016-03-02 09:31:57 +01:00
parent b3a3454a2f
commit acf027ac98
1 changed files with 43 additions and 15 deletions

View File

@ -33,6 +33,8 @@ class Scale(Thread):
self.weight = 0
self.weight_info = 'ok'
self.device = None
self.probed_device_paths = []
self.path_to_scale = ''
def lockedstart(self):
with self.lock:
@ -61,27 +63,53 @@ class Scale(Thread):
elif status == 'disconnected' and message:
_logger.warning('Disconnected Scale: '+message)
def _get_raw_response(self, connection):
response = ""
while True:
byte = connection.read(1)
if byte:
response += byte
else:
return response
def get_device(self):
try:
if not os.path.exists(self.input_dir):
self.set_status('disconnected','Scale Not Found')
return None
devices = [ device for device in listdir(self.input_dir)]
scales = [ device for device in devices if ('mettler' in device.lower()) or ('toledo' in device.lower()) ]
if len(scales) > 0:
print join(self.input_dir,scales[0])
self.set_status('connected','Connected to '+scales[0])
return serial.Serial(join(self.input_dir,scales[0]),
baudrate = 9600,
bytesize = serial.SEVENBITS,
stopbits = serial.STOPBITS_ONE,
parity = serial.PARITY_EVEN,
#xonxoff = serial.XON,
timeout = 0.02,
writeTimeout= 0.02)
else:
self.set_status('disconnected','Scale Not Found')
return None
if len(devices) > 0:
for device in devices:
path = self.input_dir + device
# don't keep probing devices that are not a scale,
# only keep probing if in the past the device was
# confirmed to be a scale
if path not in self.probed_device_paths or path == self.path_to_scale:
_logger.debug('Probing: ' + path)
connection = serial.Serial(path,
baudrate = 9600,
bytesize = serial.SEVENBITS,
stopbits = serial.STOPBITS_ONE,
parity = serial.PARITY_EVEN,
timeout = 0.02,
writeTimeout= 0.02)
connection.write("W")
self.probed_device_paths.append(path)
if self._get_raw_response(connection):
_logger.debug(path + ' is scale')
self.path_to_scale = path
self.set_status('connected','Connected to '+device)
return connection
else:
_logger.debug('Already probed: ' + path)
self.set_status('disconnected','Scale Not Found')
return None
except Exception as e:
self.set_status('error',str(e))
return None