current working omni inspection

This commit is contained in:
Stoyan Zlatev
2024-01-29 16:01:10 +01:00
parent 27a6bf7713
commit c6a76c07ee
87 changed files with 2026 additions and 3903 deletions
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
@@ -17,17 +16,16 @@
public class ExchangeConnection : IExchangeHubMaster
{
public const string GROUP_KEY = "GroupNameKey";
public const string HUB_DIR = ".\\ExchangeHub";
public const string HUB_NAME = "ExchangeHub";
public const string STR_EMPTY = "";
private static readonly string GroupName = Environment.MachineName;
private static readonly string LoggingDir = Directory.CreateDirectory(HUB_DIR).FullName;
private readonly ICollection<IDisposable> disposables;
private HubConnection connection;
private IHubProxy proxy;
private string outputFile;
public ExchangeConnection()
=> this.disposables = new List<IDisposable>();
@@ -66,7 +64,7 @@
}
catch (Exception e)
{
this.FileAppendLine(e.ToString());
this.NotifyStateChanged(e.ToString());
}
}
@@ -91,11 +89,11 @@
Task.Factory.StartNew(this.connection.Dispose);
this.FileAppendLine($"Connection disconnected.");
this.NotifyStateChanged($"Connection disconnected.");
}
catch (Exception e)
{
this.FileAppendLine(e.ToString());
this.NotifyStateChanged(e.ToString());
}
}
@@ -104,6 +102,7 @@
if (this.connection?.State == ConnectionState.Connected)
{
this.proxy.Invoke<string>(nameof(this.Disposed), GroupName);
this.NotifyStateChanged($"{nameof(SendDisposed)}");
}
}
@@ -112,6 +111,7 @@
if (this.connection?.State == ConnectionState.Connected)
{
this.proxy.Invoke(nameof(this.StartFlow), volumeM3H, GroupName);
this.NotifyStateChanged($"{nameof(SendStartFlow)}");
}
}
@@ -120,6 +120,7 @@
if (this.connection?.State == ConnectionState.Connected)
{
this.proxy.Invoke(nameof(this.StopFlow), GroupName);
this.NotifyStateChanged($"{nameof(SendStopFlow)}");
}
}
@@ -128,6 +129,7 @@
if (this.connection?.State == ConnectionState.Connected)
{
this.proxy.Invoke(nameof(this.StartReferenceMessurement), durationSeconds, GroupName);
this.NotifyStateChanged($"{nameof(SendStartReferenceMessurement)}");
}
}
@@ -136,6 +138,7 @@
if (this.connection?.State == ConnectionState.Connected)
{
this.proxy.Invoke(nameof(this.StopReferenceMessurement), volumeM3H, GroupName);
this.NotifyStateChanged($"{nameof(SendStopReferenceMessurement)}");
}
}
@@ -144,6 +147,7 @@
if (GroupName == groupName)
{
this.Disposed?.Invoke(groupName);
this.NotifyStateChanged($"{nameof(Disposed)}");
}
}
@@ -152,6 +156,7 @@
if (GroupName == groupName)
{
this.StartFlow?.Invoke(volumeM3H, groupName);
this.NotifyStateChanged($"{nameof(FlowStarted)} -> {volumeM3H}m³/h");
}
}
@@ -160,6 +165,7 @@
if (GroupName == groupName)
{
this.StopFlow?.Invoke(groupName);
this.NotifyStateChanged($"{nameof(FlowStopped)}");
}
}
@@ -168,6 +174,7 @@
if (GroupName == groupName)
{
this.StartReferenceMessurement?.Invoke(seconds, groupName);
this.NotifyStateChanged($"{nameof(MessurementStarted)} -> {seconds}s");
}
}
@@ -176,54 +183,49 @@
if (GroupName == groupName)
{
this.StopReferenceMessurement?.Invoke(volumeMessured, groupName);
this.NotifyStateChanged($"{nameof(MessurementStopped)} -> {volumeMessured}m³/h");
}
}
private void Connection_Closed()
{
this.FileAppendLine("HubConnection closed!");
this.NotifyStateChanged("HubConnection closed!");
}
private void Connection_ConnectionSlow()
{
this.FileAppendLine("HubConnection is about to timeout!");
this.NotifyStateChanged("HubConnection is about to timeout!");
}
private void Connection_Error(Exception e)
{
this.FileAppendLine(e.ToString());
this.NotifyStateChanged(e.ToString());
}
private void Connection_Received(string data)
{
this.FileAppendLine(data);
this.NotifyStateChanged(data);
}
private void Connection_Reconnected()
{
this.FileAppendLine("HubConnection reconnected!");
this.NotifyStateChanged("HubConnection reconnected!");
}
private void Connection_Reconnecting()
{
this.FileAppendLine("HubConnection reconnecting!");
this.NotifyStateChanged("HubConnection reconnecting!");
}
private void Connection_StateChanged(StateChange state)
{
this.FileAppendLine($"{state.OldState} -> {state.NewState}");
this.NotifyStateChanged($"{state.OldState} -> {state.NewState}");
}
private void FileAppendLine(string text)
private void NotifyStateChanged(string text)
{
try
{
var fileName = $"{LoggingDir}\\{DateTime.Now:yyyy_MM_dd}.txt";
File.AppendAllText(
path: $"{LoggingDir}\\{DateTime.Now:yyyy_MM_dd}.txt",
contents: $"[{DateTime.Now:HH:mm:ss}] {text}{Environment.NewLine}");
this.StateChanged?.Invoke(text, GroupName);
}
catch (Exception e)
+13
View File
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<appSettings>
<add key="HubURL" value="http://sla12iis01.emea.sensus.net/LaaProductionWeb" />
<!--<add key="OmniDB" value="Server=SLASQL01.emea.sensus.net; Database=AuftragKopie; User ID=sa; Password=sqlserver;" />-->
<add key="OmniDB" value="Server=SLASQL01.emea.sensus.net; Database=Auftrag; User ID=sa; Password=sqlserver;"/>
<!--<add key="COMPorts" value="COM1, COM3, COM5, COM7, COM5, COM9, COM11, COM13, COM15, COM17"/>-->
<add key="COMPorts" value="COM4"/>
</appSettings>
</configuration>
+305
View File
@@ -0,0 +1,305 @@
<Application x:Class="InspectionUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="Spinner" TargetType="{x:Type Path}">
<Setter Property="Data" Value="M 10 3 C 6.13401 3 3 6.13401 3 10 C 3 10.2761 2.77614 10.5 2.5 10.5 C 2.22386 10.5 2 10.2761 2 10 C 2 5.58172 5.58172 2 10 2 C 14.4183 2 18 5.58172 18 10 C 18 14.4183 14.4183 18 10 18 C 9.72386 18 9.5 17.7761 9.5 17.5 C 9.5 17.2239 9.72386 17 10 17 C 13.866 17 17 13.866 17 10 C 17 6.13401 13.866 3 10 3 Z" />
<Setter Property="Stretch" Value="Uniform" />
<Setter Property="Fill" Value="LightGray" />
<Setter Property="Stroke" Value="Transparent" />
<Setter Property="StrokeEndLineCap" Value="Flat" />
<Setter Property="StrokeStartLineCap" Value="Flat" />
<Setter Property="StrokeThickness" Value="0.5" />
<Setter Property="RenderTransformOrigin" Value="0.5, 0.5" />
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform />
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
From="0"
To="360"
Duration="0:0:1"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ComboboxFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2" StrokeDashArray="1 2" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" SnapsToDevicePixels="true" StrokeThickness="1"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="TextBox.Static.Background" Color="#FFFFFFFF"/>
<Style x:Key="ComboBoxEditableTextBox" TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="MinWidth" Value="0"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<ScrollViewer x:Name="PART_ContentHost" Background="Transparent" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<SolidColorBrush x:Key="ComboBox.Static.Background" Color="White" />
<SolidColorBrush x:Key="ComboBox.Static.Border" Color="White"/>
<SolidColorBrush x:Key="ComboBox.Static.Glyph" Color="#FF606060"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Border" Color="White"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Background" Color="Transparent"/>
<SolidColorBrush x:Key="ComboBox.Static.Editable.Button.Border" Color="Transparent"/>
<LinearGradientBrush x:Key="ComboBox.MouseOver.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFECF4FC" Offset="0.0"/>
<GradientStop Color="#FFDCECFC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.MouseOver.Border" Color="#FF7EB4EA"/>
<SolidColorBrush x:Key="ComboBox.MouseOver.Glyph" Color="#FF000000"/>
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Border" Color="#FF7EB4EA"/>
<LinearGradientBrush x:Key="ComboBox.MouseOver.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFEBF4FC" Offset="0.0"/>
<GradientStop Color="#FFDCECFC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.MouseOver.Editable.Button.Border" Color="#FF7EB4EA"/>
<LinearGradientBrush x:Key="ComboBox.Pressed.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFDAECFC" Offset="0.0"/>
<GradientStop Color="#FFC4E0FC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.Pressed.Border" Color="#FF569DE5"/>
<SolidColorBrush x:Key="ComboBox.Pressed.Glyph" Color="#FF000000"/>
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Border" Color="#FF569DE5"/>
<LinearGradientBrush x:Key="ComboBox.Pressed.Editable.Button.Background" EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFDAEBFC" Offset="0.0"/>
<GradientStop Color="#FFC4E0FC" Offset="1.0"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="ComboBox.Pressed.Editable.Button.Border" Color="#FF569DE5"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Background" Color="#FFF0F0F0"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Border" Color="#FFD9D9D9"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Glyph" Color="#FFBFBFBF"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Background" Color="#FFFFFFFF"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Border" Color="#FFBFBFBF"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Background" Color="Transparent"/>
<SolidColorBrush x:Key="ComboBox.Disabled.Editable.Button.Border" Color="Transparent"/>
<Style x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Focusable" Value="false"/>
<Setter Property="ClickMode" Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Border x:Name="templateRoot" Background="{StaticResource ComboBox.Static.Background}" BorderBrush="{StaticResource ComboBox.Static.Border}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true">
<Border x:Name="splitBorder" BorderBrush="Transparent" BorderThickness="1" HorizontalAlignment="Right" Margin="0" SnapsToDevicePixels="true" Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}">
<Path x:Name="arrow" Data="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708" Fill="{StaticResource ComboBox.Static.Glyph}" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Center" Width="8" Stretch="Uniform"/>
</Border>
</Border>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Static.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Static.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.MouseOver.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.MouseOver.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.MouseOver.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Pressed.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsPressed, RelativeSource={RelativeSource Mode=Self}}" Value="true"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Pressed.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Pressed.Editable.Button.Border}"/>
</MultiDataTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Fill" TargetName="arrow" Value="{StaticResource ComboBox.Disabled.Glyph}"/>
</Trigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="false"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Border}"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Mode=Self}}" Value="false"/>
<Condition Binding="{Binding IsEditable, RelativeSource={RelativeSource AncestorType={x:Type ComboBox}}}" Value="true"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Background}"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource ComboBox.Disabled.Editable.Border}"/>
<Setter Property="Background" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Background}"/>
<Setter Property="BorderBrush" TargetName="splitBorder" Value="{StaticResource ComboBox.Disabled.Editable.Button.Border}"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxEditableTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource Mode=TemplatedParent}}" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
<Border x:Name="dropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1">
<ScrollViewer x:Name="DropDownScrollViewer">
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
<ToggleButton x:Name="toggleButton" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" Style="{StaticResource ComboBoxToggleButton}"/>
<Border x:Name="border" Background="{StaticResource TextBox.Static.Background}" Margin="{TemplateBinding BorderThickness}">
<TextBox x:Name="PART_EditableTextBox" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource Mode=TemplatedParent}}" Margin="{TemplateBinding Padding}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="true">
<Setter Property="Foreground" Value="Black"/>
</Trigger>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxTemplate" TargetType="{x:Type ComboBox}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}" Width="0"/>
</Grid.ColumnDefinitions>
<Popup x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" Margin="1" Placement="Bottom" PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
<Border x:Name="dropDownBorder" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}" BorderThickness="1">
<ScrollViewer x:Name="DropDownScrollViewer">
<Grid x:Name="grid" RenderOptions.ClearTypeHint="Enabled">
<Canvas x:Name="canvas" HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
<ToggleButton x:Name="toggleButton" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource Mode=TemplatedParent}}" Style="{StaticResource ComboBoxToggleButton}"/>
<ContentPresenter x:Name="contentPresenter" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" Content="{TemplateBinding SelectionBoxItem}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="false" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="ComboBoxStyle" TargetType="{x:Type ComboBox}">
<Setter Property="FocusVisualStyle" Value="{StaticResource ComboboxFocusVisual}"/>
<Setter Property="Background" Value="{StaticResource ComboBox.Static.Background}"/>
<Setter Property="BorderBrush" Value="{StaticResource ComboBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
<Setter Property="Padding" Value="6,3,5,3"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template" Value="{StaticResource ComboBoxTemplate}"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="FontFamily" Value="Consolas"/>
<Style.Triggers>
<Trigger Property="IsEditable" Value="true">
<Setter Property="IsTabStop" Value="false"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="Template" Value="{StaticResource ComboBoxEditableTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
</Application.Resources>
</Application>
+17
View File
@@ -0,0 +1,17 @@
namespace InspectionUI
{
using System;
using System.Globalization;
using System.Threading;
using System.Windows;
public partial class App : Application
{
internal static event Action Exiting;
protected override void OnExit(ExitEventArgs e)
{
Exiting?.Invoke();
}
}
}
@@ -4,15 +4,17 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D766BA80-CCA1-4D05-96B9-AAE520F30595}</ProjectGuid>
<ProjectGuid>{01A28A70-D5E6-4898-8C22-E64400A3B80F}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>OMNIPruefung</RootNamespace>
<AssemblyName>OMNIPruefung</AssemblyName>
<RootNamespace>InspectionUI</RootNamespace>
<AssemblyName>InspectionUI</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -34,15 +36,11 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.6.0.4\lib\net40\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="SqlExtensions, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\SqlExtensions\SqlExtensions.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
@@ -61,55 +59,25 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="EOLWindow.xaml.cs">
<DependentUpon>EOLWindow.xaml</DependentUpon>
<Compile Include="ItemsGrid.xaml.cs">
<DependentUpon>ItemsGrid.xaml</DependentUpon>
</Compile>
<Compile Include="Helpers\BooleanProgressBackgroundConverter.cs" />
<Compile Include="Helpers\BooleanVisibilityConverter.cs" />
<Compile Include="Models\Appsettings.cs" />
<Compile Include="Models\COMPorts.cs" />
<Compile Include="Models\EOLContentM.cs" />
<Compile Include="Models\OmniInspectionModel.cs" />
<Compile Include="OmniInspection.xaml.cs">
<DependentUpon>OmniInspection.xaml</DependentUpon>
</Compile>
<Compile Include="ViewModels\BaseVM.cs" />
<Compile Include="ViewModels\Content\SettingsContentVM.cs" />
<Compile Include="ViewModels\Features\OMNIPlusVM.cs" />
<Compile Include="ViewModels\Base\Command.cs" />
<Compile Include="ViewModels\Base\Command[T].cs" />
<Compile Include="ViewModels\Base\VM[T].cs" />
<Compile Include="ViewModels\ContentVM.cs" />
<Compile Include="ViewModels\Content\COMContentVM.cs" />
<Compile Include="ViewModels\Content\EOLContentVM.cs" />
<Compile Include="ViewModels\Content\ExchangeHubContentVM.cs" />
<Compile Include="ViewModels\Content\MainContentVM.cs" />
<Compile Include="ViewModels\Features\OMNISysParameters.cs" />
<Compile Include="ViewModels\NodeVM.cs" />
<Compile Include="ViewModels\OmniAuftragVM.cs" />
<Compile Include="ViewModels\OmniInspectionVM.cs" />
<Compile Include="ViewModels\Options\COMOptionVM.cs" />
<Compile Include="ViewModels\Options\EOLOptionVM.cs" />
<Compile Include="ViewModels\Options\ExchangeHubOptionVM.cs" />
<Compile Include="ViewModels\Options\MainOptionVM.cs" />
<Compile Include="ViewModels\Options\SettingsOptionVM.cs" />
<Compile Include="ViewModels\OptionVM.cs" />
<Compile Include="Views\Content\COMContent.xaml.cs">
<DependentUpon>COMContent.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Content\EOLContent.xaml.cs">
<DependentUpon>EOLContent.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Content\ExchangeHub.xaml.cs">
<DependentUpon>ExchangeHub.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Options\COMOption.xaml.cs">
<DependentUpon>COMOption.xaml</DependentUpon>
</Compile>
<Compile Include="Views\Options\Option.xaml.cs">
<DependentUpon>Option.xaml</DependentUpon>
</Compile>
<Page Include="EOLWindow.xaml">
<Compile Include="ViewModels\Appsettings.cs" />
<Compile Include="ViewModels\CompilerServices.cs" />
<Compile Include="ViewModels\DefaultsHeaderRow.cs" />
<Compile Include="ViewModels\DefaultsRowVM.cs" />
<Compile Include="ViewModels\HeadersRowVM.cs" />
<Compile Include="ViewModels\ItemsGridActionsVM.cs" />
<Compile Include="ViewModels\ItemsGridHeaderVM.cs" />
<Compile Include="ViewModels\ItemsGridRowVM.cs" />
<Compile Include="ViewModels\ItemsGridVM.cs" />
<Compile Include="ViewModels\MainVM.cs" />
<Compile Include="ViewModels\MetersPoolVM.cs" />
<Compile Include="ViewModels\MeterVM.cs" />
<Compile Include="ViewModels\ItemsGridCellVM.cs" />
<Compile Include="ViewModels\ReferenceMeterVM.cs" />
<Compile Include="ViewModels\VM.cs" />
<Page Include="ItemsGrid.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
@@ -125,30 +93,6 @@
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="OmniInspection.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Content\COMContent.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\Content\EOLContent.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\Content\ExchangeHub.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\Options\COMOption.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\Options\Option.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
@@ -168,13 +112,20 @@
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Content Include="MainWindow.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ExchangeHub\ExchangeHub.csproj">
<Project>{6033FF0C-CF32-4BC5-8EFE-4774CCDC663D}</Project>
@@ -185,22 +136,5 @@
<Name>OmniPlus</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="Images\empty.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\folder.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\logo.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\meter.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Images\settings.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
@@ -0,0 +1,80 @@
<Grid x:Class="InspectionUI.ItemsGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:InspectionUI.ViewModels">
<Grid.Resources>
<DataTemplate DataType="{x:Type VM:ItemsGridHeaderVM}">
<Label Background="WhiteSmoke"
BorderBrush="White"
BorderThickness="0, 1, 1, 0"
Content="{Binding Value}"
FontFamily="Consolas"
FontSize="14"
FontWeight="Bold"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="{Binding HorisontalContentAlignment}"
Margin="0"
Padding="3, 5"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"/>
</DataTemplate>
<DataTemplate DataType="{x:Type VM:ItemsGridCellVM}">
<Label Background="{Binding Background, TargetNullValue={x:Static SystemColors.WindowBrush}}"
BorderBrush="WhiteSmoke"
BorderThickness="0, 1, 1, 0"
Content="{Binding Value}"
FontFamily="Consolas"
FontSize="14"
Foreground="{Binding Foreground, TargetNullValue={x:Static SystemColors.ControlTextBrush}}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="{Binding HorisontalContentAlignment}"
Margin="0"
Padding="3, 5"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center" />
</DataTemplate>
<DataTemplate DataType="{x:Type VM:ItemsGridActionsVM}">
<Border BorderBrush="WhiteSmoke"
BorderThickness="0, 1, 1, 0" >
<StackPanel HorizontalAlignment="Center"
Orientation="Horizontal"
Margin="0"
VerticalAlignment="Stretch">
<Button Background="Transparent"
BorderBrush="Transparent"
Content="A"
Cursor="Hand"
FontFamily="Consolas"
FontSize="14"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Padding="5, 0"
VerticalAlignment="Center"
VerticalContentAlignment="Center"/>
<Button Background="Transparent"
BorderBrush="Transparent"
Content="B"
Cursor="Hand"
FontFamily="Consolas"
FontSize="14"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Padding="5, 0"
VerticalAlignment="Center"
VerticalContentAlignment="Center" />
<Button Background="Transparent"
BorderBrush="Transparent"
Content="C"
Cursor="Hand"
FontFamily="Consolas"
FontSize="14"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Padding="5, 0"
VerticalAlignment="Center"
VerticalContentAlignment="Center" />
</StackPanel>
</Border>
</DataTemplate>
</Grid.Resources>
</Grid>
@@ -0,0 +1,91 @@
namespace InspectionUI
{
using InspectionUI.ViewModels;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
public partial class ItemsGrid : Grid
{
public ItemsGrid()
{
this.InitializeComponent();
}
public ItemsGridVM ItemsSource
{
get => this.GetValue(ItemsSourceProperty) as ItemsGridVM;
set => this.SetValue(ItemsSourceProperty, value);
}
}
public partial class ItemsGrid
{
public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
name: nameof(ItemsSource)
, propertyType: typeof(ItemsGridVM)
, ownerType: typeof(ItemsGrid)
, typeMetadata: new FrameworkPropertyMetadata(null, ItemsSourceChanged));
private static void ItemsSourceChanged(DependencyObject control, DependencyPropertyChangedEventArgs args)
{
if (control is ItemsGrid itemsGrid)
{
if (args.OldValue is ItemsGridVM oldSource)
{
oldSource.PropertyChanged -= itemsGrid.ReorderItems;
}
if (args.NewValue is ItemsGridVM newSource)
{
newSource.PropertyChanged += itemsGrid.ReorderItems;
}
}
}
private void ReorderItems(object sender, PropertyChangedEventArgs e)
{
this.Children.Clear();
this.RowDefinitions.Clear();
this.ColumnDefinitions.Clear();
var row = 0;
var col = 0;
foreach (var rowItem in this.ItemsSource)
{
this.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
foreach (var cell in rowItem)
{
if (row == 0)
{
if (cell is ItemsGridHeaderVM header)
{
for (int i = 0; i < header.ColSpan; i++)
{
this.ColumnDefinitions.Add(new ColumnDefinition { Width = header.Width });
}
}
}
var cellContent = new ContentControl { Content = cell };
Grid.SetRow(cellContent, row);
Grid.SetRowSpan(cellContent, cell.RowSpan);
Grid.SetColumn(cellContent, col);
Grid.SetColumnSpan(cellContent, cell.ColSpan);
this.Children.Add(cellContent);
col += cell.ColSpan;
}
col = 0;
row++;
}
}
}
}

Before

Width:  |  Height:  |  Size: 641 B

After

Width:  |  Height:  |  Size: 641 B

@@ -0,0 +1,121 @@
<Window x:Class="InspectionUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:InspectionUI.ViewModels"
xmlns:Local="clr-namespace:InspectionUI"
Icon="MainWindow.png"
Height="600"
Width="977">
<Window.DataContext>
<VM:MainVM />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border BorderBrush="LightGray" BorderThickness="0, 1" Grid.Row="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Command="{Binding Reload}"
Content="Neu laden"
Cursor="Hand"
FontFamily="Consolas"
Grid.Column="0"
IsEnabled="{Binding IsReloadEnabled}"
Margin="5, 5, 0, 5"
Padding="10, 5"/>
<TextBox Grid.Column="1"
FontFamily="Consolas"
FontWeight="Bold"
HorizontalContentAlignment="Left"
Margin="5, 5, 0, 5"
Text="{Binding SuchNr}"
Width="150"
VerticalContentAlignment="Center"/>
<ComboBox Background="White"
BorderBrush="White"
FontFamily="Consolas"
FontWeight="Bold"
Grid.Column="2"
Margin="5, 5, 0, 5"
Padding="5"
SelectedIndex="{Binding Size}"
Style="{DynamicResource ComboBoxStyle}" >
<ComboBoxItem Content="1½&quot;" Padding="10, 5" IsSelected="True" />
<ComboBoxItem Content="2&quot;" Padding="10, 5" />
</ComboBox>
<ComboBox Background="White"
BorderBrush="White"
FontFamily="Consolas"
FontWeight="Bold"
Grid.Column="3"
Margin="5, 5, 0, 5"
Padding="5"
SelectedValue="{Binding Type}"
SelectedValuePath="Content"
Style="{DynamicResource ComboBoxStyle}" >
<ComboBoxItem Content="C2" Padding="10, 5" IsSelected="True" />
<ComboBoxItem Content="R2" Padding="10, 5" />
<ComboBoxItem Content="T2" Padding="10, 5" />
</ComboBox>
<Button Command="{Binding CheckInspection}"
Content="Überprüfen"
Cursor="Hand"
FontFamily="Consolas"
Grid.Column="5"
IsEnabled="{Binding IsCheckInspectionEnabled}"
Margin="5"
Padding="10, 5"
Visibility="Collapsed"/>
<Button Command="{Binding StartInspection}"
Content="Start"
Cursor="Hand"
FontFamily="Consolas"
Grid.Column="6"
IsEnabled="{Binding IsStartInspectionEnabled}"
Margin="5"
Padding="10, 5"/>
<Button Command="{Binding CancelInspection}"
Content="Abbruch"
Cursor="Hand"
FontFamily="Consolas"
Grid.Column="7"
IsEnabled="{Binding IsCancelInspectionEnabled}"
Margin="5"
Padding="10, 5"
Visibility="Collapsed"/>
</Grid>
</Border>
<Border Grid.Row="1">
<Label Content="{Binding Errors}"
FontFamily="Consolas"
FontWeight="Bold"
Foreground="Red"
Margin="5"
Padding="0" />
</Border>
<!-- TODO: Order head -->
<ScrollViewer Grid.Row="2"
CanContentScroll="True"
IsDeferredScrollingEnabled="True"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Hidden">
<Local:ItemsGrid ItemsSource="{Binding MetersPool}" Margin="10, 0, 10, 10" />
</ScrollViewer>
</Grid>
</Window>
@@ -1,7 +1,7 @@
using System.Windows;
namespace OMNIPruefung
namespace InspectionUI
{
using System.Windows;
public partial class MainWindow : Window
{
public MainWindow()
@@ -1,17 +1,18 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// C:\Users\SZLATEV\source\repos\laa_production\Common\OMNIPruefung\Properties\AssemblyInfo.cs
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("OMNI+ Prüfung")]
[assembly: AssemblyTitle("InspectionUI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("OMNI+ Prüfung")]
[assembly: AssemblyCopyright("Copyright © 2023")]
[assembly: AssemblyProduct("InspectionUI")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace OMNIPruefung.Properties {
namespace InspectionUI.Properties {
using System;
@@ -19,7 +19,7 @@ namespace OMNIPruefung.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
@@ -39,7 +39,7 @@ namespace OMNIPruefung.Properties {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PruefsoftwareUI.Properties.Resources", typeof(Resources).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("InspectionUI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
@@ -8,11 +8,11 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace OMNIPruefung.Properties {
namespace InspectionUI.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -0,0 +1,45 @@
namespace InspectionUI.ViewModels
{
using System;
using System.Configuration;
using System.IO;
public class Appsettings
{
private static readonly string ExeLocation
= typeof(App).Assembly.Location;
private static readonly Configuration configuration
= ConfigurationManager.OpenExeConfiguration(ExeLocation);
private static readonly KeyValueConfigurationCollection appsettings
= configuration.AppSettings.Settings;
public static string[] COMPorts
{
get => appsettings[nameof(COMPorts)]
.Value
.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
}
public static string CurrentDirectory
{
get => new FileInfo(ExeLocation).DirectoryName;
}
public static string OmniDB
{
get => appsettings[nameof(OmniDB)]?.Value;
}
public static string HubURL
{
get => appsettings[nameof(HubURL)]?.Value;
}
public static String OutputDirectory
{
get => Directory
.CreateDirectory(Path.Combine(CurrentDirectory, "Debug", $"{DateTime.Now:yyyy-MM-dd}"))
.FullName;
}
}
}
@@ -0,0 +1,17 @@
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public class CallerMemberNameAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public class CallerFilePathAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
public class CallerLineNumberAttribute : Attribute
{
}
}
@@ -0,0 +1,25 @@
namespace InspectionUI.ViewModels
{
using OmniPlus;
public class DefaultsHeaderRow : ItemsGridRowVM
{
public DefaultsHeaderRow()
{
this.Add(new ItemsGridHeaderVM());
this.Add(new ItemsGridHeaderVM());
this.Add(new ItemsGridHeaderVM());
var auftrag = OmniContext.Current.Auftrag;
foreach (var pp in auftrag.Pruefpunkte)
{
this.Add(new ItemsGridHeaderVM { Value = $"m³/h" });
this.Add(new ItemsGridHeaderVM { Value = $"r/s" });
this.Add(new ItemsGridHeaderVM { Value = $"acc. %" });
}
this.Add(new ItemsGridHeaderVM());
}
}
}
@@ -0,0 +1,25 @@
namespace InspectionUI.ViewModels
{
using OmniPlus;
public class DefaultsRowVM : ItemsGridRowVM
{
public DefaultsRowVM()
{
this.Add(new ItemsGridHeaderVM());
this.Add(new ItemsGridHeaderVM());
this.Add(new ItemsGridHeaderVM());
var auftrag = OmniContext.Current.Auftrag;
foreach (var pp in auftrag.Pruefpunkte)
{
this.Add(new ItemsGridHeaderVM { Value = $"{pp.FlowM3H:0.000}" });
this.Add(new ItemsGridHeaderVM { Value = $"{pp.Rotations}/{pp.Duration}" });
this.Add(new ItemsGridHeaderVM { Value = $"{pp.MinAccuracy}-{pp.MaxAccuracy}" });
}
this.Add(new ItemsGridHeaderVM { Value = "3.3" });
}
}
}
@@ -0,0 +1,29 @@
namespace InspectionUI.ViewModels
{
using OmniPlus;
public class HeadersRowVM : ItemsGridRowVM
{
public HeadersRowVM() : base()
{
this.Add(new ItemsGridHeaderVM { Width = ItemsGridHeaderVM.Auto });
this.Add(new ItemsGridHeaderVM { Value = "MeterNr", Width = ItemsGridHeaderVM.Star });
this.Add(new ItemsGridHeaderVM { Value = "SerialNr", Width = ItemsGridHeaderVM.Star });
var auftrag = OmniContext.Current.Auftrag;
foreach (var pp in auftrag.Pruefpunkte)
{
this.Add(new ItemsGridHeaderVM
{
Value = $"Q{pp.PPNR}",
Width = ItemsGridHeaderVM.Star,
ColSpan = 3
});
}
this.Add(new ItemsGridHeaderVM { Value = "Crr. %", Width = ItemsGridHeaderVM.Star });
}
}
}
@@ -0,0 +1,12 @@
namespace InspectionUI.ViewModels
{
internal class ItemsGridActionsVM : ItemsGridCellVM
{
private MeterVM meterVM;
public ItemsGridActionsVM(MeterVM meterVM) : base()
{
this.meterVM = meterVM;
}
}
}
@@ -0,0 +1,44 @@
namespace InspectionUI.ViewModels
{
using System.Windows;
using System.Windows.Media;
public class ItemsGridCellVM : VM
{
public ItemsGridCellVM() : base()
{
}
private string value;
public string Value
{
get => this.value;
set => this.Set(() => this.value = value);
}
private Brush background;
public Brush Background
{
get => this.background;
set => this.Set(() => this.background = value);
}
private Brush foreground;
public Brush Foreground
{
get => this.foreground;
set => this.Set(() => this.foreground = value);
}
private HorizontalAlignment horizontalContentAlignment = HorizontalAlignment.Right;
public HorizontalAlignment HorisontalContentAlignment
{
get => this.horizontalContentAlignment;
set => this.Set(() => this.horizontalContentAlignment = value);
}
public int ColSpan { get; set; } = 1;
public int RowSpan { get; set; } = 1;
}
}
@@ -0,0 +1,17 @@
namespace InspectionUI.ViewModels
{
using System.Windows;
internal class ItemsGridHeaderVM : ItemsGridCellVM
{
public ItemsGridHeaderVM() : base()
{
}
public GridLength Width { get; set; }
internal static readonly GridLength Auto = new GridLength(1, GridUnitType.Auto);
internal static readonly GridLength Star = new GridLength(1, GridUnitType.Star);
}
}
@@ -0,0 +1,84 @@
namespace InspectionUI.ViewModels
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class ItemsGridRowVM : VM, IEnumerable<ItemsGridCellVM>
{
private readonly IList<ItemsGridCellVM> cells;
public ItemsGridRowVM() : base()
{
this.cells = new List<ItemsGridCellVM>();
}
protected ItemsGridCellVM this[int index]
{
get
{
if (index >= this.cells.Count)
{
return default(ItemsGridCellVM);
}
return this.cells[index];
}
}
protected int LastIndex
{
get => this.Count() - 1;
}
public void Add(ItemsGridCellVM value)
{
this.cells.Add(value);
}
public void Clear()
{
foreach (var cell in this.cells)
{
cell.Dispose();
}
this.cells.Clear();
}
public IEnumerator<ItemsGridCellVM> GetEnumerator()
{
return this.cells.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
protected void Set<T>(Action propertySetterAction, T newValue, string format, int index)
{
this.Set(propertySetterAction);
this.Set(newValue, format, index);
}
protected void Set<T>(T value, string format, int index)
{
this.InvokeAsync(() =>
{
if (string.IsNullOrWhiteSpace(format))
{
format = "{0}";
}
this[index].Value = string.Format(format, value);
});
}
protected void Set(Action<ItemsGridCellVM> setter, int index)
{
this.InvokeAsync(() => setter(this[index]));
}
}
}
@@ -0,0 +1,50 @@
namespace InspectionUI.ViewModels
{
using System.Collections;
using System.Collections.Generic;
public abstract class ItemsGridVM : VM, IEnumerable<ItemsGridRowVM>
{
private readonly IList<ItemsGridRowVM> rows;
protected ItemsGridVM() : base()
{
this.rows = new List<ItemsGridRowVM>();
}
public IEnumerator<ItemsGridRowVM> GetEnumerator()
{
return this.rows.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
protected void Add(ItemsGridRowVM item)
{
this.rows.Add(item);
}
protected void Clear()
{
foreach (var item in this.rows)
{
item.Dispose();
}
this.rows.Clear();
}
protected int IndexOf(ItemsGridRowVM item)
{
return this.rows.IndexOf(item);
}
protected void Insert(int index, ItemsGridRowVM item)
{
this.rows.Insert(index, item);
}
}
}
@@ -0,0 +1,169 @@
namespace InspectionUI.ViewModels
{
using OmniPlus;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
public class MainVM : VM
{
private readonly OmniContext omniContext;
public MainVM() : base()
{
this.IsReloadEnabled = true;
this.MetersPool = new MetersPoolVM();
this.Reload = new Command(this.ReloadCommand);
this.CheckInspection = new Command(this.CheckInspectionCommand);
this.StartInspection = new Command(this.StartInspectionCommand);
this.CancelInspection = new Command(this.CancelInspectionCommand);
this.omniContext = OmniContext.GetOrCreateInstance(Appsettings.OmniDB, Appsettings.OutputDirectory);
}
private int size;
public int Size
{
get => Math.Max(this.size - 5, 0);
set => this.Set(() => this.size = value + 5);
}
private string type;
public string Type
{
get => this.type;
set => this.Set(() => this.type = value);
}
private string suchnr;
public string SuchNr
{
get => this.suchnr;
set => this.Set(() => this.suchnr = value);
}
private bool reloadEnabled;
public bool IsReloadEnabled
{
get => this.reloadEnabled;
set => this.Set(() => this.reloadEnabled = value);
}
public ICommand Reload { get; }
private bool checkInspectionEnabled;
public bool IsCheckInspectionEnabled
{
get => this.checkInspectionEnabled;
set => this.Set(() => this.checkInspectionEnabled = value);
}
public ICommand CheckInspection { get; }
private bool startInspectionEnabled;
public bool IsStartInspectionEnabled
{
get => this.startInspectionEnabled;
set => this.Set(() => this.startInspectionEnabled = value);
}
public ICommand StartInspection { get; }
private bool cancelInspectionEnabled;
public bool IsCancelInspectionEnabled
{
get => this.cancelInspectionEnabled;
set => this.Set(() => this.cancelInspectionEnabled = value);
}
public ICommand CancelInspection { get; }
private string errors;
public string Errors
{
get => this.errors;
set => this.Set(() => this.errors = value);
}
public MetersPoolVM MetersPool { get; }
private void ReloadCommand()
{
this.EnableButtons(false);
this.Errors = default(string);
if (!string.IsNullOrWhiteSpace(this.SuchNr))
{
this.omniContext.LoadAuftrag(this.SuchNr);
}
else if (this.size >= 0 && !string.IsNullOrWhiteSpace(this.type))
{
this.omniContext.LoadAuftrag((byte)this.size, this.type);
}
else
{
this.Errors = "FertigungauftragsNr oder Größe und Typ eingeben.";
}
if (string.IsNullOrWhiteSpace(this.Errors))
{
Task.Factory
.StartNew(() =>
{
this.MetersPool.LoadMeters();
})
.ContinueWith(_ =>
{
this.MetersPool.SaveMeterStates();
})
.ContinueWith(_ =>
{
this.EnableButtons(true);
});
}
else
{
this.EnableButtons(true);
}
}
private void CheckInspectionCommand()
{
Task.Factory.StartNew(() =>
{
this.EnableButtons(false);
this.MetersPool.RunCheckInspection();
this.EnableButtons(true);
});
}
private void StartInspectionCommand()
{
Task.Factory.StartNew(() =>
{
this.EnableButtons(false);
this.MetersPool.RunInspection();
this.IsReloadEnabled = true;
});
}
private void CancelInspectionCommand()
{
Task.Factory.StartNew(() =>
{
this.EnableButtons(false);
this.MetersPool.CancelInspection();
this.EnableButtons(true);
});
}
private void EnableButtons(bool enabled)
{
this.IsReloadEnabled = enabled;
this.IsCheckInspectionEnabled = enabled;
this.IsStartInspectionEnabled = enabled;
this.IsCancelInspectionEnabled = !enabled;
}
}
}
@@ -0,0 +1,216 @@
namespace InspectionUI.ViewModels
{
using OmniPlus;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Media;
public class MeterVM : ItemsGridRowVM
{
private readonly OmniMeter meter;
private int uinr = 0;
public MeterVM(OmniMeter meter) : base()
{
this.meter = meter;
this.Add(new ItemsGridHeaderVM { Value = $"{this.meter.SlotNr, 2}." });
this.Add(new ItemsGridCellVM());
this.Add(new ItemsGridCellVM());
var auftrag = OmniContext.Current.Auftrag;
foreach (var _ in auftrag.Pruefpunkte)
{
this.Add(new ItemsGridCellVM());
this.Add(new ItemsGridCellVM());
this.Add(new ItemsGridCellVM());
}
this.Add(new ItemsGridCellVM());
}
private string meterId;
protected string MeterNr
{
get => this.meterId;
set => this.Set(() => this.meterId = value, value, "{0}", 1);
}
private int? serialNr;
protected int? SerialNr
{
get => this.serialNr;
set => this.Set(() => this.serialNr = value, value, "{0}", 2);
}
public override void Dispose()
{
try
{
this.meter.Dispose();
}
catch (Exception e)
{
this.meter.NotifyStateChanged($"[{DateTime.Now}] {e}");
}
base.Dispose();
}
internal Task ConnectAsync()
{
void Connect()
{
this.meter.ConnectIrda();
this.meter.IdentitfyMeter();
this.MeterNr = this.meter.MeterNr;
this.SerialNr = this.meter.SerialNr;
}
return this.StartNew(Connect);
}
public Task SaveMeterStateAsync()
{
return this.StartNew(this.meter.SaveMeterState);
}
public Task LoadTestRunAsync()
{
return this.StartNew(this.meter.LoadTestRun);
}
public Task InitializeInspectionAsync(bool preserveState = false)
{
this.uinr = 0;
void InitializeInspection()
{
this.meter.InitializeForInspection(preserveState);
this.Set(this.meter.TestRun.CrrfBefore, "{0:0.0}", this.LastIndex);
}
return this.StartNew(InitializeInspection);
}
public Task StartCalibrationAsync(OmniPruefpunkt pp)
{
this.uinr++;
void StartCalibration()
{
this.meter.StartCalibration((ushort)pp.Rotations, (ushort)pp.Duration);
this.ShowRestTime(pp.Duration, this.uinr * 3 + 1);
}
return this.StartNew(StartCalibration);
}
public Task StopCalibrationAsync(OmniPruefpunkt pp, double refm3s)
{
void StopCalibration()
{
var response = this.meter.StopCalibration(pp, refm3s);
var index = this.uinr * 3;
this.Set(response.Item1, "{0:0.00000000}", index);
this.Set(response.Item2, "{0}", index + 1);
this.Set(response.Item3, "{0:0.00}", index + 2);
}
return this.StartNew(StopCalibration);
}
public Task FinishInspectionAsync()
{
void FinishInspection()
{
this.meter.FinishInspection();
var crrf = this.meter.TestRun.CrrfAfter;
var background = this.meter.TestRun.Succeeded == true
? Brushes.Green
: Brushes.Red;
this.Set(x =>
{
x.Background = background;
x.Foreground = Brushes.White;
}, this.LastIndex);
this.Set(crrf, "{0:0.0}", this.LastIndex);
this.uinr = 1;
foreach (var testedPP in this.meter.TestRun.TestedPoints)
{
var index = this.uinr * 3;
this.Set(testedPP.Acc, "{0:0.00}", index + 2);
this.uinr++;
}
}
return this.StartNew(FinishInspection);
}
private void ShowRestTime(int duration, int index)
{
var interval = 1000;
var timeout = duration * interval;
var waitHandle = new ManualResetEventSlim();
var timer = new System.Timers.Timer
{
AutoReset = true,
Enabled = true,
Interval = interval
};
void TimerElapsed(object _, ElapsedEventArgs _1)
{
duration--;
if (duration > 0)
{
this.Set(duration, "{0}", index);
}
}
timer.Elapsed += TimerElapsed;
timer.Start();
waitHandle.Wait(timeout);
timer.Stop();
waitHandle.Reset();
waitHandle.Wait(100);
timer.Elapsed -= TimerElapsed;
this.Set(default(string), "{0}", index);
}
private Task StartNew(Action task)
{
return Task
.Factory
.StartNew(task)
.ContinueWith(t =>
{
if (t.Exception != null)
{
this.meter.NotifyStateChanged($"[{DateTime.Now}] {t.Exception}");
}
});
}
}
}
@@ -0,0 +1,154 @@
namespace InspectionUI.ViewModels
{
using OmniPlus;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
public class MetersPoolVM : ItemsGridVM
{
private ReferenceMeterVM referenceMeter;
public MetersPoolVM() : base()
{
}
public void CancelInspection()
{
this.referenceMeter.Stop();
}
public void LoadMeters()
{
this.InvokeAsync(() =>
{
this.Clear();
this.Add(new HeadersRowVM());
this.Add(new DefaultsHeaderRow());
this.Add(new DefaultsRowVM());
this.referenceMeter = new ReferenceMeterVM();
this.Add(this.referenceMeter);
});
var tasks = new List<Task>();
var nr = 1;
foreach (var portName in Appsettings.COMPorts)
{
var meter = OmniContext.Current.LoadMeter(nr++, portName);
var meterVM = new MeterVM(meter);
this.Add(meterVM);
tasks.Add(meterVM.ConnectAsync());
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
this.NotifyPropertyChanged();
}
internal void SaveMeterStates()
{
var tasks = new List<Task>();
foreach (var item in this.ToArray())
{
if (item is MeterVM meterVM)
{
tasks.Add(meterVM.SaveMeterStateAsync());
}
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
}
public void RunCheckInspection()
{
}
public void RunInspection()
{
var tasks = new List<Task>();
var meters = this
.Select(x => x is MeterVM m ? m : null)
.Where(x => x != null)
.ToArray();
foreach (var meterVM in meters)
{
tasks.Add(meterVM.LoadTestRunAsync());
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
tasks.Clear();
foreach (var meterVM in meters)
{
tasks.Add(meterVM.InitializeInspectionAsync());
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
var pruefpunkte = OmniContext
.Current
.Auftrag
.Pruefpunkte;
foreach (var pp in pruefpunkte)
{
this.referenceMeter.Start(pp);
tasks.Clear();
foreach (var meterVM in meters)
{
tasks.Add(meterVM.StartCalibrationAsync(pp));
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
var refm3s = this.referenceMeter.GetFlow();
tasks.Clear();
foreach (var meterVM in meters)
{
tasks.Add(meterVM.StopCalibrationAsync(pp, refm3s));
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
}
this.referenceMeter.Stop();
tasks.Clear();
foreach (var meterVM in meters)
{
tasks.Add(meterVM.FinishInspectionAsync());
}
Task.Factory
.ContinueWhenAll(tasks.ToArray(), _ => { })
.Wait();
}
}
}
@@ -0,0 +1,244 @@
namespace InspectionUI.ViewModels
{
using ExchangeHub;
using OmniPlus;
using System;
using System.IO;
using System.Threading;
using System.Timers;
public class ReferenceMeterVM : ItemsGridRowVM
{
private readonly ExchangeConnection signarR;
private readonly string outputFile;
private int ppnr = 0;
public ReferenceMeterVM() : base()
{
this.Add(new ItemsGridHeaderVM());
this.Add(new ItemsGridHeaderVM { Value = "RZ:" });
this.Add(new ItemsGridHeaderVM());
var auftrag = OmniContext.Current.Auftrag;
foreach (var _ in auftrag.Pruefpunkte)
{
this.Add(new ItemsGridHeaderVM());
this.Add(new ItemsGridHeaderVM());
this.Add(new ItemsGridHeaderVM());
}
this.Add(new ItemsGridHeaderVM());
this.signarR = new ExchangeConnection();
this.signarR.StateChanged += SignarR_StateChanged;
this.outputFile = Path.Combine(Appsettings.OutputDirectory, "signalr.txt");
this.signarR.Connect(Appsettings.HubURL);
}
internal void Start(OmniPruefpunkt pp)
{
this.ppnr += 3;
this.StartFlow(pp);
this.StartRZ(pp);
}
private void StartFlow(OmniPruefpunkt pp)
{
var interval = 1000;
var timeout = 5;// 00;
var volume = default(double);
var waitHandle = new ManualResetEventSlim();
var timer = new System.Timers.Timer
{
AutoReset = true,
Enabled = true,
Interval = interval,
};
void FlowStarted(double value, string _)
{
volume = value;
timer.Stop();
waitHandle.Set();
}
void TimerElapsed(object _, ElapsedEventArgs _1)
{
if (timeout < 0)
{
timeout = 0;
timer.Stop();
waitHandle.Set();
}
else
{
this.Set(timeout, "... {0}", this.ppnr);
}
timeout--;
}
timer.Elapsed += TimerElapsed;
this.signarR.StartFlow += FlowStarted;
timer.Start();
this.signarR.SendStartFlow(pp.FlowM3H);
waitHandle.Wait(timeout * interval);
waitHandle.Reset();
this.signarR.StartFlow -= FlowStarted;
timer.Elapsed -= TimerElapsed;
waitHandle.Wait(1000);
this.Set(default(string), "{0}", this.ppnr);
}
private void StartRZ(OmniPruefpunkt pp)
{
var interval = 1000;
var timeout = 6;// 0;
var seconds = default(double);
var waitHandle = new ManualResetEventSlim();
var timer = new System.Timers.Timer
{
AutoReset = true,
Enabled = true,
Interval = interval,
};
void RZStarted(int value, string _)
{
seconds = value;
timer.Stop();
waitHandle.Set();
}
void TimerElapsed(object _, ElapsedEventArgs _1)
{
if (timeout < 0)
{
timeout = 0;
timer.Stop();
waitHandle.Set();
}
else
{
this.Set(timeout, "... {0}", this.ppnr + 1);
}
timeout--;
}
timer.Elapsed += TimerElapsed;
this.signarR.StartReferenceMessurement += RZStarted;
timer.Start();
this.signarR.SendStartReferenceMessurement(pp.Duration);
waitHandle.Wait(timeout * interval);
waitHandle.Reset();
this.signarR.StartReferenceMessurement -= RZStarted;
timer.Elapsed -= TimerElapsed;
waitHandle.Wait(1000);
this.Set(seconds, "{0}", this.ppnr + 1);
}
internal double GetFlow()
{
var interval = 1000;
var timeout = 6;// 0;
var referenceV = 0D;
var waitHandle = new ManualResetEventSlim();
var timer = new System.Timers.Timer
{
AutoReset = true,
Enabled = true,
Interval = interval,
};
void ReceiveFlow(double value, string _)
{
timeout = 0;
referenceV = value;
timer.Stop();
waitHandle.Set();
}
void TimerElapsed(object _, ElapsedEventArgs _1)
{
if (timeout < 0)
{
timeout = 0;
timer.Stop();
waitHandle.Set();
}
else
{
this.Set(timeout, "... {0}", this.ppnr + 2);
}
timeout--;
}
timer.Elapsed += TimerElapsed;
this.signarR.StopReferenceMessurement += ReceiveFlow;
timer.Start();
this.signarR.SendStopReferenceMessurement();
waitHandle.Wait(timeout * interval);
waitHandle.Reset();
this.signarR.StopReferenceMessurement -= ReceiveFlow;
timer.Elapsed -= TimerElapsed;
waitHandle.Wait(1000);
this.Set(referenceV, "{0:0.00000000}", this.ppnr);
this.Set(default(string), "{0}", this.ppnr + 2);
return referenceV;
}
internal void Stop()
{
this.signarR.SendStopFlow();
this.ppnr = 0;
}
public override void Dispose()
{
try
{
this.signarR.SendStopFlow();
this.signarR.Disconnect();
}
catch (Exception e)
{
File.AppendAllText(this.outputFile, $"[{DateTime.Now}][...] {e}{Environment.NewLine}");
}
base.Dispose();
}
private void SignarR_StateChanged(string value, string groupName)
{
File.AppendAllText(this.outputFile, $"[{DateTime.Now}][{groupName}] {value}{Environment.NewLine}");
}
}
}
@@ -0,0 +1,100 @@
namespace InspectionUI.ViewModels
{
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
public abstract class VM : INotifyPropertyChanged, IDisposable
{
private static readonly Dispatcher dispatcher = Application.Current.Dispatcher;
protected VM()
{
App.Exiting += this.Dispose;
}
public event PropertyChangedEventHandler PropertyChanged;
public virtual void Dispose()
{
App.Exiting -= this.Dispose;
}
protected void NotifyPropertyChanged(string propertyName = "")
{
if (this.PropertyChanged != null)
{
dispatcher.Invoke(new Action(() =>
{
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}));
}
}
protected void InvokeAsync(Action action)
{
dispatcher.Invoke(action);
}
protected void Set(Action propertySetterAction, [CallerMemberName] string property = "")
{
this.InvokeAsync(propertySetterAction);
this.NotifyPropertyChanged(property);
}
protected class Command : ICommand
{
private readonly Action executable;
public Command(Action executable)
{
this.executable = executable;
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object _)
{
return this.executable != null;
}
public void Execute(object _)
{
this.executable?.Invoke();
}
}
protected class Command<T> : ICommand
{
private readonly Action<T> executable;
public Command(Action<T> executable)
{
this.executable = executable;
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object _)
{
return this.executable != null;
}
public void Execute(object parameter)
{
this.executable?.Invoke(parameter is T t ? t : default(T));
}
}
}
}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.3" targetFramework="net48" requireReinstallation="true" />
</packages>
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="PSNR" value="2015"/>
<add key="Type" value="T2" />
<add key="COMPorts" value="COM4" />
<add key="ExchangeHubURL" value="http://sla12iis01.emea.sensus.net/LaaProductionWeb" />
<!--<add key="ExchangeHubURL" value="http://localhost:52822/LaaProductionWeb"/>-->
<!--<add key="OmniDB" value="Server=SLASQL01.emea.sensus.net; Database=AuftragKopie; User ID=sa; Password=sqlserver;" />-->
<add key="OmniDB" value="Server=SLASQL01.emea.sensus.net; Database=Auftrag; User ID=sa; Password=sqlserver;" />
</appSettings>
</configuration>
-151
View File
@@ -1,151 +0,0 @@
<Application x:Class="OMNIPruefung.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Helpers="clr-namespace:OMNIPruefung.Helpers"
xmlns:ContentV="clr-namespace:OMNIPruefung.Views.Content"
xmlns:OptionsV="clr-namespace:OMNIPruefung.Views.Options"
xmlns:ContentVM="clr-namespace:OMNIPruefung.ViewModels.Content"
xmlns:OptionsVM="clr-namespace:OMNIPruefung.ViewModels.Options"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style TargetType="Label">
<Setter Property="FontFamily" Value="Consolas" />
<Setter Property="Padding" Value="0" />
</Style>
<Style TargetType="TextBox">
<Setter Property="Padding" Value="3, 5" />
<Setter Property="FontFamily" Value="Consolas" />
</Style>
<Style TargetType="Button">
<Setter Property="FontFamily" Value="Consolas" />
</Style>
<SolidColorBrush x:Key="LightBlue" Color="#ECF0F1" />
<SolidColorBrush x:Key="DarkBlue" Color="#003595" />
<SolidColorBrush x:Key="Blue" Color="#0072CE" />
<SolidColorBrush x:Key="HoverBlue" Color="#110072CE" />
<SolidColorBrush x:Key="Green" Color="#71D54C" />
<SolidColorBrush x:Key="HoverGreen" Color="#1171D54C" />
<SolidColorBrush x:Key="Red" Color="#CF2E2E" />
<SolidColorBrush x:Key="HoverRed" Color="#11F78DA7" />
<Style x:Key="SystemBtn" TargetType="{x:Type Button}">
<Setter Property="Background" Value="{x:Static SystemColors.ControlBrush}" />
<Setter Property="BorderBrush" Value="{x:Static SystemColors.ControlBrush}" />
<Setter Property="Foreground" Value="{x:Static SystemColors.ControlTextBrush}" />
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FontFamily" Value="Consolas" />
<Setter Property="FontWeight" Value="SemiBold" />
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Margin" Value="13, 0, 0, 0" />
<Setter Property="Padding" Value="13, 8"/>
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="border"
CornerRadius="3.5"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<ContentPresenter x:Name="contentPresenter"
Focusable="False"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
Margin="{TemplateBinding Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" TargetName="border" Value="{x:Static SystemColors.ControlLightBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static SystemColors.ControlDarkBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Background" TargetName="border" Value="{x:Static SystemColors.ControlLightBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static SystemColors.ControlDarkBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="border" Value="{x:Static SystemColors.ControlLightBrush}"/>
<Setter Property="BorderBrush" TargetName="border" Value="{x:Static SystemColors.ControlDarkBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Helpers:BooleanVisibilityConverter x:Key="BooleanVisibility" />
<Helpers:BooleanProgressBackgroundConverter x:Key="BooleanProgress" />
<Style x:Key="RadioNodeStyle" TargetType="{x:Type RadioButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}">
<ContentPresenter SnapsToDevicePixels="True" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#55f0f0f0" />
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Background" Value="AliceBlue" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsChecked" Value="True" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="AliceBlue" />
</MultiTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type OptionsVM:MainOptionVM}">
<OptionsV:Option DataContext="{Binding .}" Icon="/Images/folder.png"/>
</DataTemplate>
<DataTemplate DataType="{x:Type OptionsVM:ExchangeHubOptionVM}">
<OptionsV:Option DataContext="{Binding .}" Icon="/Images/folder.png"/>
</DataTemplate>
<DataTemplate DataType="{x:Type OptionsVM:EOLOptionVM}">
<OptionsV:Option DataContext="{Binding .}" Icon="/Images/folder.png"/>
</DataTemplate>
<DataTemplate DataType="{x:Type OptionsVM:COMOptionVM}">
<OptionsV:COMOption DataContext="{Binding .}" ProgressIcon="/Images/meter.png"/>
</DataTemplate>
<DataTemplate DataType="{x:Type ContentVM:MainContentVM}">
<Label Content="{Binding Header}" />
</DataTemplate>
<DataTemplate DataType="{x:Type ContentVM:ExchangeHubContentVM}">
<ContentV:ExchangeHub DataContext="{Binding .}" />
</DataTemplate>
<DataTemplate DataType="{x:Type ContentVM:EOLContentVM}">
<ContentV:EOLContent DataContext="{Binding .}" />
</DataTemplate>
<DataTemplate DataType="{x:Type ContentVM:COMContentVM}">
<ContentV:COMContent DataContext="{Binding .}" />
</DataTemplate>
<!--<a href="https://www.flaticon.com/free-icons/folder" title="folder icons">Folder icons created by kmg design - Flaticon</a>-->
<!--<a href="https://www.flaticon.com/free-icons/water-meter" title="water meter icons">Water meter icons created by Umeicon - Flaticon</a>-->
<!--<a href="https://www.flaticon.com/free-icons/settings" title="settings icons">Settings icons created by Freepik - Flaticon</a>-->
</Application.Resources>
</Application>
-27
View File
@@ -1,27 +0,0 @@
namespace OMNIPruefung
{
using System;
using System.IO;
using System.Windows;
using System.Windows.Threading;
public partial class App : Application
{
public static readonly string ExePath = typeof(App).Assembly.Location;
public static readonly string ExeDirectory = new FileInfo(ExePath).DirectoryName;
public static event Action Disposed;
public static void Invoke(Action action)
=> Current.Dispatcher.Invoke(action, DispatcherPriority.ApplicationIdle);
public static void BeginInvoke(Action action)
=> Current.Dispatcher.BeginInvoke(action, DispatcherPriority.ApplicationIdle);
public static void NotifyDisposed()
=> Disposed?.Invoke();
protected override void OnExit(ExitEventArgs _)
=> NotifyDisposed();
}
}
@@ -1,9 +0,0 @@
<Window x:Class="OMNIPruefung.EOLWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="450"
Width="800">
<DataGrid Background="White" HeadersVisibility="None" >
</DataGrid>
</Window>
@@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace OMNIPruefung
{
/// <summary>
/// Interaction logic for EOLWindow.xaml
/// </summary>
public partial class EOLWindow : Window
{
public EOLWindow()
{
InitializeComponent();
}
}
}
@@ -1,44 +0,0 @@
namespace OMNIPruefung.Helpers
{
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
public class BooleanProgressBackgroundConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool boolean)
{
if (boolean)
{
return Brushes.Green;
}
else
{
return Brushes.Red;
}
}
return Brushes.Gray;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Brush brush)
{
if (brush == Brushes.Green)
{
return true;
}
else if (brush == Brushes.Red)
{
return false;
}
}
return default(bool?);
}
}
}
@@ -1,16 +0,0 @@
namespace OMNIPruefung.Helpers
{
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
public class BooleanVisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> value is bool visible && visible ? Visibility.Visible : Visibility.Collapsed;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> value is Visibility visibility && visibility == Visibility.Visible;
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 B

@@ -1,47 +0,0 @@
<Window x:Class="OMNIPruefung.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ContentVM="clr-namespace:OMNIPruefung.ViewModels.Content"
Icon="/Images/logo.png"
Background="LightGray"
Title="OMNI+ Pruefung"
Height="450"
Width="800">
<Window.DataContext>
<ContentVM:MainContentVM />
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="230" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0"
Background="White"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Options}" Margin="2, 0"/>
</ScrollViewer>
<GridSplitter Grid.Column="1"
ResizeDirection="Columns"
ResizeBehavior="PreviousAndNext"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="LightGray"
Width="3"/>
<DockPanel Grid.Column="2"
Background="White">
<ContentControl Content="{Binding Content}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="White"/>
</DockPanel>
</Grid>
</Window>
@@ -1,81 +0,0 @@
namespace OMNIPruefung.Models
{
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
public class Appsettings
{
private static readonly Configuration configuration
= ConfigurationManager.OpenExeConfiguration(App.ExePath);
private static readonly KeyValueConfigurationCollection appsettings
= configuration.AppSettings.Settings;
public event Action StateChanged;
public string this[string key]
{
get
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentNullException(nameof(key), "Should not be null or white space.");
}
var existingKey = appsettings.AllKeys.FirstOrDefault(x => x.Equals(key, StringComparison.OrdinalIgnoreCase));
if (string.IsNullOrWhiteSpace(existingKey))
{
appsettings.Add(key, string.Empty);
}
return appsettings[key].Value;
}
set
{
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentNullException(nameof(key), "Should not be null or white space.");
}
var existingKey = appsettings.AllKeys.FirstOrDefault(x => x.Equals(key, StringComparison.OrdinalIgnoreCase));
if (string.IsNullOrWhiteSpace(existingKey))
{
appsettings.Add(key, string.Empty);
}
appsettings[key].Value = value;
configuration.Save(ConfigurationSaveMode.Full, true);
this.StateChanged?.Invoke();
}
}
public string PSNR => this[nameof(PSNR)];
public IEnumerable<string> AllKeys => appsettings.AllKeys;
public string ExchangeHubURL
{
get => this[nameof(this.ExchangeHubURL)];
set => this[nameof(this.ExchangeHubURL)] = value;
}
public string ExchangeHubOutputDir
{
get => this[nameof(this.ExchangeHubOutputDir)];
set => this[nameof(this.ExchangeHubOutputDir)] = value;
}
internal COMPorts COMPorts
=> new COMPorts(this[nameof(COMPorts)]
?.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
?? new string[] { });
public string OmniDB => this[nameof(OmniDB)];
internal static readonly Appsettings Current = new Appsettings();
}
}
@@ -1,37 +0,0 @@
namespace OMNIPruefung.Models
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO.Ports;
internal class COMPorts : IEnumerable<string>
{
private readonly string[] comports;
private readonly string[] existing;
public COMPorts(string[] comports)
{
this.comports = comports;
this.existing = SerialPort.GetPortNames();
}
public bool Exists(string portName)
{
return Array.IndexOf(this.existing, portName) >= 0;
}
public IEnumerator<string> GetEnumerator()
{
foreach (var portName in this.comports)
{
yield return portName;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}
@@ -1,27 +0,0 @@
namespace OMNIPruefung.Models
{
using OmniPlus;
public class EOLContentM
{
private readonly OmniIrdaEOL eol;
public EOLContentM()
{
this.eol = new OmniIrdaEOL(Appsettings.Current.OmniDB);
}
public void Load()
{
//var comports = new COMPorts();
//foreach (var portName in comports)
//{
// if (comports.Exists(portName))
// {
// this.eol.AddConnection(portName);
// }
//}
}
}
}
@@ -1,21 +0,0 @@
namespace OMNIPruefung.Models
{
using OmniPlus;
public class OmniInspectionModel
{
private OmniDatabase database;
public OmniInspectionModel()
{
this.database = new OmniDatabase(Appsettings.Current.OmniDB);
}
public OmniAuftrag Auftrag { get; private set; }
public void LoadAuftrag(string suchNr)
{
this.Auftrag = this.database.LoadAuftrag(suchNr);
}
}
}
@@ -1,26 +0,0 @@
<Window x:Class="OMNIPruefung.OmniInspection"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:VM="clr-namespace:OMNIPruefung.ViewModels"
Height="600"
Width="977">
<Window.DataContext>
<VM:OmniInspectionVM />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding SuchNr}" Width="150" Margin="5" FontFamily="Consolas" />
<Button Grid.Column="1" Command="{Binding Load}" Content="Load" Margin="5" Padding="5" FontFamily="Consolas" />
<Label Grid.Column="2" Content="{Binding AuftragVM}" />
</Grid>
</Grid>
</Window>
@@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace OMNIPruefung
{
/// <summary>
/// Interaction logic for OmniInspection.xaml
/// </summary>
public partial class OmniInspection : Window
{
public OmniInspection()
{
InitializeComponent();
}
}
}
@@ -1,25 +0,0 @@
namespace OMNIPruefung.ViewModels.Base
{
using System;
using System.Windows.Input;
public class Command : ICommand
{
private readonly Action commandHandler;
public Command(Action commandHandler)
=> this.commandHandler = commandHandler;
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object parameter)
=> this.commandHandler != null;
public void Execute(object parameter)
=> this.commandHandler?.Invoke();
}
}
@@ -1,25 +0,0 @@
namespace OMNIPruefung.ViewModels.Base
{
using System;
using System.Windows.Input;
public class Command<T> : ICommand
{
private readonly Action<T> commandCallback;
public Command(Action<T> commandCallback)
=> this.commandCallback = commandCallback;
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object parameter)
=> this.commandCallback != null;
public void Execute(object parameter)
=> this.commandCallback?.Invoke(parameter is T value ? value : default(T));
}
}
@@ -1,19 +0,0 @@
namespace OMNIPruefung.ViewModels.Base
{
using System.ComponentModel;
public abstract class VM<T> : INotifyPropertyChanged where T : VM<T>
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string property)
=> this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
protected void Set<T>(ref T oldValue, T newValue, string property)
{
oldValue = newValue;
this.NotifyPropertyChanged(property);
}
}
}
@@ -1,49 +0,0 @@
namespace OMNIPruefung.ViewModels
{
using System;
using System.ComponentModel;
using System.Windows.Input;
public abstract class BaseVM : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string property)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
}
protected void Set<T>(ref T oldValue, T newValue, string property)
{
oldValue = newValue;
this.NotifyPropertyChanged(property);
}
protected class Command : ICommand
{
private readonly Action executable;
public Command(Action executable)
{
this.executable = executable;
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object _)
{
return this.executable != null;
}
public void Execute(object _)
{
this.executable?.Invoke();
}
}
}
}
@@ -1,722 +0,0 @@
namespace OMNIPruefung.ViewModels.Content
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using OmniPlus;
using OmniPlus.Features;
using OmniPlus.Features.Enums;
using OmniPlus.Inspection;
using OMNIPruefung.Models;
using OMNIPruefung.ViewModels.Base;
using OMNIPruefung.ViewModels.Features;
using OMNIPruefung.ViewModels.Options;
public class COMContentVM : ContentVM
{
private readonly IDictionary<OmniPlusTestPoint, OmniPlusTest> results
= new SortedDictionary<OmniPlusTestPoint, OmniPlusTest>();
private OmniConnection connection;
private OmniDatabase database;
public COMContentVM() : base()
{
this.Meter = new OMNIPlusVM();
this.Option = new COMOptionVM(this);
this.Option.OptionSelected += this.NotifyOptionSelected;
this.database = new OmniDatabase(Appsettings.Current.OmniDB);
}
private int nr;
public int Nr
{
get => this.nr;
set
{
this.nr = value;
this.NotifyPropertyChanged(nameof(this.Nr));
}
}
private string portName;
public string PortName
{
get => this.portName;
set
{
this.portName = value;
this.connection = new OmniIrdaConnection(value);
this.NotifyPropertyChanged(nameof(this.PortName));
}
}
private int progress;
public int Progress
{
get => this.progress;
set
{
this.progress = value;
this.NotifyPropertyChanged(nameof(this.Progress));
}
}
private bool running;
public bool Running
{
get => this.running;
set
{
this.running = value;
this.NotifyPropertyChanged(nameof(this.Running));
}
}
private bool connected;
public bool Connected
{
get => this.connected;
set
{
this.connected = value;
this.NotifyPropertyChanged(nameof(this.Connected));
}
}
private bool visible;
public bool Visible
{
get => this.visible;
set
{
this.visible = value;
this.NotifyPropertyChanged(nameof(this.Visible));
}
}
private bool isvalid = true;
public bool IsValid
{
get => this.isvalid;
set
{
this.isvalid = value;
this.NotifyPropertyChanged(nameof(this.IsValid));
}
}
private string state;
public string State
{
get => this.state;
set
{
this.state = value;
this.NotifyPropertyChanged(nameof(this.State));
}
}
public OMNIPlusVM Meter { get; }
internal void CancelExecution()
{
this.Dispose();
this.State = "Prüfung abgebrochen.";
this.Connected = false;
this.Running = false;
}
internal Task InitializeAsync(CancellationToken cancellationToken)
{
cancellationToken.Register(this.CancelExecution);
void Initialize()
{
this.results.Clear();
this.Header = $"{this.PortName}";
this.State = this.Header;
try
{
this.connection.Open();
this.Connected = true;
this.Running = true;
if (this.IsRunning())
{
this.Header = $"{this.PortName}";
this.State = $"{this.PortName} verbunden";
}
else
{
this.connection.Close();
this.Header = $"{this.PortName} - nicht verbunden!";
this.State = this.Header;
}
}
catch (Exception e)
{
this.connection.Close();
this.Header = $"({this.PortName} - {e.Message}!)";
this.State = this.Header;
}
}
return Task.Factory.StartNew(Initialize, cancellationToken);
}
internal Task ReadSystemParametersAsync(CancellationToken cancelationToken)
{
cancelationToken.Register(this.CancelExecution);
void ReadSystemParameters()
{
if (this.IsRunning())
{
var response = this.connection.ViewSystemParameters();
App.Invoke(() =>
{
this.Running = response.Status == Status.Completed;
this.IsValid = response.IsValid;
this.Header = response.BuildInfo.Value;
this.Progress += 10;
this.Meter.Add(response);
});
}
}
return Task.Factory.StartNew(ReadSystemParameters, cancelationToken);
}
internal Task SetInputVolumeAsync(OmniPlusType defaults, CancellationToken cancelationToken)
{
cancelationToken.Register(this.CancelExecution);
void SetInputVolume()
{
if (this.IsRunning())
{
var response = this.connection.Set(defaults.InputVolume);
this.Running = response.Status == Status.Completed;
this.IsValid = this.Running;
this.Progress += 10;
if (this.IsValid)
{
this.Meter.Add(defaults.InputVolume);
this.State = $"{this.Header}";
}
else
{
this.State = $"{this.Header} - {response.Status}";
}
}
}
return Task.Factory.StartNew(SetInputVolume, cancelationToken);
}
internal Task StartPPCalibrationAsync(OmniPlusTestPoint pp, CancellationToken cancellationToken)
{
cancellationToken.Register(this.CancelExecution);
void StartPPCalibration()
{
this.results[pp] = new OmniPlusTest();
if (this.IsRunning())
{
var rotations = pp.Rotations;
var duration = pp.Duration;
var response = connection.StartChamberCalibration(pp.Rotations, pp.Duration);
this.Running = response.Status == Status.Completed;
this.IsValid = response.Completed && response.Control == ChamberCalibrationResponse.TEST_ACTIVATED;
this.Progress += 10;
this.Meter.Add(pp);
if (this.IsValid)
{
this.State = $"{this.Header} PP {rotations}/{duration}";
}
else
{
this.State = $"{this.Header} PP {rotations}/{duration}, Status:{response.Status}, Control:{response.Control}";
}
}
}
return Task.Factory.StartNew(StartPPCalibration, cancellationToken);
}
internal Task StopPPCalibrationAsync(OmniPlusTestPoint pp, double referenceFlowM3S, CancellationToken cancellationToken)
{
cancellationToken.Register(this.CancelExecution);
void StopPPCalibration()
{
if (this.IsRunning())
{
var response = connection.ViewChamberCalibration();
this.results[pp].Rotations = response.Rotations;
this.results[pp].Duration = response.Duration;
this.results[pp].MeterFlowM3S = pp.MeterFlowM3S(this.results[pp]);
this.results[pp].ReferenceFlowM3S = referenceFlowM3S;
this.Running = response.Status == Status.Completed;
this.IsValid = response.Completed && response.Control == ChamberCalibrationResponse.TEST_COMPLETED;
this.Meter.Add(this.results[pp]);
if (this.IsValid)
{
this.State = $"{this.Header} PP {pp.Rotations}/{pp.Duration} - completed.";
}
else
{
this.State = $"{this.Header} PP {pp.Rotations}/{pp.Duration} failed: Status:{response.Status}, Control:{response.Control}";
}
}
this.Progress += 10;
}
return Task.Factory.StartNew(StopPPCalibration, cancellationToken);
}
internal Task SetRegisterSettingsAsync(CancellationToken cancellationToken)
{
cancellationToken.Register(this.CancelExecution);
void SetRegisterSettings()
{
if (this.IsRunning())
{
var registerSettings = new RegisterSettings();
registerSettings.IntPart = this.Meter.IntPart;
registerSettings.Fraction = this.Meter.Fraction;
registerSettings.Size = this.Meter.Size;
registerSettings.Range = this.Meter.Range;
registerSettings.VolumePerPulseUnit = 0x00;
registerSettings.MeterUnits = (byte)MessurementUnits.CubicMeters;
registerSettings.FlowUnits = (byte)MessurementUnits.CubicMeters;
registerSettings.FlowRate = (byte)TimeUnits.Hours;
registerSettings.FactoryCorrection = 33;
registerSettings.FieldCorrection = 0x00;
registerSettings.PulseWeight = 0;
registerSettings.PulseWidth = 7;
registerSettings.PulseUpdate = 0;
var response = this.connection.Set(registerSettings);
if (response.Status == Status.Completed)
{
this.Meter.AddResult($">>> Correction Factor", $"{registerSettings.FactoryCorrection / 10D:0.00} %");
}
else
{
this.Meter.AddResult($">>> !!! Correction Factor", $"{registerSettings.FactoryCorrection / 10D:0.00} %");
}
}
}
return Task.Factory.StartNew(SetRegisterSettings, cancellationToken);
}
internal Task FinishInspectionAsync(CancellationToken cancellationToken)
{
cancellationToken.Register(this.CancelExecution);
void FinishInspection()
{
//if (!this.IsRunning())
//{
// return;
//}
//var configurationParameters = this.connection.ViewConfigurationParameters();
//var canContinue = configurationParameters.Succeeded;
//// if (canContinue)
//{
// this.Meter.Add(configurationParameters);
// // TODO: Uncomment in production
// // var systemTimeReset = connection.SetSystemTime();
// //canContinue = systemTimeReset.Succeeded;
//}
//// if (canContinue)
//{
// var registerSettings = new RegisterSettings();
// registerSettings.IntPart = this.Meter.IntPart;
// registerSettings.Fraction = this.Meter.Fraction;
// registerSettings.Size = this.Meter.Size;
// registerSettings.Range = this.Meter.Range;
// registerSettings.VolumePerPulseUnit = 0x00;
// registerSettings.MeterUnits = (byte)MessurementUnits.USGallons;
// registerSettings.FlowUnits = (byte)MessurementUnits.USGallons;
// registerSettings.FlowRate = (byte)TimeUnits.Minutes;
// registerSettings.FactoryCorrection = this.Meter.FactoryCorrection;
// registerSettings.FieldCorrection = 0x00;
// registerSettings.PulseWeight = 0x01;
// registerSettings.PulseWidth = 0x02;
// registerSettings.PulseUpdate = 0x00;
// var response = this.connection.Set(registerSettings);
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var configurationParametersSet = new ConfigurationParametersSet();
// configurationParametersSet.ProgrammableID = this.Meter.BuildInfo;
// configurationParametersSet.FactoryID = this.Meter.BuildInfo;
// configurationParametersSet.NumberOfReadingDigits = 8;
// configurationParametersSet.ReadingPreset = "000000000";
// configurationParametersSet.OptionalUniDirFields = 1;
// configurationParametersSet.AlarmPercistancePeriodDays = 31;
// configurationParametersSet.DataLogIntervalMinutes = 60;
// configurationParametersSet.ManifacturingTime = Epoch20000101.UTCNow - 30000;
// configurationParametersSet.SystemTime = Epoch20000101.UTCNow;
// configurationParametersSet.RebootCount = 0;
// configurationParametersSet.BuildInfo = this.Meter.BuildInfo;
// var response = this.connection.Set(configurationParametersSet);
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var response = this.connection.ClearDisplay();
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var response = this.connection.Set(new LeakAlarm
// {
// FlowRateGal = 0.25F, // 0.25 gpm
// TimeLimit = 24 * 60 * 60 // 24 hours => 86400sec
// });
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var response = this.connection.Set(new HighFlowAlarm
// {
// FlowRateGal = 25F, // 25 gpm
// TimeLimit = 1 * 60 * 60 // 1 hours => 86400sec
// });
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var response = this.connection.Set(new ReverseFlowAlarm
// {
// FlowRateGal = -1F, // -1 gpm
// TimeLimit = 60 // 1 hours => 86400sec
// });
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var response = this.connection.ClearAlarms();
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var alarmsState = this.connection.ViewAlarmsState();
// canContinue = alarmsState.Succeeded;
// //&& alarmsState.UsrEnabled
// //&& alarmsState.PreEnabledInactive;
// //TODO: Check alarms
//}
//// if (canContinue)
//{
// var response = this.connection.EnableNFC();
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var registerSettingsAfter = this.connection.ViewRegisterSettings();
// //canContinue = registerSettingsAfter.Succeeded
// // && meter.Compare(registerSettingsAfter);
//}
//// if (canContinue)
//{
// var systemParametersAfter = this.connection.ViewSystemParameters();
// canContinue = systemParametersAfter.Succeeded;
// //&& meter.Compare(systemParametersAfter);
//}
//// if (canContinue)
//{
// var configurationParametersAfter = this.connection.ViewConfigurationParameters();
// canContinue = configurationParametersAfter.Succeeded;
// //&& meter.Compare(configurationParametersAfter);
//}
//// if (canContinue)
//{
// var alarmsState = this.connection.ViewAlarmsState();
// canContinue = alarmsState.Succeeded;
// //&& alarmsState.UsrEnabled
// //&& alarmsState.PreEnabledInactive;
//}
//// if (canContinue)
//{
// var response = this.connection.ViewAlarmSettings(0x01);
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var response = this.connection.ViewAlarmSettings(0x02);
// canContinue = response.Succeeded;
//}
//// if (canContinue)
//{
// var response = this.connection.ViewAlarmSettings(0x04);
// canContinue = response.Succeeded;
//}
//if (canContinue)
//{
// //connection.Set(new FactorySeal
// //{
// // Sealed = true,
// //});
// //var factorySeal = connection.ViewFactorySeal();
// //canContinue = factorySeal.Succeeded && factorySeal.Sealed;
//}
this.Progress = 100;
}
return Task.Factory.StartNew(FinishInspection, cancellationToken);
}
internal Task GetRegisterSettingsAsync(CancellationToken cancellationToken)
{
cancellationToken.Register(this.CancelExecution);
void GetRegisterSettings()
{
if (this.IsRunning())
{
var response = this.connection.ViewRegisterSettings();
if (response.Completed)
{
this.Meter.AddResult("<<< Correction factor", $"{(response.FactoryCorrection / 10D):0.00} %");
}
else
{
this.Meter.AddResult("<<< !!! Correction factor", $"{(response.FactoryCorrection / 10D):0.00} %");
}
}
}
return Task.Factory.StartNew(GetRegisterSettings, cancellationToken);
}
internal double GetCorrectionFactor()
{
var orderedResults = this.results
.OrderBy(x => x.Key.GPM);
var accuracies = orderedResults
.Select(x => x.Value.AccuracyPercentage())
.ToArray();
var correction = accuracies.GetCorrectionFactor();
this.State = $"{this.Header}, correction: {correction:0.00} %";
this.Meter.AddFactoryCorrection(correction);
this.Meter.AddResult(string.Empty, string.Empty);
var correctionUnit = 1 + correction / 100;
var testPoints = orderedResults
.Select(x => x.Key)
.ToArray();
var length = testPoints.Length;
for (int i = 0; i < length; i++)
{
var testPoint = testPoints[i];
var accuracy = accuracies[i];
var _accuracy = accuracy * correctionUnit;
var state = "Out Of Range";
if (testPoint.MinDiff <= _accuracy && _accuracy <= testPoint.MaxDiff)
{
state = "OK";
}
else if (this.IsValid)
{
this.IsValid = false;
}
this.Meter.AddResult($"{accuracy:0.00} %", $"{_accuracy:0.00} % - ({state})");
}
return correction;
}
public override void Dispose()
{
try
{
this.connection?.Close();
}
catch (Exception e)
{
this.State = e.Message;
}
}
public bool IsRunning()
{
if (!this.Running)
{
return false;
}
return this.Connected;
}
internal Task ReadDisplayAsync(CancellationToken cancellationToken)
{
void ReadDisplay()
{
var response = this.connection.ViewReadings();
this.Meter.AddResult($"<<< Display value", response.Value);
}
return Task.Factory.StartNew(ReadDisplay, cancellationToken);
}
public Task GetStateIfNewAsync(CancellationToken cancellationToken)
{
void GetState()
{
var buildInfo = this.connection.ViewBuildInformation();
if (buildInfo.Status != Status.Completed)
{
return;
}
var omniID = buildInfo.Value;
if (string.IsNullOrWhiteSpace(omniID))
{
return;
}
//else if (this.database.OMNIPlus_Exists(omniID))
//{
// return;
//}
var commands = new List<byte[]>();
commands.Add(new byte[] { 0x01 });
commands.Add(new byte[] { 0x03 });
commands.Add(new byte[] { 0x05 });
commands.Add(new byte[] { 0x07 });
commands.Add(new byte[] { 0x09 });
commands.Add(new byte[] { 0x0B });
commands.Add(new byte[] { 0x0D });
commands.Add(new byte[] { 0x0F });
commands.Add(new byte[] { 0x11 });
commands.Add(new byte[] { 0x13 });
commands.Add(new byte[] { 0x15 });
commands.Add(new byte[] { 0x17 });
commands.Add(new byte[] { 0x1F });
commands.Add(new byte[] { 0x21 });
commands.Add(new byte[] { 0x25 });
commands.Add(new byte[] { 0x27 });
commands.Add(new byte[] { 0x29 });
commands.Add(new byte[] { 0x2B });
commands.Add(new byte[] { 0xFD, 0x02 });
commands.Add(new byte[] { 0xFD, 0x05 });
commands.Add(new byte[] { 0xFD, 0x06 });
commands.Add(new byte[] { 0xFD, 0x08 });
commands.Add(new byte[] { 0xFD, 0x0A });
commands.Add(new byte[] { 0xFD, 0x0E });
commands.Add(new byte[] { 0xFD, 0x10 });
commands.Add(new byte[] { 0xFD, 0x12 });
commands.Add(new byte[] { 0xFD, 0x14 });
commands.Add(new byte[] { 0xFD, 0x22 });
commands.Add(new byte[] { 0xFD, 0x24 });
commands.Add(new byte[] { 0xFD, 0x26 });
commands.Add(new byte[] { 0xFD, 0x28 });
commands.Add(new byte[] { 0xFD, 0x39 });
commands.Add(new byte[] { 0xFD, 0x3D });
commands.Add(new byte[] { 0xFD, 0x55 });
commands.Add(new byte[] { 0xFD, 0x63 });
commands.Add(new byte[] { 0xFD, 0x7B });
commands.Add(new byte[] { 0xFD, 0x7E, 0x00 });
commands.Add(new byte[] { 0xFD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
commands.Add(new byte[] { 0xFD, 0x8B });
commands.Add(new byte[] { 0xFD, 0xA9 });
commands.Add(new byte[] { 0xFD, 0xAA });
commands.Add(new byte[] { 0xFD, 0xAC });
commands.Add(new byte[] { 0xFD, 0xB7 });
commands.Add(new byte[] { 0xFD, 0xBC });
commands.Add(new byte[] { 0xFD, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
commands.Add(new byte[] { 0xFD, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
commands.Add(new byte[] { 0xFD, 0xC4, 0x00 });
commands.Add(new byte[] { 0xFD, 0xC6 });
commands.Add(new byte[] { 0xFD, 0xC7 });
var state = new StringBuilder();
foreach (var cmd in commands)
{
var response = this.connection.Send(cmd);
var entry = $"{BitConverter.ToString(cmd)}:{BitConverter.ToString(response)}";
state.AppendLine(entry);
}
//this.database.OMNIPlus_Insert(omniID, state.ToString());
};
return Task.Factory.StartNew(GetState, cancellationToken);
}
}
}
@@ -1,825 +0,0 @@
namespace OMNIPruefung.ViewModels.Content
{
using ExchangeHub;
using OmniPlus;
using OmniPlus.Inspection;
using OMNIPruefung.Models;
using OMNIPruefung.ViewModels.Base;
using OMNIPruefung.ViewModels.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;
using TimersTimer = System.Timers.Timer;
public class EOLContentVM : ContentVM
{
private static readonly string line = new string('=', 500);
private readonly ExchangeConnection exchangeConnection;
private readonly OmniDatabase dbcontext;
private CancellationTokenSource cancellationTokenSource;
private CancellationToken cancellationToken;
private ManualResetEventSlim awaiter;
private ICollection<Task> tasks;
private TimersTimer timer;
private bool canceled;
public EOLContentVM() : base()
{
this.Header = "EOL";
this.CanStart = true;
this.CanCheck = true;
this.Option = new EOLOptionVM(this);
this.Option.OptionSelected += this.NotifyOptionSelected;
this.tasks = new List<Task>();
this.exchangeConnection = new ExchangeConnection();
this.dbcontext = new OmniDatabase(Appsettings.Current.OmniDB);
this.OmniDefaults = new OmniPlusType();
this.LoadComPorts = new Command(this.PrepareConnections);
this.CancelInspection = new Command(this.CancelInspectionHandler);
this.StartInspection = new Command(this.StartInspectionHandler);
this.CheckInspection = new Command(this.CheckInspectionHandler);
this.ReadDisplay = new Command(this.ReadDisplayCommand);
}
private byte size;
public byte Size
{
get => this.size;
set
{
this.size = value;
this.NotifyPropertyChanged(nameof(this.Type));
}
}
private string type;
public string Type
{
get => this.type;
set
{
this.type = value;
this.NotifyPropertyChanged(nameof(this.Type));
}
}
private string text;
public string Text
{
get => this.text;
set
{
this.text = value;
this.NotifyPropertyChanged(nameof(this.Text));
}
}
private string error;
public string Error
{
get => this.error;
set
{
this.error = value;
this.NotifyPropertyChanged(nameof(this.Error));
}
}
private string state;
public string State
{
get => this.state;
set
{
this.state = value;
this.NotifyPropertyChanged(nameof(this.State));
}
}
private bool canStart;
public bool CanStart
{
get => this.canStart;
set
{
this.canStart = value;
this.NotifyPropertyChanged(nameof(this.CanStart));
}
}
private bool canCheck;
public bool CanCheck
{
get => this.canCheck;
set
{
this.canCheck = value;
this.NotifyPropertyChanged(nameof(this.CanCheck));
}
}
private bool canStop;
public bool CanStop
{
get => this.canStop;
set
{
this.canStop = value;
this.NotifyPropertyChanged(nameof(this.CanStop));
}
}
private int secondsLeft;
public int AvailableIn
{
get => this.secondsLeft;
set
{
this.secondsLeft = value;
this.NotifyPropertyChanged(nameof(this.AvailableIn));
}
}
private string suchnr;
public string SuchNr
{
get => this.suchnr;
set => this.Set(ref this.suchnr, value, nameof(SuchNr));
}
private OmniPlusType omniDefaults;
public OmniPlusType OmniDefaults
{
get => this.omniDefaults;
set
{
this.omniDefaults = value;
this.NotifyPropertyChanged(nameof(this.OmniDefaults));
}
}
public String Line => line;
public ICommand LoadComPorts { get; }
public ICommand CancelInspection { get; }
public ICommand StartInspection { get; }
public ICommand CheckInspection { get; }
public ICommand ReadDisplay { get; }
private string errorLog;
private void PrepareConnections()
{
try
{
this.errorLog = Path.Combine(App.ExeDirectory, $"ui_logs.txt");
File.AppendAllText(this.errorLog, string.Empty);
}
catch (Exception e)
{
this.State = e.ToString();
}
this.exchangeConnection.Connect(Appsettings.Current.ExchangeHubURL);
if (string.IsNullOrWhiteSpace(this.SuchNr) && this.Size == 0 && this.Type is null)
{
this.Error = "FertigungsauftragNr eingeben oder Size und Type auswählen!";
return;
}
this.Error = default(string);
App.Invoke(() =>
{
if (this.Nodes.Any())
{
foreach (var disposable in this.Nodes.Cast<IDisposable>())
{
disposable.Dispose();
}
this.Nodes.Clear();
this.Option.Clear();
}
if (!string.IsNullOrWhiteSpace(this.SuchNr))
{
this.dbcontext.LoadAuftrag(this.SuchNr);
}
else if (this.Size > 0 && !string.IsNullOrWhiteSpace(this.Type))
{
this.dbcontext.LoadAuftrag(this.Size, this.Type);
this.Text = $"ME OMNI 1.5-2\" {this.Type}";
}
});
try
{
App.Invoke(() =>
{
var placeNr = 1;
foreach (var com in Appsettings.Current.COMPorts)
{
var comVM = new COMContentVM();
comVM.ContentSelected += this.NotifyCotnentSelected;
comVM.PortName = com;
comVM.Nr = placeNr++;
comVM.Header = $"{com}";
comVM.State = $"{com}";
this.Nodes.Add(comVM);
this.Option.Add(comVM.Option);
}
this.Option.SetIndentation(this.Option.Indent);
});
var metersVM = this.Nodes.Cast<COMContentVM>();
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.InitializeAsync(cancellationToken));
}
});
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.GetStateIfNewAsync(cancellationToken));
}
});
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.ReadSystemParametersAsync(cancellationToken));
}
}, false);
}
catch (Exception e)
{
this.Error = e.ToString();
this.LogError(e.ToString());
}
App.Invoke(() =>
{
this.CanStop = false;
this.CanStart = true;
this.Error = default(string);
this.State = default(string);
});
}
private void CancelInspectionHandler()
{
this.canceled = true;
this.CanStop = false;
this.CanStart = false;
this.Error = default(string);
this.State = "Warte bis abbruch abgeschlossen ...";
try
{
this.exchangeConnection.SendStopFlow();
this.exchangeConnection.Disconnect();
this.awaiter?.Set();
this.cancellationTokenSource?.Cancel();
this.tasks.Clear();
this.State = "Vorgang wurde abbgebrochen!";
}
catch (Exception e)
{
this.Error = e.ToString();
this.State = default(string);
this.LogError(e.ToString());
}
Task.Factory.StartNew(() =>
{
this.WaitUntil(this.AvailableIn, show: true, error: true);
this.Error = default(string);
this.State = default(string);
});
}
private void StartInspectionHandler()
{
this.canceled = false;
this.CanStart = false;
this.CanStop = true;
this.cancellationTokenSource = new CancellationTokenSource();
this.cancellationToken = this.cancellationTokenSource.Token;
var metersVM = this.Nodes.Cast<COMContentVM>();
this.cancellationToken.Register(() => this.canceled = true);
this.InvokeAsync(() =>
{
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.SetInputVolumeAsync(this.OmniDefaults, cancellationToken));
}
});
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.SetRegisterSettingsAsync(cancellationToken));
}
});
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.GetRegisterSettingsAsync(cancellationToken));
}
});
foreach (var pp in this.OmniDefaults.TestPoints)
{
if (this.canceled)
{
break;
}
var rotations = pp.Rotations;
var duration = pp.Duration;
this.StartFlow(pp.RequiredFlowM3H);
if (this.canceled)
{
break;
}
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.StartPPCalibrationAsync(pp, cancellationToken));
}
});
this.StartReferenceMessurement(duration);
if (this.canceled)
{
break;
}
this.WaitUntil(duration, true, false);
if (this.canceled)
{
break;
}
var referenceFlowM3S = this.GetReferenceFlowM3S();
if (referenceFlowM3S == default(double))
{
break;
}
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.StopPPCalibrationAsync(pp, referenceFlowM3S, cancellationToken));
}
});
if (this.canceled)
{
break;
}
}
this.exchangeConnection.SendStopFlow();
foreach (var meterVM in metersVM)
{
meterVM.GetCorrectionFactor();
}
foreach (var meterVM in metersVM)
{
meterVM.Dispose();
}
this.WaitUntil(this.AvailableIn, show: true);
this.CanStart = true;
this.Error = default(string);
this.State = default(string);
}, this.cancellationToken);
}
private void CheckInspectionHandler()
{
this.canceled = false;
this.CanStart = false;
this.CanStop = true;
this.cancellationTokenSource = new CancellationTokenSource();
this.cancellationToken = this.cancellationTokenSource.Token;
var metersVM = this.Nodes.Cast<COMContentVM>();
this.cancellationToken.Register(() => this.canceled = true);
this.InvokeAsync(() =>
{
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.GetRegisterSettingsAsync(cancellationToken));
}
});
foreach (var pp in this.OmniDefaults.TestPoints)
{
if (this.canceled)
{
break;
}
var rotations = pp.Rotations;
var duration = pp.Duration;
this.StartFlow(pp.RequiredFlowM3H);
if (this.canceled)
{
break;
}
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.StartPPCalibrationAsync(pp, cancellationToken));
}
});
this.StartReferenceMessurement(duration);
if (this.canceled)
{
break;
}
this.WaitUntil(duration, true, false);
if (this.canceled)
{
break;
}
var referenceFlowM3S = this.GetReferenceFlowM3S();
if (referenceFlowM3S == default(double))
{
break;
}
this.WaitUntil((int)(Math.Truncate(duration * 0.2) + 1), true, false);
this.InvokeAsync((tasks, cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.StopPPCalibrationAsync(pp, referenceFlowM3S, cancellationToken));
}
});
if (this.canceled)
{
break;
}
}
this.exchangeConnection.SendStopFlow();
foreach (var meterVM in metersVM)
{
meterVM.GetCorrectionFactor();
}
foreach (var meterVM in metersVM)
{
meterVM.Dispose();
}
this.WaitUntil(this.AvailableIn, show: true);
this.CanStart = true;
this.Error = default(string);
this.State = default(string);
}, this.cancellationToken);
}
private void WaitUntil(int duration, bool show = false, bool error = true)
{
if (duration <= 0)
{
this.AvailableIn = 0;
return;
}
this.CanStart = false;
this.AvailableIn = duration;
this.awaiter = new ManualResetEventSlim();
this.timer = new TimersTimer(1000)
{
AutoReset = true,
Enabled = true
};
this.timer.Elapsed += (_1, _2) =>
{
if (show)
{
if (error)
{
this.State = null;
this.Error = $"Verfügbar in {this.AvailableIn} Sekunden";
}
else
{
this.Error = null;
this.State = $"Noch {this.AvailableIn} Sekunden verbleiben";
}
}
if (this.AvailableIn <= 0)
{
this.AvailableIn = 0;
this.awaiter?.Set();
return;
}
this.AvailableIn -= 1;
};
this.timer.Start();
this.awaiter.Wait(this.AvailableIn * 1000);
this.awaiter = null;
this.timer.Stop();
this.timer = null;
}
private void StartFlow(double volumeM3H)
{
var received = false;
var volume = volumeM3H;
var timeout = 500; // seconds
void FlowStarted(double value, string _)
{
timeout = 0;
received = true;
volume = value;
}
this.exchangeConnection.StartFlow += FlowStarted;
this.exchangeConnection.SendStartFlow(volumeM3H);
this.State = "Warten auf Q(soll) ...";
while (!received && timeout > 0)
{
if (this.canceled)
{
this.AvailableIn = timeout;
break;
}
Thread.Sleep(1000);
timeout--;
this.State = $"Warten auf Q({volumeM3H:0.0000}): {timeout} Sekunden verbleiben ...";
}
this.exchangeConnection.StartFlow -= FlowStarted;
if (!this.canceled)
{
this.State = $"Durchfluss {volume:0.0000} erreicht ...";
}
}
private void StartReferenceMessurement(int duration)
{
var received = false;
var reference = 0;
var timeout = 60; // seconds
void ReferenceMessurementStarted(int seconds, string _)
{
timeout = 0;
received = true;
reference = seconds;
}
this.exchangeConnection.StartReferenceMessurement += ReferenceMessurementStarted;
this.exchangeConnection.SendStartReferenceMessurement(duration);
this.State = "Warten bis RZ gestarted ...";
while (!received && timeout > 0)
{
if (this.canceled)
{
this.AvailableIn = timeout;
break;
}
Thread.Sleep(1000);
timeout--;
this.State = $"Warten bis RZ gestarted: {timeout} Sekunden verbleiben ...";
}
this.exchangeConnection.StartReferenceMessurement -= ReferenceMessurementStarted;
if (!this.canceled)
{
this.State = $"Referenzmessung gestartet ...";
}
}
private double GetReferenceFlowM3S()
{
var received = false;
var referenceV = 0D;
var timeout = 60; // seconds
void ReferenceFlowM3SecReceived(double value, string _)
{
timeout = 0;
received = true;
referenceV = value;
}
this.exchangeConnection.StopReferenceMessurement += ReferenceFlowM3SecReceived;
this.exchangeConnection.SendStopReferenceMessurement();
this.State = "Warten RZ-Ergebnis ...";
while (!received && timeout > 0)
{
if (this.canceled)
{
this.AvailableIn = timeout;
break;
}
Thread.Sleep(1000);
timeout--;
this.State = $"Warten RZ-Ergebnis: {timeout} Sekunden verbleiben ...";
}
this.exchangeConnection.StopReferenceMessurement -= ReferenceFlowM3SecReceived;
if (!this.canceled)
{
this.State = $"Referenzmessung bereit ...";
}
return referenceV;
}
private void InvokeAsync(Action<ICollection<Task>, CancellationToken> action, bool wait = true)
{
this.tasks = new List<Task>();
action?.Invoke(this.tasks, this.cancellationToken);
if (tasks.Any())
{
var handle = Task.Factory
.ContinueWhenAll(this.tasks.ToArray(), _tasks =>
{
foreach (var t in _tasks)
{
if (t.Exception != null)
{
this.LogError($"[{t.Id}]:{t.Exception}{Environment.NewLine}");
}
}
});
if (wait)
{
handle.Wait();
}
this.tasks.Clear();
}
}
private Task InvokeAsync(Action action, CancellationToken cancellationToken)
{
return Task
.Factory
.StartNew(action, cancellationToken)
.ContinueWith(t =>
{
if (t.Exception != null)
{
this.LogError($"[{t.Id}]:{t.Exception}{Environment.NewLine}");
}
});
}
private void LogError(string error)
{
try
{
File.AppendAllText(this.errorLog, error);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private void ReadDisplayCommand()
{
this.cancellationTokenSource = new CancellationTokenSource();
this.cancellationToken = this.cancellationTokenSource.Token;
var metersVM = this.Nodes.Cast<COMContentVM>();
this.InvokeAsync(() =>
{
this.InvokeAsync((tasks, _cancellationToken) =>
{
foreach (var meterVM in metersVM)
{
tasks.Add(meterVM.ReadDisplayAsync(_cancellationToken));
}
});
}, this.cancellationToken);
}
}
}
@@ -1,84 +0,0 @@
namespace OMNIPruefung.ViewModels.Content
{
using ExchangeHub;
using OMNIPruefung.Models;
using OMNIPruefung.ViewModels.Base;
using OMNIPruefung.ViewModels.Options;
using System;
using System.Threading.Tasks;
using System.Windows.Input;
public class ExchangeHubContentVM : ContentVM
{
private readonly ExchangeConnection connection;
public ExchangeHubContentVM() : base()
{
this.Header = "Exchange HUB";
this.Option = new ExchangeHubOptionVM(this);
this.Option.OptionSelected += this.NotifyOptionSelected;
this.Connect = new Command(this.ConnectHubHandler);
this.Disconnect = new Command(this.DisconnectHubHandler);
this.connection = new ExchangeConnection();
this.connection.StateChanged += Connection_StateChanged1;
this.NotifyPropertyChanged(nameof(this.LogContent));
}
private bool connected;
public bool Connected
{
get => this.connected;
set
{
this.connected = value;
this.NotifyPropertyChanged(nameof(this.Connected));
this.NotifyPropertyChanged(nameof(this.Disconnected));
}
}
public bool Disconnected => !this.Connected;
public string LogContent { get; private set; }
public ICommand Connect { get; }
public ICommand Disconnect { get; }
private void ConnectHubHandler()
{
Task.Factory.StartNew(() =>
{
this.connection.Connect(Appsettings.Current.ExchangeHubURL);
});
}
private void Connection_StateChanged1(string value, string groupName)
{
this.LogContent += $"[{groupName}] {value}{Environment.NewLine}";
this.NotifyPropertyChanged(nameof(this.LogContent));
}
private void DisconnectHubHandler()
{
Task.Factory.StartNew(() =>
{
try
{
this.connection.Disconnect();
this.Connected = false;
}
catch (Exception e)
{
this.LogContent += $"{e}{Environment.NewLine}";
this.NotifyPropertyChanged(nameof(this.LogContent));
}
});
}
}
}
@@ -1,44 +0,0 @@
namespace OMNIPruefung.ViewModels.Content
{
using OMNIPruefung.ViewModels.Base;
using System.Collections.ObjectModel;
public class MainContentVM : ContentVM
{
public MainContentVM() : base()
{
this.Content = this;
this.Header = "OMNI+ Prüfung";
this.ContentSelected += this.SetContentSelected;
this.Options = new ObservableCollection<OptionVM>();
// var exchangeHubVM = new ExchangeHubContentVM();
// exchangeHubVM.ContentSelected += this.SetContentSelected;
// this.Options.Add(exchangeHubVM.Option);
// this.Nodes.Add(exchangeHubVM);
var contentEOL = new EOLContentVM();
contentEOL.ContentSelected += this.SetContentSelected;
this.Options.Add(contentEOL.Option);
this.Nodes.Add(contentEOL);
}
private ContentVM content;
public ContentVM Content
{
get => this.content;
set
{
this.content = value;
this.NotifyPropertyChanged(nameof(this.Content));
}
}
public ObservableCollection<OptionVM> Options { get; }
private void SetContentSelected(ContentVM content)
=> this.Content = content;
}
}
@@ -1,56 +0,0 @@
namespace OMNIPruefung.ViewModels.Content
{
using OMNIPruefung.Models;
using OMNIPruefung.ViewModels.Base;
using OMNIPruefung.ViewModels.Options;
using System.Collections.ObjectModel;
using System.Linq;
public class SettingsContentVM : ContentVM
{
private readonly Appsettings appsettings;
public SettingsContentVM()
{
this.Header = "Einstellungen";
this.Option = new SettingsOptionVM(this);
this.Option.OptionSelected += this.NotifyOptionSelected;
this.appsettings = new Appsettings();
var settings = this.appsettings
.AllKeys
.Select(x => new SettingVM(x, this.appsettings));
this.Settings = new ObservableCollection<SettingVM>(settings);
}
public ObservableCollection<SettingVM> Settings { get; }
}
public class SettingVM : VM<SettingVM>
{
private readonly string key;
private readonly Appsettings appsettings;
public SettingVM(string key, Appsettings appsettings)
{
this.key = key;
this.appsettings = appsettings;
}
public string Key => this.key;
private string value;
public string Value
{
get => this.appsettings[this.key];
set
{
this.appsettings[this.key] = value;
this.NotifyPropertyChanged(nameof(this.Value));
}
}
}
}
@@ -1,21 +0,0 @@
namespace OMNIPruefung.ViewModels.Base
{
using System;
public class ContentVM : NodeVM
{
public ContentVM() : base()
{
}
public virtual event Action<ContentVM> ContentSelected;
public OptionVM Option { get; protected set; }
protected void NotifyOptionSelected()
=> this.ContentSelected?.Invoke(this);
protected void NotifyCotnentSelected(ContentVM content)
=> this.ContentSelected?.Invoke(content);
}
}
@@ -1,127 +0,0 @@
namespace OMNIPruefung.ViewModels.Features
{
using OmniPlus;
using OmniPlus.Features;
using OmniPlus.Inspection;
using OMNIPruefung.Models;
using OMNIPruefung.ViewModels.Base;
using System;
using System.Collections.ObjectModel;
using System.Windows;
public class OMNIPlusVM : VM<OMNIPlusVM>
{
// TODO: save all in database
private readonly OmniDatabase database;
public OMNIPlusVM()
{
this.database = new OmniDatabase(Appsettings.Current.OmniDB);
this.Results = new ObservableCollection<Result>();
}
public ushort IntPart { get; internal set; }
public ushort Fraction { get; internal set; }
public byte Size { get; internal set; }
public byte Range { get; internal set; }
public sbyte FactoryCorrection { get; internal set; }
public ObservableCollection<Result> Results { get; }
internal void AddResult(string key, string value)
{
Application.Current.Dispatcher.Invoke(new Action(() =>
{
this.Results.Add(new Result
{
Key = key,
Value = value
});
}));
}
internal void Add(OmniPlus.Features.SystemParameters response)
{
if (response.Completed)
{
this.AddResult(nameof(response.VersionAndType), response.VersionAndType.Value);
this.AddResult(nameof(response.BuildInfo), response.BuildInfo.Value);
this.AddResult(nameof(response.BatteryVoltage), $"{(response.BatteryVoltage.Volts + 0.0001) / 1000:0.0000 V}");
this.AddResult(nameof(response.ManifacturingTime), $"{response.ManifacturingTime.DateTime:dd.MM.yyyy}");
this.AddResult(nameof(response.SystemTime), $"{response.SystemTime.DateTime:dd.MM.yyyy}");
this.AddResult(nameof(response.RebootsCount), $"{response.RebootsCount}");
this.AddResult(nameof(response.FactorySealed), $"{response.FactorySealed}");
}
}
internal void Add(InputVolume response)
{
this.Size = response.Size;
this.Range = response.Range;
this.IntPart = response.IntPartFull;
this.Fraction = response.Fraction;
this.AddResult(string.Empty, string.Empty);
this.AddResult(nameof(InputVolume), string.Empty);
this.AddResult(nameof(response.Size), $"{response.Size}");
this.AddResult(nameof(response.Range), $"{response.Range}");
this.AddResult(nameof(response.Direction), $"{response.Direction}");
this.AddResult(nameof(response.IntPart), $"{response.IntPart}");
this.AddResult(nameof(response.Fraction), $"{response.Fraction}");
}
internal void Add(OmniPlusTestPoint pp)
{
this.AddResult(string.Empty, string.Empty);
this.AddResult("Test point", $"{pp.Rotations}/{pp.Duration:0}");
this.AddResult("Test flow", $"{pp.RequiredFlowM3H:0.00000000 m³/h}");
this.AddResult("Test frame", $"{pp.MinDiff:0.00}% - {pp.MaxDiff:0.00}%");
}
internal void Add(OmniPlusTest test)
{
this.AddResult("Test result:", $"{test.Rotations:0}/{test.Duration:0.0000}");
this.AddResult("Meter flow", $"{test.MeterFlowM3S:0.00000000} m³/h");
this.AddResult("Reference flow", $"{test.ReferenceFlowM3S:0.00000000} m³/h");
this.AddResult("Accuracy", $"{test.AccuracyPercentage():0.00}%");
}
internal void Add(ConfigurationParameters response)
{
this.AddResult(nameof(response.ProgrammableID), response.ProgrammableID.Value);
this.AddResult(nameof(response.FactoryID), response.FactoryID.Value);
this.AddResult(nameof(response.ReadingDigits), $"{response.ReadingDigits.Count}");
this.AddResult(nameof(response.Readings), response.Readings.Value);
this.AddResult("Optional Uni-Dir-Fields", response.OptionalUniDirFields.Value);
this.AddResult("Alarm persistence", $"{response.AlarmPersistenceDays:0 days}");
this.AddResult("Data log interval", $"{response.DataLogIntervalMins:0 min.}");
this.AddResult(nameof(response.DeviceID), response.DeviceID.Value);
}
internal void AddFactoryCorrection(double value)
{
this.FactoryCorrection = (sbyte)(value * 10);
this.AddResult("Correction factor", $"{value:0.00} %");
}
}
public class Result
{
public string Key { get; set; }
public string Value { get; set; }
}
public class Property
{
public string Key { get; set; }
public string Value { get; set; }
}
}
@@ -1,161 +0,0 @@
namespace OMNIPruefung.ViewModels.Features
{
using OmniPlus.Features;
using OMNIPruefung.ViewModels.Base;
using System;
using System.Collections.Generic;
public class OMNISysParameters : VM<OMNIPlusVM>
{
private SystemParameters parameters;
public OMNISysParameters(SystemParameters parameters)
{
this.parameters = parameters;
if (this.parameters is null)
{
this.parameters = new SystemParameters();
}
this.BuildInfo = this.parameters.BuildInfo.Value;
this.Manifactured = this.parameters.ManifacturingTime.DateTime;
this.Timedrift = this.parameters.SystemTime.DateTime;
this.Reboots = this.parameters.RebootsCount;
this.Version = this.parameters.VersionAndType.Value;
var voltage = Math.Max(this.parameters.BatteryVoltage.Volts, (ushort)1);
this.Voltage = voltage / 1000D;
this.ADCCounts = this.parameters.BatteryVoltage.ADCCount;
this.Sealed = this.parameters.FactorySealed;
this.IsValid = this.parameters.IsValid;
}
private string buildInfo;
public string BuildInfo
{
get => this.buildInfo;
set
{
this.buildInfo = value;
this.NotifyPropertyChanged(nameof(this.BuildInfo));
}
}
private DateTime manifactured;
public DateTime Manifactured
{
get => this.manifactured;
set
{
this.manifactured = value;
this.NotifyPropertyChanged(nameof(this.Manifactured));
}
}
private DateTime timedrift;
public DateTime Timedrift
{
get => this.timedrift;
set
{
this.timedrift = value;
this.NotifyPropertyChanged(nameof(this.Timedrift));
}
}
private byte reboots;
public byte Reboots
{
get => this.reboots;
set
{
this.reboots = value;
this.NotifyPropertyChanged(nameof(this.Reboots));
}
}
private string version;
public string Version
{
get => this.version;
set
{
this.version = value;
this.NotifyPropertyChanged(nameof(this.Version));
}
}
private double voltage;
public double Voltage
{
get => this.voltage;
set
{
this.voltage = value;
this.NotifyPropertyChanged(nameof(this.Voltage));
}
}
private uint adc;
public uint ADCCounts
{
get => this.adc;
set
{
this.adc = value;
this.NotifyPropertyChanged(nameof(this.ADCCounts));
}
}
private bool @sealed;
public bool Sealed
{
get => this.@sealed;
set
{
this.@sealed = value;
this.NotifyPropertyChanged(nameof(this.Sealed));
}
}
private bool isvalid;
public bool IsValid
{
get => this.isvalid;
set
{
this.isvalid = value;
this.NotifyPropertyChanged(nameof(this.IsValid));
}
}
public Dictionary<string, string> ToDictionary()
{
var dictionary = new Dictionary<string, string>();
dictionary["Version & Type: "] = this.Version;
dictionary["Build info: "] = this.BuildInfo;
dictionary["Manifactured: "] = $"{this.Manifactured:yyyy-MM-dd}";
dictionary["Last update: "] = $"{this.Timedrift:yyyy-MM-dd HH:mm:ss}";
dictionary["Battery voltage: "] = $"{this.Voltage:0.000}V";
dictionary["ADC counts: "] = $"{this.ADCCounts}";
dictionary["Reboots count: "] = $"{this.Reboots}";
dictionary["Factory sealed: "] = $"{this.Sealed}";
return dictionary;
}
public static implicit operator OMNISysParameters(SystemParameters parameters)
=> new OMNISysParameters(parameters);
}
}
@@ -1,36 +0,0 @@
namespace OMNIPruefung.ViewModels
{
using OMNIPruefung.ViewModels.Base;
using System;
using System.Collections.ObjectModel;
public abstract class NodeVM : VM<NodeVM>, IDisposable
{
protected NodeVM()
{
this.Nodes = new ObservableCollection<NodeVM>();
App.Disposed += this.Dispose;
}
private string header;
public virtual string Header
{
get => this.header;
set
{
this.header = value;
this.NotifyPropertyChanged( nameof(this.Header));
}
}
public ObservableCollection<NodeVM> Nodes { get; }
public virtual void Dispose()
{
}
}
}
@@ -1,14 +0,0 @@
namespace OMNIPruefung.ViewModels
{
using OmniPlus;
public class OmniAuftragVM : BaseVM
{
private OmniAuftrag auftrag;
public OmniAuftragVM(OmniAuftrag auftrag)
{
this.auftrag = auftrag;
}
}
}
@@ -1,31 +0,0 @@
namespace OMNIPruefung.ViewModels
{
using OMNIPruefung.Models;
using System.Windows.Input;
public class OmniInspectionVM : BaseVM
{
private OmniInspectionModel model;
public OmniInspectionVM()
{
this.model = new OmniInspectionModel();
this.Load = new Command(this.LoadComamnd);
}
private string suchNr;
public string SuchNr
{
get => this.suchNr;
set => this.Set(ref this.suchNr, value, nameof(SuchNr));
}
public ICommand Load { get; }
private void LoadComamnd()
{
this.model.LoadAuftrag(this.suchNr);
}
}
}
@@ -1,107 +0,0 @@
namespace OMNIPruefung.ViewModels
{
using OMNIPruefung.ViewModels.Base;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Input;
public class OptionVM : NodeVM
{
const int INDENT = 13;
private readonly NodeVM parent;
public OptionVM(NodeVM parent)
{
this.parent = parent;
this.parent.PropertyChanged += this.Parent_PropertyChanged;
}
public event Action OptionSelected;
private int indent = INDENT;
public int Indent
{
get => this.indent;
set
{
this.indent = value;
this.NotifyPropertyChanged(nameof(this.Indent));
}
}
public override string Header
{
get => this.parent?.Header;
set => this.NotifyPropertyChanged(this.Header);
}
private bool expanded;
public bool IsExpanded
{
get => this.expanded;
set
{
this.expanded = value;
this.NotifyPropertyChanged(nameof(this.IsExpanded));
}
}
private bool selected;
public bool IsSelected
{
get => this.selected;
set
{
if (!this.selected && value)
{
this.OptionSelected?.Invoke();
}
this.selected = value;
this.NotifyPropertyChanged(nameof(this.IsSelected));
}
}
public ICommand ToggleNodes => new Command(() =>
{
this.IsExpanded = !this.IsExpanded;
});
public ObservableCollection<OptionVM> Options { get; }
= new ObservableCollection<OptionVM>();
internal void Add(OptionVM option)
{
App.Invoke(() => this.Options.Add(option));
}
internal void Clear()
{
App.Invoke(() => this.Options.Clear());
}
internal void SetIndentation(int indent = INDENT)
{
this.indent = indent;
foreach (var option in this.Options)
{
option.SetIndentation(this.indent + INDENT);
}
}
protected virtual void Parent_PropertyChanged(object sender, PropertyChangedEventArgs args)
{
this.NotifyPropertyChanged(nameof(this.Header));
this.NotifyPropertyChanged(nameof(this.Indent));
this.NotifyPropertyChanged(nameof(this.IsExpanded));
this.NotifyPropertyChanged(nameof(this.IsSelected));
}
}
}
@@ -1,70 +0,0 @@
namespace OMNIPruefung.ViewModels.Options
{
using OMNIPruefung.ViewModels.Content;
using System.ComponentModel;
public class COMOptionVM : OptionVM
{
private readonly COMContentVM parent;
public COMOptionVM(COMContentVM parent) : base(parent)
{
this.parent = parent;
}
public int Nr
{
get => this.parent.Nr;
set => this.NotifyPropertyChanged(nameof(this.Nr));
}
public int Progress
{
get => this.parent.Progress;
set => this.NotifyPropertyChanged(nameof(this.Progress));
}
public bool Running
{
get => this.parent.Running;
set => this.NotifyPropertyChanged(nameof(this.Running));
}
public bool IsValid
{
get => this.parent.IsValid;
set => this.NotifyPropertyChanged(nameof(this.IsValid));
}
public bool Connected
{
get => this.parent.Connected;
set => this.NotifyPropertyChanged(nameof(this.Connected));
}
public bool Visible
{
get => this.parent.Visible;
set => this.NotifyPropertyChanged(nameof(this.Visible));
}
public string State
{
get => this.parent.State;
set => this.NotifyPropertyChanged(nameof(this.State));
}
protected override void Parent_PropertyChanged(object sender, PropertyChangedEventArgs args)
{
base.Parent_PropertyChanged(sender, args);
this.NotifyPropertyChanged(nameof(this.Connected));
this.NotifyPropertyChanged(nameof(this.Running));
this.NotifyPropertyChanged(nameof(this.Nr));
this.NotifyPropertyChanged(nameof(this.Progress));
this.NotifyPropertyChanged(nameof(this.State));
this.NotifyPropertyChanged(nameof(this.Visible));
this.NotifyPropertyChanged(nameof(this.IsValid));
}
}
}
@@ -1,12 +0,0 @@
namespace OMNIPruefung.ViewModels.Options
{
using OMNIPruefung.ViewModels.Content;
public class EOLOptionVM : OptionVM
{
public EOLOptionVM(EOLContentVM parent) : base(parent)
{
}
}
}
@@ -1,11 +0,0 @@
namespace OMNIPruefung.ViewModels.Options
{
using OMNIPruefung.ViewModels.Content;
public class ExchangeHubOptionVM : OptionVM
{
public ExchangeHubOptionVM(ExchangeHubContentVM parent) : base(parent)
{
}
}
}
@@ -1,11 +0,0 @@
namespace OMNIPruefung.ViewModels.Options
{
using OMNIPruefung.ViewModels.Content;
public class MainOptionVM : OptionVM
{
public MainOptionVM(MainContentVM parent) : base(parent)
{
}
}
}
@@ -1,11 +0,0 @@
namespace OMNIPruefung.ViewModels.Options
{
using OMNIPruefung.ViewModels.Content;
public class SettingsOptionVM : OptionVM
{
public SettingsOptionVM(SettingsContentVM parent) : base(parent)
{
}
}
}
@@ -1,30 +0,0 @@
<ScrollViewer x:Class="OMNIPruefung.Views.Content.COMContent"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="White">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DataGrid Grid.Row="0" ItemsSource="{Binding Meter.Results}" FontFamily="Consolas" FontSize="13" HeadersVisibility="Column" />
<TextBlock Grid.Row="1"
Margin="13"
FontFamily="Consolas"
TextAlignment="Left"
Text="{Binding TestResults}" />
<TextBlock Grid.Row="2"
Margin="13"
FontFamily="Consolas"
TextAlignment="Left"
Text="{Binding Error}" />
</Grid>
</ScrollViewer>
@@ -1,12 +0,0 @@
namespace OMNIPruefung.Views.Content
{
using System.Windows.Controls;
public partial class COMContent : ScrollViewer
{
public COMContent()
{
this.InitializeComponent();
}
}
}
@@ -1,201 +0,0 @@
<Grid x:Class="OMNIPruefung.Views.Content.EOLContent"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:OptionsVM="clr-namespace:OMNIPruefung.ViewModels.Options"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="White">
<Grid Margin="13">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" /> <!-- Auftrag:-->
<RowDefinition Height="Auto" /> <!--Kd.Auftrag:-->
<RowDefinition Height="Auto" /> <!-- PosNr:-->
<RowDefinition Height="Auto" /> <!-- IdentNr:-->
<RowDefinition Height="Auto" /> <!-- Kurztext:-->
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Column="0" Grid.Row="0" Content="Auftragskarte" Margin="0" Padding="0" FontWeight="Bold" FontSize="14" Grid.ColumnSpan="5" />
<Label Grid.Column="0" Grid.Row="1" Content="{Binding Line}" Margin="0" Padding="0" FontWeight="Bold" Grid.ColumnSpan="5" />
<Label Grid.Column="0" Grid.Row="2" Content="AuftragNr:" HorizontalContentAlignment="Left" FontWeight="Bold" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="0" Grid.Row="3" Content="Kd.AuftragNr:" HorizontalContentAlignment="Left" FontWeight="Bold" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="0" Grid.Row="4" Content="PosNr:" HorizontalContentAlignment="Left" FontWeight="Bold" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="0" Grid.Row="5" Content="IdentNr:" HorizontalContentAlignment="Left" FontWeight="Bold" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="0" Grid.Row="6" Content="Kurztext:" HorizontalContentAlignment="Left" FontWeight="Bold" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="1" Grid.Row="2" Content="3221652" HorizontalContentAlignment="Left" Margin="0" Padding="21, 5, 0, 0" />
<Label Grid.Column="1" Grid.Row="3" Content="71156877" HorizontalContentAlignment="Left" Margin="0" Padding="21, 5, 0, 0" />
<Label Grid.Column="1" Grid.Row="4" Content="30" HorizontalContentAlignment="Left" Margin="0" Padding="21, 5, 0, 0" />
<Label Grid.Column="1" Grid.Row="5" Content="96011428" HorizontalContentAlignment="Left" Margin="0" Padding="21, 5, 0, 0" />
<Label Grid.Column="1" Grid.Row="6" Content="{Binding Text}" HorizontalContentAlignment="Left" Margin="0" Padding="21, 5, 0, 0" />
<Label Grid.Column="2" Grid.Row="2" Content="Prüfpunkte" HorizontalContentAlignment="Left" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
<Label Grid.Column="3" Grid.Row="2" Content="Toleranzen" HorizontalContentAlignment="Right" Grid.ColumnSpan="2" FontWeight="Bold" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="2" Grid.Row="3" Content="Abweichung" HorizontalContentAlignment="Left" FontWeight="Bold" Margin="0" Padding="0, 5, 0, 0"/>
<Label Grid.Column="3" Grid.Row="3" Content="min %" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
<Label Grid.Column="4" Grid.Row="3" Content="max %" HorizontalContentAlignment="Right" Grid.ColumnSpan="2" FontWeight="Bold" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="2" Grid.Row="4" Content="{Binding OmniDefaults.TestPoints[0].RequiredFlowM3H}" ContentStringFormat="{}{0:0.0000} m³/h" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
<Label Grid.Column="2" Grid.Row="5" Content="{Binding OmniDefaults.TestPoints[1].RequiredFlowM3H}" ContentStringFormat="{}{0:0.0000} m³/h" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
<Label Grid.Column="2" Grid.Row="6" Content="{Binding OmniDefaults.TestPoints[2].RequiredFlowM3H}" ContentStringFormat="{}{0:0.0000} m³/h" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
<Label Grid.Column="3" Grid.Row="4" Content="{Binding OmniDefaults.TestPoints[0].MinDiff}" ContentStringFormat="{}{0:0.00} %" HorizontalContentAlignment="Right" Margin="0" Padding="0, 5, 21, 0" />
<Label Grid.Column="3" Grid.Row="5" Content="{Binding OmniDefaults.TestPoints[1].MinDiff}" ContentStringFormat="{}{0:0.00} %" HorizontalContentAlignment="Right" Margin="0" Padding="0, 5, 21, 0" />
<Label Grid.Column="3" Grid.Row="6" Content="{Binding OmniDefaults.TestPoints[2].MinDiff}" ContentStringFormat="{}{0:0.00} %" HorizontalContentAlignment="Right" Margin="0" Padding="0, 5, 21, 0" />
<Label Grid.Column="4" Grid.Row="4" Content="{Binding OmniDefaults.TestPoints[0].MaxDiff}" ContentStringFormat="{}{0:0.00} %" HorizontalContentAlignment="Right" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="4" Grid.Row="5" Content="{Binding OmniDefaults.TestPoints[1].MaxDiff}" ContentStringFormat="{}{0:0.00} %" HorizontalContentAlignment="Right" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="4" Grid.Row="6" Content="{Binding OmniDefaults.TestPoints[2].MaxDiff}" ContentStringFormat="{}{0:0.00} %" HorizontalContentAlignment="Right" Margin="0" Padding="0, 5, 0, 0" />
<Label Grid.Column="0" Grid.Row="7" Content="{Binding Line}" Margin="0" Padding="0" FontWeight="Bold" Grid.ColumnSpan="5" />
<Label Grid.Column="0" Grid.Row="8" Content="{Binding State}" Margin="0" Padding="0, 3" Grid.ColumnSpan="5" FontWeight="Bold" Background="Transparent"/>
<Label Grid.Column="0" Grid.Row="8" Content="{Binding Error}" Margin="0" Padding="0, 3" Grid.ColumnSpan="5" FontWeight="Bold" Background="Transparent" Foreground="{StaticResource Red}" />
<Grid Grid.Row="9" Grid.ColumnSpan="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="150" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding SuchNr}" Margin="0, 2, 2, 2" />
<ComboBox Grid.Column="1" Text="{Binding Size}" HorizontalAlignment="Stretch" Margin="0, 2, 2, 2">
<ComboBoxItem IsSelected="True">5</ComboBoxItem>
<ComboBoxItem >6</ComboBoxItem>
<ComboBoxItem >7</ComboBoxItem>
<ComboBoxItem >8</ComboBoxItem>
<ComboBoxItem >9</ComboBoxItem>
<ComboBoxItem >10</ComboBoxItem>
<ComboBoxItem >11</ComboBoxItem>
</ComboBox>
<ComboBox Grid.Column="2" Text="{Binding Type}" HorizontalAlignment="Stretch" Margin="2, 2, 0, 2">
<ComboBoxItem IsSelected="True">C2</ComboBoxItem>
<ComboBoxItem >F2</ComboBoxItem>
<ComboBoxItem >R2</ComboBoxItem>
<ComboBoxItem >T2</ComboBoxItem>
</ComboBox>
<Button Grid.Column="3"
Content="Überprüfung starten"
Style="{DynamicResource SystemBtn}"
Visibility="{Binding CanCheck, Converter={StaticResource BooleanVisibility}}"
Command="{Binding CheckInspection}"/>
<Button Grid.Column="4"
Content="Displays auslesen"
Style="{DynamicResource SystemBtn}"
Command="{Binding ReadDisplay}"/>
</Grid>
<!--<Label Grid.Column="0" Grid.Row="9" Content="Type eingeben: " VerticalContentAlignment="Center" VerticalAlignment="Stretch"/>
<TextBox Grid.Column="1" Grid.Row="9" Text="{Binding Type}" />-->
</Grid>
<ItemsControl Grid.Row="1"
ItemsSource="{Binding Option.Options}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type OptionsVM:COMOptionVM}">
<Grid Margin="0, 3, 0, 0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0"
Grid.Column="0"
Padding="0"
Margin="0"
FontSize="13"
FontWeight="Bold"
VerticalContentAlignment="Center"
ContentStringFormat="{}{0}. "
Content="{Binding Nr}" />
<Label Grid.Row="0"
Grid.Column="1"
Padding="0"
Margin="0"
FontSize="13"
VerticalContentAlignment="Center"
Content="{Binding State}" />
<Label Grid.Row="0"
Grid.Column="2"
Padding="0"
Margin="0"
FontSize="13"
Foreground="Gray"
VerticalContentAlignment="Center"
Content="{Binding Progress}"
ContentStringFormat="{}{0} %" />
<ProgressBar Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Foreground="{Binding IsValid, Converter={StaticResource BooleanProgress}}"
Value="{Binding Progress}"
Background="WhiteSmoke"
BorderBrush="WhiteSmoke"
BorderThickness="1"
Margin="0, 5"
Padding="0"
Height="8"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Margin="0"
Content="Plätze aktualisieren"
Style="{DynamicResource SystemBtn}"
Visibility="{Binding CanStart, Converter={StaticResource BooleanVisibility}}"
Command="{Binding LoadComPorts}"/>
<Button Grid.Column="2"
Content="Abbruch"
Style="{DynamicResource SystemBtn}"
Visibility="{Binding CanStop, Converter={StaticResource BooleanVisibility}}"
Command="{Binding CancelInspection}"/>
<Button Grid.Column="3"
Content="Prüfung starten"
Style="{DynamicResource SystemBtn}"
Visibility="{Binding CanStart, Converter={StaticResource BooleanVisibility}}"
Command="{Binding StartInspection}"/>
</Grid>
</Grid>
</Grid>
@@ -1,12 +0,0 @@
namespace OMNIPruefung.Views.Content
{
using System.Windows.Controls;
public partial class EOLContent : Grid
{
public EOLContent()
{
this.InitializeComponent();
}
}
}
@@ -1,93 +0,0 @@
<Grid x:Class="OMNIPruefung.Views.Content.ExchangeHub"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="150"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Margin="21, 21, 21, 0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0"
Grid.Column="0"
Content="Hub URL:"
FontFamily="Consolas"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"/>
<TextBox Grid.Row="0"
Grid.Column="1"
Height="30"
FontFamily="Consolas"
Text="{Binding URL}"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"/>
<Line Grid.Row="1" Height="10" />
<Label Grid.Row="2"
Grid.Column="0"
FontFamily="Consolas"
Content="Output Directory:"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"/>
<TextBox Grid.Row="2"
Grid.Column="1"
Height="30"
FontFamily="Consolas"
Text="{Binding OutputDir}"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"/>
<StackPanel Grid.Row="3"
Grid.Column="1"
Orientation="Horizontal"
Margin="0, 10, 0, 0">
<Button VerticalAlignment="Stretch"
HorizontalAlignment="Left"
Style="{StaticResource SystemBtn}"
Content="Speichern"
Margin="0, 0, 10, 0"/>
<Button VerticalAlignment="Stretch"
HorizontalAlignment="Left"
Style="{StaticResource SystemBtn}"
Command="{Binding Connect}"
Content="Verbinden"
Margin="0, 0, 10, 0"/>
<Button VerticalAlignment="Stretch"
HorizontalAlignment="Left"
Style="{StaticResource SystemBtn}"
Command="{Binding Disconnect}"
Content="Trennen"
Margin="0, 0, 10, 0"/>
</StackPanel>
</Grid>
<GridSplitter Grid.Row="1"
Height="3"
ResizeBehavior="PreviousAndNext"
ResizeDirection="Rows"
Background="LightGray"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" />
<ScrollViewer Grid.Row="2"
Margin="0"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
<TextBlock FontFamily="Consolas"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Text="{Binding LogContent}"
Padding="21, 21, 0, 0"/>
</ScrollViewer>
</Grid>
@@ -1,12 +0,0 @@
namespace OMNIPruefung.Views.Content
{
using System.Windows.Controls;
public partial class ExchangeHub : Grid
{
public ExchangeHub()
{
this.InitializeComponent();
}
}
}
@@ -1,81 +0,0 @@
<Grid x:Class="OMNIPruefung.Views.Options.COMOption"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ToggleButton Grid.Row="0"
IsChecked="{Binding IsExpanded}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<ContentPresenter SnapsToDevicePixels="True" />
</ControlTemplate>
</ToggleButton.Template>
<RadioButton GroupName="sidebar_nodes"
Cursor="Hand"
Padding="0, 2"
Margin="0, 2, 0, 0"
Style="{StaticResource RadioNodeStyle}"
IsChecked="{Binding IsSelected}">
<RadioButton.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding ToggleNodes}" />
</RadioButton.InputBindings>
<Grid Margin="0, 0, 0, 1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Indent}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ProgressBar Grid.Column="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Visibility="{Binding Connected, Converter={StaticResource BooleanVisibility}}"
Foreground="{Binding Running, Converter={StaticResource BooleanProgress}}"
Background="Transparent"
Value="{Binding Progress}"
BorderThickness="0"
Opacity="0.1"
Margin="5, 2"
Padding="0"/>
<Label Grid.Column="2"
Visibility="{Binding Connected, Converter={StaticResource BooleanVisibility}}"
Content="{Binding Progress}"
ContentStringFormat="{}{0}%"
HorizontalAlignment="Right"
VerticalAlignment="Stretch"
Opacity="0.5" />
<Label Grid.Column="1"
FontSize="14"
Margin="0"
Padding="0"
FontWeight="Bold"
Foreground="Black"
Background="Transparent"
Content="{Binding Nr}"
ContentStringFormat="{}{0}."
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"/>
<Label Grid.Column="2"
Padding="0"
Margin="5"
Content="{Binding Header}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"/>
</Grid>
</RadioButton>
</ToggleButton>
<ItemsControl Grid.Row="1"
ItemsSource="{Binding Options}"
Visibility="{Binding IsExpanded, Converter={StaticResource BooleanVisibility}}"/>
</Grid>
@@ -1,21 +0,0 @@
namespace OMNIPruefung.Views.Options
{
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
public partial class COMOption : Grid
{
public static readonly DependencyProperty ProgressIconProperty
= DependencyProperty.Register(nameof(ProgressIcon), typeof(ImageSource), typeof(Option));
public COMOption()
=> this.InitializeComponent();
public ImageSource ProgressIcon
{
get => this.GetValue(ProgressIconProperty) as ImageSource;
set => this.SetValue(ProgressIconProperty, value);
}
}
}
@@ -1,58 +0,0 @@
<Grid x:Class="OMNIPruefung.Views.Options.Option"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:v="clr-namespace:OMNIPruefung.Views.Options">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ToggleButton Grid.Row="0"
IsChecked="{Binding IsExpanded}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<ContentPresenter SnapsToDevicePixels="True" />
</ControlTemplate>
</ToggleButton.Template>
<RadioButton GroupName="sidebar_nodes"
Cursor="Hand"
Padding="0, 2"
Margin="0, 2, 0, 0"
Style="{StaticResource RadioNodeStyle}"
IsChecked="{Binding IsSelected}">
<RadioButton.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" Command="{Binding ToggleNodes}" />
</RadioButton.InputBindings>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Indent}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="1"
Source="{Binding Icon, RelativeSource={RelativeSource AncestorType=v:Option, Mode=FindAncestor}}"
Height="{Binding IconSize, RelativeSource={RelativeSource AncestorType=v:Option, Mode=FindAncestor}}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
Width="16"/>
<Label Grid.Column="2"
Padding="0"
Margin="5"
Background="Transparent"
Content="{Binding Header}"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"/>
</Grid>
</RadioButton>
</ToggleButton>
<ItemsControl Grid.Row="1"
ItemsSource="{Binding Options}"
Visibility="{Binding IsExpanded, Converter={StaticResource BooleanVisibility}}"/>
</Grid>
@@ -1,31 +0,0 @@
namespace OMNIPruefung.Views.Options
{
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
public partial class Option : Grid
{
public static readonly DependencyProperty IconProperty
= DependencyProperty.Register(nameof(Icon), typeof(ImageSource), typeof(Option));
public static readonly DependencyProperty IconSizeProperty
= DependencyProperty.Register(nameof(IconSize), typeof(int), typeof(Option),
new FrameworkPropertyMetadata(16));
public Option()
=> this.InitializeComponent();
public ImageSource Icon
{
get => this.GetValue(IconProperty) as ImageSource;
set => this.SetValue(IconProperty, value);
}
public int IconSize
{
get => this.GetValue(IconSizeProperty) is int size ? size : 16;
set => this.SetValue(IconSizeProperty, value);
}
}
}
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net40" />
</packages>
@@ -144,6 +144,11 @@
var max = points[2];
var crrf = default(double);
if (min == 0 || mid == 0 || max == 0)
{
succeeded = false;
}
if (Math.Abs(mid - max) <= 3 && Math.Max(mid, max) - min <= 6.5)
{
var avgMidMax = (mid + max) / 2;
+7 -5
View File
@@ -7,12 +7,14 @@
{
private readonly ConcurrentDictionary<int, OmniMeter> meters;
private readonly OmniDatabase database;
private readonly string outputDirectory;
private int runId;
private OmniContext(string connectionString)
private OmniContext(string connectionString, string outputDirectory)
{
this.database = new OmniDatabase(connectionString);
this.outputDirectory = outputDirectory;
this.database = new OmniDatabase(connectionString, outputDirectory);
this.meters = new ConcurrentDictionary<int, OmniMeter>();
}
@@ -20,11 +22,11 @@
public static OmniContext Current { get; private set; }
public static OmniContext GetOrCreateInstance(string connectionString)
public static OmniContext GetOrCreateInstance(string connectionString, string outputDirectory)
{
if (Current is null)
{
Current = new OmniContext(connectionString);
Current = new OmniContext(connectionString, outputDirectory);
}
return Current;
@@ -44,7 +46,7 @@
public OmniMeter LoadMeter(int nr, string portName)
{
var meter = new OmniMeter(nr, portName);
var meter = new OmniMeter(nr, portName, this.outputDirectory);
return this.meters.AddOrUpdate(nr, meter, (_, _1) => meter);
}
+26 -17
View File
@@ -13,11 +13,11 @@
public class OmniDatabase
{
private readonly ISQLConnection sqlConnection;
private readonly string logFile;
private readonly string outputFile;
public OmniDatabase(string connectionString)
public OmniDatabase(string connectionString, string outputDirectory)
{
this.logFile = Path.Combine(Directory.GetCurrentDirectory(), "sql_logger.txt");
this.outputFile = Path.Combine(outputDirectory, "sql_errors.txt");
this.sqlConnection = SQLConnection.CreateSQLConnection(connectionString, this.ErrorLogger);
}
@@ -276,7 +276,7 @@
private void ErrorLogger(string error)
{
File.AppendAllText(this.logFile, $"{error}{Environment.NewLine}");
File.AppendAllText(this.outputFile, $"{error}{Environment.NewLine}");
}
}
@@ -393,14 +393,14 @@
public DateTime? EndDate { get; set; }
public ICollection<OmniPruefpunktResult> TestPoints { get; }
public ICollection<OmniPruefpunktResult> TestedPoints { get; }
= new List<OmniPruefpunktResult>();
internal void AddTestPoint(int ppnr, short testPointId, double gpm, int rotations, double duration, double m3s, double refm3s, double acc)
{
var tp = new OmniPruefpunktResult
{
Nr = (byte)ppnr,
PPNR = (byte)ppnr,
TpId = testPointId,
Rotations = rotations,
Duration = duration,
@@ -410,7 +410,7 @@
GPM = gpm
};
this.TestPoints.Add(tp);
this.TestedPoints.Add(tp);
OmniContext.Current.UpdateTestRun(tp.ToDictionary(), this.Id, this.SlotNr);
}
@@ -430,7 +430,7 @@
internal double[] GetAccuracies()
{
return this.TestPoints
return this.TestedPoints
.OrderBy(x => x.GPM)
.Select(x => x.Accuracy ?? default(double))
.ToArray();
@@ -440,18 +440,25 @@
{
this.EndDate = DateTime.Now;
OmniContext.Current.UpdateTestRun(new Dictionary<string, object>
var parameters = new Dictionary<string, object>
{
{ nameof(CrrfAfter), this.CrrfAfter },
{ nameof(Succeeded), this.Succeeded },
{ nameof(EndDate), this.EndDate },
}, this.Id, this.SlotNr);
};
foreach (var testedPP in this.TestedPoints)
{
parameters[$"Q{testedPP.PPNR}_Acc"] = testedPP.Acc;
}
OmniContext.Current.UpdateTestRun(parameters, this.Id, this.SlotNr);
}
}
public class OmniPruefpunktResult
{
public byte? Nr { get; set; }
public byte? PPNR { get; set; }
public short? TpId { get; set; }
@@ -467,16 +474,18 @@
public double? GPM { get; set; }
public double? Acc { get; set; }
public IDictionary<string, object> ToDictionary()
{
return new Dictionary<string, object>
{
{ $"Q{this.Nr}_{nameof(TpId)}", this.TpId },
{ $"Q{this.Nr}_{nameof(Rotations)}", this.Rotations },
{ $"Q{this.Nr}_{nameof(Duration)}", this.Duration },
{ $"Q{this.Nr}_{nameof(MeterM3S)}", this.MeterM3S },
{ $"Q{this.Nr}_{nameof(RefM3S)}", this.RefM3S },
{ $"Q{this.Nr}_{nameof(Accuracy)}", this.Accuracy },
{ $"Q{this.PPNR}_{nameof(TpId)}", this.TpId },
{ $"Q{this.PPNR}_{nameof(Rotations)}", this.Rotations },
{ $"Q{this.PPNR}_{nameof(Duration)}", this.Duration },
{ $"Q{this.PPNR}_{nameof(MeterM3S)}", this.MeterM3S },
{ $"Q{this.PPNR}_{nameof(RefM3S)}", this.RefM3S },
{ $"Q{this.PPNR}_{nameof(Accuracy)}", this.Accuracy },
};
}
}
+41 -29
View File
@@ -16,19 +16,23 @@
const string NA = "n/a";
private readonly ConcurrentQueue<object> states = new ConcurrentQueue<object>();
private readonly string stateFile;
private readonly string outputDirectory;
private readonly string outputFile;
private readonly int slotnr;
private readonly string portName;
private OmniConnection connection;
public OmniMeter(int nr, string portName)
public OmniMeter(int nr, string portName, string outputDirectory)
{
this.slotnr = nr;
this.portName = portName;
this.stateFile = this.GetOrCreateStateFile(nr, portName);
this.SlotNr = nr;
this.PortName = portName;
this.outputDirectory = outputDirectory;
this.outputFile = GetOrCreateOutputFile(nr, portName, outputDirectory);
}
public int SlotNr { get; }
public string PortName { get; }
public string MeterNr { get; private set; }
public int? SerialNr { get; private set; }
@@ -39,7 +43,7 @@
{
if (this.connection is null)
{
this.connection = new OmniIrdaConnection(this.portName);
this.connection = new OmniIrdaConnection(this.PortName);
this.connection.StateChenged += this.NotifyStateChanged;
}
@@ -78,7 +82,12 @@
this.connection = null;
File.AppendAllLines(this.stateFile, this.states.Select(x => $"{x}"));
this.states.Enqueue($"=== {DateTime.Now:HH:mm:ss} {new string('=', 100)}");
while (this.states.TryDequeue(out var state))
{
File.AppendAllText(this.outputFile, $"{state}{Environment.NewLine}");
}
}
public void InitializeForInspection(bool preserveState = false)
@@ -99,7 +108,7 @@
isvalid = systemParameters.IsValid;
}
this.TestRun.SlotNr = (byte)this.slotnr;
this.TestRun.SlotNr = (byte)this.SlotNr;
this.TestRun.BuildInfo = buildInfo;
this.TestRun.VersionAndType = versionAndType;
this.TestRun.ManifacturedDate = manifactured;
@@ -115,8 +124,6 @@
this.TestRun.CrrfBefore = this.connection.ViewFactoryCorrection();
this.TestRun.SaveChanges();
var defaults = OmniContext.Current.Auftrag.TypParameter;
var inputVolumeResult = this.connection.Set(new InputVolume
{
@@ -126,11 +133,13 @@
Range = defaults.Range,
Size = defaults.Size
});
this.TestRun.SaveChanges();
}
public void LoadTestRun()
{
this.TestRun = OmniContext.Current.AddTestRun(this.slotnr, this.MeterNr);
this.TestRun = OmniContext.Current.AddTestRun(this.SlotNr, this.MeterNr);
}
public void SaveMeterState()
@@ -232,14 +241,14 @@
return new Tuple<double, string, double>(m3s, rs, acc);
}
public void FinishInspection(bool preserveState = false)
public void FinishInspection()
{
var crrf = this.TestRun
.GetAccuracies()
.GetCorrectionFactor(out bool succeeded);
var defaults = OmniContext.Current.Auftrag.TypParameter;
if (!preserveState)
if (succeeded)
{
var response = this.connection.Set(new RegisterSettings
{
@@ -261,7 +270,20 @@
this.TestRun.Succeeded = succeeded;
this.TestRun.CrrfAfter = crrf;
foreach (var testedPP in this.TestRun.TestedPoints)
{
testedPP.Acc = testedPP.Accuracy * (1 + crrf / 100D);
}
this.TestRun.CloseTestRun();
this.states.Enqueue($"=== {DateTime.Now:HH:mm:ss} {new string('=', 100)}");
while (this.states.TryDequeue(out var state))
{
File.AppendAllText(this.outputFile, $"{state}{Environment.NewLine}");
}
}
public void NotifyStateChanged(object state)
@@ -269,23 +291,13 @@
this.states.Enqueue(state);
}
private string GetOrCreateStateFile(int slotNr, string portName)
private static string GetOrCreateOutputFile(int slotNr, string portName, string outputDirectory)
{
var directory = Directory.GetCurrentDirectory();
var stateDirectory = Path.Combine(directory, "Debug", $"{slotNr}_{portName}");
var stateFile = Path.Combine(stateDirectory, $"{DateTime.Now:yyyy-MM-dd}.txt");
var outputFile = Path.Combine(outputDirectory, $"[{slotNr}][{portName}].txt");
try
{
Directory.CreateDirectory(stateDirectory);
File.AppendAllText(stateFile, $"{nameof(OmniMeter)}.{nameof(GetOrCreateStateFile)}({nameof(slotNr)}:{slotNr}, {nameof(portName)}:{portName});{Environment.NewLine}");
}
catch (Exception e)
{
this.states.Enqueue(e);
}
File.AppendAllText(outputFile, $"{nameof(OmniMeter)}.{nameof(GetOrCreateOutputFile)}({nameof(slotNr)}:{slotNr}, {nameof(portName)}:{portName});{Environment.NewLine}");
return stateFile;
return outputFile;
}
}
}
+15 -86
View File
@@ -42,7 +42,7 @@ INSERT INTO [OmniTestPoints]
([OmniTypeId], [OmniVariant], [GalPerMin], [Rotations], [Duration], [MinAccuracy], [MaxAccuracy])
VALUES ( 1, 'C2', 160.00, 700, 35, 98.5, 101.5)
, ( 1, 'C2', 1.00, 4, 32, 98.5, 101.5)
, ( 1, 'C2', 0.25, 4, 127, 95.0, 101.5)
, ( 1, 'C2', 0.275, 4, 127, 95.0, 101.5)
--------------------------------------------------------------------------------------------------
, ( 1, 'R2', 150.00, 600, 32, 98.5, 101.5)
, ( 1, 'R2', 2.00, 8, 32, 98.5, 101.5)
@@ -54,7 +54,7 @@ VALUES ( 1, 'C2', 160.00, 700, 35, 98.5,
--------------------------------------------------------------------------------------------------
, ( 2, 'C2', 160.00, 800, 40, 98.5, 101.5)
, ( 2, 'C2', 1.00, 4, 32, 98.5, 101.5)
, ( 2, 'C2', 0.25, 4, 127, 95.0, 101.5)
, ( 2, 'C2', 0.275, 4, 127, 95.0, 101.5)
--------------------------------------------------------------------------------------------------
, ( 2, 'R2', 200.00, 1000, 40, 98.5, 101.5)
, ( 2, 'R2', 2.50, 10, 32, 98.5, 101.5)
@@ -71,7 +71,7 @@ CREATE TABLE [OmniPlus] (
);
CREATE TABLE [OmniTestRuns] (
[Id] INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
[Id] INT NOT NULL,
[SlotNr] TINYINT NOT NULL,
[MeterNr] VARCHAR(32) NOT NULL,
[AddDate] DATETIME NOT NULL DEFAULT(GETDATE()),
@@ -86,101 +86,30 @@ CREATE TABLE [OmniTestRuns] (
[Q1_TpId] SMALLINT NULL,
[Q1_Rotations] INT NULL,
[Q1_Duration] FLOAT NULL,
[Q1_FlowM3S] FLOAT NULL,
[Q1_MeterM3S] FLOAT NULL,
[Q1_RefM3S] FLOAT NULL,
[Q1_Accuracy] FLOAT NULL,
[Q2_TpId] SMALLINT NULL,
[Q2_Rotations] INT NULL,
[Q2_Duration] FLOAT NULL,
[Q2_FlowM3S] FLOAT NULL,
[Q2_MeterM3S] FLOAT NULL,
[Q2_RefM3S] FLOAT NULL,
[Q2_Accuracy] FLOAT NULL,
[Q3_TpId] SMALLINT NULL,
[Q3_Rotations] INT NULL,
[Q3_Duration] FLOAT NULL,
[Q3_FlowM3S] FLOAT NULL,
[Q3_MeterM3S] FLOAT NULL,
[Q3_RefM3S] FLOAT NULL,
[Q3_Accuracy] FLOAT NULL,
[CrrfAfter] FLOAT NULL,
[Succeeded] BIT NULL,
[Q1_Acc] FLOAT NULL,
[Q2_Acc] FLOAT NULL,
[Q3_Acc] FLOAT NULL,
[EndDate] DATETIME NULL,
);
------USE [PushExt]
------GO
------IF OBJECT_ID(N'OmniExport') IS NOT NULL DROP TABLE [OmniExport]
------GO
------CREATE TABLE [OmniExport] (
------ [BuildID] INT NOT NULL IDENTITY(1,1) NOT FOR REPLICATION,
------ [OrderNumber] INT NOT NULL,
------ [LineNumber] INT NOT NULL,
------ [ManufacturingSN] VARCHAR(30) NOT NULL,
------ [CustomerSN] VARCHAR(30) NOT NULL,
------ [MeterSN] VARCHAR(30) NOT NULL,
------ [PCBAID] VARCHAR(30) NOT NULL,
------ [EhatPCBAID] VARCHAR(30) NOT NULL,
------ [ManufactureDate] DATETIME NOT NULL,
------ [ShipDate] DATETIME NOT NULL,
------ [Flow1] DECIMAL(4, 1) NOT NULL,
------ [Flow2] DECIMAL(4, 1) NOT NULL,
------ [Flow3] DECIMAL(4, 1) NOT NULL,
------ [Flow4] DECIMAL(4, 1) NOT NULL,
------ [Flow5] DECIMAL(4, 1) NOT NULL,
------ [Flow6] DECIMAL(4, 1) NOT NULL,
------ [PartNumber] VARCHAR(50) NOT NULL
------)
------GO
------ALTER TABLE [OmniExport] ADD CONSTRAINT [PK_OmniExport_BuildID] PRIMARY KEY ([BuildID])
------GO
------ALTER TABLE [OmniExport] ADD CONSTRAINT [DF_OmniExport_Flow1] DEFAULT (0.0) FOR [Flow1]
------GO
------ALTER TABLE [OmniExport] ADD CONSTRAINT [DF_OmniExport_Flow2] DEFAULT (0.1) FOR [Flow2]
------GO
------ALTER TABLE [OmniExport] ADD CONSTRAINT [DF_OmniExport_Flow3] DEFAULT (0.2) FOR [Flow3]
------GO
------ALTER TABLE [OmniExport] ADD CONSTRAINT [DF_OmniExport_Flow4] DEFAULT (0.3) FOR [Flow4]
------GO
------ALTER TABLE [OmniExport] ADD CONSTRAINT [DF_OmniExport_Flow5] DEFAULT (0.4) FOR [Flow5]
------GO
------ALTER TABLE [OmniExport] ADD CONSTRAINT [DF_OmniExport_Flow6] DEFAULT (0.5) FOR [Flow6]
------GO
CONSTRAINT [PK_OmniTestRuns] PRIMARY KEY ([Id], [SlotNr])
);