Документация Engee
Notebook

Токовая направленная защита нулевой последовательности

Введение

В предыдущем связанном примере был представлен блок токовой направленной (ненаправленной) защиты нулевой последовательности (ТНЗНП). Для проверки его работы использовалось программное управление моделью.

В данном примере рассмотрено проведение автоматического тестирования комплекта из двух ступеней ТНЗНП. Для этого применяется та же модель энергосистемы, что и в предыдущем примере.

Описание модели энергосистемы

Схема и параметры энергосистемы представлены ниже:

image.png

Параметры энергосистемы С1:
Активное сопротивление прямой последовательности– 0,393 Ом
Индуктивное сопротивление прямой последовательности – 4,276 Ом
Активное сопротивление нулевой последовательности – 0,494 Ом
Индуктивное сопротивление нулевой последовательности – 4,02 Ом
Эквивалентная ЭДС– 230 кВ
Фазовый угол ЭДС– 10°

Параметры энергосистемы С2:
Активное сопротивление прямой последовательности– 4,85 Ом
Индуктивное сопротивление прямой последовательности – 25,604 Ом
Активное сопротивление нулевой последовательности – 10,607 Ом
Индуктивное сопротивление нулевой последовательности – 53,347 Ом
Эквивалентная ЭДС– 220 кВ
Фазовый угол ЭДС– 0°

Параметры линий Л1 и Л2:
Длина 100 км
Удельное сопротивление линии прямой последовательности 0,0958 + j 0,4038 Ом/км
Удельное сопротивление линии нулевой последовательности 0,3471+ j 1,2432Ом/км
Удельная емкость прямой последовательности 2,642 мкСм/км
Удельная емкость нулевой последовательности 2,119 мкСм/км

Автоматическое тестирование релейной защиты

Для начала откроем модель и загрузим её для быстрого запуска:

In [ ]:
example_path = @__DIR__; # Получаем абсолютный путь к директории, содержащей текущий скрипт
cd(example_path); # Переходим в директорию примера

model_name = "ground_directional_overcurrent_relay_autotest.engee"
engee.open(model_name); # Открываем модель
model = engee.load(model_name); # Загрузим модель для быстрого доступа

Вспомогательные функции

Для реализации автоматического тестирования предлагается обернуть код, использованный в примере реализации ТНЗНП, во вспомогательные функции, соединить их в основную функцию для тестирования и организовать цикл проверки защиты по всем точкам короткого замыкания.

Первым шагом создадим и опишем вспомогательные функции.

Ниже приведена функция для получения заданных в модели токовых уставок защит. Она необходима для контроля превышения уставок по току:

In [ ]:
"""
    get_trip_values(path, protections...)

Вспомогательная функция для получения токовых уставок и времени срабатывания защит.

# Аргументы
- `path::String`: путь к модели
- `protections::Vararg{String}`: список наименований защит

# Возвращает
Кортеж кортежей `(I_trip::Float64, t_trip::Float64)` для каждой переданной защиты.
"""
function get_trip_values(path::String, protections::Vararg{String})
    # Внутри списка [] итеративно перебираются переданные защиты и запрашивает параметр I_trip и t_trip
    trip_list = [(parse(Float64, engee.get_param(path * "/" * protection, "I_trip")),
                parse(Float64, engee.get_param(path * "/" * protection, "t_trip")))
                for protection in protections]
    return tuple(trip_list...)
end;

Перед запуском каждой симуляции необходимо убедиться, что все точки короткого замыкания в модели отключены, кроме требуемой. Для этого создаётся функция сброса, которая отключает переданные ей точки КЗ:

In [ ]:
"""
    reset_sc(sc_locations)

Вспомогательная функция для отключения всех заданных точек короткого замыкания (КЗ).

# Аргументы
- `sc_locations::AbstractVector{String}`: список имён (путей) точек КЗ в модели.

# Поведение
Для каждой точки КЗ параметр `"temporal"` сбрасывается в `false`, что эквивалентно её отключению.
"""
function reset_sc(sc_locations::AbstractVector{String})
    # Проходимся по всем точкам КЗ и отключаем их
    for sc_loc in sc_locations
        engee.set_param!(engee.gcm().name * "/" * sc_loc, "temporal" => false)
    end
end;

Опишем функцию для визуального анализа условий срабатывания комплекта защиты:

In [ ]:
using Plots
"""
    plot_current(t, I; protections...)

Вспомогательная функция для построения графика тока с отметками токовых уставок.

# Аргументы
- `t::AbstractVector{<:Number}`: вектор времени.
- `I::AbstractVector{<:Number}`: вектор значений тока.
- `protections::Vararg{Tuple}`: любое количество кортежей вида `(value, label)`, где:
    - `value::Number` — значение токовой уставки,
    - `label::String` — подпись линии (наименование ступени).

# Поведение
- Строит график тока `I` в А от времени `t` в с.  
- Добавляет горизонтальные линии для каждой переданной ступени защиты.

# Пример
plot_current(t, I, (530, "1-я ступень"), (260, "2-я ступень"))
"""
function plot_current(t::AbstractVector, I::AbstractVector, protections...)
    # Строим основной график
    gr()
    fig = plot(
    t, I,
    label="3I0",
    xlabel="t, c",
    ylabel="I, А",
    title="График тока",
    color=:blue
    )

    # Добавляем горизонтальные линии токовых уставок
    for protection in protections
        value, label = protection
        hline!(fig, [value], label=label, linestyle=:dash)
    end

    display(fig) # Функция сразу отображает график
end;

Также нам пригодится функция, которая сигнализирует о превышение токовой уставки и проверяющая наличие сигнала на срабатывания от любой из ступеней:

In [ ]:
"""
    check_trip(I_sc, protections...)

Вспомогательная функция для проверки срабатывания защиты.

# Аргументы
- `I_sc::Number`: ток короткого замыкания.
- `protections::Vararg{Tuple{Number,Bool}}`: любое количество кортежей `(I_trip, signal)`, где:
    - `I_trip::Number` — ток уставки для ступени защиты,
    - `signal::Bool` — сигнал срабатывания ступени.

# Возвращает
- `trip_status::Bool` — `true`, если сработал хотя бы один сигнал защиты.  
- `trip_correct::Bool` — `true`, если хотя бы одна уставка была превышена током `I_sc`.

# Пример
check_trip(100, (120, false), (80, true))
(true, true)
"""
function check_trip(I_sc::Number, protections::Vararg{Tuple{Number,Bool}})
    trip_status = any(protection -> protection[2], protections) # Проверка хотя бы одного сигнала на срабатывание
    trip_correct = any(protection -> I_sc >= protection[1], protections) # Проверка превышения хотя бы одной уставки
    return trip_status, trip_correct
end;

Тестирование проводится для комплекта защит на линии Л-1. Управление линией Л-2 осуществляется через блоки автоматики управления выключателями (АУВ) В3 и В4. Эти блоки позволяют моделировать действие релейной защиты на Л-2, отключая её с заданной выдержкой времени.

Кроме того, с помощью АУВ можно:

  • сразу подать команду на отключение Л-2 (сценарий с отключенной параллельной линией);

  • задать такие параметры, при которых Л-2 останется включённой на всём протяжении симуляции.

Для удобства управления Л-2 через параметры АУВ обернём данную логику в отдельную функцию:

In [ ]:
"""
    set_parallel_line(path, paral_line_status; t_sc=0.0)

Изменяет параметры параллельной линии (Л-2) в модели в зависимости от её состояния в моделируемом режиме.

# Аргументы
- `path::String` — путь к модели.
- `paral_line_status::String` — статус линии, возможные значения:
    - `"on"` — линия включена.
    - `"off"` — линия отключена.
    - `"SC"` — на линии короткое замыкание.
- `t_sc::Float64` (по умолчанию `0.0`) — время возникновения КЗ на линии (используется только при `"SC"`).

# Поведение
- `"on"` — устанавливает стартовый таймер АУВ В3 и В4 в 10.0 с (заведомо больший интервала симуляции).
- `"off"` — задаёт параметры так, что АУВ сразу подают команду на отключение с нулевыми задержками.
- `"SC"` — задаёт параметры для селективного отключения повреждённой линии, включая `t_start`, `t_trip`, `cb_delay` и др.
"""
function set_parallel_line(path::String, paral_line_status::String; t_sc::Float64=0.5)
    if paral_line_status == "on" # Линия Л-2 включена, время КЗ значительно выше интервала моделирования
        engee.set_param!(path * "/АУВ В3", "t_start" => 10.0)
        engee.set_param!(path * "/АУВ В4", "t_start" => 10.0)
    
    elseif paral_line_status == "off"  # Линия Л-2 отключена, нулевые параметры
        engee.set_param!(path * "/АУВ В3",
            "t_start" => 0.0,
            "t_trip" => 0.0,
            "cb_delay" => 0.0,
            "off_duration" => 0.0,
            "success_reclose" => "Неуспешное")
        engee.set_param!(path * "/АУВ В4",
            "t_start" => 0.0,
            "t_trip" => 0.0,
            "cb_delay" => 0.0,
            "off_duration" => 0.0,
            "success_reclose" => "Неуспешное")
    
    elseif paral_line_status == "SC"  # На линии Л-2 короткое замыкание, можно изменить параметры под тип КЗ
        engee.set_param!(path * "/АУВ В3",
            "t_start" => t_sc,
            "t_trip" => 0.4,
            "cb_delay" => 0.07,
            "off_duration" => 1.0,
            "success_reclose" => "Неуспешное")
        engee.set_param!(path * "/АУВ В4",
            "t_start" => t_sc,
            "t_trip" => 0.06,
            "cb_delay" => 0.07,
            "off_duration" => 1.4,
            "success_reclose" => "Неуспешное")
    else # Добавлено напоминание допустимых значений 
        error("Неверный параметр paral_line_status: $paral_line_status. Допустимые значения: \"on\", \"off\", \"SC\".")
    end
end;

Основная функция

Ниже представлена основная функция тестирования:

In [ ]:
"""
    run_protection_sim(t_sc, protections...; current_signal_name="|3I0_1|", fault_location="К2", fault_type="Single-phase to ground (a-g)", paral_line_status="on")

Основная функция моделирования и проверки защиты.

# Аргументы
- `t_sc::Float64` — момент возникновения КЗ на линии, в секундах.
- `protections::Vararg{String}` — любое количество наименований защит для проверки.
- `current_signal_name="|3I0_1|"` — наименования контролируемого параметра, в данном примере тока 3I0
- `fault_location::String="К2"` — место КЗ в модели.
- `fault_type::String="Single-phase to ground (a-g)"` — тип КЗ.
- `paral_line_status::String="on"` — статус параллельной линии (см. `set_parallel_line`).

# Поведение
1. Настраивает параметры КЗ в модели.  
2. Изменяет состояние параллельной линии с помощью `set_parallel_line`.  
3. Запускает моделирование модели через `engee.run`.  
4. Получает токовые уставки всех переданных защит через `get_trip_values`.  
5. Определяет момент КЗ и ток КЗ, проверяет срабатывание защиты через `check_trip`.  
6. Выводит результаты в консоль.  
7. Строит график тока с горизонтальными линиями уставок через `plot_current`.
"""
function run_protection_sim(t_sc::Float64, protections::Vararg{String};
                            current_signal_name = "|3I0_1|",
                            fault_location::String = "К2",
                            fault_type::String = "Single-phase to ground (a-g)",
                            paral_line_status::String = "on")
    println("Изменение параметров модели...")
    path = engee.gcm().name

    # Настройка КЗ
    engee.set_param!(path * "/" * fault_location,
                    "temporal" => true,
                    "start_time" => Dict("value" => t_sc, "unit" => "s"),
                    "duration" => Dict("value" => 10.0, "unit" => "s"),
                    "type" => fault_type)

    # Изменение статуса линии Л-2
    set_parallel_line(path, paral_line_status; t_sc=t_sc) # Функция отредактируем параметры линии под заданный режим
    
    println("Параметры изменены. Начало симуляции модели...")
    
    # Запуск моделирования и сохранение результатов
    results = engee.run(path)
    println("Моделирование завершено
            ")

    # Получаем токовые уставки и время срабатывания всех переданных защит
    trip_info = get_trip_values(path, protections...)  # кортежи (I_trip, t_trip)

    # Получаем переходный процесс. Важно указать корректный замер тока, при изменение наименования сигнала или смене комплекта защиты!
    I0 = results[current_signal_name].value
    t = results[current_signal_name].time

    # Определяем момент КЗ
    # За время 0.07 секунд с момента КЗ линия не успевает отключиться из-за задержки отключения выключателей.
    # При этом переходный процесс в следствии КЗ близок к завершению
    index_sc = findfirst(t .>= t_sc + 0.07) # Функция возвращает индекс первого элемента удовлетворяющего условию
    I_sc = I0[index_sc]

    # Получаем сигналы срабатывания всех защит с учётом их t_trip
    signals = Bool[] # В списке будем хранить статусы срабатывания ступеней
    for i in 1:length(protections)
        I_trip, t_trip = trip_info[i] # Считываем информацию по каждой ступени
        # Определяем момент срабатывания данной ступени с учётом момента КЗ
        t_trip_moment = t_sc + t_trip + 0.02  # добавляем минимальную задержку
        index_trip = findfirst(t .>= t_trip_moment)
        push!(signals, results[protections[i] * ".Сраб"].value[index_trip])
    end

    # Проверяем срабатывание и корректность для всех переданных ступеней
    trip_status, trip_correct = check_trip(I_sc, [(trip_info[i][1], signals[i]) for i in 1:length(protections)]...)

    # Вывод результатов
    for i in 1:length(protections)
        println("""Уставка $(protections[i]): $(trip_info[i][1]) А, t_trip = $(trip_info[i][2]) с, сигнал срабатывания: $(signals[i])""")
    end
    println("""
    Величина тока КЗ: $(round(I_sc, digits=2)) А
    Превышение токовой уставки: $trip_correct
    Срабатывание защиты: $trip_status
    """)

    # Построение графика
    println("Построение графика...")
    # Формируем линии токовых уставок для графика
    lines_for_plot = [(trip_info[i][1], protections[i]) for i in 1:length(protections)]
    # Строим график
    plot_current(t, I0, lines_for_plot...)
end;

Цикл тестирования

Код ниже запускает цикл тестирования комплекта ТНЗНП на стороне С1 по всем точкам КЗ.

Внимание! Выполнение кода занимает около 10-12 минут.

In [ ]:
path = engee.gcm().name
sc_locations = ["К1", "К2", "К3", "К4", "К5", "К6"]
paral_line_status = ["on", "on", "off", "on", "on", "SC"] # Состояние параллельной линии
mode_decription = ["Срабатывание", "Срабатывание", "Срабатывание", # Краткое описание ожидаемого действия РЗ
"Несрабатывание - КЗ за спиной", "Срабатывание", "Несрабатывание - КЗ на Л-2"]

protection_first_stage = "С1: ТНЗНП 1ст Л1"
protection_second_stage = "С1: ТНЗНП 2ст Л1"

for (i, sc_loc) in enumerate(sc_locations)
    println("""---Моделирование КЗ в точке $sc_loc---
    Ожидаемый результат работы комплекта защиты: $(mode_decription[i])
    Статус линии Л-2: $(paral_line_status[i])
    """)
    
    # Сброс всех точек КЗ
    reset_sc(sc_locations)

    # Запуск моделирования для точки КЗ sc_loc и статуса линии
    run_protection_sim(0.5, protection_first_stage, protection_second_stage,
                        current_signal_name = "|3I0_1|",
                        fault_location=sc_loc,
                        paral_line_status=paral_line_status[i])
    # sleep(10) # Расокментируйте, если не успевает отобразиться график
end
---Моделирование КЗ в точке К1---
Ожидаемый результат работы комплекта защиты: Срабатывание
Статус линии Л-2: on

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
Уставка С1: ТНЗНП 1ст Л1: 1876.1 А, t_trip = 0.06 с, сигнал срабатывания: true
Уставка С1: ТНЗНП 2ст Л1: 979.35 А, t_trip = 0.4 с, сигнал срабатывания: false
Величина тока КЗ: 31975.09 А
Превышение токовой уставки: true
Срабатывание защиты: true

Построение графика...
No description has been provided for this image
---Моделирование КЗ в точке К2---
Ожидаемый результат работы комплекта защиты: Срабатывание
Статус линии Л-2: on

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
Уставка С1: ТНЗНП 1ст Л1: 1876.1 А, t_trip = 0.06 с, сигнал срабатывания: false
Уставка С1: ТНЗНП 2ст Л1: 979.35 А, t_trip = 0.4 с, сигнал срабатывания: false
Величина тока КЗ: 762.91 А
Превышение токовой уставки: false
Срабатывание защиты: false

Построение графика...
No description has been provided for this image
---Моделирование КЗ в точке К5---
Ожидаемый результат работы комплекта защиты: Срабатывание
Статус линии Л-2: on

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
Уставка С1: ТНЗНП 1ст Л1: 1876.1 А, t_trip = 0.06 с, сигнал срабатывания: false
Уставка С1: ТНЗНП 2ст Л1: 979.35 А, t_trip = 0.4 с, сигнал срабатывания: false
Величина тока КЗ: 5.5886153192698e11 А
Превышение токовой уставки: true
Срабатывание защиты: false

Построение графика...
No description has been provided for this image
---Моделирование КЗ в точке К6---
Ожидаемый результат работы комплекта защиты: Несрабатывание - КЗ на Л-2
Статус линии Л-2: SC

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
AssertionError: I[1] == Colon() && length(I) == 1

Stacktrace:
 [1] getindex(x::WorkspaceArray{Float64}, I::Nothing)
   @ WorkspaceArrays.Arrays /usr/local/ijulia-core/packages/WorkspaceArrays/0C8OV/src/Arrays.jl:309
 [2] run_protection_sim(::Float64, ::String, ::Vararg{String}; current_signal_name::String, fault_location::String, fault_type::String, paral_line_status::String)
   @ Main ./In[7]:59
 [3] top-level scope
   @ ./In[20]:20

Вы можете попробовать самостоятельно изменить цикл для автоматического тестирования комплекта ТЗНП на стороне С2. В подсказке находится цикл для тестирования второго комплекта

Подсказка

Ограничение

При тестировании второго комплекта выявляется ограничение разработанной функции.

В режиме короткого замыкания в точке К1 индикаторы срабатывания ТЗНП в коде не фиксируют работу защиты. Причина в том, что состояние первой ступени считывается в момент времени . В этот момент величина тока ниже уставки срабатывания.

После размыкания контактов выключателя на противоположенной стороне линии ток вырастает и первая ступень срабатывает раньше второй ступени.

In [ ]:
path = engee.gcm().name
sc_locations = ["К1", "К2", "К3", "К4", "К5", "К6"]
paral_line_status = ["off", "on", "off", "on", "on", "SC"]
mode_decription = ["Срабатывание", "Срабатывание", "Срабатывание", # Для защиты С2 КЗ за спиной - точка К5
"Срабатывание", "Несрабатывание - КЗ за спиной", "Несрабатывание - КЗ на Л-2"]

# Изменяется наименование тестируемой защиты
protection_first_stage = "С2: ТНЗНП 1ст Л1"
protection_second_stage = "С2: ТНЗНП 2ст Л1"

for (i, sc_loc) in enumerate(sc_locations)
    println("""---Моделирование КЗ в точке $sc_loc---
    Ожидаемый результат работы комплекта защиты: $(mode_decription[i])
    Статус линии Л-2: $(paral_line_status[i])
    """)
    
    # Сброс всех точек КЗ
    reset_sc(sc_locations)

    # Запуск моделирования для точки КЗ sc_loc и статуса линии
    run_protection_sim(0.5, protection_first_stage, protection_second_stage,
                        current_signal_name = "|3I0_2|", # еняем измерительтока для защиты на стороне С2
                        fault_location=sc_loc,
                        paral_line_status=paral_line_status[i])
end
---Моделирование КЗ в точке К1---
Ожидаемый результат работы комплекта защиты: Срабатывание
Статус линии Л-2: off

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
Уставка С2: ТНЗНП 1ст Л1: 865.5 А, t_trip = 0.06 с, сигнал срабатывания: false
Уставка С2: ТНЗНП 2ст Л1: 465.0 А, t_trip = 0.4 с, сигнал срабатывания: false
Величина тока КЗ: 715.79 А
Превышение токовой уставки: true
Срабатывание защиты: false

Построение графика...
---Моделирование КЗ в точке К2---
Ожидаемый результат работы комплекта защиты: Срабатывание
Статус линии Л-2: on

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
Уставка С2: ТНЗНП 1ст Л1: 865.5 А, t_trip = 0.06 с, сигнал срабатывания: true
Уставка С2: ТНЗНП 2ст Л1: 465.0 А, t_trip = 0.4 с, сигнал срабатывания: false
Величина тока КЗ: 5399.47 А
Превышение токовой уставки: true
Срабатывание защиты: true

Построение графика...
---Моделирование КЗ в точке К3---
Ожидаемый результат работы комплекта защиты: Срабатывание
Статус линии Л-2: off

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
Уставка С2: ТНЗНП 1ст Л1: 865.5 А, t_trip = 0.06 с, сигнал срабатывания: true
Уставка С2: ТНЗНП 2ст Л1: 465.0 А, t_trip = 0.4 с, сигнал срабатывания: false
Величина тока КЗ: 1884.48 А
Превышение токовой уставки: true
Срабатывание защиты: true

Построение графика...
---Моделирование КЗ в точке К4---
Ожидаемый результат работы комплекта защиты: Срабатывание
Статус линии Л-2: on

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
Уставка С2: ТНЗНП 1ст Л1: 865.5 А, t_trip = 0.06 с, сигнал срабатывания: false
Уставка С2: ТНЗНП 2ст Л1: 465.0 А, t_trip = 0.4 с, сигнал срабатывания: true
Величина тока КЗ: 558.09 А
Превышение токовой уставки: true
Срабатывание защиты: true

Построение графика...
---Моделирование КЗ в точке К5---
Ожидаемый результат работы комплекта защиты: Несрабатывание - КЗ за спиной
Статус линии Л-2: on

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
Уставка С2: ТНЗНП 1ст Л1: 865.5 А, t_trip = 0.06 с, сигнал срабатывания: false
Уставка С2: ТНЗНП 2ст Л1: 465.0 А, t_trip = 0.4 с, сигнал срабатывания: false
Величина тока КЗ: 1523.31 А
Превышение токовой уставки: true
Срабатывание защиты: false

Построение графика...
---Моделирование КЗ в точке К6---
Ожидаемый результат работы комплекта защиты: Несрабатывание - КЗ на Л-2
Статус линии Л-2: SC

Изменение параметров модели...
Параметры изменены. Начало симуляции модели...
Моделирование завершено
            
Уставка С2: ТНЗНП 1ст Л1: 865.5 А, t_trip = 0.06 с, сигнал срабатывания: false
Уставка С2: ТНЗНП 2ст Л1: 465.0 А, t_trip = 0.4 с, сигнал срабатывания: false
Величина тока КЗ: 94.68 А
Превышение токовой уставки: false
Срабатывание защиты: false

Построение графика...

Вывод

В данном примере было представлено автоматическое тестирование комплекта ТНЗНП. Вы можете использовать написанные функции для тестирования своего комплекта защиты.

На что обратить внимание при использование в своей модели:

  • Время переходного процесса в основной функции

  • Наименование параметров уставок в get_trip_values()

  • Наименование тока на графике в plot_current()

  • В set_parallel_line() используются наименования АУВ В3 и В4 и уникальные настройки параметров АУВ. Для использования на нескольких линиях можете добавить в функцию передачу наименований АУВ и их параметров.

Вы можете в целом доработать использованные в примере функции под свои нужды. К примеру дополнить функцию check_trip() контролем направления мощности и времени срабатывания. Или создать функцию для проверки корректности срабатывания дистанционной защиты.