В настоящее время я работаю над проектом, в котором я пытаюсь отправить ZPL-метку из браузера на принтер Zebra (ZQ520) с помощью Javascript и Bluetooth.
В настоящее время я могу найти принтер через Bluetooth 4.0, используя его SUUID и его имя. Я также могу отправлять небольшие этикетки ZPL на принтер через 'characteristic.writeValue', и принтер печатает их правильно сразу после того, как я их отправил.
Моя основная проблема заключается в том, что существует максимальная длина BLE-передачи метки. Все, что короче 512 символов, передается и печатается правильно.
Если моя метка превышает 512 символов, принтер выдает исключение DOMException и ничего не печатает.
Мой текущий код:
navigator.bluetooth.requestDevice({
filters:[
{ name: 'deviceName' }, { services: [ServiceUUID] }
]
}
.then(device => {
console.info(device);
return device.gatt.connect();
})
.then(server => {
console.info(server);
serverInstance = server;
return server.getPrimaryService(ServiceUUID);
})
.then(service => {
console.info(service);
return service.getCharacteristic(commandCharacteristicUUID);
})
.then(characteristic => {
var zpl = "^FS^FT66,339^A0N,68,83^FDBeispieltext^FS^FT66,439^A0N,68,83^FDBeispieltext^FS^FT66,539^A0N,68,83^FDBeispieltext^FS^FT66,639^A0N,68,83^FDBeispieltext^FS^FT66,739^A0N,68,83^FDBeispieltext^FS^FT66,839^A0N,68,83^FDBeispieltext^FS^FT66,939^A0N,68,83^FDBeispieltext^FS^PQ1,0,1,Y^XZ";
var encoder = new TextEncoder();
var data = encoder.encode(zpl);
console.info(data);
return characteristic.writeValue(data);
})
.catch(error => {
console.info('Connection failed!', error);
});
Ограничение в 512 байт для подключения BLE также задокументировано в документации BLE принтера: «Объем данных, который может быть записан в характеристику, составляет минимум ATT MTU удаленного соединения и 512 байт». https://www.zebra.com/content/dam/zebra/software/en/application-notes/AppNote-BlueToothLE-v4.pdf
Как мне обойти проблему? Фактическая метка, которую я должен отправить, имеет размер более 2500 байт.
В документации упоминается, что также возможна «длинная запись» через Bluetooth. Я предполагаю, что есть также возможность записывать на принтер небольшие пакеты данных вместо отправки сразу всей этикетки.
В настоящее время я пытаюсь найти правильный синтаксис, как это сделать с помощью Javascript.
Я не совсем уверен, как сделать несколько записей. Могу ли я просто добавить несколько операторов «return character.writeValue» в один и тот же блок «characteristic => {}»?
Я нашел решение с помощью этого учебника:
Добавленный к коду, который у меня был раньше, он выглядит примерно так:
var zpl = "..."; // whatever your label is
navigator.bluetooth.requestDevice({
filters:[
{ name: 'deviceName' },
{ services: [ServiceUUID] }
]
})
.then(device => {
console.info(device);
return device.gatt.connect();
})
.then(server => {
console.info(server);
serverInstance = server;
return server.getPrimaryService(ServiceUUID);
})
.then(service => {
console.info(service);
return service.getCharacteristic(commandCharacteristicUUID);
})
.then(characteristic => {
var maxChunk = 300;
var j = 0;
if ( zpl.length > maxChunk ) {
for ( var i = 0; i < zpl.length; i += maxChunk ) {
var subStr;
if ( i + maxChunk <= zpl.length ) {
subStr = zpl.substring(i, i + maxChunk);
} else {
subStr = zpl.substring(i, zpl.length);
}
setTimeout(writeStrToCharacteristic, 250 * j, subStr);
j++;
}
} else {
writeStrToCharacteristic(zpl);
}
function writeStrToCharacteristic (str) {
let buffer = new ArrayBuffer(str.length);
let dataView = new DataView(buffer);
for (var i = 0; i <str.length; i++) {
dataView.setUint8( i, str.charAt(i).charCodeAt() );
}
console.info('accessing the device');
return characteristic.writeValue(buffer);
}
})
.catch(error => {
console.info('Connection failed!', error);
});
JavaScript записывает на принтер куски по 300 байт, пока не будет обработана вся этикетка. Важно иметь небольшую задержку между каждой последовательной записью, иначе принтер по какой-либо причине не будет отвечать.
Вы пытались разделить данные на несколько записей?