/rlebe[dev].dev
Настольное приложение для производственного участка

Задание на станок уходит одной кнопкой. Приложение — одним файлом

Программа стоит на компьютере рядом с линией сверления и отреза. Забирает производственные задания из учётной системы, раскладывает номенклатуру на конкретные отрезки профиля, показывает мастеру, что уйдёт на станок, и отправляет пакет по протоколу оборудования. Ни сервера, ни установщика, ни прав администратора — исполняемый файл и всё.

1 · Позиция заданияиз учётной системы
Короб приборный 3-0326-207-1 · план 2 шт
2 · Разбор в комплект профилейпо атрибутам номенклатуры
Основной854 мм × 2 · свер. 250, 354
Перемычка412 мм × 4
Отражатель830 мм × 2
3 · Пакет на станок157 байт вместо 1216
?{tasks:[{s:854,n:2,d:[250,354],oc:"Osnov",cli:"3-0326-207-1"},{s:412,n:4,oc:"Per",…}]}
1 файл
никакой установки
Win + macOS
одна кодовая база
0
зависимостей на машине
~1 мин
сборка релиза
01 Зачем это нужно

Между заданием и станком стоит человек с калькулятором

Мастер открывает задание, смотрит номенклатуру, в уме умножает комплект на план, выписывает размеры на бумажку и вбивает их в панель станка. Каждая цифра проходит через руки дважды, и каждая может поехать.

Брак

Ошибка стоит профиля целиком

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

Время

Ручной пересчёт съедает смену

Комплект на десяток позиций — это сотня отрезков, которые кто-то считает вручную перед каждым запуском.

Неполные данные

Незаполненный атрибут всплывает у станка

Если у номенклатуры не проставлена длина профиля, узнают об этом в момент запуска — когда линия уже освобождена под задание.

Повторяемость

Второй запуск даёт другой результат

Тот же заказ, другой мастер — другая раскладка. Сравнивать выработку между сменами не с чем.

02 Форма поставки

Настольное приложение, а не «ещё одна вкладка в браузере»

Компьютер участка живёт в той же сети, что и станок, и часто вообще без выхода наружу. Ставить туда сервер, базу и веб-приложение — значит завести отдельную инфраструктуру ради одной кнопки. Поэтому это десктоп: программу приносят на флешке, кладут на рабочий стол и запускают.

Windows
  • Один .exe примерно на 60 МБ — внутри и код, и графический клиент.
  • Python на машине не нужен, устанавливать нечего, права администратора не спрашиваются.
  • Собирается одной командой примерно за минуту; версия и метаданные подтягиваются из проекта, а не вписываются руками.
  • Сборка не требует тяжёлого C++-тулчейна — это отдельный путь, сделанный именно ради простоты выпуска.
macOS
  • Тот же код собирается в .app — интерфейс родной, а не веб-страница в окне.
  • Сборка идёт на CI, потому что бандл для macOS может собрать только macOS. Тег в репозитории — и готовый архив лежит в релизе.
  • Пути к настройкам и журналам берутся системные для каждой платформы, а не «папка рядом с программой».
  • Права на сетевые соединения объявлены в метаданных сборки — иначе система молча режет исходящие запросы.
Одна база кода

Никакого «версия для мака отстаёт»

Обе платформы собираются из одного проекта одними и теми же метаданными. Разница только в команде сборки.

Честно про подпись

Что будет при первом запуске

Приложение не подписано, поэтому macOS придержит первый запуск. Для внутреннего инструмента это снимается одной командой или пунктом «Открыть» в контекстном меню — и это описано в документации, а не выясняется на объекте.

03 Что происходит внутри

Четыре экрана и ни одного ручного ввода размеров

1

Список заданий с поиском и страницами

Задания приходят из учётной системы вместе с датой, статусом и числом позиций. Мастер находит нужное поиском, а не листает журнал.

2

Разбор номенклатуры в комплект профилей

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

3

Сводка и список замечаний

Сколько отрезков и какой суммарной длины уйдёт на станок — и отдельно позиции, у которых атрибуты не заполнены или не распознаны. Проблема видна до запуска, а не у линии.

4

Отправка с подтверждением

Перед отправкой — вопрос «точно?». Рядом кнопки «скопировать адрес пакета» и «открыть в браузере»: если что-то пошло не так, наладчик повторит запрос руками и увидит сырой ответ оборудования.

04 Протокол оборудования

Станок отвечает «200 OK» и на принятый пакет, и на отклонённый

Протокол реализован по документации производителя линии. Смысл работы — не «отправить запрос», а не дать участку решить, что задание ушло, когда оно не ушло.

Состояние

Сначала спрашиваем, готов ли станок

Занятое оборудование молча игнорирует команды — ни ошибки, ни отказа. Поэтому перед отправкой запрашивается состояние, и пока линия работает, отправка блокируется с человеческим объяснением.

Ответ

Разбирается тело, а не код ответа

Реальный итог лежит внутри страницы, которую возвращает станок: принят пакет или отклонён, и с каким кодом ошибки. Код HTTP тут ничего не значит.

Размер

Одинаковые отрезки сливаются в один блок

Вместо тридцати повторов уходит три блока с количеством. На реальном задании пакет сократился с 1216 до 157 байт — это разница между «не влезло в ограничение» и «ушло с запасом».

Символы

Кириллица кодируется по приложению документации

Имя клиента и код заказа попадают на панель станка. Неподдерживаемые символы отбрасываются с предупреждением — иначе панель отвечает кодом ошибки, который на участке никто не расшифрует.

Поле пакетаОграничение оборудования
размер отрезкадо 4 цифр — не длиннее 9999 мм
количестводо 3 цифр — не больше 999 штук
сверловкане более двух отступов на отрезок
код заказане длиннее 8 символов
имя клиентане длиннее 12 символов
пакет целикомдо 100 заданий и не больше 2953 байт

Все шесть проверяются до отправки. Нарушение — это понятное сообщение в интерфейсе, а не отказ станка спустя секунду.

05 Разбор одного бага

Браузер страницу показывает. Библиотека — падает

Промышленный контроллер отдаёт страницу, длина которой не сходится с тем, что он сам объявил в заголовке. Строгая HTTP-библиотека дочитывает тело ровно по объявленной длине, оставшийся хвост закрывающего тега принимает за начало следующего ответа и падает с ошибкой разбора. Тот же адрес, открытый в браузере, показывает страницу без единого замечания.

Чинить контроллер нельзя — это оборудование, прошивка чужая. Значит, снисходительным должен стать клиент: для станка написан отдельный транспорт, который отправляет строку запроса байт в байт как в документации и читает ответ до конца страницы, а не до объявленной длины.

Остальное приложение при этом продолжает работать через обычный HTTP-клиент. Исключение сделано ровно для одного узла, а не размазано по всему коду.

Диагностика

Проверка связи без интерфейса

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

Журнал

Сутки работы участка — в файле

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

06 Как собран код

Пять слоёв, зависимости строго в одну сторону

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

Домен

Модели и справочники без ввода-вывода

Неизменяемые объекты-значения, справочник типов профилей, иерархия ошибок и узкие интерфейсы: у шлюза станка две операции, у сборщика пакета — одна.

Сценарии

Загрузка → разбор → сведение → пакет

Сценарий зависит только от интерфейсов домена, а конкретные реализации подставляются в единственной точке связывания.

Проверяемость

Логика проверяется без станка и без сети

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

Расширение

Новый профиль — запись в справочнике

Типы профилей и ограничения протокола вынесены из кода разбора. Добавить четвёртый тип или переехать на другую линию — это данные и одна реализация интерфейса, а не переписывание.

07 Стек

Python на десктопе — без Electron и без браузера

Приложение
Python 3.11FletasyncioPydantic
Сеть
aiohttpсвой транспортполитика повторовHTTP-протокол станка
Сборка
PyInstallerнативный бандлGitHub ActionsPoetry
Эксплуатация
системные пути настроекротация журналовконсольная диагностика
08 Дальше

Если между вашей учётной системой и станком стоит человек

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

Протокол оборудованияРазбор документации, кодирование, ограничения, состояние линии, честный разбор ответа.
Настольное приложениеОдин файл под Windows и macOS, без сервера и без установки на машине участка.
Связь с учётомЗадания, номенклатура и атрибуты подтягиваются из той системы, в которой они уже ведутся.
Обсудить проект →