Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions ARIEC61850.sln
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AR.Iec61850.Cli", "apps\AR.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AR.Iec61850.SvPublisher", "apps\AR.Iec61850.SvPublisher\AR.Iec61850.SvPublisher.csproj", "{49560545-7AA9-44AC-8196-9D6D98241B04}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AR.Iec61850.VirtualRelayLab", "apps\AR.Iec61850.VirtualRelayLab\AR.Iec61850.VirtualRelayLab.csproj", "{4F02C69F-8B2D-4F9E-9A2B-1F5E7A3C6D41}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AR.Iec61850.IedDiscovery", "apps\AR.Iec61850.IedDiscovery\AR.Iec61850.IedDiscovery.csproj", "{A187DF4A-8A80-4DE0-B286-27A8E8BCAB9A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AR.Iec61850.IedSimulator", "apps\AR.Iec61850.IedSimulator\AR.Iec61850.IedSimulator.csproj", "{C3D12F10-2A81-43A6-9BBA-FB789E6641E2}"
Expand All @@ -20,6 +22,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AR.Iec61850.Transports.Npca
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AR.Iec61850.Tests", "tests\AR.Iec61850.Tests\AR.Iec61850.Tests.csproj", "{0D9D1E7D-FF86-49A3-A81D-38D3E0880BF8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AR.Iec61850.VirtualRelayLab.Tests", "tests\AR.Iec61850.VirtualRelayLab.Tests\AR.Iec61850.VirtualRelayLab.Tests.csproj", "{B7E2A1D4-73C6-4F90-8D8F-9A5B2C4E1F33}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -34,6 +38,10 @@ Global
{49560545-7AA9-44AC-8196-9D6D98241B04}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49560545-7AA9-44AC-8196-9D6D98241B04}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49560545-7AA9-44AC-8196-9D6D98241B04}.Release|Any CPU.Build.0 = Release|Any CPU
{4F02C69F-8B2D-4F9E-9A2B-1F5E7A3C6D41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F02C69F-8B2D-4F9E-9A2B-1F5E7A3C6D41}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F02C69F-8B2D-4F9E-9A2B-1F5E7A3C6D41}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F02C69F-8B2D-4F9E-9A2B-1F5E7A3C6D41}.Release|Any CPU.Build.0 = Release|Any CPU
{A187DF4A-8A80-4DE0-B286-27A8E8BCAB9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A187DF4A-8A80-4DE0-B286-27A8E8BCAB9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A187DF4A-8A80-4DE0-B286-27A8E8BCAB9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -58,6 +66,10 @@ Global
{0D9D1E7D-FF86-49A3-A81D-38D3E0880BF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0D9D1E7D-FF86-49A3-A81D-38D3E0880BF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0D9D1E7D-FF86-49A3-A81D-38D3E0880BF8}.Release|Any CPU.Build.0 = Release|Any CPU
{B7E2A1D4-73C6-4F90-8D8F-9A5B2C4E1F33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7E2A1D4-73C6-4F90-8D8F-9A5B2C4E1F33}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7E2A1D4-73C6-4F90-8D8F-9A5B2C4E1F33}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7E2A1D4-73C6-4F90-8D8F-9A5B2C4E1F33}.Release|Any CPU.Build.0 = Release|Any CPU
{7B46B7B7-DF3F-4F3A-9DC9-E49AF0D97B61}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B46B7B7-DF3F-4F3A-9DC9-E49AF0D97B61}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B46B7B7-DF3F-4F3A-9DC9-E49AF0D97B61}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<ProjectReference Include="..\..\src\AR.Iec61850.Transports.Npcap\AR.Iec61850.Transports.Npcap.csproj" />
<ProjectReference Include="..\..\src\AR.Iec61850\AR.Iec61850.csproj" />
</ItemGroup>

<PropertyGroup>
<Copyright>Copyright (C) 2026 Mas Ari / masarray</Copyright>
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF>
<AssemblyName>AR.Iec61850.VirtualRelayLab</AssemblyName>
<RootNamespace>AR.Iec61850.VirtualRelayLab</RootNamespace>
<Product>AR Virtual Relay Lab</Product>
<Description>IEC 61850 Sampled Values virtual overcurrent and earth-fault protection laboratory.</Description>
</PropertyGroup>

</Project>
173 changes: 173 additions & 0 deletions apps/AR.Iec61850.VirtualRelayLab/AlgorithmEditorWindow.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<Window x:Class="AR.Iec61850.VirtualRelayLab.AlgorithmEditorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Protection Algorithm Editor"
Width="1120"
Height="720"
MinWidth="940"
MinHeight="620"
WindowStartupLocation="CenterOwner"
Background="{StaticResource ShellBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="56" />
<RowDefinition Height="*" />
<RowDefinition Height="48" />
</Grid.RowDefinitions>

<Border Grid.Row="0" Background="#17232D" BorderBrush="#2D3C47" BorderThickness="0,0,0,1">
<Grid Margin="16,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel VerticalAlignment="Center">
<TextBlock Text="Protection Algorithm Editor" Foreground="#F4F7F9" FontSize="15" FontWeight="SemiBold" />
<TextBlock Text="Typed, unit-aware laboratory DSL · changes are validated before staging" Foreground="#9FB0BC" FontSize="10.5" />
</StackPanel>
<Border Grid.Column="1" Padding="8,4" CornerRadius="4" Background="#203440" BorderBrush="#355262" BorderThickness="1" VerticalAlignment="Center">
<TextBlock Text="SAFE LAB MODE" Foreground="#B9C7D0" FontSize="9.5" FontWeight="SemiBold" />
</Border>
</Grid>
</Border>

<Grid Grid.Row="1" Margin="12">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="205" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="260" />
</Grid.ColumnDefinitions>

<Border Grid.Column="0" Style="{StaticResource PanelBorder}" Padding="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="42" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderBrush="{StaticResource LineBrush}" BorderThickness="0,0,0,1" Padding="12,0">
<TextBlock Text="PROTECTION ELEMENT" Style="{StaticResource SectionLabel}" VerticalAlignment="Center" />
</Border>
<ListBox Grid.Row="1" x:Name="ElementList" SelectedIndex="0" BorderThickness="0" Background="Transparent" Padding="7" SelectionChanged="ElementList_SelectionChanged">
<ListBoxItem Content="50P-1 Instantaneous OC" Padding="8,7" />
<ListBoxItem Content="51P Time OC" Padding="8,7" />
<ListBoxItem Content="50N Instantaneous EF" Padding="8,7" />
<ListBoxItem Content="51N Time EF" Padding="8,7" />
<ListBoxItem Content="TRIP Logic matrix" Padding="8,7" />
<ListBoxItem Content="SMV Trust policy" Padding="8,7" />
</ListBox>
</Grid>
</Border>

<Border Grid.Column="2" Style="{StaticResource PanelBorder}" Padding="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="42" />
<RowDefinition Height="*" />
<RowDefinition Height="32" />
</Grid.RowDefinitions>
<Border BorderBrush="{StaticResource LineBrush}" BorderThickness="0,0,0,1" Padding="12,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="EditorTitleText" Text="50P-1 · Standard precision profile" FontSize="12.5" FontWeight="SemiBold" VerticalAlignment="Center" />
<TextBlock Grid.Column="1" Text="v1 · modified" Foreground="{StaticResource MutedBrush}" FontFamily="Cascadia Mono, Consolas" FontSize="10" VerticalAlignment="Center" />
</Grid>
</Border>
<TextBox Grid.Row="1" x:Name="AlgorithmTextBox"
AcceptsReturn="True"
AcceptsTab="True"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
TextWrapping="NoWrap"
FontFamily="Cascadia Mono, Consolas"
FontSize="12.5"
Background="#111B22"
Foreground="#D8E4EB"
BorderThickness="0"
Padding="14"
SpellCheck.IsEnabled="False" />
<Border Grid.Row="2" Background="#F3F6F8" BorderBrush="{StaticResource LineBrush}" BorderThickness="0,1,0,0" Padding="10,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="CursorStatusText" Text="Deterministic runtime · no file, network, reflection or unmanaged access" Foreground="{StaticResource MutedBrush}" FontSize="9.8" VerticalAlignment="Center" />
<TextBlock Grid.Column="1" Text="UTF-8 · DSL" Foreground="#83919B" FontFamily="Cascadia Mono, Consolas" FontSize="9.5" VerticalAlignment="Center" />
</Grid>
</Border>
</Grid>
</Border>

<Border Grid.Column="4" Style="{StaticResource PanelBorder}" Padding="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="42" />
<RowDefinition Height="Auto" />
<RowDefinition Height="1" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderBrush="{StaticResource LineBrush}" BorderThickness="0,0,0,1" Padding="12,0">
<TextBlock Text="VALIDATION &amp; WATCH" Style="{StaticResource SectionLabel}" VerticalAlignment="Center" />
</Border>
<StackPanel Grid.Row="1" Margin="12">
<Border x:Name="ValidationBadge" Padding="9,6" CornerRadius="4" Background="#EEF2F5" BorderBrush="{StaticResource LineBrush}" BorderThickness="1">
<TextBlock x:Name="ValidationText" Text="Not validated" Foreground="{StaticResource MutedBrush}" FontSize="11" FontWeight="SemiBold" />
</Border>
<TextBlock Text="The active algorithm remains unchanged until validation and staging both succeed." TextWrapping="Wrap" Foreground="{StaticResource MutedBrush}" FontSize="10.5" Margin="1,9,1,0" />
</StackPanel>
<Border Grid.Row="2" Background="{StaticResource LineBrush}" />
<StackPanel Grid.Row="3" Margin="12">
<TextBlock Text="LIVE VARIABLES" Style="{StaticResource SectionLabel}" Margin="0,0,0,9" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<TextBlock Text="phaseCurrent" Foreground="{StaticResource MutedBrush}" FontSize="10.5" />
<TextBlock Grid.Column="1" Text="1.000 A" Style="{StaticResource EngineeringValue}" FontSize="10.5" />
<TextBlock Grid.Row="1" Text="pickup" Foreground="{StaticResource MutedBrush}" FontSize="10.5" />
<TextBlock Grid.Row="1" Grid.Column="1" Text="false" Style="{StaticResource EngineeringValue}" FontSize="10.5" />
<TextBlock Grid.Row="2" Text="operateTimer" Foreground="{StaticResource MutedBrush}" FontSize="10.5" />
<TextBlock Grid.Row="2" Grid.Column="1" Text="0.000 s" Style="{StaticResource EngineeringValue}" FontSize="10.5" />
<TextBlock Grid.Row="3" Text="smv.allowsTrip" Foreground="{StaticResource MutedBrush}" FontSize="10.5" />
<TextBlock Grid.Row="3" Grid.Column="1" Text="true" Foreground="{StaticResource HealthyBrush}" FontFamily="Cascadia Mono, Consolas" FontSize="10.5" />
<TextBlock Grid.Row="4" Text="execution" Foreground="{StaticResource MutedBrush}" FontSize="10.5" />
<TextBlock Grid.Row="4" Grid.Column="1" Text="3.2 µs" Style="{StaticResource EngineeringValue}" FontSize="10.5" />
</Grid>

<TextBlock Text="SAFETY GATES" Style="{StaticResource SectionLabel}" Margin="0,18,0,8" />
<TextBlock Text="✓ bounded instruction budget&#x0a;✓ unit/type analysis&#x0a;✓ deterministic state&#x0a;✓ mandatory SMV trip gate"
Foreground="#4D7257" FontFamily="Cascadia Mono, Consolas" FontSize="10.5" />
</StackPanel>
</Grid>
</Border>
</Grid>

<Border Grid.Row="2" Background="{StaticResource SurfaceBrush}" BorderBrush="{StaticResource LineBrush}" BorderThickness="0,1,0,0">
<Grid Margin="12,7">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="Editor prototype: typed DSL contract and activation workflow are locked before runtime compiler implementation." Foreground="{StaticResource MutedBrush}" FontSize="10.5" VerticalAlignment="Center" />
<StackPanel Grid.Column="1" Orientation="Horizontal">
<Button Style="{StaticResource LeanButton}" Content="Validate" Margin="0,0,7,0" Click="Validate_Click" />
<Button x:Name="StageButton" Style="{StaticResource PrimaryButton}" Content="Stage algorithm" Margin="0,0,7,0" IsEnabled="False" Click="Stage_Click" />
<Button Style="{StaticResource LeanButton}" Content="Close" Click="Close_Click" />
</StackPanel>
</Grid>
</Border>
</Grid>
</Window>
Loading
Loading