import math
import openerp.addons.hw_proxy.controllers.main as hw_proxy
import subprocess
+from threading import Thread
+from Queue import Queue, Empty
try:
import usb.core
_logger = logging.getLogger(__name__)
-class EscposDriver(hw_proxy.Proxy):
-
- supported_printers = [
- { 'vendor' : 0x04b8, 'product' : 0x0e03, 'name' : 'Epson TM-T20' }
- ]
+class EscposDriver(Thread):
+ def __init__(self):
+ Thread.__init__(self)
+ self.queue = None
+ self.status = {'status':'connecting', 'messages':[]}
+
+ self.supported_printers = [
+ { 'vendor' : 0x04b8, 'product' : 0x0e03, 'name' : 'Epson TM-T20' },
+ { 'vendor' : 0x04b8, 'product' : 0x0202, 'name' : 'Epson TM-T70' },
+ ]
def connected_usb_devices(self,devices):
connected = []
return connected
def get_escpos_printer(self):
- printers = self.connected_usb_devices(self.supported_printers)
- if len(printers) > 0:
- return escpos.printer.Usb(printers[0]['vendor'], printers[0]['product'])
- else:
+ try:
+ printers = self.connected_usb_devices(self.supported_printers)
+ if len(printers) > 0:
+ self.set_status('connected','Connected to '+printers[0]['name'])
+ return escpos.printer.Usb(printers[0]['vendor'], printers[0]['product'])
+ else:
+ self.set_status('disconnected','Printer Not Found')
+ return None
+ except Exception as e:
+ self.set_status('error',str(e))
return None
-
- @http.route('/hw_proxy/open_cashbox', type='json', auth='admin')
- def open_cashbox(self):
- _logger.info('ESC/POS: OPEN CASHBOX')
- eprint = self.get_escpos_printer()
- if eprint != None:
- eprint.cashdraw(2)
- eprint.cashdraw(5)
- else:
- _logger.error('ESC/POS: OPEN CASHBOX: could not find printer')
-
- @http.route('/hw_proxy/print_receipt', type='json', auth='admin')
- def print_receipt(self, receipt):
- _logger.info('ESC/POS: PRINT RECEIPT')
- eprint = self.get_escpos_printer()
- if eprint != None:
- self.print_receipt_body(eprint,receipt)
- eprint.cut()
+
+ def get_status(self):
+ self.push_task('status')
+ return self.status
+
+ def open_cashbox(printer):
+ printer.cashdraw(2)
+ printer.cashdraw(5)
+
+ def set_status(self, status, message = None):
+ if status == self.status['status']:
+ if message != None and message != self.status['messages'][-1]:
+ self.status['messages'].append(message)
else:
- _logger.error('ESC/POS: PRINT RECEIPT: could not find printer')
-
+ self.status['status'] = status
+ if message:
+ self.status['messages'] = [message]
+ else:
+ self.status['messages'] = []
+
+ if status == 'error' and message:
+ _logger.error('ESC/POS Error: '+message)
+ elif status == 'disconnected' and message:
+ _logger.warning('ESC/POS Device Disconnected: '+message)
+
+ def run(self):
+ self.queue = Queue()
+ while True:
+ try:
+ timestamp, task, data = self.queue.get(True)
+
+ printer = self.get_escpos_printer()
+
+ if printer == None:
+ if task != 'status':
+ self.queue.put((timestamp,task,data))
+ time.sleep(5)
+ continue
+ elif task == 'receipt':
+ if timestamp >= time.time() - 1 * 60 * 60:
+ self.print_receipt_body(printer,data)
+ printer.cut()
+ elif task == 'cashbox':
+ if timestamp >= time.time() * 12:
+ self.open_cashbox(printer)
+ elif task == 'status':
+ pass
+
+ except Exception as e:
+ self.set_status('error', str(e))
+ _logger.error(e);
+
+ def push_task(self,task, data = None):
+ if not self.isAlive():
+ self.start()
+ self.queue.put((time.time(),task,data))
+
def print_receipt_body(self,eprint,receipt):
def check(string):
+'/'+ str(receipt['date']['year']).zfill(4)
+' '+ str(receipt['date']['hour']).zfill(2)
+':'+ str(receipt['date']['minute']).zfill(2) )
+
+driver = EscposDriver()
+
+hw_proxy.drivers['escpos'] = driver
+class EscposProxy(hw_proxy.Proxy):
+
+ @http.route('/hw_proxy/open_cashbox', type='json', auth='admin')
+ def open_cashbox(self):
+ _logger.info('ESC/POS: OPEN CASHBOX')
+ driver.push_task('cashbox')
+
+ @http.route('/hw_proxy/print_receipt', type='json', auth='admin')
+ def print_receipt(self, receipt):
+ _logger.info('ESC/POS: PRINT RECEIPT')
+ driver.push_task('receipt',receipt)
+
import time
import random
import subprocess
+import simplejson
import werkzeug
import werkzeug.wrappers
_logger = logging.getLogger(__name__)
from openerp.addons.web.controllers.main import manifest_list, module_boot, html_template
+# drivers modules must add to drivers an object with a get_status() method
+# so that 'status' can return the status of all active drivers
+drivers = {}
+
class Proxy(http.Controller):
def __init__(self):
self.scale = 'closed'
self.scale_weight = 0.0
+ def get_status(self):
+ statuses = {}
+ for driver in drivers:
+ statuses[driver] = drivers[driver].get_status()
+ return statuses
+
@http.route('/hw_proxy/hello', type='http', auth='admin')
- def helloajx(self):
+ def hello(self):
return request.make_response('ping', {
'Cache-Control': 'no-cache',
'Content-Type': 'text/html; charset=utf-8',
'Access-Control-Allow-Methods': 'GET',
})
- @http.route('/hw_proxy/handshake', type='json', auth='admin')
- def handshake(self):
- return True
+ @http.route('/hw_proxy/status', type='http', auth='admin')
+ def status_http(self):
+ resp = '<html>\n<body>\n<h1>Hardware Proxy Status</h1>\n'
+ statuses = self.get_status()
+ for driver in statuses:
+
+ status = statuses[driver]
+
+ if status['status'] == 'connecting':
+ color = 'black'
+ elif status['status'] == 'connected':
+ color = 'green'
+ else:
+ color = 'red'
+
+ resp += "<h2 style='color:"+color+";'>"+driver+' : '+status['status']+"</h2>\n"
+ resp += "<ul>\n"
+ for msg in status['messages']:
+ resp += '<li>'+msg+'</li>\n'
+ resp += "</ul>\n"
+ resp += "<script>\n\tsetTimeout(function(){window.location.reload();},30000);\n</script>\n</body>\n</html>\n\n"
+
+ return request.make_response(resp,{
+ 'Cache-Control': 'no-cache',
+ 'Content-Type': 'text/html; charset=utf-8',
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Methods': 'GET',
+ })
+
+ @http.route('/hw_proxy/status', type='json', auth='admin')
+ def status_json(self):
+ return request.make_response(simplejson.dumps(self.get_status()),{
+ 'Cache-Control': 'no-cache',
+ 'Content-Type': 'text/html; charset=utf-8',
+ 'Access-Control-Allow-Origin': '*',
+ 'Access-Control-Allow-Methods': 'GET',
+ })
@http.route('/hw_proxy/scan_item_success', type='json', auth='admin')
def scan_item_success(self, ean):
class Scanner(Thread):
def __init__(self):
Thread.__init__(self)
+ self.status = {'status':'connecting', 'messages':[]}
self.input_dir = '/dev/input/by-id/'
+ self.barcodes = Queue()
self.keymap = {
2: ("1","!"),
3: ("2","@"),
57:(" "," "),
}
+ def set_status(self, status, message = None):
+ if status == self.status['status']:
+ if message != None and message != self.status['messages'][-1]:
+ self.status['messages'].append(message)
+ else:
+ self.status['status'] = status
+ if message:
+ self.status['messages'] = [message]
+ else:
+ self.status['messages'] = []
+
+ if status == 'error' and message:
+ _logger.error('Barcode Scanner Error: '+message)
+ elif status == 'disconnected' and message:
+ _logger.warning('Disconnected Barcode Scanner: '+message)
+
+
+
def get_device(self):
try:
if not evdev:
keyboards = [ device for device in devices if 'kbd' in device ]
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]))
else:
- _logger.error('Could not find the Barcode Scanner')
+ self.set_status('disconnected','Barcode Scanner Not Found')
return None
except Exception as e:
- _logger.error('Found the Barcode Scanner, but unable to access it\n Exception: ' + str(e))
+ self.set_status('error',str(e))
return None
@http.route('/hw_proxy/Vis_scanner_connected', type='json', auth='admin')
return barcode
except Empty:
return ''
+
+ def get_status(self):
+ return self.status
def run(self):
""" This will start a loop that catches all keyboard events, parse barcode
try:
device.ungrab()
except Exception as e:
- _logger.error('Unable to release barcode scanner\n Exception:'+str(e))
+ self.set_status('error',str(e))
device = self.get_device()
if not device:
time.sleep(5) # wait until a suitable device is plugged
shift = False
except Exception as e:
- _logger.error('Could not read Barcode Scanner Events:\n Exception: '+str(e))
+ self.set_status('error',str(e))
s = Scanner()
+hw_proxy.drivers['scanner'] = s
+
class ScannerDriver(hw_proxy.Proxy):
- @http.route('/hw_proxy/is_scanner_connected', type='json', auth='admin')
- def is_scanner_connected(self):
- if not s.isAlive():
- s.start()
- return s.get_device() != None
-
@http.route('/hw_proxy/scanner', type='json', auth='admin')
def scanner(self):
if not s.isAlive():