williamkapke / ipp

Internet Printing Protocol (IPP) for nodejs
412 stars 111 forks source link

My print only supports application/octet-stream - how can I print an image / pdf ? #101

Open exotexot opened 1 year ago

exotexot commented 1 year ago

Hello,

I managed to connect to my printer with this library! However, my printer ONLY supports application/octet-stream, How can I send it the right command to print a normal pdf.

I tried the example from this modules readme (any many others) but didn't get it to work.

I tried PDFkit and PCLkit

` const doc = new PDFDocument(); doc.fontSize(25).text("Some text with an embedded font!", 100, 100); doc.end();

      const printerURI = "http://192.168.1.88/ipp/lp_u1_2";

      const printer = ipp.Printer(printerURI, { version: "1.0" }); //only works with version 1.0

      const msg = {
        "operation-attributes-tag": {
          "requesting-user-name": "William",
          "job-name": "My Test Job",
          "document-format": "application/octet-stream",
        },
        data: doc,
      };
      printer.execute("Print-Job", msg, function (err, res) {
        console.log(res);
      });`

Any advice? :/

thenewguy commented 1 year ago

Put a cups server in front of the printer and send your print to cups is probably the easiest path

exotexot commented 1 year ago

I mean, the printer I'm using is actually a normal printer and can obviously print everything correctly.

I just need to use this printer over a cheap DS-510 silex network print server thing. Here I get an IPP address so I was thinking I could send a print request over this IPP library. I feel like I just need to tell the printer to print the document in the right format somehow.

However, in this library it tells me that it only support "application/octet-stream"...

thenewguy commented 1 year ago

application/octet-stream is just a generic mimetype that means binary. This probably means there is a particular format the printer needs - i.e. you need a special driver to communicate. You can figure that out or rely on something like CUPs to handle it.

exotexot commented 1 year ago

Okay I understand.. But just to make sure: is CUPs like a hardware module that you would suggest, or is it a software module, that ideally is compatible with node.js?

thenewguy commented 1 year ago

It is a print server that exposes printers for IPP Everywhere printing (which is what you want for printing a PDF if your printer doesn't offer this natively) - http://www.cups.org/

exotexot commented 1 year ago

I'll look into that. Thank you very much! :)

exotexot commented 1 year ago

@thenewguy thank you so much. I could get it to work with cups.

However, could you point me in the right direction of HOW to send a print job via nodeJS? I guess using THIS ipp library here is not the way, is it?

thenewguy commented 1 year ago

I don't currently use this project. But it should work for you - in the past I've even made it work from the browser.

But if you want help you'll need to have a more specific problem that shows what you've done/how you've done it, what the results were, and what you expected to happen.

Hopefully someone who is currently using this code will be able to help you

exotexot commented 1 year ago

Sure..

This is the list of the supported Printer Attributes, when calling

getPrinterAttributes: () => {
    printer.execute("Get-Printer-Attributes", null, function (err, res) {
      console.log(res);
    });
  }

Result:

 {
   version: '1.0',
   statusCode: 'successful-ok',
   id: 20103438,
   'operation-attributes-tag': {
     'attributes-charset': 'utf-8',
     'attributes-natural-language': 'en-us'
   },
   'printer-attributes-tag': {
     'printer-name': '',
     'printer-location': '',
     'printer-info': 'MFG:EPSON;CMD:ESCPL2,BDC,D4,D4PX,ESCPR1,END4,GENEP;MDL:ET-2750 Series;CLS:PRINTER;DES:EPSON ET-2750 Series;CID:EpsonRGB;FID:FXN,DPA,WFA,ETN,AFN,DAN,WRA;RID:40;DDS:022500;ELG:1162;SN:583738503030393803;',
     'printer-make-and-model': 'ET-2750 Series',
     'printer-state': 'idle',
     'printer-state-reasons': 'none',
     'printer-state-message': 'Ready [ET-2750 Series]  ',
     'charset-configured': 'utf-8',
     'printer-is-accepting-jobs': true,
     'queued-job-count': 0,
     'printer-up-time': 16113,
     'printer-uri-supported': [
       'http://192.168.1.84/ipp/lp_u1_2',
       'http://192.168.1.84:631/ipp/lp_u1_2',
       'http://192.168.1.84dummy',
       'http://192.168.1.84:631dummy',
       'http://192.168.1.84dummy',
       'http://192.168.1.84:631dummy',
       'http://192.168.1.84dummy',
       'http://192.168.1.84:631dummy'
     ],
     'uri-security-supported': [
       'none', 'none',
       'none', 'none',
       'none', 'none',
       'none', 'none'
     ],
     'operations-supported': [
       'Print-Job',
       'Validate-Job',
       'Cancel-Job',
       'Get-Job-Attributes',
       'Get-Jobs',
       'Get-Printer-Attributes'
     ],
     'charset-supported': [ 'us-ascii', 'utf-8' ],
     'generated-natural-language-supported': 'en-us',
     'natural-language-configured': 'en-us',
     'document-format-supported': 'application/octet-stream',
     'document-format-default': 'application/octet-stream',
     'pdl-override-supported': 'not-attempted',
     'compression-supported': 'none',
     'job-sheets-default': 'none',
     'job-sheets-supported': [ 'none', 'standard' ]
   }
 }

So I can print from the printer. However, if I want to print a PDF file, then only garbage comes out of the printer (or the Printer prints the contents of the file, and not the actual file)

printFile: async () => {
    console.log("calling2");
    fs.readFile("./test.pdf", (err, data) => {
      if (err) console.log(err);
      else {
        const msg = {
          "operation-attributes-tag": {
            "requesting-user-name": "bla",
            "job-name": "My Test Job",
            "document-format": "application/octet-stream",
          },
          data: Buffer.from(data),
        };
        printer.execute("Print-Job", msg, function (err, res) {
          console.log(res);
        });
      }
    });
  },

I've tried many variations (with and without using buffer for the data property. But the result is always like shown on the picture...

I've set up the CUPS thing. Added my printer and can print test pages just fine.... But I'm struggling the issue a print command which prints proper pdfs from my nodeJS environment.

IMG_1623 Medium

thenewguy commented 1 year ago

I am a little confused by what you've sent. I thought you said CUPs worked? Now you replace your printer address with the cups address and communicate with the printer through CUPs

thenewguy commented 1 year ago

Show the response from the CUPS server for the Get-Printer-Attributes. It should list application/pdf as a supported type

exotexot commented 1 year ago

Okay.

So in my environment im running the cups server in a docker using this image: https://hub.docker.com/r/olbat/cupsd This services runs on 127.0.0.1:631

I connected my printer via USB to a Silex DS510 to make the printer discoverable in my network. I receive a local ip address for my printer then and an ipp interface: http://192.168.1.84/ipp/lp_u1_2

I can add this printer in the cups server, see image attached:

Screenshot 2023-02-02 at 17 53 40

Unfortunately using this ipp library, I cannot comminacte with the cups server itself

const printerURI2 = "http://127.0.0.1:631";
const printer2 = ipp.Printer(printerURI2, { version: "1.0" });

module.exports = {
  getPrinterAttributes: () => {
    printer2.execute("Get-Printer-Attributes", null, function (err, res) {
      console.log(res); // returns undefined using printer2
    });

Edit: I also tried this URI: http://127.0.0.1:631/printers/EPSON-TEST and I can't connect using this IPP library to his uri. I only can communicate via the local ip.

thenewguy commented 1 year ago

You have to configure CUPs to allow network printing and make sure the networking is correct. I think this will work for you but you have to learn how to configure it. It depends on your particular hardware layout so I can't be much help here other than to say that I've used this library to print through cups from a web browser successfully.