бесплатный quality-report для экспортов PLCopenXML

Приняли чужой ПЛК-проект? Узнайте, что вам досталось

Загрузите экспорт PLCopenXML — за 5 секунд отчёт о том, что в коде на самом деле: опечатки в тегах, невызванные таймеры, недостижимые ветви погодного графика, потеря дроби, мёртвый код. Свой проект перед сдачей проверяется так же.

🔒 Файл обрабатывается в памяти и на диск не пишется — ни код, ни имена POU у нас не остаются. Что происходит с вашим кодом →

Проверить прямо здесь

перетащите .xml сюда или выберите файл

Файла под рукой нет? В CODESYS это полминуты: Project → Export PLCopenXML →

Код заказчика нельзя выгружать наружу?

Тогда не выгружайте. Локальная версия проверяет файл на вашем компьютере и не выходит в сеть вообще — это не обещание, а свойство программы: движок открыт, а запрет проверяется тестом. Один .exe, без установки и без Python: перетащите на него экспорт — рядом появится тот же отчёт.

⬇ Скачать для Windows

Linux/macOS: python cli.py project.xml · исходники на GitHub

Проект лежит в git? uses: caspershes/plc-lint@v1GitHub Action роняет сборку на находках уровня high.

Что проверяем · всего 34 проверки

Из-за этого контроллер встанет или пойдёт вразнос (13)

CFC: деление на литеральный нольв графике CFC делитель блока — литеральный 0
Аналоговый вход без проверки достоверностиобрыв Pt1000 приедет в регулятор как честные 0 °C (профиль)
Бесконечный цикл без выходаWHILE TRUE без выхода — встанет скан
Деление на литеральный нольлитеральный /0 и делитель-переменная без защиты
Дубль Modbus-адреса у модулейодин адрес на шине у двух модулей
Индекс за границами массивалитеральный индекс вне объявленных границ
Канал не заполняется — пропуск в семействеобъявлено у всех каналов, пишется у всех кроме одного
Команда зависит от собственной обратной связистоит → нет разрешения → нет команды → стоит
Невызванный таймер/триггерTON/TP/R_TRIG читаются, но FB не вызван
Недостижимая ветвь IF/ELSIFмёртвые ELSIF — классика погодного графика
Опечатка в имени глобала (gvl.*)ссылки на глобалы без объявления в GVL
Параметр канала получает чужой каналавария насоса 1 приходит на вход насоса 2
Функция неявного контроля не защищаетCheck-функция есть, но её защита выхолощена

Тихие дефекты: работает, но не так, как задумано (11)

CASE без ветви ELSE (нет default)неучтённые значения селектора
REAL_TO_TIME(...)*N — усечение уставкидробная уставка времени теряется до конверсии
REAL_TO_WORD(...)*N — переполнение WORD?произведение выходит за 0..65535
Нет функций неявного контроля (рантайм-защиты)нет рантайм-защит CheckBounds/CheckDiv*
Присваивание переменной самой себеx := x — опечатка или потеря логики
Проверка присутствует, но не активнапроверка есть, но не зарегистрирована
Пустая ветвь IF/циклазабытая логика в IF или цикле
Сторожевой таймер задачи отключёнзависший скан никто не перезапустит
Строка расставляет индексы иначе, чем группаодиннадцать строк пишут в свой канал, двенадцатая — в чужой
Таймер с нулевой выдержкой (PT := T#0)PT := T#0S — выдержки фактически нет
Целочисленное деление (потеря дроби?)5/2 даст 2 — дробь отбрасывается

Стиль и сопровождаемость (10)

Magic number — сырая константа в кодесырые константы в логике без имени
POU без единого комментарияPOU с логикой без единого пояснения
Глубокая вложенность IFглубоко вложенные IF
Двойная `;;` (пустой оператор)двойные ;; и прочий мусор
Дублированный блок логики (copy-paste)структурно дублированные блоки и контуры
Имя не по стандарту PLCopenпрефиксы имён по типу (профиль)
Криптовое имя переменнойкриптовые односимвольные имена
Мёртвый код — POU нигде не вызываетсяPOU, которые нигде не вызываются
Неиспользуемая локальная переменнаяобъявлены, но нигде не используются
Раздутая рутина (кандидат на декомпозицию)раздутые POU — кандидаты на декомпозицию

К каждому замечанию — варианты решения с примерами кода.

Обработка идёт в памяти — загруженный код не сохраняется. Инструмент советует; правки по коду принимает инженер (см. что линтер не видит). Что происходит с вашим кодом → · Что с вашим кодом · Отраслевой срез · Обратная связь · GitHub