diff --git a/addons/hw_escpos/controllers/main.py b/addons/hw_escpos/controllers/main.py index 52307318870..c2e777fcd3a 100644 --- a/addons/hw_escpos/controllers/main.py +++ b/addons/hw_escpos/controllers/main.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import commands import logging import simplejson import os @@ -11,7 +12,7 @@ import math import md5 import openerp.addons.hw_proxy.controllers.main as hw_proxy import subprocess -from threading import Thread +from threading import Thread, Lock from Queue import Queue, Empty try: @@ -39,6 +40,7 @@ class EscposDriver(Thread): def __init__(self): Thread.__init__(self) self.queue = Queue() + self.lock = Lock() self.status = {'status':'connecting', 'messages':[]} def connected_usb_devices(self): @@ -47,6 +49,13 @@ class EscposDriver(Thread): if usb.core.find(idVendor=device['vendor'], idProduct=device['product']) != None: connected.append(device) return connected + + def lockedstart(self): + self.lock.acquire() + if not self.isAlive(): + self.daemon = True + self.start() + self.lock.release() def get_escpos_printer(self): try: @@ -105,6 +114,8 @@ class EscposDriver(Thread): elif task == 'cashbox': if timestamp >= time.time() - 12: self.open_cashbox(printer) + elif task == 'printstatus': + self.print_status(printer) elif task == 'status': pass @@ -113,10 +124,31 @@ class EscposDriver(Thread): _logger.error(e); def push_task(self,task, data = None): - if not self.isAlive(): - self.start() + self.lockedstart() self.queue.put((time.time(),task,data)) + def print_status(self,eprint): + localips = ['0.0.0.0','127.0.0.1','127.0.1.1'] + ips = [ c.split(':')[1].split(' ')[0] for c in commands.getoutput("/sbin/ifconfig").split('\n') if 'inet addr' in c ] + ips = [ ip for ip in ips if ip not in localips ] + eprint.text('\n\n') + eprint.set(align='center',type='b',height=2,width=2) + eprint.text('PosBox Status\n') + eprint.text('\n') + eprint.set(align='center') + + if len(ips) == 0: + eprint.text('ERROR: Could not connect to LAN\n\nPlease check that the PosBox is correc-\ntly connected with a network cable,\n that the LAN is setup with DHCP, and\nthat network addresses are available') + elif len(ips) == 1: + eprint.text('IP Address\n'+ips[0]+'\n') + else: + eprint.text('IP Addresses\n') + for ip in ips: + eprint.text(ip+'\n') + + eprint.text('\n\n') + eprint.cut() + def print_receipt_body(self,eprint,receipt): def check(string): @@ -134,7 +166,6 @@ class EscposDriver(Thread): else: return str(amount) - def printline(left, right='', width=40, ratio=0.5, indent=0): lwidth = int(width * ratio) rwidth = width - lwidth @@ -157,6 +188,7 @@ class EscposDriver(Thread): # Receipt Header if receipt['company']['logo']: + eprint.set(align='center') eprint.print_base64_image(receipt['company']['logo']) eprint.text('\n') else: @@ -245,6 +277,8 @@ class EscposDriver(Thread): driver = EscposDriver() hw_proxy.drivers['escpos'] = driver + +driver.push_task('printstatus') class EscposProxy(hw_proxy.Proxy): diff --git a/addons/hw_scanner/controllers/main.py b/addons/hw_scanner/controllers/main.py index 105856a3e28..8fbdae62db6 100644 --- a/addons/hw_scanner/controllers/main.py +++ b/addons/hw_scanner/controllers/main.py @@ -4,7 +4,7 @@ import os import time from os import listdir from os.path import join -from threading import Thread +from threading import Thread, Lock from select import select from Queue import Queue, Empty @@ -26,6 +26,7 @@ except ImportError: class Scanner(Thread): def __init__(self): Thread.__init__(self) + self.lock = Lock() self.status = {'status':'connecting', 'messages':[]} self.input_dir = '/dev/input/by-id/' self.barcodes = Queue() @@ -86,6 +87,12 @@ class Scanner(Thread): 57:(" "," "), } + def lockedstart(self): + self.lock.acquire() + if not self.isAlive(): + self.start() + self.lock.release() + def set_status(self, status, message = None): if status == self.status['status']: if message != None and message != self.status['messages'][-1]: @@ -102,8 +109,6 @@ class Scanner(Thread): elif status == 'disconnected' and message: _logger.warning('Disconnected Barcode Scanner: '+message) - - def get_device(self): try: if not evdev: @@ -135,6 +140,8 @@ class Scanner(Thread): busy reading another barcode """ + self.lockedstart() + while True: try: timestamp, barcode = self.barcodes.get(True, 5) @@ -144,8 +151,7 @@ class Scanner(Thread): return '' def get_status(self): - if not s.isAlive(): - s.start() + self.lockedstart() return self.status def run(self): @@ -209,7 +215,6 @@ hw_proxy.drivers['scanner'] = s class ScannerDriver(hw_proxy.Proxy): @http.route('/hw_proxy/scanner', type='json', auth='none', cors='*') def scanner(self): - if not s.isAlive(): - s.start() return s.get_barcode() + diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index 8eb32d63873..683cfaeb08b 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -162,25 +162,37 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal }, // find a proxy and connects to it. for options see find_proxy + // - force_ip : only try to connect to the specified ip. + // - port: what port to listen to (default 8069) + // - progress(fac) : callback for search progress ( fac in [0,1] ) autoconnect: function(options){ var self = this; this.set_connection_status('connecting',{}); + var found_url = new $.Deferred(); var success = new $.Deferred(); - this.find_proxy(options) - .then(function(proxies){ - if(proxies.length > 0){ - self.connect(proxies[0]) - .then(function(){ - success.resolve(); - },function(){ - self.set_connection_status('disconnected'); - success.reject(); - }); - }else{ - self.set_connection_status('disconnected'); - success.reject(); - } + + if ( options.force_ip ){ + // if the ip is forced by server config, bailout on fail + found_url = this.try_hard_to_connect(options.force_ip, options) + }else if( localStorage['hw_proxy_url'] ){ + // try harder when we remember a good proxy url + found_url = this.try_hard_to_connect(localStorage['hw_proxy_url'], options) + .then(null,function(){ + return self.find_proxy(options); + }); + }else{ + // just find something quick + found_url = this.find_proxy(options); + } + + success = found_url.then(function(url){ + return self.connect(url); }); + + success.fail(function(){ + self.set_connection_status('disconnected'); + }); + return success; }, @@ -217,10 +229,50 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal } }, - // returns as a deferred a list of valid hosts urls that can be used as proxy. + // try several time to connect to a known proxy url + try_hard_to_connect: function(url,options){ + options = options || {}; + var port = ':' + (options.port || '8069'); + + this.set_connection_status('connecting'); + + if(url.indexOf('//') < 0){ + url = 'http://'+url; + } + + if(url.indexOf(':',5) < 0){ + url = url+port; + } + + // try real hard to connect to url, with a 1sec timeout and up to 'retries' retries + function try_real_hard_to_connect(url, retries, done){ + + done = done || new $.Deferred(); + + var c = $.ajax({ + url: url + '/hw_proxy/hello', + method: 'GET', + timeout: 1000, + }) + .done(function(){ + done.resolve(url); + }) + .fail(function(){ + if(retries > 0){ + try_real_hard_to_connect(url,retries-1,done); + }else{ + done.reject(); + } + }); + return done; + } + + return try_real_hard_to_connect(url,3); + }, + + // returns as a deferred a valid host url that can be used as proxy. // options: // - port: what port to listen to (default 8069) - // - force_ip : limit the search to the specified ip // - progress(fac) : callback for search progress ( fac in [0,1] ) find_proxy: function(options){ options = options || {}; @@ -228,36 +280,17 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal var port = ':' + (options.port || '8069'); var urls = []; var found = false; - var proxies = []; - var done = new $.Deferred(); var parallel = 8; + var done = new $.Deferred(); // will be resolved with the proxies valid urls var threads = []; var progress = 0; - this.set_connection_status('connecting'); - if(options.force_ip){ - var url = options.force_ip; - if(url.indexOf('//') < 0){ - url = 'http://'+url; - } - if(url.indexOf(':',5) < 0){ - url = url+port; - } - urls.push(url); - }else{ - if(localStorage['hw_proxy_url']){ - urls.push(localStorage['hw_proxy_url']); - } - - urls.push('http://localhost'+port); - - for(var i = 0; i < 256; i++){ - urls.push('http://192.168.0.'+i+port); - urls.push('http://192.168.1.'+i+port); - urls.push('http://192.168.2.'+i+port); - urls.push('http://10.0.0.'+i+port); - } + urls.push('http://localhost'+port); + for(var i = 0; i < 256; i++){ + urls.push('http://192.168.0.'+i+port); + urls.push('http://192.168.1.'+i+port); + urls.push('http://10.0.0.'+i+port); } var prog_inc = 1/urls.length; @@ -269,40 +302,39 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal } } - function thread(url,done){ - if(!url){ + function thread(done){ + var url = urls.shift(); + + done = done || new $.Deferred(); + + if( !url || found || !self.searching_for_proxy ){ done.resolve(); + return done; } + var c = $.ajax({ url: url + '/hw_proxy/hello', method: 'GET', - timeout: 300, + timeout: 400, }).done(function(){ found = true; update_progress(); - proxies.push(url); done.resolve(url); }) .fail(function(){ update_progress(); - var next_url = urls.shift(); - if(found ||! self.searching_for_proxy || !next_url){ - done.resolve(); - }else{ - thread(next_url,done); - } + thread(done); }); + return done; } this.searching_for_proxy = true; - for(var i = 0; i < Math.min(parallel,urls.length); i++){ - threads.push(thread(urls.shift(),new $.Deferred())); + for(var i = 0, len = Math.min(parallel,urls.length); i < len; i++){ + threads.push(thread()); } - var done = new $.Deferred(); - $.when.apply($,threads).then(function(){ var urls = []; for(var i = 0; i < arguments.length; i++){ @@ -310,7 +342,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal urls.push(arguments[i]); } } - done.resolve(urls); + done.resolve(urls[0]); }); return done; diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index f2a254593d1..a2f0759d1a1 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -258,8 +258,8 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa var total = order ? order.getTotalTaxIncluded() : 0; var taxes = order ? total - order.getTotalTaxExcluded() : 0; - this.el.querySelector('.summary .total > .value').innerText = this.format_currency(total); - this.el.querySelector('.summary .total .subentry .value').innerText = this.format_currency(taxes); + this.el.querySelector('.summary .total > .value').textContent = this.format_currency(total); + this.el.querySelector('.summary .total .subentry .value').textContent = this.format_currency(taxes); }, }); diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index 748fcbfee1b..d0cd945d4f4 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -635,9 +635,9 @@ Shop:

-
+                
-
+
@@ -711,9 +711,9 @@

-
+                
-
+