Работа с промышленными сканерами штрихкодов Symbol из 1С по протоколу SNAPI через Zebra Scanner SDK

0. 403 25.10.16 18:03 Сейчас в теме
Промышленные сканеры Symbol - штука недешевая. Зато имеют надежное исполнение, абсолютно всеядные и универсальные, беспроводные, а самое интересное - имеют расширенные возможности управления через собственный протокол SNAPI (ну, есть и попроще у них сканеры, но я про самые вкусные - беспроводные и со SNAPI). Эти возможности позволяют реализовать эффективные сценарии работы.
Одна проблема - нигде не смог найти примеры для работы из 1С по этому протоколу. Все стандартные протоколы поддерживаются, но ведь смак именно в расширенных возможностях!
Поэтому пришлось копаться самому...

Перейти к публикации

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. pethouseua 22.02.19 12:32 Сейчас в теме
А сталкивались ли Вы с задачей работы со сканером по протоколу SNAPI в терминале? Как модно "пробросить" сканер в терминал?
2. herfis 403 22.02.19 12:45 Сейчас в теме
(1) Не сталкивался. Админы поделились сакральным знанием о том, что требуемой стабильности работы при работе через терминал им добиться не удалось (периодически были какие-то проблемы), поэтому этот вариант при мне уже не рассматривался.
Сейчас поглядываем в сторону перехода на андроидные терминалы с мобильным клиентом 1С на них (покрыв всю складскую зону вайфаем). Но сам пока еще ничего не щупал.
pethouseua; +1 Ответить
3. bcosta 16.09.19 14:05 Сейчас в теме
Здравствуйте!
Не передать команду воспроизведения сигнала на сканер. Делал сначала по примеру Вашего кода в статье. Заставил сканер сканировать штрихкод, с этим все просто. По аналогии и с использованием документации Zebra Scanner SDK добавил команду SET_ACTION. Но сканер молчит. В итоге скачал Вашу обработку, но Ваш код абсолютно идентичен и тоже не работает. Через приложение SDK - C++ Sample App сканер издает звук, а через 1С - нет. Сканер Zebra DS2278. Так же пытался передать прочие команды на сканер. Заработала только команда перезагрузки сканера REBOOT_SCANNER. Остальные, которые пытался, не работают. Нужен только сигнал, остальные команды не нужны. Можете что-нибудь подсказать?
4. herfis 403 16.09.19 15:00 Сейчас в теме
(3) В новых редакциях сканера сканер и база определяются как разные устройства (а может и раньше так было, не суть). Если берется просто первое устройство из списка (как в обработке), то это скорее всего база. Но если раньше можно было посылать сигнал на базу и это успешно работало (сканер пикал), то в новых редакциях сканера (той же модели) "пикнуть" сканером (а также выполнить некоторые другие команды) стало возможно только послав сигнал именно на устройство сканера (как правило, это второе устройство в списке устройств).
Сам не ожидал такого нарушения обратной совместимости для серьезного промышленного производителя. Хотя причины, в принципе, понятны. Но тем не менее. Просто теперь нужно сканер и базу получать через API как отдельные устройства и посылать им команды раздельно.
Возможно, позже допилю обработку под этот новый ньюанс.
ЗЫ. Пока что внес дополнение в статью. Спасибо за замечание.
6. bcosta 17.09.19 10:54 Сейчас в теме
(4) Спасибо. Так получилось. Получается сканирование штрихкода идет через базу, а сигнал через сканер?
7. herfis 403 17.09.19 11:54 Сейчас в теме
(6) У меня так. Через сканер получать сканирование даже не пробовал.
5. herfis 403 16.09.19 15:08 Сейчас в теме
Кстати, эксперимент с андроидными ТСД завершился успешно (тоже Zebra). Удалось организовать аналогичный по обратной связи сценарий через мобильный клиент 1С. С помощью ВК от IgorKissil, честь ему и хвала.
8. user1311287 09.12.20 17:40 Сейчас в теме
Здравствуйте!
Подключился к сканеру, удалось выполнить команду издания сигнала. Не удается подключить обработчик события, при вызове метода регистрации обработчика ошибок нет, успешно отрабатывает, возвращает 0. Но при попытке сканирования штрихкод не обрабатывается пробовал и на клиенте и на сервере, (во внешней обработке), в чем может быть проблема?
9. user1311287 09.12.20 18:19 Сейчас в теме
(8) т.е событие обработчика не вызывается
13. herfis 403 16.12.20 15:56 Сейчас в теме
(9) Прошу прощения. Ввел в заблуждение. Логический номер сканера/базы нужно указывать не в Open/Close, а при посылке команды на сканер в параметре ScannerID. Ниже в комментариях будет подробнее.
10. herfis 403 10.12.20 13:37 Сейчас в теме
(8) Проблема может быть в том, что при обновлении некоторых моделей (для тех же самых моделей!) производитель изменил логику работы. В них с базой и со сканером нужно работать как с разными логическими устройствами. В примере и в обработке идет работа с логическим устройством номер 0. У вас может оказаться так, что 0 - это база, а сканер имеет номер 1. Соответственно нужно в вызовах методов компоненты Open и Close изменить 0 на 1 в параметрах вызова. А при необходимости мигать и "бипать" именно базой - подключаться к ней отдельно как к логическому устройству с номером 0.
11. GrRusel 15.12.20 13:16 Сейчас в теме
День добрый.
Скачал обработку. Пытаюсь отправить на сканер Beep, но выдаёт ошибку:
Error beeping: 112 ERROR_DEVICE_UNAVAILABLE
Сканер Zebra DS2278
Нужно что бы пикал именно сканер, а не база.

Попробовал через SDK - C# Sample App и вот лог:
1. CLOSE - Command success.
2. OPEN - Command success.
3. REGISTER_FOR_EVENTS - Command success.
4. GET_SCANNERS - Command success.
5. GET_PAIRING_BARCODE - Command failed. Error:118
6. SET_ACTION - Command failed. Error:116

6 пункт это соотв посылаю Beep
12. GrRusel 15.12.20 13:54 Сейчас в теме
Продолжение

НО! Если сначала запускаю 123Scan, потом SDK - C# Sample App, то санер определяется не как HIDkeybord, а как два устройства SNAPI и при посылке Beep на 3 устройство всё бикает как надо

Подскажите как быть, а вернее заставить пиликать в 1С?

Всё разобрался. При переключении всего и вся в SNAPI - всё заработало. Кстати сам сканер имеет ID = 3. В наличии пять комплектов - у кого ID = 3 у кого ID = 2. Жесть.

P.S. Правда в таком режиме не работает NativeApi в 1С, со всеми вытекающими. Получается надо переписывать обработку события в 1С или может есть способ как малой кровью сделать так что бы и стандартный NativeApi работал и SNAPI?
14. herfis 403 16.12.20 16:12 Сейчас в теме
(12) Логический номер базы/сканера указывается в параметре scannerID при посылке команды (в xml с параметрами команды, который передается вторым параметром методу ExecCommand). В обработке логические номера захардкожены, так как в старых партиях DS2278 (желтого цвета) которые использовались у нас с этим никогда проблем не возникало. А вот с появлением новых партий (черных с зелеными вставками) тоже началась чехарда с логическими номерами. И если они не совпадают с захардкоженными в обработке, то она не будет работать так как надо. Нужно изменить их на те, что у вас в реальности.
В продакшене для автоматического определения номера сканера я использовал такую затычку:
// уточнение ID устройства
ПараметрыПодключения.Вставить("ИДУстройства", 1);
Статус = -1; КоличествоСканеров = 0; Ответ = ""; 
СписокID = new COMSafeArray("VT_I4", 255);
ОбъектДрайвера.GetScanners(КоличествоСканеров, СписокID, Ответ, Статус);
Если Статус = 0 Тогда
	НачалоПодстрокиID = Найти(Ответ, "<scannerID>");
	Пока НачалоПодстрокиID > 0 Цикл
		Ответ = Сред(Ответ, НачалоПодстрокиID + 11);
		НачалоПодстрокиМодели = Найти(Ответ, "<modelnumber>");
		Если НачалоПодстрокиМодели > 0 Тогда
			Если Сред(Ответ, НачалоПодстрокиМодели + 13, 2) = "DS" Тогда // нашли именно сканер, а не базу
				КонецПодстрокиID = Найти(Ответ, "</scannerID>");
				ПараметрыПодключения.Вставить("ИДУстройства", Число(Сред(Ответ, 1, КонецПодстрокиID - 1)));
				Прервать;
			КонецЕсли;
		КонецЕсли;
		НачалоПодстрокиID = Найти(Ответ, "<scannerID>");
	КонецЦикла;
КонецЕсли;
Показать

ЗЫ. Если у вас типовая с БПО, то обработку события переписывать не нужно. Просто реализовать в рамках идеологии БПО работу со сканером в режиме SNAPI как работу с отдельным устройством (реализовать соответствующие обертки команд). В итоге при подключении сканера к рабочему месту будет просто выбираться не стандартный драйвер сканера, а какой-нибудь "Сканер SNAPI".
15. GrRusel 16.12.20 18:05 Сейчас в теме
(14) Да уже всё сделал, но всё равно спасибо за ответ :) Ещё сделал проверку, что сканер должен быть в режиме SNAPI:

	CoreScanner.ExecCommand(ScannerCommands["GET_DEVICE_TOPOLOGY"],"<inArgs><scannerID>1</scannerID></inArgs>", Response, Status);
	ScannerTypeStart = StrFind(Response, "SNAPI");
	
	Если ScannerTypeStart = 0 Тогда
		Возврат;
	КонецЕсли;


Там же и номер сканера вытаскиваю.

Если у вас типовая с БПО, то обработку события переписывать не нужно.

Конфа типовая, но сииильно переписанная. В итоге подключается и стандартный драйвер и SNAPI одновременно. Если наш сканер в режиме SNAPI, то типовой драйвер не обрабатывает событие и соотв. наоборот.
16. herfis 403 16.12.20 18:18 Сейчас в теме
(15) О, спасибо. Может, кому пригодится. У нас только в SNAPI и работают, так как блокировка сканировки и обратная связь на сканер - обязательные требования.
Если наш сканер в режиме SNAPI, то типовой драйвер не обрабатывает событие и соотв. наоборот.

Логично. Типовой драйвер в SNAPI не умеет, а через дрова производителя меня интересовал только SNAPI. Но если раскопать, то по-идее можно и другие режимы подтянуть.
17. GrRusel 17.12.20 10:44 Сейчас в теме
(16) Остался один момент, который мне ооочень не нравится
При сканировании мы получаем значение ШК вытаскивая его из <datalabel> с помощью:
StrReplace(StrReplace(DataLabel, "0x3", ""), " ", "")

А если в ШК будут нечитаемые спец символы - таких не мало может быть в коде, а про 2D я вообще молчу особенно всякие ЕГАИСы маркировки шин лекарств и т.д. в которых идёт крипто-хвост в коде. Ну в общем как-то меня это напрягает. С простыми ШК всё ок, а вот со сложными могут быть нюансы.
18. herfis 403 17.12.20 12:32 Сейчас в теме
(17) Да, это простейший "костыль" для исключительно цифровых штрихкодов. Для более сложных штрихкодов потребуется более интеллектуальная обработка.
Но там относительно просто. <datalabel> содержит коды символов штрихкода через пробел с префиксом "0x". То есть если просто разбить эту строку по пробелам, убрать в каждом слове "0x" и преобразовать к числу - то получим честный массив кодов штрихкода, включая спец-символы и прочее.
ЗЫ. И еще ньюанс. Раз цифры начинаются с 0x30 - то выходит что коды символов там в шестнадцатеричке. Т.е. перед преобразованием к числу нужно будет еще в десятичку перевести.
19. GrRusel 17.12.20 13:17 Сейчас в теме
(18) Вот тут я не очень понял :(
Вот есть у нас простейший ШК: 00346200942800000019
Получили datalabel: <datalabel>0x30 0x30 0x33 0x34 0x36 0x32 0x30 0x30 0x39 0x34 0x32 0x38 0x30 0x30 0x30 0x30 0x30 0x30 0x31 0x39</datalabel>
содержит коды символов штрихкода через пробел с префиксом "0x"

30 30 33 34 36 32 30 30 39 34 32 38 30 30 30 30 30 30 31 39
И? а дальше что? Не пойму :( что к числу преобразовывать?
20. herfis 403 17.12.20 13:58 Сейчас в теме
(19) 30 30 33 34 36 32 30 30 39 34 32 38 30 30 30 30 30 30 31 39 - это шестнадцатиричные коды символов штрихкода со сканера.
В десятичке это 48 48 51 52 и т.д.
Просто в ASCII коды символов цифр 0,1,2,3 и т.д. начинаются с 48 (шестнадцатеричной 30). И поэтому достаточно вычесть 48 из кода символа, чтобы получить нужную цифру (ну или просто отбросить троечку в шестнадцатеричке, как сделано в обработке). Но универсальным способом для любых символов будет банальное одинэсное Символ(КодСимвола). А если тебе нужно работать с криптохвостом не на уровне символов, а на уровне их кодов - то вот они сразу и есть.
21. GrRusel 17.12.20 15:06 Сейчас в теме
(20) А ну вот теперь всё понятно :)
22. user1311287 18.12.20 12:12 Сейчас в теме
(10)
Спасибо, что откликнулись! Подписываюсь на события следующим образом
//1001 - REGISTER_FOR_EVENTS
CoreScanner.ExecCommand(1001,
	StrTemplate("<inArgs><scannerID>1</scannerID><cmdArgs><arg-int>%1</arg-int><arg-int>%2</arg-int></cmdArgs></inArgs>",
	6, // number of events
	"1,2,4,8,16,32"),
	Response, Status);

Пробовал и с id и без id, и id обеих устройств подряд. id брал из результата процедуры GetScanners.
Метод во всех случаях отрабатывает, возвращает Status 0, только при сканировании 1с ни холодно ни жарко.
Проблема, предполагаю, где-то в обратной связи 1с с com объектом, хотя, при добавлении обработчика (AddHandler) в 1с, ругается, если в процедуре-обработчике параметров меньше чем указано в документации, т.е "событие" он видит. Процедуру обработчик объявлял и на клиенте и на сервере и с клиента на сервере.
Смотрю исходники Sampleapp.cpp, идут в комплекте с SDK, примерно тоже самое написано, только у них все работает, в режиме snapi штрихкод успешно выводится на экран.
пробовал и на другом пк с такой же win7 x64, база файловая, 1с 8.3.15. Сканер DS2278. Вашу обработку правда не использовал, но думаю вряд ли картина будет отличаться.
Была 1 попытка использовать метод из статьи https://infostart.ru/1c/articles/714025/, через эмулятор ничего не вышло
Ищу дальше..
23. herfis 403 18.12.20 16:21 Сейчас в теме
(22) Даже не знаю, что сказать.
В статье подключение к сканеру, регистрации события и подключение обработчика описаны без купюр(все это нужно делать конечно же на клиенте, включая обработчик). В обработке тоже самое. Поэтому если не работает, то обработку скачивать смысла нет.
На всякий случай акцентирую (хотя это вроде очевидно): ссылка на компоненту должна оставаться "живой" после подключения и регистрации. Или событие ловить будет просто некому. То есть должна быть либо клиентской переменной модуля формы (как в обработке)
&AtClient
var CoreScanner

Либо "жить" в экспортных переменных модуля управляемого приложения (как в БПО)
24. user1311287 22.12.20 08:48 Сейчас в теме
(23) Сейчас понял какой я болван. Действительно абсолютно очевидная вещь, но, видимо в силу отсутствия опыта работы с событиями из внешних компонент даже в голову не пришло ничего подобное. Наверное акцент на объявление переменной нужно сделать в статье, вдруг найдется второй такой же ... вроде меня. Спасибо огромное!
25. G_114492037554344237850 14.02.21 17:04 Сейчас в теме
Если пользователь долго работает со сканером и не трогает клаву/мышь, то ПК уходит в сон, потому что включён zebra snapi. Кто-нибудь нашёл какое-нибудь элегантное решение этой проблемы?
Оставьте свое сообщение
Вопросы с вознаграждением