ScadaPy — использование OPC UA
В предыдущих нескольких статьях, мною были описаны возможности применения протокола modbus для создания собственной Scada системы на базе python. В этот раз хочется поделиться опытом построения системы опроса подчиненных устройств с использованием ОРС технологии.
Недостатки OPC серверов в том, что их можно использовать только в операционных системах семейства Microsoft Windows (как правило они платные), а об устройствах использующих ОС Linux можно было забыть.
Но со временем была создана спецификация OPC Unified Architecture (англ. Унифицированная архитектура OPC), что дало возможность использовать данную технологию передачи данных на иных операционных системах отличных от Windows. Это касается и встраиваемых систем, где может быть запущен полноценный Linux.
Подробнее можно прочитать здесь.
Например, на одноплатном компьютере Raspberry Pi можно запустить одновременно несколько различных OPC UA серверов для опроса терминальных устройств, счетчиков, датчиков и т.д., при этом система будет работать вполне стабильно.
Установка библиотек
Для работы с OPC UA и modbus серверами используются Xubuntu 17.04 Desktop и Windows 8.1. В Xubuntu 17.04 уже установлены Python 2.7 и Python 3.5 по умолчанию. Выбираем Python 3.5.
Если после установки операционной системы на компьютер не были добавлены необходимые пакеты, то нужно выполнить:
sudo apt-get install python3-pip sudo pip3 install pytz PyQt5 sudo apt-get install python3-opcua, libxml2-dev, python3-lxml
Решаем проблему зависимостей:
После поставим еще необходимые библиотеки:
sudo pip3 install requests pyserial
Для windows можно установить через pip3.exe, библиотека и примеры находятся здесь
Для запуска сервера, библиотеку нужно импортировать:
import sys from opcua import ua, Server
Теперь создаем OPC UA сервер.
server = Server() #можно прописать IP адрес сетевого интерфейса сервера, если их несколько server.set_endpoint("opc.tcp://0.0.0.0:4840/") #Записываем название сервера server.set_server_name("Server") #здесь указываем расположение сертификатов шифрования # можно обойтись и без них , тогда данные между клиентом и сервером не будут шифроваться server.load_certificate("server_cert.der") server.load_private_key("server_private_key.pem") #настраиваем собственное пространство имен uri = "http://server" idx = server.register_namespace(uri) #получаем ссылку на объект где будут располагаться наши узлы objects = server.get_objects_node() #создаем объект и присваиваем ему имя Object_1 =objects.add_object(idx,’MyFirstObject) Object_2 =objects.add_object(idx,’MySecondObject) Object_3 =objects.add_object(idx,’MyThirdObject) #теперь создаем переменные Discret_1 = Object_1.add_variable(idx,'Discret_1',[0,0,0,0,0,0,0,0]) Discret_2 = Object_2.add_variable(idx,'Discret_2',[0,0,0,0,0,0,0,0]) Analog_3 = Object_3.add_variable(idx,'Analog_3',[10,20,30,40,50]) #запускаем сервер server.start()
Вот и весь код на python для запуска OPC UA. Как оказалось ничего сложного, и если теперь подключиться к запущенному серверу с помощью UA Expert, то можно увидеть иерархический список наших объектов и переменных со значениями.
Для модификации значений переменных используется функция set_value типа:
Discret_1.set_value([1,1,1,1,1,1,1,1])
Конечно это очень примитивный пример, но в библиотеке OPC UA заложено намного больше возможностей, о которых можно прочитать здесь.
Единственное в чем не удалось разобраться, так это, как установить логин и пароль на сервер, вроде как-то посредством politics, думаю позже решу эту проблему.
Конфигуратор серверов
В продолжение к вышесказанному, возникла задача по оперативному конфигурированию каждого вновь создаваемого сервера.
Для данной цели был написан «Конфигуратор серверов» на библиотеке PyQt5.
— создается база данных на sqlite3
— формируются таблицы для slave и master частей сервера.
— таблицы заполняются необходимыми параметрами.
— формируется скрипт запуска.
Основная идея – серверы должны одинаково работать как в Windows, так и в Linux.
Скачать можно здесь
Структура каталогов:
srvconf.py – программа «Конфигуратор сервера»
db – находится файл базы данных srvDb.db.
img – файлы .png для кнопок
source – файлы шаблонов серверов
- mercury.py – библиотека для опроса счетчиков меркурий 230
- modbustcp_master_dcon.py – slave-сервер modbusTCP, master – опрашивает подчиненные устройства по протоколу DCON (Advantech). В настоящий момент только модуль 4050.
- modbustcp_master_http.py – slave-сервер modbusTCP, master – формирует запрос методом GET по URL или IP, в ответ получаем список значений типа int или string разделенных запятыми. Используется для встроенных систем с http серверами на борту, я использовал для ESP8266 c wi-fi соединением.
- modbustcp_master_ping.py – slave-сервер modbusTCP, master – отправляет ICMP пакет ping на указанный сервер, в случае true формирует дискретную 1, в случае false – 0.
- modbustcp_master_rtu.py — slave-сервер modbusTCP, master – modbusRTU. Используется для опроса подчиненных устройств по протоколу modbusRTU
- modbustcp_master_tcp.py — slave-сервер modbusTCP, master – modbusTCP. Используется для опроса удаленных устройств по протоколу modbusTCP.
- opcua_master_dcon.py — slave-сервер OPC-UA, master – опрашивает подчиненные устройства по протоколу DCON (Advantech). В настоящий момент только модуль 4050.
- opcua_master_http.py — slave-сервер OPC-UA, master – формирует запрос методом GET по URL или IP, в ответ получаем список значений типа int или string разделенных запятыми. Используется для встроенных систем с http серверами на борту, я использовал для ESP8266 c wi-fi соединением.
- opcua_master_mercury230.py — slave-сервер OPC-UA, master – формируются команды опроса счетчиков меркурий 230. Реализация исключительно только для OPCUA, поскольку не все параметры ответа по данному протоколу можно однозначно обработать для того чтобы поместить в регистры modbus.
- opcua_master_ping.py — slave-сервер OPC-UA,master – отправляет ICMP пакет ping на указанный сервер, в случае true формирует дискретную 1, в случае false – 0.
- opcua_master_rtu.py — slave-сервер OPC-UA,master – modbusRTU. Используется для опроса подчиненных устройств по протоколу modbusRTU.
- opcua_master_tcp.py — slave-сервер OPC-UA, master – modbusTCP. Используется для опроса удаленных устройств по протоколу modbusTCP.
Для Windows будет создан файл типа start_XX.bat, для Linux файл типа start_XX.sh, где ХХ порядковый номер сервера в таблице servers.
Содержимое файла start_XX.bat:
rem Скрипт создан в программе 'ScadaPy Конфигуратор сервера v.3.11' rem Название сервера 'Windows opcua_mercury230 ' rem Slave адрес '192.168.0.103' rem Slave порт '4840' rem Тип master 'master_mercury230' rem Тип slave 'opcUA' rem Интерфейс tty 'com6' rem Скорость tty '9600' start c:\Python35\python.exe F:\scadapy\config\source\opcua_master_mercury230.py 68 F:\scadapy\config\db\srvDb.db
# Скрипт создан в программе 'ScadaPy Конфигуратор сервера v.3.09' # Название сервера 'Modbus TCP' # Slave адрес '192.168.0.101' # Slave порт '504' # Тип master 'master_modbusTCP' # Тип slave 'modbusTCP' # Интерфейс tty '/dev/ttyUSB0' # Скорость tty '9600' /home/jack/config/source/modbustcp_master_tcp.py 67 /home/jack/config/db/srvDb.db
В параметрах запуска для Linux используется xfce4-terminal, т.к. работаю в Xubuntu 17.04,
но можно указать и другой тип запуска, вроде gnome-terminal.
xfce4-terminal --command='sudo /home/jack/config/scr/start_67.sh'
В примерах довольно понятно описаны параметры заполнения таблиц.
Примечательно, что на raspberry Pi запускалось одновременно 4 сервера — mobus_ping, opcua_http, opcua_mercury230 на /dev/ttyUSB0 и modbus_dcon на /dev/ttyUSB1, при этом он работал довольно стабильно и без сбоев.
Управление на данный момент реализовано частично и только в master_dcon, поэтому используется только телесигнализация и телеизмерения. В дальнейшем думаю добавить и телеуправление.
Шлюзы промышленных протоколов обмена на Linux. Собери сам
Я занимаюсь разработкой, внедрением и эксплуатацией систем автоматического управления технологическими процессами (АСУ ТП). Поначалу работал со SCADA-системами. Потом довольно быстро переключился на работу с протоколами обмена промышленных устройств. Как самостоятельное написание драйверов, так и настройка систем сбора данных. В настоящий момент моя работа проходит атмосфере Modbus-ов, МЭКов-101/104-х, ОРС и прочих протоколов.
Рис. 1. Многообразие протоколов обмена, используемых в АСУ ТП
Кратко о том, как устроена типичная система сбора данных (Немного упрощенно).
Рис. 2. Система сбора данных
Специальное ПО, называемое OPC-сервером ведёт опрос устройств, подключенных к интерфейсу RS-485. OPC-сервер является своего рода прослойкой между SCADA-системой и устройствами, переводя язык на котором общаются устройства в язык, понятный SCADA-системе. Преобразователь Ethernet/RS-485 служит для преобразования TCP/IP-пакетов в пакеты, которые ходят по физической среде RS-485.
Эта схема имеет ряд недостатков:
- Установим, например, в ОРС-сервере таймаут ожидания ответа 200 мс. В идеальном случае, когда пакеты в Ethernet ходят без задержек, обмен с устройствами идёт с хорошей скоростью (интенсивностью). Но если пакет, содержащий ответ, задерживается, например, на 300 мс (это больше таймаута ожидания ответа 200 мс), то ОРС-сервер считает, что ответ на запрос не пришел и отправляет следующий запрос. В это время приходит ответ на предыдущий запрос, но ОРС-сервер думает, что это пришел ответ на текущий запрос и передаёт неправильные данные наверх. Как результат данные на АРМе «скачут». Чтобы уйти от таких ситуаций установим таймаут больше. Возьмём с запасом — 3000 мс. Если ответ приходит раньше 3000 мс, то оставшееся время не ждём, переходим к следующему запросу. Пока всё идёт хорошо, но стоит нескольким устройствам перестать отвечать, как образуются задержки по 3000 мс на каждое устройство. Время опроса увеличивается.
- Большинство протоколов, используемых в АСУ ТП (Modbus, счетчики э/э) основываются на последовательном опросе одних и тех же параметров. Учитывая, что большую часть времени значения параметров остаются неизменными, сеть передачи данных используется для передачи одного и того же. Это нерационально, если среда передачи GPRS, и трафик стоит денег. Кроме того, в среде передачи GPRS задержки прохождения пакетов могут достигать нескольких секунд. Зачем тратить время и ресурсы для передачи одного и того же?
В общем какие-то аппаратные шлюзы есть и в немалом количестве. Но в виде готовых неделимых решений. Всё в одном. И это мне не особо нравится. Понадобился мне когда-то шлюз, преобразующий протоколы счетчиков СЭТ-4ТМ в OPC UA с шестью портами RS-485 и двумя Ethernet. У одного производителя есть шлюз с поддержкой нужных протоколов обмена, но мало портов RS-485, у другого есть нужное количество портов RS-485, но нет двух портов Ethernet. У третьего есть два порта Ethernet, но нет всех протоколов обмена. У четвёртого есть почти всё, но нет OPC UA, имеющиеся на борту МЭК-60870-5-104 или ModBus-TCP требуют ОРС-сервера для этих протоколов.
А как бы было замечательно: купить контроллер или мини-ПК с ОС у одного производителя. Купить ПО для контроллера у другого. Если одного производителя ПО не поддерживает что-то, докупить что-то из ПО у другого, объединить между собой компоненты ПО через стандартный программный интерфейс. Казалось бы, вот оно светлое будущее!
Вот поэтому шлюзы протоколов применяются реже чем связка «ОРС-сервер и «Преобразователь Ethernet в RS-485»» — из-за их неделимости на компоненты.
Одна из причин, почему мало развиты SCADA для Linux: SCADA есть, протоколов обмена в ней поддержано мало, а ОРС-серверов для связи с оборудованием нет. SCADA оставляет интегратора один на один с железом.
Читатель уже может задавать вопрос: Что можете предложить? Что уже есть? Есть OPC UA серверы для Linux для следующих протоколов:
- МЭК 60870-5-104;
- МЭК 60870-5-101;
- Счетчики Меркурий 230, 231, 233, 234, 236;
- Счетчики СЭТ-4ТМ, ПСЧ-3ТМ, ПСЧ-4ТМ;
- Счетчики Энергомера;
- SNMP;
- MQTT;
- Счетчики Меркурий 200.
OPC UA серверы и преобразователь работают на архитектурах x64, ARMv7 и AARCH64.
Таким образом, для аппаратной части можно использовать как проверенные временем решения на базе мини промышленных компьютеров, так и всевозможные «raspberry pi совместимые» ARM миникомпьютеры. Как производится установка и настройка ПО с примерами можно почитать здесь или здесь.
В общем виде структура комплекса выглядит так:
Система обладает масштабируемостью. Используются компоненты необходимые только для решения текущей задачи.
С использованием OPC UA сервера наша схема преобразуется:
У нас получилось следующее:
- OPC UA сервер собирает данные с устройств по RS-485 без больших задержек между запросами;
- Данные в SCADA выдаются по нескольку штук в одном TCP-пакете по изменению;
- К OPC UA серверу можно подключить несколько одинаково настроенных АРМов. Пригодится, если нужно дублирование.