Поделюсь одним интересным кейсом, как мы сделали пилотный проект системы контроля освещением и что из этого получилось.
Клиент: крупный логистический центр в Московской Области, с которым мы работаем с 2016 года. За это время мы провели уже много работ по диспетчеризации инженерных систем, вывели в единую BMS вентиляцию, котельную, энергетику, отопление, энергоучет и много чего еще. А в этом году решили добавить еще и диспетчеризацию освещения в общую систему.
Что имеем? Установлен силовой шкаф управления освещением на 45 линий: складские ряды, коридоры, мезонин. На каждой линии установлен автомат защиты и модульный контактор. Помимо силового щита есть щит управления с ручным и автоматическим управлением. Автоматическое управление подразумевает включение и выключение линии по датчику движения, которые установлены в рядах, где двигается техника. Некоторые линии находятся в ручной режиме и постоянно включены, а некоторые, наоборот выключены. Задачу нам поставили следующую: отслеживать работу каждой линии, отслеживать залипание контакторов, оповещать о неисправностях и получать аналитику по наработке. Можно было бы полностью заменить шкафы, сделать дистанционное управление, расписание и много чего еще, но это было бы очень сильное удорожание проекта, а нас попросили именно вписаться в небольшой бюджет не меняя того, что и так работает стабильно.
Задача поставлена, начинаем реализацию. Есть несколько способов отследить работу линии освещения. Самый простой способ это использовать свободный или дополнительный контакт модульного контактора. Но конкретно в нашем случае эта схема не сработает, так как питание катушки контактора идет от общего автомата и возможна ситуация, когда на линии освещения контактор будет замкнут, а автомат выключен и питания на линии не будет. Этот способ будет работать только если питание катушки контактора идет из под автомата этого же контактора. Можно было бы поставить дополнительные контакты положения и сработки к автоматам, это даст более полную картину, но в нашем случае места в шкафу не было от слова совсем и раздвинуть автоматы для дополнительных контактов просто не было возможности. Решили пойти самым надежным путем, взять непосредственно фазу, идущую на питание линии и завести ее на контроллер. Так как у нас большая часть автоматики на объекте сделана на отечественных Контарах, то мы просто взяли модули расширения, которые воспринимают 220 вольт на входе. Это не частая опция у контроллеров, поэтому, если бы стоял другой производитель, пришлось бы ставить 45 промежуточных реле. Получился аккуратный и не большой шкаф диспетчеризации, мы повесили его рядом с силовым шкафом и обвязали все аккуратно многожильным кабелем. Расключение шкафа и отключение света согласовали заранее, а на все работы ушло около 1,5 часов.
Подключаем сигнальные линииС физикой все просто и понятно, после всех работ мы имеем 45 булевых переменных, которые мы добавили в скаду, настроили им архивацию и оставили это все работать на неделю.
Силовой шкаф до расключенияДальше разрабатываем интерфейс пользователя.
Основное окно секции освещенияЗдесь 46 линий разбитые на 2 экрана. Порядковый номер, состояние линии (включена, выключена, неисправна) и комментарий. Внизу есть оперативный график, можно посмотреть, как менялось состояние линии за последний час. Линии можно переключать, на скриншоте выбрана 16 линия.
На этом экране можно получить оперативную информацию о состоянии освещения. Есть отдельные окна трендов и настроек.
Окно с настройкамиВ этом окне мы вывели гибкую возможность настроек оповещения о залипании линии. Есть скрипт, который срабатывает по изменению переменной, в нашем случае булевой переменной с контроллера. Скрипт сравнивает новое значение с предыдущим, и если переменная изменила свое значение, то происходит сброс таймера наработки этой линии. Сравнение переменной нужно для того, чтобы если связь с ОРС не устойчивая, то не происходил сброс всех переменных одновременно.
Таким образом, мы имеем таймер каждой переменной, который сбрасывается каждый раз, как щелкает контактор в ту или иную сторону. Дальше пишем скрипт, который будет формировать аварийное сообщение, когда таймер перейдет заданное значение для выключенного или включенного состояния. И отдельная кнопка отправки этого сообщения в телеграм ответственному лицу.
Временные трендыОтдельное окно с временными трендами. Можно выбрать одну или несколько линий освещения и посмотреть их состояние за выбранный промежуток времени. На таких графиках удобно отслеживать длительную стоянку или работу линии. Если сформировалось аварийное сообщение о залипании контактора, можно по тренду посмотреть в какое время он перестал работать, единичный это случай или нет, и какие тенденции к повторению.
Отчет за выбранное времяДальше переходим к отчетам. Отчет можно сформировать за выбранный промежуток времени, за сутки или по часам. В отчете формируются данные по наработке и простою каждой линии, а также количество включений. Эта информация оказалась очень полезной для бизнеса предприятия, так как есть статистика по использованию и контролю производственного освещения. В отчете отлично видно, что ряд К17 используется намного чаще, чем другие ряды. При этом ряд К11 не выключался за эти дни вообще.
Отчет за выбранное времяВторая страница отчета выводит ту же информацию, но в виде диаграмм.
По итогу нашего проекта мы смогли создать систему диспетчеризации и аналитики освещения без какого-либо вмешательство в текущую работу системы освещения. Мы преследовали цель в первую очередь отслеживать состояния контакторов и автоматических выключателей, выявлять неисправности силовой части и своевременно оповещать эксплуатацию об этом. Но, в дополнение к основной задаче мы получили еще и очень полезную информацию для бизнеса и логистики.
Контроль отрицательных остатков - это когда перед тобой стоит покупатель, держит в руках нечто, что он собрался купить, а система тебе говорит: а нету этого в наличии, не буду оформлять продажу! Самое смешное, что на первый взгляд все кажется логичным и рациональным. Человек склонен ошибаться. У него может дрогнуть рука и вместо 10 шт. он введет 100 и не заметит. И вот в этот момент добрая и бдительная система подскажет ему путь к истине. И так оно и происходит в тех редких (ну очень!) случаях, когда вводят 100 вместо 10, а на складе как раз те самые 10 и есть. Но склады, они на то и склады чтобы хранить много и очень много. И если на складе в момент пользовательской ошибки будет не 10, а 100, 1000 или 10 000, то тогда система перестанет быть бдительной и заснет на день, неделю, месяц... Было бы лучше, если бы она заснула навсегда (почему - вы поймете чуть позже), но, к несчастью, рано или поздно система просыпается. И вы обнаруживаете себя в ситуации, которую я описал в самом начале. Вот они - эти 10 шт. в руках у покупателя. И руки ни у кого не дрожат. 10 шт. у покупателя и те же 10 шт. пользователь пытается ввести в систему. Но не тут-то было! Система кричит вам: стоп! стоп! стоп! отрицательный остаток! И что теперь делать пользователю? Глубоко вздохнуть и начать сверять все документы с этим товаром за день, неделю, месяц... Как повезет. Если очень повезет, то прилетит фея из известного анекдота и все будет "по-настоящему". В нашем случае "по-настоящему" - это когда причиной отрицательного остатка является не ошибка при вводе какого-либо документа, а пропуск приходного документа. Искать черную кошку в темной комнате особенно тяжело, когда ее там нет. Теперь пользователь просмотрит документы не за неделю-месяц, а вообще все. За все время. Не найдет ошибок. Еще раз глубоко вздохнет. Проведет инвентаризацию на складе. Оформит поступление товара... Все это время продажи этого товара будут стоять (ха! ха!) Вот она - месть программиста!
Самое удивительное в этой истории то, насколько широко распространен ныне этот "замечательный" алгоритм. Суеверный ужас пользователя перед отрицательными числами еще как-то можно понять. Но чем объяснить неприязнь к отрицательным числам со стороны разработчиков? Со стороны тех, кто с математикой все-таки не на "вы"? Отрицательное число - такое же число, как и положительное. И чем, в принципе может быть плох отрицательный остаток? Кому он может навредить? Вот положительный может навредить. И очень сильно. Не верите? Тогда представьте себе, что у вас в системе "хороший", положительный остаток, 100 тонн яблок. А на складе 0. И к вам подходит клиент, который уже оплатил этот самый "хороший" остаток. И теперь он хочет, чтобы его десять тяжелых грузовиков были немедленно загружены. А вот "плохой" остаток никогда не привел бы вас к такой ситуации, не так ли? Как хотите, но лично я бы сперва контролировал положительные остатки, а уж потом, на досуге, отрицательные.
Контроль отрицательных остатков исходит из неверного постулата, что причина отрицательного остатка может быть найдена и исправлена "здесь и сейчас". Сам факт наличия ошибок, приводящих к отрицательным остаткам почти всегда обнаруживается со значительной задержкой во времени, а поиск ошибки может сильно затянуться. Можно сказать, что контроль отрицательных остатков попросту не работает. Но этого мало. Контроль отрицательных остатков не только бесполезен, он еще и опасен. И вот чем:
Мы ни на полнанометра не оторвемся от реальности, если будем исходить из того, что продажи нам не даст остановить никто. Теперь представим себе ситуацию. На складе лежит 10 шт. В учетной системе числится остаток 5 шт. Приходит клиент и забирает все 10 шт. Какие тут могут быть варианты действий пользователя? Первый, самый распространенный, не регистрировать операцию вовсе. Отложить регистрацию до лучших времен. Когда кто-то сумеет найти причину отрицательного остатка и исправить ее. Чем он опасен? Тем, что теперь на складе 0 шт., а в системе все еще числится 5 шт. И рано или поздно эти несуществующие 5 шт. будут проданы. Понимая, что отказ от регистрации события может привести к перерезервированию, пользователь может поступить более изощренно. Списать количество до нуля. Т.е. зарегистрировать отпуск 5 шт. Но это не сильно отличается от первого варианта. Через 10 минут другой пользователь, который вводит приходные документы, спохватится и зарегистрирует наконец поступление 5 шт. То самое поступление, отсутствие которого и вызвало срабатывание контроля отрицательных остатков. И мы снова получим ситуацию с нулевым остатком на складе и положительным остатком в системе. Вообще говоря, искажать информацию или откладывать ввод информации - не самая лучшая идея. Корректный и максимально быстрый ввод информации должен быть в приоритете над всеми прочими соображениями. Поэтому самым разумным было бы зарегистрировать операцию как есть и вывести остатки в минус. Но именно этого нам и не дает сделать жесткий контроль отрицательных остатков!
Справедливости ради надо отметить, что иногда контроль отрицательных остатков может быть реализован в мягкой форме. В отличие от жесткого, мягкий контроль не блокирует работу пользователя, а только лишь предупреждает о появлении отрицательных остатков. Это избавляет нас от опасности перерезервирования. Но и мягкий контроль не является просто бесполезным. Он также вреден, хотя этот вред не столь очевиден, как в случае с жестким вариантом.
Базы данных нуждаются в контроле. Если не будет какой-либо системы обеспечивающей связь с реальностью, база данных очень быстро станет бесполезной и опасной. Это очевидно всем, и пользователям, и профессионалам. Но тут есть еще один момент. Он очевиден, как я надеюсь, профессионалам. А вот пользователям - вовсе нет. Речь идет о том, что систему связи с реальностью невозможно построить только лишь на алгоритме. Какими бы хитрыми ни были ваш алгоритм или группа алгоритмов, не будет такого, что вы их запускаете и получаете на выходе что-то типа: все в порядке, база полностью соответствует реальности. Действительно работающие системы связи с реальностью требуют наличия посредника (кем бы он ни был, но чаще всего это человек). Результат достигается в связке алгоритма и посредника.
Пользователю, однако, все это неочевидно. Он пользователь и полагается на профессионалов. Он склонен думать, что профессионалы уже все предусмотрели. Они снабдили его базу данных чудо-алгоритмом под названием контроль отрицательных остатков. Этот алгоритм сам (подумать только!) находит ошибки. И чего еще тут можно желать? Контроль отрицательных остатков создает у пользователей опасную иллюзию.
Те, кто придумали контроль отрицательных остатков, явно страдают болезнью, которую я ("украв" яркое определение у дедушки Ленина) называю детской болезнью автоматизации в учете. Они совершенно правильно считают, что настоящая автоматизация - это когда система выполняет полезные действия сама. Не пользователь должен сообразить что именно ему сейчас требуется. Найти, к примеру, соответствующий отчет, установить его параметры и получить наконец информацию. Нет, система сама все это сделает за него в нужное время и в нужном месте. И это отлично работает во многих случаях. Например, когда мы резервируем товар. Мы не лезем в один отчет, чтобы посмотреть сколько есть на складе. Затем в другой отчет, чтобы посмотреть сколько уже зарезервировали. Система сама определяет свободный остаток и возможное количество резерва. Кстати, систему резервирования довольно часто путают с контролем отрицательных остатков. Но это суть разные вещи. Система резервирования действует автономно от начала и до конца. А контроль отрицательных остатков блокирует работу и передает решение проблемы на сторону пользователя. Собственно, этот момент и является ключевым в вопросе применимости автоматизации. Жесткий контроль отрицательных остатков останавливает процесс и ждет решения от пользователя. Но пользователь не может решить проблему! У него просто нет времени на это. Кроме того, у пользователя может не быть (и скорее всего не будет) полномочий на внесение исправлений в далеком прошлом. Мягкий контроль не останавливает процесс, но он тоже вреден. Сообщение об отрицательных остатках по причинам, описанным выше, будет полностью проигнорировано пользователем. Сам по себе сигнал об отрицательных остатках - важный и полезный. Но он подается в неподходящем месте и в неподходящее время. В результате, критически важный сигнал будет потерян. Все уверены в том, что в системе есть работающий контур, но он не работает.
Контроль отрицательных остатков - наивная технология, появившаяся на заре автоматизации. Если в старых продуктах с ее наличием еще можно как-то смириться (в смысле, отключить), то в новых продуктах это контрпродуктивное решение просто недопустимо. И если вы встречаете контроль отрицательных остатков в новом продукте, то это повод задуматься.
Тут возникает резонный вопрос. А что взамен? Ответ в общем случае прост. Ничего особенного. У вас ведь есть отчет об остатках. Там наверняка есть отбор или хотя бы сортировка. Так или иначе вы можете получить список отрицательных остатков. А дальше назначается человек (или группа людей) с соответствующими полномочиями и располагающий достаточным временем. Этот человек на регулярной основе будет заниматься расследованием отрицательных остатков и их исправлением. Нет другого способа разумно организовать этот процесс. Что могут сделать разработчики в этой ситуации? Рационального, а не наивно-вредного? Разработать специально под этот процесс инструмент для работы с отрицательными остатками. В современных продуктах, как правило, множество регистров. У вас может не быть отрицательных остатков по складу, но будут отрицательные остатки по партиям, например. Нужен отчет, который выдаст все отрицательные остатки, какие только есть в системе. Далее, расследование отрицательных остатков заключается в основном в сверке с первичными документами. Мы не знаем в какой транзакции была допущена ошибка. Поэтому перебираем все документы от текущей даты к неопределенному прошлому. Этот путь можно сократить, если мы будем знать дату появления отрицательного остатка. Тогда можно будет идти не от текущей даты, а от даты появления отрицательного остатка. И, наконец, довольно часто отрицательные остатки возникают из-за так называемой "пересортицы". Вместо одного склада указали другой, вместо одной партии - другую. Есть способ при определенных условиях находить кандидатов на пересортицу. Не всегда и не всех, но то, что будет найдено сократит время поиска некорректной транзакции до минимума.