Skip to content

Commit

Permalink
Support for device uri
Browse files Browse the repository at this point in the history
  • Loading branch information
Cédric de Launois committed Feb 22, 2025
1 parent 3c75686 commit a21d1cc
Show file tree
Hide file tree
Showing 14 changed files with 397 additions and 133 deletions.
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ Here is a quick example of how to print a label using the library:
.setDelay(1000)
.setImages(List.of(image));
// Print the job
// Print the job, using the first detected USB Brother printer
BrotherQLConnection connection = new BrotherQLConnection();
try {
try (connection) {
// Open the connection with the printer
connection.open();
Expand All @@ -80,12 +80,17 @@ Here is a quick example of how to print a label using the library:
} catch (BrotherQLException e) {
// Error while printing, See e.getMessage()
} finally {
connection.close();
...
}
```
The list of available USB printers can be obtained through a call to `BrotherQLConnection.listDevices()`,
that will return a list of printer identifier like `usb://Brother/QL-700?serial=XXXX`, where `QL-700` is the name
of a model (see `BrotherQLModel` enum class), and `?serial=XXXX` is optional and can be used to define the serial number
of the printer to use.
The identifier is to be used as parameter of the `BrotherQLConnection` constructor.


## Linux UDEV Configuration

Please note that the package need Read/Write access to the USB printer device.
Expand Down
8 changes: 7 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<groupId>org.delaunois</groupId>
<artifactId>brotherql</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>1.1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<licenses>
<license>
Expand Down Expand Up @@ -172,6 +172,12 @@
<version>2.0.16</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>

</project>
64 changes: 47 additions & 17 deletions src/main/java/org/delaunois/brotherql/BrotherQLConnection.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
Expand All @@ -27,7 +29,7 @@
*
* @author Cedric de Launois
*/
public final class BrotherQLConnection {
public final class BrotherQLConnection implements Closeable {

private static final Logger LOGGER = System.getLogger(BrotherQLConnection.class.getName());

Expand Down Expand Up @@ -66,21 +68,49 @@ public final class BrotherQLConnection {
private BrotherQLDevice device;

/**
* Construct a connection assuming a USB Printer Device.
* Construct a connection to the first USB Brother Printer found.
*/
public BrotherQLConnection() {
this.device = new BrotherQLDeviceUsb();
}

/**
* Construct a connection assuming the given Printer Device.
* Construct a connection to the device identified by the given printer identifier.
* The identifier is a string like "usb://Brother/QL-700?serial=XXX"
* See {@link #listDevices()} to get the identifiers of connected printers.
*
* @param address the device address
*/
public BrotherQLConnection(String address) {
URI uri = URI.create(address);
if ("usb".equals(uri.getScheme())) {
this.device = new BrotherQLDeviceUsb(uri);
} else {
throw new UnsupportedOperationException("Scheme " + uri.getScheme() + " not supported");
}
}

/**
* Construct a connection using the given Printer Device.
*
* @param device the backend device to use
*/
public BrotherQLConnection(BrotherQLDevice device) {
this.device = device;
}

/**
* Get the list of connected Brother printers.
* Only USB devices can be discovered.
*
* @return the list of printer identifiers, e.g. "usb://Brother/QL-700?serial=XXX"
* @throws BrotherQLException if an error occurred while getting the device list
*/
public static List<String> listDevices() throws BrotherQLException {
// Only USB devices can be discovered
return BrotherQLDeviceUsb.listDevices();
}

/**
* Search for a USB Brother printer and open a connection.
*
Expand All @@ -104,13 +134,13 @@ public void reset() throws BrotherQLException {
}

/**
* Get the printer identification.
* Get the printer model.
* The device must be opened first.
*
* @return the printer id or null if no Brother printer were detected
* @return the printer model or null if no Brother printer were detected
*/
public BrotherQLPrinterId getPrinterId() {
return device.getPrinterId();
public BrotherQLModel getModel() {
return device.getModel();
}

/**
Expand All @@ -123,7 +153,7 @@ public BrotherQLPrinterId getPrinterId() {
*/
public BrotherQLStatus requestDeviceStatus() throws BrotherQLException {
if (device.isClosed()) {
return new BrotherQLStatus(null, device.getPrinterId(), Rx.msg("error.notopened"));
return new BrotherQLStatus(null, device.getModel(), Rx.msg("error.notopened"));
}

device.write(CMD_STATUS_REQUEST, TIMEOUT);
Expand All @@ -138,7 +168,7 @@ public BrotherQLStatus requestDeviceStatus() throws BrotherQLException {
*/
public BrotherQLStatus readDeviceStatus() {
if (device.isClosed()) {
return new BrotherQLStatus(null, device.getPrinterId(), Rx.msg("error.notopened"));
return new BrotherQLStatus(null, device.getModel(), Rx.msg("error.notopened"));
}

BrotherQLStatus brotherQLStatus;
Expand All @@ -150,7 +180,7 @@ public BrotherQLStatus readDeviceStatus() {
} else {
byte[] status = new byte[STATUS_SIZE];
response.get(status);
brotherQLStatus = new BrotherQLStatus(status, device.getPrinterId());
brotherQLStatus = new BrotherQLStatus(status, device.getModel());
}

LOGGER.log(Level.DEBUG, "Status is " + brotherQLStatus);
Expand Down Expand Up @@ -300,13 +330,13 @@ private void checkJob(List<BufferedImage> images, BrotherQLMedia media) throws B
throw new BrotherQLException(String.format(Rx.msg("error.img.badwidth"), media.bodyWidthPx));
}

BrotherQLPrinterId printerId = device.getPrinterId();
BrotherQLModel model = device.getModel();
if (BrotherQLMediaType.CONTINUOUS_LENGTH_TAPE.equals(media.mediaType)) {
if (bodyLengthPx < printerId.clMinLengthPx) {
throw new BrotherQLException(String.format(Rx.msg("error.img.minheight"), printerId.clMinLengthPx));
if (bodyLengthPx < model.clMinLengthPx) {
throw new BrotherQLException(String.format(Rx.msg("error.img.minheight"), model.clMinLengthPx));
}
if (bodyLengthPx > printerId.clMaxLengthPx) {
throw new BrotherQLException(String.format(Rx.msg("error.img.maxheight"), printerId.clMaxLengthPx));
if (bodyLengthPx > model.clMaxLengthPx) {
throw new BrotherQLException(String.format(Rx.msg("error.img.maxheight"), model.clMaxLengthPx));
}
} else {
if (bodyLengthPx != media.bodyLengthPx) {
Expand All @@ -326,7 +356,7 @@ private void sendControlCode(List<BufferedImage> images, BrotherQLJob job, Broth
ByteArrayOutputStream bos = new ByteArrayOutputStream();

// Switch to raster if multiple modes exist
if (!device.getPrinterId().rasterOnly) {
if (!device.getModel().rasterOnly) {
bos.write(CMD_SWITCH_TO_RASTER);
}

Expand Down Expand Up @@ -372,7 +402,7 @@ private void sendControlCode(List<BufferedImage> images, BrotherQLJob job, Broth
}

private int getFeedAmount(BrotherQLJob job, BrotherQLMedia media) {
if (device.getPrinterId().allowsFeedMargin) {
if (device.getModel().allowsFeedMargin) {
return job.getFeedAmount() & 0xFFFF;
} else if (media.mediaType.equals(BrotherQLMediaType.DIE_CUT_LABEL)) {
return 0;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/org/delaunois/brotherql/BrotherQLMedia.java
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,13 @@ public enum BrotherQLMedia {
* @return the media
*/
public static BrotherQLMedia identify(BrotherQLStatus status) {
BrotherQLPrinterId printerId = status.getPrinterId();
BrotherQLModel model = status.getModel();
BrotherQLMediaType mediaType = status.getMediaType();
int labelWidthMm = status.getMediaWidth();
int labelLengthMm = status.getMediaLength();

int rgtSizeByte = 90;
if (BrotherQLPrinterId.QL_1050.equals(printerId) || BrotherQLPrinterId.QL_1060N.equals(printerId)) {
if (BrotherQLModel.QL_1050.equals(model) || BrotherQLModel.QL_1060N.equals(model)) {
rgtSizeByte = 162;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,73 +16,73 @@
*
* @author Cedric de Launois
*/
public enum BrotherQLPrinterId {
public enum BrotherQLModel {

/**
* Brother QL-500
*/
QL_500("Brother QL-500", 0x2015, true, 295, 11811, true),
QL_500("QL-500", 0x2015, true, 295, 11811, true),

/**
* Brother QL-550
*/
QL_550("Brother QL-550", 0x2016, false, 295, 11811, true),
QL_550("QL-550", 0x2016, false, 295, 11811, true),

/**
* Brother QL-560
*/
QL_560("Brother QL-560", 0x2027, false, 295, 11811, true),
QL_560("QL-560", 0x2027, false, 295, 11811, true),

/**
* Brother QL-570
*/
QL_570("Brother QL-570", 0x2028, false, 150, 11811, true),
QL_570("QL-570", 0x2028, false, 150, 11811, true),

/**
* Brother QL-580N
*/
QL_580N("Brother QL-580N", 0x2029, false, 150, 11811, false),
QL_580N("QL-580N", 0x2029, false, 150, 11811, false),

/**
* Brother QL-650TD
*/
QL_650TD("Brother QL-650TD", 0x201B, true, 295, 11811, false),
QL_650TD("QL-650TD", 0x201B, true, 295, 11811, false),

/**
* Brother QL-700
*/
QL_700_P("Brother QL-700", 0x2042, false, 150, 11811, true),
QL_700_P("QL-700", 0x2042, false, 150, 11811, true),

/**
* Brother QL-700M
*/
QL_700_M("Brother QL-700M", 0x2049, false, 150, 11811, true),
QL_700_M("QL-700M", 0x2049, false, 150, 11811, true),

/**
* Brother QL-1050
*/
QL_1050("Brother QL-1050", 0x2020, true, 295, 35433, false),
QL_1050("QL-1050", 0x2020, true, 295, 35433, false),

/**
* Brother QL-1060N
*/
QL_1060N("Brother QL-1060N", 0x202A, true, 295, 35433, false),
QL_1060N("QL-1060N", 0x202A, true, 295, 35433, false),

/**
* Unknown printer
*/
UNKNOWN(Rx.msg("printerid.unknown"), 0x000, false, 0, 0, true);
UNKNOWN(Rx.msg("model.unknown"), 0x000, false, 0, 0, true);

private static final Map<Integer, BrotherQLPrinterId> CODE_MAP = new HashMap<>();
private static final Map<Integer, BrotherQLModel> CODE_MAP = new HashMap<>();

static {
for (BrotherQLPrinterId mt : BrotherQLPrinterId.values()) {
for (BrotherQLModel mt : BrotherQLModel.values()) {
CODE_MAP.put(mt.code, mt);
}
}

/**
* The name of the printer.
* The model of the printer.
*/
public final String name;

Expand Down Expand Up @@ -111,7 +111,7 @@ public enum BrotherQLPrinterId {
*/
public final boolean rasterOnly;

BrotherQLPrinterId(String name, Integer code, boolean allowsFeedMargin, int clMinLengthPx, int clMaxLengthPx, boolean rasterOnly) {
BrotherQLModel(String name, Integer code, boolean allowsFeedMargin, int clMinLengthPx, int clMaxLengthPx, boolean rasterOnly) {
this.code = code;
this.allowsFeedMargin = allowsFeedMargin;
this.clMinLengthPx = clMinLengthPx;
Expand All @@ -124,11 +124,11 @@ public enum BrotherQLPrinterId {
* Identify the printer based on the code.
*
* @param code the code
* @return the printer Id
* @return the printer model
*/
public static BrotherQLPrinterId fromCode(int code) {
BrotherQLPrinterId printerId = CODE_MAP.get(code);
return printerId == null ? UNKNOWN : printerId;
public static BrotherQLModel fromCode(int code) {
BrotherQLModel model = CODE_MAP.get(code);
return model == null ? UNKNOWN : model;
}

@Override
Expand Down
Loading

0 comments on commit a21d1cc

Please sign in to comment.