Столкнулся на днях с очень интересной задачей, на работе, мною же, внедрялась Система Быстрых Платежей по 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)


  1. Che603000
    22.12.2021 01:00
    +4

    Попробуйте расширение написать для хром. API для работы есть. https://web.dev/serial/


    1. Struam Автор
      22.12.2021 12:53

      В любом случае это решение даже если заработает, оно не будет кроссбраузерное...


  1. hecategram
    22.12.2021 01:24
    +3

    Давно лет так двенадцать отправлял смс через usb модем. Ставил на комп denwer. и уже в нем через php отправлял команды в порт.

    Ну а так зачем брать кота в мешке. Купить на али плату Wemos D1 и дисплей. Все быстро соединяется, пишется небольшая програмка и можно все через вай фай отправлять. Не каких проводов. По цене будет раза в два дешевле.


    1. lxsmkv
      22.12.2021 06:32

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


    1. kAIST
      23.12.2021 10:35

      А корпус? А если десяток таких штук надо сделать? Это же не для домашнего использования.


  1. Dreablin
    22.12.2021 02:37
    +5

    Мы решали подобну задачу через регистрацию своего URI в Windows (типа callto: или mailto:). Менеджер в Браузере нажимает на ссылку, система запускает программу на С++, которая принимает параметр из браузера и работает с COM портом соответствующтм образом.

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

    Могу в личку скинуть .reg файл для создания URI с параметром, если нужно.


    1. Skykharkov
      22.12.2021 05:52

      Это если локально и под Windows и если под Windows у юзера есть права записи в реестр. А если требуется весь "зоопарк" браузеров\операционок, тут уж без "локального\удаленного" микро-сервиса никак. Более универсально, даже на C# можно почти под все ОС и так далее.


    1. Struam Автор
      22.12.2021 12:29

      Про такую возможность не подумал... Спасибо за наводку


  1. Gengenid
    22.12.2021 06:05

    А просто планшет, который в полноэкранном режиме показывает страницу с QR кодом и сервер, который эту страницу отдает?

    Привязываться к таким сомнительным аппаратным решениям...


    1. Struam Автор
      22.12.2021 12:31

      А дисплей включается, показывает QR код и после чего его можно отключить, нет нужды постоянно включенным держать.


      1. Gengenid
        22.12.2021 14:55

        А зачем ему выключаться?


  1. lxsmkv
    22.12.2021 06:33

    Мне вспомнилось, есть ведь еще e-ink дисплеи. Что было бы, возможно, практичнее, потому что нет привязки к программно-аппаратной части. Накроется эта фирма делающая такие дисплеи и привет, а если у тебя софт на ардуинке (или т.п.), то оно никуда не денется. А корпус, да его один раз смоделировать и на 3д принтере распечатать/заказать, да еще и забрендировать можно. И стоит e-ink дисплей от 20 долларов. Контраста для считывания должно хватать в типовых условиях освещения.


    1. Struam Автор
      22.12.2021 12:32

      Это для больших решений, где не 3 - 5 дисплеев требуется, а иначе смысл заморачиваться со всей этой сборкой.


  1. esata
    22.12.2021 06:58
    +1

    Мне приходит на ум WebUSB, только на Windows перед этим скорее всего надо установить Zadig Libusbk драйвер чтобы с устройством можно было работать напрямую (только для Windows).

    Также можно подцепить к экрану Arduino c Bluetooth рисивером и управлять устройством в браузере с помощью WebBluetooth. Для этого драйверов ставить не нужно.


  1. jMas
    22.12.2021 07:29

    Тут говорят что можно писать через Serial API, но это делают через расширение для Chrome.


  1. AKudinov
    22.12.2021 07:42
    +6

    Занятно.
    Автору дали последовательный порт, дали протокол к нему (не очень сложный).
    И... автор недоволен, ругается, требует ещё какой-то "API или приложение для интеграции" и обзывает "полурабочим девайсом, вокруг которого нужны еще танцы с бубном чтобы он заработал".
    Я ни разу не представитель производителя экрана, но... искренне не понимаю (мягко говоря) причину такой негативной реакции автора. Тем более, ему никто и не обещал сопряжения устройства с браузером. А устройтство, управляющееся через последовательный порт -- просто мечта, мне кажется. К нему не нужно какой-то специфический драйвер ставить, у которого свой программный интерфейс, который только со своей библиотекой работает, и т.д. и т.п.
    Если уж так плохо, можно под специфическую задачу сопряжения устройства с браузером свою небольшую программку написать, которая открывает сокет на localhost, и транслирует данные из него в последовательный порт.


    1. hellamps
      22.12.2021 08:01

      ну почти мечта... этот виртуальный компорт небось будет прыгать с номерами порта...


      1. AKudinov
        22.12.2021 08:05
        +1

        Пока ни разу не замечал, чтобы номер порта менялся спонтанно. Т.е. если одно и то же устройство подключать к одному и тому же порту USB, то номер порта стабильно один и тот же.

        В принципе, если напрячься, можно сделать поиск устройства по VID/PID/SN, и находить соответствующий ему номер порта, но это уже перебор, на мой взгляд.


        1. VelocidadAbsurda
          22.12.2021 12:24

          Смотря на чём писать. В питоновской библиотеке serial получение VID/PID есть "из коробки", постоянно так и делаю, не задумываясь о номерах портов вообще. Пример:

          import serial
          ports = serial.tools.list_ports.comports()
          print(ports[0].vid, ports[0].pid)


          1. AKudinov
            22.12.2021 12:49

            Хм, интересно. Я "автоматически" мыслю в категориях C++/Win32 API.
            А что будет, если питоновская библиотека встретит честный железный последовательный порт? Какие VID/PID она покажет?


            1. VelocidadAbsurda
              22.12.2021 14:14

              Тоже интересно стало, но ни на одном из имеющихся PC железных портов не нашлось. Но у объектов портов кроме числовых vid, pid есть атрибут hwid в виде строки более вольного формата (пример для USB порта: USB VID:PID=1915:C00A SER=E67672362BEB LOCATION=1-5:1.1), возможно там будет что-то осмысленное.


    1. Struam Автор
      22.12.2021 12:37
      -2

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

      К тому же это мое личное мнение, что продавая девайс надо либо предупреждать о режимах работы данного устройства либо предоставлять готовое к работе устройство "из коробки"


      1. AKudinov
        22.12.2021 12:59
        +2

        Ещё недавно, покупая сотовый телефон, нужно было думать, для работы в сетях какого стандарта (GSM или CDMA) и частотного диапазона (а это и сейчас актуально) он предназначен. А когда покупаю монитор, я смотрю, какие интерфейсы на нём есть, и сравниваю с тем, что есть на видеокарте моего ПК.
        Фокус в том, что "готовое к работе устройство из коробки" в Вашем представлении -- одно, в представлении производителя экрана -- совсем другое. И мне кажется, производитель и помыслить не мог, что "выводить данные изнутри браузера" -- это вот прямо обязательная функция, без которой его устройство не может считаться полноценным.


      1. Punk_Joker
        22.12.2021 14:43

        О каких режимах стоило предупреждать? Подключаете к компу и спокойно с ним работаете, в чем проблема?


  1. vsb
    22.12.2021 08:19
    +3

    Поясните, почему вы пишете, что WebSerial не позволяет писать в последовательный порт. API вроде на месте.


    1. Struam Автор
      22.12.2021 12:40

      Не получилось отправлять данные в COM порт, может чего-то не хватило или версия не та, у меня Chrome Версия 96.0.4664.110, не завелось.


  1. NosovK
    22.12.2021 08:51
    +4

    По-моему вы плохо смотрели про web api для com порта. Мы ещё до карантина написали интеграцию с кассовым аппаратом через COM из браузера напрямую. И там спокойно работал двухсторонний обмен через com порт.


  1. DOTsDev
    22.12.2021 12:42
    +1

    Вот ведь как бывает. А я только вчера GSM модемный пул написал с REST API. Он правда под линукс, но зато на еpoll + FastAPI. В принципе если выкинуть модемную обертку, то получится асинхронный доступ к кучке USB - TTY устройств прямо из http клиента. Можно и под форточку переделать.


  1. balandinve
    22.12.2021 12:42

    Тоже делали аналогичным образом, только у нас касса была подключена к ПК.

    В той компании уже не работаю, но схема - работает.


  1. BruTO8000
    22.12.2021 12:43

    Как из браузера отправлять команды в COM порт?

    Так как мы в браузере и так работаем с JS, думаю несложно будет написать API на NodeJS, которое будет принимать HTTP запросы, и отправлять на COM порт.

    npm i serialport


    1. Struam Автор
      22.12.2021 12:46
      +1

      Только ведь NodeJS еще дополнительно дружить с windows надо, на каждой машине.


  1. ettychel
    22.12.2021 12:49

    Помню игрался с МК и пользовался espruino. Там прошивка на МК летела прям с WebIDE (страничка браузера по сути), возможно там вы сможете найти ответ на свой вопрос)


    1. ettychel
      22.12.2021 18:05
      +1

      @Struam собственно API так и называется WebSerial

      https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API

      https://caniuse.com/web-serial


  1. 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 "кричим" в браузер о стадии выполнения.

    Это то,что будет работать(и работает)во всез браузерах во всех ОСях.


    1. jMas
      22.12.2021 18:06

      Если ответить разрешающим заголовком, то CORS решаются достаточно тривиально.


      1. irbis_al
        22.12.2021 18:09

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


  1. AlexDevFx
    22.12.2021 15:52
    +2

    Странное впечатление от статьи. Я таки не понял, что хотел сказать автор. Он просит совета или рассказывает как написал интеграцию с COM портом, не приведя ни строчки кода?


  1. OkunevPY
    22.12.2021 21:11

    https://wicg.github.io/serial/#writable-attribute

    Давно уже есть спецификация на serial.

    Не понимаю в чём проблема найти


  1. 65536
    22.12.2021 23:43
    +1

    Проще купить самый дешевый телефон. Выключить отключение экрана. Открыть фулскрином специальную страницу в браузере и слать в неё по вебсокетам нужное содержимое. Нажали в црм сгенерить код - отобразился код. Покупатель оплатил, процессинг прошел, отобразилась зелёная галочка)


  1. soir
    23.12.2021 22:58

    Может быть можно как-нибудь "расшарить" девайс на USB порту в сеть и тогда слать в него команды с какого-нибудь сервера. Мы так билеты в киосках самообслуживания печатаем. Приложение в киоске работает в обычном браузере, а печать на принтер в киоске происходит с сервера в облаке. Правда у нас принтеры билетов с сетевым интерфейсом, а не с COM.


  1. diafour
    24.12.2021 01:27

    Есть ещё вариант, но древний, поэтому думаю, что вряд ли станете связываться.

    Была аналогичная задача общаться из браузера по ком порту, но вместо описания протокола был код на Дельфи. Самым простым оказалось сделать обёртку в виде ActiveX и через него получать данные от устройства в js.