mirror of
https://github.com/bringout/oca-ocb-hw.git
synced 2026-04-23 12:02:00 +02:00
Initial commit: Hw packages
This commit is contained in:
commit
a9d00500da
161 changed files with 10506 additions and 0 deletions
227
odoo-bringout-oca-ocb-hw_escpos/hw_escpos/escpos/printer.py
Normal file
227
odoo-bringout-oca-ocb-hw_escpos/hw_escpos/escpos/printer.py
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from __future__ import print_function
|
||||
import serial
|
||||
import socket
|
||||
import usb.core
|
||||
import usb.util
|
||||
|
||||
from .escpos import *
|
||||
from .constants import *
|
||||
from .exceptions import *
|
||||
from time import sleep
|
||||
|
||||
class Usb(Escpos):
|
||||
""" Define USB printer """
|
||||
|
||||
def __init__(self, idVendor, idProduct, interface=0, in_ep=None, out_ep=None):
|
||||
"""
|
||||
@param idVendor : Vendor ID
|
||||
@param idProduct : Product ID
|
||||
@param interface : USB device interface
|
||||
@param in_ep : Input end point
|
||||
@param out_ep : Output end point
|
||||
"""
|
||||
|
||||
self.errorText = "ERROR PRINTER\n\n\n\n\n\n"+PAPER_FULL_CUT
|
||||
|
||||
self.idVendor = idVendor
|
||||
self.idProduct = idProduct
|
||||
self.interface = interface
|
||||
self.in_ep = in_ep
|
||||
self.out_ep = out_ep
|
||||
|
||||
# pyusb dropped the 'interface' parameter from usb.Device.write() at 1.0.0b2
|
||||
# https://github.com/pyusb/pyusb/commit/20cd8c1f79b24082ec999c022b56c3febedc0964#diff-b5a4f98a864952f0f55d569dd14695b7L293
|
||||
if usb.version_info < (1, 0, 0) or (usb.version_info == (1, 0, 0) and usb.version_info[3] in ("a1", "a2", "a3", "b1")):
|
||||
self.write_kwargs = dict(interface=self.interface)
|
||||
else:
|
||||
self.write_kwargs = {}
|
||||
|
||||
self.open()
|
||||
|
||||
def open(self):
|
||||
""" Search device on USB tree and set is as escpos device """
|
||||
|
||||
self.device = usb.core.find(idVendor=self.idVendor, idProduct=self.idProduct)
|
||||
if self.device is None:
|
||||
raise NoDeviceError()
|
||||
try:
|
||||
if self.device.is_kernel_driver_active(self.interface):
|
||||
self.device.detach_kernel_driver(self.interface)
|
||||
self.device.set_configuration()
|
||||
usb.util.claim_interface(self.device, self.interface)
|
||||
|
||||
cfg = self.device.get_active_configuration()
|
||||
intf = cfg[(0,0)] # first interface
|
||||
if self.in_ep is None:
|
||||
# Attempt to detect IN/OUT endpoint addresses
|
||||
try:
|
||||
is_IN = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN
|
||||
is_OUT = lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT
|
||||
endpoint_in = usb.util.find_descriptor(intf, custom_match=is_IN)
|
||||
endpoint_out = usb.util.find_descriptor(intf, custom_match=is_OUT)
|
||||
self.in_ep = endpoint_in.bEndpointAddress
|
||||
self.out_ep = endpoint_out.bEndpointAddress
|
||||
except usb.core.USBError:
|
||||
# default values for officially supported printers
|
||||
self.in_ep = 0x82
|
||||
self.out_ep = 0x01
|
||||
|
||||
except usb.core.USBError as e:
|
||||
raise HandleDeviceError(e)
|
||||
|
||||
def close(self):
|
||||
i = 0
|
||||
while True:
|
||||
try:
|
||||
if not self.device.is_kernel_driver_active(self.interface):
|
||||
usb.util.release_interface(self.device, self.interface)
|
||||
self.device.attach_kernel_driver(self.interface)
|
||||
usb.util.dispose_resources(self.device)
|
||||
else:
|
||||
self.device = None
|
||||
return True
|
||||
except usb.core.USBError as e:
|
||||
i += 1
|
||||
if i > 10:
|
||||
return False
|
||||
|
||||
sleep(0.1)
|
||||
|
||||
def _raw(self, msg):
|
||||
""" Print any command sent in raw format """
|
||||
if len(msg) != self.device.write(self.out_ep, msg, timeout=5000, **self.write_kwargs):
|
||||
self.device.write(self.out_ep, self.errorText, **self.write_kwargs)
|
||||
raise TicketNotPrinted()
|
||||
|
||||
def __extract_status(self):
|
||||
maxiterate = 0
|
||||
rep = None
|
||||
while rep == None:
|
||||
maxiterate += 1
|
||||
if maxiterate > 10000:
|
||||
raise NoStatusError()
|
||||
r = self.device.read(self.in_ep, 20, self.interface).tolist()
|
||||
while len(r):
|
||||
rep = r.pop()
|
||||
return rep
|
||||
|
||||
def get_printer_status(self):
|
||||
status = {
|
||||
'printer': {},
|
||||
'offline': {},
|
||||
'error' : {},
|
||||
'paper' : {},
|
||||
}
|
||||
|
||||
self.device.write(self.out_ep, DLE_EOT_PRINTER, **self.write_kwargs)
|
||||
printer = self.__extract_status()
|
||||
self.device.write(self.out_ep, DLE_EOT_OFFLINE, **self.write_kwargs)
|
||||
offline = self.__extract_status()
|
||||
self.device.write(self.out_ep, DLE_EOT_ERROR, **self.write_kwargs)
|
||||
error = self.__extract_status()
|
||||
self.device.write(self.out_ep, DLE_EOT_PAPER, **self.write_kwargs)
|
||||
paper = self.__extract_status()
|
||||
|
||||
status['printer']['status_code'] = printer
|
||||
status['printer']['status_error'] = not ((printer & 147) == 18)
|
||||
status['printer']['online'] = not bool(printer & 8)
|
||||
status['printer']['recovery'] = bool(printer & 32)
|
||||
status['printer']['paper_feed_on'] = bool(printer & 64)
|
||||
status['printer']['drawer_pin_high'] = bool(printer & 4)
|
||||
status['offline']['status_code'] = offline
|
||||
status['offline']['status_error'] = not ((offline & 147) == 18)
|
||||
status['offline']['cover_open'] = bool(offline & 4)
|
||||
status['offline']['paper_feed_on'] = bool(offline & 8)
|
||||
status['offline']['paper'] = not bool(offline & 32)
|
||||
status['offline']['error'] = bool(offline & 64)
|
||||
status['error']['status_code'] = error
|
||||
status['error']['status_error'] = not ((error & 147) == 18)
|
||||
status['error']['recoverable'] = bool(error & 4)
|
||||
status['error']['autocutter'] = bool(error & 8)
|
||||
status['error']['unrecoverable'] = bool(error & 32)
|
||||
status['error']['auto_recoverable'] = not bool(error & 64)
|
||||
status['paper']['status_code'] = paper
|
||||
status['paper']['status_error'] = not ((paper & 147) == 18)
|
||||
status['paper']['near_end'] = bool(paper & 12)
|
||||
status['paper']['present'] = not bool(paper & 96)
|
||||
|
||||
return status
|
||||
|
||||
def __del__(self):
|
||||
""" Release USB interface """
|
||||
if self.device:
|
||||
self.close()
|
||||
self.device = None
|
||||
|
||||
|
||||
|
||||
class Serial(Escpos):
|
||||
""" Define Serial printer """
|
||||
|
||||
def __init__(self, devfile="/dev/ttyS0", baudrate=9600, bytesize=8, timeout=1):
|
||||
"""
|
||||
@param devfile : Device file under dev filesystem
|
||||
@param baudrate : Baud rate for serial transmission
|
||||
@param bytesize : Serial buffer size
|
||||
@param timeout : Read/Write timeout
|
||||
"""
|
||||
self.devfile = devfile
|
||||
self.baudrate = baudrate
|
||||
self.bytesize = bytesize
|
||||
self.timeout = timeout
|
||||
self.open()
|
||||
|
||||
|
||||
def open(self):
|
||||
""" Setup serial port and set is as escpos device """
|
||||
self.device = serial.Serial(port=self.devfile, baudrate=self.baudrate, bytesize=self.bytesize, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=self.timeout, dsrdtr=True)
|
||||
|
||||
if self.device is not None:
|
||||
print("Serial printer enabled")
|
||||
else:
|
||||
print("Unable to open serial printer on: %s" % self.devfile)
|
||||
|
||||
|
||||
def _raw(self, msg):
|
||||
""" Print any command sent in raw format """
|
||||
self.device.write(msg)
|
||||
|
||||
|
||||
def __del__(self):
|
||||
""" Close Serial interface """
|
||||
if self.device is not None:
|
||||
self.device.close()
|
||||
|
||||
|
||||
|
||||
class Network(Escpos):
|
||||
""" Define Network printer """
|
||||
|
||||
def __init__(self,host,port=9100):
|
||||
"""
|
||||
@param host : Printer's hostname or IP address
|
||||
@param port : Port to write to
|
||||
"""
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.open()
|
||||
|
||||
|
||||
def open(self):
|
||||
""" Open TCP socket and set it as escpos device """
|
||||
self.device = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.device.connect((self.host, self.port))
|
||||
|
||||
if self.device is None:
|
||||
print("Could not open socket for %s" % self.host)
|
||||
|
||||
|
||||
def _raw(self, msg):
|
||||
self.device.send(msg)
|
||||
|
||||
|
||||
def __del__(self):
|
||||
""" Close TCP connection """
|
||||
self.device.close()
|
||||
Loading…
Add table
Add a link
Reference in a new issue