-
-
Save tresf/898ab2d4d259aef2d4f7 to your computer and use it in GitHub Desktop.
<html> | |
<!-- | |
Author: A. Tres Finocchiaro, tres.finocchiaro@gmail.com | |
License: LGPL 2.1 | |
Depends: QZ Tray 2.0.0-alpha1+ | |
--> | |
<!-- Note: jquery is not needed in alpha2 --> | |
<script type="text/javascript" src="js/dependencies/jquery-1.11.3.min.js"></script> | |
<!-- Note: rsvp can be overriden via qz.setPromiseType(...) TODO: Get usage from @bberenz --> | |
<script type="text/javascript" src="js/dependencies/rsvp-3.1.0.min.js"></script> | |
<script type="text/javascript" src="js/qz-tray.js"></script> | |
<script> | |
// Scale manufacturers | |
var mt = { | |
vendor: '0x0EB8', | |
product: '0xF000', | |
device: '0x00', | |
endpoint: '0x81', | |
}; | |
var dymo = { | |
vendor: '0x0922', | |
product: '0x8009', | |
device: '0x00', | |
endpoint: '0x82', | |
}; | |
// FIXME: Verify with physical scale | |
var stamps = { | |
vendor: '0x1446', // or '0x6A73' | |
product: '0xF000', | |
device: '0x00', | |
endpoint: '0x81', | |
}; | |
var scale = mt; | |
var err = function(e) { console.error(e); } | |
var release = function() { | |
qz.usb.releaseDevice(scale.vendor, scale.product).catch(function(e) { | |
console.error(e); | |
}); | |
} | |
qz.websocket.connect().then(function() { | |
return qz.usb.claimDevice(scale.vendor, scale.product, scale.device); | |
}).catch(err).then(function() { | |
return qz.usb.readData(scale.vendor, scale.product, scale.endpoint, '8'); | |
}).then(function(data) { | |
// Get status | |
var status = parseInt(data[1], 16); | |
switch(status) { | |
case 1: // fault | |
case 5: // underweight | |
case 6: // overweight | |
case 7: // calibrate | |
case 8: // re-zero | |
status = 'error'; break; | |
case 3: | |
status = 'busy'; break; | |
case 2: // stable at zero | |
case 4: // stable non-zero | |
default: | |
status = 'stable'; | |
} | |
// Get precision | |
var precision = parseInt(data[3], 16); | |
precision = precision ^ -256; // unsigned to signed | |
// Get weight | |
data.splice(0,4); | |
data.reverse(); | |
weight = parseInt(data.join(''), 16); | |
// Apply precision | |
weight *= Math.pow(10, precision); | |
weigth = weight.toFixed(Math.abs(precision)); | |
// Get units | |
var units = parseInt(data[2], 16); | |
switch(units) { | |
case 3: | |
units = 'kg'; break; | |
case 11: // ounces | |
units = 'oz'; break; | |
case 12: | |
default: | |
units = 'lbs'; | |
} | |
alert(status + ": " + weight + units); | |
}).then(release).catch(release); | |
</script> | |
</html> |
In trying to find an explanation for the previous readings that come through, I happened on information that the scale precision is also sent through the raw data, at index 3 as an unsigned byte. Converting to signed yields a negative number such that weight * 10^[signed_value]
yeilds the correct weight.
// Get precision
var precision = parseInt(data[3], 16);
precision = precision ^ -256; //unsigned to signed
// Get weight
...
weight *= Math.pow(10, precision);
weight = weight.toFixed(Math.abs(precision));
@bberenz Done, and done, thanks.
FYI, I don't think GitHub sends notices on Gists, so I'm attempting to tag you instead. 👍
Anyone have a recommendation for a USB scale that this would work with? Would this also work with a Bluetooth scale?
@ProPixelMedia this proof of concept is now part of QZ Tray. https://github.com/qzind/tray/blob/master/js/qz-tray.js
With regards to HID communications, all scales use the same protocol. Bluetooth might use the HID protocol or it may use a serial protocol. Serial protocols differ.
I don't see the point of the empty
sendData
call, so it probably can be removed.Chaining promises will save you horizontal space, plus you can combine similar catches.
Here both
connect
andclaimDevice
will use theerr
catch function if they fail, and onlyreadData
will use therelease
catch on failure.