Блог

Технический долг в Legacy-ПЛК: Когда рефакторить, а когда нет

В старом проекте ПЛК легко найти то, что хочется немедленно переписать. LD-сети без комментариев, уставки числами прямо в сравнении, десять почти одинаковых веток для насосов или клапанов, временные биты с именами, понятными только автору пятнадцатилетней давности. Для инженера это выглядит как неопрятный код. Для производства этот же код может быть частью линии, которая годами запускается каждое утро.
Поэтому технический долг в Legacy-ПЛК - не конкурс на красоту проекта. Это решение о риске: что мешает безопасно поддерживать объект сильнее, чем риск остановки после вмешательства. Иногда старую лестницу нужно оставить в покое и только обнести наблюдаемостью и документацией. Иногда именно отказ от изменения становится самым дорогим выбором.

Короткий ответ

Рефакторить Legacy-ПЛК стоит не потому, что проект выглядит устаревшим, а когда есть измеримая проблема: повторяющиеся ошибки, невозможность проверить изменение, нехватка диагностики, опасные неявные константы или необходимость модернизации узла.
Практичная стратегия - «ограждение + постепенная замена»:
1.Зафиксировать работающую ревизию, резервную копию и сценарии нормальной работы.
2.Описать входы, выходы, блокировки и критичные режимы проблемного участка.
3.Добавить наблюдаемость: понятные статусы, журнал, комментарии, таблицу констант и тестовые сценарии.
4.Менять один изолированный фрагмент за раз с возможностью быстрого возврата.
5.После проверки обновлять baseline и только затем брать следующий участок.
Это не урок по языкам IEC 61131-3. Вопрос здесь не в том, на чем «правильнее» писать, а в том, как не превратить улучшение проекта в незапланированную остановку линии.

Как выглядит технический долг в работающем ПЛК

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

LD без комментариев и границ

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

Магические числа

Таймер с константой 15000, сравнение с 73 или коэффициент, появившийся без единиц измерения, часто работают много лет. Но когда требуется изменить время продувки или порог разрешения, спор начинается не с расчета, а с вопроса: «Это секунды, миллисекунды, проценты или значение после масштабирования?»
Магическое число - это не обязательно ошибочная настройка. Это настройка без контекста, которая опасна при любом обслуживании.

Copy-paste блоки

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

Почему «перепишем красиво» - плохое начало проекта

Legacy-логика хранит не только ошибки, но и неочевидные знания о реальном процессе. В странном контакте может быть обход давно известной особенности механики. В лишнем таймере - защита от дребезга конкретного датчика. В ветке, похожей на дубль, - условие, которое однажды спасло партию продукта.
Если переписать такую логику по впечатлению от экрана редактора, можно получить аккуратный проект, который не выдержит первый редкий режим. Основные риски большого рефакторинга:
•меняется сразу много поведения, и при отказе трудно найти причину;
•нет эталонных сценариев для сравнения «до» и «после»;
•окно останова короче времени на полноценную проверку;
•у эксплуатации нет быстрого и проверенного отката;
•часть знаний остается у людей, которых не было на испытании.
Первый вопрос перед изменением должен звучать не «как переписать этот код», а «каким доказательством мы подтвердим, что процесс после изменения ведет себя как нужно?»

Стратегия: ограждение, затем постепенная замена

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

Шаг 1. Снять слепок рабочей системы

До вмешательства фиксируют фактическую ревизию проекта, выгрузку из контроллера, резервную копию, версии устройств и дату. Удобно приложить короткое описание: какие агрегаты работали, какие режимы доступны и какие замечания уже известны. Без такого baseline откат превращается в догадку.

Шаг 2. Нарисовать границу участка

Выбирают не «весь проект старый», а конкретную зону: пуск одного насоса, группа клапанов, блок подачи материала. Для нее составляют лист входов, выходов, разрешений, аварий, уставок и зависимостей от соседних участков. Уже этот шаг часто выявляет, почему кусок кода страшно трогать.

Шаг 3. Добавить наблюдаемость до изменения поведения

В Legacy-проекте полезно сначала сделать поведение видимым: подписать сети, вынести список констант с единицами измерения, зафиксировать причины блокировки, собрать журналы состояний и подготовить сценарии проверки. Если это возможно без вмешательства в управляющую логику, риск заметно ниже, а решение о рефакторинге становится обоснованнее.

Шаг 4. Заменять маленькими участками

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

Шаг 5. Закрывать изменение документально

После стендовой проверки и проверки на объекте обновляют ревизию, описывают измененный участок, записывают результаты сценариев и сохраняют принятую резервную копию. Если документация отстает, через полгода новый аккуратный блок снова станет частью неразличимого Legacy.

Что проверить до первого изменения

Ниже короткий фильтр, который помогает не начинать рефакторинг на эмоциях.
Вопрос
Если ответа нет
Есть ли выгрузка и проверенный способ вернуть текущую рабочую ревизию?
изменения не начинать до backup/restore
Известно ли окно останова и критерий его превышения?
согласовать окно, ответственных и план возврата
Понятна ли граница изменяемого участка: сигналы, блокировки, взаимовлияния?
сначала описать контур и зависимости
Есть ли сценарии нормального и отказного поведения до изменения?
снять поведение и оформить проверку
Кто принимает результат на объекте и кто разрешает откат?
назначить роли до загрузки
Этот фильтр хорошо охлаждает желание «быстро убрать копипаст». Если нет возможности доказать результат и вернуться назад, безопаснее сначала организовать контроль вокруг старого кода.

Пять сценариев: трогать или не трогать

1. LD без комментариев, но узел стабилен и изменений не планируется

Ситуация. Небольшая линия работает годами. В LD почти нет комментариев, названия промежуточных битов плохие, но отказов по логике не было, новых режимов в ближайшем плане нет, окно останова минимально.
Решение: сейчас не рефакторить поведение.
Выгрузить рабочую ревизию, подписать внешний лист сигналов и зависимостей, оформить резервную копию, зафиксировать ключевые сети в эксплуатационном описании. Код не станет прекраснее, зато объект перестанет быть полностью непрозрачным без риска повторного пуска после массовой правки.
Триггер для возврата к вопросу: модернизация узла, повторяющаяся диагностика неисправности или необходимость менять алгоритм.

2. Магические числа участвуют в разрешениях и задержках пуска

Ситуация. Внутри сетей стоят числовые уставки без обозначений, а эксплуатация регулярно просит менять времена и пороги под продукт или сезон. Ошибка в интерпретации числа может вызвать отказ пуска или неверный режим оборудования.
Решение: трогать, но узко.
Сначала составить ведомость существующих значений с назначением и единицами, сверить ее с технологом и снять поведение на текущих значениях. Затем заменить неявные константы именованными параметрами с ограничением допустимого диапазона и журналированием изменения. Логику последовательности не переписывать одновременно с нормализацией уставок.
Почему польза выше риска: изменения уставок уже происходят; оставить их неявными означает продолжать рискованную практику.

3. Copy-paste блоки расходятся после каждого ремонта

Ситуация. Участок содержит несколько одинаковых агрегатов. Исправление аварии или задержки в одном блоке забывают перенести в соседние; дефекты повторяются на разных механизмах.
Решение: трогать по одному типу агрегата.
Выделить единый контракт агрегата - команды, разрешения, состояния, аварии - и подготовить регрессионные сценарии по каждой существующей копии. Новую типовую реализацию сначала применить к одному некритичному механизму, сравнить поведение, затем переносить на остальные в согласованные окна.
Почему не «заменить все за раз»: копии уже могли получить реальные отличия; сначала их нужно обнаружить и классифицировать.

4. Некрасивый LD содержит цепи, связанные с безопасностью или редким аварийным режимом

Ситуация. Код плохо читается, но управляет отсечением, защитой оборудования либо режимом, который трудно или опасно воспроизвести на работающем объекте. У команды нет полноценного стенда и доказанной программы испытаний.
Решение: не рефакторить до появления доказательств.
Оградить участок: документировать назначение, собрать исходную ревизию, определить наблюдаемые признаки срабатывания, разработать сценарий испытаний и только после согласования требований рассматривать изменение. Для функций, влияющих на безопасность, обычное «стало читабельнее» не является критерием приемки.
Триггер для изменения: утвержденные сценарии проверки, стенд или окно испытаний и ответственное лицо, принимающее результат.

5. Модернизация оборудования уже требует менять старую логику

Ситуация. Компонент снимается с поддержки, вводится новый привод или участок расширяется. Оставить проект как есть уже нельзя: вмешательство неизбежно, а существующий LD плохо позволяет проверить новые ветки.
Решение: трогать, используя модернизацию как контролируемую границу.
Зафиксировать исходное поведение, выделить интерфейс старой и новой части, сохранить старую реализацию для отката и заменить только логику модернизируемого участка. Сценарии проверки должны закрывать как штатный режим, так и отказ/восстановление. После приемки обновить проектный baseline и документацию.
Почему это разумный момент: риск вмешательства уже принят проектом модернизации; можно направить его не на латание, а на уменьшение долга в четко ограниченной зоне.

Матрица решения для руководителя АСУ ТП

Признак
Скорее оградить и наблюдать
Скорее планировать замену
Узел стабилен, новых функций нет
да
нет
Дефект регулярно повторяется из-за копий
недостаточно
да
Неизвестна рабочая ревизия или нет отката
сначала исправить управление версиями
до этого не менять
Меняются уставки, но их смысл не зафиксирован
краткое ограждение обязательно
узкая нормализация нужна
Изменение затрагивает критичный режим без стенда
да, до подготовки проверки
нет
Модернизация все равно требует остановки и загрузки
только как подготовка
да, по границе модернизации
Матрица не заменяет инженерное решение, но убирает две крайности: «ничего не трогаем, потому что работает» и «перепишем все, потому что некрасиво».

Как не превратить постепенную замену в вечный черновик

Стратегия маленьких шагов работает только тогда, когда у каждого шага есть конец. Для выбранного участка заранее задают:
•какую проблему изменение должно убрать;
•какие сценарии доказывают сохранение или улучшение поведения;
•какую ревизию можно быстро восстановить;
•какой документ обновляется после приемки;
•когда участок считается закрытым и не требует параллельной старой реализации.
Если старая и новая логика годами живут рядом «на всякий случай», долг не уменьшается, а удваивается. Ограждение должно дать время на безопасную замену, а не стать оправданием бесконечного переходного состояния.

Для углубления: где LD уместен как язык

В этой статье LD рассматривается как уже существующее наследие на объекте и источник эксплуатационного риска. Отдельный вопрос - где Ladder Diagram сам по себе оправдан, а где усложняет алгоритмы. Он разобран в материале «LD (Ladder) в 2026: где язык релейной логики оправдан, а где маскирует технический долг».

Итог

Технический долг в Legacy-ПЛК опасен не старым видом проекта, а невозможностью уверенно изменить и проверить его поведение. LD без комментариев, магические числа и размноженные копии стоит считать сигналами для работы, но не поводом переписывать работающую линию одним большим релизом.
Начинайте с baseline, границ, наблюдаемости и испытательных сценариев. Там, где вмешательство не дает измеримой пользы, оградите код и оставьте работать. Там, где долг уже вызывает ошибки или модернизация делает изменение неизбежным, заменяйте небольшими проверяемыми участками с готовым откатом. Так рефакторинг становится инженерным управлением риском, а не спором о том, чей проект выглядит современнее.

Обсуждение