mike42 / escpos-php

PHP library for printing to ESC/POS-compatible thermal and impact printers
Other
2.53k stars 861 forks source link

Get status of the printer #43

Open defacto133 opened 9 years ago

defacto133 commented 9 years ago

Is there a command to get the status of the printer (online/offline), when the paper is ending or the paper is finished?

CroModder commented 9 years ago

I am also waiting for this feature, but as far as I know none of the ESC/POS libraries does not support that. There is "ESC c 3 n" command for that purpose but I have no idea how to do that. So let's hope someone will implement that.

mike42 commented 9 years ago

This is not currently implemented.

Can you both reply back with which model printers you're using, and which PrintConnector you're using to speak to them?

This will require two-way communication, which will be some new territory. It should be possible to add for FilePrintConnector and NetworkPrintConnector, but not WindowsPrintConnector, which interacts with system printing and does not have the luxury of being able to read back responses.

CroModder commented 9 years ago

I am using model TM-T20 which is connected to RaspberryPi over USB. Do you know over which protocol should printer communicate with the host to achieve this? Would like to help but have very limited knowledge in that area :worried:

defacto133 commented 9 years ago

Thank you for the quick response!

I'm using a TM-T20ii and I'm using a NetworkPrintConnector (this printer will end up connected to a Raspberry Pi over Ethernet, at the moment I'm doing some tests on my Linux pc).

I've already done some tests trying to send the Status Commands through a TCP connection but with no success, in particular when the cover is open or there's no paper the printer simply does not respond (see https://download.epson-biz.com/modules/pos/index.php?page=prod&pcat=3&pid=3721 under Programming Guide for the Status Commands), then when the cover is closed again the printer answers immediately.

While Googling I've found this page http://www.amigopos.com/faq/faq_262.aspx and I've compiled and run the C program in section "4.7.8.2 For Linux" and it seems that through an UDP connection is possibile to get the printer status but I've not investigated this solution further.

Another solution that I've found is to install the Linux Printer Driver for the TM-T20ii (available here https://download.epson-biz.com/modules/pos/index.php?page=prod&pcat=3&pid=3721) then use a C++ program to use the Status API to get the ASB status of the printer.

defacto133 commented 9 years ago

Here's the function that I'm using to get the ASB (Automatic Status Back) from the TM-T20II through an UDP socket. I've followed the UB-E02 Technical Reference Guide even though the printer actually mounts an UB-E03.

https://gist.github.com/defacto133/5a22db20185cd1cdc9f6

mike42 commented 9 years ago

Thanks for sharing this gist, I hadn't seen ASB before. I don't think this will fit well in the driver code (simply because it's not using ESC/POS commands), but it would make a good example snippet for other people on networked Epson printers.

I'll need to attempt something similar using the ESC/POS DLE EOT command along with a timeout, so it is able to work over interfaces like USB.

mike42 commented 9 years ago

I've just uploaded a new function which uses the DLE EOT (transmit real-time status) command. This was tested on my TM-T20 over USB, with the code snippet below.

I think DLE EOT has limited usefulness: It returned objects characters containing all the correct status flags if the printer had just been rebooted (and not yet printed any output). For a printer that had been printing, it worked properly only if the printer was in an online state. Otherwise, responses hung until the printer came online (ie, the user closed the cover or replaced the paper). For this reason, the code times out and returns null if no response is received in 5s.

<?php
require_once("Escpos.php");
$c = new FilePrintConnector("/dev/usb/lp0");
$printer = new Escpos($c);

// Get status
echo "Getting status .. ";
$a = $printer -> getPrinterStatus(Escpos::STATUS_PRINTER);
echo "ok\n";
// Print status (may be 'null' if it timed out)
print_r($a);

echo "Getting offline cause .. ";
$a = $printer -> getPrinterStatus(Escpos::STATUS_OFFLINE_CAUSE);
echo "ok\n";
// Print status (may be 'null' if it timed out)
print_r($a);

echo "Getting error cause .. ";
$a = $printer -> getPrinterStatus(Escpos::STATUS_ERROR_CAUSE);
echo "ok\n";
// Print status (may be 'null' if it timed out)
print_r($a);

echo "Getting paper roll status .. ";
$a = $printer -> getPrinterStatus(Escpos::STATUS_PAPER_ROLL);
echo "ok\n";
// Print status (may be 'null' if it timed out)
print_r($a);

// Close printer
$printer -> close();

If you have an ethernet printer, the ASB solution is clearly preferable- @defacto133, do you mind if I add your example to the example/ folder?

defacto133 commented 9 years ago

No problem :ok_hand: feel free to refactor it.

groggit commented 8 years ago

I've implemented the library to print usernames and passwords for wifi hotspot tickets and it works great (Zijang ZJ-5890 via USB on raspberry Pi).

Only problem remaining is if the printer is offline my script hangs, so I'd like to include a status check to work around this.

I tried:

$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);
$status = $printer -> getPrinterStatus(Printer::STATUS_PRINTER);
print_r($status);

but getting no response whether online or offline. Problem with my code?, or maybe my printer doesn't support this?

dumorim commented 8 years ago

It does not work in t20

 $connector = new NetworkPrintConnector('192.168.0.249', '9100');
        $printer = new Printer($connector);
      $order = $printer -> getPrinterStatus(Printer::STATUS_PAPER_ROLL);
        $justification = array(
            Printer::JUSTIFY_CENTER,);
        for ($i = 0; $i < count($justification); $i++) {
            $printer->setUnderline($i);
            $printer->setJustification($justification[$i]);
            $printer->setTextSize(2, 2);
            $printer->setFont(Printer::FONT_B);
         $printer->text("PEDIDO MESA {$order}\n\n");
            $printer->setFont();
            $printer->setJustification();
            $printer->setTextSize(2, 1);
            $printer->setPrintWidth();
            $printer->setUnderline(0);
mike42 commented 8 years ago

@dumorim, @groggit -This issue is still open because a working implementation of getPrinterStatus() is yet to be written.

I think the GS a command may enable us to move forward with this. It asks the printer to send status updates as they happen, and a quick test over a TM-T20II Epson printer confirms this behaviour.

image

Code:

<?php
require __DIR__ . '/vendor/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;

$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

// Ask for updates, and wait to see if they arrive
$connector -> write(Printer::GS . "a" . chr(255));
while(true) {
  echo ".";
  usleep(1000000);
  echo $connector -> read(1);
}

$printer -> close();

To get that output, I opened the printer, pressed feed buttons, took out the paper, etc. Each time the printer was ready to print again, the ASCII character 14 was printed.

dumorim commented 8 years ago

error 504 Gateway Time-out

use Mike42\Escpos\PrintConnectors\NetworkPrintConnector;
use Mike42\Escpos\Printer;

   $connector = new NetworkPrintConnector('192.168.0.249', '9100');
        $printer = new Printer($connector);
        $connector -> write(Printer::GS . "a" . chr(255));
        while(true) {
            echo ".";
            usleep(1000000);
            echo $connector -> read(1);
        }

        $printer -> close();
mike42 commented 8 years ago

@dumorim From your posts, I assume you just want the status of your printer from your application. If this is the case, then please read the comment I posted above in more detail, as it provides some info on the progress of this feature, and a work-around which you may like to try for your setup.

However, if you want to try to implement the GS a command in this driver to get this feature added sooner, then this code will show you how the command works. Just execute it on the command-line instead, as it has binary output and doesn't terminate.

dumorim commented 8 years ago

ok. Thank you very much!

canorioss commented 7 years ago

Hola, no domino el inglés. Yo estoy trabajando con Ubuntu y para saber si la impresora esta conectada y encendida loquea hago es una comprobación de existencia del archivo lp0:

If( file_exist("dev/usb/lp0") ){
 // compruebo los permisos
  if( is_readable("dev/usb/lp0") ){
     // código para trabajar con la impresora
  }else{
   // permisos de archivo denegado por el SO.
  }
}else{
 // impresora apagada o desconectada
}

Para solucionar el problema de permisos he creado una tarea en cron que se ejecuta cada minuto, en la cuál asigno permisos de lectura y ejecución al archivo "dev/usb/lp0".

Saludos ..

wichogg commented 7 years ago

Hello

I have try this code:

<?php
require __DIR__ . '/vendor/autoload.php';
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;

$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);

// Ask for updates, and wait to see if they arrive
$connector -> write(Printer::GS . "a" . chr(255));
while(true) {
  echo ".";
  usleep(1000000);
  echo $connector -> read(1);
}

$printer -> close();

It works nice, how ever for my application I need this in real time status, for example if I open the cover, I can see the output changing, how ever if I leave the cover open, this does not return the error or status,

is there any way for this to return the realtime status (another way to use DLE EOT)?

I have try this with TM u220 USB.

iimnd commented 7 years ago

any update for this issue? i want to create a warning when paper end.

wichogg commented 7 years ago

I quite on this, could not make it

I know javapos implementation has it, but I could not make it work even in Linux command line

Stenerson commented 7 years ago

I believe the solutions to this will end up being quite printer-specific and therefore may not fit well into a library like this.

The solution that I'd recommend at this time is the ePOS-Device SDK for JavaScript. I'm sure it will only help a very small subset of people who need to print to POS printers but I've found personally that it works well, especially for getting events from the printer when the paper is out, cover is open, gains/loses connectivity, etc.

If you have a javascript environment (server or client), a printer that supports ePOS and the need to check the printer status, I recommend taking a look at the SDK. Note: To view the full documentation you may need to sign up for a (free) Epson developer account.

groggit commented 7 years ago

although not a complete solution, I ended up using a custom error handler. It doesn't show specific printer status but it is useful to give some generic user feedback when there is a problem with the printer:

<?php

function customError($errno, $errstr) {
  echo '<script>';
  echo 'alert("Check Printer");';
  echo 'window.history.go(-2);';
  echo '</script>';
}

//set error handler
set_error_handler("customError");

// print the customer docket

require "assets/php/escpos/autoload.php";
use Mike42\Escpos\Printer;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;

$connector = new FilePrintConnector("/dev/usb/lp0");
$printer = new Printer($connector);
francoisk commented 6 years ago

Regarding DLE EOT (real-time status): on the TM-T20II (though I am sure this works for many Epsons), if you turn on memory switch 1-3 (which sets "BUSY condition" to "receive buffer full" from "receive buffer full or offline"), the printer will respond to DLE EOT at all times, including when the cover is open or it's out of paper. (And not just once per printer reboot---always, consistently.)

According to the manual, the printer goes into "offline" mode in the following cases: • During power on until the printer is ready • During the self-test • While roll paper is fed using the Feed button • When the roll paper cover is open • When the printer stops printing due to a paper end • During a macro execution standby state • When an error has occurred (See "Error Status" on page 17.)

So the setting change above makes it "not BUSY" when in these states.

For my project I don't currently see a use for ASB (GS a) now that the real-time status is working as expected.

jaroja4 commented 6 years ago

Hi @mike42 I'm not using composer I'm trying to print from a Raspberry Pi (raspbian) but I have some problems. In: '<? php require_once ("Escpos.php"); $ c = new FilePrintConnector ("/ dev / usb / lp0"); $ printer = new Escpos ($ c);'

Where do I locate the file Escpos.php ??

Thank you.

ludi81 commented 5 years ago

Hi @francoisk,

I am using TM-T88V and would like to detect paper empty. can you say me which switch I need to change? Ist it switch 2-1 https://www.manualslib.com/manual/48680/Epson-Tm-T88iii-Series.html?page=24#manual

Furthermore I would like to know if it is possible to clear outstanding printing commands (e.g. if the paper is empty).