TL;DR: Добавьте файл ~/.atol/drivers10/uem.env для отключения проверки службы.
О чем речь
ККТ – Контрольно-Кассовая Техника, умное название для кассы.
АТОЛ – доминирующий игрок на российском рынке кассовой техники. Каждая вторая торговая точка возле вас, скорее всего, будет использовать их продукцию.
ДТО – драйвер торгового оборудования. По сути это динамическая библиотека, которую можно встроить в свой программный продукт и взаимодействовать с ККТ их производства.
Что случилось
В конце 2025 года изменилось налоговое законодательство, и с 1 января 2026 года используется ставка НДС 22%. Для поддержки этих изменений АТОЛ выпустили новую версию драйвера 10.10.8.0 от 09.12.2025. В списке изменений, кроме всего прочего, есть такой пункт: «Добавлена интеграция драйвера со службой UEM, теперь работа данной службы для драйвера обязательна».
Наши приключения начинаются именно тут, так как никакой документации на эту службу нет. Служба после установки не запускается, а драйвер без нее не работает. А если ваш программный продукт использует Docker, то вообще непонятно, где должна быть служба запущена: внутри или снаружи.
Что за служба
Официальная документация ограничивается только таким описанием:
Агент АТОЛ UEM – программный компонент, являющийся частью сервиса АТОЛ UEM. Он обеспечивает подключение к этому сервису и проведение дистанционных сервисных операций, включая диагностику, обновление и настройку параметров Устройств, а также централизованное управление ими из единого интерфейса. При этом Агент взаимодействует со всеми устройствами кассового узла, позволяя осуществлять комплексное управление их конфигурацией и состоянием.
Получается, что ради слежки за вами компания АТОЛ сделала так, что компьютер, который использует драйвер, должен быть обязательно подключен к интернету. Без интернета служба не запустится и драйвер работать не будет. Но человек, который не в теме может возразить, что кассы же сейчас «онлайн»? Всё так, но им разрешено быть офлайн до 30 дней, накапливать данные, а затем отправлять все документы разом.
И ладно, хорошо, я хочу, чтобы за мной следили и работа в оффлайне – это не мой случай. Но служба просто не запускается.
Почему не работает
Тут решение нашел не я. Скорее всего первым в самом конце декабря был Дмитрий Бачило на YouTube: https://youtu.be/5t0QBE24h58.
Оказалось всё просто: АТОЛ в дистрибутиве для Linux в конфиге по умолчанию указали неправильный адрес сервера, к которому подключается служба. А документации, напомню, никакой нет.
Конфиг находится тут: /etc/uem/agent/config.yml. Для восстановления работоспособности службы нужно заменить параметры:
uemconfig.uem_hostс mqtts://plt.atol.ru на mqtts://plt-002.atol.ruuemconfig.uem_portс 8883 на 1883uemconfig.uem_reg_hostс https://entry-plt.atol.ru на https://entry-plt-002.atol.ru
После внесенных изменений служба начинает работать, а следовательно и драйвер.
Как использовать драйвер в контейнере
У компании Бизнес Проект есть продукт, который работает с ККТ. Он написан на Python и работает в Docker-контейнере. До последнего обновления работало так:
- в образе находилась библиотека
linux-x64/libfptr10.soиз дистрибутива, который можно загрузить на https://fs.atol.ru/, папка «Программное обеспечение» / «ДТО» / «10.х» - также из дистрибутива в образе нужен модуль
wrappers/python/libfptr10.py - ККТ подключен к Docker-хосту, на него ничего ставить не нужно
- Контейнер запускается с параметром
--device /dev/serial/by-id/usb-ATOL_Group_ATOL_USB_device_12345678-if00:/dev/ttyACM1, что прокидывает tty-устройство в него - Код внутри упрощенно выглядит так:
from libfptr10 import IFptr
fptr = IFptr()
fptr.setSingleSetting(
IFptr.LIBFPTR_SETTING_PORT,
str(IFptr.LIBFPTR_PORT_COM),
)
fptr.setSingleSetting(
IFptr.LIBFPTR_SETTING_COM_FILE,
'/dev/ttyACM1',
)
fptr.setSingleSetting(
IFptr.LIBFPTR_SETTING_OFD_CHANNEL,
str(IFptr.LIBFPTR_OFD_CHANNEL_PROTO),
)
fptr.applySingleSettings()
fptr.open()
Всё работало хорошо, но после обновления драйвер вызов fptr.open() заканчивался ошибкой с кодом 11 и описанием «Для работы с драйвером необходимо запустить службу UEMA».
Как починить
Еще раз отмечу, что у меня не было цели отключить службу из-за того, что она выполняет какую-то слежку или типа того. Я всего лишь хотел заставить работать драйвер внутри Docker-контейнера, как работала предыдущая версия драйвера. Но как это сделать?
Без документации не понятно как конкретно наладить взаимодействие драйвера и службы. Изначально я думал, что нужно наладить сетевое взаимодействие между ними. Ничего не помогало, и пришлось обратиться к методам обратной разработки.
Алгоритм инициализации драйвера упрощенно выглядит так:
- проверяем наличие файла
~/.atol/drivers10/uem.env - если он есть, тогда ничего не делаем
- если его нет, тогда выполняем
systemctl is-active uem-agent - если systemctl ответил, что служба не запущена, тогда возвращаем ошибку
Без этих знаний у меня не было шансов запустить службу на хосте, а драйвер в контейнере. То есть отучить драйвер от службы мы можем двумя способами:
- создать пустой файл
~/.atol/drivers10/uem.env - создать shell-скрипт systemctl с одной строчкой кода
echo active
На этом всё, драйвер замечательно работает без этой службы.
Заключение
Хорошо, что получилось починить работу драйвера своими силами, но со стороны компании АТОЛ придумывать своим клиентам такие квесты, я считаю, не очень красиво. Нужно было просто добавить документацию, так как если вы делаете библиотеку для встраивания в другие программные продукты, то программист должен понимать что это и как оно работает.