Изучаем возможность передачи структур в GOOSE-сообщении
Напомним, Functional Constraint указывает какие сервисы могут быть использованы для доступа к тем или иным данным. Один из наиболее широко используемых в практике передачи GOOSE-сообщений FC=ST (то есть Status). ST — это данные, полученные от процесса. То есть они не могут быть изменены, скажем, оператором, или каким-то образом сконфигурированы. Те, кто хотя бы раз сталкивался с наладкой РЗА с GOOSE, обязательно видели данные с FC=ST, так как к этой группе относятся все данные, касающиеся пуска и срабатывания защиты, положения коммутационных аппаратов, словом, всего того, что надо для наладки РЗА. Впрочем, мало кто придаёт этим FC должное значение… А зря.
На простом примере покажем пользу от FC. Предположим, что мы хотим собрать в наборе данных все атрибуты сигнала срабатывания защиты: собственно, сам факт срабатывания, флаг качества и метку времени: general, q, t. Решая задачу «в лоб» мы создадим набор данных из 3 элементов:
<DataSet name="TESTINGDATA">
<FCDA ldInst="LD" prefix="" lnClass="PTOC" lnInst="1" doName="Op" daName="general" fc="ST" />
<FCDA ldInst="LD" prefix="" lnClass="PTOC" lnInst="1" doName="Op" daName="q" fc="ST" />
<FCDA ldInst="LD" prefix="" lnClass="PTOC" lnInst="1" doName="Op" daName="t" fc="ST" />
</DataSet>
Окей, гугл. Запись примитивная: есть логическое устройство LD, в нём логический узел PTOC, в нём — объект данных Op, у которого есть три атрибута. Возникает вопрос, зачем здесь fc? Да на самом деле и незачем. Просто по схеме SCL обязательно должен присутствовать этот атрибут, так что он обязательно включается. Вопрос, а можно ли как-то изменить эту запись? Оказывается можно. Её можно сократить до одной строки:
<DataSet name="TESTINGDATA">
<FCDA ldInst="LD" prefix="" lnClass="PTOC" lnInst="1" doName="Op" fc="ST"/>
</DataSet>
Что изменилось? Исчезло указание в явном виде на атрибут данных da. Теперь вместо этого будет использоваться fc. Буквально эта запись означает, что в набор данных должны войти все данные объекта Op, имеющие fc=”ST”, то есть в данном случае опять те же general, q, t.
Является ли такая запись правильной? Да.
Изменится ли посылка GOOSE-сообщения при передаче такого набора данных? Давайте смотреть.
В качестве первого подопытного мы выбрали SIPROTEC 7SJ801. Опустим длинный рассказ по созданию станции, GOOSE Application и сразу перейдём к делу. Мы создадим 2 GOOSE-сообщения, соответственно, с двумя наборами данных, которые будут включать одни и те же данные.
В отличие от примера записи выше мы создали наборы, включающие другие данные. На результаты эксперимента, на самом деле, это не влияет. Просто нам так было удобнее.
Сначала реализуем первый пример: указываем все атрибуты в явном виде. DIGSI по-умолчанию делает именно так. При этом если нажать на поле FC/DA mapping (выделено синим), то нам открывается окно, в котором мы можем выбрать необходимые нам атрибуты.
Приведенной картинке соответствует следующая запись набора данных (Private-элементы намеренно удалены):
<DataSet name="DataSet">
<FCDA ldInst="CTRL" prefix="button" lnClass="GGIO" lnInst="1" doName="SPCSO9" fc="ST" daName="stVal"/>
<FCDA ldInst="CTRL" prefix="button" lnClass="GGIO" lnInst="1" doName="SPCSO9" fc="ST" daName="q"/>
<FCDA ldInst="CTRL" prefix="button" lnClass="GGIO" lnInst="1" doName="SPCSO9" fc="ST" daName="t"/>
</DataSet>
Несложно видеть, что приведенная запись аналогично рассмотренному в самом начале набору данных.
Теперь создадим второй тип набора данных, собранный по функциональным ограничениям. Очевидно, что создать его достаточно просто: надо убрать “галочки” у конкретных атрибутов и поставить её непосредственно перед FC:
Содержание такого набора данных будет отображаться следующим образом:
Кажется, задача решена. Убедимся в этом, заглянув в SCL-файл:
<DataSet name="FCD">
<FCDA ldInst="CTRL" prefix="button" lnClass="GGIO" lnInst="1" doName="SPCSO9" fc="ST"/>
</DataSet>
Ура, то, что надо!
Тут самое время отметить тот факт, что описанная тут последовательность (то есть убрать “галочки” с атрибутов и поставить их на FC) срабатывает не во всех версиях DIGSI. Так, по моим наблюдениям, в версии 4.87 она не работала. Хотя вручную её тоже можно было сделать – для этого надо было отредактировать самостоятельно файл станции и импортировать его в DIGISI.
Загружаем конфигурацию в SIPROTEC, в Wireshark смотрим что получилось. Вот наше первое GOOSE-сообщение:
Всё ожидаемо: булевый stVal, битстриговый q и UTC – t. HEX для кусочка DATA прилагается.
Смотрим что мы имеем в GOOSE-сообщений, в котором передается Dataset, собранный по FC.
Совсем невооруженный взгляд может не заметить отличий. Чуть более вооруженный сразу же увидит, что внутри Data передаётся не последовательность элементов, а элемент Structure, который, в свою очередь, содержит последовательность из stVal, q, t. Кроме того, обращает на себя внимание тот факт, что в отличие от предыдущего случая количество элементов в передаваемом наборе данных (Number Dataset Entries) в данном случае указано равным 1, а не 3, как в предыдущем.
Безусловно, для приложений с нормальным BER-декодером ни тот, ни другой вариант, не будут представлять особых сложностей в декодировании и интерпретации. Однако, эта особенность таит в себе несколько подводных камней, потенциально ведущих к проблемам при выполнении конкретных проектов, в частности, к проблемам функциональной совместимости.