From f3da22c0671d0fc2d4cd5a6aacb056bd51feab94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Thu, 24 Apr 2014 19:12:59 +0200 Subject: [PATCH 1/5] [IMP] point_of_sale, hw_scale: first commit for the hw_scale module, which handles scale connections for the POS bzr revid: fva@openerp.com-20140424171259-hi9ma6w0fkdfrqnv --- addons/hw_proxy/controllers/main.py | 37 ---- addons/hw_scale/__init__.py | 25 +++ addons/hw_scale/__openerp__.py | 45 ++++ addons/hw_scale/controllers/__init__.py | 3 + addons/hw_scale/controllers/main.py | 202 ++++++++++++++++++ addons/hw_scale/mettler.py | 100 +++++++++ addons/point_of_sale/static/src/js/devices.js | 42 +--- addons/point_of_sale/static/src/js/screens.js | 11 +- 8 files changed, 383 insertions(+), 82 deletions(-) create mode 100644 addons/hw_scale/__init__.py create mode 100644 addons/hw_scale/__openerp__.py create mode 100644 addons/hw_scale/controllers/__init__.py create mode 100644 addons/hw_scale/controllers/main.py create mode 100755 addons/hw_scale/mettler.py diff --git a/addons/hw_proxy/controllers/main.py b/addons/hw_proxy/controllers/main.py index ea9b45c1b35..c65c7966b7c 100644 --- a/addons/hw_proxy/controllers/main.py +++ b/addons/hw_proxy/controllers/main.py @@ -24,9 +24,6 @@ from openerp.addons.web.controllers.main import manifest_list, module_boot, html drivers = {} class Proxy(http.Controller): - def __init__(self): - self.scale = 'closed' - self.scale_weight = 0.0 def get_status(self): statuses = {} @@ -154,40 +151,6 @@ class Proxy(http.Controller): """ print "help_canceled" - @http.route('/hw_proxy/weighting_start', type='json', auth='none', cors='*') - def weighting_start(self): - if self.scale == 'closed': - print "Opening (Fake) Connection to Scale..." - self.scale = 'open' - self.scale_weight = 0.0 - time.sleep(0.1) - print "... Scale Open." - else: - print "WARNING: Scale already Connected !!!" - - @http.route('/hw_proxy/weighting_read_kg', type='json', auth='none', cors='*') - def weighting_read_kg(self): - if self.scale == 'open': - print "Reading Scale..." - time.sleep(0.025) - self.scale_weight += 0.01 - print "... Done." - return self.scale_weight - else: - print "WARNING: Reading closed scale !!!" - return 0.0 - - @http.route('/hw_proxy/weighting_end', type='json', auth='none', cors='*') - def weighting_end(self): - if self.scale == 'open': - print "Closing Connection to Scale ..." - self.scale = 'closed' - self.scale_weight = 0.0 - time.sleep(0.1) - print "... Scale Closed." - else: - print "WARNING: Scale already Closed !!!" - @http.route('/hw_proxy/payment_request', type='json', auth='none', cors='*') def payment_request(self, price): """ diff --git a/addons/hw_scale/__init__.py b/addons/hw_scale/__init__.py new file mode 100644 index 00000000000..a208bc1c551 --- /dev/null +++ b/addons/hw_scale/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +import controllers + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/hw_scale/__openerp__.py b/addons/hw_scale/__openerp__.py new file mode 100644 index 00000000000..c986d88e44c --- /dev/null +++ b/addons/hw_scale/__openerp__.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + + +{ + 'name': 'Weighting Scale Hardware Driver', + 'version': '1.0', + 'category': 'Hardware Drivers', + 'sequence': 6, + 'summary': 'Hardware Driver for Weighting Scales', + 'description': """ +Barcode Scanner Hardware Driver +================================ + +This module allows the point of sale to connect to a scale using a USB HSM Serial Scale Interface, +such as the Mettler Toledo Ariva. + +""", + 'author': 'OpenERP SA', + 'depends': ['hw_proxy'], + 'test': [ + ], + 'installable': True, + 'auto_install': False, +} + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hw_scale/controllers/__init__.py b/addons/hw_scale/controllers/__init__.py new file mode 100644 index 00000000000..b5f0bcc9ec6 --- /dev/null +++ b/addons/hw_scale/controllers/__init__.py @@ -0,0 +1,3 @@ +import main +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/hw_scale/controllers/main.py b/addons/hw_scale/controllers/main.py new file mode 100644 index 00000000000..4c8e1ffd0cd --- /dev/null +++ b/addons/hw_scale/controllers/main.py @@ -0,0 +1,202 @@ +# -*- coding: utf-8 -*- +import logging +import os +import time +from os import listdir +from os.path import join +from threading import Thread, Lock +from select import select +from Queue import Queue, Empty +from bitstring import BitArray + +import openerp +import openerp.addons.hw_proxy.controllers.main as hw_proxy +from openerp import http +from openerp.http import request +from openerp.tools.translate import _ + +_logger = logging.getLogger(__name__) + +try: + import serial +except ImportError: + _logger.error('OpenERP module hw_scale depends on the pyserial python module') + serial = None + + +class Scale(Thread): + def __init__(self): + Thread.__init__(self) + self.lock = Lock() + self.scalelock = Lock() + self.status = {'status':'connecting', 'messages':[]} + self.input_dir = '/dev/serial/by-id/' + self.weight = 0 + self.weight_info = 'ok' + self.device = None + + def lockedstart(self): + with self.lock: + if not self.isAlive(): + self.daemon = True + self.start() + + 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('Scale Error: '+message) + elif status == 'disconnected' and message: + _logger.warning('Disconnected Scale: '+message) + + def get_device(self): + try: + 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]) +# s = serial.Serial("/dev/serial/by-id/usb-METTLER_TOLEDO_15_kg_DI_Firmware_CKOR_F_Ser_CDC-if00",baudrate=9600,bytesize=serial.SEVENBITS,parity=serial.PARITY_EVEN) + 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.01, + writeTimeout= 0.01) + else: + self.set_status('disconnected','Scale Not Found') + return None + except Exception as e: + self.set_status('error',str(e)) + return None + + def get_weight(self): + self.lockedstart() + return self.weight + + def get_weight_info(self): + self.lockedstart() + return self.weight_info + + def get_status(self): + self.lockedstart() + return self.status + + def read_weight(self): + with self.scalelock: + if self.device: + try: + self.device.write('W') + time.sleep(0.2) + answer = [] + + while True: + char = self.device.read(1) + if not char: + break + else: + answer.append(char) + + if '?' in answer: + stat = ord(answer[answer.index('?')+1]) + if stat == 0: + self.weight_info = 'ok' + else: + self.weight_info = [] + if stat & 1 : + self.weight_info.append('moving') + if stat & 1 << 1: + self.weight_info.append('over_capacity') + if stat & 1 << 2: + self.weight_info.append('negative') + if stat & 1 << 3: + self.weight_info.append('outside_zero_capture_range') + if stat & 1 << 4: + self.weight_info.append('center_of_zero') + if stat & 1 << 5: + self.weight_info.append('net_weight') + else: + answer = answer[1:-1] + if 'N' in answer: + answer = answer[0:-1] + self.weight = float(''.join(answer)) + + except Exception as e: + self.set_status('error',str(e)) + self.device = None + + def set_zero(self): + with self.scalelock: + if self.device: + try: + self.device.write('Z') + except Exception as e: + self.set_status('error',str(e)) + self.device = None + + def set_tare(self): + with self.scalelock: + if self.device: + try: + self.device.write('T') + except Exception as e: + self.set_status('error',str(e)) + self.device = None + + def clear_tare(self): + with self.scalelock: + if self.device: + try: + self.device.write('C') + except Exception as e: + self.set_status('error',str(e)) + self.device = None + + def run(self): + self.device = None + + while True: + if self.device: + self.read_weight() + time.sleep(0.05) + else: + with self.scalelock: + self.device = self.get_device() + if not self.device: + time.sleep(5) + +s = Scale() + +hw_proxy.drivers['scale'] = s + +class ScaleDriver(hw_proxy.Proxy): + @http.route('/hw_proxy/scale_read/', type='json', auth='none', cors='*') + def scale_read(self): + return {'weight':s.get_weight(), 'unit':'kg', 'info':s.get_weight_info()} + + @http.route('/hw_proxy/scale_zero/', type='json', auth='none', cors='*') + def scale_zero(self): + s.set_zero() + return True + + @http.route('/hw_proxy/scale_tare/', type='json', auth='none', cors='*') + def scale_tare(self): + s.set_tare() + return True + + @http.route('/hw_proxy/scale_clear_tare/', type='json', auth='none', cors='*') + def scale_clear_tare(self): + s.clear_tare() + return True + + diff --git a/addons/hw_scale/mettler.py b/addons/hw_scale/mettler.py new file mode 100755 index 00000000000..5c5df97a60e --- /dev/null +++ b/addons/hw_scale/mettler.py @@ -0,0 +1,100 @@ +#!/usr/bin/python +import serial +import time +import sys +from bitstring import BitArray + +path = "/dev/serial/by-id/usb-METTLER_TOLEDO_15_kg_DI_Firmware_CKOR_F_Ser_CDC-if00" + +device = serial.Serial(path, + baudrate = 9600, + bytesize = serial.SEVENBITS, + stopbits = serial.STOPBITS_ONE, + parity = serial.PARITY_EVEN, + #xonxoff = serial.XON, + timeout = 0.1, + writeTimeout= 0.1) + +if len(sys.argv) == 1: + cmd = 'weight' +else: + cmd = sys.argv[1] + +def write(stuff): + print stuff + device.write(stuff) + +def read_answer(): + answer = [] + while True: + char = device.read(1) + if not char: + return answer + else: + answer.append(char) + +def print_answer(answer): + print answer + if '?' in answer: + status = answer[answer.index('?')+1] + print 'status_bits: '+BitArray(int=ord(status),length=8).bin + + +if cmd == 'weight': + while True: + time.sleep(0.25) + write('W') + time.sleep(0.25) + print_answer(read_answer()) + +if cmd == 'interactive': + weight = 0 + status = '' + while True: + time.sleep(0.25) + device.write('W') + answer = read_answer() + if '?' in answer: + oldstatus = status + b = answer[answer.index('?')+1] + if b == '\x00' or b == ' ': + pass # ignore status + elif b == 'B': + status = 'too_heavy' + elif b == 'D': + status = 'negative' + elif b == 'A' or b == 'Q' or b == '\x01': + status = 'moving' + else: + status = 'unknown' + print b.__repr__(), BitArray(int=ord(b),length=8).bin + if oldstatus != status: + print status + else: + oldweight = weight + answer = answer[1:-1] + if 'N' in answer: + answer = answer[0:-1] + weight = float(''.join(answer)) + if oldweight != weight: + print weight + + +elif cmd == 'zero': + time.sleep(1) + write('Z') + time.sleep(1) + print_answer(read_answer()) + +elif cmd == 'test': + time.sleep(1) + write('A') + time.sleep(1) + write('B') + time.sleep(1) + answer = read_answer() + if '@' in answer: + print 'all test passed' + else: + print_answer(answer) + diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index f46b156371c..316aea50e43 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -384,47 +384,17 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal return this.message('help_canceled'); }, - //the client is starting to weight - weighting_start: function(){ - var ret = new $.Deferred(); - if(!this.weighting){ - this.weighting = true; - this.message('weighting_start').always(function(){ - ret.resolve(); - }); - }else{ - console.error('Weighting already started!!!'); - ret.resolve(); - } - return ret; - }, - - // the client has finished weighting products - weighting_end: function(){ - var ret = new $.Deferred(); - if(this.weighting){ - this.weighting = false; - this.message('weighting_end').always(function(){ - ret.resolve(); - }); - }else{ - console.error('Weighting already ended !!!'); - ret.resolve(); - } - return ret; - }, - - //returns the weight on the scale. - // is called at regular interval (up to 10x/sec) between a weighting_start() - // and a weighting_end() - weighting_read_kg: function(){ + // returns the weight on the scale. + scale_read: function(){ var self = this; var ret = new $.Deferred(); - this.message('weighting_read_kg',{}) + console.log('scale_read'); + this.message('scale_read',{}) .then(function(weight){ + console.log(weight) ret.resolve(self.use_debug_weight ? self.debug_weight : weight); }, function(){ //failed to read weight - ret.resolve(self.use_debug_weight ? self.debug_weight : 0.0); + ret.resolve(self.use_debug_weight ? self.debug_weight : {weight:0.0, info:'ok'}); }); return ret; }, diff --git a/addons/point_of_sale/static/src/js/screens.js b/addons/point_of_sale/static/src/js/screens.js index 1d6f018ae1b..c58e7d860a0 100644 --- a/addons/point_of_sale/static/src/js/screens.js +++ b/addons/point_of_sale/static/src/js/screens.js @@ -526,12 +526,8 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa }); queue.schedule(function(){ - return self.pos.proxy.weighting_start() - },{ important: true }); - - queue.schedule(function(){ - return self.pos.proxy.weighting_read_kg().then(function(weight){ - self.set_weight(weight); + return self.pos.proxy.scale_read().then(function(weight){ + self.set_weight(weight.weight); }); },{duration:50, repeat: true}); @@ -584,9 +580,6 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa $('body').off('keyup',this.hotkey_handler); this.pos.proxy_queue.clear(); - this.pos.proxy_queue.schedule(function(){ - self.pos.proxy.weighting_end(); - },{ important: true }); }, }); From 3f0a8e8931adfb40b4393074193a00bc20ede601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 25 Apr 2014 14:22:20 +0200 Subject: [PATCH 2/5] [IMP] point_of_sale, hw_scale: various small fixes and improvements for the scale module bzr revid: fva@openerp.com-20140425122220-q7rw1dve8bgs25as --- addons/hw_scale/controllers/main.py | 8 ++++---- addons/point_of_sale/point_of_sale_view.xml | 6 +++--- addons/point_of_sale/static/src/js/devices.js | 2 +- addons/point_of_sale/static/src/js/widgets.js | 16 +++++++++------- addons/point_of_sale/static/src/xml/pos.xml | 2 +- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/addons/hw_scale/controllers/main.py b/addons/hw_scale/controllers/main.py index 4c8e1ffd0cd..3c4aa12a1b9 100644 --- a/addons/hw_scale/controllers/main.py +++ b/addons/hw_scale/controllers/main.py @@ -59,12 +59,11 @@ class Scale(Thread): def get_device(self): try: - 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()) ] + 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]) -# s = serial.Serial("/dev/serial/by-id/usb-METTLER_TOLEDO_15_kg_DI_Firmware_CKOR_F_Ser_CDC-if00",baudrate=9600,bytesize=serial.SEVENBITS,parity=serial.PARITY_EVEN) return serial.Serial(join(self.input_dir,scales[0]), baudrate = 9600, bytesize = serial.SEVENBITS, @@ -97,7 +96,7 @@ class Scale(Thread): if self.device: try: self.device.write('W') - time.sleep(0.2) + time.sleep(0.1) answer = [] while True: @@ -119,6 +118,7 @@ class Scale(Thread): self.weight_info.append('over_capacity') if stat & 1 << 2: self.weight_info.append('negative') + self.weight = 0.0 if stat & 1 << 3: self.weight_info.append('outside_zero_capture_range') if stat & 1 << 4: diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index 7740020e37f..15d2dc64289 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -739,12 +739,10 @@ - + - - @@ -752,6 +750,8 @@ + + diff --git a/addons/point_of_sale/static/src/js/devices.js b/addons/point_of_sale/static/src/js/devices.js index 316aea50e43..2b016445638 100644 --- a/addons/point_of_sale/static/src/js/devices.js +++ b/addons/point_of_sale/static/src/js/devices.js @@ -394,7 +394,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal console.log(weight) ret.resolve(self.use_debug_weight ? self.debug_weight : weight); }, function(){ //failed to read weight - ret.resolve(self.use_debug_weight ? self.debug_weight : {weight:0.0, info:'ok'}); + ret.resolve(self.use_debug_weight ? self.debug_weight : {weight:0.0, unit:'Kg', info:'ok'}); }); return ret; }, diff --git a/addons/point_of_sale/static/src/js/widgets.js b/addons/point_of_sale/static/src/js/widgets.js index 95ff7cbea7e..54aa8d115f0 100644 --- a/addons/point_of_sale/static/src/js/widgets.js +++ b/addons/point_of_sale/static/src/js/widgets.js @@ -693,7 +693,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa 'open_cashbox', 'print_receipt', 'print_pdf_invoice', - 'weighting_read_kg', + 'scale_read', 'payment_status', ], minimized: false, @@ -811,12 +811,6 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa self.pos.proxy.add_notification('transaction_end',function(){ self.$('.status.transaction').removeClass('on'); }); - self.pos.proxy.add_notification('weighting_start',function(){ - self.$('.status.weighting').addClass('on'); - }); - self.pos.proxy.add_notification('weighting_end',function(){ - self.$('.status.weighting').removeClass('on'); - }); }, }); @@ -876,6 +870,14 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa msg += _t('Printer'); } } + if( this.pos.config.iface_electronic_scale ){ + var scale = status.drivers.scale ? status.drivers.scale.status : false; + if( scale != 'connected' && scale != 'connecting' ){ + warning = true; + msg = msg ? msg + ' & ' : msg; + msg += _t('Scale'); + } + } msg = msg ? msg + ' ' + _t('Offline') : msg; this.set_status(warning ? 'warning' : 'connected', msg); }else{ diff --git a/addons/point_of_sale/static/src/xml/pos.xml b/addons/point_of_sale/static/src/xml/pos.xml index 02c6374578b..34d6e729d06 100644 --- a/addons/point_of_sale/static/src/xml/pos.xml +++ b/addons/point_of_sale/static/src/xml/pos.xml @@ -692,7 +692,7 @@
  • Open Cashbox
  • -
  • Read Weighting Scale
  • +
  • Read Weighting Scale
  • From 24852d7ec9f3dda1899c9d25b74349ef7be3addf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 25 Apr 2014 14:32:46 +0200 Subject: [PATCH 3/5] [FIX] hw_scale: remove useless python module bzr revid: fva@openerp.com-20140425123246-lexb4viqi6k7zwgq --- addons/hw_scale/controllers/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/hw_scale/controllers/main.py b/addons/hw_scale/controllers/main.py index 3c4aa12a1b9..ed2d898fcfc 100644 --- a/addons/hw_scale/controllers/main.py +++ b/addons/hw_scale/controllers/main.py @@ -7,7 +7,6 @@ from os.path import join from threading import Thread, Lock from select import select from Queue import Queue, Empty -from bitstring import BitArray import openerp import openerp.addons.hw_proxy.controllers.main as hw_proxy From c0d62797c93f3eca43a8c9666a641538d96c6b80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Fri, 25 Apr 2014 14:40:05 +0200 Subject: [PATCH 4/5] [FIX] hw_scale: remove useless driver test script bzr revid: fva@openerp.com-20140425124005-pugnyq6gsl0gw8yx --- addons/hw_scale/mettler.py | 100 ------------------------------------- 1 file changed, 100 deletions(-) delete mode 100755 addons/hw_scale/mettler.py diff --git a/addons/hw_scale/mettler.py b/addons/hw_scale/mettler.py deleted file mode 100755 index 5c5df97a60e..00000000000 --- a/addons/hw_scale/mettler.py +++ /dev/null @@ -1,100 +0,0 @@ -#!/usr/bin/python -import serial -import time -import sys -from bitstring import BitArray - -path = "/dev/serial/by-id/usb-METTLER_TOLEDO_15_kg_DI_Firmware_CKOR_F_Ser_CDC-if00" - -device = serial.Serial(path, - baudrate = 9600, - bytesize = serial.SEVENBITS, - stopbits = serial.STOPBITS_ONE, - parity = serial.PARITY_EVEN, - #xonxoff = serial.XON, - timeout = 0.1, - writeTimeout= 0.1) - -if len(sys.argv) == 1: - cmd = 'weight' -else: - cmd = sys.argv[1] - -def write(stuff): - print stuff - device.write(stuff) - -def read_answer(): - answer = [] - while True: - char = device.read(1) - if not char: - return answer - else: - answer.append(char) - -def print_answer(answer): - print answer - if '?' in answer: - status = answer[answer.index('?')+1] - print 'status_bits: '+BitArray(int=ord(status),length=8).bin - - -if cmd == 'weight': - while True: - time.sleep(0.25) - write('W') - time.sleep(0.25) - print_answer(read_answer()) - -if cmd == 'interactive': - weight = 0 - status = '' - while True: - time.sleep(0.25) - device.write('W') - answer = read_answer() - if '?' in answer: - oldstatus = status - b = answer[answer.index('?')+1] - if b == '\x00' or b == ' ': - pass # ignore status - elif b == 'B': - status = 'too_heavy' - elif b == 'D': - status = 'negative' - elif b == 'A' or b == 'Q' or b == '\x01': - status = 'moving' - else: - status = 'unknown' - print b.__repr__(), BitArray(int=ord(b),length=8).bin - if oldstatus != status: - print status - else: - oldweight = weight - answer = answer[1:-1] - if 'N' in answer: - answer = answer[0:-1] - weight = float(''.join(answer)) - if oldweight != weight: - print weight - - -elif cmd == 'zero': - time.sleep(1) - write('Z') - time.sleep(1) - print_answer(read_answer()) - -elif cmd == 'test': - time.sleep(1) - write('A') - time.sleep(1) - write('B') - time.sleep(1) - answer = read_answer() - if '@' in answer: - print 'all test passed' - else: - print_answer(answer) - From a57f44393d9b8f7eb1613cec3c9513e9bc960c75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20van=20der=20Essen?= Date: Mon, 28 Apr 2014 11:52:46 +0200 Subject: [PATCH 5/5] [FIX] hw_scale: don't crash if the serial connection gets broken bzr revid: fva@openerp.com-20140428095246-w6pyo8y7rrhsvsjl --- addons/hw_scale/controllers/main.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/addons/hw_scale/controllers/main.py b/addons/hw_scale/controllers/main.py index ed2d898fcfc..161a7896b38 100644 --- a/addons/hw_scale/controllers/main.py +++ b/addons/hw_scale/controllers/main.py @@ -128,7 +128,11 @@ class Scale(Thread): answer = answer[1:-1] if 'N' in answer: answer = answer[0:-1] - self.weight = float(''.join(answer)) + try: + self.weight = float(''.join(answer)) + except ValueError as v: + self.set_status('error','No data Received, please power-cycle the scale'); + self.device = None except Exception as e: self.set_status('error',str(e))