Я, как любой другой любитель «поковыряться» в различных железках, связанных с датчиками, микроконтроллерами и сопутствующих штуках, несколько лет назад столкнулся с необходимостью связать очередную микроконтроллерную историю с ПК, а именно, мне нужно было выводить в реальном времени значения различных сигналов с МК на дисплей компьютера в виде различных графиков, прогресс‑баров, а также, с помощью кнопок и ползунков управлять моим «железом».
В тот момент я уже относительно продолжительное количество времени работал на должности «инженер АСУ ТП», поэтому не понаслышке знал о популярных существующих системах диспетчеризации (по другому — SCADA системах) и для моих целей этого было крайне избыточно, особенно если учитывать их физический объем на жестком диске, необходимость использования OPC‑сервера и/или специфичных протоколов обмена.
Было принято решение написать свою с нуля! С функционалом близким (ну, или частичным) к крупным SCADA, но ориентированную на простого юзера, без лишних усложнений чтобы любой начинающий мог быстро в пару кликов создать необходимый графический интерфейс. Плюс к этому, давно хотел начать изучать C# и попробовать написать десктопное приложение с графическим интерфейсом.
Этот проект уже несколько лет как «завершен» и свою задачу выполнил, поэтому решил поделиться им с Вами, вдруг кто то, как и я в свое время, ищет подобный софт для своих задач но не хочет углубляться в тонкости проектирования систем диспетчеризации!
Кратко, что такое SCADA-система
SCADA (Supervisory Control And Data Acquisition — диспетчерское управление и сбор данных) — программный пакет, предназначенный для разработки или обеспечения работы в реальном времени систем сбора, обработки, отображения и архивирования информации об объекте мониторинга или управления. (взято тут)
Более подробное описание того что это такое можно с легкостью найти на просторах интернета, я лишь хотел сразу обозначить, что, под термином «SCADA», часто имеют в виду весь комплекс от контроллеров и различных датчиков до HMI (человеко‑машинный интерфейс — то самое, что мы видим на дисплее компьютера и жмакаем по различным кнопкам). В пределах данной статьи разговор будет идти именно о HMI, что тоже покрывается термином «SCADA», особенно, на реальных объектах в разговорной речи.
ASCADA. Что это такое и почему я её называю "простейшей".
ASCADA — это программа, основанная на C# Winforms (.Net 3.5 для большей совместимости, чтобы на каждом "тапочке" работала без проблем). Предназначена для быстрого и простого проектирования систем визуального контроля технологических параметров, передаваемых от микроконтроллеров через последовательный порт или промышленных контроллеров через протоколы Modbus RTU/TCP. Используется в домашних решениях для управления и отображения различных параметров.
С первого взгляда видно то, что это сделано на Winforms, о чем сейчас сожалею, так как почти 90% времени работаю с линуксом, а там, через wine это дело работает мягко говоря кривовато (но работает), да и по "красивости" интерфейса есть вопросы, но да ладно.
Общий принцип такой: внутри проекта создаются так называемые теги - так в АСУ ТП называют различные сигналы, или более привычно - переменные. Теги, как и переменные, могут быть разных типов, в моем варианте предусмотрены следующие типы: bool, int, float, string. Здесь важно понимать, что тег - это не совсем переменная в привычном смысле, поэтому его тип это почти условность, которая определяет его предназначение.
Например:
int - это любое целочисленное число, которое поместится в стандартный int и означает то, что если мы хотим привязать к какому то объекту (или его свойству) этот тип, то этот объект должен поддерживать работу с таким типом о чем заботливо будет подсказано при попытке это сделать.
float - это числа с плавающей точкой, следовательно, вы успешно можете привязать его к прогресс-бару, но не получится привязать к этому типу позицию x:y объекта.
string используется в текстовых окнах, чтобы отображать какие либо сообщения от микроконтроллера в текстовом виде.
bool - это тот же int, с той лишь разницей, что используется в дискретных объектах - кнопках, переключателях и т.д. и оперирует со значениями 0
либо 1
.
Путем привязки созданных тегов к объектам на экране и передачи значений по этим тегам (если быть точнее то передаем значения мы по ID тега) и происходит так называемая диспетчеризация. Объекты светятся, моргают, отображают значения параметров и все замечательно. Обмен может происходить в обе стороны, как со стороны микроконтроллера, так и со стороны ASCADA, например при нажатии на кнопку или перемещении ползунка. По моему мнению - это абсолютно просто. Но обо всем по порядку.
Как передавать значения тегов от микроконтроллера в ASCADA
Так как цель разработки была - максимально все упростить, то и "протокол" обмена крайне прост (если вообще язык повернется назвать это протоколом). Передача происходит в символьном виде через последовательный порт, он же COM-порт. Выглядит это так:
0&100*
В этом примере пакета данных мы передали int или float значение 100
в тег с ID равным 0
, где &
- символ-разделитель, а *
- символ конца пакета данных.
Еще несколько примеров: 19&Hello World*
- передали строковое значение Hello World
тегу с ID =19
; 234&1958,59*
- передали значение с плавающей точкой 1958,59
в тег ID =234
. Как видите, все максимально просто и понятно.
На примере с изображения видно что если кликнуть по объекту, то в внизу экрана в поле "Object Tag Property" отображается список из заранее созданных тегов и групп, в которых они были созданы. Также, всегда указывается какие типы тегов выбранный объект поддерживает.
Как "запустить/воспроизвести" созданный проект в ASCADA?
На момент публикации реализовано только два способа запуска созданного проекта:
Из менеджера проекта.
Путем генерации иконки быстрого запуска.
Первый способ заключается в том, что при сохранении изменений в проекте создается файл с расширением .ascproj, который по своей сути это бинарная сериализация всего и вся что есть в проекте, включая изображения и т.д. Следовательно, если вы сохраните проект в директории программы в папке /Projects, то он отобразится в менеджере проектов, который запускается при старте программы:
Здесь мы кликаем по нужному проекту и видим его превью в виде того что в нем находится и текстовое описание (если мы, конечно, создавали это описание). Далее, у нас есть выбор - запустить его или редактировать, мы нажимаем запустить - кнопку START. После этого в новом окне откроется проект уже не в редакторе, а в виде программы, которая разворачивается на весь экран. Нам остается лишь открыть нужный COM-порт на нужном бодрейте, и, если в этот момент наш микроконтроллер или радиомодем шлет туда пакеты в приведенном выше формате, наши объекты начнут шевелиться, изменять свои значения и т.д.
"Но ведь это долго и неудобно" - скажете вы. И будете правы. Именно поэтому я сделал второй способ запуска - генерация иконки быстрого запуска.
Для этого при редактировании проекта необходимо перейти в его свойства (иконка шестеренки в правом верхнем углу редактора или в Project/Properties).
Здесь мы можем выбрать: запускать ли проект на весь экран сразу или нет, с какого экрана начнется запуск (можно создавать много разных экранов и между ними переключаться), активировать авто подключение к COM-порту и к какому именно COM-порту и, что самое интересное на мой взгляд - это генерация иконки быстрого запуска.
Стоит лишь выбрать в каком месте на компьютере создать иконку и дать ей имя. Как только мы нажмем Accept, то по указанному пути создастся иконка приложения, при нажатии по которой, наш проект сразу запустится, и, при необходимости, откроет нужный COM-порт!
Итак, с основным смыслом данной программы, я думаю, уже не осталось вопросов. Кратко поговорим про возможности:
Возможности ASCADA
Для реализации наших проектов в нашем арсенале есть несколько типов объектов, это:
Динамические объекты
Статические объекты
Компоненты
Фейсплэйты
Динамические объекты, в контексте данной программы, это объекты к которым можно привязать тег (переменную) и эти объекты будут каким-либо способом реагировать на это, например: прогресс-бары, текстовые окна, ползунки, кнопки, переключатели, графики (тренды) и т.д.
Статические объекты - это объекты, к которым не привязывается тег, то есть это: изображения, геометрические фигуры, системные дата и время, обычный текст (например, если хотим сделать какую то подпись).
Компоненты - объекты, которые работают в фоновом режиме, например: звуковой сигнал, который реагирует на значение "1" тега с типом bool и воспроизводит мелодию выбранную на компьютере, CSV-логгер, который с заданным периодом времени пишет значение тега в .csv таблицу и создает тем самым лог, и компонент изменения свойств объекта, который позволяет к свойству какого-либо объекта привязать тег (например положение/размер объекта).
Фейсплэйты - это объекты, которые представляют собой кастомные объекты, созданные из стандартных. Например, мы хотим сделать меню проекта с кнопками навигации по проекту, и, чтобы нам не пришлось каждый раз копировать одни и те же кнопки с экрана на экран - мы создаем один фейсплэйт с ними и вставляем готовый фейсплэйт туда куда нам необходимо. Удобно, согласитесь?:)
Все графические объекты в ASCADA реализованы с помощью векторной графики и имеет достаточно гибкие свойства для кастомизации - от толщины границ и их цвета, до использования псевдо-прозрачности (свойство Crop Background, которое позволяет сымитировать эффект прозрачности объекта, но по факту делает фоновым изображением объекта скрин из области под объектом).
Однако, на случай, когда покажется что этого мало и картинка все равно выглядит "топорно", я предусмотрел возможность использовать изображения для различных прогресс-баров, круглых баров и т.д., что дает возможность создавать красивые объекты если брать .png объектов с различных фотостоков.
Как видите, при желании, можно создать очень даже симпатичный графический интерфейс для своих проектов по диспетчеризации.
Также, хочется отдельно упомянуть возможности самих «экранов» на которых находятся объекты. У экранов тоже есть несколько свойств — вы можете задавать им разрешение, задавать фоновый цвет или выбрать изображение для фона.
Также, есть очень интересная функция — использовать экран как темплэйт. Это означает что выбранный экран можно использовать как «шаблон» для всех других, а именно — все объекты что есть на этом экране, будут отображаться на остальных. Зачем это нужно? А для того, что если вам в вашем проекте, опять же, нужно меню с навигацией или панель с отображением даты и времени, то при реализации темплэйта вам не придется это все создавать/копировать на другие экраны. Как по мне, это удобно:)
А еще, хотелось бы упомянуть что в «плеере проекта», то есть когда проект уже запущен, есть возможность просматривать значения тегов в реальном времени в специальном окне, плюс есть эмулятор в котором вы можете текстом набрать пакет, который ожидаете от микроконтроллера и смотреть как на это реагируют различные объекты — что тоже удобно, чтобы каждый раз не подключать устройство.
Эпилог
Данная программа создавалась лишь для того, чтобы мне в моих проектах не приходилось каждый раз писать графический интерфейс в различных Processing и т.д., а делать это в пару кликов и с нужным мне функционалом. А также, с минимальными заморочками в плане программирования и траты на это времени.
Как выглядит примитивный пример как отправить в тег ASCADA с ID 4 значение float 36.6 от Arduino:
void send()
{
float temper = 36.6F;
String data_pack = "4&" + String(temper) + "*";
Serial.print(data_pack);
}
На мой взгляд это максимально просто, что справится даже самый начинающий.
Не буду в подробностях описывать другие возможности ASCADA в данной статье, как например, возможность работы через протоколы Modbus RTU и Modbus TCP, так как не вижу смысла. Если кого-то это интересует, то этот человек и сам разберется с интерфейсом.
Целью этой статьи не было рассказать о каких-либо интересных новых технологиях, о каких то моих знаниях и навыках. Цель была просто поделиться инструментом, который я когда-то создал сам для себя и если кому-то когда-то кроме меня пригодятся мой труд я буду только рад. Абсолютно никакого коммерческого интереса не преследую, лишь просто хочется чтобы это еще кому то пригодилось.
Даже больше, если будет какая то обратная связь и данный проект кого-то заинтересует, то я открою исходники в общий доступ для возможного развития - мне абсолютно не жалко:) Но скажу сразу, что в тот момент я только начинал изучать C# и создание графических приложений как таковых, а значит, данный софт просто весь состоит из костылей и неправильных решений. Спустя столько лет я бы все делал абсолютно по другому, с нормальной архитектурой и т.д. Но что есть, то есть :)
Буду рад критике, как мы знаем, без нее не бывает развития. А еще больше, если кому то было интересно!
Делюсь ссылкой на гитхаб уже скомпиллированного проекта, который нужно только запустить и пользоваться. Всем добра!
Комментарии (42)
SpiderEkb
22.10.2023 12:44Как выглядит примитивный пример как отправить в тег ASCADA с ID 4 значение float 36.6 от Arduino
Не совсем понятно - связь тега с конкретным датчиком захардкожена в прошивке контроллера?
MikeKozlovAVR Автор
22.10.2023 12:44Если я правильно понял суть вопроса, то - да. Со стороны контроллера необходимо передать какое-то значение на указанный ID тега, а в проекте привязать этот тег к любому объекту, чтобы этот объект выводил переданное в тег значение.
SpiderEkb
22.10.2023 12:44Хорошо. Допустим, у вам на порту 1 висит какой-то датчик.
По ряду причин, вам потребовалось его перевесить на порт 2.
Потребует это правки кода на МК?
Аналогично - есть датчик на порту . Вешаем еще один на порт 2. Нужно править код на МК?
Или в вашем случае "тег" связан с физическим портом на МК (и МК передает фактически значени того, что там на порту висит), а разборки что там это значит уже на стороне ПК идут?
MikeKozlovAVR Автор
22.10.2023 12:44Нет, тег никак не связан с портом. То есть внутри ASCADA реализован парсинг всего что прилетает в порт, и уже в зависимости от того что именно пришло происходит событие которое изменяет значение в привязанных к конкретному тега объектах
SpiderEkb
22.10.2023 12:44+3при подключении нового устройства требуется изменение кода МК?
Почему спрашиваю. В свое время занимался подобным. Делали "систему мониторинга инженерного оборудования зданий". МК там свои были, на STM32. Визуализация тоже своя - карта обслуживаемого района с объектами, окно аварийных сообщений...
Но там было требование - любые изменения конфигурации должны быть "на горячую, без остановки системы" (просто потому что остановить систему ЛДСС - лифтовая диспетчествкая связи и сигнализация - по нормативам означает предварительное отключение всх лифтов. А их в системе может быть 300-500 штук...)
Посему, у нас была разработана классификация устройств. Например, для датчика типа "сухой контакт" было так:
Тип датчика (информационный, аварийный, триггер, с задержкой)
Нормальное состояние (замкнут/разомкнут) - для всех, кроме информационных
Задержка (для датчиков с задержкой)
Тип датчика:
информационный - не генерирует событий, только возврат состояния по запросу
аварийный - обычный датчик, который генерирует событие при переходе из нормального состояния в аварийное.
триггер - аварийный датчик, который сам не возвращается в нормальное состояние, нужно сбрасывать отдельной командой
с задержкой - аварией считается не одиночный переход в аварийное состояние, но непрерывное нахождение в нем в течении заданного времени
Устройства подключаются к контроллеру нижнего уровня (УСО - устройство сопряжения с объектом). При старте УСО запрашивает у системы карту своих устройств и хранит ее в памяти в виде номер клеммы (куда подключено устройство), тип устройства, блок конфигурации (если нужно). Есть команды "удалить устройство из карты" и "добавить устройство в карту".
Т.е. подключение устройства - сначала идем на объект и физически цепляем устройство на клемму, затем уже с компа его описываем и посылаем команду "подключить". С этого момента система уже с ним может работать.
УСО постоянно "обтряхивает" состояние устройств по карте конфигурации. Обнаружило повод для события (например, переход из нормального состояния авариное) - посылает наверх (на контроллер верхнего уровня - IP-шлюз) короткое сообщение - номер клеммы + состояние.
IP-шлюз добавляет к посылке номер УСО (их несколько, может быть и 10 и 20 и 30 на одном шлюзе) от которого пришло сообщение и отправляет на комп в диспетчерской. Там дописывается номер шлюза и это идет в обработку - номер шлюза+номер УСО + номер клеммы составляют "физический адрес устройства в системе". Дальше блок данных (в общем случае).Система уже по адресу устройства в таблице определяет что это такое и как нужно обрабатывать данные. Например, для аварийного датчика будет прописано аварийное сообщение - что на самом деле есть "переход в аварийное состояние".
Кроме того, устройство привязано к объекту - где оно установлено. В результате, получив, скажем посылку 01 03 02 01 система раскрутит ее как:
IP-шлюз 1
УСО 3
Клемма 2
Состояние 1
Дальше по таблице - это охранная сигнализация машинного помещения пассажирского лифта, улица .... дом ... подъезд ... Состояние 1 означает "несанкционированное проникновение". На основе всего этого будет сформировано понятное человеку сообщение, еще и на карте будет подсвечено где именно случилось.
Это так, вкратце. В реале там всего кратно больше и сложнее, но в общем и целом принцип такой.
MikeKozlovAVR Автор
22.10.2023 12:44+1Всё, я понял что вы имели в виду. Смотрите, если конкретная реализация кода на микроконтроллере позволяет на ходу добавлять/удалять какой либо сигнал из системы не останавливая ее - то есть не хардкодом, а конфигурацией то да, так сделать можно. Ведь данный софт не прикладной всё таки, а скорее как конструктор системы. Но в самой ASCADA на горячую изменить тег не получится, придется перезапускать HMI-проект. Как возможный вариант - это зарезервировать заранее в проекте какое нибудь количество тегов и добавлять удалять сигналы путем создания отдельного экрана с текстовыми/числовыми полями и кнопками из разряда: поле номер клеммы, поле ID тега, поле имя сигнала, кнопка добавить/удалить. Но всю механику этих процессов всё равно нужно будет предусматривать в ПО на микроконтроллере.
olku
22.10.2023 12:44А можно плагинами сделать? Поллим папку с сериализованными объектами тегов, далее load/unload. Для безопасности и совместимости плагины можно подписывать... и продавать.
MikeKozlovAVR Автор
22.10.2023 12:44Такой функционал можно было предусмотреть и создать еще один объект или окно которое было бы своеобразным менаджером тегов в режиме работы "на горячую", но так как ни разу не сталкивался в своих поделках с такой потребностью - то такого функционала и нету. Ведь всё что тут реализовано возникло только из за того что был нужен тот или иной функционал мне в своих проектах.
agalakhov
22.10.2023 12:44+1Почему в качестве разделителя выбран такой странный символ, &? Чем хуже, например, 0=42.0 1=21.7 ?
MikeKozlovAVR Автор
22.10.2023 12:44Если честно, уже и не помню причину, вроде бы связано было с передачей string в которой мне нужен был символ '=', а '&' не использовался вообще нигде
smart_pic
22.10.2023 12:44Как передать значение переменной из МК в систему понятно.
А как передается значение при изменении свича или слайдера в системе в МК.?
формат сообщений одинаковый?
MikeKozlovAVR Автор
22.10.2023 12:44Да, "протокол" абсолютно идентичный на ввод и на вывод данных. При перемещении слайдера будет вызываться событие, которое в системе организует передачу текущего значения слайдера по ID тега, который привязан к этому слайдеру.
igorts
22.10.2023 12:44+2Изначально SCADA пакет создавались под Unix системы, помню такой SCADA пакет RTAP/Plus от компании Hewlett-Packard, который функционировал по ОС HP-UX, и эти системы были дорогими и доступными только для больших компаний
Потом в какой то момент появились реализации под Windows (один из первых был пакет Intouch) и в силу низкой стоимости и популярности intel+Windows эти пакеты практически вытеснили юниксовый
Затем появился протокол OPC DA , который стал стандартом де факто для SCADA и который основан на протоколе сетевого взаимодействия от MS - DCOM, что надолго привязало SCADA пакеты к платформе Windows (думается MS тут немало пстарались)
Наконец после популяризации Linux и появления спецификации протокола OPC UA, основанного на TCP или HTTPS картина стала постепенно меняться, появилось много решений под Linux
Тенденция сейчас все больше к созданию гуи под Web технологии, наиболее часто встречается связка svg, http, js на платформе которых и делают пользовательский интерфейс
MikeKozlovAVR Автор
22.10.2023 12:44На счет web согласен, в тот момент когда писалась эта программа были даже мысли создавать что то вроде сервера с вэб-мордой на которой было бы такое же отображение объектов как и в обычной реализации, чтобы можно было с любого устройства в сети выйти на страницу. Но кроме мыслей это никуда ее пошло, ни времени на это не было да и знаний, думаю, тоже
ponikrf
22.10.2023 12:44+3По сути так и есть - это решение из прошлого века.
Я даже больше скажу, когда мы заменили скаду на собственное решение с использованием Grafana получилось в итоге даже лучше. Потому что смотреть на цифры в один момент времени не имеет большого смысла. Графики показывают полноценно работу системы, и по ним можно полноценно диагностировать проблемы.
Ну и в целом SCADA в том виде в котором она была - имеет ну слишком много проблем. Рассказ об этом на самом деле тянет на целую статью.
SpiderEkb
22.10.2023 12:44+1Ну вот мы сразу собственное решение двигали. Но... Начиналось это в 1993-м году (первые мк делали на 8080) и про скаду никто тут не слышал еще.
Вообще все с нуля делали, аналогов в стране не было.
Ну а аотом уже не было смысла на скаду уходить - слишком много наработок было.
Окончательная версия - двухуровневая сеть мк (между собой они по rs485 общались, с сервером по udp), сервер ("ядро") к которому с одной стороны подключались мк верхнего уровня, с другой - интерфейсные клиенты разного плана (диспетчер, аварийная бригада, еще что-то).
Все это сильно распределенное было и достаточно объемное
igorts
22.10.2023 12:44Мы делали сами систему сбора данных, разные протоколы, под разные SCADA и на текущий момент практически во всех проектах ее используем
Делали и SCADA , но не стали ее развивать, слишком это дорого, не окупится
SpiderEkb
22.10.2023 12:44У нас оно было специализированное - то, что на диспетчерских в УК работает. Соответственно, интерфейс был сразу заточен на "неквалифицированного пользователя" - максимально просто и наглядно показывать что и где случилось.
Основная специфика там была в том, что все это очень распределенное в пространстве - по всему городу (два дома тут, три дома там...), а иногда еще и по городам-спутникам.
На компе в диспетчерской "ядро" (которое и маршрутизатор и отношение "многие-ко-многим" и монитор состояния контроллеров верхнего уровня и еще куча логики в нем), к нем по UDP подключаются контроллеры верхнего уровня (IP-шлюзы) - их там может быть штук 20.
К каждому IP-шлюзу по RS485 подключались несколько (где-то 5-ти хватало, где-то до 30-ти доходило) контроллеров нижнего уровня (УСО - устройство сопряжения с объектом). На них уже размещались "клеммные доски", позволяющие физически подключать устройства.
Устройства самые разные - датчики всякие, например, охрана служенных помещений (электрощитовая, машзалы лифтов), контроль работы клапанов дымоудаления, пожарная сигнализация (она на пульт пожарной охраны идет, но и на диспетчерскую тоже дублируется), лифтовые контроллеры...
Механизмов мало было - дистанционные замки в служебных помещениях.
Были устройства ГГС - громкоговорящая связь полудуплексная (со служебными помещениями, с кабинами лифтов) - там кнопка вызова + устройство коммутации линии + VoIP линия.
Видеонаблюдение можно было подключать, еще (где просили) подключали приборы общедомового учета (чтобы данные автоматом в диспетчерскую снимались).
В общем и целом на диспетчерской могло быть порядка тысячи устройств (одних лифтов 500-600 штук ну и остального...)
Протокол обмена - двоичный, датаграммы где в заголовке "физический адрес устройства" (номер шлюза - номер УСО - номер клеммы) + блок данных переменной длины который интерпретировался уже в соответствии с тем что это за устройство.
К ядру уже по TCP подключались интерфейсные клиенты. Они разных типов - диспетчер, аварийная бригада, просмотр логов и т.п.
Каждый клиент при регистрации в ядре указывал свой тип и как он будет работать - получать все из системы (диспетчер), получать сообщения только от заданной группы устройств (аварийная бригада - их интересуют только лифты и то не все, а только те, что за этой бригадой закреплены), вообще не получать сообщений, только ответы на посланные им запросы состояний и т.п.
Конфигурация вся "на горячую" - сначала физически подключаем устройство к клеммам, потом на компе уже включаем его в систему (описываем - где, что, куда подключено). На соотв. УСО уходит инициализация и устройство начинает работать.
Для новых типов были предусмотрены "драйвера" в виде DLL. Указывается в конфигурации и пришедшая датаграмма отправляется туда. А там уже вся ее обработка, вывод сообщений всех и т.п. В этом случае передо добавлением устройства добавлялся новый "тип" с указанием "драйвера".
Конфигурация в виде двух деревьев - с одной стороны дерево устройств: шлюз-усо-устройство, с другой - дерево объектов: улица-дом-подъезд... Каждое устройство связано с объектом, на котором оно физически установлено.
Все это позволяло формировать аварийные сообщения человеческим языком - что где случилось и подсвечивать все это на карте (все объекты были с привязкой к карте и детальной схеме объекта (например, дом - есть на карте, можно посмотреть детальную схему с подъездами и прочим).
Все это было проще реализовать самим чем путаться вписывать в какую-то готовую скаду.
С вебом решили не связываться. Все было в двоичном виде. Для интерфейсных клиентов в ядре был свой TCP сервер куда они подключались. Т.е. запускаешь клиент, указываешь к какому объекту подключаться (IP-адрес из справочника) и вперед - регистрация клиента в ядре и работаем.
9982th
22.10.2023 12:44Расскажите подробней, пожалуйста. С какой скады ушли? Что использовали для архивирования данных? Как реализовали управление из графаны, самописные плагины или что-то еще? Как у нее со стабильностью в таком сценарии использования, если оставить вкладку с автообновлением на месяц - работает?
MiraclePtr
22.10.2023 12:44Поддержку, очень интересно.
Я бы даже сказал, было бы очень круто увидеть статью об этом.
ponikrf
22.10.2023 12:44+1Ушли с CodeSys (2?) не помню если честно. Дело в том что изначально не мы делали этот проект.
Суть проекта - мониторинг. Тот кто это делал до нас, поставил модули ввода, завел в них датчики, поставил ПЛК, прописал это все дело в ПЛК, поставил OPC + SCADA.
Но в итоге меня попросили посмотреть, можно ли с этим что то сделать, потому что это работало от слова "никак". Производительность просто отвратительная, схема отвратительная, как и конечный результат соответствующий.
Вносить изменения в такую схему для меня было просто неприемлемо сложно. Взять проект ПЛК, прописать входные данные, выходные данные, залить прошивку, прописать OPC сервер и только потом получить все это дело в SCADA.
В конечном итоге из этой схемы я выкинул все кроме модулей ввода.
Мы экспериментировали со сборщиком на PHP но результат был не очень.
Потом родился VRack и мы начали собирать данные им сразу в 2 базы ClickHouse и Graphite. А отображать все продолжали в Grafana.
Отдельно хотелось бы выделить ClickHouse, боже это просто чудо. Мы делаем запросы к нашим устройствам, получаем с них данные по датчикам и сохраняем их в ClickHouse. На данный момент у нас в базе данных только по датчикам 7 533 369 159 записей, таблица занимает в базе всего 36GB. ClickHouse супер эффективная база данных для хранения именно сырых данных. Поэтому мы пихаем в нее все что считаем нужным. Например, дополнительно к получению каждой метрики по датчику мы так же сохраняем сколько времени у нас ушло на запрос. Это позволяет локализовать сетевые проблемы или проблемы с оборудованием (преобразователи или сами модули ввода).
В ClickHouse есть агрегируемые таблицы, вам не нужно самим заниматься агрегацией, база все сделает за вас. Есть несколько движков таблиц, таблица даже может прикинутся Graphite-like таблицей.
Если вы сами занимаетесь получением и хранением данных - рекомендую, независимо от масштаба ClickHouse.
Такс, по поводу управления. Управление если необходимо осуществляется у нас обычно через отдельный самописный интерфейс для мобилки. С появлением Vue2/3 и VRack для меня это перестало быть хоть какой то минимальной проблемой. Вобще если вам интересно - можете глянуть могу статью про VRack.
По поводу графаны - у нее есть для нас серьезная проблема. Графана ну слишком быстро развивается. Она работает в целом хорошо, но нас по итогу она не устроила и мы переходим сейчас на собственное решение. В итоге стек для решение тех задач у нас - VRack/VRack-db/Clickhouse/Vue3/ECharts/.
Просто для понимания трудозатрат - все это я делаю в одного. Например новый интерфейс вместо графаны я сделал за 4 вечера и 2 выходных. Соответственно в этот интерфейс при желании я могу встроить управление, VRack мне это позволяет.
VRack-db я использую для кеширования данных и моментального отображения графиков. Graphite хоть и хороша, но у нее есть концептуальная проблема - он очень сильно нагружает SSD, 3-4 года и SDD на выброс. Я подумал подумал и решил вобще не хранить данные на SSD для отображения графиков и просто запилить In Memory базу данных. В формате Graphite с нужной нам точностью все метрики у нас занимают в памяти не больше гигабайта. В случае чего все равно есть сырые данные в Clickhouse.
Для меня сейчас, самое главное - это мобильность. Если инструмент не позволяет себя расширять или заменять, я на него даже не посмотрю. В OpenSource сейчас есть кучу реально крутых вещей, ClickHouse хороший тому пример.
Получилось чет многовато. Короче как я и говорил, это тянет все на отдельную статью)
AntonSor
22.10.2023 12:44+1Спасибо, очень интересно! Надо будет где-нибудь применить. И ещё найти аналогичную систему с открытым исходным кодом, чтобы не зависеть от пропадания с гитхаба
smart_pic
22.10.2023 12:44Похоже вы повторили то что сделана на мониторах Nextion Но там конечно возможностей побольше будет в плане создания интерфейса и разных скриптов на события.
Вопрос : а по ТСР эта система работает , а то только про сом порт речь идет
Стоит лишь выбрать в каком месте на компьютере создать иконку и дать ей имя. Как только мы нажмем Accept, то по указанному пути создастся иконка приложения, при нажатии по которой, наш проект сразу запустится, и, при необходимости, откроет нужный COM-порт!
MikeKozlovAVR Автор
22.10.2023 12:44Кстати да, на момент создания этого софта я еще не знал про Nextion (возможно их тогда и не было, либо были не популярны), но позже когда для очередной поделки решил воспользоваться их дисплеем, то тоже подумал что есть большое сходство, особенно в плане протокола обмена. Видимо, ребята тоже старались сделать чтобы было максимально просто. Но всё же у них направление на "гуи" для дисплейного модуля, а не для работы на ПК. Для Modbus RTU и Modbus TCP предусмотрен такой элемент как "девайс", в котором можно настроить какой регистр с какого адреса привязать к тегу и прочие вещи как байт-свап и т.д. На счет автозапуска по TCP, если память не изменяет, то я такого не делал. То есть нужно будет вручную нажать "Connect all devices".
NutsUnderline
22.10.2023 12:44есть еще пара производителей таких HMI интерфейсов, без декларированной привязки к SCADA а чтобы красиво и редактировалось в редакторе. Но железо там не слабенькое, цена не кислая, в результате это уже не для самоделкиных...
SHLab
22.10.2023 12:44Боюсь далеко не пара. Что то прям очень похожее мы делали для ЖКХ в Москве еще в начале 2000-х годов ) и мы были совсем не одни на рынке )
NutsUnderline
22.10.2023 12:44я про тех которые можно купить не за космические для самодельщика деньги
Moog_Prodigy
22.10.2023 12:44+2Автор, вы делаете великое дело! На самом деле, многие это еще не осознают, потому что многие думают "scada это фронт, а я бэк, купят как нить". Есть маленькие проекты, типа CaScada, но все закрытое, каждый хочет свой кусок с асушного пирога урвать, а пирожок то маленький. Если для фирм\заводов платное решение да с поддержкой - нравится, то и в путь, господа.
Есть проекты средней величины типа OpenScada. Но оно уже переусложнено, плюс разработчики из Украины....сложно.
Можно пиратить. Но опять же как указал автор - высокий порог входа. Он не то чтобы высокий, но специфичен у каждой системы, и вот эта специфика добавляет постоянно мноооого геморроя. Система как будто говорит нам: наймите специалиста. Заплатите денег побольше! А потом еще! И еще много-много раз. Система в этом не виновата, ее такой создали разработчики, которым в свою очередь диктовали требования маркетологи. Плюс "как быть пряником и нравиться всем". Кому то не нужен OPC сервер, а какой нибудь завод скажет - о, у нас такие обьемы, конечно без серверов никуда, все будет. И выкатят им софт, которому они только и будут радоваться. Стоп. Получается только крупные заказчики и используют весь (и то не весь) функционал типичных SCADA, а на мелких плевать, и это так и есть. А те кто разрабатывают небольшие скады, хотят почему то денег. Их тоже можно понять. Но нужно понимать и сегодняшнее положение дел в асутп. Денег там 0. Спецы бегут. А кто остался - поддерживают существующее костылями. Я сам там работал, поддерживая древние скады еще под DOS, siemens S5 -115 и рулящее мощными механизмами. Это актуально до сих пор, и оно будет работать, потому что а смысл что то обновлять, если работает? Хорошо, жк экран поставим.
Универсальность готовых продуктов - одновременно их и плюс и минус. Может подойти для любого техпроцесса. Но разворачивание и настройка превращается в кипение в котле будто ты грешник.
Автор, твори, делай! На маленьких производствах, дома, такое очень востребовано!
MikeKozlovAVR Автор
22.10.2023 12:44Спасибо за теплые слова. Это решение именно для домашних проектов т.к. нет гарантий на отказоустойчивость и так далее, зато очень просто и быстро.
Siemargl
22.10.2023 12:44Нет, самоделки в этой области это гемор.
/- Ой, у нас студент что то сделал, поправьте плз.
Исходники есть?
-Нет
Пиратьте пока дают Сименс, ГЕ, РА
ЗЫ. Тема очень сложная, не для самодельщиков.
MikeKozlovAVR Автор
22.10.2023 12:44Смотря про какой уровень идет речь, если в промышленности либо на крупных объектах то однозначно крупные системы с экосистемами, которые отлажены со временем. Если дома, для условной теплицы - то вполне что то из самоделкиных сгодится. Я, проработав несколько лет в атомной промышленности, никогда в жизни не стал бы использовать что то самодельное, даже если бы был в нем уверен так как ответственность огромная.
Даже из крупнейших систем на рынке приходилось выбирать очень тщательно. И за обилием минусов в виде тяжести, стоимости и частичной монопольности системы я считаю одними из лучших это Siemens, так как надежность иногда просто поражала.
zatim
Я правильно понимаю, при передаче значения переменной ее тип не передается? Как программа угадывает его тип? Как отличает целочисленную 5 от строковой '5', например?
MikeKozlovAVR Автор
Этот нюанс лежит на стороне разработчика со стороны МК, ведь тип тега определяет то как он будет парситься в ASCADA. Ведь так или иначе значение отсылается в символьном виде. Ну а вообще, вопрос вполне справедливый, мне на тот момент показалось удачной идея написать библиотеку для МК внутренностями которой и будет проверяться корректность значения
zatim
Мы, видимо, о разных вещах говорим. Ведь ascada и запускается на пк, она ведь и должна парсить входные данные от мк, разве нет? Или, по вашей задумке, данные будут ходить строго от пк к мк?
А разве не проще добавить в тег всего один символ - букву, обозначающую тип. I, F, B, S, например. Это полностью исключит разночтения и существенно упростит парсинг.
kmarakov
Венгерская нотация?
SpiderEkb
На самом деле, каждая переменная (тег) - это текущее значение какого-то датчика. И тип этого значения определяется уже на уровне визуализации исходя из того, что это за датчик.
Специфика в том, что значение датчика может быть физически типа bool ("нормальное стояние" / "аварийное состояние"), а отображаемая переменная при этом будет иметь тип string - расшифровка того, что там не самом деле произошло.
zatim
А, понял, тип прописывается заранее, согласно номеру ID. Спасибо за разъяснение)
SpiderEkb
Я не утверждаю что здесь именно так. Но тег - это не типизированная переменная. Это просто идентификатор какого-то датчика. Как трактовать его показания - это уже вопрос конфигурации системы на стороне ПК.
MiraclePtr
Я так понимаю, программа уже знает, какого типа какой тег, ещё на этапе конфигурации (привязок данных).
Точно так же как, например, при использовании классического Modbus RTU/TCP в любой классической скаде (точнее, в OPC-сервере) при считывании данных с устройства вы не можете определить, что именно лежит в регистре - signed int, unsigned int, часть signed long/unsigned long/float (и какой порядок байт endianness у устройства?) или вообще набор битовых флагов. Пожтом вы задание тип данных для тега при создании тега в программе