Токовая направленная защита нулевой последовательности
Введение
В предыдущем связанном примере был представлен блок токовой направленной (ненаправленной) защиты нулевой последовательности (ТНЗНП). Для проверки его работы использовалось программное управление моделью.
В данном примере рассмотрено проведение автоматического тестирования комплекта из двух ступеней ТНЗНП. Для этого применяется та же модель энергосистемы, что и в предыдущем примере.
Описание модели энергосистемы
Схема и параметры энергосистемы представлены ниже:
Параметры энергосистемы С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 мкСм/км
Автоматическое тестирование релейной защиты
Для начала откроем модель и загрузим её для быстрого запуска:
example_path = @__DIR__; # Получаем абсолютный путь к директории, содержащей текущий скрипт
cd(example_path); # Переходим в директорию примера
model_name = "ground_directional_overcurrent_relay_autotest.engee"
engee.open(model_name); # Открываем модель
model = engee.load(model_name); # Загрузим модель для быстрого доступа
Вспомогательные функции
Для реализации автоматического тестирования предлагается обернуть код, использованный в примере реализации ТНЗНП, во вспомогательные функции, соединить их в основную функцию для тестирования и организовать цикл проверки защиты по всем точкам короткого замыкания.
Первым шагом создадим и опишем вспомогательные функции.
Ниже приведена функция для получения заданных в модели токовых уставок защит. Она необходима для контроля превышения уставок по току:
"""
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;
Перед запуском каждой симуляции необходимо убедиться, что все точки короткого замыкания в модели отключены, кроме требуемой. Для этого создаётся функция сброса, которая отключает переданные ей точки КЗ:
"""
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;
Опишем функцию для визуального анализа условий срабатывания комплекта защиты:
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;
Также нам пригодится функция, которая сигнализирует о превышение токовой уставки и проверяющая наличие сигнала на срабатывания от любой из ступеней:
"""
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 через параметры АУВ обернём данную логику в отдельную функцию:
"""
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;
Основная функция
Ниже представлена основная функция тестирования:
"""
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 минут.
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
Вы можете попробовать самостоятельно изменить цикл для автоматического тестирования комплекта ТЗНП на стороне С2. В подсказке находится цикл для тестирования второго комплекта
Подсказка
Ограничение
При тестировании второго комплекта выявляется ограничение разработанной функции.
В режиме короткого замыкания в точке К1 индикаторы срабатывания ТЗНП в коде не фиксируют работу защиты. Причина в том, что состояние первой ступени считывается в момент времени . В этот момент величина тока ниже уставки срабатывания.
После размыкания контактов выключателя на противоположенной стороне линии ток вырастает и первая ступень срабатывает раньше второй ступени.
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
Вывод
В данном примере было представлено автоматическое тестирование комплекта ТНЗНП. Вы можете использовать написанные функции для тестирования своего комплекта защиты.
На что обратить внимание при использование в своей модели:
-
Время переходного процесса в основной функции
-
Наименование параметров уставок в
get_trip_values() -
Наименование тока на графике в
plot_current() -
В
set_parallel_line()используются наименования АУВ В3 и В4 и уникальные настройки параметров АУВ. Для использования на нескольких линиях можете добавить в функцию передачу наименований АУВ и их параметров.
Вы можете в целом доработать использованные в примере функции под свои нужды. К примеру дополнить функцию check_trip() контролем направления мощности и времени срабатывания. Или создать функцию для проверки корректности срабатывания дистанционной защиты.
.png)