Как я могу записать несколько значений в характеристику BLE через Javascript?

В настоящее время я работаю над проектом, в котором я пытаюсь отправить 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.

Вы пытались разделить данные на несколько записей?

Emil 02.07.2019 15:35

Я не совсем уверен, как сделать несколько записей. Могу ли я просто добавить несколько операторов «return character.writeValue» в один и тот же блок «characteristic => {}»?

Anton Delticom 03.07.2019 09:03
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
2
1 344
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

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.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 байт, пока не будет обработана вся этикетка. Важно иметь небольшую задержку между каждой последовательной записью, иначе принтер по какой-либо причине не будет отвечать.

Другие вопросы по теме