Несколько касс на одном ТС ПИоТ: экземпляры, порты и API оркестратора

Одна касса на кассовом узле — простой случай, он закрывается обычной установкой. Когда касс несколько, появляется отдельный слой: для каждой создаётся свой экземпляр ТС ПИоТ со своим набором портов.

Настраивается это не мышкой, а запросами к оркестратору. Разберём порядок и особенность, которая для касс АТОЛ упрощает схему.

Условие, о котором нужно знать заранее

Все кассы должны быть оформлены на один ИНН. Это не рекомендация: при попытке зарегистрировать экземпляр для кассы с другим ИНН оркестратор вернёт ошибку 1026 «Обнаружено несколько ИНН».

Режим работы с несколькими кассами поддержан со стороны драйвера АТОЛ. У некоторых других вендоров поддержка на момент выхода инструкции ещё ожидалась.

Три порта на каждый экземпляр

У каждого экземпляра ТС ПИоТ есть идентификатор и три порта:

ПараметрЧто это
portПорт экземпляра, по которому с ним общается оркестратор
softPortПорт API проверки кодов — к нему обращается кассовая программа
dkktPortgRPC-порт драйвера, к которому подключается экземпляр

Если softPort при создании не передать, он приравнивается к нулю, и кассовая программа будет подключаться на порт по умолчанию — 51401.

Типовая раскладка выглядит так:

Свойства драйвера ККТ АТОЛ: раскрытый список COM-портов
Каждой кассе — свой канал связи. В свойствах драйвера видно, какие порты заняты
КассаidportsoftPortdkktPort
№1012824562150401514014043
№2012824562250402514024044
№3012824562350403514034045

Для второй и последующих касс port и softPort указывать обязательно — иначе они конфликтуют между собой.

Особенность АТОЛ: один сервис на все кассы

Здесь схема для АТОЛ заметно проще общей.

Несколько касс могут обслуживаться одним gRPC-сервисом на одном порту. Если сервис слушает, скажем, 4042, и через него доступны три кассы, то все три будут отображаться с одинаковым dkktPort = 4042.

Отдельный gRPC-порт под каждую кассу не нужен. Сервис возвращает массив касс, а оркестратор добавляет их все в общий список. Проверить, что получилось, можно запросом GET /api/v1/dkktList.

Параметр dkktPort при этом сохраняет смысл: он показывает, через какой экземпляр драйвера обслуживается конкретная касса.

Что должно быть готово

  • Один или несколько экземпляров драйвера запущены и принимают gRPC-подключения.
  • Для каждого экземпляра драйвера определён gRPC-порт. Если экземпляров несколько, их порты не должны пересекаться.
  • Оркестратор доступен по адресу http://127.0.0.1:51077.
  • Для каждого экземпляра ТС ПИоТ выбраны уникальные port и softPort.

Шаг 1. Создать экземпляр

curl --location --request POST 'http://127.0.0.1:51077/api/v1/tspiot' \
--header 'Content-Type: application/json' \
--data '{
  "id": "0128245622",
  "port": 50402,
  "softPort": 51402,
  "dkktPort": 4043
}'

В качестве id используется идентификатор создаваемого экземпляра — как правило, заводской номер кассы.

Успешный ответ — HTTP 201 с телом, где среди прочего возвращается serviceState. В рабочем состоянии там «Работает».

Шаг 2. Зарегистрировать экземпляр

Создание — это ещё не регистрация. Для каждой новой кассы после создания экземпляра выполняется отдельный запрос с её реквизитами:

curl --location --request PUT 'http://127.0.0.1:51077/api/v1/tspiot' \
--header 'Content-Type: application/json' \
--data '{
  "id": "0128245622",
  "kktSerial": "0128245622",
  "fnSerial": "9999000000001051",
  "kktInn": "9717169631"
}'

Ответ содержит tspiotId — идентификатор зарегистрированного экземпляра.

Шаг 3. Привязать локальный модуль

Настройка ЛМ ЧЗ относится к конкретному экземпляру и не заменяет параметр dkktPort. Первый указывает, через какой драйвер обслуживается касса, второй — через какой локальный модуль идут проверки.

curl --location --request PUT 'http://127.0.0.1:51077/api/v1/settings/lm/0128245622' \
--header 'Content-Type: application/json' \
--data '{
  "address": "127.0.0.1",
  "port": 5997,
  "login": "<логин ЛМ ЧЗ>",
  "password": "<пароль ЛМ ЧЗ>"
}'

Настройка применяется сразу, перезапускать экземпляр не нужно.

Два сценария на выбор. Рекомендуемый — свой локальный модуль на каждый экземпляр, с непересекающимися портами: 5996, 5997, 5998. Допустимый — один модуль на несколько экземпляров, но только если такая схема не приводит к конфликтам регистрации, лицензии и данных касс.

Обратите внимание: здесь указывается порт самого локального модуля, а не контроллера. Порт контроллера — 50063 — задаётся отдельно и меняться не должен. Путаница этих двух портов — самая частая ошибка настройки.

Шаг 4. Проверить результат

Список экземпляров:

curl --location 'http://127.0.0.1:51077/api/v1/instances/info'

Подробности по конкретному:

curl --location 'http://127.0.0.1:51077/api/v1/instances/info/0128245622'

В ответе смотрите clientPort — он должен совпадать с указанным softPort — и блок regData с реквизитами кассы.

Какой локальный модуль привязан:

curl --location 'http://127.0.0.1:51077/api/v1/settings/lm/0128245622'

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

Работоспособность самого контроллера проверяется запросом GET /api/v1/instances/lm/{id} — он возвращает версию, состояние и сведения об ОС, но не адрес подключения.

Как обращается кассовая программа

После создания и регистрации кассовая программа обращается к API проверки кодов по тому softPort, который был указан. Для второй кассы из примера адрес будет таким:

http://127.0.0.1:51402/api/v3/codes/check

То есть у каждой кассы свой адрес проверки. Это нужно прописать в настройках кассового ПО — в Frontol это поле «Порт ЕСМ», в — порт в настройках подключения к ТС ПИоТ.

Коды ошибок оркестратора

Ошибки приходят объектом с полями code, text и необязательным description. Ориентироваться следует на код, а не на текст сообщения.

КодHTTPЧто означает
1001400Некорректное тело запроса
1002400Некорректный параметр запроса
1009500Ошибка создания, удаления или изменения службы
1010400Служба с таким именем уже существует
1012400Служба с таким именем не создана
1013500Служба не была запущена
1015500, 204Не запущен агент-сервис драйвера
1022500Получена ошибка от сервиса ЕСМ
1023204Не найдено ни одной зарегистрированной службы
1026403Обнаружено несколько ИНН
1000500Неизвестная ошибка

Коды вида 20xx приходят из слоя работы с модулем, и текст у них начинается с префикса error — например, «error 2046: Служба ЕСМ либо не зарегистрирована, либо не запущена». Их разбор — в статье про ошибки ЕСМ.

Частые вопросы

Обязательно ли делать это через API? Для второй и последующих касс — да, отдельного интерфейса для этого нет.

Сколько касс можно подключить? Ограничение не в количестве, а в свободных портах и реквизитах: все кассы на один ИНН, лицензия на каждую отдельно.

Можно ли обойтись без отдельных экземпляров? Для АТОЛ упрощается только часть с драйвером: один gRPC-сервис на все кассы. Экземпляр ТС ПИоТ на каждую кассу нужен всё равно.

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

Как подключить несколько касс к одному компьютеру физически? Физическое подключение — отдельная тема: каждой кассе нужен свой канал связи и свой COM-порт. Схема с терминальным сервером разобрана в статье про работу по RDP.

Коротко

Каждой кассе — свой экземпляр ТС ПИоТ с уникальными port и softPort. Создаётся POST-запросом к оркестратору на 127.0.0.1:51077, регистрируется PUT-запросом с реквизитами кассы, локальный модуль привязывается отдельным запросом. Для АТОЛ есть послабление: все кассы могут обслуживаться одним gRPC-сервисом драйвера на общем порту. Жёсткое условие — все кассы на один ИНН, иначе ошибка 1026. Кассовая программа обращается к каждой кассе по её собственному softPort.


Материал носит информационный характер. Сайт atoldriver.ru не является представительством компании АТОЛ или АО «ЕСП» и не оказывает услуг по обслуживанию оборудования.