Услуги Кейсы Подход Обо мне Обсудить задачу
← Все кейсы
ВидеоаналитикаМашинное зрениеCVControl API1С

Живой счётчик выработки на экране директора

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

15 сек
частота опроса — лёгкий запрос, только счётчик
1
источник правды — сервер CVControl, копия не хранится
2
площадки группы, фильтры определяются автоматически
~5
дней на рабочий прототип

01 — Постановка задачиAPI есть. Но пользоваться им можно только методом проб

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

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

  • Авторизация принимает данные строго как обычную веб-форму — JSON тот же самый эндпоинт молча отклоняет с «field required», как будто поля вообще не было в запросе.
  • Фильтры устройств организованы деревом, а не плоским списком — верхние узлы это «папки», и если запросить события по такой папке, сервер вернёт вперемешку данные всех вложенных камер и зон разом. Забирать нужно только «листья» дерева.
  • Пагинация есть, но обходить её нужно самому — листать offset вручную, пока не наберётся заявленное сервером общее количество записей.
  • Идентификаторы листовых фильтров у двух площадок группы оказались разными числами для одной и той же по смыслу точки учёта — жёстко прописывать их в коде нельзя, дерево нужно каждый раз обходить заново.
Отдельная находка

У эндпоинта событий есть необязательный параметр load_info, который вроде бы отвечает только за подгрузку не особо нужных деталей события. На практике же выяснилось, что при load_info=false сервер вместе с деталями «забывает» посчитать и поле count — общее количество событий за период стабильно возвращалось нулевым, хотя сами события в ответе были. Отключили эту «оптимизацию» — счётчик заработал верно. Такие вещи не видны по документации, только по расхождению цифр с тем, что реально происходит в цехе.

02 — АрхитектураТри способа читать одни и те же данные, без единой лишней базы

Соблазн — завести отдельную БД и копить туда историю «на всякий случай». Не стали: у CVControl уже есть собственное хранилище, дублировать его целиком избыточно. Вместо этого — три лёгких клиента поверх одного и того же API, каждый под свою задачу:

  • Скрипт постраничной выгрузки (только стандартная библиотека Python, без внешних зависимостей) — для полной архивной выгрузки за период, с автоматическим обходом дерева фильтров и пагинации.
  • Внешняя обработка 1С — тот же самый API, но напрямую из учётной системы: логин, обход фильтров, постраничная выгрузка событий средствами платформы 1С, без промежуточных файлов.
  • Настольное табло реального времени — лёгкий опрос раз в 15 секунд одним запросом с limit=1, чтобы получить только актуальный count, без выгрузки самих событий. Работает как обычное окно Windows на компьютере руководителя — без браузера, без локального сервера, без внешних зависимостей.
GET /v1/events/?begin_time=...&end_time=...&id_filter=20&limit=1&offset=0&load_info=true 200 OK count: 34410

03 — Детали, которые обычно опускаютПростой линии — это не «давно не было ответа от сервера»

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

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

Третья мелочь — какой день считать выходным. Отсутствие прироста в субботу или воскресенье — норма, а не авария; такое же событие в будний день — уже повод для звонка мастеру смены. Порог простоя и рабочие дни вынесены в настройки, а не зашиты в логику — у разных площадок группы разный график.

Иллюстрация
Тот же экран в выходной день — нулевая выработка не считается простоем.

04 — ИтогЧто это дало

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

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

Похожая задача на вашем производстве?

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

Обсудить задачу →