-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathUsbScaleTest.java
More file actions
129 lines (116 loc) · 3.79 KB
/
Copy pathUsbScaleTest.java
File metadata and controls
129 lines (116 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package com.nighthacking;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.usb.UsbConfiguration;
import javax.usb.UsbDevice;
import javax.usb.UsbDeviceDescriptor;
import javax.usb.UsbEndpoint;
import javax.usb.UsbException;
import javax.usb.UsbHostManager;
import javax.usb.UsbHub;
import javax.usb.UsbInterface;
import javax.usb.UsbPipe;
import javax.usb.UsbServices;
import javax.usb.event.UsbPipeDataEvent;
import javax.usb.event.UsbPipeErrorEvent;
import javax.usb.event.UsbPipeListener;
/**
* Self-contained implementation that connects to a USB scale and outputs the
* data returned to the command line.
*
* @author Stephen Chin <[email protected]>
*/
public class UsbScaleTest implements UsbPipeListener {
private final UsbDevice device;
private UsbInterface iface;
private UsbPipe pipe;
private byte[] data = new byte[6];
private UsbScaleTest(UsbDevice device) {
this.device = device;
}
public static void main(String[] args) throws UsbException {
UsbScaleTest scale = UsbScaleTest.findScale();
scale.open();
try {
for (int i = 0; i < 60; i++) {
scale.syncSubmit();
}
} finally {
scale.close();
}
}
public static UsbScaleTest findScale() throws UsbException {
UsbServices services = UsbHostManager.getUsbServices();
UsbHub rootHub = services.getRootUsbHub();
// Dymo M10 Scale:
UsbDevice device = findDevice(rootHub, (short) 0x0922, (short) 0x8003);
// Dymo M25 Scale:
if (device == null) {
device = findDevice(rootHub, (short) 0x0922, (short) 0x8004);
}
if (device == null) {
return null;
}
return new UsbScaleTest(device);
}
private static UsbDevice findDevice(UsbHub hub, short vendorId, short productId) {
for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices()) {
UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
if (desc.idVendor() == vendorId && desc.idProduct() == productId) {
return device;
}
if (device.isUsbHub()) {
device = findDevice((UsbHub) device, vendorId, productId);
if (device != null) {
return device;
}
}
}
return null;
}
private void open() throws UsbException {
UsbConfiguration configuration = device.getActiveUsbConfiguration();
iface = configuration.getUsbInterface((byte) 0);
// this allows us to steal the lock from the kernel
iface.claim(usbInterface -> true);
final List<UsbEndpoint> endpoints = iface.getUsbEndpoints();
pipe = endpoints.get(0).getUsbPipe(); // there is only 1 endpoint
pipe.addUsbPipeListener(this);
pipe.open();
}
private void syncSubmit() throws UsbException {
pipe.syncSubmit(data);
}
public void close() throws UsbException {
pipe.close();
iface.release();
}
@Override
public void dataEventOccurred(UsbPipeDataEvent upde) {
boolean empty = data[1] == 2;
boolean overweight = data[1] == 6;
boolean negative = data[1] == 5;
boolean grams = data[2] == 2;
int scalingFactor = data[3];
int weight = (data[4] & 0xFF) + (data[5] << 8);
if (empty) {
System.out.println("EMPTY");
} else if (overweight) {
System.out.println("OVERWEIGHT");
} else if (negative) {
System.out.println("NEGATIVE");
} else { // Use String.format since printf causes problems on remote exec
System.out.println(String.format("Weight = %,.1f%s",
scaleWeight(weight, scalingFactor),
grams ? "g" : "oz"));
}
}
private double scaleWeight(int weight, int scalingFactor) {
return weight * Math.pow(10, scalingFactor);
}
@Override
public void errorEventOccurred(UsbPipeErrorEvent upee) {
Logger.getLogger(UsbScaleTest.class.getName()).log(Level.SEVERE, "Scale Error", upee);
}
}