-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
22f9ad0
commit 8423e20
Showing
1 changed file
with
146 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
""" | ||
Label printing plugin for InvenTree. | ||
Supports direct printing of labels on label printers | ||
""" | ||
# translation | ||
from django.utils.translation import gettext_lazy as _ | ||
from django.core.validators import MinValueValidator | ||
from django.core.validators import MaxValueValidator | ||
|
||
# InvenTree plugin libs | ||
from plugin import InvenTreePlugin | ||
from plugin.mixins import LabelPrintingMixin, SettingsMixin | ||
|
||
# Zebra printer support | ||
import zpl | ||
import socket | ||
|
||
from inventree_zebra.version import ZEBRA_PLUGIN_VERSION | ||
|
||
|
||
class ZebraLabelPlugin(LabelPrintingMixin, SettingsMixin, InvenTreePlugin): | ||
|
||
AUTHOR = "Michael Buchmann" | ||
DESCRIPTION = "Label printing plugin for Zebra printers" | ||
VERSION = ZEBRA_PLUGIN_VERSION | ||
NAME = "Zebra" | ||
SLUG = "zebra" | ||
TITLE = "Zebra Label Printer" | ||
|
||
SETTINGS = { | ||
'CONNECTION': { | ||
'name': _('Printer Interface'), | ||
'description': _('Select local or network printer'), | ||
'choices': [('local', 'Local printer e.g. USB'), | ||
('network', 'Network printer with IP address')], | ||
'default': 'local', | ||
}, | ||
'IP_ADDRESS': { | ||
'name': _('IP Address'), | ||
'description': _('IP address in case of network printer'), | ||
'default': '', | ||
}, | ||
'PORT': { | ||
'name': _('Port'), | ||
'description': _('Network port in case of network printer'), | ||
'default': '9100', | ||
}, | ||
'LOCAL_IF': { | ||
'name': _('Local Device'), | ||
'description': _('Interface of local printer'), | ||
'default': '/dev/usb/lp0', | ||
}, | ||
'THRESHOLD': { | ||
'name': _('Threshold'), | ||
'description': _('Threshold for converting gray scale to BW (0-255)'), | ||
'validator': [int, MinValueValidator(0), MaxValueValidator(255)], | ||
'default': 200, | ||
}, | ||
'DARKNESS': { | ||
'name': _('Darkness'), | ||
'description': _('Darkness of the print out. 0-30'), | ||
'validator': [int, MinValueValidator(0), MaxValueValidator(30)], | ||
'default': 20, | ||
}, | ||
'DPMM': { | ||
'name': _('Dots per mm'), | ||
'description': _('The resolution of the printer'), | ||
'choices': [(8, '8 dots per mm'), (12, '12 dots per mm'), (24, '24 dots per mm')], | ||
'default': 8, | ||
}, | ||
'PRINTER_INIT': { | ||
'name': _('Printer Init'), | ||
'description': _('Additional ZPL commands sent to the printer. Use carefully!'), | ||
'default': '~TA000~JSN^LT0^MNW^MTT^PMN^PON^PR2,2^LRN', | ||
}, | ||
} | ||
|
||
def print_label(self, **kwargs): | ||
|
||
# Read settings | ||
connection = self.get_setting('CONNECTION') | ||
interface = self.get_setting('LOCAL_IF') | ||
port = int(self.get_setting('PORT')) | ||
threshold = self.get_setting('THRESHOLD') | ||
darkness = self.get_setting('DARKNESS') | ||
dpmm = int(self.get_setting('DPMM')) | ||
printer_init = self.get_setting('PRINTER_INIT') | ||
label_image = kwargs['png_file'] | ||
|
||
# Extract width (x) and height (y) information. | ||
width = kwargs['width'] | ||
height = kwargs['height'] | ||
|
||
# Set the darkness | ||
fn = lambda x: 255 if x > threshold else 0 | ||
label_image = label_image.convert('L').point(fn, mode='1') | ||
|
||
# Uncomment this if you need the intermediate png file for debugging. | ||
# label_image.save('/home/user/label.png') | ||
|
||
# Convert image to Zebra zpl | ||
li = zpl.Label(height, width, dpmm) | ||
li.set_darkness(darkness) | ||
li.labelhome(0, 0) | ||
li.zpl_raw(printer_init) | ||
li.origin(0, 0) | ||
li.write_graphic(label_image, width) | ||
li.endorigin() | ||
|
||
# Uncomment this if you need the intermediate zpl file for debugging. | ||
# datafile=open('/home/user/label.txt','w') | ||
# datafile.write(li.dumpZPL()) | ||
# datafile.close() | ||
|
||
# Select the right printer. | ||
# This is a multi printer hack. In case the label has an IP address in the metadata | ||
# the address in the settings is overwritten be the metadata. By this you can | ||
# specify a separate printer for each label. | ||
|
||
label = kwargs['label_instance'] | ||
try: | ||
ip_address = label.metadata['ip_address'] | ||
except Exception: | ||
ip_address = self.get_setting('IP_ADDRESS') | ||
|
||
# Send the label to the printer | ||
if (connection == 'local'): | ||
try: | ||
pass | ||
printer = open(interface, 'w') | ||
printer.write(li.dumpZPL()) | ||
printer.close() | ||
except Exception as error: | ||
raise ConnectionError('Error connecting to local printer: ' + str(error)) | ||
elif (connection == 'network'): | ||
try: | ||
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
mysocket.connect((ip_address, port)) | ||
data = li.dumpZPL() | ||
mysocket.send(data.encode()) | ||
mysocket.close() | ||
except Exception as error: | ||
raise ConnectionError('Error connecting to network printer: ' + str(error)) | ||
else: | ||
print('Unknown Interface') |