Программа для публикации GOOSE сообщений в соответствии со стандартом IEC61850-8-1.
- Проверка работы IED при приёме Goose-сообщений с различными параметрами
- Проведение Ping-Pong тестирования производительности Goose
- Управление при помощи скрипта на языке C#
- Доступ к любым полям Goose-сообщения
- Выбор типа и структуры данных для публикации
- Ручной или автоматический режим публикации
- Сохранение cid-файла для подписки на публикуемый Goose
- Windows 10 / 11
- Microsoft .NET Framework 4.8
- Сетевой драйвер Npcap
Note
Драйвер Npcap также устанавливается при установке последней версии Wireshark.
- Набрать код на языке C#, используя предопределённые классы для работы с Goose
- При нажатии на кнопку
Run Script
код будет скомпилирован и выполнен - В случае возникновения ошибки будет выведено соответствующее сообщение
- Для досрочного завершения выполнения скрипта нажать кнопку
Stop
Note
За основу скрипта можно взять один из примеров, поправив его под свои задачи.
Код из любого примера можно скопировать в редактор скриптов и запустить.
- Описание всех подддерживаемых функций
- Пример работы с типом Boolean
- Пример работы с численными типами Int и Float
- Пример работы с типом Dbpos (положение выключателя)
- Пример работы с типом Octet64
- Пример работы с типом Quality
- Публикация нескольких Goose одновременно
Для конфигурирования параметров Goose-сообщения потребуется объект класса GooseSettings
.
Данный объект содержит множество настроек, большинство из которых являются опциональными.
Все обязательные настройки приведены в коде ниже.
var settings = new GooseSettings() // Объект для хранения настроек
{
interface = "Ethernet",
gocbRef = "IED1SYS/LLN0$GO$GSE1", // Ссылка на блок управления Goose публикатора
datSet = "IED1SYS/LLN0$DataSet", // Ссылка на набор данных публикатора
goID = "MyGooseID"
};
var publisher = new GoosePublisher(settings); // Объект для публикации
Для публикации Goose-сообщений потребуется объект класса GoosePublisher
, который отвечает за работу с сетью.
В конструктор объекта GoosePublisher
следует передать объект типа GooseSettings
.
Публикуемый набор данных может содержать список атрибутов данных (DA) или объект данных (DO) целиком.
Структура набора данных задаётся на этапе конфигурирования при помощи параметров isStruct
и hasTimeStamp
.
Структура набора данных при settings.isStruct = true
DataSet
{
DataObject DO типа SPS / INS / DPS
{
DataAttribute - stVal DA типа MMS_TYPE
DataAttribute - q DA типа Quality
DataAttribute - t DA типа Timestamp
}
}
Структура набора данных при settings.isStruct = false
DataSet
{
DataAttribute - stVal DA типа MMS_TYPE
DataAttribute - q DA типа Quality
}
Структура набора данных при settings.isStruct = false
и settings.hasTimeStamp = true
DataSet
{
DataAttribute - stVal DA типа MMS_TYPE
DataAttribute - q DA типа Quality
DataAttribute - t DA типа Timestamp
}
Тип данных и начальное значение атрибута данных stVal
задаётся на этапе конфигурирования при помощи
параметров mmsType
и initVal
.
settings.mmsType = MMS_TYPE.INT32;
settings.initVal = 42;
При присваивании initVal
тип выражения должен соответствовать типу данных stVal
.
settings.mmsType = MMS_TYPE.INT32;
settings.initVal = false; // Ошибка 'MMS type mismatch'
// Значение 'false' типа bool не конвертируется в int
Все поддерживаемые типы данных приведены в таблице
MMS_TYPE | Тип C# | Пример |
---|---|---|
BOOLEAN | bool | true |
INT32 | int, uint | -42 |
INT32U | int, uint | 404 |
FLOAT32 | float, double | 3.14 |
BIT_STRING | string (bin) | "011010" |
OCTET_STRING | string (hex) | "c0ffee" |
Управление публикацией осуществляется с помощью объекта GoosePublisher
.
Предусмотрено два режима публикации: ручной и автоматический.
В ручном режиме публикации:
- Требуется вручную вызывать метод
Send()
- Требуется вручную устанавливать время жизни сообщений
TAL
- Требуется вручную задавать интервалы времени между публикациями сообщений
- Изменения в наборе данных не приводят к отправке сообщений
publisher.TAL = 1500; // Установка TimeAllowedToLive - 1500 мс
...
publisher.Send(); // Публикация одного сообщения
...
Timer.Sleep(500); // Ожидание 500 мс
...
publisher.SendFew(5, 200); // Публикация 5-и сообщений с интервалом 200 мс
Автоматический режим публикации запускается вызовом метода Run(minTime, maxTime)
.
В качестве параметров передаются минимальный и максимальный интервалы ретрансляции (мс).
В автоматическом режиме публикации:
- Время жизни сообщений, а также время отправки определяются автоматически
- Изменение свойств
Value
илиQuality
приводит к мгновенной отправке сообщения и уменьшению интервала между сообщениями до минимального.
Параметры автоматического режима ретрансляции сообщений соответствуют корпоративному профилю ФСК ЕЭС.
publisher.Run(10, 1000); // Запуск автоматического механизма публикации
while(true)
{
publisher.Value++; // Увеличение значения stVal
Timer.Sleep(5000); // каждые 5 секунд
}
С помощью свойства publisher.Value
можно в любой момент времени изменить значение stVal
.
Тип Value
определяется исходя из значения параметра settings.mmsType
.
В зависимости от типа данных для Value
допустимы различные операции.
Тип данных BOOLEAN
publisher.Value = true;
...
publisher.Value = false;
...
publisher.Value = !publisher.Value;
Типы данных INT32 | INT32U | FLOAT32
publisher.Value = 42;
...
publisher.Value++;
...
publisher.Value += 3.14;
Тип данных BIT_STRING
// Dbpos - тип данных для отображения состояния коммутационного аппарата
publisher.Value = Dbpos.Intermediate; // "00"
publisher.Value = Dbpos.Off // "01"
publisher.Value = Dbpos.On; // "10"
publisher.Value = Dbpos.BadState; // "11"
// Обобщенный тип bit-string
publisher.Value = "1_0101"; // bits: 5, padding: 3
publisher.Value = "01_0101"; // bits: 6, padding: 2
publisher.Value = "101_0101"; // bits: 7, padding: 1
publisher.Value = "0101_0101"; // bits: 8, padding: 0
publisher.Value = "1_0101_0101"; // bits: 9, padding: 7
publisher.Value = "01_0101_0101"; // bits: 10, padding: 6
Тип данных OCTET_STRING
publisher.Value = "DEAD_BEEF";
...
publisher.Value += "BAAD_FOOD";
Для изменения качества данных требуется свойству publisher.Quality
установить новое значение типа Quality
.
var q = new Quality()
{
Validity = Validity.Good, // Invalid | Reserved | Questionable
Overflow = true,
OutofRange = true,
BadReference = true,
Oscillatory = true,
Failure = true,
OldData = true,
Inconsistent = true,
Inaccurate = true,
Source = true,
Test = true,
OperatorBlocked = true
};
publisher.Quality = q; // Установка качества данных
...
publisher.Quality = new Quality() // Способ без дополнительной переменной
{
Validity = Validity.Questionable,
Failure = true,
Test = true
};
При каждом изменении данных счётчик stNum
увеличивается на 1, а счётчик sqNum
сбрасывается в 0.
При каждой ретрансляции сообщения без изменения данных счётчик sqNum
увеличивается на 1.
Кроме того, предусмотрено прямое управление счётчиками. Логика увеличения счётчиков при этом не отключается.
publisher.StNum = 42;
publisher.SqNum = 43;
Флаги режима симуляции можно задать независимо на этапе конфигурирования.
При публикации сообщений режим симуляции можно задать с помощью свойства Simulation
.
settings.simulation_reserved = true; // Бит симуляции в поле Reserved 1
settings.simulation_goosePdu = true; // Флаг симуляции в goosePdu
...
publisher.Run(100, 1000);
...
publisher.Simulation = false; // Оба флага выставляются одновременно
Подписаться на публикуемый Goose можно с помощью cid-файла публикатора и конфигуратора ICT, поставляемого производителем IED.
Для сохранения cid-файла требуется вызвать метод SaveSCL(iedName)
publisher.SaveSCL("IED1"); // Имя файла GooseScript.cid
...
publisher.SaveSCL("IED1", "myFile.cid"); // Имя файла myFile.cid
Сохранение файла произойдёт только в том случае, если значения gocbRef
и datSet
более менее корректны:
- Ссылки начинаются с имени IED, переданного в
SaveSCL(iedName)
первым аргументом - В качестве DO может использоваться только LLN0
Note
Файл конфигурации лишь примерно соответствует XSD схеме SCL и не подлежит валидации.
Полный списко параметров GooseSettings
приведён в таблице.
Параметр | Тип | Диапазон | Описание |
---|---|---|---|
interfaceName | string | Имя интерфейса для публикации | |
dstMac | uint16 | 0 - 3FF | Последние два байта MAC-адреса назначения |
hasVlan | bool | Добавление VLAN тэга к сообщению | |
vlanID | uint16 | 0 - FFF | Идентификатор VLAN |
appID | uint16 | 0 - FFFF | Идентификатор приложения |
simulation_reserved | bool | Бит симуляции в поле Reserved 1 | |
gocbRef | string | Ссылка на блок управления публикатора | |
TAL | uint32 | Время жизни сообщения в миллисекундах | |
datSet | string | Ссылка на набор данных публикатора | |
goID | string | Идентификатор Goose-сообщения | |
simulation_goosePdu | bool | Флаг симуляции в goosePdu | |
confRev | uint32 | Номер ревизии DataSet | |
ndsCom | bool | Флаг незавершенного конфигурирования | |
mmsType | MMS_TYPE | Тип данных атрибута stVal набора данных | |
initVal | dynamic | Начальное значение stVal | |
isStruct | bool | Весь DO добавляется в набор данных | |
hasTimeStamp | bool | Добавление TimeStamp в набор данных |
Ctrl + X
- удаление текущей строкиCtrl + MouseWheel
- изменение масштаба текста- При закрытии программы скрипт сохраняется в файл
GooseScript.cs
- При удаленни всего текста из окна редактора после перезапуска будет восстановлен скрипт по умолчанию
Сборка производтся с помощью Microsoft Visual Studio Community.
- Клонировать проект
- Скачать пакет NuGet
SharpPcap
- Собрать Release
- Для получения одного исполняемого файла можно использовать утилиту
ilMerge
.\ILMerge /target:winexe /out:Out.exe ^
GooseScript.exe ^
PacketDotNet.dll ^
SharpPcap.dll ^
System.Buffers.dll ^
System.Memory.dll ^
System.Numerics.Vectors.dll ^
System.Runtime.CompilerServices.Unsafe.dll ^
System.Text.Encoding.CodePages.dll
del /q GooseScript.exe
del /q Out.pdb
ren Out.exe GooseScript.exe