omni plus new ui
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
namespace ExchangeHub.Contracts
|
||||
{
|
||||
public delegate void VoidEventHandler(string groupName);
|
||||
|
||||
public delegate void IntEventHandler(int value, string groupName);
|
||||
|
||||
public delegate void DoubleEventHandler(double value, string groupName);
|
||||
|
||||
public delegate void StringEventHandler(string value, string groupName);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
namespace ExchangeHub.Contracts
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
/// <summary>
|
||||
/// Only for COM usage.
|
||||
/// Exposes event handlers for the (VB6) master.
|
||||
/// </summary>
|
||||
[Guid("9FAA6100-E33F-46F7-9151-C85903472388")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
public interface IExchangeEvents
|
||||
{
|
||||
/// <summary>
|
||||
/// On received: VB6 should stop all running tasks.
|
||||
/// </summary>
|
||||
void Disposed(string groupName);
|
||||
|
||||
/// <summary>
|
||||
/// On received: VB6 should start given flow.
|
||||
/// On sent: VB6 notifies that the flow is reached.
|
||||
/// </summary>
|
||||
void StartFlow(double valueM3H, string groupName);
|
||||
|
||||
/// <summary>
|
||||
/// On received: VB6 should stop any flow.
|
||||
/// On sent: VB6 notifies that the flow is stopped.
|
||||
/// </summary>
|
||||
void StopFlow(string groupName);
|
||||
|
||||
/// <summary>
|
||||
/// On received: VB6 should start reference volume messuring.
|
||||
/// On sent: VB6 notifies that the reference messuring has started.
|
||||
/// </summary>
|
||||
void StartReferenceMessurement(int durationSeconds, string groupName);
|
||||
|
||||
/// <summary>
|
||||
/// On received: VB6 should stop reference volume messuring.
|
||||
/// On sent: VB6 sends the volume messured.
|
||||
/// </summary>
|
||||
void StopReferenceMessurement(double valueM3, string groupName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace ExchangeHub.Contracts
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Only for the SignalR host.</para>
|
||||
/// <para>Exposes used events as methods.</para>
|
||||
/// </summary>
|
||||
public interface IExchangeHub : IExchangeEvents
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace ExchangeHub.Contracts
|
||||
{
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[Guid("21EA6C57-A004-456E-8D99-7DCAD3481205")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
public interface IExchangeHubMaster : IExchangeHubSlave
|
||||
{
|
||||
void Connect(string url);
|
||||
|
||||
void SendDisposed(string _ = "");
|
||||
|
||||
void SendStartFlow(double volumeM3H, string _ = "");
|
||||
|
||||
void SendStopFlow(string _ = "");
|
||||
|
||||
void SendStartReferenceMessurement(int durationSeconds, string _ = "");
|
||||
|
||||
void SendStopReferenceMessurement(double volumeM3 = 0D, string _ = "");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace ExchangeHub.Contracts
|
||||
{
|
||||
public interface IExchangeHubSlave
|
||||
{
|
||||
event VoidEventHandler Disposed;
|
||||
|
||||
event DoubleEventHandler StartFlow;
|
||||
|
||||
event VoidEventHandler StopFlow;
|
||||
|
||||
event IntEventHandler StartReferenceMessurement;
|
||||
|
||||
event DoubleEventHandler StopReferenceMessurement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
namespace ExchangeHub
|
||||
{
|
||||
using ExchangeHub.Contracts;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Microsoft.AspNet.SignalR.Client;
|
||||
|
||||
[ClassInterface(ClassInterfaceType.None)]
|
||||
[ComSourceInterfaces(typeof(IExchangeEvents))]
|
||||
[Guid("2ABFAC6C-9F3C-4702-9E08-4979A26577EF")]
|
||||
[ProgId("ExchangeHub.ExchangeConnection")]
|
||||
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;
|
||||
|
||||
public ExchangeConnection()
|
||||
=> this.disposables = new List<IDisposable>();
|
||||
|
||||
public event VoidEventHandler Disposed;
|
||||
public event DoubleEventHandler StartFlow;
|
||||
public event VoidEventHandler StopFlow;
|
||||
public event IntEventHandler StartReferenceMessurement;
|
||||
public event DoubleEventHandler StopReferenceMessurement;
|
||||
public event StringEventHandler StateChanged;
|
||||
|
||||
public void Connect(string url)
|
||||
{
|
||||
this.connection = new HubConnection(url, queryString: $"{GROUP_KEY}={Environment.MachineName}");
|
||||
this.connection.Closed += this.Connection_Closed;
|
||||
this.connection.ConnectionSlow += this.Connection_ConnectionSlow;
|
||||
this.connection.Error += this.Connection_Error;
|
||||
this.connection.Received += this.Connection_Received;
|
||||
this.connection.Reconnected += this.Connection_Reconnected;
|
||||
this.connection.Reconnecting += this.Connection_Reconnecting;
|
||||
this.connection.StateChanged += this.Connection_StateChanged;
|
||||
|
||||
this.proxy = this.connection.CreateHubProxy(HUB_NAME);
|
||||
|
||||
this.disposables.Add(this.proxy.On<string>( nameof(this.Disposed), this.ReceiveDisposed));
|
||||
this.disposables.Add(this.proxy.On<double, string>( nameof(this.StartFlow), this.FlowStarted));
|
||||
this.disposables.Add(this.proxy.On<string>( nameof(this.StopFlow), this.FlowStopped));
|
||||
this.disposables.Add(this.proxy.On<int, string>( nameof(this.StartReferenceMessurement), this.MessurementStarted));
|
||||
this.disposables.Add(this.proxy.On<double, string>( nameof(this.StopReferenceMessurement), this.MessurementStopped));
|
||||
|
||||
try
|
||||
{
|
||||
this.connection
|
||||
.Start()
|
||||
.Wait();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.FileAppendLine(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.SendDisposed();
|
||||
|
||||
this.connection.Closed -= this.Connection_Closed;
|
||||
this.connection.ConnectionSlow -= this.Connection_ConnectionSlow;
|
||||
this.connection.Error -= this.Connection_Error;
|
||||
this.connection.Received -= this.Connection_Received;
|
||||
this.connection.Reconnected -= this.Connection_Reconnected;
|
||||
this.connection.Reconnecting -= this.Connection_Reconnecting;
|
||||
this.connection.StateChanged -= this.Connection_StateChanged;
|
||||
|
||||
foreach (var disposable in this.disposables)
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
|
||||
Task.Factory.StartNew(this.connection.Dispose);
|
||||
|
||||
this.FileAppendLine($"Connection disconnected.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.FileAppendLine(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public void SendDisposed(string _ = STR_EMPTY)
|
||||
{
|
||||
if (this.connection?.State == ConnectionState.Connected)
|
||||
{
|
||||
this.proxy.Invoke<string>(nameof(this.Disposed), GroupName);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendStartFlow(double volumeM3H, string _ = STR_EMPTY)
|
||||
{
|
||||
if (this.connection?.State == ConnectionState.Connected)
|
||||
{
|
||||
this.proxy.Invoke(nameof(this.StartFlow), volumeM3H, GroupName);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendStopFlow(string _ = STR_EMPTY)
|
||||
{
|
||||
if (this.connection?.State == ConnectionState.Connected)
|
||||
{
|
||||
this.proxy.Invoke(nameof(this.StopFlow), GroupName);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendStartReferenceMessurement(int durationSeconds, string _ = STR_EMPTY)
|
||||
{
|
||||
if (this.connection?.State == ConnectionState.Connected)
|
||||
{
|
||||
this.proxy.Invoke(nameof(this.StartReferenceMessurement), durationSeconds, GroupName);
|
||||
}
|
||||
}
|
||||
|
||||
public void SendStopReferenceMessurement(double volumeM3H = 0D, string _ = STR_EMPTY)
|
||||
{
|
||||
if (this.connection?.State == ConnectionState.Connected)
|
||||
{
|
||||
this.proxy.Invoke(nameof(this.StopReferenceMessurement), volumeM3H, GroupName);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReceiveDisposed(string groupName)
|
||||
{
|
||||
if (GroupName == groupName)
|
||||
{
|
||||
this.Disposed?.Invoke(groupName);
|
||||
}
|
||||
}
|
||||
|
||||
private void FlowStarted(double volumeM3H, string groupName)
|
||||
{
|
||||
if (GroupName == groupName)
|
||||
{
|
||||
this.StartFlow?.Invoke(volumeM3H, groupName);
|
||||
}
|
||||
}
|
||||
|
||||
private void FlowStopped(string groupName)
|
||||
{
|
||||
if (GroupName == groupName)
|
||||
{
|
||||
this.StopFlow?.Invoke(groupName);
|
||||
}
|
||||
}
|
||||
|
||||
private void MessurementStarted(int seconds, string groupName)
|
||||
{
|
||||
if (GroupName == groupName)
|
||||
{
|
||||
this.StartReferenceMessurement?.Invoke(seconds, groupName);
|
||||
}
|
||||
}
|
||||
|
||||
private void MessurementStopped(double volumeMessured, string groupName)
|
||||
{
|
||||
if (GroupName == groupName)
|
||||
{
|
||||
this.StopReferenceMessurement?.Invoke(volumeMessured, groupName);
|
||||
}
|
||||
}
|
||||
|
||||
private void Connection_Closed()
|
||||
{
|
||||
this.FileAppendLine("HubConnection closed!");
|
||||
}
|
||||
|
||||
private void Connection_ConnectionSlow()
|
||||
{
|
||||
this.FileAppendLine("HubConnection is about to timeout!");
|
||||
}
|
||||
|
||||
private void Connection_Error(Exception e)
|
||||
{
|
||||
this.FileAppendLine(e.ToString());
|
||||
}
|
||||
|
||||
private void Connection_Received(string data)
|
||||
{
|
||||
this.FileAppendLine(data);
|
||||
}
|
||||
|
||||
private void Connection_Reconnected()
|
||||
{
|
||||
this.FileAppendLine("HubConnection reconnected!");
|
||||
}
|
||||
|
||||
private void Connection_Reconnecting()
|
||||
{
|
||||
this.FileAppendLine("HubConnection reconnecting!");
|
||||
}
|
||||
|
||||
private void Connection_StateChanged(StateChange state)
|
||||
{
|
||||
this.FileAppendLine($"{state.OldState} -> {state.NewState}");
|
||||
}
|
||||
|
||||
private void FileAppendLine(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)
|
||||
{
|
||||
this.StateChanged?.Invoke(e.ToString(), GroupName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{6033FF0C-CF32-4BC5-8EFE-4774CCDC663D}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>ExchangeHub</RootNamespace>
|
||||
<AssemblyName>ExchangeHub</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.AspNet.SignalR.Client, Version=2.4.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.AspNet.SignalR.Client.2.4.3\lib\net40\Microsoft.AspNet.SignalR.Client.dll</HintPath>
|
||||
</Reference>
|
||||
<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="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Contracts\EventHandlers.cs" />
|
||||
<Compile Include="Contracts\IExchangeEvents.cs" />
|
||||
<Compile Include="Contracts\IExchangeHub.cs" />
|
||||
<Compile Include="Contracts\IExchangeHubMaster.cs" />
|
||||
<Compile Include="Contracts\IExchangeHubSlave.cs" />
|
||||
<Compile Include="ExchangeConnection.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 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("ExchangeHub")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("ExchangeHub")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2023")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(true)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("6033ff0c-cf32-4bc5-8efe-4774ccdc663d")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.AspNet.SignalR.Client" version="2.4.3" targetFramework="net40" />
|
||||
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -6,6 +6,7 @@
|
||||
<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=AuftragKopie; User ID=sa; Password=sqlserver;" />-->
|
||||
<add key="OmniDB" value="Server=SLASQL01.emea.sensus.net; Database=Auftrag; User ID=sa; Password=sqlserver;" />
|
||||
</appSettings>
|
||||
</configuration>
|
||||
@@ -8,7 +8,7 @@
|
||||
public partial class App : Application
|
||||
{
|
||||
public static readonly string ExePath = typeof(App).Assembly.Location;
|
||||
public static readonly string Path = new FileInfo(ExePath).DirectoryName;
|
||||
public static readonly string ExeDirectory = new FileInfo(ExePath).DirectoryName;
|
||||
|
||||
public static event Action Disposed;
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,10 @@
|
||||
<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>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.configuration" />
|
||||
<Reference Include="System.Data" />
|
||||
@@ -65,6 +69,11 @@
|
||||
<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" />
|
||||
@@ -77,6 +86,8 @@
|
||||
<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" />
|
||||
@@ -114,6 +125,10 @@
|
||||
<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>
|
||||
@@ -161,7 +176,7 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ExchangeHub\ExchangeHub.csproj">
|
||||
<ProjectReference Include="..\ExchangeHub\ExchangeHub.csproj">
|
||||
<Project>{6033FF0C-CF32-4BC5-8EFE-4774CCDC663D}</Project>
|
||||
<Name>ExchangeHub</Name>
|
||||
</ProjectReference>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<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>
|
||||
@@ -0,0 +1,26 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,5 +8,12 @@
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -10,7 +11,7 @@
|
||||
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;
|
||||
@@ -21,12 +22,14 @@
|
||||
= 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;
|
||||
@@ -102,6 +105,18 @@
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
@@ -176,11 +191,16 @@
|
||||
if (this.IsRunning())
|
||||
{
|
||||
var response = this.connection.ViewSystemParameters();
|
||||
this.Running = response.IsValid;
|
||||
this.Header = response.BuildInfo.Value;
|
||||
this.Progress += 10;
|
||||
|
||||
this.Meter.Add(response);
|
||||
App.Invoke(() =>
|
||||
{
|
||||
this.Running = response.Status == Status.Completed;
|
||||
this.IsValid = response.IsValid;
|
||||
this.Header = response.BuildInfo.Value;
|
||||
this.Progress += 10;
|
||||
|
||||
this.Meter.Add(response);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,10 +216,11 @@
|
||||
if (this.IsRunning())
|
||||
{
|
||||
var response = this.connection.Set(defaults.InputVolume);
|
||||
this.Running = response.Succeeded;
|
||||
this.Running = response.Status == Status.Completed;
|
||||
this.IsValid = this.Running;
|
||||
this.Progress += 10;
|
||||
|
||||
if (this.Running)
|
||||
if (this.IsValid)
|
||||
{
|
||||
this.Meter.Add(defaults.InputVolume);
|
||||
|
||||
@@ -228,13 +249,14 @@
|
||||
var rotations = pp.Rotations;
|
||||
var duration = pp.Duration;
|
||||
var response = connection.StartChamberCalibration(pp.Rotations, pp.Duration);
|
||||
|
||||
this.Running = response.Succeeded && response.Control == ChamberCalibrationResponse.TEST_ACTIVATED;
|
||||
this.Running = response.Status == Status.Completed;
|
||||
this.IsValid = response.Completed && response.Control == ChamberCalibrationResponse.TEST_ACTIVATED;
|
||||
|
||||
this.Progress += 10;
|
||||
|
||||
this.Meter.Add(pp);
|
||||
|
||||
if (this.Running)
|
||||
if (this.IsValid)
|
||||
{
|
||||
this.State = $"{this.Header} PP {rotations}/{duration}";
|
||||
}
|
||||
@@ -256,24 +278,25 @@
|
||||
{
|
||||
if (this.IsRunning())
|
||||
{
|
||||
var resonse = connection.ViewChamberCalibration();
|
||||
var response = connection.ViewChamberCalibration();
|
||||
|
||||
this.results[pp].Rotations = resonse.Rotations;
|
||||
this.results[pp].Duration = resonse.Duration;
|
||||
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 = resonse.Succeeded && resonse.Control == ChamberCalibrationResponse.TEST_COMPLETED;
|
||||
this.Running = response.Status == Status.Completed;
|
||||
this.IsValid = response.Completed && response.Control == ChamberCalibrationResponse.TEST_COMPLETED;
|
||||
|
||||
this.Meter.Add(this.results[pp]);
|
||||
|
||||
if (this.Running)
|
||||
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:{resonse.Status}, Control:{resonse.Control}";
|
||||
this.State = $"{this.Header} PP {pp.Rotations}/{pp.Duration} failed: Status:{response.Status}, Control:{response.Control}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -298,16 +321,25 @@
|
||||
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.MeterUnits = (byte)MessurementUnits.CubicMeters;
|
||||
registerSettings.FlowUnits = (byte)MessurementUnits.CubicMeters;
|
||||
registerSettings.FlowRate = (byte)TimeUnits.Hours;
|
||||
registerSettings.FactoryCorrection = 33;
|
||||
registerSettings.FieldCorrection = 0x00;
|
||||
registerSettings.PulseWeight = 0x01;
|
||||
registerSettings.PulseWidth = 0x02;
|
||||
registerSettings.PulseUpdate = 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} %");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -508,9 +540,13 @@
|
||||
{
|
||||
var response = this.connection.ViewRegisterSettings();
|
||||
|
||||
if (response.Succeeded)
|
||||
if (response.Completed)
|
||||
{
|
||||
this.Meter.AddResult("<<< Correction factor", $"{response.FactoryCorrection / 10D:0.00} %");
|
||||
this.Meter.AddResult("<<< Correction factor", $"{(response.FactoryCorrection / 10D):0.00} %");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Meter.AddResult("<<< !!! Correction factor", $"{(response.FactoryCorrection / 10D):0.00} %");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -520,20 +556,41 @@
|
||||
|
||||
internal double GetCorrectionFactor()
|
||||
{
|
||||
var deviations = this.results
|
||||
.OrderBy(x => x.Key.GPM)
|
||||
var orderedResults = this.results
|
||||
.OrderBy(x => x.Key.GPM);
|
||||
var accuracies = orderedResults
|
||||
.Select(x => x.Value.DifferencePercentage())
|
||||
.ToArray();
|
||||
|
||||
var correction = deviations.GetCorrectionFactor();
|
||||
var correctionUnit = 1 + correction / 100;
|
||||
var correction = accuracies.GetCorrectionFactor();
|
||||
|
||||
this.State = $"{this.Header}, correction: {correction:0.00} %";
|
||||
this.Meter.AddFactoryCorrection(correction);
|
||||
this.Meter.AddResult(string.Empty, string.Empty);
|
||||
|
||||
foreach (var deviation in deviations)
|
||||
var correctionUnit = 1 + correction / 100;
|
||||
var testPoints = orderedResults
|
||||
.Select(x => x.Key)
|
||||
.ToArray();
|
||||
var length = testPoints.Length;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
this.Meter.AddResult($"{deviation:0.00} %", $"{deviation * correctionUnit:0.00} %");
|
||||
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;
|
||||
@@ -560,5 +617,106 @@
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,10 +49,11 @@
|
||||
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 int size;
|
||||
public int Size
|
||||
private byte size;
|
||||
public byte Size
|
||||
{
|
||||
get => this.size;
|
||||
set
|
||||
@@ -159,6 +160,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
private string suchnr;
|
||||
public string SuchNr
|
||||
{
|
||||
get => this.suchnr;
|
||||
set => this.Set(ref this.suchnr, value, nameof(SuchNr));
|
||||
}
|
||||
|
||||
private OmniPlusType omniDefaults;
|
||||
public OmniPlusType OmniDefaults
|
||||
{
|
||||
@@ -181,13 +189,14 @@
|
||||
|
||||
public ICommand CheckInspection { get; }
|
||||
|
||||
public ICommand ReadDisplay { get; }
|
||||
|
||||
private string errorLog;
|
||||
private void PrepareConnections()
|
||||
{
|
||||
try
|
||||
{
|
||||
var directory = Directory.CreateDirectory(".\\Results");
|
||||
this.errorLog = Path.Combine(directory.FullName, $"errors.txt");
|
||||
this.errorLog = Path.Combine(App.ExeDirectory, $"ui_logs.txt");
|
||||
|
||||
File.AppendAllText(this.errorLog, string.Empty);
|
||||
}
|
||||
@@ -198,53 +207,67 @@
|
||||
|
||||
this.exchangeConnection.Connect(Appsettings.Current.ExchangeHubURL);
|
||||
|
||||
if (this.Size == 0 || this.Type is null)
|
||||
if (string.IsNullOrWhiteSpace(this.SuchNr) && this.Size == 0 && this.Type is null)
|
||||
{
|
||||
this.Error = "Size und Type auswählen!";
|
||||
this.Error = "FertigungsauftragNr eingeben oder Size und Type auswählen!";
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
this.Error = default(string);
|
||||
|
||||
|
||||
if (this.Nodes.Any())
|
||||
App.Invoke(() =>
|
||||
{
|
||||
foreach (var disposable in this.Nodes.Cast<IDisposable>())
|
||||
if (this.Nodes.Any())
|
||||
{
|
||||
disposable.Dispose();
|
||||
foreach (var disposable in this.Nodes.Cast<IDisposable>())
|
||||
{
|
||||
disposable.Dispose();
|
||||
}
|
||||
|
||||
this.Nodes.Clear();
|
||||
this.Option.Clear();
|
||||
}
|
||||
|
||||
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.dbcontext.LoadOmniDefaults((byte)this.Size, this.Type, this.OmniDefaults);
|
||||
this.NotifyPropertyChanged(nameof(this.OmniDefaults));
|
||||
this.Text = $"ME OMNI 1.5-2\" {this.Type}";
|
||||
this.Text = $"ME OMNI 1.5-2\" {this.Type}";
|
||||
}
|
||||
});
|
||||
|
||||
try
|
||||
{
|
||||
var placeNr = 1;
|
||||
|
||||
foreach (var com in Appsettings.Current.COMPorts)
|
||||
App.Invoke(() =>
|
||||
{
|
||||
var comVM = new COMContentVM();
|
||||
comVM.ContentSelected += this.NotifyCotnentSelected;
|
||||
comVM.PortName = com;
|
||||
comVM.Nr = placeNr++;
|
||||
comVM.Header = $"{com}";
|
||||
comVM.State = $"{com}";
|
||||
var placeNr = 1;
|
||||
|
||||
this.Nodes.Add(comVM);
|
||||
this.Option.Add(comVM.Option);
|
||||
}
|
||||
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.Option.SetIndentation(this.Option.Indent);
|
||||
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 this.Nodes.Cast<COMContentVM>())
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.InitializeAsync(cancellationToken));
|
||||
}
|
||||
@@ -252,11 +275,19 @@
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in this.Nodes.Cast<COMContentVM>())
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.GetStateIfNewAsync(cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.ReadSystemParametersAsync(cancellationToken));
|
||||
}
|
||||
}, wait: false);
|
||||
}, false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -264,10 +295,13 @@
|
||||
this.LogError(e.ToString());
|
||||
}
|
||||
|
||||
this.CanStop = false;
|
||||
this.CanStart = true;
|
||||
this.Error = default(string);
|
||||
this.State = default(string);
|
||||
App.Invoke(() =>
|
||||
{
|
||||
this.CanStop = false;
|
||||
this.CanStart = true;
|
||||
this.Error = default(string);
|
||||
this.State = default(string);
|
||||
});
|
||||
}
|
||||
|
||||
private void CancelInspectionHandler()
|
||||
@@ -360,14 +394,10 @@
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
// this.canceled = this.canceled || meterVM.IsRunning();
|
||||
|
||||
tasks.Add(meterVM.StartPPCalibrationAsync(pp, cancellationToken));
|
||||
}
|
||||
});
|
||||
@@ -397,8 +427,6 @@
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
// this.canceled = this.canceled || meterVM.IsRunning();
|
||||
|
||||
tasks.Add(meterVM.StopPPCalibrationAsync(pp, referenceFlowM3S, cancellationToken));
|
||||
}
|
||||
});
|
||||
@@ -411,20 +439,9 @@
|
||||
|
||||
this.exchangeConnection.SendStopFlow();
|
||||
|
||||
if (!this.canceled)
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
meterVM.GetCorrectionFactor();
|
||||
}
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.SetRegisterSettingsAsync(cancellationToken));
|
||||
}
|
||||
});
|
||||
meterVM.GetCorrectionFactor();
|
||||
}
|
||||
|
||||
foreach (var meterVM in metersVM)
|
||||
@@ -564,8 +581,6 @@
|
||||
};
|
||||
this.timer.Elapsed += (_1, _2) =>
|
||||
{
|
||||
this.AvailableIn -= 1;
|
||||
|
||||
if (show)
|
||||
{
|
||||
if (error)
|
||||
@@ -584,7 +599,12 @@
|
||||
{
|
||||
this.AvailableIn = 0;
|
||||
this.awaiter?.Set();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
this.AvailableIn -= 1;
|
||||
|
||||
};
|
||||
|
||||
this.timer.Start();
|
||||
@@ -741,8 +761,6 @@
|
||||
{
|
||||
foreach (var t in _tasks)
|
||||
{
|
||||
this.LogError($"[{t.Id}]:{nameof(t.Status)} = {t.Status}{Environment.NewLine}");
|
||||
|
||||
if (t.Exception != null)
|
||||
{
|
||||
this.LogError($"[{t.Id}]:{t.Exception}{Environment.NewLine}");
|
||||
@@ -766,8 +784,6 @@
|
||||
.StartNew(action, cancellationToken)
|
||||
.ContinueWith(t =>
|
||||
{
|
||||
this.LogError($"[{t.Id}]:{nameof(t.Status)} = {t.Status}{Environment.NewLine}");
|
||||
|
||||
if (t.Exception != null)
|
||||
{
|
||||
this.LogError($"[{t.Id}]:{t.Exception}{Environment.NewLine}");
|
||||
@@ -786,5 +802,24 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
internal void Add(OmniPlus.Features.SystemParameters response)
|
||||
{
|
||||
if (response.Succeeded)
|
||||
if (response.Completed)
|
||||
{
|
||||
this.AddResult(nameof(response.VersionAndType), response.VersionAndType.Value);
|
||||
this.AddResult(nameof(response.BuildInfo), response.BuildInfo.Value);
|
||||
@@ -66,6 +66,8 @@
|
||||
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}");
|
||||
@@ -75,18 +77,18 @@
|
||||
|
||||
internal void Add(OmniPlusTestPoint pp)
|
||||
{
|
||||
this.AddResult("", $"");
|
||||
this.AddResult("Test point:", $"{pp.Rotations}/{pp.Duration:0}");
|
||||
this.AddResult("Volume", $"{pp.RequiredFlowM3H:0.00000000 m³/h}");
|
||||
this.AddResult("Validation frame", $"{pp.MinDiff:0.00}% - {pp.MaxDiff:0.00}%");
|
||||
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 volume", $"{test.MeterFlowM3S:0.00000000 m³}");
|
||||
this.AddResult("Reference volume", $"{test.ReferenceFlowM3S:0.00000000 m³}");
|
||||
this.AddResult("Deviation", $"{test.DifferencePercentage():0.00}%");
|
||||
this.AddResult("Meter flow", $"{test.MeterFlowM3S:0.00000000} m³/h");
|
||||
this.AddResult("Reference flow", $"{test.ReferenceFlowM3S:0.00000000} m³/h");
|
||||
this.AddResult("Accuracy", $"{test.DifferencePercentage():0.00}%");
|
||||
}
|
||||
|
||||
internal void Add(ConfigurationParameters response)
|
||||
@@ -105,7 +107,7 @@
|
||||
{
|
||||
this.FactoryCorrection = (sbyte)(value * 10);
|
||||
|
||||
this.AddResult("Correction", $"{value:0.00} %");
|
||||
this.AddResult("Correction factor", $"{value:0.00} %");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace OMNIPruefung.ViewModels
|
||||
{
|
||||
using OmniPlus;
|
||||
|
||||
public class OmniAuftragVM : BaseVM
|
||||
{
|
||||
private OmniAuftrag auftrag;
|
||||
|
||||
public OmniAuftragVM(OmniAuftrag auftrag)
|
||||
{
|
||||
this.auftrag = auftrag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,12 @@
|
||||
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;
|
||||
@@ -58,6 +64,7 @@
|
||||
this.NotifyPropertyChanged(nameof(this.Progress));
|
||||
this.NotifyPropertyChanged(nameof(this.State));
|
||||
this.NotifyPropertyChanged(nameof(this.Visible));
|
||||
this.NotifyPropertyChanged(nameof(this.IsValid));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,12 +77,15 @@
|
||||
|
||||
<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>
|
||||
<ComboBox Grid.Column="0" Text="{Binding Size}" HorizontalAlignment="Stretch" Margin="0, 2, 2, 2">
|
||||
<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>
|
||||
@@ -91,7 +94,7 @@
|
||||
<ComboBoxItem >10</ComboBoxItem>
|
||||
<ComboBoxItem >11</ComboBoxItem>
|
||||
</ComboBox>
|
||||
<ComboBox Grid.Column="1" Text="{Binding Type}" HorizontalAlignment="Stretch" Margin="2, 2, 0, 2">
|
||||
<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>
|
||||
@@ -102,6 +105,10 @@
|
||||
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"/>
|
||||
@@ -152,7 +159,7 @@
|
||||
Grid.ColumnSpan="3"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
Foreground="{Binding Running, Converter={StaticResource BooleanProgress}}"
|
||||
Foreground="{Binding IsValid, Converter={StaticResource BooleanProgress}}"
|
||||
Value="{Binding Progress}"
|
||||
Background="WhiteSmoke"
|
||||
BorderBrush="WhiteSmoke"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
this.WritePlain(1, 1, 1, 1);
|
||||
|
||||
this.waitHandle.Wait(1);
|
||||
@@ -42,6 +42,11 @@
|
||||
|
||||
this.waitHandle.Wait(3000);
|
||||
this.waitHandle.Reset();
|
||||
|
||||
if (response != null && response.Length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.StopListening();
|
||||
|
||||
@@ -362,5 +362,44 @@
|
||||
|
||||
return BitConverter.GetBytes(checksum);
|
||||
}
|
||||
|
||||
public static byte[] CalculateCRC16(this byte[] data, ushort start, ushort length)
|
||||
{
|
||||
var ui_index = start;
|
||||
var test = default(byte);
|
||||
var zeichen = default(byte);
|
||||
var crc_result = ushort.MaxValue;
|
||||
|
||||
if (data.Length >= length + start)
|
||||
{
|
||||
while (ui_index < length + start)
|
||||
{
|
||||
zeichen = data[ui_index];
|
||||
ui_index++;
|
||||
|
||||
for (byte h = 0; h < 8; h++)
|
||||
{
|
||||
test = 0;
|
||||
|
||||
if ((crc_result & 0x8000) != 0)
|
||||
{
|
||||
test = 0x80;
|
||||
}
|
||||
|
||||
crc_result <<= 1;
|
||||
|
||||
if (((zeichen & 0x80) ^ test) != 0)
|
||||
{
|
||||
crc_result ^= 0x1021;
|
||||
}
|
||||
|
||||
zeichen <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return BitConverter.GetBytes(crc_result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
this.buffer.Clear();
|
||||
this.waitHandle.Set();
|
||||
}
|
||||
@@ -85,7 +84,7 @@
|
||||
protected void WriteEncoded(params byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
{
|
||||
if (this.encoder.TryEncode(bytes, out byte[] message))
|
||||
{
|
||||
this.Write(message, 0, message.Length);
|
||||
@@ -145,7 +144,6 @@
|
||||
|
||||
private void StartReading()
|
||||
{
|
||||
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
this.readingTask = Task.Factory.StartNew(this.ReadingTaskHandler, this.cancellationToken);
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
public class ConfigurationParametersSet : FeatureRequest
|
||||
{
|
||||
const int LENGTH = 90;
|
||||
const int LENGTH = 80;
|
||||
|
||||
public ConfigurationParametersSet() : base(LENGTH)
|
||||
{
|
||||
@@ -88,9 +88,9 @@
|
||||
get => this.programmableID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 1, 20);
|
||||
this.SetASCIIBytes(value, 0, 20);
|
||||
|
||||
this.programmableID = this.bytes.ToASCIIString(1, 20);
|
||||
this.programmableID = this.bytes.ToASCIIString(0, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,9 +105,9 @@
|
||||
get => this.factoryID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 22, 33);
|
||||
this.SetASCIIBytes(value, 21, 33);
|
||||
|
||||
this.factoryID = this.bytes.ToASCIIString(22, 33);
|
||||
this.factoryID = this.bytes.ToASCIIString(21, 33);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,9 +139,9 @@
|
||||
get => this.readingPreset;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 39, 47);
|
||||
this.SetASCIIBytes(value, 38, 47);
|
||||
|
||||
this.readingPreset = this.bytes.ToASCIIString(36, 47);
|
||||
this.readingPreset = this.bytes.ToASCIIString(38, 47);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,9 +240,9 @@
|
||||
get => this.buildInfo;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 65, 79);
|
||||
this.SetASCIIBytes(value, 64, 79);
|
||||
|
||||
this.buildInfo = this.bytes.ToASCIIString(65, 79);
|
||||
this.buildInfo = this.bytes.ToASCIIString(64, 79);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,9 +257,9 @@
|
||||
get => this.deviceID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 81, 89);
|
||||
this.SetASCIIBytes(value, 80, 89);
|
||||
|
||||
this.deviceID = this.bytes.ToASCIIString(81, 89);
|
||||
this.deviceID = this.bytes.ToASCIIString(80, 89);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,6 @@
|
||||
set => this.SecondsSince = (uint)(value - epoch).TotalSeconds;
|
||||
}
|
||||
|
||||
public static uint UTCNow => new Epoch20000101 { DateTime = DateTime.UtcNow }.SecondsSince + 3;
|
||||
public static uint UTCNow => new Epoch20000101 { DateTime = DateTime.UtcNow }.SecondsSince + 10;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,14 +28,17 @@
|
||||
|
||||
if (responseLength > 1)
|
||||
{
|
||||
Array.Copy(response, 1, this.bytes, 0, this.length);
|
||||
for (int src = 1, dst = 0; src < responseLength && dst < this.length; src++, dst++)
|
||||
{
|
||||
this.bytes[dst] = response[src];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Status Status { get; set; }
|
||||
|
||||
public bool Succeeded => this.Status == Status.Completed;
|
||||
public bool Completed => this.Status == Status.Completed;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
=> obj is FeatureResponse outer && outer.bytes == this.bytes;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
|
||||
internal static class FeaturesExtensions
|
||||
public static class FeaturesExtensions
|
||||
{
|
||||
public const int BYTE_BITS = 8;
|
||||
|
||||
@@ -49,14 +49,20 @@
|
||||
|
||||
public static byte[] Reverse(this byte[] bytes)
|
||||
{
|
||||
var length = bytes.Length / 2;
|
||||
|
||||
for (int i = 0; i < length; i++)
|
||||
if (bytes is null || bytes.Length <= 1)
|
||||
{
|
||||
var last = length - i - 1;
|
||||
var first = bytes[i];
|
||||
bytes[i] = bytes[last];
|
||||
bytes[last] = first;
|
||||
return bytes;
|
||||
}
|
||||
|
||||
var length = bytes.Length;
|
||||
var _length = length / 2;
|
||||
var last = length - 1;
|
||||
|
||||
for (int i = 0; i < _length; i++)
|
||||
{
|
||||
var current = bytes[i];
|
||||
bytes[i] = bytes[last - i];
|
||||
bytes[last - i] = current;
|
||||
}
|
||||
|
||||
return bytes;
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using OmniPlus.Connections;
|
||||
using OmniPlus.Features;
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using static OmniPlus.Features.Features;
|
||||
|
||||
public delegate byte[] MessageHandler(params byte[] bytes);
|
||||
@@ -9,12 +14,19 @@
|
||||
|
||||
public abstract class OmniConnection
|
||||
{
|
||||
public abstract bool IsOpen { get; }
|
||||
|
||||
protected MessageHandler MessageHandler { get; set; }
|
||||
|
||||
public abstract void Close();
|
||||
|
||||
public abstract void Open();
|
||||
|
||||
public byte[] Send(params byte[] bytes)
|
||||
{
|
||||
return this.MessageHandler?.Invoke(bytes);
|
||||
}
|
||||
|
||||
public FactoryID ViewFactoryID()
|
||||
{
|
||||
var response = this.MessageHandler.Invoke(VIEW_FACTORY_ID);
|
||||
@@ -363,11 +375,12 @@
|
||||
|
||||
public FeatureResponse Unseal()
|
||||
{
|
||||
var request = new byte[18];
|
||||
request[0] = DEVICE_SPECIFIC;
|
||||
request[1] = SET_FACTORY_SEAL;
|
||||
|
||||
|
||||
// TODO: Implement factory unseal.
|
||||
// 1. ((View Seconds Active) >> 8) &0xFFFF
|
||||
// 2. CRC16_iPERL(View Factory ID),
|
||||
// 3. ViewCustomerText.Substring(0, 4).Sum(x => x.Count(x => x == 1))
|
||||
// 4. ViewReadingPreset.Substring(3, 4)
|
||||
// - The ASCII values in hex for those characters are 0x33 34 35 36 which when reinterpreted as a uint32BE represents
|
||||
// - the value 859059510 in decimal. That, mod 11 is 1, so VVVV is 0x0001.
|
||||
// - When the input data is a string, and does not contain the number of characters required for this algorithm,
|
||||
@@ -377,10 +390,78 @@
|
||||
// - to send the unseal command.Because of this, if the register responds with Unable to execute,
|
||||
// - you should recalculate the hash which should last for a longer period if SSSS is large / close to rolling over.
|
||||
// - Also, if the 7th digit rolls over during unsealing, the hash will not be valid.
|
||||
// - Current system time is written into manufacturing date/ time if the manufacturing date/ time has not been set
|
||||
// - Current system time is written into manufacturing date/ time if the manufacturing date / time has not been set
|
||||
// - when factory seal is set.
|
||||
var muster = new byte[] { (byte)'F', (byte)'a', (byte)'c', (byte)'t', (byte)'o', (byte)'r', (byte)'y' };
|
||||
var key = new byte[16];
|
||||
|
||||
return new FeatureResponse();
|
||||
// 1. ((View Seconds Active) >> 8) &0xFFFF
|
||||
var secondsActive = new Epoch20000101(this.Send(0xFD, 0x3D)).SecondsSince;
|
||||
var SSSS = BitConverter.GetBytes((secondsActive >> 8) & 0xFFFF);
|
||||
|
||||
Buffer.BlockCopy(SSSS, 0, key, 0, 4);
|
||||
|
||||
// 2. CRC16_iPERL(View Factory ID),
|
||||
var factoryID = this.ViewFactoryID().Value;
|
||||
var factoryIDBytes = Encoding.ASCII.GetBytes(factoryID);
|
||||
var IIII = factoryIDBytes.CalculateCRC16(0, (ushort)factoryIDBytes.Length);
|
||||
|
||||
Buffer.BlockCopy(IIII, 0, key, 4, 2);
|
||||
|
||||
// 3. ViewCustomerText.Substring(0, 4).Sum(x => x.Count(x => x == 1))
|
||||
var customerText = this.ViewCustomerText().Value;
|
||||
var ctLength = customerText?.Length ?? 0;
|
||||
var CCCC = new byte[4];
|
||||
|
||||
for (int ct = 0; ct < 4; ct++)
|
||||
{
|
||||
if (ctLength > ct + 3)
|
||||
{
|
||||
CCCC[ct] = (byte)customerText[ct + 3];
|
||||
}
|
||||
else
|
||||
{
|
||||
CCCC[ct] = muster[ct];
|
||||
}
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(CCCC, 0, key, 8, 4);
|
||||
|
||||
// 4. ViewReadingPreset.Substring(3, 4)
|
||||
var readings = this
|
||||
.ViewReadings()
|
||||
.Value
|
||||
.Substring(3, 4)
|
||||
.ToCharArray()
|
||||
.Reverse()
|
||||
.Select(x => (byte)x)
|
||||
.ToArray();
|
||||
|
||||
|
||||
for (int x = readings.Length - 1; x < 4; x++)
|
||||
{
|
||||
readings[x] = muster[x];
|
||||
}
|
||||
|
||||
var value = BitConverter.ToUInt32(readings, 0) % 11;
|
||||
var VVVV = BitConverter.GetBytes(value);
|
||||
|
||||
Buffer.BlockCopy(VVVV, 0, key, 12, 4);
|
||||
|
||||
Console.WriteLine(BitConverter.ToString(key));
|
||||
|
||||
if (key is null || key.Length != 16)
|
||||
{
|
||||
return new FactorySeal();
|
||||
}
|
||||
|
||||
//var _key = key.Reverse();
|
||||
|
||||
Buffer.BlockCopy(key, 0, request, 2, 16);
|
||||
|
||||
var response = this.MessageHandler.Invoke(request);
|
||||
|
||||
return new FactorySeal(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
public class OmniContext
|
||||
{
|
||||
private readonly ConcurrentDictionary<int, OmniMeter> meters;
|
||||
private readonly OmniDatabase database;
|
||||
|
||||
private OmniContext(string connectionString)
|
||||
{
|
||||
this.database = new OmniDatabase(connectionString);
|
||||
this.meters = new ConcurrentDictionary<int, OmniMeter>();
|
||||
}
|
||||
|
||||
public OmniAuftrag Auftrag { get; set; }
|
||||
|
||||
public static OmniContext Current { get; private set; }
|
||||
|
||||
public static OmniContext GetOrCreateInstance(string connectionString)
|
||||
{
|
||||
if (Current is null)
|
||||
{
|
||||
Current = new OmniContext(connectionString);
|
||||
}
|
||||
|
||||
return Current;
|
||||
}
|
||||
|
||||
public void LoadAuftrag(string suchnr)
|
||||
{
|
||||
this.Auftrag = this.database.LoadAuftrag(suchnr);
|
||||
}
|
||||
|
||||
public void LoadAuftrag(byte size, string type)
|
||||
{
|
||||
this.Auftrag = this.database.LoadAuftrag(size, type);
|
||||
}
|
||||
|
||||
public OmniMeter LoadMeter(int nr, string portName)
|
||||
{
|
||||
var meter = new OmniMeter(nr, portName);
|
||||
|
||||
return this.meters.AddOrUpdate(nr, meter, (_, _1) => meter);
|
||||
}
|
||||
|
||||
internal bool Exists(string meterNr)
|
||||
{
|
||||
return this.database.OmniPlus_Exists(meterNr);
|
||||
}
|
||||
|
||||
internal void Add(string meterNr, string meterState)
|
||||
{
|
||||
this.database.OmniPlus_Insert(meterNr, meterState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,221 +1,294 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using OmniPlus.Features;
|
||||
using Common.SqlExtensions;
|
||||
using Common.SqlExtensions.Interfaces;
|
||||
|
||||
using OmniPlus.Inspection;
|
||||
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class OmniDatabase
|
||||
{
|
||||
private readonly string connectionString;
|
||||
private readonly ISQLConnection sqlConnection;
|
||||
|
||||
public OmniDatabase(string omniDatabase)
|
||||
=> this.connectionString = omniDatabase;
|
||||
|
||||
public void AddOrUpdate(int position, SystemParameters parameters)
|
||||
public OmniDatabase(string connectionString)
|
||||
{
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
{
|
||||
sqlConnection.OpenConnection();
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
INSERT
|
||||
INTO [OmniTestStates] ([Position])
|
||||
VALUES (@{nameof(position)})";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(position), position));
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
sqlCommand.Parameters.Clear();
|
||||
}
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
UPDATE [OmniTestStates]
|
||||
SET [BuildInfo] = @{nameof(parameters.BuildInfo)}
|
||||
, [ManifacturingTime] = @{nameof(parameters.ManifacturingTime)}
|
||||
, [RebootsCount] = @{nameof(parameters.RebootsCount)}
|
||||
, [VersionAndType] = @{nameof(parameters.VersionAndType)}
|
||||
WHERE [Position] = @{nameof(position)}";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(position), position));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.VersionAndType), parameters.VersionAndType.Value));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.RebootsCount), parameters.RebootsCount));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.ManifacturingTime), parameters.ManifacturingTime.DateTime));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.BuildInfo), parameters.BuildInfo.Value));
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
sqlCommand.Parameters.Clear();
|
||||
}
|
||||
}
|
||||
this.sqlConnection = SQLConnection.CreateSQLConnection(connectionString);
|
||||
}
|
||||
|
||||
public void AddOrUpdate(int position, ConfigurationParameters parameters)
|
||||
public OmniAuftrag LoadAuftrag(string suchNr)
|
||||
{
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
var auftrag = default(OmniAuftrag);
|
||||
|
||||
this.sqlConnection
|
||||
.CreateCommand($@"
|
||||
SELECT [APP].[FertigungsauftragNr] -- 0
|
||||
, [APP].[AuftragNr] -- 1
|
||||
, [APP].[PositionNr] -- 2
|
||||
, [APP].[Menge] -- 3
|
||||
, [APP].[KundenNr] -- 4
|
||||
, [APP].[IdentNr] -- 5
|
||||
, [IDN].[KurzBez] -- 6
|
||||
, [IDN].[Typ] -- 7
|
||||
, [IDN].[Typzusatz] -- 8
|
||||
, [IDN].[Nennweite] -- 9
|
||||
, [OT].[TypeId] -- 10
|
||||
, [OT].[Type] -- 11
|
||||
, [OT].[Size] -- 12
|
||||
, [OT].[Range] -- 13
|
||||
, [OT].[Direction] -- 14
|
||||
, [OT].[IntPart] -- 15
|
||||
, [OT].[Fraction] -- 16
|
||||
, [OT].[CorrectionFactor] -- 17
|
||||
, [OT].[PulsePerRotation] -- 18
|
||||
, [OTP].[TestPointId] -- 19
|
||||
, [OTP].[OmniTypeId] -- 20
|
||||
, [OTP].[OmniVariant] -- 21
|
||||
, [OTP].[GalPerMin] -- 22
|
||||
, [OTP].[Rotations] -- 23
|
||||
, [OTP].[Duration] -- 24
|
||||
, [OTP].[MinAccuracy] -- 25
|
||||
, [OTP].[MaxAccuracy] -- 26
|
||||
FROM [AlleAuftragPositionen] AS [APP]
|
||||
JOIN [Identnr] AS [IDN] ON [IDN].[IdentNr] = [APP].[IdentNr]
|
||||
JOIN [OmniTypes] AS [OT] ON [IDN].[Typzusatz] LIKE '%' + [OT].[Type] + '%'
|
||||
JOIN [OmniTestPoints] AS [OTP] ON [OTP].[OmniTypeId] = [OT].[TypeId] AND [IDN].[Typzusatz] LIKE '%' + [OTP].[OmniVariant] + '%'
|
||||
WHERE [APP].[FertigungsauftragNr] = @{nameof(suchNr)}
|
||||
ORDER BY [OTP].[GalPerMin] DESC")
|
||||
.SetParameter(nameof(suchNr), suchNr)
|
||||
.ExecuteReader(reader =>
|
||||
{
|
||||
if (auftrag is null)
|
||||
{
|
||||
auftrag = new OmniAuftrag
|
||||
{
|
||||
FertigungsauftragNr = reader.GetInt(0),
|
||||
AuftragNr = reader.GetInt(1),
|
||||
PositionNr = reader.GetSmallint(2),
|
||||
Menge = reader.GetInt(3),
|
||||
KundenNr = reader.GetInt(4),
|
||||
IdentNr = reader.GetInt(5),
|
||||
KurzBez = reader.GetString(6),
|
||||
Typ = reader.GetString(7),
|
||||
Typzusatz = reader.GetString(8),
|
||||
Nennweite = reader.GetInt(9),
|
||||
Grosse = reader.GetString(11),
|
||||
Variante = reader.GetString(21)
|
||||
};
|
||||
}
|
||||
|
||||
if (auftrag.TypParameter is null)
|
||||
{
|
||||
auftrag.TypParameter = new OmniParameter
|
||||
{
|
||||
TypeId = reader.GetTinyint(10),
|
||||
Type = reader.GetString(11),
|
||||
Size = reader.GetTinyint(12),
|
||||
Range = reader.GetTinyint(13),
|
||||
Direction = reader.GetTinyint(14),
|
||||
IntPart = reader.GetTinyint(15),
|
||||
Fraction = reader.GetInt(16),
|
||||
Factor = reader.GetSmallint(17),
|
||||
PulsePerRotation = reader.GetTinyint(18)
|
||||
};
|
||||
}
|
||||
|
||||
if (auftrag.Pruefpunkte is null)
|
||||
{
|
||||
auftrag.Pruefpunkte = new HashSet<OmniPruefpunkt>();
|
||||
}
|
||||
|
||||
auftrag.Pruefpunkte.Add(new OmniPruefpunkt
|
||||
{
|
||||
TestPointId = reader.GetSmallint(19),
|
||||
OmniTypeId = reader.GetTinyint(20),
|
||||
OmniVariant = reader.GetString(21),
|
||||
GalPerMin = reader.GetValue<double>(22),
|
||||
Rotations = reader.GetSmallint(23),
|
||||
Duration = reader.GetSmallint(24),
|
||||
MinAccuracy = reader.GetValue<double>(25),
|
||||
MaxAccuracy = reader.GetValue<double>(26),
|
||||
});
|
||||
});
|
||||
|
||||
return auftrag ?? new OmniAuftrag
|
||||
{
|
||||
sqlConnection.OpenConnection();
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
INSERT
|
||||
INTO [OmniTestStates] ([Position])
|
||||
VALUES (@{nameof(position)})";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(position), position));
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
sqlCommand.Parameters.Clear();
|
||||
}
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
UPDATE [OmniTestStates]
|
||||
SET [ProgrammableID] = @{nameof(parameters.ProgrammableID)}
|
||||
, [FactoryID] = @{nameof(parameters.FactoryID)}
|
||||
, [ReadingDigitsCount] = @{nameof(parameters.ReadingDigits.Count)}
|
||||
, [ReadingDigitsOffsest] = @{nameof(parameters.ReadingDigits.Offset)}
|
||||
, [Readings] = @{nameof(parameters.Readings)}
|
||||
, [OptionalUniDirFields] = @{nameof(parameters.OptionalUniDirFields)}
|
||||
, [AlarmPersitenceDays] = @{nameof(parameters.AlarmPersistenceDays)}
|
||||
, [DataLogIntervalMins] = @{nameof(parameters.DataLogIntervalMins)}
|
||||
WHERE [Position] = @{nameof(position)}";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(position), position));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.ProgrammableID), parameters.ProgrammableID.Value));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.FactoryID), parameters.FactoryID.Value));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.ReadingDigits.Count), parameters.ReadingDigits.Count));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.ReadingDigits.Offset), parameters.ReadingDigits.Offset));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.Readings), parameters.Readings.Value));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.OptionalUniDirFields), parameters.OptionalUniDirFields.Value));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.AlarmPersistenceDays), parameters.AlarmPersistenceDays));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.DataLogIntervalMins), BitConverter.GetBytes(parameters.DataLogIntervalMins)
|
||||
.Reverse()
|
||||
.ToArray()));
|
||||
|
||||
try
|
||||
{
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
sqlCommand.Parameters.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
TypParameter = new OmniParameter(),
|
||||
Pruefpunkte = new List<OmniPruefpunkt>()
|
||||
};
|
||||
}
|
||||
|
||||
public void LoadOmniDefaults(byte size, string variant, OmniPlusType omniType)
|
||||
public OmniAuftrag LoadAuftrag(byte size, string variant)
|
||||
{
|
||||
omniType?.TestPoints?.Clear();
|
||||
var auftrag = default(OmniAuftrag);
|
||||
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
this.sqlConnection
|
||||
.CreateCommand($@"
|
||||
SELECT [OT].[TypeId] -- 0
|
||||
, [OT].[Type] -- 1
|
||||
, [OT].[Size] -- 2
|
||||
, [OT].[Range] -- 3
|
||||
, [OT].[Direction] -- 4
|
||||
, [OT].[IntPart] -- 5
|
||||
, [OT].[Fraction] -- 6
|
||||
, [OT].[CorrectionFactor] -- 7
|
||||
, [OT].[PulsePerRotation] -- 8
|
||||
, [OTP].[TestPointId] -- 9
|
||||
, [OTP].[OmniTypeId] -- 10
|
||||
, [OTP].[OmniVariant] -- 11
|
||||
, [OTP].[GalPerMin] -- 12
|
||||
, [OTP].[Rotations] -- 13
|
||||
, [OTP].[Duration] -- 14
|
||||
, [OTP].[MinAccuracy] -- 15
|
||||
, [OTP].[MaxAccuracy] -- 16
|
||||
FROM [OmniTypes] AS [OT]
|
||||
JOIN [OmniTestPoints] AS [OTP]
|
||||
ON [OTP].[OmniTypeId] = [OT].[TypeId]
|
||||
WHERE [OT].[Size] = @{nameof(size)}
|
||||
AND [OTP].[OmniVariant] = @{nameof(variant)}
|
||||
ORDER BY [OTP].[GalPerMin] DESC")
|
||||
.SetParameter(nameof(size), size)
|
||||
.SetParameter(nameof(variant), variant)
|
||||
.ExecuteReader(reader =>
|
||||
{
|
||||
if (auftrag is null)
|
||||
{
|
||||
auftrag = new OmniAuftrag
|
||||
{
|
||||
Grosse = reader.GetString(1),
|
||||
Variante = reader.GetString(11)
|
||||
};
|
||||
}
|
||||
|
||||
if (auftrag.TypParameter is null)
|
||||
{
|
||||
auftrag.TypParameter = new OmniParameter
|
||||
{
|
||||
TypeId = reader.GetTinyint(0),
|
||||
Type = reader.GetString(1),
|
||||
Size = reader.GetTinyint(2),
|
||||
Range = reader.GetTinyint(3),
|
||||
Direction = reader.GetTinyint(4),
|
||||
IntPart = reader.GetTinyint(5),
|
||||
Fraction = reader.GetInt(6),
|
||||
Factor = reader.GetSmallint(7),
|
||||
PulsePerRotation = reader.GetTinyint(8)
|
||||
};
|
||||
}
|
||||
|
||||
if (auftrag.Pruefpunkte is null)
|
||||
{
|
||||
auftrag.Pruefpunkte = new HashSet<OmniPruefpunkt>();
|
||||
}
|
||||
|
||||
auftrag.Pruefpunkte.Add(new OmniPruefpunkt
|
||||
{
|
||||
TestPointId = reader.GetSmallint(9),
|
||||
OmniTypeId = reader.GetTinyint(10),
|
||||
OmniVariant = reader.GetString(11),
|
||||
GalPerMin = reader.GetValue<double>(12),
|
||||
Rotations = reader.GetSmallint(13),
|
||||
Duration = reader.GetSmallint(14),
|
||||
MinAccuracy = reader.GetValue<double>(15),
|
||||
MaxAccuracy = reader.GetValue<double>(16),
|
||||
});
|
||||
});
|
||||
|
||||
return auftrag ?? new OmniAuftrag
|
||||
{
|
||||
sqlConnection.OpenConnection();
|
||||
TypParameter = new OmniParameter(),
|
||||
Pruefpunkte = new List<OmniPruefpunkt>()
|
||||
};
|
||||
}
|
||||
|
||||
var field = 0;
|
||||
public bool OmniPlus_Exists(string meterNr)
|
||||
{
|
||||
return this.sqlConnection
|
||||
.CreateCommand($@"SELECT COUNT(1) FROM [OmniPlus] WHERE [MeterNr] = @{nameof(meterNr)}")
|
||||
.SetParameter(nameof(meterNr), meterNr)
|
||||
.ExecuteScalar(x => x.GetInt()) > 0;
|
||||
}
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
SELECT [Id]
|
||||
, [Size]
|
||||
, [Range]
|
||||
, [Direction]
|
||||
, [IntPart]
|
||||
, [Fraction]
|
||||
, [PulsePerRotation]
|
||||
, [CorrectionFactor]
|
||||
FROM [OmniTestTypes]
|
||||
WHERE [Size] = @{nameof(size)}";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(size), size));
|
||||
|
||||
using (var sqlDataReader = sqlCommand.ExecuteReader())
|
||||
{
|
||||
if (sqlDataReader.Read())
|
||||
{
|
||||
field = 0;
|
||||
|
||||
omniType.OmniId = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.Size = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.Range = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.Direction = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.IntPart = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.Fraction = (ushort)sqlDataReader.GetValue<int>(field++);
|
||||
omniType.PulsePerRotation = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.CorrectionFactor = sqlDataReader.GetValue<short>(field++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = $@"
|
||||
SELECT [GalPerMin]
|
||||
, [Rotations]
|
||||
, [Duration]
|
||||
, [MinDiff]
|
||||
, [MaxDiff]
|
||||
FROM [OmniTestPoints]
|
||||
WHERE [OmniTypeId] = @{nameof(omniType.OmniId)}
|
||||
AND [OmniVariant] = @{nameof(variant)}
|
||||
AND [MinDiff] IS NOT NULL
|
||||
ORDER BY [GalPerMin] ASC";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(omniType.OmniId), omniType.OmniId));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(variant), variant));
|
||||
|
||||
using (var sqlDataReader = sqlCommand.ExecuteReader())
|
||||
{
|
||||
var milliliterPerRotation = omniType.MilliliterPerRotation();
|
||||
|
||||
while (sqlDataReader.Read())
|
||||
{
|
||||
field = 0;
|
||||
|
||||
omniType.TestPoints.Add(new OmniPlusTestPoint
|
||||
{
|
||||
MLR = milliliterPerRotation,
|
||||
GPM = sqlDataReader.GetValue<double>(field++),
|
||||
Rotations = (ushort)sqlDataReader.GetValue<short>(field++),
|
||||
Duration = (ushort)sqlDataReader.GetValue<short>(field++),
|
||||
MinDiff = sqlDataReader.GetValue<double>(field++),
|
||||
MaxDiff = sqlDataReader.GetValue<double>(field++),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public int OmniPlus_Insert(string meterNr, string meterState)
|
||||
{
|
||||
return this.sqlConnection
|
||||
.CreateCommand($@"INSERT INTO [OmniPlus] VALUES (@{nameof(meterNr)}, @{nameof(meterState)})")
|
||||
.SetParameter(nameof(meterNr), meterNr)
|
||||
.SetParameter(nameof(meterState), meterState)
|
||||
.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
internal static class SqlConnectionExtensions
|
||||
public class OmniAuftrag
|
||||
{
|
||||
public static void OpenConnection(this SqlConnection connection)
|
||||
{
|
||||
connection.FireInfoMessageEventOnUserErrors = true;
|
||||
connection.InfoMessage += Connection_InfoMessage;
|
||||
connection.Open();
|
||||
}
|
||||
public int FertigungsauftragNr { get; internal set; }
|
||||
|
||||
public static TValue GetValue<TValue>(this SqlDataReader reader, int index)
|
||||
{
|
||||
if (reader.FieldCount > index && !reader.IsDBNull(index) && reader.GetValue(index) is TValue value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
public int AuftragNr { get; internal set; }
|
||||
|
||||
return default(TValue);
|
||||
}
|
||||
public short PositionNr { get; internal set; }
|
||||
|
||||
private static void Connection_InfoMessage(object sender, SqlInfoMessageEventArgs args)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.AppendAllText(".\\sql_connection.log", args.Message);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
public int Menge { get; internal set; }
|
||||
|
||||
public int KundenNr { get; internal set; }
|
||||
|
||||
public int IdentNr { get; internal set; }
|
||||
|
||||
public string KurzBez { get; internal set; }
|
||||
|
||||
public string Typ { get; internal set; }
|
||||
|
||||
public string Grosse { get; internal set; }
|
||||
|
||||
public string Variante { get; internal set; }
|
||||
|
||||
public string Typzusatz { get; internal set; }
|
||||
|
||||
public int Nennweite { get; internal set; }
|
||||
|
||||
public OmniParameter TypParameter { get; internal set; }
|
||||
|
||||
public ICollection<OmniPruefpunkt> Pruefpunkte { get; internal set; }
|
||||
}
|
||||
|
||||
public class OmniParameter
|
||||
{
|
||||
public byte TypeId { get; internal set; }
|
||||
|
||||
public string Type { get; internal set; }
|
||||
|
||||
public byte Size { get; internal set; }
|
||||
|
||||
public byte Range { get; internal set; }
|
||||
|
||||
public byte Direction { get; internal set; }
|
||||
|
||||
public byte IntPart { get; internal set; }
|
||||
|
||||
public int Fraction { get; internal set; }
|
||||
|
||||
public short Factor { get; internal set; }
|
||||
|
||||
public byte PulsePerRotation { get; internal set; }
|
||||
}
|
||||
|
||||
public class OmniPruefpunkt
|
||||
{
|
||||
public short TestPointId { get; internal set; }
|
||||
|
||||
public byte OmniTypeId { get; internal set; }
|
||||
|
||||
public double MaxAccuracy { get; internal set; }
|
||||
|
||||
public short Duration { get; internal set; }
|
||||
|
||||
public string OmniVariant { get; internal set; }
|
||||
|
||||
public double GalPerMin { get; internal set; }
|
||||
|
||||
public short Rotations { get; internal set; }
|
||||
|
||||
public double MinAccuracy { get; internal set; }
|
||||
|
||||
public double FlowM3H => this.GalPerMin.GPM2M3H();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using System;
|
||||
using ExchangeHub;
|
||||
|
||||
public class OmniExchange
|
||||
{
|
||||
private readonly ExchangeConnection connection;
|
||||
|
||||
public OmniExchange()
|
||||
{
|
||||
this.connection = new ExchangeConnection();
|
||||
}
|
||||
|
||||
public void Connect(string url)
|
||||
{
|
||||
this.connection.Connect(url);
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
this.connection.Disconnect();
|
||||
}
|
||||
|
||||
public void StopFlow()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,11 @@
|
||||
this.MessageHandler = this.stream.Send;
|
||||
}
|
||||
|
||||
public override bool IsOpen
|
||||
{
|
||||
get => this.stream.IsOpen;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
this.stream.Close();
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
|
||||
public sealed class OmniIrdaEOL
|
||||
{
|
||||
private readonly IDictionary<int, OmniConnection> connections;
|
||||
private readonly IDictionary<int, OmniMeter> meters;
|
||||
private readonly OmniExchange exchangeHub;
|
||||
private readonly OmniDatabase database;
|
||||
|
||||
public OmniIrdaEOL(string connectionString)
|
||||
{
|
||||
this.connections = new Dictionary<int, OmniConnection>();
|
||||
this.meters = new Dictionary<int, OmniMeter>();
|
||||
this.exchangeHub = new OmniExchange();
|
||||
this.database = new OmniDatabase(connectionString);
|
||||
}
|
||||
|
||||
public void AddConnection(string portName)
|
||||
{
|
||||
var nr = this.connections.Count + 1;
|
||||
this.connections[nr] = new OmniIrdaConnection(portName);
|
||||
this.meters[nr] = new OmniMeter();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var connection in this.connections.Values)
|
||||
{
|
||||
connection.Close();
|
||||
}
|
||||
|
||||
this.connections.Clear();
|
||||
this.meters.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,32 +2,141 @@
|
||||
{
|
||||
using OmniPlus.Features.Enums;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
public class OmniMeter
|
||||
{
|
||||
const string NA = "n/a";
|
||||
|
||||
private readonly int slotnr;
|
||||
private readonly string portName;
|
||||
private OmniConnection connection;
|
||||
|
||||
public void ConnectIrda(string portName)
|
||||
public OmniMeter(int nr, string portName)
|
||||
{
|
||||
if (this.connection != null)
|
||||
{
|
||||
this.connection.Close();
|
||||
}
|
||||
|
||||
this.connection = new OmniIrdaConnection(portName);
|
||||
this.connection.Open();
|
||||
this.slotnr = nr;
|
||||
this.portName = portName;
|
||||
}
|
||||
|
||||
public void ConnectUniPro(string portName)
|
||||
public string MeterNr { get; private set; }
|
||||
|
||||
public int? SerialNr { get; private set; }
|
||||
|
||||
public void ConnectIrda()
|
||||
{
|
||||
if (this.connection is null)
|
||||
{
|
||||
this.connection = new OmniIrdaConnection(this.portName);
|
||||
}
|
||||
|
||||
if (!this.connection.IsOpen)
|
||||
{
|
||||
this.connection.Close();
|
||||
this.connection.Open();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.connection != null)
|
||||
{
|
||||
this.connection.Close();
|
||||
}
|
||||
|
||||
this.connection = new OmniUniProConnection(portName);
|
||||
this.connection.Open();
|
||||
this.connection = null;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
this.ConnectIrda();
|
||||
|
||||
this.MeterNr = NA;
|
||||
this.SerialNr = default(int?);
|
||||
var buildInfo = this.connection.ViewBuildInformation();
|
||||
|
||||
if (buildInfo.Status != Status.Completed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.MeterNr = buildInfo.Value;
|
||||
this.SerialNr = OmniContext.Current.Auftrag.IdentNr;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(this.MeterNr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (OmniContext.Current.Exists(this.MeterNr))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var commands = new List<byte[]>
|
||||
{
|
||||
new byte[] { 0x01 },
|
||||
new byte[] { 0x03 },
|
||||
new byte[] { 0x05 },
|
||||
new byte[] { 0x07 },
|
||||
new byte[] { 0x09 },
|
||||
new byte[] { 0x0B },
|
||||
new byte[] { 0x0D },
|
||||
new byte[] { 0x0F },
|
||||
new byte[] { 0x11 },
|
||||
new byte[] { 0x13 },
|
||||
new byte[] { 0x15 },
|
||||
new byte[] { 0x17 },
|
||||
new byte[] { 0x1F },
|
||||
new byte[] { 0x21 },
|
||||
new byte[] { 0x25 },
|
||||
new byte[] { 0x27 },
|
||||
new byte[] { 0x29 },
|
||||
new byte[] { 0x2B },
|
||||
new byte[] { 0xFD, 0x02 },
|
||||
new byte[] { 0xFD, 0x05 },
|
||||
new byte[] { 0xFD, 0x06 },
|
||||
new byte[] { 0xFD, 0x08 },
|
||||
new byte[] { 0xFD, 0x0A },
|
||||
new byte[] { 0xFD, 0x0E },
|
||||
new byte[] { 0xFD, 0x10 },
|
||||
new byte[] { 0xFD, 0x12 },
|
||||
new byte[] { 0xFD, 0x14 },
|
||||
new byte[] { 0xFD, 0x22 },
|
||||
new byte[] { 0xFD, 0x24 },
|
||||
new byte[] { 0xFD, 0x26 },
|
||||
new byte[] { 0xFD, 0x28 },
|
||||
new byte[] { 0xFD, 0x39 },
|
||||
new byte[] { 0xFD, 0x3D },
|
||||
new byte[] { 0xFD, 0x55 },
|
||||
new byte[] { 0xFD, 0x63 },
|
||||
new byte[] { 0xFD, 0x7B },
|
||||
new byte[] { 0xFD, 0x7E, 0x00 },
|
||||
new byte[] { 0xFD, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
new byte[] { 0xFD, 0x8B },
|
||||
new byte[] { 0xFD, 0xA9 },
|
||||
new byte[] { 0xFD, 0xAA },
|
||||
new byte[] { 0xFD, 0xAC },
|
||||
new byte[] { 0xFD, 0xB7 },
|
||||
new byte[] { 0xFD, 0xBC },
|
||||
new byte[] { 0xFD, 0xC2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
new byte[] { 0xFD, 0xC3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
new byte[] { 0xFD, 0xC4, 0x00 },
|
||||
new byte[] { 0xFD, 0xC6 },
|
||||
new byte[] { 0xFD, 0xC7 }
|
||||
};
|
||||
|
||||
var meterState = new StringBuilder();
|
||||
|
||||
foreach (var cmd in commands)
|
||||
{
|
||||
var response = this.connection.Send(cmd);
|
||||
var entry = $"{BitConverter.ToString(cmd)}:{BitConverter.ToString(response)};";
|
||||
|
||||
meterState.Append(entry);
|
||||
}
|
||||
|
||||
OmniContext.Current.Add(this.MeterNr, meterState.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,8 +37,13 @@
|
||||
<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>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
@@ -96,8 +101,7 @@
|
||||
<Compile Include="Features\VersionAndType.cs" />
|
||||
<Compile Include="Inspection\OmniPlusFormulas.cs" />
|
||||
<Compile Include="OmniConnection.cs" />
|
||||
<Compile Include="OmniExchange.cs" />
|
||||
<Compile Include="OmniIrdaEOL.cs" />
|
||||
<Compile Include="OmniContext.cs" />
|
||||
<Compile Include="OmniIrdaConnection.cs" />
|
||||
<Compile Include="OmniMeter.cs" />
|
||||
<Compile Include="OmniDatabase.cs" />
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
USE [AuftragKopie];
|
||||
|
||||
IF OBJECT_ID(N'OmniTestStates') IS NOT NULL DROP TABLE [OmniTestStates];
|
||||
IF OBJECT_ID(N'OmniTestPoints') IS NOT NULL DROP TABLE [OmniTestPoints];
|
||||
IF OBJECT_ID(N'OmniTestTypes') IS NOT NULL DROP TABLE [OmniTestTypes];
|
||||
IF OBJECT_ID(N'OmniTypes') IS NOT NULL DROP TABLE [OmniTypes];
|
||||
IF OBJECT_ID(N'OmniPlus') IS NOT NULL DROP TABLE [OmniPlus];
|
||||
|
||||
CREATE TABLE [OmniTestTypes] (
|
||||
[Id] TINYINT NOT NULL IDENTITY(1, 1),
|
||||
CREATE TABLE [OmniTypes] (
|
||||
[TypeId] TINYINT NOT NULL IDENTITY(1, 1),
|
||||
[Type] VARCHAR(5) NOT NULL,
|
||||
[Size] TINYINT NOT NULL,
|
||||
[Range] TINYINT NOT NULL,
|
||||
@@ -14,84 +14,136 @@ CREATE TABLE [OmniTestTypes] (
|
||||
[Fraction] INT NOT NULL,
|
||||
[CorrectionFactor] SMALLINT NOT NULL,
|
||||
[PulsePerRotation] TINYINT NOT NULL,
|
||||
CONSTRAINT [PK_OmniTestTypes_Id] PRIMARY KEY ([Id])
|
||||
CONSTRAINT [PK_OmniTestTypes_TypeId] PRIMARY KEY ([TypeId])
|
||||
);
|
||||
|
||||
INSERT INTO [OmniTestTypes]
|
||||
INSERT INTO [OmniTypes]
|
||||
([Type], [Size], [Range], [Direction], [IntPart], [Fraction], [CorrectionFactor], [PulsePerRotation])
|
||||
VALUES ( '1½"', 0x05, 0x00, 0x00, 0x00, 34017, 100, 8)
|
||||
, ( '2"', 0x06, 0x00, 0x00, 0x00, 34017, 100, 8)
|
||||
, ( '3"', 0x07, 0x01, 0x00, 0x01, 50827, 100, 8)
|
||||
, ( '4"', 0x08, 0x01, 0x00, 0x01, 50827, 100, 8)
|
||||
, ( '6"', 0x09, 0x02, 0x00, 0x06, 16754, 100, 8)
|
||||
, ( '8"', 0x0A, 0x03, 0x80, 0x01, 36814, 1000, 8)
|
||||
, ( '10"', 0x0B, 0x04, 0x80, 0x02, 21667, 1000, 8);
|
||||
, ( '2"', 0x06, 0x00, 0x00, 0x00, 34017, 100, 8);
|
||||
|
||||
CREATE TABLE [OmniTestPoints] (
|
||||
[Id] SMALLINT NOT NULL IDENTITY(1, 1),
|
||||
[TestPointId] SMALLINT NOT NULL IDENTITY(1, 1),
|
||||
[OmniTypeId] TINYINT NOT NULL,
|
||||
[OmniVariant] CHAR(2) NULL,
|
||||
[GalPerMin] FLOAT NOT NULL,
|
||||
[Rotations] SMALLINT NOT NULL,
|
||||
[Duration] SMALLINT NOT NULL,
|
||||
[MinDiff] FLOAT NULL,
|
||||
[MaxDiff] FLOAT NULL,
|
||||
CONSTRAINT [PK_OmniTestPoints_Id] PRIMARY KEY ([Id]),
|
||||
CONSTRAINT [FK_OmniTestPoints_OmniTypeId_OmniPlus_Id] FOREIGN KEY ([OmniTypeId]) REFERENCES [OmniTestTypes]([Id]),
|
||||
[MinAccuracy] FLOAT NULL,
|
||||
[MaxAccuracy] FLOAT NULL,
|
||||
CONSTRAINT [PK_OmniTestPoints_TestPointId] PRIMARY KEY ([TestPointId]),
|
||||
CONSTRAINT [FK_OmniTestPoints_OmniTypes_OmniTypeId] FOREIGN KEY ([OmniTypeId]) REFERENCES [OmniTypes]([TypeId]),
|
||||
CONSTRAINT [CHK_OmniTestPoints_Rotations] CHECK ([Rotations] BETWEEN 1 AND 5000),
|
||||
CONSTRAINT [CHK_OmniTestPoints_Duration] CHECK ([Duration] BETWEEN 1 AND 3600)
|
||||
);
|
||||
|
||||
INSERT INTO [OmniTestPoints]
|
||||
([OmniTypeId], [OmniVariant], [GalPerMin], [Rotations], [Duration], [MinDiff], [MaxDiff])
|
||||
------------------------------------------------------------------------------------------
|
||||
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, 'F2', 160.00, 700, 35, 98.5, 101.5)
|
||||
, ( 1, 'F2', 1.00, 4, 32, 98.5, 101.5)
|
||||
, ( 1, 'F2', 0.25, 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)
|
||||
, ( 1, 'R2', 0.75, 4, 43, 95.0, 101.5)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 1, 'T2', 160.00, 700, 35, 98.5, 101.5)
|
||||
, ( 1, 'T2', 1.25, 6, 38, 98.5, 101.5)
|
||||
, ( 1, 'T2', 0.75, 4, 43, 95.0, 101.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, 'F2', 160.00, 800, 40, 98.5, 101.5)
|
||||
, ( 2, 'F2', 1.00, 4, 32, 98.5, 101.5)
|
||||
, ( 2, 'F2', 0.25, 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)
|
||||
, ( 2, 'R2', 1.00, 4, 32, 95.0, 101.5)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 2, 'T2', 200.00, 1000, 40, 98.5, 101.5)
|
||||
, ( 2, 'T2', 1.50, 8, 43, 98.5, 101.5)
|
||||
, ( 2, 'T2', 1.00, 4, 32, 95.0, 101.5);
|
||||
([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, 'R2', 150.00, 600, 32, 98.5, 101.5)
|
||||
, ( 1, 'R2', 2.00, 8, 32, 98.5, 101.5)
|
||||
, ( 1, 'R2', 0.75, 4, 43, 95.0, 101.5)
|
||||
--------------------------------------------------------------------------------------------------
|
||||
, ( 1, 'T2', 160.00, 700, 35, 98.5, 101.5)
|
||||
, ( 1, 'T2', 1.25, 6, 38, 98.5, 101.5)
|
||||
, ( 1, 'T2', 0.75, 4, 43, 95.0, 101.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, 'R2', 200.00, 1000, 40, 98.5, 101.5)
|
||||
, ( 2, 'R2', 2.50, 10, 32, 98.5, 101.5)
|
||||
, ( 2, 'R2', 1.00, 4, 32, 95.0, 101.5)
|
||||
--------------------------------------------------------------------------------------------------
|
||||
, ( 2, 'T2', 200.00, 1000, 40, 98.5, 101.5)
|
||||
, ( 2, 'T2', 1.50, 8, 43, 98.5, 101.5)
|
||||
, ( 2, 'T2', 1.00, 4, 32, 95.0, 101.5);
|
||||
|
||||
CREATE TABLE [OmniTestStates] (
|
||||
[Position] INT NOT NULL,
|
||||
[BuildInfo] VARCHAR(50) NULL,
|
||||
[ManifacturingTime] DATETIME NULL,
|
||||
[RebootsCount] TINYINT NULL,
|
||||
[VersionAndType] VARCHAR(50) NULL,
|
||||
[ProgrammableID] VARCHAR(50) NULL,
|
||||
[FactoryID] VARCHAR(50) NULL,
|
||||
[ReadingDigitsCount] BINARY(1) NULL,
|
||||
[ReadingDigitsOffsest] BINARY(1) NULL,
|
||||
[Readings] VARCHAR(50) NULL,
|
||||
[OptionalUniDirFields] VARCHAR(50) NULL,
|
||||
[AlarmPersitenceDays] BINARY(1) NULL,
|
||||
[DataLogIntervalMins] BINARY(2) NULL,
|
||||
[DeviceID] VARCHAR(50) NULL,
|
||||
CONSTRAINT [PK_OmniTestStates_Position] PRIMARY KEY ([Position]),
|
||||
CONSTRAINT [CHK_OmniTestStates_Position] CHECK ([Position] BETWEEN 1 AND 10)
|
||||
);
|
||||
CREATE TABLE [OmniPlus] (
|
||||
[MeterNr] VARCHAR(32) NOT NULL PRIMARY KEY,
|
||||
[MeterState] VARCHAR(MAX) NOT 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
|
||||
@@ -28,6 +28,11 @@
|
||||
this.MessageHandler = this.stream.Send;
|
||||
}
|
||||
|
||||
public override bool IsOpen
|
||||
{
|
||||
get => this.stream.IsOpen;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
this.stream.Close();
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Common.SqlExtensions.Interfaces
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public interface ISQLCommand
|
||||
{
|
||||
int ExecuteNonQuery();
|
||||
|
||||
IEnumerable<T> ExecuteReader<T>(Func<ISQLReader, T> expression);
|
||||
|
||||
void ExecuteReader(Action<ISQLReader> expression);
|
||||
|
||||
T ExecuteScalar<T>(Func<ISQLReader, T> expression);
|
||||
|
||||
T FirstOrDefault<T>(Func<ISQLReader, T> expression);
|
||||
|
||||
ISQLCommand SetParameter(string name, object value);
|
||||
|
||||
ISQLCommand SetParameters(IEnumerable<KeyValuePair<string, object>> parameters);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace Common.SqlExtensions.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// <see cref="ISQLConnection"/> simply exposes the <see cref="ISQLConnection.CreateCommand(string)"/> method.
|
||||
/// </summary>
|
||||
public interface ISQLConnection
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a command with given command text.
|
||||
/// </summary>
|
||||
/// <param name="commandText"><see cref="System.String"/> - SQL query string.</param>
|
||||
/// <returns></returns>
|
||||
ISQLCommand CreateCommand(string commandText);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
namespace Common.SqlExtensions.Interfaces
|
||||
{
|
||||
using System;
|
||||
|
||||
public interface ISQLReader
|
||||
{
|
||||
bool GetBool(int index = -1);
|
||||
|
||||
DateTime GetDate(int index = -1);
|
||||
|
||||
int GetInt(int index = -1);
|
||||
|
||||
long GetLong(int index = -1);
|
||||
|
||||
short GetSmallint(int index = -1);
|
||||
|
||||
string GetString(int index = -1);
|
||||
|
||||
byte GetTinyint(int index = -1);
|
||||
|
||||
T GetValue<T>(int index = -1);
|
||||
|
||||
object GetValue(string column);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 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("SqlExtensions")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SqlExtensions")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2024")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("b8523894-2c40-4ff0-a399-b7a91fae45ea")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -0,0 +1,83 @@
|
||||
namespace Common.SqlExtensions
|
||||
{
|
||||
using Common.SqlExtensions.Interfaces;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
|
||||
public class SQLCommand : ISQLCommand
|
||||
{
|
||||
private readonly SQLConnection sqlConnection;
|
||||
private readonly IDictionary<string, SqlParameter> parameters;
|
||||
|
||||
public SQLCommand(SQLConnection sqlConnection, string commandText)
|
||||
{
|
||||
this.sqlConnection = sqlConnection.EnsureNotNull(nameof(sqlConnection));
|
||||
this.CommandText = commandText.EnsureNotNullOrWhiteSpace(nameof(commandText));
|
||||
this.parameters = new Dictionary<string, SqlParameter>();
|
||||
}
|
||||
|
||||
internal string CommandText { get; }
|
||||
|
||||
internal SqlParameter[] Parameters
|
||||
=> this.parameters.Values.ToArray();
|
||||
|
||||
public int ExecuteNonQuery()
|
||||
=> this.sqlConnection.ExecuteNonQuery(this);
|
||||
|
||||
public IEnumerable<T> ExecuteReader<T>(Func<ISQLReader, T> expression)
|
||||
{
|
||||
foreach (var result in this.sqlConnection.ExecuteReader(this, expression))
|
||||
{
|
||||
yield return result;
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteReader(Action<ISQLReader> expression)
|
||||
{
|
||||
expression.ThrowIfNull(nameof(expression));
|
||||
|
||||
this.sqlConnection.ExecuteReader(this, reader =>
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
expression(reader);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public T ExecuteScalar<T>(Func<ISQLReader, T> expression)
|
||||
=> this.sqlConnection.ExecuteScalar(this, expression);
|
||||
|
||||
public T FirstOrDefault<T>(Func<ISQLReader, T> expression)
|
||||
=> this.sqlConnection.FirstOrDefault(this, expression);
|
||||
|
||||
public ISQLCommand SetParameter(string name, object value)
|
||||
{
|
||||
name.ThrowIfNullOrWhiteSpace(nameof(name));
|
||||
|
||||
if (value is null)
|
||||
{
|
||||
value = DBNull.Value;
|
||||
}
|
||||
|
||||
var parameter = new SqlParameter(name, value);
|
||||
|
||||
this.parameters[name] = parameter;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public ISQLCommand SetParameters(IEnumerable<KeyValuePair<string, object>> parameters)
|
||||
{
|
||||
foreach (var kvp in parameters)
|
||||
{
|
||||
this.SetParameter(kvp.Key, kvp.Value);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
namespace Common.SqlExtensions
|
||||
{
|
||||
using Common.SqlExtensions.Interfaces;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Linq;
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper class around the <see cref="System.Data.SqlClient"/>.
|
||||
/// Exposes <see cref="System.Data.SqlClient.SqlConnection"/>, <see cref="System.Data.SqlClient.SqlCommand"/> and <see cref="System.Data.SqlClient.SqlDataReader"/> classes
|
||||
/// in a fluent manner, all exposed methods can be chained in a single C# query.
|
||||
/// </summary>
|
||||
public class SQLConnection : ISQLConnection
|
||||
{
|
||||
private readonly string connectionString;
|
||||
private readonly Action<string> errorCallback;
|
||||
|
||||
/// <summary>
|
||||
/// When <paramref name="connectionString"/> is null, white space or is not a valid connection string exception is thrown.
|
||||
/// </summary>
|
||||
/// <param name="connectionString"><see cref="System.String"/> - SQL connection string.</param>
|
||||
private SQLConnection(string connectionString)
|
||||
{
|
||||
// connectionString.ThrowIfNullOrWhiteSpace(nameof(connectionString));
|
||||
|
||||
var connectionStringBuilder = new SqlConnectionStringBuilder(connectionString);
|
||||
|
||||
this.connectionString = connectionStringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When <paramref name="connectionString"/> is null, white space or is not a valid connection string exception is thrown.
|
||||
/// Additionaly accepts <see cref="System.Action{System.String}"/> for error handling.
|
||||
/// Whenever the sql query throws error on execution, this will be passesd within the callback.
|
||||
/// </summary>
|
||||
/// <param name="connectionString"><see cref="System.String"/> - SQL connection string.</param>
|
||||
/// <param name="errorCallback"><see cref="System.Action{System.String}"/> - error handler for SQL execution errors.</param>
|
||||
private SQLConnection(string connectionString, Action<string> errorCallback = null)
|
||||
: this(connectionString)
|
||||
=> this.errorCallback = errorCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="Common.SqlExtensions.ISQLCommand"/> wrapper that accepts a SQL query string.
|
||||
/// </summary>
|
||||
/// <param name="commandText"><see cref="System.String"/> - SQL query string</param>
|
||||
/// <returns><see cref="Common.SqlExtensions.ISQLCommand"/> - that exposes basic functionalities from the <see cref="System.Data.SqlClient.SqlCommand" />.</returns>
|
||||
public ISQLCommand CreateCommand(string commandText)
|
||||
=> new SQLCommand(this, commandText);
|
||||
|
||||
/// <summary>
|
||||
/// Static method that creates a <see cref="Common.SqlExtensions.ISQLConnection"/> client with given connection string.
|
||||
/// </summary>
|
||||
/// <param name="connectionString"><see cref="System.String"/> - SQL connection string.</param>
|
||||
/// <returns><see cref="Common.SqlExtensions.ISQLConnection"/></returns>
|
||||
public static ISQLConnection CreateSQLConnection(string connectionString)
|
||||
=> new SQLConnection(connectionString);
|
||||
|
||||
/// <summary>
|
||||
/// Static method that creates a <see cref="Common.SqlExtensions.ISQLConnection"/> client with given connection string and error callback that receives all error messages.
|
||||
/// </summary>
|
||||
/// <param name="connectionString"><see cref="System.String"/> - SQL connection string.</param>
|
||||
/// <param name="errorCallback"><see cref="System.Action{System.String}"/> - error handler for SQL execution errors.</param>
|
||||
/// <returns><see cref="Common.SqlExtensions.ISQLConnection"/></returns>
|
||||
public static ISQLConnection CreateSQLConnection(string connectionString, Action<string> errorCallback = null)
|
||||
=> new SQLConnection(connectionString, errorCallback);
|
||||
|
||||
/// <summary>
|
||||
/// Internal method called from <see cref="Common.SqlExtensions.ISQLCommand"/>.
|
||||
/// Like in a <see cref="System.Data.SqlClient.SqlCommand"/> performs INSERT, UPDATE, DELETE queries and returns the number of rows affected.
|
||||
/// </summary>
|
||||
/// <param name="command"><see cref="System.String"/> - SQL query string</param>
|
||||
/// <returns><see cref="System.Int32"/> - the number of rows affected.</returns>
|
||||
internal int ExecuteNonQuery(SQLCommand command)
|
||||
{
|
||||
command.ThrowIfNull(nameof(command));
|
||||
|
||||
var rowsAffected = 0;
|
||||
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
{
|
||||
sqlConnection.OpenWithErrorHandling(this.errorCallback);
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = command.CommandText;
|
||||
|
||||
sqlCommand.Parameters.AddRange(command.Parameters);
|
||||
|
||||
rowsAffected = sqlCommand.ExecuteNonQuery();
|
||||
|
||||
sqlCommand.Parameters.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
return rowsAffected;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method called from <see cref="Common.SqlExtensions.ISQLCommand"/>.
|
||||
/// Like in a <see cref="System.Data.SqlClient.SqlCommand"/> performs SELECT queries and returns a enumerable of the results readed.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Is the type that returns the <see cref="System.Func{IFluentSQLReader, T} expression"/></typeparam>
|
||||
/// <param name="command"><see cref="System.String"/> - SQL query string</param>
|
||||
/// <param name="expression">Expression that reads specified data from the <see cref="Common.SqlExtensions.ISQLReader"/>.</param>
|
||||
/// <returns><see cref="System.Collections.Generic.IEnumerable{T}"/></returns>
|
||||
internal IEnumerable<T> ExecuteReader<T>(SQLCommand command, Func<ISQLReader, T> expression)
|
||||
{
|
||||
command.ThrowIfNull(nameof(command));
|
||||
expression.ThrowIfNull(nameof(expression));
|
||||
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
{
|
||||
sqlConnection.OpenWithErrorHandling(this.errorCallback);
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = command.CommandText;
|
||||
|
||||
sqlCommand.Parameters.AddRange(command.Parameters);
|
||||
|
||||
using (SQLReader sqlReader = sqlCommand.ExecuteReader())
|
||||
{
|
||||
sqlCommand.Parameters.Clear();
|
||||
|
||||
while (sqlReader.Read())
|
||||
{
|
||||
yield return expression(sqlReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method called from <see cref="Common.SqlExtensions.ISQLCommand"/>.
|
||||
/// Like in a <see cref="System.Data.SqlClient.SqlCommand"/> performs SELECT queries and returns a enumerable of the results readed.
|
||||
/// </summary>
|
||||
/// <param name="command"><see cref="System.String"/> - SQL query string</param>
|
||||
/// <param name="expression">Expression that reads specified data from the <see cref="Common.SqlExtensions.ISQLReader"/>.</param>
|
||||
internal void ExecuteReader(SQLCommand command, Action<SQLReader> expression)
|
||||
{
|
||||
command.ThrowIfNull(nameof(command));
|
||||
expression.ThrowIfNull(nameof(expression));
|
||||
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
{
|
||||
sqlConnection.OpenWithErrorHandling(this.errorCallback);
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = command.CommandText;
|
||||
|
||||
sqlCommand.Parameters.AddRange(command.Parameters);
|
||||
|
||||
using (SQLReader sqlReader = sqlCommand.ExecuteReader())
|
||||
{
|
||||
sqlCommand.Parameters.Clear();
|
||||
|
||||
expression(sqlReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method called from <see cref="Common.SqlExtensions.ISQLCommand"/>.
|
||||
/// Like in a <see cref="System.Data.SqlClient.SqlCommand"/> performs SELECT, READ, UPDATE, DELETE queries and returns first column from the first row from the result.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">From user specified.</typeparam>
|
||||
/// <param name="command"><see cref="System.String"/> - SQL query string</param>
|
||||
/// <param name="expression">Expression that reads specified data from the <see cref="Common.SqlExtensions.ISQLReader"/>.</param>
|
||||
/// <returns><see cref="System.Collections.Generic.IEnumerable{T}"/></returns>
|
||||
internal T ExecuteScalar<T>(SQLCommand command, Func<ISQLReader, T> expression)
|
||||
{
|
||||
command.ThrowIfNull(nameof(command));
|
||||
expression.ThrowIfNull(nameof(expression));
|
||||
|
||||
var scalarResult = default(T);
|
||||
|
||||
using (var sqlConnection = new SqlConnection(this.connectionString))
|
||||
{
|
||||
sqlConnection.OpenWithErrorHandling(this.errorCallback);
|
||||
|
||||
using (var sqlCommand = sqlConnection.CreateCommand())
|
||||
{
|
||||
sqlCommand.CommandText = command.CommandText;
|
||||
|
||||
sqlCommand.Parameters.AddRange(command.Parameters);
|
||||
|
||||
var scalarObject = sqlCommand.ExecuteScalar();
|
||||
|
||||
sqlCommand.Parameters.Clear();
|
||||
|
||||
if (scalarObject is T scalarValue)
|
||||
{
|
||||
scalarResult = scalarValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return scalarResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is same like <see cref="Common.SqlExtensions.SQLConnection.ExecuteReader{T}(SQLCommand, Func{ISQLReader, T})"/> but returns only the first data row.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">From user specified.</typeparam>
|
||||
/// <param name="command"><see cref="System.String"/> - SQL query string</param>
|
||||
/// <param name="expression">Expression that reads specified data from the <see cref="Common.SqlExtensions.ISQLReader"/>.</param>
|
||||
/// <returns><see cref="{T}"/></returns>
|
||||
internal T FirstOrDefault<T>(SQLCommand command, Func<ISQLReader, T> expression)
|
||||
=> this
|
||||
.ExecuteReader(command, expression)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
namespace Common.SqlExtensions
|
||||
{
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
public static class SQLExtensions
|
||||
{
|
||||
internal static T EnsureNotNull<T>(this T value, string member)
|
||||
{
|
||||
value.ThrowIfNull(member);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
internal static string EnsureNotNullOrWhiteSpace(this string value, string member)
|
||||
{
|
||||
value.ThrowIfNullOrWhiteSpace(member);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
internal static void ThrowIfNull<T>(this T value, string member)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentException($"{member} should not be null.", member);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void ThrowIfNullOrWhiteSpace(this string value, string member)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
throw new ArgumentException($"{member} should not be null or white space.", member);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void OpenWithErrorHandling(this SqlConnection sqlConnection, Action<string> errorCallback)
|
||||
{
|
||||
sqlConnection.ThrowIfNull(nameof(sqlConnection));
|
||||
|
||||
sqlConnection.FireInfoMessageEventOnUserErrors = true;
|
||||
|
||||
if (errorCallback != null)
|
||||
{
|
||||
sqlConnection.InfoMessage += (_, args) => errorCallback(args.Message);
|
||||
}
|
||||
|
||||
sqlConnection.Open();
|
||||
}
|
||||
|
||||
public static object SqlValue(this object value, int index)
|
||||
{
|
||||
if (value is null)
|
||||
{
|
||||
return DBNull.Value;
|
||||
}
|
||||
|
||||
return $"'{new SqlParameter($"x{index}", value).SqlValue}'";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
namespace Common.SqlExtensions
|
||||
{
|
||||
using Common.SqlExtensions.Interfaces;
|
||||
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
public class SQLReader : ISQLReader, IDisposable
|
||||
{
|
||||
private readonly SqlDataReader sqlDataReader;
|
||||
|
||||
private int index;
|
||||
|
||||
private SQLReader(SqlDataReader sqlDataReader)
|
||||
=> this.sqlDataReader = sqlDataReader.EnsureNotNull(nameof(sqlDataReader));
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.sqlDataReader.Close();
|
||||
this.sqlDataReader.Dispose();
|
||||
}
|
||||
|
||||
public bool GetBool(int index = -1)
|
||||
{
|
||||
this.SetIndex(index);
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(this.index))
|
||||
{
|
||||
return this.sqlDataReader.GetBoolean(this.index);
|
||||
}
|
||||
|
||||
return default(bool);
|
||||
}
|
||||
|
||||
public DateTime GetDate(int index = -1)
|
||||
{
|
||||
this.SetIndex(index);
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(this.index))
|
||||
{
|
||||
return this.sqlDataReader.GetDateTime(this.index);
|
||||
}
|
||||
|
||||
return default(DateTime);
|
||||
}
|
||||
|
||||
public int GetInt(int index = -1)
|
||||
{
|
||||
this.SetIndex(index);
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(this.index))
|
||||
{
|
||||
return this.sqlDataReader.GetInt32(this.index);
|
||||
}
|
||||
|
||||
return default(int);
|
||||
}
|
||||
|
||||
public long GetLong(int index = -1)
|
||||
{
|
||||
this.SetIndex(index);
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(this.index))
|
||||
{
|
||||
return this.sqlDataReader.GetInt64(this.index);
|
||||
}
|
||||
|
||||
return default(long);
|
||||
}
|
||||
|
||||
public short GetSmallint(int index = -1)
|
||||
{
|
||||
this.SetIndex(index);
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(this.index))
|
||||
{
|
||||
return this.sqlDataReader.GetInt16(this.index);
|
||||
}
|
||||
|
||||
return default(short);
|
||||
}
|
||||
|
||||
public string GetString(int index = -1)
|
||||
{
|
||||
this.SetIndex(index);
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(this.index))
|
||||
{
|
||||
return $"{this.sqlDataReader.GetValue(this.index)}";
|
||||
}
|
||||
|
||||
return default(string);
|
||||
}
|
||||
|
||||
public byte GetTinyint(int index = -1)
|
||||
{
|
||||
this.SetIndex(index);
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(this.index))
|
||||
{
|
||||
return this.sqlDataReader.GetByte(this.index);
|
||||
}
|
||||
|
||||
return default(byte);
|
||||
}
|
||||
|
||||
public T GetValue<T>(int index = -1)
|
||||
{
|
||||
this.SetIndex(index);
|
||||
|
||||
if (!this.sqlDataReader.IsDBNull(this.index))
|
||||
{
|
||||
if (this.sqlDataReader.GetValue(this.index) is T value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
|
||||
public object GetValue(string column)
|
||||
{
|
||||
column.EnsureNotNullOrWhiteSpace(nameof(column));
|
||||
|
||||
var colIndex = this.sqlDataReader.GetOrdinal(column);
|
||||
|
||||
if (colIndex >= 0 && colIndex < this.sqlDataReader.FieldCount - 1)
|
||||
{
|
||||
if (!this.sqlDataReader.IsDBNull(colIndex))
|
||||
{
|
||||
return this.sqlDataReader.GetValue(colIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return default(object);
|
||||
}
|
||||
|
||||
internal bool Read()
|
||||
{
|
||||
this.index = -1;
|
||||
|
||||
return this.sqlDataReader.Read();
|
||||
}
|
||||
|
||||
private void SetIndex(int index)
|
||||
{
|
||||
this.index++;
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
this.index = index;
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator SQLReader(SqlDataReader sqlDataReader)
|
||||
=> new SQLReader(sqlDataReader);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{B8523894-2C40-4FF0-A399-B7A91FAE45EA}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SqlExtensions</RootNamespace>
|
||||
<AssemblyName>SqlExtensions</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Interfaces\ISQLCommand.cs" />
|
||||
<Compile Include="Interfaces\ISQLConnection.cs" />
|
||||
<Compile Include="Interfaces\ISQLReader.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="SQLCommand.cs" />
|
||||
<Compile Include="SQLConnection.cs" />
|
||||
<Compile Include="SQLExtensions.cs" />
|
||||
<Compile Include="SQLReader.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>mkdir $(SolutionDir)packages\$(ProjectName)
|
||||
copy $(TargetDir)* $(SolutionDir)packages\$(ProjectName)\*</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user