Столкнулся на днях с очень интересной задачей, на работе, мною же, внедрялась Система Быстрых Платежей по QR коду.
Задача не сложная, у банков представлены достаточно удобные API для интеграций и собственно первый этап интеграции, с самописной CRM системой, работающей на web сервере – прошел гладко и быстро.
Работая в браузере можно было легко сформировать QR код и отправить его клиенту для последующей оплаты или показать в окошке на новой вкладке, как удобно…
Но как оказалось это не слишком удобно и есть специальные девайсы – дисплеи для вывода именно QR кода.
Собственно, не раздумывая был заказан один такой дисплей для интеграции в CRM и упрощения действий для менеджеров, ну и конечно же большего удобства клиентов.
Буквально через 3 дня курьер принес посылку с заказанным дисплеем (в интернете не так много контор которые предлагают подобное решение) и вот этот чудо девайс на рабочем столе.
Далее при распаковке посылки оказалось, что кроме самого дисплея и пупырки в которую он был упакован, больше ничего не было, от слова совсем, ни драйверов, ни инструкций, ничего, даже гарантийного талона, только талон на доставку…
После переписки с менеджерами, где был куплен сей девайс, на почту прилетело письмо с краткой инструкцией:
Нужный драйвер был найден на Github (STM32 Virtual COM Port Driver)
А дальше в папочке лежал текстовый файл с примером команд и программка (Terminal v1.9b by Bray) для проверки что сие чудо работает.
На законный вопрос о существовании какого-либо API или приложения для интеграции был следующий ответ:
Достаточно странный ответ для компании, которая продает не запчасти для последующего самостоятельного сбора, а готовый продукт, продает, по сути, полурабочий девайс, вокруг которого нужны еще танцы с бубном чтобы он заработал. Хотя еще более интересно посмотреть на «ПО которое будет работать с банками с внешним API» …
Но делать нечего, надо как-то интегрировать, что-то придумывать.
Набор команд у девайса не большой:
[Q]Вывод QR кода
[QL]Вывод QR кода с логотипом
[CQ]Стирание QR кода с экрана
[CQL]Стирание QR кода с экрана без стирания логотипа
[T1]Вывод текста в верхней зоне экрана над QR кодом
[T2]Вывод текста в нижней зоне экрана под QR кодом
[OFF]Выключение экрана
Поддерживает UTF-8, команда должна завершаться переводом строки.
После изучения списка команд, тестового формирования QR кода, начались поиски каких-либо решений на просторе интернета.
Основная сложность заключалась в том, что девайс подключен к компьютеру по USB, а менеджеры работают в CRM системе через браузер. И как организовать связь между ними сходу мыслей не было.
На хабре нашел статью про возможность подключения к COM порту у браузера Chrome, но в последствии оказалось, что там есть возможность только читать с COM порта, а тут задача именно отправлять команды.
В общем и целом, интеграция зашла в тупик, не понятно, что делать и с какой стороны подходить.
К счастью, в голове вовремя проскользнула мысль про XMLHttpRequest и кроссдоменную работу.
Быстро была сверстана страничка для теста, на компьютере включен XAMPP и простенький PHP код который должен был получать POST запрос с параметрами, после чего создавался текстовый файл и уже после этого PHP запускал BAT файл который посылал команду в COM порт.
На удивление все сработало, на дисплее появилось заветное сообщение!
На самом деле на этом можно было бы и остановиться, на каждой машине тихонечко поднять локальный сервер XAMPP, добавить в автозагрузку службы и в принципе все бы работало, но внутренняя тяга к максимальному удобству заставила подумать еще чуть-чуть и найти более красивое решение.
К сожалению, последний раз с программированием именно для windows я сталкивался больше 15 лет назад, поэтому пришлось читать и вспоминать самые азы, благо не все забыто и вспомнить получилось.
Приложение, выполняет те же функции, как и сервер XAMPP – просто слушает на локальном хосте 80 порт, создается небольшой сервер, но уже без всяких BAT файлов отправляет нужные команды в COM порт, дисплей работает…
Конечно, там еще есть очень много к чему приложить руки, но данное решение лично мне нравится гораздо больше, оно более лаконично.
Если вдруг кто-то знает еще варианты как решить проблему интеграции браузера и COM порта, напишите пожалуйста, буду благодарен.
Комментарии (41)
hecategram
22.12.2021 01:24+3Давно лет так двенадцать отправлял смс через usb модем. Ставил на комп denwer. и уже в нем через php отправлял команды в порт.
Ну а так зачем брать кота в мешке. Купить на али плату Wemos D1 и дисплей. Все быстро соединяется, пишется небольшая програмка и можно все через вай фай отправлять. Не каких проводов. По цене будет раза в два дешевле.
lxsmkv
22.12.2021 06:32Тоже слышал от наших админов наших историю, что во времена до повсеместногo мобильного интернета, для экстренной отсылки sms сообщений сотрудникам в интранете был веб интерфейс связаный скриптом с нетленной Нокией, которая физически лежала в серверной.
kAIST
23.12.2021 10:35А корпус? А если десяток таких штук надо сделать? Это же не для домашнего использования.
Dreablin
22.12.2021 02:37+5Мы решали подобну задачу через регистрацию своего URI в Windows (типа callto: или mailto:). Менеджер в Браузере нажимает на ссылку, система запускает программу на С++, которая принимает параметр из браузера и работает с COM портом соответствующтм образом.
Впринципе тоже нужно писать софт по Windows, но оно запускается каждый раз без необходимости слушать порт и висеть онлайн постоянно, что на Windows не всегда хорошо работает...
Могу в личку скинуть .reg файл для создания URI с параметром, если нужно.
Skykharkov
22.12.2021 05:52Это если локально и под Windows и если под Windows у юзера есть права записи в реестр. А если требуется весь "зоопарк" браузеров\операционок, тут уж без "локального\удаленного" микро-сервиса никак. Более универсально, даже на C# можно почти под все ОС и так далее.
Gengenid
22.12.2021 06:05А просто планшет, который в полноэкранном режиме показывает страницу с QR кодом и сервер, который эту страницу отдает?
Привязываться к таким сомнительным аппаратным решениям...
lxsmkv
22.12.2021 06:33Мне вспомнилось, есть ведь еще e-ink дисплеи. Что было бы, возможно, практичнее, потому что нет привязки к программно-аппаратной части. Накроется эта фирма делающая такие дисплеи и привет, а если у тебя софт на ардуинке (или т.п.), то оно никуда не денется. А корпус, да его один раз смоделировать и на 3д принтере распечатать/заказать, да еще и забрендировать можно. И стоит e-ink дисплей от 20 долларов. Контраста для считывания должно хватать в типовых условиях освещения.
Struam Автор
22.12.2021 12:32Это для больших решений, где не 3 - 5 дисплеев требуется, а иначе смысл заморачиваться со всей этой сборкой.
esata
22.12.2021 06:58+1Мне приходит на ум WebUSB, только на Windows перед этим скорее всего надо установить Zadig Libusbk драйвер чтобы с устройством можно было работать напрямую (только для Windows).
Также можно подцепить к экрану Arduino c Bluetooth рисивером и управлять устройством в браузере с помощью WebBluetooth. Для этого драйверов ставить не нужно.
jMas
22.12.2021 07:29Тут говорят что можно писать через Serial API, но это делают через расширение для Chrome.
AKudinov
22.12.2021 07:42+6Занятно.
Автору дали последовательный порт, дали протокол к нему (не очень сложный).
И... автор недоволен, ругается, требует ещё какой-то "API или приложение для интеграции" и обзывает "полурабочим девайсом, вокруг которого нужны еще танцы с бубном чтобы он заработал".
Я ни разу не представитель производителя экрана, но... искренне не понимаю (мягко говоря) причину такой негативной реакции автора. Тем более, ему никто и не обещал сопряжения устройства с браузером. А устройтство, управляющееся через последовательный порт -- просто мечта, мне кажется. К нему не нужно какой-то специфический драйвер ставить, у которого свой программный интерфейс, который только со своей библиотекой работает, и т.д. и т.п.
Если уж так плохо, можно под специфическую задачу сопряжения устройства с браузером свою небольшую программку написать, которая открывает сокет на localhost, и транслирует данные из него в последовательный порт.hellamps
22.12.2021 08:01ну почти мечта... этот виртуальный компорт небось будет прыгать с номерами порта...
AKudinov
22.12.2021 08:05+1Пока ни разу не замечал, чтобы номер порта менялся спонтанно. Т.е. если одно и то же устройство подключать к одному и тому же порту USB, то номер порта стабильно один и тот же.
В принципе, если напрячься, можно сделать поиск устройства по VID/PID/SN, и находить соответствующий ему номер порта, но это уже перебор, на мой взгляд.
VelocidadAbsurda
22.12.2021 12:24Смотря на чём писать. В питоновской библиотеке serial получение VID/PID есть "из коробки", постоянно так и делаю, не задумываясь о номерах портов вообще. Пример:
import serial ports = serial.tools.list_ports.comports() print(ports[0].vid, ports[0].pid)
AKudinov
22.12.2021 12:49Хм, интересно. Я "автоматически" мыслю в категориях C++/Win32 API.
А что будет, если питоновская библиотека встретит честный железный последовательный порт? Какие VID/PID она покажет?VelocidadAbsurda
22.12.2021 14:14Тоже интересно стало, но ни на одном из имеющихся PC железных портов не нашлось. Но у объектов портов кроме числовых vid, pid есть атрибут hwid в виде строки более вольного формата (пример для USB порта: USB VID:PID=1915:C00A SER=E67672362BEB LOCATION=1-5:1.1), возможно там будет что-то осмысленное.
Struam Автор
22.12.2021 12:37-2Вы когда покупаете телефон или монитор проводите еще специальные действия для того чтобы начать с ним работать, пишите софт или может ищите решения для того чтобы устройство запустилось, привлекаете специалистов для этого...
К тому же это мое личное мнение, что продавая девайс надо либо предупреждать о режимах работы данного устройства либо предоставлять готовое к работе устройство "из коробки"
AKudinov
22.12.2021 12:59+2Ещё недавно, покупая сотовый телефон, нужно было думать, для работы в сетях какого стандарта (GSM или CDMA) и частотного диапазона (а это и сейчас актуально) он предназначен. А когда покупаю монитор, я смотрю, какие интерфейсы на нём есть, и сравниваю с тем, что есть на видеокарте моего ПК.
Фокус в том, что "готовое к работе устройство из коробки" в Вашем представлении -- одно, в представлении производителя экрана -- совсем другое. И мне кажется, производитель и помыслить не мог, что "выводить данные изнутри браузера" -- это вот прямо обязательная функция, без которой его устройство не может считаться полноценным.
Punk_Joker
22.12.2021 14:43О каких режимах стоило предупреждать? Подключаете к компу и спокойно с ним работаете, в чем проблема?
NosovK
22.12.2021 08:51+4По-моему вы плохо смотрели про web api для com порта. Мы ещё до карантина написали интеграцию с кассовым аппаратом через COM из браузера напрямую. И там спокойно работал двухсторонний обмен через com порт.
DOTsDev
22.12.2021 12:42+1Вот ведь как бывает. А я только вчера GSM модемный пул написал с REST API. Он правда под линукс, но зато на еpoll + FastAPI. В принципе если выкинуть модемную обертку, то получится асинхронный доступ к кучке USB - TTY устройств прямо из http клиента. Можно и под форточку переделать.
balandinve
22.12.2021 12:42Тоже делали аналогичным образом, только у нас касса была подключена к ПК.
В той компании уже не работаю, но схема - работает.
BruTO8000
22.12.2021 12:43Как из браузера отправлять команды в COM порт?
Так как мы в браузере и так работаем с JS, думаю несложно будет написать API на NodeJS, которое будет принимать HTTP запросы, и отправлять на COM порт.
npm i serialport
Struam Автор
22.12.2021 12:46+1Только ведь NodeJS еще дополнительно дружить с windows надо, на каждой машине.
ettychel
22.12.2021 12:49Помню игрался с МК и пользовался espruino. Там прошивка на МК летела прям с WebIDE (страничка браузера по сути), возможно там вы сможете найти ответ на свой вопрос)
ettychel
22.12.2021 18:05+1@Struam собственно API так и называется WebSerial
https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API
irbis_al
22.12.2021 14:45Тут такие темы уже обсуждались...я там писал свое решение(работаем через браузер со всем POS оборудованием через rs-232 причем в соновном в линуксе...Надо сделать прогу которая запускается на компе и прослушивает WebSocket и перекидывает пакеты в драйвер нативный для данной ОСИ(У нас драйвере на java поэтому нет разницы) ...Почему имеенно websoket? Потому что вы можете обратится из него к localhost
В бразузере в JS
var socket = new WebSocket("ws://localhost:7081");
socket.send(Ваши команды и ваш пакет);Прога шлюз прослушивает порт websoket 7081 и выполняет задачу.
Если ваша система загружена c url типа mycrm.com,то к localhost проблемно обычным REST обратится из-за CORS ,Same Origin Policy...а WebSocketом можно ходить на любой URL...
Всё... когда мы получили уже задачу и данные от браузера,то нативными решениями или по низкоуровневому протоколу rs-232 (я его предпочитаю ибо ИС кроссплатформенная) либо используюя решение производителя(обычно оно только под винду по технологии ActiveX объекта) выполняем задачу и по websoket "кричим" в браузер о стадии выполнения.
Это то,что будет работать(и работает)во всез браузерах во всех ОСях.
AlexDevFx
22.12.2021 15:52+2Странное впечатление от статьи. Я таки не понял, что хотел сказать автор. Он просит совета или рассказывает как написал интеграцию с COM портом, не приведя ни строчки кода?
OkunevPY
22.12.2021 21:11https://wicg.github.io/serial/#writable-attribute
Давно уже есть спецификация на serial.
Не понимаю в чём проблема найти
65536
22.12.2021 23:43+1Проще купить самый дешевый телефон. Выключить отключение экрана. Открыть фулскрином специальную страницу в браузере и слать в неё по вебсокетам нужное содержимое. Нажали в црм сгенерить код - отобразился код. Покупатель оплатил, процессинг прошел, отобразилась зелёная галочка)
soir
23.12.2021 22:58Может быть можно как-нибудь "расшарить" девайс на USB порту в сеть и тогда слать в него команды с какого-нибудь сервера. Мы так билеты в киосках самообслуживания печатаем. Приложение в киоске работает в обычном браузере, а печать на принтер в киоске происходит с сервера в облаке. Правда у нас принтеры билетов с сетевым интерфейсом, а не с COM.
diafour
24.12.2021 01:27Есть ещё вариант, но древний, поэтому думаю, что вряд ли станете связываться.
Была аналогичная задача общаться из браузера по ком порту, но вместо описания протокола был код на Дельфи. Самым простым оказалось сделать обёртку в виде ActiveX и через него получать данные от устройства в js.
Che603000
Попробуйте расширение написать для хром. API для работы есть. https://web.dev/serial/
Struam Автор
В любом случае это решение даже если заработает, оно не будет кроссбраузерное...