Support for Epson ESC/POS printer command system.
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
escpos Bump version from 0.1 to 0.2 Dec 12, 2018
requirements Added Bluetooth interface connection Mar 6, 2018
.coveragerc
.gitignore
LICENSE
MANIFEST.in
README.rst Fixed README markup for PyPI renderer Dec 12, 2018
setup.cfg Added tests for CB55-C and Nitere NPDV-1020 Feb 4, 2017
setup.py Printer implementations provide column widths Mar 8, 2018
tox.ini Preliminary support for Python 3 Jan 11, 2017

README.rst

PyESCPOS

Development status Supported Python versions License Latest version

A Python support for Epson© ESC/POS® compatible printers. Read more at Epson ESCPOS FAQ (PDF document).

This project is inspired on Manuel F. Martinez work for python-escpos implementation, among other projects, whose specific bits of work (available here on Github and many other open-source repositories) has helped so much.

The ESC/POS® is a standard that every manufacturer tend to modify to suit their (even already implemented) needs. Indeed, there is no standard but something awkward, an illusion of a standard. On the surface, one can say that it's pretty much the same, but when you look just a little bit more deeper, you quickly realize that they are almost completely different, even between models belonging to the same manufacturer.

This project aims to make viable the use, at the point-of-sale (POS), of different printers (the most common ones, at least) that are minimally based on ESC/POS® standard, without need to modify the client application code. To achieve this, it is necessary to set a lowest common denominator between needed features and provide implementations that seek to meet this minimum.

Current Implementations

Current implementations was tested against following hardware:

Manufacturer Models Firmware Versions Notes
Bematech S/A MP-4200 TH 1.3, 1.6  
Epson TM-T20 1.14  
Elgin Elgin i9 1.03.20, 1.03.24, 1.03.31  
Elgin Elgin i7 1.00.08  
Elgin Elgin RM-22 1.00.09 Elgin RM-22 portable thermal mini printer
Nitere NPDV-1020
Multifunction Terminal model TMF-101/IG (an alias for CB55-C model)
Unknown OEM CB55-C 1.3.5 Embedded in Nitere NPDV-1020 (model TMF-101/IG)
Urmet Daruma DR700 L/H/M and DR700 L-e/H-e 02.51.00, 01.20.00, 01.21.00  
Urmet Daruma DR800 L/H 03.13.01  

You can get a list of all available implementations with the following snippet:

from escpos import helpers

for impl in helpers.find_implementations(sort_by='model.name'):
    print('{:.<25} {}'.format(impl.model.name, impl.fqname))

Which produces an output similar to:

Bematech MP-4200 TH...... escpos.impl.bematech.MP4200TH
CB55-C................... escpos.impl.unknown.CB55C
Daruma DR700............. escpos.impl.daruma.DR700
Daruma DR800............. escpos.impl.daruma.DR800
Elgin I7................. escpos.impl.elgin.ElginI7
Elgin I9................. escpos.impl.elgin.ElginI9
Elgin RM-22.............. escpos.impl.elgin.ElginRM22
Epson TM-T20............. escpos.impl.epson.TMT20
Generic Daruma........... escpos.impl.daruma.DarumaGeneric
Generic ESC/POS.......... escpos.impl.epson.GenericESCPOS
Generic Elgin............ escpos.impl.elgin.ElginGeneric
Nitere NPDV-1020......... escpos.impl.nitere.NitereNPDV1020

Usage Examples

Serial RS232 Example

Serial communications support requires PySerial version 2.7 or later.

from escpos import SerialConnection
from escpos.impl.epson import GenericESCPOS

# assumes RTS/CTS for 'ttyS5' and infers an instance of RTSCTSConnection
conn = SerialConnection.create('/dev/ttyS5:9600,8,1,N')
printer = GenericESCPOS(conn)
printer.init()
printer.text('Hello World!')

Network TCP/IP Example

You can connect to your printer through network TCP/IP interface.

from escpos import NetworkConnection
from escpos.impl.epson import GenericESCPOS

conn = NetworkConnection.create('10.0.0.101:9100')
printer = GenericESCPOS(conn)
printer.init()
printer.text('Hello World!')

Bluetooth Example

You can connect to your printer through a bluetooth interface (only via RFCOMM). Bluetooth support requires PyBluez version 0.22.

from escpos import BluetoothConnection
from escpos.impl.epson import GenericESCPOS

# uses SPD (service port discovery) services to find which port to connect to
conn = BluetoothConnection.create('00:01:02:03:04:05')
printer = GenericESCPOS(conn)
printer.init()
printer.text('Hello World!')

If you know in which port you can connect beforehand, just pass its number after device address using a forward slash, for example 00:01:02:03:04:05/4, will connect to port 4 on 00:01:02:03:04:05 address.

File Print Example

This printer “prints” just into a file-handle. Especially on *nix-systems this comes very handy. A common use case is when you hava parallel port printer or any other printer that are directly attached to the filesystem. Note that you may want to stay away from using USB-to- Parallel-Adapters since they are extremely unreliable and produce many arbitrary errors.

from escpos import FileConnection
from escpos.impl.elgin import ElginI9

conn = FileConnection('/dev/usb/lp1')
printer = ElginI9(conn)
printer.init()
printer.text('Hello World!')
print(printer.device.output)

Dummy Print Example

The Dummy-printer is mainly for testing- and debugging-purposes. It stores all of the “output” as raw ESC/POS in a string and returns that.

from escpos import DummyConnection
from escpos.impl.epson import GenericESCPOS

conn = DummyConnection()
printer = GenericESCPOS(conn)
printer.init()
printer.text('Hello World!')
print(printer.device.output)

Printing Barcodes

There is a default set of parameters for printing barcodes. Each ESC/POS implementation will take care of the details and try their best to print your barcode as you asked.

from escpos import barcode
from escpos import SerialConnection
from escpos.impl.epson import GenericESCPOS

conn = SerialConnection.create('COM1:9600,8,1,N')
printer = GenericESCPOS(conn)
printer.init()
printer.code128('0123456789',
        barcode_height=96, # ~12mm (~1/2")
        barcode_width=barcode.BARCODE_DOUBLE_WIDTH,
        barcode_hri=barcode.BARCODE_HRI_BOTTOM)

printer.lf()

printer.ean13('4007817525074',
        barcode_height=120, # ~15mm (~9/16"),
        barcode_width=barcode.BARCODE_NORMAL_WIDTH,
        barcode_hri=barcode.BARCODE_HRI_TOP)

printer.cut()

The barcode data should be complete including check digits and any other payload data required that makes that data valid for the symbology you're dealing with. Thus, if you need to print an EAN-13 barcode, for example, you need to provide all thirteen digits.

Configuring Resilient Connections

Network (TCP/IP) and Bluetooth (RFCOMM) connections provided by PyESCPOS both use a simple exponential backoff algorithm to implement a (more) resilient connection to the device. Your application or your users can configure backoff retry parameters through a well-known INI-like file format:

[retry]
max_tries = 3
delay = 3
factor = 2

Whose parameters are:

  • max_tries (integer > 0) Number of tries before give up;
  • delay (integer > 0) Delay between retries (in seconds);
  • factor (integer > 1) Multiply factor in which delay will be increased for the next retry.

Normally that file lives in ~/.escpos/config.cfg but you can determine where you want to put this file. For that you must call config.configure function indicating full path to the configuration file, for example:

from escpos import config
config.configure(filename='/path/to/config.cfg')

Your application must call config.configure before importing anything else.

More Examples

Eventually you may find more examples in the PyESCPOS wiki pages.

Disclaimer

It is important that you read this disclaimer.

None of the vendors cited in this project agree or endorse any of the patterns or implementations. Its names are used only to maintain context.