Как я могу записать несколько значений в характеристику BLE через Javascript? - PullRequest
1 голос
/ 02 июля 2019

В настоящее время я работаю над проектом, в рамках которого я пытаюсь отправить ZPL-метку из браузера на принтер Zebra (ZQ520) с использованием Javascript и Bluetooth.

В настоящее время я могу найтиПринтер через Bluetooth 4.0, используя его SUUID и его имя.Я также могу отправлять небольшие наклейки ZPL на принтер через «attribute.writeValue», и принтер правильно их печатает сразу после отправки.

Моя главная проблема заключается в том, что максимальная длинаBLE может иметь передачу метки.Все, что короче 512 символов, передается и печатается правильно.

Если моя метка превышает 512 символов, принтер выдает «DOMException» и ничего не печатает.

Мой текущий код:

navigator.bluetooth.requestDevice({
  filters:[
    { name: 'deviceName' }, { services: [ServiceUUID] }
  ]
}
.then(device => {
    console.log(device);
    return device.gatt.connect();
})
.then(server => {
  console.log(server);
  serverInstance = server; 
  return server.getPrimaryService(ServiceUUID);
})
.then(service => {
  console.log(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.log(data);
  return characteristic.writeValue(data);
})
.catch(error => {
   console.log('Connection failed!', error);
});

512 байтПредел соединения BLE также задокументирован в документации BLE принтера: «Объем данных, которые могут быть записаны в характеристику, составляет минимум MTU ATT удаленного соединения и 512 байтов».https://www.zebra.com/content/dam/zebra/software/en/application-notes/AppNote-BlueToothLE-v4.pdf

Как обойти проблему?Фактическая метка, которую я должен отправить, имеет размер более 2500 байт.

В документации упоминается, что также возможна «длинная запись» через Bluetooth.Я предполагаю, что есть также возможность записывать небольшие пакеты данных на принтер вместо отправки всей этикетки сразу.

Сейчас я просто пытаюсь найти правильный синтаксис, как это сделать с помощью Javascript.

1 Ответ

0 голосов
/ 03 июля 2019

Я нашел решение с помощью этого урока:

https://github.com/Zebra/Zebra-Printer-Samples/blob/master/WeChat-MiniProgram-Samples/WeChatPrintDemo/README.md

Добавленный к коду, который у меня был раньше, он в основном выглядит так:

  var zpl = "..."; // whatever your label is

  navigator.bluetooth.requestDevice({
    filters:[
      { name: 'deviceName' },
      { services: [ServiceUUID] }
    ]
  })
  .then(device => {
    console.log(device);
    return device.gatt.connect();
  })
  .then(server => {
    console.log(server);
    serverInstance = server; 
    return server.getPrimaryService(ServiceUUID);
  })
  .then(service => {
    console.log(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.log('accessing the device');
      return characteristic.writeValue(buffer);
    }
  })
  .catch(error => {
    console.log('Connection failed!', error);
  });

JavaScript записывает куски по 300 байт на принтер, пока не будет обработана вся этикетка.Важно иметь небольшую задержку между каждой последовательной записью, иначе принтер не будет отвечать по любой причине.

...