Ваш софт для ТСД — просто подписчик на Intent’ы, а не хозяин сканера. И вот почему

от автора

Привет, Хабр!

Сегодня продолжим погружать вас в мир товаров и их учета с помощью ТСД. Расскажем про неочевидные, но очень большие проблемы, которые мы в Клеверенсе вынуждены решать довольно необычным способом.

Сразу хочу подсветить главное используемая технология и описанное её применение запатентовано компанией Клеверенс, а также отметить факт того, что мобильной платформе Клеверенс (Mobile SMARTS) в 2026 году исполнилось 22 года. Примеры проблем и решений, описанных ниже в статье, начинались у пользователей с истоков прихода ТСД в Россию.

Ну так вот… ТСД – довольно интересное устройство. И как у любого интересного устройства, у него есть свои особенности. Чем является терминал с точки зрения компьютера или сервера, куда он передает информацию? Наверное вы предположите, что это некое специализированное устройство со своим драйвером? Все верно, если речь идет о хорошем и добросовестном производителе (об этом уже есть статья тут). Но очень и очень многие ТСД определяются компьютерами как… клавиатуры. Да-да, вы не ослышались, именно так. Клавиатура, с которой кто-то вводит информацию.

Давайте уточним терминологию. ТСД – это терминал сбора данных. Устройство, со сканером, модулем обработки, экраном, модулем связи с сервером, комплектом аккумуляторов. 

Сканер – это часть ТСД, отвечающая за, собственно, сканирование штрихкодов. Это важно, чтобы не запутаться в дальнейшем рассказе.

В чем проблема такого «клавиатурного» подхода? Проблем, на самом деле, много.

  1. Т.к. сервер считает терминал клавиатурой, он применяет к нему принципы работы с клавиатурой. Например, к нему приходят нажатия  ‘1’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘1’. У сервера свое ПО в котором этот случай расценивается как залипание клавиши. И он с легкой компьютерной руки обрезает наш код, скажем, до 10001. Это абсолютно реальная ситуация.

  2. А еще на клавиатуре ограничен набор символов, которые она может отправить. И сервер может знать об этом ограничении. А ТСД нет, он шлет, что видит. В итоге, может пропасть часть каких-то специализированных символов.

  3. А еще, если уж производитель сэкономил на драйверах (а именно для этого терминал заставляют прикидываться клавиатурой), то он наверняка допустил еще один конструктивный просчет. У ТСД такого производителя ограничена возможность программно заблокировать часть, отвечающую за сканирование. Проще разорвать цепь питания.

Стоп, что? Зачем лезть в цепь питания сканера? Какую бизнес задачу мы решаем?

Сейчас расскажем.

Представьте себе процесс инвентаризации. Кладовщик берет палету какого-нибудь разнородного товара и быстро-быстро его пропикивает. В идеальном мире все штрихкоды считались верно и, самое главное, про все мы знаем.

По факту обязательно попадется штрихкод, неизвестный системе. Как быть в этом случае?

Человек бешено сканирует, он устал и давно не смотрит на мониторчик ТСД.

Все звуки на терминале выключены еще в прошлом году, ибо от его веселого пика можно с ума сойти. Ну или дело происходит в каком-нибудь книжном магазине и кладовщик не хочет нервировать покупателей.

Надо как-то привлечь внимание нашего уставшего человека к мониторчику? Он ведь может не заметить предупреждения и продолжит пикать. И неизвестный товар потеряется. А вот если кладовщик увидит проблему, то сможет как-то ее решить: сфотографировать этикетку, ввести номенклатуру вручную, словом что-то да предпримет. 

Выход только один блокировать сканер. Если луч не загорается кладовщик будет вынужден разбираться что пошло не так, посмотрит на мониторчик, увидит информационное сообщение, предпримет меры.

Кстати, этот, казалось бы, простой и логичный шаг принудительно «гасить» луч сканера до тех пор, пока человек не отреагирует на сообщение системы оказался настолько уникальным и важным для отрасли, что компания «Клеверенс» получила на него официальный патент на изобретение (№ 2847180). Суть нашего запатентованного метода в следующем: если учетная система не готова принять следующий штрихкод (например, ждет, пока кладовщик введет недостающие данные через экран ТСД, подтвердит ошибку или отсканирует нужную пломбу), она блокирует сканер программно или отключая его питание. Сканировать «в пустоту» больше не получится. Это на 100% страхует бизнес от потери данных и заставляет сотрудника перевести взгляд в приложение на ТСД.

Далеко не все клиенты с таким сталкиваются и некоторым кажется, что Клеверенс перемудрил. Но только тем, у кого небольшой поток товара. Компании с огромными складами и миллионами товарных позиций знают, что сканер надо уметь выключать автоматически. И что бизнес-процессы могут быть в разы сложнее, чем описано выше. 

Приведем несколько примеров.

Завод «Марс»

Очень упрощая, технологический процесс построен следующим образом: 

  • Кладовщик пикает батончики и складывает их в мешок. По достижению определенного количества батончиков процесс останавливается. 

  • Теперь надо опломбировать мешок и отсканировать пломбу. 

  • После пломбировки мешка его надо положить на полку и отсканировать данные уже полки.

  • И только после этого можно начать наполнять новый мешок.

Как видите, если ТСД не будет вмешиваться в работу кладовщика, то в разных мешках может оказаться разное число батончиков, а какой-то из мешков просто забудут закинуть на полку. Закинут позже, а куда черт его знает. В данном случае терминал буквально помогает не допускать ошибок, он останавливает работу по сканированию батончиков, когда их число достигло определенного количества. И теперь уже не примет никакой другой штрих-код, кроме как штрих-код пломбы мешка, а потом полки.

На том заводе еще были качественные ТСД Intermec, с ними не возникло особых проблем и их получилось глубоко интегрировать.   

Компания Symbol/Zebra

А потом в страну приехала компания Symbol/Zebra и началась битва дистров со скидками аж до 70 процентов на ТСД. Это вызвало кучу проблем.

Представьте. Завод по производству нетканых материалов. Приходит паллета с товаром. Ее надо разобрать и убедиться, что весь товар на паллете это одна номенклатура. Если в паллете встречается другая номенклатура (а такое бывает), ее надо отложить в сторону для дальнейшей сортировки.

На тот момент интеграция с Symbol была на уровне клавиатуры. Чтобы отличать сканирование от ручного ввода, мы использовали замер таймаутов между символами. Но процесс был жестко завязан на ERP-систему SAP: нужно было проверять состав палеты, и если попадалось чужое сырье вызывать ошибку, автоматически создавать в SAP новую субпартию и требовать от кладовщика переложить товар.

И, конечно, начались проблемы. Терминал дико ругался, видя «левую» номенклатуру, но кладовщик не смотрел на экранчик и продолжал пикать. В конце работы часть товара уходила не туда. Вибрация и звуки не помогли — на шумном производстве их игнорируют. В итоге нам пришлось вытаскивать низкоуровневое C-API от Symbol, заворачивать его под .NET для Windows Mobile и чинить бесконечные краши прошивки, чтобы научить систему принудительно гасить лазер при ошибке валидации в SAP.

ТСД DataLogic

Но это еще цветочки по сравнению с тем, как пришлось колдовать с ТСД DataLogic. Его проблемой было то, что при программной остановке сканера через штатные библиотеки, ему требовалось около двух секунд только на выключение. И потом еще больше на запуск. А главное ровно через 200 таких циклов «вкл/выкл» штатная библиотека намертво вешала всю операционную систему ТСД. Помогала только полная перезагрузка с извлечением батареи.

Осложняло историю то, что подобные сканеры использовались на агропредприятии, на линии упаковки кур. Все выглядело следующим образом:

  • По конвейеру идут тушки куриц.

  • Упаковщик сканирует каждую и складывает в коробку. По ТЗ пропускная способность системы должна была быть две курицы в секунду.

  • После того, как коробка заполнена, система останавливает процесс сканирования куриц, печатается этикетка на коробку с номером партии, датой и фамилией упаковщика. Коробка запечатывается, спикивается и отправляется дальше по процессу. А упаковщик начинает заполнять новую коробку. 

Задача примерно такая же, как и в первом примере. По заполнению мешка/коробки не давать сканировать товар, а требовать штрих-код упаковки.

Еще раз вспомним: мы сканируем две курицы в секунду, это бешеный ритм. А остановка/пуск сканера занимают несколько секунд и это еще если не придется перегружать весь ТСД. В такой ситуации, ТСД солидно тормозит конвейер.

Эту проблему удалось решить, обойдя бажную библиотеку производителя. Наши программисты нашли способ подавать команду обесточивания прямо на аппаратный порт терминала, к которому физически подключен считыватель. В этом случае сканер отключался за миллисекунды, не выгружая библиотеки в память, и ТСД таки смог уложиться в бешеный ритм конвейера. Но попотеть пришлось изрядно.

Клиенты и производители сканеров часто предъявляют нам претензии за то, что ТСД не всегда работают так, как требуется. Вроде на демо производителя терминал прекрасно себя показывает, а в реальных условиях нещадно тупит. Клеверенс, в чем дело? Это же ваш софт виноват, да???

Мы стараемся доносить суть проблемы. На демо-приложениях вендоров сканер работает в статическом режиме под него зашит один простой шаблон, и он «молотит» штрихкоды без остановок. В реальных же бизнес-процессах нашему софту приходится управлять сканером динамически и асинхронно: через каждые 30 миллисекунд менять профили, отключать одни кодировки и включать другие, параллельно опрашивая учетную систему. Демо-версии просто не рассчитаны на такую логику, поэтому вся их магия сыплется в реальных условиях. Потому все ТСД у нас могут быть интегрированы в одном из трех вариантов: 

  1. Дикая. Она практически ничего не делает со сканером. Если уж он назвался клавиатурой будет клавиатурой.

  2. Базовая. Тут мы уже управляем питанием и делаем еще несколько служебных вещей.

  3. Полная (глубокая). Тут мы хорошо так залазим в сканер и его функционал, получаем от него любые спецсимволы или даже фото.

Главная правда тут в том, что степень интеграции мало зависит от денег клиента или нашего желания. Она почти целиком зависит от аппаратного исполнения сканера. 

Если он позволяет залезть к себе достаточно глубоко, то и интеграцию получит глубокую. Если же он клавиатура, то что можно ждать от клавиатуры? Получит дикую.

Это часто вызывает непонимание клиентов. Мол а чего нам дикую интеграцию, давайте глубокую! Хотим чтобы прям все и по высшему уровню. А мы бы и рады, да доступное SDK сканера этого не позволяет. Приходится объяснять.

Еще одна очень интересная тема связана с одновременным чтением нескольких штрих-кодов. Есть этикетки, где могут быть расположены 2D-штрих-коды и, например, линейные. Производители хвалятся смотрите, наш ТСД умеет считывать все и одновременно! И показывают правда умеет. 

Только правда в том, что успешная считка происходит на какой-то одной этикетке, под которую сделан специальный шаблон для сканирования. Будет другая этикетка, где все расположено чуть-чуть иначе и шаблон придется переделывать. Вариантов таких этикеток тысячи. И пока под каждую не будет шаблона оно нормально работать не будет. На складе какого-нибудь оптовика обязательно найдется этикетка с двойным-тройным штрих-кодом под которую шаблона еще нет. 

Нам видится, что единственным правильным вариантом здесь станет блок сканера на определенные виды кодов. Скажем, мы читаем 2D-код и сканер как бы не видит все остальные. Он видит только 2D. Считали 2D, переключаемся на линейный. И так далее. Но в этой реализации мы вновь упираемся в программные блокировки сканера. По идее они должны занимать миллисекунды. Сколько они займут в реальности никто не знает.

А ещё, в продолжение этого же кейса много мелких упаковок с индивидуальными или разноформатными штрихкодами могут располагаться очень плотно друг к другу. Тут приходится решать задачу софтом: сканер может считать сразу несколько кодов, в этом случае мы можем просто вычленить нужный ШК. Прикол тут в том, что без правильной интеграции сканер читает какой-то один код, какой ему «по кайфу», а остальные кладовщику приходится закрывать пальцами.

Как пример табачная маркировка или любые другие товары с кодами DataMatrix. На этикетке могут быть одновременно расположены и 2D-код, и обычные линейные штрихкоды. Чтобы система не путалась, идеальный сценарий такой: программно отключить все кодировки, кроме 2D (DataMatrix). Кладовщик считывает марку она мгновенно распознается, потому что сканер не отвлекается на линейные коды. Как только марка считана, мы тут же программно запрещаем 2D и включаем чтение линейных кодов для следующего шага. Звучит круто, но беда в том, что включение/выключение поддержки конкретных символик на лету занимает у многих ТСД чудовищные секунды времени, а то и вешает сканер. Вот тут и приходится лезть в мозги железа и пытаться как-то изголяться, чтобы это работало мгновенно. 

Конечно, всегда найдется клиент, который скажет: «что-то вы там перемудрили». Им не нужны двойные считывания, у них нет сложной маркировки или владельцам не интересен комфорт сотрудников. Но для нас это не повод махать на все рукой.

На практике ТСД живут на складах по 10 лет, перепродаются на Авито, и в итоге у клиента образуется огромный «зоопарк» из железа разных эпох. Производителю всё равно, как его старый сканер будет работать сегодня. А мы в Клеверенс берем на себя ответственность за то, чтобы даже этот старый «зоопарк» стабильно тянул ваши сложные процессы. Приходя к нам, вы получаете работающий склад. Даже если ваш сканер искренне думает, что он — клавиатура.

Конечно же, относительно «зоопарков» ТСД наших пользователей у нас ещё есть много чего рассказать о нативном клиенте Mobile SMARTS и оптимизации конфигураций мобильных приложений, но об этом чуть позднее…

ссылка на оригинал статьи https://habr.com/ru/articles/1067326/