2
0
mirror of https://github.com/inventree/inventree-website.git synced 2025-06-12 01:55:37 +00:00
This commit is contained in:
SchrodingersGat
2024-04-24 21:49:11 +00:00
parent 12e8882f9a
commit d04b74c788
29 changed files with 791 additions and 168 deletions

View File

@ -31,11 +31,11 @@
<meta property="og:url" content="/SergeoLacruz/inventree-zebra-plugin" />
<meta property="og:site_name" content="InvenTree" />
<meta property="og:type" content="article" />
<meta property="article:published_time" content="2024-04-22T00:55:04+00:00" />
<meta property="article:published_time" content="2024-04-24T21:49:01+00:00" />
<meta name="twitter:card" content="summary" />
<meta property="twitter:title" content="Inventree Zebra Plugin" />
<script type="application/ld+json">
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"SergeoLacruz"},"dateModified":"2024-04-22T00:55:04+00:00","datePublished":"2024-04-22T00:55:04+00:00","description":"Zebra Label Printer Plugin for Inventree","headline":"Inventree Zebra Plugin","mainEntityOfPage":{"@type":"WebPage","@id":"/SergeoLacruz/inventree-zebra-plugin"},"url":"/SergeoLacruz/inventree-zebra-plugin"}</script>
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"SergeoLacruz"},"dateModified":"2024-04-24T21:49:01+00:00","datePublished":"2024-04-24T21:49:01+00:00","description":"Zebra Label Printer Plugin for Inventree","headline":"Inventree Zebra Plugin","mainEntityOfPage":{"@type":"WebPage","@id":"/SergeoLacruz/inventree-zebra-plugin"},"url":"/SergeoLacruz/inventree-zebra-plugin"}</script>
<!-- End Jekyll SEO tag -->
</head>
@ -69,19 +69,21 @@
<p> SergeoLacruz</p>
</span>
</a></span>
<span class="sm:ml-2 text-sm">last modified: 22 Apr 2024</span>
<span class="sm:ml-2 text-sm">last modified: 24 Apr 2024</span>
</h2>
<div class="flex-wrap md:flex md:flex-nowrap">
<div class="w-full md:w-auto md:mr-4">
<p>Zebra Label Printer Plugin for Inventree</p>
<p>This is a label printing plugin for <a href="https://inventree.org">InvenTree</a>, which provides support for Zebra Label printers .
It was only tested with GK420T but should work for other ZPL printers too. It uses the ZPL library to
convert the png data provided by InvenTree to Zebras bitmap format.</p>
<p>This is a label printing plugin for <a href="https://inventree.org">InvenTree</a>, which provides
support for Zebra Label printers. It was only tested with GK420T but should work for
other ZPL printers too. It uses the ZPL library to convert the png data provided by
InvenTree to Zebras bitmap format.</p>
<p>It can output the print data either to a local printer connected to the computer via USB or to a network printer
with an IP address. The output can be configured in the InvenTree plugin user interface.</p>
<p>It can output the print data either to a local printer connected to the computer via
USB or to a network printer with an IP address. The output can be configured in the
InvenTree plugin user interface.</p>
<p>Error handling is very basic.</p>
@ -107,12 +109,12 @@ with an IP address. The output can be configured in the InvenTree plugin user in
device /dev/usb/lp0. No printer spooler is involved so far.</p>
<h3 id="threshold">Threshold</h3>
<p>The image from pillow comes in greyscale. The plugin converts it ti pure BW because this gives a much
<p>The image from pillow comes in greyscale. The plugin converts it ti pure BW because this gives a much
better print result. The threshold between black and white can be adjusted here.</p>
<h3 id="darkness">Darkness</h3>
<p>This is a value that influences the darkness of the print. Allowed values are 0 (white) to 30 (black).
It is directly converted to a SD command in ZPL. If your black areas tend to blur out reduce the
It is directly converted to a SD command in ZPL. If your black areas tend to blur out reduce the
darkness.</p>
<h3 id="dots-per-mm">Dots per mm</h3>
@ -132,8 +134,8 @@ is passed directly to the printer without any checks. So be careful when editing
here.</p>
<h2 id="label-template">Label Template</h2>
<p>The label needs a template described in html and css. The template should start with a page definition
that defines the label size as shown below:</p>
<p>The label needs a template described in html and css. The template should
start with a page definition that defines the label size as shown below:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> @page {
{% localize off %}
@ -146,13 +148,32 @@ that defines the label size as shown below:</p>
}
</code></pre></div></div>
<p>The height and width parameters are defined in the InvenTree admin panel in the label section. These values
have to fit the label size that is in the printer. See the example templates for details on template definition.</p>
<p>The height and width parameters are defined in the InvenTree admin panel
in the label section. These values have to fit the label size that is in
the printer. See the example templates for details on template definition.</p>
<h2 id="multi-printer-hack">Multi printer hack</h2>
<p>We have the requirement to print labels in different sizes. As we do not
want to change the reel for each print we set up a second printer loaded
with a different label size. InvenTree is not yet able to handle different
printers. So I added a multi printer hack. You can define a key with an IP
address in the label meta data:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{"ip_address":"xxx.yyy.zzz.eee"}
{"darkness":xx}
</code></pre></div></div>
<p>If the printer driver finds that key, the IP address from the printer settings
is overwritten with the address from the meta data. So the print will end up
in another printer.</p>
<p>Only the IP address and darkness can be overwritten so far. All other settings remain.</p>
<h2 id="how-it-works">How it works</h2>
<p>First import all the stuff you need. Here we use the translation mechanism from Django for multi language support.
The import the InvenTree libs and everything you need for plugin. Here we have ZPL for the Zebra bitmaps and socket
for the IP connection to the printer.</p>
<p>First import all the stuff you need. Here we use the translation mechanism from
Django for multi language support. The import the InvenTree libs and everything
you need for plugin. Here we have ZPL for the Zebra bitmaps and socket for the
IP connection to the printer.</p>
<p>The next part is this:</p>
@ -167,7 +188,7 @@ for the IP connection to the printer.</p>
</code></pre></div></div>
<p>The name of the class can be freely chosen. You reference to it in the entry_points section of the setup.py file.
The parameters need to be like in the example. Then there is the description block. The keywords are fixed and
The parameters need to be like in the example. Then there is the description block. The keywords are fixed and
need to be like that. The values are found in the UI as shown in the pictures below.</p>
<p><img src="/assets/plugins/plugin_admin.png" alt="Admin">
@ -191,9 +212,9 @@ need to be like that. The values are found in the UI as shown in the pictures be
</code></pre></div></div>
<p>We need to define a dict with the name SETTINGS. Please be aware the keys need to be in all CAPITAL letters like CONNECTION.
Simple parameters are just text strings like the port. We can set a default. The name and description shows up in the UI.
Simple parameters are just text strings like the port. We can set a default. The name and description shows up in the UI.
Instead of a simple text we can also use choices. The first string like “local” it the key you use in the code. The second
one is the description in the UI.
one is the description in the UI.
After that we need to define a function:</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">print_label</span><span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">){</span>
@ -212,27 +233,27 @@ After that we need to define a function:</p>
<li>png_file</li>
</ul>
<p>The item_instance is the part to be printed. This allows direct access to all part data. The arguments width and height
come from the settings of the label in the admin interface. NOT from the html template.
For the Zebra printer we use the png_file. This is a PIL (python Pillow) object with the graphic of the label in PNG format.
<p>The item_instance is the part to be printed. This allows direct access to all part data. The arguments width and height
come from the settings of the label in the admin interface. NOT from the html template.
For the Zebra printer we use the png_file. This is a PIL (python Pillow) object with the graphic of the label in PNG format.
The PIL object is a greyscale image. Because the printer can just print pure BW we convert this to a BW picture.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">fn</span> <span class="o">=</span> <span class="k">lambda</span> <span class="n">x</span> <span class="p">:</span> <span class="mi">255</span> <span class="k">if</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="n">Threshold</span> <span class="k">else</span> <span class="mi">0</span>
<span class="n">label_image</span> <span class="o">=</span> <span class="n">label_image</span><span class="p">.</span><span class="nf">convert</span><span class="p">(</span><span class="sh">'</span><span class="s">L</span><span class="sh">'</span><span class="p">).</span><span class="nf">point</span><span class="p">(</span><span class="n">fn</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="sh">'</span><span class="s">1</span><span class="sh">'</span><span class="p">)</span>
</code></pre></div></div>
<p>The threshold can by modified by a plugin parameter. 200 is a good starting value. This trick gives much better prints.
<p>The threshold can by modified by a plugin parameter. 200 is a good starting value. This trick gives much better prints.
We can put the result of this directly into the ZPL library.</p>
<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">l</span> <span class="o">=</span> <span class="n">zpl</span><span class="p">.</span><span class="nc">Label</span><span class="p">(</span><span class="n">Height</span><span class="p">,</span> <span class="n">Width</span><span class="p">,</span> <span class="n">dpmm</span><span class="p">)</span>
<span class="n">l</span><span class="p">.</span><span class="nf">origin</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">li</span><span class="p">.</span><span class="nf">set_darkness</span><span class="p">(</span><span class="n">darkness</span><span class="p">)</span>
<span class="bp">...</span>
<span class="n">l</span><span class="p">.</span><span class="nf">write_graphic</span><span class="p">(</span><span class="n">label_image</span><span class="p">,</span> <span class="n">Width</span><span class="p">)</span>
<span class="n">l</span><span class="p">.</span><span class="nf">endorigin</span><span class="p">()</span>
</code></pre></div></div>
<p>Width and Height define is the size of the label in millimeters as described above.
The third parameter is the resolution of the printer in dots per mm.
The third parameter is the resolution of the printer in dots per mm.
write_graphic converts the pillow data to ZPL.</p>
<p>The plugin was tested with a labels of various sizes defined using css and html. The DPI scaling
@ -248,11 +269,11 @@ Lets have a look at the following printout:</p>
<p><img src="/assets/plugins/qr.png" alt="QRCodes"></p>
<p>Both codes have been printed with the same printer on the same reel. The left one is
<p>Both codes have been printed with the same printer on the same reel. The left one is
hardly readable using my mobile. The right one reads easily even as it is smaller.</p>
<h3 id="secret-1-scale">Secret 1, Scale</h3>
<p>The printer resolution is 8 dots per mm resulting in a dot size of 0.125mm. The QR code pixel
<p>The printer resolution is 8 dots per mm resulting in a dot size of 0.125mm. The QR code pixel
and the printer pixel size should be integrally divisible. The code in the picture has 21
pixels plus one in the frame, so 23 pixel. The frame is set in the HTML description.</p>
@ -260,7 +281,7 @@ pixels plus one in the frame, so 23 pixel. The frame is set in the HTML descript
</code></pre></div></div>
<p>I selected two dots per pixel. So 23 * 2 * 0.125 = 6.125mm. If the size is something different
scaling takes place and the result might be worse. If you like a larger printout select more
scaling takes place and the result might be worse. If you like a larger printout select more
dots per pixel. From a certain size upwards the value does not matter any more because the code
gets large enough to be readable in any quality.</p>
@ -273,9 +294,9 @@ media type and printer age. The printer head tends to wear out and the darkness
need an adjustment from time to time.</p>
<h3 id="alternative">Alternative</h3>
<p>You can also bypass the InvenTree template and printing system and directly create ZPL from
<p>You can also bypass the InvenTree template and printing system and directly create ZPL from
the parts data. The printer knows best how to render the label and the print quality is best.
If you are interested in this way have a look at the <a href="https://github.com/yellowcrescent/inventree-zpl-plugin">inventree-zpl-plugin</a>
If you are interested in this way have a look at the <a href="https://github.com/yellowcrescent/inventree-zpl-plugin">inventree-zpl-plugin</a>
that does exactly that.</p>
</div>