Инженерные системы наших дата-центров, часть 2

Trace Mode и с чем его едят
Повторюсь, изначально в в первом дата-центре выраженного мониторинга не было, а необходимость в нем была. И воплощать эту потребность решили сперва на базе уже строящегося «Миран-2», который планировался еще и модульным. Проектировщики и интеграторы предложили в качестве SCADA использовать отечественный Trace Mode. Данный продукт на тот момент мог удовлетворить все хотелки в плане мониторинга, был относительно простым в дальнейшей разработке (ежели бы такая необходимость возникла… и она-таки возникла) и стоил вроде бы не очень больших денег. В общем, неплохой вариант для простой системы.

АРМ дежурного ЦОД «Миран-2».


Trace Mode являет собой вполне классической образчик SCADA, имеет в себе ядро-сервер, опрашивающий циклично все необходимые железки по сети и клиент-консоли на АРМах дежурных, которые всю жизненную информацию от сервера и выводят, в виде различных мнемосхем. Такой вариант исполнения был использован для мониторинга «Миран-2» в целом. Для модульных ЦОД внутри (их пока у нас два) — был использован вариант с «тонкими» клиентами (java-апплет в браузере).

Фото панели с «тонким» клиентом в браузере и панели с клиент-консолью.


Кратко расскажу о внутренней структуре проектов. Есть условно два уровня:
  • нижний уровень, опрос устройств. Осуществляется «Источниками/Приемниками» — некие структурные шаблоны, которые определяют различные протоколы, технологии и интерфейсы (Modbus RTU/TCP-IP, SNMP, DDE, OPC etc.), содержат настройки связи. В общем, являются софтварным отражением периферии.
  • верхний уровень, тэги. В Trace Mode они называются «Каналами». Эти шаблоны уже определяют тип параметра, получаемого от «Источников» (дискретный/аналоговый), задают для него масштабирование, аварийные/предаварийные пределы (для аналоговых сигналов), назначают привязку к словарям аварийных сообщений, наконец, «каналы» же устанавливают будет ли данный параметр архивироваться или нет. Соответственно, к различным графическим элементам на мнемосхемах эти «каналы» можно привязать для оперативного мониторинга.

Trace Mode IDE. «Источники/Приемники».


Trace Mode IDE. «Каналы».


Это и есть ядро SCADA.
Конечно же в Trace Mode есть также возможность писать подпрограммы на общепринятых промышленных языках (ST, LD, FBD), создавать отчеты, рассылать SMS и E-mail.
На заметку.
Все продукты в семействе Trace Mode защищены HASP-ключами. Для работы в IDE требуется свой ключ, лимитирующий в проекте количество источников данных (e.g. лицензия на 128, 256, 512… N устройств). Для работы МРВ требуется свой ключ. Он лимитирует максимальное количество «каналов» в скомпилированном проекте; в подмножество каналов, помимо самих каналов, входят и вызовы программ, шаблонов экранов. Также ключ определяет доступность некоторых технологий, у нас, в частности, возможность запуска OPC-сервера Trace Mode. Для клиент-консолей, которые используются в АРМах, ключ лимитирует число экранов (в проекте дюжина мнемосхем, а ключ на десять? Два экрана перестанут вызываться). «Тонкие» клиенты? Ну вы поняли, ограничения на кол-во одновременных подключений, шаблонов документов...

Изначально, мониторинг от интегратора был довольно прост. Самый минимум: данные о состоянии вводных и вспомогательных автоматов, данные по энергопотреблению, показания температурных датчиков и датчиков влажности, состояние кондиционеров и ИБП, а также (один из важнейших параметров) — по-стоечный расчет энергопотребления.

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

Перво-наперво, система мониторинга была «причесана и вылизана», а именно: исправлены всяческие «очепятки», приведены в соответствие порядок чисел (200 градусов Цельсия в холодном коридоре превращаются в 20,0), найден консенсус, в чем же мы меряем потребление в стойках — в кВт или все-таки в кВА. Спойлер!

Вторым эшелоном шли исправления стратегические. Например, в первоначальной версии проекта первого модульного ЦОД не было никакой индикации о состоянии его ИБП, в норме ли они или уже отключились в аварийном состоянии из-за поломки. Был расширен список возможных аварийных ситуаций и сообщений о многих узлах ЦОД. Мнемосхемы обрастали различными значками, индикаторами и дополнительными параметрами, в общем, всем, что должно было помочь понять — здоров или нет дата-центр.

Основная мнемосхема ЦОД «Миран-2»


Основная мнемосхема ЦОД «Миран-1»


Мнемосхема состояния ИБП узла связи «Миран-2»


Мнемосхема ДГУ-1 «Миран-2»


Всплывающая мнемосхема модульного ЦОД «Модуль-2»


Огромные панели с мигающими мнемосхемами — это очень круто и хорошо, но дежурный все же человек, которому свойственно уставать, забывать и не замечать. Системы мобильных ЦОД не имеют, к сожалению, журнала тревог, поэтому было решено реализовать рассылку аварийных писем, как службе главного инженера, так и в тикетную систему нашей тех.поддержки. В последствии, к этому еще добавилась и оповещающая сирена.

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

Т.к. системы модульных ЦОД были оснащены только лишь «тонкими» клиентами и графиков и трендов они не поддерживали (опять же), хоть какой-то анализ был выполнен в виде суточных отчетов на E-mail`ы службы главного инженера (с простейшими табличками, заполненных мин/максами значений по датчикам температур и энергопотребления стоек). Наглядность, впрочем, все равно оставляла желать лучшего. Ко всему прочему, еще одним камнем преткновения стала нестабильная работа собственных архивов Trace Mode, из которых эти данные извлекались.

Перебрав несколько вариантов решения всего этого безобразия, было решено остановиться на варианте с отгрузкой данных из Trace Mode во внешнюю БД для дальнейшей обработки.

Когда я уже хотел приступать к реализации вышеозначенного варианта, наш главный инженер наткнулся на просторах интернета на сайт grafana. Дружно повздыхав над красотой графиков, мы сошлись на том, что-де реализовать подобное под наши нужды на текущей платформе — затруднительно. Тем не менее, grafana крепко засела у меня в голове и я стал искать любые гайды с описанием реализованных решений с ее участием. Переломными стали несколько статей на хабре: 1 и 2 (Хабр окрыляет помогает!) с упоминанием демона collectd и его плагинов.

Теперь уже вполне себе вызрела идея как все это реализовать под наши нужды.


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

Содержимое файла конфигурации для collectd
# Config file for collectd(1).
#
# Some plugins need additional configuration and are disabled by default.
# Please read collectd.conf(5) for details.
#
# You should also read /usr/share/doc/collectd-core/README.Debian.plugins
# before enabling any more plugins.

Hostname "graphite"
FQDNLookup true
#BaseDir "/var/lib/collectd"
#PluginDir "/usr/lib/collectd"
TypesDB "/usr/share/collectd/types.db" "/etc/collectd/my_types.db"
Interval 10
#Interval 60
#Timeout 2
#ReadThreads 5

LoadPlugin logfile
LoadPlugin cpu
LoadPlugin disk
LoadPlugin memory
LoadPlugin modbus  //тот самый плагин
LoadPlugin snmp
LoadPlugin write_graphite

#LoadPlugin email
#LoadPlugin sensors
#LoadPlugin serial

<Plugin logfile>
    LogLevel "info"
    File STDOUT
    Timestamp true
    PrintSeverity true
</Plugin>

<Plugin modbus>

#DC2 VRU Data -------------------------------------------------

 <Data "VRU-QF1-Status">
   RegisterBase 380
   RegisterType int16
   Type word
   Instance "VRU-QF1-Status"
 </Data>

 <Data "VRU-QF2-Status">
   RegisterBase 381
   RegisterType int16
   Type word
   Instance "VRU-QF2-Status"
 </Data>
…
 <Data "VRU1-U-AN">
   RegisterBase 300
   RegisterType int16
   Type voltage
   Instance "VRU1-U-AN"
 </Data>

 <Data "VRU1-U-BN">
   RegisterBase 301
   RegisterType int16
   Type voltage
   Instance "VRU1-U-BN"
 </Data>

 <Data "VRU1-U-CN">
   RegisterBase 302
   RegisterType int16
   Type voltage
   Instance "VRU1-U-CN"
 </Data>

 <Host "DC2_PLC">
   Address "XXX.XXX.XXX.XXX"
   Port    "502"
   Interval 5
   
   <Slave 1>
    Instance "Vars"
    Collect  "VRU-QF1-Status"
    Collect  "VRU-QF2-Status"
...
    Collect  "VRU1-U-AN"
    Collect  "VRU1-U-BN"
    Collect  "VRU1-U-CN"
...
   </Slave>
 </Host>

<Plugin snmp>
# DC2_Module1_UPS1 -------------------------------------------------
 <Data "UPS1_load_A">
  Type "percent"
  Table false
  Instance "Load_A"
  Values ".1.3.6.1.2.1.33.1.4.4.1.5.1"
 </Data>

 <Data "UPS1_load_B">
  Type "percent"
  Table false
  Instance "Load_B"
  Values ".1.3.6.1.2.1.33.1.4.4.1.5.2"
 </Data>

 <Data "UPS1_load_C">
  Type "percent"
  Table false
  Instance "Load_C"
  Values ".1.3.6.1.2.1.33.1.4.4.1.5.3"
 </Data>
...
 <Host "DC2_Module1_UPS1">
   Address "XXX.XXX.XXX.XXX"
   Version 1
   Community "public"
   Collect "UPS1_load_A"
   Collect "UPS1_load_B"
   Collect "UPS1_load_C"
...
   Interval 5
 </Host>

<Plugin write_graphite>
	<Carbon>
		Host "localhost"
#		Port "2003"
		Prefix "collectd."
		Protocol "tcp"
#		Postfix "collectd"
#		StoreRates false
#		AlwaysAppendDS false
#		EscapeCharacter "_"
	</Carbon>
</Plugin>

Include "/etc/collectd/collectd.conf.d/*.conf"


Дашборд главного ВРУ «Миран-2».


Дашборд с наиболее важными параметрами «Модуль-2».


Дашборд с климатическими трендами «Модуль-2».


Дашборд с трендами по потреблению стоек «Модуль-1».


Подводя итоги
Итак, текущие плюсы решения на collectd + graphite + grafana в сравнении с Trace Mode:
  • Бесплатно (финдир вытирает скупую мужскую слезу счастья).
  • Open Source. Можно теоретически добавить недостающую фичу, написав ее самому.
  • Доступность. По сути, это страничка в браузере для конечного пользователя, а, следовательно, есть у каждого в гаджете в кармане. В Trace Mode поддержки для гаджетов толком нет.
  • Простота и удобство расширения. Достаточно при первоначальной настройке collectd + graphite «скормить» им все необходимые данные — и последующие получившиеся метрики можно редактировать и преобразовывать на лету прямо в grafana. Скажем «Нет!» компиляциям МРВ и клиент-консолей в Trace Mode!
  • Очень неплохие возможности по отображению и анализу графиков «из коробки». Trace Mode в этом плане крайне, хм, консервативен.
  • Есть оповещения и уведомления об аварийных ситуациях во всех новомодных чатиках, по почте etc. Trace Mode же может рассылать E-mail`ы и за отдельную денежку — SMS (если у вас есть необходимое железо).

Минусы:
  • Полновесную SCADA подобной связкой не заменить. Никакого управления тех.процессом. Если, конечно, управление Вам необходимо.
  • Open Source. Ваш покорный слуга не имеет надлежащей квалификации для дописания хотелок, а посему смиренно ждет и/или просит более умных товарищей в git-сообществе.
  • Набор панелей невелик (хоть и расширяется за счет плагинов).
  • Движок алертинга пока очень прост, хитрых условий в нем не настроишь. Разработчики обещают расширить функционал.

Пока решено оставить систему мониторинга неким гибридом из классической SCADA Trace Mode со своими клиент-приложениями и серверами как скрытого от посторонних ядра с АСУ и АСМ и внешней обертки grafana с красивыми и удобными метриками, доступной всем внутри корпоративной сети. К чему в итоге мы придем — покажет время, разных инженерных задач еще хватает.

Инженерные системы наших дата-центров, часть 1

Введение в ЦОДоведение
Что есть центр обработки данных? Говорим «ЦОД» — представляем себе бескрайние ангары, заполненные бесчисленными рядами стоек с мерно гудящими железками. Железки загадочно перемигиваются разноцветными огоньками из полумрака. С лицевой стороны их обдувает прохладным бризом от промышленных кондиционеров. В холодных зонах можно наотличненько просквозить себе шею и простудиться. Поэтому админы всегда носят свитера.

Нашей компанией построены два отдельно стоящих дата-центра, бесхитростно именуемые «Миран-1» и «Миран-2». Первый представляет собой вполне привычный тип, с одним большим машинным залом и несколькими поменьше этажом выше. Второй ЦОД представляет из себя ангар, в котором на данный момент установлены два мобильных малых ЦОДа, а также строится третий. Мобильные ЦОДы — двухэтажные конструкции-контейнеры, первый этаж которых есть серверный зал со стойками и кондиционерами, он еще именуется серверным блоком, на втором же смонтированы ВРУ, установлены ИБП и различные щиты управления.

Так исторически сложилось, что «Миран-1» не имел единого мониторинга инженерной инфраструктуры (посыпаем голову пеплом) и мы стремимся исправить этот недостаток. Посему речь большей частью пойдет о втором дата-центре.

ТП, ВРУ, PDU
В «Миран-2» реализована система гарантированного электроснабжения (СГЭ). Как видно из схемы ниже, в обычных условиях дата-центр питается от двух независимых внешних вводов от ТП; в случае пропадания напряжения на внешних вводах (а такое у нас иногда случается) — питание идет от дизель-генераторной установки ДГУ2, фактически; под будущий задел предусмотрено место для еще двух.


Идем дальше. ВРУ выполнено двухсекционным с секционным выключателем под управлением АВР1. Контроллер АВР замкнет секционник в случае пропадания напряжения на одном или обоих вводах, в последнем случаем через 15 секунд будет дан сигнал на запуск ДГУ. Все эти неприятности «Модуль-1 и «Модуль-2» переживают на своих внутренних ИБП.


Основное назначение секций и их автоматов, помимо питания различных вспомогательных щитов освещения, управления вентиляцией и прочего — исполнять роль вводов электропитания для «Модуль-1» и «Модуль-2» (QF1.1-.2 и QF2.1-.2 на схеме, соответственно). Каждый модульный ЦОД имеет внутри себя свое собственное ВРУ.

Мнемосхема главного распределительного щита «Модуль-2»


Фото главного распределительного щита «Модуль-2».


Мнемосхема энергоблока «Модуль-1»


Мнемосхема стоек «Модуль-1»


Большая часть стоек в «Модуль-1» и «Модуль-2» — производителей Rittal и RiT. Из PDU используем: в «Модуль-1» — сборную солянку из Eurolan, APC, DELTA. «Модуль-2» — целиком на PDU фирмы RiT.

Окунись в прохладу ©
Все клиентское железо, а также инженерная инфраструктура в процессе своей работы выделяют много тепла. Это тепло необходимо отводить, иначе железо быстро умрет. Отводом у нас занимаются шесть инверторных фреоновых кондиционеров фирмы Daikin. Вся их деятельность гордо называется «фреоновым режимом», который обеспечивает сухой тропический прохладный климат от +15 до +23 С° в холодном коридоре. Данная система охлаждения применяется и в «Модуле-1», и в «Модуле-2».

Также в «Модуле-1» существует еще один режим охлаждения, «режим фрикулинга». Его должны обеспечивать четыре приточных установки и дюжина вытяжек. В теории. К сожалению, на практике отвод тепла таким образом был не слишком эффективным, если внутри было задействовано чуть больше половины стоек. Поэтому данный режим для первого модульного ЦОДа так и не используется, оставаясь, по сути, резервным.
Мнемосхема серверного блока «Модуль-1»


Мнемосхема серверного блока «Модуль-2». Никаких приточек, только хардкор! фреон!


От клеммного зажима до ПЛК
Опросом и агрегацией информации от всей периферии дата-центра «Миран-2» занимаются три ПЛК: по одному на «Модуль» и один общий. Эти вундержелезки носят имя небезызвестной компании WAGO.

Рассмотрим структуру системы опроса на основе решения для «Модуль-2».


Схема шины ПЛК с модулями, скриншот из WAGO-IO-Check


Фото щита диспетчеризации «Модуль-2».


Как видно из схемы, на шине установлен сам ПЛК серии 750-881, четыре дискретных модуля 750-1405 на 16 каналов каждый и один аналоговый модуль 750-455 на четыре канала. Через дискретные модули ПЛК получает данные о состоянии автоматических выключателей питания («сухие» дополнительные контакты) в обеих секциях ГРЩ, о состоянии автоматов в собственном щите, а также о состоянии вентиляции энергоблока. Посредством аналогового модуля — получает данные от двух датчиков температуры и влажности (4-20 мА) здесь же, внутри энергоблока.

ПЛК также оснащен двумя Ethernet-портами и через них он общается по Modbus TCP/IP с еще несколькими железяками, как то:
  • два вводных автомата фирмы Schneider Electric, от них же получается информация о входных мощностях, напряжениях, токах и прочем;
  • две системы измерения токов фирмы АВВ в тандеме с двумя модулями ввода от фирмы ОВЕН — результатом их совместного труда есть вычисление по-стоечной мощности;
  • контроллеры CAREL и 6 их подопечных — кондиционеры Daikin;
  • и, наконец, младший братик — каплер 750-342 c семью дискретными модулями. Их задача отслеживать состояние 48 выключателей + 12 резервных в серверном блоке на 24 стойки.

Фото ABB CMS-600 и трансформаторов тока.


Фото ОВЕН МЭ110-220.3М.


Фото ПЛК CAREL.


Фото щита слаботочных систем «Модуль-2».


Отдельно стоит упомянуть ИБП, они опрашиваются непосредственно SCADA, минуя ПЛК, по SNMP-протоколу.


Вся получаемая информация посредством программы формируется в собственный список Modbus-регистров, которая уже опрашивается SCADA.

Небольшой кусочек из основной программы
(* PLC_A2 *)
%QX256.0 := A2_1QF1;	//присваиваем каждому биту 256го слова
%QX256.1 := A2_1QF2;	//текущее состояние различных автоматов
%QX256.2 := A2_QS1;
%QX256.3 := A2_QS2;
%QX256.4 := A2_3QF1;
%QX256.5 := A2_3QF2;
%QX256.6 := A2_3QF3;
%QX256.7 := A2_3QF4;
%QX256.8 := A2_3QF5;
%QX256.9 := A2_3QF6;
%QX256.10 := A2_3QF7;
%QX256.11 := A2_3QF8;
%QX256.12 := A2_3QF9;
%QX256.13 := A2_3QF10;
%QX256.14 := A2_KM1;
%QX256.15 := A2_KM2;

(* QF1 *)   //вводной автоматический выключатель № 1
%QW332 := QF1_I_L1;    //токи по фазам
%QW333 := QF1_I_L2;
%QW334 := QF1_I_L3;
%QW335 := QF1_U_L12;   //линейные (межфазные) напряжения
%QW336 := QF1_U_L23;
%QW337 := QF1_U_L31;
%QW338 := QF1_U_L1;   //фазные (фаза-нуль) напряжения
%QW339 := QF1_U_L2;
%QW340 := QF1_U_L3;
%QW341 := QF1_P_L1;   //активная мощность по фазам
%QW342 := QF1_P_L2;
%QW343 := QF1_P_L3;
%QW344 := QF1_P_Sum;  //суммарная активная мощность (кВт)
%QW345 := QF1_Q_L1;   //реактивная мощность по фазам
%QW346 := QF1_Q_L2;
%QW347 := QF1_Q_L3;
%QW348 := QF1_Q_Sum;  //суммарная реактивная мощность (квар)
%QW349 := QF1_S_Sum;  //полная мощность (кВА)
%QW350 := QF1_CosF;   //коэффициент мощности


Еще один кусочек из другой подпрограммы
//Это работа кодогенератора CODESYS, в котором есть удобный настройщик связи
//с периферией по Modbus TCP/IP. Эта подпрограмма, в частности, отвечает 
//за получение от ОВЕН МЭ110-220.3М показаний 
//по трем напряжениям фаза-нейтраль

PROGRAM MBCFG_subCMS_1(* generated by config one prg for each slave *)

VAR_OUTPUT
U_L1  :  WORD; (**) 
U_L2  :  WORD; (**) 
U_L3  :  WORD; (**)

/*--- system variables (read only) ----------------------------------------*/
MBCFG_IpAddress    :   STRING(12) := 'XXX.XXX.XXX.XXX';//IP-адрес Slave-устройства
MBCFG_Port         :   UINT := 502;               //Порт, дефолтный
MBCFG_UnitID       :   BYTE := 2;                 //ID Slave-устройства
MBCFG_TimeOut      :   TIME := t#300ms;           //Таймаут на получение ответа
MBCFG_RequestDelay :   TIME := t#1000ms;          //Задержка до следующего опроса
MBCFG_Error        :   MBCFG_eERROR := MBCFG_START_UP;
MBCFG_LastJob      :   MBCFG_typCOM_JOB;
/*-------------------------------------------------------------------------*/
END_VAR

VAR CONSTANT
    zz_VARIABLECOUNT:   INT := 3; (* number of variables  *)
    zz_JOBCOUNT     :   INT := 1; (* number of jobs *)
END_VAR
VAR

/*=== VARIABLE LIST =============*/
zz_VariableList :   ARRAY[1..zz_VARIABLECOUNT] OF MBCFG_typVARIABLE :=
    ( DataType        := MBCFG_TYPE_WORD,  
      ByteOrder       := MBCFG_BYTE_ORDER_0,
      BitSize         := 16,
      ptVar           := 0,
      ReadJobIndex    := 1,
      ReadStartBitNo  := 0,
      WriteJobIndex   := 0,
      WriteStartBitNo := 0 ),
   (  DataType        := MBCFG_TYPE_WORD,
      ByteOrder       := MBCFG_BYTE_ORDER_0,
      BitSize         := 16,
      ptVar           := 0,
      ReadJobIndex    := 1,
      ReadStartBitNo  := 32,
      WriteJobIndex   := 0,
      WriteStartBitNo := 0 ),
   (  DataType        := MBCFG_TYPE_WORD,
      ByteOrder       := MBCFG_BYTE_ORDER_0,
      BitSize         := 16,
      ptVar           := 0,
      ReadJobIndex    := 1,
      ReadStartBitNo  := 64,
      WriteJobIndex   := 0,
      WriteStartBitNo := 0
   );

/*=== JOB LIST ==================*/
zz_JobList     :   ARRAY[1..zz_JOBCOUNT] OF MBCFG_typCOM_JOB :=
   (  Functioncode            := 3, //Номер функции, 0x03, Read Holding Registers
      ReadStartAddress        := 26,//Адрес первого регистра
      ReadQuantity            := 5, //Кол-во регистров, которые следует прочесть
      WriteStartAddress       := 0,
      WriteQuantity           := 0,
      ptReadData              := 0, 
      ptWriteData             := 0
   );

zz_DataField_1_Read       :       ARRAY[1..5] OF WORD;

/*=== MODBUS MASTER ==============*/
zz_MBCFG_MASTER_ETH :       MBCFG_MASTER_TCP;

END_VAR

/*--- for each variable -------------------------*/
   zz_VariableList[1].ptVar := ADR(U_L1);
   zz_VariableList[2].ptVar := ADR(U_L2);
   zz_VariableList[3].ptVar := ADR(U_L3);
/*-----------------------------------------------*/

/*--- for each job -----------------------------------*/
zz_JobList[1].ptReadData   := ADR(zz_DataField_1_Read);
/*----------------------------------------------------*/

/*#### START OF FIXED CODE #####################################*/
zz_MBCFG_MASTER_ETH(	strIpAddress    := MBCFG_IpAddress,
                        uiPort          := MBCFG_Port,
                        bUnitID         := MBCFG_UnitID,
                        tTimeOut        := MBCFG_TimeOut,
                        iVariableCount  := zz_VARIABLECOUNT,
                        ptVariableList  := ADR(zz_VariableList),
                        iJobCount       := zz_JOBCOUNT,
                        ptJobList       := ADR(zz_JobList),
                        tRequestDelay   := MBCFG_RequestDelay,
                        eError          => MBCFG_Error,
                        LastJob         => MBCFG_LastJob
                    );

%QW377 := U_L1;
%QW378 := U_L2;
%QW379 := U_L3;