diff --git a/hw_customer_display/__init__.py b/hw_customer_display/__init__.py index d362d317..0914de44 100644 --- a/hw_customer_display/__init__.py +++ b/hw_customer_display/__init__.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- ############################################################################## # -# Hardware Customer Display module for OpenERP +# Hardware Customer Display module for Odoo # Copyright (C) 2014 Akretion (http://www.akretion.com) # @author Alexis de Lattre # diff --git a/hw_customer_display/__openerp__.py b/hw_customer_display/__openerp__.py index 59ca8f19..ef05e105 100644 --- a/hw_customer_display/__openerp__.py +++ b/hw_customer_display/__openerp__.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- ############################################################################## # -# Hardware Customer Display module for OpenERP +# Hardware Customer Display module for Odoo # Copyright (C) 2014 Akretion (http://www.akretion.com) # @author Alexis de Lattre # @@ -26,22 +26,24 @@ 'version': '0.1', 'category': 'Hardware Drivers', 'license': 'AGPL-3', - 'summary': 'Adds a support for Customer LCD in Point of Sale', + 'summary': 'Adds support for Customer Display in the Point of Sale', 'description': """ Hardware Customer Display ========================= -This module adds support for Customer Display in the Point of Sale. It has been tested with a Bixolon BCD-1100 (http://www.bixolon.com/html/en/product/product_detail.xhtml?prod_id=61), but should support most serial and USB-serial LCD displays out-of-the-box or with inheritance of a few functions. This module is designed to be installed on the *POSbox* (i.e. the proxy on which the USB devices are connected) and not on the Odoo server. +This module adds support for Customer Display in the Point of Sale. This module is designed to be installed on the *POSbox* (i.e. the proxy on which the USB devices are connected) and not on the main Odoo server. On the main Odoo server, you should install the module *pos_customer_display*. The configuration of the hardware is done in the configuration file of the Odoo server of the POSbox. You should add the following entries in the configuration file: * customer_display_device_name (default = /dev/ttyUSB0) * customer_display_device_rate (default = 9600) * customer_display_device_timeout (default = 2 seconds) -* customer_display_device_rows (default = 2) -* customer_display_device_cols (default = 20) -This module has been developped during a POS code sprint at Akretion France from July 7th to July 10th 2014. +The number of rows and cols of the Customer Display (usually 2 x 20) should be configured on the main Odoo server, in the menu Point of Sale > Configuration > Point of Sales. + +It has been tested with a Bixolon BCD-1100 (http://www.bixolon.com/html/en/product/product_detail.xhtml?prod_id=61), but should support most serial and USB-serial LCD displays out-of-the-box or with inheritance of a few functions. To setup the BCD-1100 on Linux, you will find some technical instructions on this page : http://techtuxwords.blogspot.fr/2012/12/linux-and-bixolon-bcd-1100.html + +This module has been developped during a POS code sprint at Akretion France from July 7th to July 10th 2014. This module is part of the POS project of the Odoo Community Association http://odoo-community.org/. You are invited to become a member and/or get involved in the Association ! Please contact Alexis de Lattre from Akretion for any help or question about this module. """, diff --git a/hw_customer_display/controllers/__init__.py b/hw_customer_display/controllers/__init__.py index 76e27a99..7ae94c9e 100644 --- a/hw_customer_display/controllers/__init__.py +++ b/hw_customer_display/controllers/__init__.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- ############################################################################## # -# Hardware Customer Display module for OpenERP +# Hardware Customer Display module for Odoo # Copyright (C) 2014 Akretion (http://www.akretion.com) # @author Alexis de Lattre # diff --git a/hw_customer_display/controllers/main.py b/hw_customer_display/controllers/main.py index e3a314a2..6d40289b 100644 --- a/hw_customer_display/controllers/main.py +++ b/hw_customer_display/controllers/main.py @@ -1,7 +1,7 @@ # -*- encoding: utf-8 -*- ############################################################################## # -# Hardware Customer Display module for OpenERP +# Hardware Customer Display module for Odoo # Copyright (C) 2014 Akretion (http://www.akretion.com) # @author Alexis de Lattre # @@ -48,10 +48,6 @@ class CustomerDisplayDriver(Thread): 'customer_display_device_rate', 9600)) self.device_timeout = int(config.get( 'customer_display_device_timeout', 2)) - self.device_rows = int(config.get( - 'customer_display_device_rows', 2)) - self.device_cols = int(config.get( - 'customer_display_device_cols', 20)) self.serial = False def get_status(self): @@ -91,12 +87,8 @@ class CustomerDisplayDriver(Thread): def display_text(self, lines): logger.debug( "Preparing to send the following lines to LCD: %s" % lines) - if len(lines) > self.device_rows: - logger.error( - 'Odoo POS sends %d rows but LCD only has %d rows' - % (len(lines), self.device_rows)) - return - assert len(lines) <= self.device_rows, 'Too many lines' + # We don't check the number of rows/cols here, because it has already + # been checked in the POS client in the JS code lines_ascii = [] for line in lines: lines_ascii.append(unidecode(line)) @@ -104,11 +96,6 @@ class CustomerDisplayDriver(Thread): for dline in lines_ascii: row += 1 self.move_cursor(1, row) - if len(line) > self.device_cols: - logger.error( - 'Odoo POS sends %d characters but LCD only has %d cols' - % (len(line), self.device_cols)) - return self.serial_write(dline) def setup_customer_display(self): @@ -137,6 +124,15 @@ class CustomerDisplayDriver(Thread): self.serial.write(text) def send_text_customer_display(self, text_to_display): + '''This function sends the data to the serial/usb port. + We open and close the serial connection on every message display. + Why ? + 1. Because it is not a problem for the customer display + 2. Because it is not a problem for performance, according to my tests + 3. Because it allows recovery on errors : you can unplug/replug the + customer display and it will work again on the next message without + problem + ''' lines = simplejson.loads(text_to_display) assert isinstance(lines, list), 'lines_list should be a list' try: diff --git a/hw_customer_display/test-scripts/customer-display-test.py b/hw_customer_display/test-scripts/customer-display-test.py new file mode 100755 index 00000000..ad3a50d4 --- /dev/null +++ b/hw_customer_display/test-scripts/customer-display-test.py @@ -0,0 +1,68 @@ +#! /usr/bin/python +# -*- encoding: utf-8 -*- +# Author : Alexis de Lattre +# The licence is in the file __openerp__.py +# This is a test script, that you can use if you want to test/play +# with the customer display independantly from the Odoo server +# It has been tested with a Bixolon BCD-1100 + +from serial import Serial +from unidecode import unidecode +import sys + +DEVICE = '/dev/ttyUSB0' +DEVICE_RATE = 9600 +DEVICE_COLS = 20 + + +def display_text(ser, line1, line2): + print "convert to ascii" + line1 = unidecode(line1) + line2 = unidecode(line2) + print "set lines to the right lenght (%s)" % DEVICE_COLS + for line in [line1, line2]: + if len(line) < DEVICE_COLS: + line += ' ' * (DEVICE_COLS - len(line)) + elif len(line) > DEVICE_COLS: + line = line[0:DEVICE_COLS] + assert len(line) == DEVICE_COLS, 'Wrong length' + print "try to clear display" + ser.write('\x0C') + print "clear done" + print "try to position at start of 1st line" + ser.write('\x1B\x6C' + chr(1) + chr(1)) + print "position done" + print "try to write 1st line" + ser.write(line1) + print "write 1st line done" + print "try to position at start of 2nd line" + ser.write('\x1B\x6C' + chr(1) + chr(2)) + print "position done" + print "try to write 2nd line" + ser.write(line2) + print "write done" + + +def open_close_display(line1, line2): + ser = False + try: + print "open serial port" + ser = Serial(DEVICE, DEVICE_RATE, timeout=2) + print "serial port open =", ser.isOpen() + print "try to set cursor to off" + ser.write('\x1F\x43\x00') + print "cursor set to off" + display_text(ser, line1, line2) + except Exception, e: + print "EXCEPTION e=", e + sys.exit(1) + finally: + if ser: + print "close serial port" + ser.close() + + +if __name__ == '__main__': + line1 = u'POS Code Sprint' + line2 = u'@ Akretion 2014/07' + open_close_display(line1, line2)