Zebra Printing with CUPS no print ZPL or EPL - printing

I have a Zebra GK420d connect to OS X via CUPS. However, when I send files to it that are written in ZPL or EPL they are only printed in plain text.
Am I required to change to mode on the printer?

Contrary to what others said, you don't need to specially add a raw queue.
Instead, you can submit raw files into any queue using -o raw switch:
lpr -P CupsPrinterName -o raw path/to/label.zpl
Printer name can be found over that link in CUPS:
http://localhost:631/printers/
This also works on other platforms that use CUPS, like Linux.

You can create a raw CUPS queue with lpadmin. Here's the command line I used:
lpadmin -p Zebra -E -v usb://Zebra%20Technologies/ZTC%20LP%202824%20Plus?serial=XXXXXX -m raw
You can also set up a raw queue using the CUPS web admin at
http://127.0.0.1:631/

This is a bit more comprehensive answer since I seem to be returning to this question every couple of years. To print with a Zebra or other barcode printers in Linux from command line follow these steps:
List all printer targets and find the printer you want to use:
$ lpinfo -v
network https
serial serial:/dev/ttyS0?baud=115200
serial serial:/dev/ttyS1?baud=115200
network lpd
direct hp
direct usb://GODEX/G500?serial=162203C6
network smb
...
Add new queue:
$ lpadmin -p godex -E -v usb://GODEX/G500?serial=162203C6 -m raw -o usb-unidir-default=true
If your printing is slow (takes long to start), please make sure you added -o usb-unidir-default=true.
Check available queues:
$ lpstat -v
device for godex: usb://GODEX/G500?serial=162203C6
Create a label (text file):
Create a file according to your printer's requirements in EPL (Zebra), ZPL (Zebra), EZPL (Godex).
Warning, certain CUPS versions might have an issue with raw files if they are under 512 bytes of length - longer files will print, while shorter will print once and then stall for a couple of minutes (looks like there is a timeout built in). A workaround is to add comments to extend it over 512 byte limit.
Example Zebra file (test.epl):
N
A20,20,0,2,1,1,N,"text"
B20,40,0,1,1,1,30,N,"aaaa-bbbb-cccc"
P1
Example Godex file (test.ezpl):
;set portrait orientation
^XSET,ROTATION,0
;set height 20mm
^Q20,1
;set width 64mm
^W64
;start label
^L
;AA=print out text with smallest font, x=20dots, y=20dots, magnificationx=0, magnificationy=0, gap=1dot, rotationInverse=0 (no)
AA,20,20,0,0,1,0,Some sample text
;BQ=code128, x=20dots,y=40dots,narrow_bar_width=1,wide_bar_width:2,height=30dots,rotation=0deg,readable=0(no)
BQ,20,40,1,2,30,0,0,1234-1243-43214-432141
;end label
E
Push to printer:
$ lpr -P godex test.ezpl

You would need to avoid any filtering. Print using a RAW filter, as configured in the CUPS interface, or by default in your lpadmin statement. You did not state how the printer was connected, but if IP, your destination would most-likely be socket://ip.addr.ess:9100.

I am a PC guy so I don't know CUPS well, but I have used zpl and epl on PC's and found that they really like to get the raw print files. I always do a :
filecopy "c:\zplfile.txt" "\computername\printershare" type command.
I have used wordpad too, if I just want to do some text. But for labels and barcodes I would see if there is a way for you to send the raw zpl or epl to the printer port. Hope this helps.

Thanks. I have looked at it some more. It seems that while using cups you cannot send raw ZPL commands to the printer. Like what I did was create the printer in cups as a socket and started a netcat listener on 9100 and then issued some sort of command to the printer
nc -l localhost 9100
zpl_mine="^XA ~SD10 ^PW 850 ^MM T ^MN W ^JUS ^XZ,";echo $zpl_mine | nc localhost 9100 -w 1
and this does not send the information to the printer, but I have seen on some forums that you have to use some form of language like C to parse the information

Related

Zebra g420d - light flashes green but nothing is printed

I'm trying to print labels on a Zebra g420d printer, it's setup with CUPS and connected through USB to a Raspberry PI. It works excellent for printing PDF-labels so no problems with communication.
Now I create a secondary queue which is setup as a raw local printer in CUPS to print another type of labels, this time it's not PDF's, instead it's just ZPL. I print with the following command:
lpr -P <PRINTER_NAME> -o raw <FILENAME.zpl>
The green light flashes and file disappears from queue but nothing is printed. Things I have tried:
Using ZPL-driver instead of raw
Different very basic ZPL-labels, some directly from ZPL examples in documentation.
Rendering the label on http://labelary.com/viewer.html, downloading file and send to printer
ZPL with and without linebreaks after each command / at the end
I suspect something might be wrong with encoding of ZPL-commands so I enabled dump mode, here's a photo of the output with hex codes. Note that it's three tries after each other.
dump mode output
One of many ZPL-labels tried:
^XA^FO1,80,0^ADN,25^A0N,100,80,3214^FD123^FS^FO280,80,0^BY3^BCN,150,Y,N,Y,A^FD456^FS^XZ
CUPS Setup:
Description: Zebra Technologies ZTC GK420d
Location:
Driver: Local Raw Printer (grayscale, 2-sided printing)
Connection: usb://Zebra%20Technologies/ZTC%20GK420d?serial=28J2007020XX
Defaults: job-sheets=none, none media=unknown
Any ideas what the reason for this behaviour could be or what to try next?

import ip packet via hex dump

I have a hex dump generated using gdb. I have generated the dump that wireshark can understand using "od -Ax -tx1 -v". But when I open in the wireshark tool the packet doesn't get recognized properly. I think wireshark is trying to read the ethernet frame while the buffer has data from IP header. Is there a way to indicate wireshark to parse hexdump assuming fro IP header.
Have a look at text2pcap. There are 2 basic approaches you can take:
Add a dummy Ethernet header using the -e <l3pid> option, or
Set the encapsulation type of the converted pcap file to link-layer type LINKTYPE_RAW using the -l 101 option.

WMIC enconding issue when run command from Linux

I'm trying to get informations from a windows machine using WMIC in Linux.
Basically, my commands looks like below:
wmic '--authentication-file=/tmp/auth_file' '//127.0.0.1' 'SELECT Name FROM Win32_ComputerSystem'
The connection works fine and the results are correctly printed in the console. The problem is when the info has some type of encoding (like UserNames, for example). In these cases, I always get strange results.
With a quick search, I found some similar issues here and the problem is the encoding of wmic output (that is UNICODE).
As suggested, I tried pipe the output to more, but it causes no effect.
My question is: Are there anyway to force the wmic output to ASCII or ISO-8859-1 when using it through Linux? Apparently, this is the only way to get the right character-enconding.
UPDATE
Just to add more infos.
The wmic command refers to a linux client that uses WMI in a remote connection.
Since this command will be called through scripts (shell, php and python), I tried to make a encoding conversion inside a simple PHP code, but apparently, it does not work, 'cause the detected encode for the output is ISO-8859-1, and conversions for ASCII or UTF-8 simple doesn't work. below is a minimalist version of PHP script
//$cdm is a command like the example above
exec("$cmd", $out);
//also tried to parse $out and used just the string with the encoding problems in the functions below
var_dump(mb_detect_encoding($out, "CP850, UTF-8, ISO-8859-1, ASCII")); // it returns "ISO-8859-1"
var_dump(mb_convert_encoding($out, "ASCII", 'ISO-8859-1'));
var_dump(mb_convert_encoding($out, "UTF-8", 'ISO-8859-1'));
var_dump(mb_convert_encoding($out, "ISO-8859-1", 'UTF-8'));
Info:
Linux: Debian 8
Windows: Windows 10

CUPS returns 'complete' on jobs which are still printing

I am communicating with CUPS using IPP protocol. I have all drivers for my printers installed in CUPS (using .ppd file) and printers got latest firmware.
When I query a job which a printer printing right now it says that the job's state is 'complete' before the printer even finish printing. It seems that the CUPS marks the job as 'complete' when it finish 'uploading' the file.
I would not expect this behaviour and I basically need to know when exactly the printer printed last paper for a job.
The code looks as follow. The self.printer().ippPrinter() is an instance of node-ipp and it points to a printer. To read the the state of the job I am using attribute 'job-state'.
var msg = {
"operation-attributes-tag": {
'job-id': id
}
};
self.printer().ippPrinter().execute("Get-Job-Attributes", msg, function(err, res){
var attributes = res['job-attributes-tag'];
self.setAttributes = attributes;
callback.call(self, attributes);
});
Does anyone know why I am having this issue or .. how to make it working?
Thank you!
CUPS can only forward job-states received from the printer. A lot of printer drivers and protocols work like 'fire and forget'.
Usually IPP printers allow CUPS and other clients to monitor the current job-state until it's finished/printed. Some manufacturers don't implement IPP properly and classify submitted jobs as printed - even if the printer has a paper jam!
Conclusion:
If your printer does not fully support IPP you probably won't be able to check for 'printed successfully'.
RFC 8011 5.3.7.1
If the implementation is a gateway to a printing system that never provides detailed status about the Print Job, the implementation MAY set the IPP Job’s state to ’completed’, provided that it also sets the ’queued-in-device’ value in the Job’s "job-state-reasons" attribute
#Jakub, you may well be communicating with CUPS using IPP... But are you sure that CUPS is communicating with the print device via IPP?
You can check this by running
lpstat -h cupsservername -v
This should return the device URI assigned to each print queue, which CUPS uses to address the actual printing device:
If that URI does contain ipp://, ipps://, http:// or https:// CUPS indeed talks IPP to the print device and you should be able to get actually correct status messages.
But if you see socket:// then CUPS is configured to use the AppSocket method (sometimes also called 'HP Jet Direct' or 'IP Direct Printing') to forward jobs. This is a "fire and forget" protocol. Basically it is the same as if you did run netcat print-device 9100 < myprintfile to shovel the printable data to port 9100 of the printer. The CUPS socket backend handling this spooling to the printer will not get any other acknoledgement from the printer than what TCP/IP provides confirming that the last packet was transfered. Hence it has to close down its process and report to the CUPS daemon successful-ok, even if the printer is still busy spitting out lots paper and will maybe never complete the full job because it runs into a paper jam...
If you see lpd:// the situation is similar (but uses port 515).
You may have success with a full status reporting by switching the CUPS-to-printdevice path from AppSocket or LPD to IPP like so:
sudo lpadmin -p printername ipp://ipaddress-of-printer
or
sudo lpadmin -p printername http://ipaddress-of-printer:631

How to send text file to printer

As i read in some fingerprint manual we can send text file to the printer. Means we can write the program in the text editor and send the whole program as a text file to the printer using the communication program using some transfer commands.
for in my host there is a file called myfile.txt in D:/ with the fallowing data
10 PRPOS 200,200
20 DIR 3
30 ALIGN 5
40 PRIMAGE “GLOBE.1”
50 PRINTFEED
RUN
How can i send this file to printer and execute the instrucations to print the image.
Please give me some code reference.
There are several ways to do this from the command line. For example:
type foo.txt > lpt1:
Or
copy foo.txt lpt1:
Or
print foo.txt
Or
notepad /p foo.txt
If you need to do it programmatically, you can execute any of those commands using the system() function or CreateProcess().
If you're on an Intermec handheld and you're connected to a Bluetooth printer, you should be able to open a serial port to COM6 and send your file over. What programming language? There should be plenty of Serial Port communication code examples out there.
My experience with Intermec PM4i label printer was a roller coaster but know I have a working app.
I tried Windows printer pipeline through generictext driver. It does work from Notepad but with few corner cases.
Printing directly from Notepad works fine until I tried QRCODE image with a very long text line. Image did not print out. Made qrcode text a short few characters and same script worked fine.
INPUT OFF
NASC 1252
BF OFF
FT "Swiss 721 Bold BT",12,0,100
PP 50,500:PT "Text line goes here"
PP 400,400:AN 7:BARSET "QRCODE",1,1,7,2,4
PB "ABC123 aabbcc....very long text goes here...I mean about 200 chars or more"
PRINTFEED
It was like Notepad cut text to a right side border and command string was broken. I made a printing preferences A3-landscape and it accepted longer text but still was not enough for all use cases.
All printers have a physical max printing width but it should not be considered in a fingerprint/directprotocol script files. After all we are not printing this text as-is but submitting commands to the printer.
My solution was to create Java application which opens a raw TCP socket to 11.22.33.44:9100 address and writes text lines, lines terminated by NL(#10). Works fine. Another helper tool I did was Delphi app.exe to read IP address from Windows printer object. I can submit label printouts "directly" from Excel application.
End users edit Excel data rows and click PRINT LABELS button
vba macro parses a fingerprint template file with ${FIELD1} find-and-replace substitutes
file is written to %wintemp%/intermec_script.txt folder
call app.exe to read IP address of user chosen printer
call java app to submit intermec_script.txt to IP:PORT socket
I should create same socket submit app in Delphi to drop javavm dependency but this solution was faster for my use case. I am more familiar with Java than my Delphi skill level.

Resources