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

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

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

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. pethouseua 22.02.19 12:32 Сейчас в теме
А сталкивались ли Вы с задачей работы со сканером по протоколу SNAPI в терминале? Как модно "пробросить" сканер в терминал?
2. herfis 452 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 452 16.09.19 15:00 Сейчас в теме
(3) В новых редакциях сканера сканер и база определяются как разные устройства (а может и раньше так было, не суть). Если берется просто первое устройство из списка (как в обработке), то это скорее всего база. Но если раньше можно было посылать сигнал на базу и это успешно работало (сканер пикал), то в новых редакциях сканера (той же модели) "пикнуть" сканером (а также выполнить некоторые другие команды) стало возможно только послав сигнал именно на устройство сканера (как правило, это второе устройство в списке устройств).
Сам не ожидал такого нарушения обратной совместимости для серьезного промышленного производителя. Хотя причины, в принципе, понятны. Но тем не менее. Просто теперь нужно сканер и базу получать через API как отдельные устройства и посылать им команды раздельно.
Возможно, позже допилю обработку под этот новый ньюанс.
ЗЫ. Пока что внес дополнение в статью. Спасибо за замечание.
6. bcosta 17.09.19 10:54 Сейчас в теме
(4) Спасибо. Так получилось. Получается сканирование штрихкода идет через базу, а сигнал через сканер?
7. herfis 452 17.09.19 11:54 Сейчас в теме
(6) У меня так. Через сканер получать сканирование даже не пробовал.
5. herfis 452 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 452 16.12.20 15:56 Сейчас в теме
(9) Прошу прощения. Ввел в заблуждение. Логический номер сканера/базы нужно указывать не в Open/Close, а при посылке команды на сканер в параметре ScannerID. Ниже в комментариях будет подробнее.
10. herfis 452 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 452 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 452 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 452 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 452 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 452 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. Кто-нибудь нашёл какое-нибудь элегантное решение этой проблемы?
26. GrRusel 02.12.21 10:36 Сейчас в теме
День добрый, всем.
Подскажите плиз, кто нить пробовал перебросить SNAPI в RDP? В режиме USB-HID всё отлично работает в RDP? а вот SNAPI ни в какую не хочет. Драйвера ставил, но всё равно ничего не происходит. Поставил на сервер 123Scan и он тоже не видит сканер который в режиме SNAPI.
27. GrRusel 08.12.21 13:44 Сейчас в теме
Списался с ТП. Ответили что никак. Так как мне надо иметь возможность посылать на сканер различные команды, а именно что бы сканер пиликал как мне надо в нужный момент, то это можно сделать только в режиме SSI over USB CDC, но как теперь переписать всё это добро под этот режим - не понимаю.
Так как у зебры есть "готовый набор (внимание!) com-компонент и примеров кода, для работы с любыми их сканерами и по любым протоколам, в том числе и по протоколу SNAPI!" знчит можно и этот протокол прикрутить, но пока не получается. Может автор статьи поможет и подключиться к вопросу? :)
28. herfis 452 09.12.21 11:51 Сейчас в теме
(27)
Может автор статьи поможет и подключиться к вопросу? :)

Нет. Автор статьи не поможет. Все, что у меня было сказать по этому вопросу, я уже ответил в (2)
ЗЫ. И, кстати, переход на андроидные терминалы с мобильным клиентом 1С вполне себя оправдывает.
29. GrRusel 09.12.21 16:55 Сейчас в теме
(28)
И, кстати, переход на андроидные терминалы с мобильным клиентом 1С вполне себя оправдывает.

Не поверите, но именно этим сейчас и занялся - переводом на Urovo DT40 :) Хотя зебру тоже оставим :)
30. herfis 452 09.12.21 17:06 Сейчас в теме
(29) Ну почему не поверю. Вполне логичный путь. Переходили на терминалы Zebra с интегрированной пистолетной рукояткой. Один из критериев выбора был - громкий пьезодинамик, хорошо слышимый на шумном складе. Ну и проверенный производитель промышленного оборудования для не самых тепличных условий. Писали свои обработчики в рамках БПО. Но использовали ВК не из состава БПО. Использовались вот эти ВК от одного автора:
https://infostart.ru/public/779912/
https://infostart.ru/public/1043267/
Вот, пожалуй, и все, чем я готов помочь по этой теме.
Оставьте свое сообщение
Вакансии
Программист 1С
Екатеринбург
зарплата до 150 000 руб.
Полный день

Разработчик 1С
Санкт-Петербург
зарплата от 130 000 руб. до 170 000 руб.
Временный (на проект)

Программист, аналитик, эксперт 1С
Санкт-Петербург
По совместительству

Программист 1С
Рязань
зарплата от 150 000 руб. до 250 000 руб.
Полный день

Архитектор 1С
Обнинск
зарплата от 150 000 руб. до 350 000 руб.
Полный день