summaryrefslogtreecommitdiff
path: root/addons/hw_scanner/controllers/main.py
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2016-06-15 12:40:59 +0200
committerChristophe Simonis <chs@odoo.com>2016-06-15 12:40:59 +0200
commitbaf494c67ba7ecba331b24bcfa5eed9bde8a16da (patch)
tree3b2c9ec3cacabcf0a5b0fb78a667d5e1b27505dc /addons/hw_scanner/controllers/main.py
parent133490b4d0e347d75bab20da8e5e0ad1f95d3a2d (diff)
parent1d81bb06a47b1aee1b7a0dcdaa03084ddedf8b7b (diff)
[MERGE] forward port of branch saas-9 up to 1d81bb0
# Conflicts: # addons/account_extra_reports/i18n/ca.po # addons/account_extra_reports/i18n/fi.po # addons/account_extra_reports/i18n/pl.po # addons/account_extra_reports/i18n/te.po # addons/account_extra_reports/i18n/zh_CN.po # addons/account_full_reconcile/i18n/hu.po # addons/account_full_reconcile/i18n/pl.po # addons/crm/crm_lead_menu.xml # addons/crm_claim/i18n/es_PE.po # addons/crm_claim/i18n/hu.po # addons/crm_claim/i18n/ja.po # addons/crm_claim/i18n/pl.po # addons/delivery/views/delivery_view.xml # addons/product/product_view.xml # addons/project_timesheet/i18n/es_PE.po # addons/stock/stock_view.xml
Diffstat (limited to 'addons/hw_scanner/controllers/main.py')
-rw-r--r--addons/hw_scanner/controllers/main.py113
1 files changed, 65 insertions, 48 deletions
diff --git a/addons/hw_scanner/controllers/main.py b/addons/hw_scanner/controllers/main.py
index 8e5e8f6af18..ad0f47a2cda 100644
--- a/addons/hw_scanner/controllers/main.py
+++ b/addons/hw_scanner/controllers/main.py
@@ -22,6 +22,13 @@ except ImportError:
_logger.error('Odoo module hw_scanner depends on the evdev python module')
evdev = None
+class ScannerDevice():
+ def __init__(self, path):
+ self.evdev = evdev.InputDevice(path)
+ self.evdev.grab()
+
+ self.barcode = []
+ self.shift = False
class Scanner(Thread):
def __init__(self):
@@ -29,6 +36,7 @@ class Scanner(Thread):
self.lock = Lock()
self.status = {'status':'connecting', 'messages':[]}
self.input_dir = '/dev/input/by-id/'
+ self.open_devices = []
self.barcodes = Queue()
self.keymap = {
2: ("1","!"),
@@ -109,25 +117,33 @@ class Scanner(Thread):
elif status == 'disconnected' and message:
_logger.info('Disconnected Barcode Scanner: %s', message)
- def get_device(self):
+ def get_devices(self):
try:
if not evdev:
return None
- devices = [ device for device in listdir(self.input_dir)]
- keyboards = [ device for device in devices if ('kbd' in device) and ('keyboard' not in device.lower())]
- scanners = [ device for device in devices if ('barcode' in device.lower()) or ('scanner' in device.lower())]
- if len(scanners) > 0:
- self.set_status('connected','Connected to '+scanners[0])
- return evdev.InputDevice(join(self.input_dir,scanners[0]))
- elif len(keyboards) > 0:
- self.set_status('connected','Connected to '+keyboards[0])
- return evdev.InputDevice(join(self.input_dir,keyboards[0]))
+
+ new_devices = [device for device in listdir(self.input_dir)
+ if join(self.input_dir, device) not in [dev.evdev.fn for dev in self.open_devices]]
+ scanners = [device for device in new_devices
+ if (('kbd' in device) and ('keyboard' not in device.lower()))
+ or ('barcode' in device.lower()) or ('scanner' in device.lower())]
+
+ for device in scanners:
+ _logger.debug('opening device %s', join(self.input_dir,device))
+ self.open_devices.append(ScannerDevice(join(self.input_dir,device)))
+
+ if self.open_devices:
+ self.set_status('connected','Connected to '+ str([dev.evdev.name for dev in self.open_devices]))
else:
self.set_status('disconnected','Barcode Scanner Not Found')
- return None
+
+ return self.open_devices
except Exception as e:
self.set_status('error',str(e))
- return None
+ return []
+
+ def release_device(self, dev):
+ self.open_devices.remove(dev)
def get_barcode(self):
""" Returns a scanned barcode. Will wait at most 5 seconds to get a barcode, and will
@@ -150,6 +166,11 @@ class Scanner(Thread):
self.lockedstart()
return self.status
+ def _get_open_device_by_fd(self, fd):
+ for dev in self.open_devices:
+ if dev.evdev.fd == fd:
+ return dev
+
def run(self):
""" This will start a loop that catches all keyboard events, parse barcode
sequences and put them on a timestamped queue that can be consumed by
@@ -160,49 +181,45 @@ class Scanner(Thread):
barcode = []
shift = False
- device = None
+ devices = None
while True: # barcodes loop
- if device: # ungrab device between barcodes and timeouts for plug & play
- try:
- device.ungrab()
- except Exception as e:
- device = None
- self.set_status('error',str(e))
- else:
- time.sleep(5) # wait until a suitable device is plugged
- device = self.get_device()
- if not device:
- continue
+ devices = self.get_devices()
try:
- device.grab()
- shift = False
- barcode = []
-
while True: # keycode loop
- r,w,x = select([device],[],[],5)
+ r,w,x = select({dev.fd: dev for dev in [d.evdev for d in devices]},[],[],5)
if len(r) == 0: # timeout
break
- events = device.read()
-
- for event in events:
- if event.type == evdev.ecodes.EV_KEY:
- #_logger.debug('Evdev Keyboard event %s',evdev.categorize(event))
- if event.value == 1: # keydown events
- if event.code in self.keymap:
- if shift:
- barcode.append(self.keymap[event.code][1])
- else:
- barcode.append(self.keymap[event.code][0])
- elif event.code == 42 or event.code == 54: # SHIFT
- shift = True
- elif event.code == 28: # ENTER, end of barcode
- self.barcodes.put( (time.time(),''.join(barcode)) )
- barcode = []
- elif event.value == 0: #keyup events
- if event.code == 42 or event.code == 54: # LEFT SHIFT
- shift = False
+
+ for fd in r:
+ device = self._get_open_device_by_fd(fd)
+
+ if not evdev.util.is_device(device.evdev.fn):
+ _logger.info('%s disconnected', str(device.evdev))
+ self.release_device(device)
+ break
+
+ events = device.evdev.read()
+
+ for event in events:
+ if event.type == evdev.ecodes.EV_KEY:
+ # _logger.debug('Evdev Keyboard event %s',evdev.categorize(event))
+ if event.value == 1: # keydown events
+ if event.code in self.keymap:
+ if device.shift:
+ device.barcode.append(self.keymap[event.code][1])
+ else:
+ device.barcode.append(self.keymap[event.code][0])
+ elif event.code == 42 or event.code == 54: # SHIFT
+ device.shift = True
+ elif event.code == 28: # ENTER, end of barcode
+ _logger.debug('pushing barcode %s from %s', ''.join(device.barcode), str(device.evdev))
+ self.barcodes.put( (time.time(),''.join(device.barcode)) )
+ device.barcode = []
+ elif event.value == 0: #keyup events
+ if event.code == 42 or event.code == 54: # LEFT SHIFT
+ device.shift = False
except Exception as e:
self.set_status('error',str(e))