OMNI: 01-16 - tests on 2020
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<Window x:Class="OMNIPruefung.EOLWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Height="450"
|
||||
Width="800">
|
||||
<DataGrid Background="White" HeadersVisibility="None" >
|
||||
|
||||
</DataGrid>
|
||||
</Window>
|
||||
@@ -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 EOLWindow.xaml
|
||||
/// </summary>
|
||||
public partial class EOLWindow : Window
|
||||
{
|
||||
public EOLWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@
|
||||
<ContentVM:MainContentVM />
|
||||
</Window.DataContext>
|
||||
|
||||
<Grid Margin="0, 3, 0, 0">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" MinWidth="230" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
@@ -43,6 +43,5 @@
|
||||
HorizontalAlignment="Stretch"
|
||||
Background="White"/>
|
||||
</DockPanel>
|
||||
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -57,30 +57,25 @@
|
||||
public string PSNR => this[nameof(PSNR)];
|
||||
|
||||
public IEnumerable<string> AllKeys => appsettings.AllKeys;
|
||||
}
|
||||
|
||||
public class ExchangeHubSettings : Appsettings
|
||||
{
|
||||
public string ExchangeHubURL
|
||||
{
|
||||
get => base[nameof(this.ExchangeHubURL)];
|
||||
set => base[nameof(this.ExchangeHubURL)] = value;
|
||||
get => this[nameof(this.ExchangeHubURL)];
|
||||
set => this[nameof(this.ExchangeHubURL)] = value;
|
||||
}
|
||||
|
||||
public string ExchangeHubOutputDir
|
||||
{
|
||||
get => base[nameof(this.ExchangeHubOutputDir)];
|
||||
set => base[nameof(this.ExchangeHubOutputDir)] = value;
|
||||
get => this[nameof(this.ExchangeHubOutputDir)];
|
||||
set => this[nameof(this.ExchangeHubOutputDir)] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public class EOLSettings : Appsettings
|
||||
{
|
||||
public IEnumerable<string> COMPorts
|
||||
=> this[nameof(COMPorts)]
|
||||
?.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
?? new string[] { };
|
||||
internal COMPorts COMPorts
|
||||
=> new COMPorts(this[nameof(COMPorts)]
|
||||
?.Split(new[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
?? new string[] { });
|
||||
|
||||
public string OmniDB => this[nameof(OmniDB)];
|
||||
|
||||
internal static readonly Appsettings Current = new Appsettings();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
namespace OMNIPruefung.Models
|
||||
{
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
|
||||
internal class COMPorts : IEnumerable<string>
|
||||
{
|
||||
private readonly string[] comports;
|
||||
private readonly string[] existing;
|
||||
|
||||
public COMPorts(string[] comports)
|
||||
{
|
||||
this.comports = comports;
|
||||
this.existing = SerialPort.GetPortNames();
|
||||
}
|
||||
|
||||
public bool Exists(string portName)
|
||||
{
|
||||
return Array.IndexOf(this.existing, portName) >= 0;
|
||||
}
|
||||
|
||||
public IEnumerator<string> GetEnumerator()
|
||||
{
|
||||
foreach (var portName in this.comports)
|
||||
{
|
||||
yield return portName;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
namespace OMNIPruefung.Models
|
||||
{
|
||||
using OmniPlus;
|
||||
|
||||
public class EOLContentM
|
||||
{
|
||||
private readonly OmniIrdaEOL eol;
|
||||
|
||||
public EOLContentM()
|
||||
{
|
||||
this.eol = new OmniIrdaEOL(Appsettings.Current.OmniDB);
|
||||
}
|
||||
|
||||
public void Load()
|
||||
{
|
||||
//var comports = new COMPorts();
|
||||
|
||||
//foreach (var portName in comports)
|
||||
//{
|
||||
// if (comports.Exists(portName))
|
||||
// {
|
||||
// this.eol.AddConnection(portName);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -57,9 +57,14 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="EOLWindow.xaml.cs">
|
||||
<DependentUpon>EOLWindow.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Helpers\BooleanProgressBackgroundConverter.cs" />
|
||||
<Compile Include="Helpers\BooleanVisibilityConverter.cs" />
|
||||
<Compile Include="Models\Appsettings.cs" />
|
||||
<Compile Include="Models\COMPorts.cs" />
|
||||
<Compile Include="Models\EOLContentM.cs" />
|
||||
<Compile Include="ViewModels\Content\SettingsContentVM.cs" />
|
||||
<Compile Include="ViewModels\Features\OMNIPlusVM.cs" />
|
||||
<Compile Include="ViewModels\Base\Command.cs" />
|
||||
@@ -93,6 +98,10 @@
|
||||
<Compile Include="Views\Options\Option.xaml.cs">
|
||||
<DependentUpon>Option.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Page Include="EOLWindow.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -18,10 +17,10 @@
|
||||
|
||||
public class COMContentVM : ContentVM
|
||||
{
|
||||
private readonly Dictionary<OmniPlusTestPoint, OmniPlusTest> results
|
||||
= new Dictionary<OmniPlusTestPoint, OmniPlusTest>();
|
||||
private readonly IDictionary<OmniPlusTestPoint, OmniPlusTest> results
|
||||
= new SortedDictionary<OmniPlusTestPoint, OmniPlusTest>();
|
||||
|
||||
private OmniPlusConnection connection;
|
||||
private OmniConnection connection;
|
||||
|
||||
public COMContentVM() : base()
|
||||
{
|
||||
@@ -30,6 +29,31 @@
|
||||
this.Option.OptionSelected += this.NotifyOptionSelected;
|
||||
}
|
||||
|
||||
private int nr;
|
||||
public int Nr
|
||||
{
|
||||
get => this.nr;
|
||||
set
|
||||
{
|
||||
this.nr = value;
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.Nr));
|
||||
}
|
||||
}
|
||||
|
||||
private string portName;
|
||||
public string PortName
|
||||
{
|
||||
get => this.portName;
|
||||
set
|
||||
{
|
||||
this.portName = value;
|
||||
this.connection = new OmniIrdaConnection(value);
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.PortName));
|
||||
}
|
||||
}
|
||||
|
||||
private int progress;
|
||||
public int Progress
|
||||
{
|
||||
@@ -90,43 +114,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
private int nr;
|
||||
public int Nr
|
||||
{
|
||||
get => this.nr;
|
||||
set
|
||||
{
|
||||
this.nr = value;
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.Nr));
|
||||
}
|
||||
}
|
||||
|
||||
private string portName;
|
||||
public string PortName
|
||||
{
|
||||
get => this.portName;
|
||||
set
|
||||
{
|
||||
this.portName = value;
|
||||
this.connection = new OmniPlusConnection(value);
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.PortName));
|
||||
}
|
||||
}
|
||||
|
||||
private string testResults;
|
||||
public string TestResults
|
||||
{
|
||||
get => this.testResults;
|
||||
set
|
||||
{
|
||||
this.testResults = value;
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.TestResults));
|
||||
}
|
||||
}
|
||||
|
||||
public OMNIPlusVM Meter { get; }
|
||||
|
||||
internal void CancelExecution()
|
||||
@@ -149,39 +136,35 @@
|
||||
this.Header = $"{this.PortName}";
|
||||
this.State = this.Header;
|
||||
|
||||
this.State = $"{this.Header} - wird ermittelt ...";
|
||||
|
||||
try
|
||||
{
|
||||
this.Connected = this.connection.Connected;
|
||||
this.connection.Open();
|
||||
|
||||
if (!this.Connected)
|
||||
{
|
||||
this.Connected = this.connection.ConnectIrda();
|
||||
this.Running = this.Connected;
|
||||
}
|
||||
this.Connected = true;
|
||||
this.Running = true;
|
||||
|
||||
if (this.IsRunning())
|
||||
{
|
||||
this.State = "Verbunden";
|
||||
this.Header = $"{this.PortName}";
|
||||
this.State = $"{this.PortName} verbunden";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.connection.Disconnect();
|
||||
this.connection.Close();
|
||||
|
||||
this.Header = $"({this.PortName} - nicht verbunden!)";
|
||||
this.Header = $"{this.PortName} - nicht verbunden!";
|
||||
this.State = this.Header;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.connection.Disconnect();
|
||||
this.Header = $"({this.PortName} - nicht vorhanden!)";
|
||||
this.connection.Close();
|
||||
this.Header = $"({this.PortName} - {e.Message}!)";
|
||||
this.State = this.Header;
|
||||
}
|
||||
}
|
||||
|
||||
return this.StartNew(Initialize, cancellationToken);
|
||||
return Task.Factory.StartNew(Initialize, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task ReadSystemParametersAsync(CancellationToken cancelationToken)
|
||||
@@ -193,30 +176,15 @@
|
||||
if (this.IsRunning())
|
||||
{
|
||||
var response = this.connection.ViewSystemParameters();
|
||||
this.Running = response.IsValid;
|
||||
this.Header = response.BuildInfo.Value;
|
||||
this.Progress += 10;
|
||||
|
||||
this.Meter.Add(response);
|
||||
|
||||
this.Header = response.BuildInfo.Value;
|
||||
this.Running = response.IsValid;
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
this.State = "Systemeigenschaften gelesen und validiert";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State = "Systemeigenschaften konnten nicht gelesen werden";
|
||||
}
|
||||
|
||||
this.Progress += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State += $" (Verbindung unterbrochen)";
|
||||
}
|
||||
}
|
||||
|
||||
return this.StartNew(ReadSystemParameters, cancelationToken);
|
||||
return Task.Factory.StartNew(ReadSystemParameters, cancelationToken);
|
||||
}
|
||||
|
||||
internal Task SetInputVolumeAsync(OmniPlusType defaults, CancellationToken cancelationToken)
|
||||
@@ -225,37 +193,32 @@
|
||||
|
||||
void SetInputVolume()
|
||||
{
|
||||
if (this.Connected)
|
||||
if (this.IsRunning())
|
||||
{
|
||||
var response = this.connection.Set(defaults.InputVolume);
|
||||
this.Running = response.Succeeded;
|
||||
this.Progress += 10;
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
this.Meter.Add(defaults.InputVolume);
|
||||
|
||||
this.State = "Flow-Eigenschaften konfiguriert";
|
||||
this.State = $"{this.Header}";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State = $"Flow-Eigenschaften: ({(int)response.Status} - {response.Status})";
|
||||
this.State = $"{this.Header} - {response.Status}";
|
||||
}
|
||||
|
||||
this.Progress += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State += $" (Verbindung unterbrochen)";
|
||||
}
|
||||
}
|
||||
|
||||
return this.StartNew(SetInputVolume, cancelationToken);
|
||||
return Task.Factory.StartNew(SetInputVolume, cancelationToken);
|
||||
}
|
||||
|
||||
internal Task StartPPCalibrationAsync(OmniPlusTestPoint pp, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.CancelExecution);
|
||||
|
||||
|
||||
void StartPPCalibration()
|
||||
{
|
||||
this.results[pp] = new OmniPlusTest();
|
||||
@@ -264,84 +227,69 @@
|
||||
{
|
||||
var rotations = pp.Rotations;
|
||||
var duration = pp.Duration;
|
||||
var activationResponse = connection.StartChamberCalibration(pp.Rotations, pp.Duration);
|
||||
this.Running = activationResponse.Succeeded && activationResponse.Control == ChamberCalibrationResponse.TEST_ACTIVATED;
|
||||
var response = connection.StartChamberCalibration(pp.Rotations, pp.Duration);
|
||||
|
||||
this.Running = response.Succeeded && response.Control == ChamberCalibrationResponse.TEST_ACTIVATED;
|
||||
this.Progress += 10;
|
||||
|
||||
this.Meter.Add(pp);
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
this.State = $"PP {rotations}/{duration} (rotations/seconds) wurde gestarted.";
|
||||
this.State = $"{this.Header} PP {rotations}/{duration}";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State = $"PP {rotations}/{duration} (rotations/seconds): {(int)activationResponse.Status} - {activationResponse.Status}";
|
||||
this.State = $"{this.Header} PP {rotations}/{duration}, Status:{response.Status}, Control:{response.Control}";
|
||||
}
|
||||
}
|
||||
|
||||
this.Progress += 10;
|
||||
}
|
||||
|
||||
return this.StartNew(StartPPCalibration, cancellationToken);
|
||||
return Task.Factory.StartNew(StartPPCalibration, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task StopPPCalibrationAsync(OmniPlusTestPoint pp, double referenceV, CancellationToken cancellationToken)
|
||||
internal Task StopPPCalibrationAsync(OmniPlusTestPoint pp, double referenceFlowM3S, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.CancelExecution);
|
||||
|
||||
|
||||
void StopPPCalibration()
|
||||
{
|
||||
if (this.IsRunning())
|
||||
{
|
||||
var calibrationResult = connection.ViewChamberCalibration();
|
||||
this.results[pp].Rotations = calibrationResult.Rotations;
|
||||
this.results[pp].Duration = calibrationResult.DurationSec;
|
||||
this.results[pp].MeterVolume = pp.VolumeM3(this.results[pp]);
|
||||
this.results[pp].VolumeMessured = referenceV;
|
||||
var resonse = connection.ViewChamberCalibration();
|
||||
|
||||
this.Running = calibrationResult.Succeeded && calibrationResult.Control == ChamberCalibrationResponse.TEST_COMPLETED;
|
||||
this.results[pp].Rotations = resonse.Rotations;
|
||||
this.results[pp].Duration = resonse.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.Meter.Add(this.results[pp]);
|
||||
|
||||
if (this.Running)
|
||||
{
|
||||
this.State = $"PP {pp.Rotations}/{pp.Duration} (rotations/seconds) wurde durchgeführt.";
|
||||
this.State = $"{this.Header} PP {pp.Rotations}/{pp.Duration} - completed.";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State = $"PP {pp.Rotations}/{pp.Duration} fehlgeschlagen: {(int)calibrationResult.Control} - {calibrationResult.Control}";
|
||||
this.State = $"{this.Header} PP {pp.Rotations}/{pp.Duration} failed: Status:{resonse.Status}, Control:{resonse.Control}";
|
||||
}
|
||||
}
|
||||
|
||||
this.Progress += 10;
|
||||
}
|
||||
|
||||
return this.StartNew(StopPPCalibration, cancellationToken);
|
||||
return Task.Factory.StartNew(StopPPCalibration, cancellationToken);
|
||||
}
|
||||
|
||||
internal Task FinishInspectionAsync(CancellationToken cancellationToken)
|
||||
internal Task SetRegisterSettingsAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.CancelExecution);
|
||||
|
||||
void FinishInspection()
|
||||
void SetRegisterSettings()
|
||||
{
|
||||
if (!this.IsRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var configurationParameters = this.connection.ViewConfigurationParameters();
|
||||
var canContinue = configurationParameters.Succeeded;
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
this.Meter.Add(configurationParameters);
|
||||
// TODO: Uncomment in production
|
||||
// var systemTimeReset = connection.SetSystemTime();
|
||||
//canContinue = systemTimeReset.Succeeded;
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
if (this.IsRunning())
|
||||
{
|
||||
var registerSettings = new RegisterSettings();
|
||||
|
||||
@@ -360,168 +308,233 @@
|
||||
registerSettings.PulseUpdate = 0x00;
|
||||
|
||||
var response = this.connection.Set(registerSettings);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var configurationParametersSet = new ConfigurationParametersSet();
|
||||
configurationParametersSet.ProgrammableID = this.Meter.BuildInfo;
|
||||
configurationParametersSet.FactoryID = this.Meter.BuildInfo;
|
||||
configurationParametersSet.NumberOfReadingDigits = 8;
|
||||
configurationParametersSet.ReadingPreset = "000000000";
|
||||
configurationParametersSet.OptionalUniDirFields = 1;
|
||||
configurationParametersSet.AlarmPercistancePeriodDays = 31;
|
||||
configurationParametersSet.DataLogIntervalMinutes = 60;
|
||||
configurationParametersSet.ManifacturingTime = Epoch20000101.UTCNow - 30000;
|
||||
configurationParametersSet.SystemTime = Epoch20000101.UTCNow;
|
||||
configurationParametersSet.RebootCount = 0;
|
||||
configurationParametersSet.BuildInfo = this.Meter.BuildInfo;
|
||||
return Task.Factory.StartNew(SetRegisterSettings, cancellationToken);
|
||||
}
|
||||
|
||||
var response = this.connection.Set(configurationParametersSet);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
internal Task FinishInspectionAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.Register(this.CancelExecution);
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ClearDisplay();
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
void FinishInspection()
|
||||
{
|
||||
//if (!this.IsRunning())
|
||||
//{
|
||||
// return;
|
||||
//}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.Set(new LeakAlarm
|
||||
{
|
||||
FlowRateGal = 0.25F, // 0.25 gpm
|
||||
TimeLimit = 24 * 60 * 60 // 24 hours => 86400sec
|
||||
});
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
//var configurationParameters = this.connection.ViewConfigurationParameters();
|
||||
//var canContinue = configurationParameters.Succeeded;
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.Set(new HighFlowAlarm
|
||||
{
|
||||
FlowRateGal = 25F, // 25 gpm
|
||||
TimeLimit = 1 * 60 * 60 // 1 hours => 86400sec
|
||||
});
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// this.Meter.Add(configurationParameters);
|
||||
// // TODO: Uncomment in production
|
||||
// // var systemTimeReset = connection.SetSystemTime();
|
||||
// //canContinue = systemTimeReset.Succeeded;
|
||||
//}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.Set(new ReverseFlowAlarm
|
||||
{
|
||||
FlowRateGal = -1F, // -1 gpm
|
||||
TimeLimit = 60 // 1 hours => 86400sec
|
||||
});
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var registerSettings = new RegisterSettings();
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ClearAlarms();
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
// registerSettings.IntPart = this.Meter.IntPart;
|
||||
// registerSettings.Fraction = this.Meter.Fraction;
|
||||
// registerSettings.Size = this.Meter.Size;
|
||||
// registerSettings.Range = this.Meter.Range;
|
||||
// registerSettings.VolumePerPulseUnit = 0x00;
|
||||
// registerSettings.MeterUnits = (byte)MessurementUnits.USGallons;
|
||||
// registerSettings.FlowUnits = (byte)MessurementUnits.USGallons;
|
||||
// registerSettings.FlowRate = (byte)TimeUnits.Minutes;
|
||||
// registerSettings.FactoryCorrection = this.Meter.FactoryCorrection;
|
||||
// registerSettings.FieldCorrection = 0x00;
|
||||
// registerSettings.PulseWeight = 0x01;
|
||||
// registerSettings.PulseWidth = 0x02;
|
||||
// registerSettings.PulseUpdate = 0x00;
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var alarmsState = this.connection.ViewAlarmsState();
|
||||
canContinue = alarmsState.Succeeded;
|
||||
//&& alarmsState.UsrEnabled
|
||||
//&& alarmsState.PreEnabledInactive;
|
||||
//TODO: Check alarms
|
||||
}
|
||||
// var response = this.connection.Set(registerSettings);
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.EnableNFC();
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var configurationParametersSet = new ConfigurationParametersSet();
|
||||
// configurationParametersSet.ProgrammableID = this.Meter.BuildInfo;
|
||||
// configurationParametersSet.FactoryID = this.Meter.BuildInfo;
|
||||
// configurationParametersSet.NumberOfReadingDigits = 8;
|
||||
// configurationParametersSet.ReadingPreset = "000000000";
|
||||
// configurationParametersSet.OptionalUniDirFields = 1;
|
||||
// configurationParametersSet.AlarmPercistancePeriodDays = 31;
|
||||
// configurationParametersSet.DataLogIntervalMinutes = 60;
|
||||
// configurationParametersSet.ManifacturingTime = Epoch20000101.UTCNow - 30000;
|
||||
// configurationParametersSet.SystemTime = Epoch20000101.UTCNow;
|
||||
// configurationParametersSet.RebootCount = 0;
|
||||
// configurationParametersSet.BuildInfo = this.Meter.BuildInfo;
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var registerSettingsAfter = this.connection.ViewRegisterSettings();
|
||||
//canContinue = registerSettingsAfter.Succeeded
|
||||
// && meter.Compare(registerSettingsAfter);
|
||||
}
|
||||
// var response = this.connection.Set(configurationParametersSet);
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var systemParametersAfter = this.connection.ViewSystemParameters();
|
||||
canContinue = systemParametersAfter.Succeeded;
|
||||
//&& meter.Compare(systemParametersAfter);
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var response = this.connection.ClearDisplay();
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var configurationParametersAfter = this.connection.ViewConfigurationParameters();
|
||||
canContinue = configurationParametersAfter.Succeeded;
|
||||
//&& meter.Compare(configurationParametersAfter);
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var response = this.connection.Set(new LeakAlarm
|
||||
// {
|
||||
// FlowRateGal = 0.25F, // 0.25 gpm
|
||||
// TimeLimit = 24 * 60 * 60 // 24 hours => 86400sec
|
||||
// });
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var alarmsState = this.connection.ViewAlarmsState();
|
||||
canContinue = alarmsState.Succeeded;
|
||||
//&& alarmsState.UsrEnabled
|
||||
//&& alarmsState.PreEnabledInactive;
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var response = this.connection.Set(new HighFlowAlarm
|
||||
// {
|
||||
// FlowRateGal = 25F, // 25 gpm
|
||||
// TimeLimit = 1 * 60 * 60 // 1 hours => 86400sec
|
||||
// });
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ViewAlarmSettings(0x01);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var response = this.connection.Set(new ReverseFlowAlarm
|
||||
// {
|
||||
// FlowRateGal = -1F, // -1 gpm
|
||||
// TimeLimit = 60 // 1 hours => 86400sec
|
||||
// });
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ViewAlarmSettings(0x02);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var response = this.connection.ClearAlarms();
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
// if (canContinue)
|
||||
{
|
||||
var response = this.connection.ViewAlarmSettings(0x04);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var alarmsState = this.connection.ViewAlarmsState();
|
||||
// canContinue = alarmsState.Succeeded;
|
||||
// //&& alarmsState.UsrEnabled
|
||||
// //&& alarmsState.PreEnabledInactive;
|
||||
// //TODO: Check alarms
|
||||
//}
|
||||
|
||||
if (canContinue)
|
||||
{
|
||||
//connection.Set(new FactorySeal
|
||||
//{
|
||||
// Sealed = true,
|
||||
//});
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var response = this.connection.EnableNFC();
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
//var factorySeal = connection.ViewFactorySeal();
|
||||
//canContinue = factorySeal.Succeeded && factorySeal.Sealed;
|
||||
}
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var registerSettingsAfter = this.connection.ViewRegisterSettings();
|
||||
// //canContinue = registerSettingsAfter.Succeeded
|
||||
// // && meter.Compare(registerSettingsAfter);
|
||||
//}
|
||||
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var systemParametersAfter = this.connection.ViewSystemParameters();
|
||||
// canContinue = systemParametersAfter.Succeeded;
|
||||
// //&& meter.Compare(systemParametersAfter);
|
||||
//}
|
||||
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var configurationParametersAfter = this.connection.ViewConfigurationParameters();
|
||||
// canContinue = configurationParametersAfter.Succeeded;
|
||||
// //&& meter.Compare(configurationParametersAfter);
|
||||
//}
|
||||
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var alarmsState = this.connection.ViewAlarmsState();
|
||||
// canContinue = alarmsState.Succeeded;
|
||||
// //&& alarmsState.UsrEnabled
|
||||
// //&& alarmsState.PreEnabledInactive;
|
||||
//}
|
||||
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var response = this.connection.ViewAlarmSettings(0x01);
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var response = this.connection.ViewAlarmSettings(0x02);
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
//// if (canContinue)
|
||||
//{
|
||||
// var response = this.connection.ViewAlarmSettings(0x04);
|
||||
// canContinue = response.Succeeded;
|
||||
//}
|
||||
|
||||
//if (canContinue)
|
||||
//{
|
||||
// //connection.Set(new FactorySeal
|
||||
// //{
|
||||
// // Sealed = true,
|
||||
// //});
|
||||
|
||||
// //var factorySeal = connection.ViewFactorySeal();
|
||||
// //canContinue = factorySeal.Succeeded && factorySeal.Sealed;
|
||||
//}
|
||||
|
||||
this.Progress = 100;
|
||||
}
|
||||
|
||||
return this.StartNew(FinishInspection, cancellationToken);
|
||||
return Task.Factory.StartNew(FinishInspection, cancellationToken);
|
||||
}
|
||||
|
||||
internal void SaveInspection(StringBuilder results)
|
||||
internal Task GetRegisterSettingsAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
if (results.Length <= 1)
|
||||
cancellationToken.Register(this.CancelExecution);
|
||||
|
||||
void GetRegisterSettings()
|
||||
{
|
||||
results.AppendLine(string.Join(";", this.Meter.Results.Select(x => x.Key)));
|
||||
if (this.IsRunning())
|
||||
{
|
||||
var response = this.connection.ViewRegisterSettings();
|
||||
|
||||
if (response.Succeeded)
|
||||
{
|
||||
this.Meter.AddResult("<<< Correction factor", $"{response.FactoryCorrection / 10D:0.00} %");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
results.AppendLine(string.Join(";", this.Meter.Results.Select(x => x.Value)));
|
||||
return Task.Factory.StartNew(GetRegisterSettings, cancellationToken);
|
||||
}
|
||||
|
||||
internal double GetCorrectionFactor()
|
||||
{
|
||||
var correction = this.results
|
||||
.OrderBy(x => x.Key.GalPerMin)
|
||||
.Select(x => x.Value.DifferencePercentage)
|
||||
.ToArray()
|
||||
.GetCorrectionFactor();
|
||||
var deviations = this.results
|
||||
.OrderBy(x => x.Key.GPM)
|
||||
.Select(x => x.Value.DifferencePercentage())
|
||||
.ToArray();
|
||||
|
||||
this.State = $"Korekturfaktor: {correction:0.00} %";
|
||||
var correction = deviations.GetCorrectionFactor();
|
||||
var correctionUnit = 1 + correction / 100;
|
||||
|
||||
this.State = $"{this.Header}, correction: {correction:0.00} %";
|
||||
this.Meter.AddFactoryCorrection(correction);
|
||||
|
||||
foreach (var deviation in deviations)
|
||||
{
|
||||
this.Meter.AddResult($"{deviation:0.00} %", $"{deviation * correctionUnit:0.00} %");
|
||||
}
|
||||
|
||||
return correction;
|
||||
}
|
||||
@@ -530,7 +543,7 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
this.connection?.Disconnect();
|
||||
this.connection?.Close();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -538,30 +551,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsRunning()
|
||||
public bool IsRunning()
|
||||
{
|
||||
if (!this.Running)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
this.Connected = this.connection.Connected;
|
||||
|
||||
return this.Connected;
|
||||
}
|
||||
|
||||
private Task StartNew(Action action, CancellationToken cancellationToken, int counter = 3)
|
||||
{
|
||||
return Task
|
||||
.Factory
|
||||
.StartNew(action, cancellationToken);
|
||||
//.ContinueWith(task =>
|
||||
//{
|
||||
// if (task.Status == TaskStatus.Faulted && counter > 0)
|
||||
// {
|
||||
// StartNew(action, cancellationToken, counter - 1).Wait();
|
||||
// }
|
||||
//});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
@@ -22,14 +21,12 @@
|
||||
public class EOLContentVM : ContentVM
|
||||
{
|
||||
private static readonly string line = new string('=', 500);
|
||||
|
||||
private readonly EOLSettings omnisettings;
|
||||
private readonly ExchangeHubSettings hubsettings;
|
||||
|
||||
private readonly ExchangeConnection exchangeConnection;
|
||||
private readonly OmniDatabase dbcontext;
|
||||
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
private CancellationToken cancellationToken;
|
||||
private OmniPlusDatabase dbcontext;
|
||||
private ManualResetEventSlim awaiter;
|
||||
private ICollection<Task> tasks;
|
||||
private TimersTimer timer;
|
||||
@@ -41,22 +38,17 @@
|
||||
this.CanStart = true;
|
||||
this.CanCheck = true;
|
||||
this.Option = new EOLOptionVM(this);
|
||||
this.OmniDefaults = new OmniPlusType();
|
||||
this.Option.OptionSelected += this.NotifyOptionSelected;
|
||||
|
||||
this.tasks = new List<Task>();
|
||||
this.omnisettings = new EOLSettings();
|
||||
this.hubsettings = new ExchangeHubSettings();
|
||||
this.exchangeConnection = new ExchangeConnection();
|
||||
this.dbcontext = new OmniPlusDatabase(this.omnisettings.OmniDB);
|
||||
this.dbcontext = new OmniDatabase(Appsettings.Current.OmniDB);
|
||||
this.OmniDefaults = new OmniPlusType();
|
||||
|
||||
this.LoadComPorts = new Command(this.PrepareConnections);
|
||||
this.CancelInspection = new Command(this.CancelInspectionHandler);
|
||||
this.StartInspection = new Command(this.StartInspectionHandler);
|
||||
this.CheckInspection = new Command(this.CheckInspectionHandler);
|
||||
|
||||
this.Option.OptionSelected += this.NotifyOptionSelected;
|
||||
|
||||
this.PrepareConnections();
|
||||
}
|
||||
|
||||
private int size;
|
||||
@@ -204,8 +196,7 @@
|
||||
this.State = e.ToString();
|
||||
}
|
||||
|
||||
this.exchangeConnection.Disconnect();
|
||||
this.exchangeConnection.Connect(this.hubsettings.ExchangeHubURL);
|
||||
this.exchangeConnection.Connect(Appsettings.Current.ExchangeHubURL);
|
||||
|
||||
if (this.Size == 0 || this.Type is null)
|
||||
{
|
||||
@@ -230,14 +221,13 @@
|
||||
|
||||
this.dbcontext.LoadOmniDefaults((byte)this.Size, this.Type, this.OmniDefaults);
|
||||
this.NotifyPropertyChanged(nameof(this.OmniDefaults));
|
||||
|
||||
this.Text = $"ME OMNI 1.5-2\" {this.Type}";
|
||||
|
||||
try
|
||||
{
|
||||
var placeNr = 1;
|
||||
|
||||
foreach (var com in this.omnisettings.COMPorts)
|
||||
foreach (var com in Appsettings.Current.COMPorts)
|
||||
{
|
||||
var comVM = new COMContentVM();
|
||||
comVM.ContentSelected += this.NotifyCotnentSelected;
|
||||
@@ -271,6 +261,7 @@
|
||||
catch (Exception e)
|
||||
{
|
||||
this.Error = e.ToString();
|
||||
this.LogError(e.ToString());
|
||||
}
|
||||
|
||||
this.CanStop = false;
|
||||
@@ -289,8 +280,9 @@
|
||||
|
||||
try
|
||||
{
|
||||
this.exchangeConnection.SendStopFlow();
|
||||
this.exchangeConnection.Disconnect();
|
||||
this.awaiter.Set();
|
||||
this.awaiter?.Set();
|
||||
this.cancellationTokenSource?.Cancel();
|
||||
this.tasks.Clear();
|
||||
|
||||
@@ -300,6 +292,7 @@
|
||||
{
|
||||
this.Error = e.ToString();
|
||||
this.State = default(string);
|
||||
this.LogError(e.ToString());
|
||||
}
|
||||
|
||||
Task.Factory.StartNew(() =>
|
||||
@@ -334,6 +327,22 @@
|
||||
}
|
||||
});
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.SetRegisterSettingsAsync(cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.GetRegisterSettingsAsync(cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
foreach (var pp in this.OmniDefaults.TestPoints)
|
||||
{
|
||||
if (this.canceled)
|
||||
@@ -344,17 +353,21 @@
|
||||
var rotations = pp.Rotations;
|
||||
var duration = pp.Duration;
|
||||
|
||||
this.StartFlow(pp.VolumeM3H);
|
||||
this.StartFlow(pp.RequiredFlowM3H);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
// this.canceled = this.canceled || meterVM.IsRunning();
|
||||
|
||||
tasks.Add(meterVM.StartPPCalibrationAsync(pp, cancellationToken));
|
||||
}
|
||||
});
|
||||
@@ -366,20 +379,27 @@
|
||||
break;
|
||||
}
|
||||
|
||||
this.WaitUntil((int)(duration * 1.2), true, false);
|
||||
this.WaitUntil(duration, true, false);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var referenceV = this.GetReferenceVolume();
|
||||
var referenceFlowM3S = this.GetReferenceFlowM3S();
|
||||
|
||||
if (referenceFlowM3S == default(double))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.StopPPCalibrationAsync(pp, referenceV, cancellationToken));
|
||||
// this.canceled = this.canceled || meterVM.IsRunning();
|
||||
|
||||
tasks.Add(meterVM.StopPPCalibrationAsync(pp, referenceFlowM3S, cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -391,37 +411,18 @@
|
||||
|
||||
this.exchangeConnection.SendStopFlow();
|
||||
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
meterVM.GetCorrectionFactor();
|
||||
}
|
||||
|
||||
var results = new StringBuilder();
|
||||
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
meterVM.SaveInspection(results);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var directory = Directory.CreateDirectory(".\\Results");
|
||||
var file = Path.Combine(directory.FullName, $"Results_{DateTime.Now:yyyyMMddHHmmss}.csv");
|
||||
|
||||
File.WriteAllText(file, results.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.State = e.ToString();
|
||||
}
|
||||
|
||||
if (!this.canceled)
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
meterVM.GetCorrectionFactor();
|
||||
}
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.FinishInspectionAsync(cancellationToken));
|
||||
tasks.Add(meterVM.SetRegisterSettingsAsync(cancellationToken));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -458,7 +459,7 @@
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.SetInputVolumeAsync(this.OmniDefaults, cancellationToken));
|
||||
tasks.Add(meterVM.GetRegisterSettingsAsync(cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -472,7 +473,7 @@
|
||||
var rotations = pp.Rotations;
|
||||
var duration = pp.Duration;
|
||||
|
||||
this.StartFlow(pp.VolumeM3H);
|
||||
this.StartFlow(pp.RequiredFlowM3H);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
@@ -494,20 +495,27 @@
|
||||
break;
|
||||
}
|
||||
|
||||
this.WaitUntil((int)(duration * 1.2), true, false);
|
||||
this.WaitUntil(duration, true, false);
|
||||
|
||||
if (this.canceled)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
var referenceV = this.GetReferenceVolume();
|
||||
var referenceFlowM3S = this.GetReferenceFlowM3S();
|
||||
|
||||
if (referenceFlowM3S == default(double))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.WaitUntil((int)(Math.Truncate(duration * 0.2) + 1), true, false);
|
||||
|
||||
this.InvokeAsync((tasks, cancellationToken) =>
|
||||
{
|
||||
foreach (var meterVM in metersVM)
|
||||
{
|
||||
tasks.Add(meterVM.StopPPCalibrationAsync(pp, referenceV, cancellationToken));
|
||||
tasks.Add(meterVM.StopPPCalibrationAsync(pp, referenceFlowM3S, cancellationToken));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -534,7 +542,6 @@
|
||||
this.CanStart = true;
|
||||
this.Error = default(string);
|
||||
this.State = default(string);
|
||||
|
||||
}, this.cancellationToken);
|
||||
}
|
||||
|
||||
@@ -593,16 +600,16 @@
|
||||
{
|
||||
var received = false;
|
||||
var volume = volumeM3H;
|
||||
var timeout = 120; // seconds
|
||||
var timeout = 500; // seconds
|
||||
|
||||
void referenceVolumeReceived(double value, string _)
|
||||
void FlowStarted(double value, string _)
|
||||
{
|
||||
timeout = -1;
|
||||
timeout = 0;
|
||||
received = true;
|
||||
volume = value;
|
||||
}
|
||||
|
||||
this.exchangeConnection.StartFlow += referenceVolumeReceived;
|
||||
this.exchangeConnection.StartFlow += FlowStarted;
|
||||
|
||||
this.exchangeConnection.SendStartFlow(volumeM3H);
|
||||
|
||||
@@ -624,6 +631,8 @@
|
||||
this.State = $"Warten auf Q({volumeM3H:0.0000}): {timeout} Sekunden verbleiben ...";
|
||||
}
|
||||
|
||||
this.exchangeConnection.StartFlow -= FlowStarted;
|
||||
|
||||
if (!this.canceled)
|
||||
{
|
||||
this.State = $"Durchfluss {volume:0.0000} erreicht ...";
|
||||
@@ -634,16 +643,16 @@
|
||||
{
|
||||
var received = false;
|
||||
var reference = 0;
|
||||
var timeout = 30; // seconds
|
||||
var timeout = 60; // seconds
|
||||
|
||||
void referenceVolumeReceived(int seconds, string _)
|
||||
void ReferenceMessurementStarted(int seconds, string _)
|
||||
{
|
||||
timeout = -1;
|
||||
timeout = 0;
|
||||
received = true;
|
||||
reference = seconds;
|
||||
}
|
||||
|
||||
this.exchangeConnection.StartReferenceMessurement += referenceVolumeReceived;
|
||||
this.exchangeConnection.StartReferenceMessurement += ReferenceMessurementStarted;
|
||||
|
||||
this.exchangeConnection.SendStartReferenceMessurement(duration);
|
||||
|
||||
@@ -665,26 +674,28 @@
|
||||
this.State = $"Warten bis RZ gestarted: {timeout} Sekunden verbleiben ...";
|
||||
}
|
||||
|
||||
this.exchangeConnection.StartReferenceMessurement -= ReferenceMessurementStarted;
|
||||
|
||||
if (!this.canceled)
|
||||
{
|
||||
this.State = $"Referenzmessung gestartet ...";
|
||||
}
|
||||
}
|
||||
|
||||
private double GetReferenceVolume()
|
||||
private double GetReferenceFlowM3S()
|
||||
{
|
||||
var received = false;
|
||||
var referenceV = 0D;
|
||||
var timeout = 30; // seconds
|
||||
var timeout = 60; // seconds
|
||||
|
||||
void referenceVolumeReceived(double value, string _)
|
||||
void ReferenceFlowM3SecReceived(double value, string _)
|
||||
{
|
||||
timeout = -1;
|
||||
timeout = 0;
|
||||
received = true;
|
||||
referenceV = value;
|
||||
}
|
||||
|
||||
this.exchangeConnection.StopReferenceMessurement += referenceVolumeReceived;
|
||||
this.exchangeConnection.StopReferenceMessurement += ReferenceFlowM3SecReceived;
|
||||
|
||||
this.exchangeConnection.SendStopReferenceMessurement();
|
||||
|
||||
@@ -706,6 +717,8 @@
|
||||
this.State = $"Warten RZ-Ergebnis: {timeout} Sekunden verbleiben ...";
|
||||
}
|
||||
|
||||
this.exchangeConnection.StopReferenceMessurement -= ReferenceFlowM3SecReceived;
|
||||
|
||||
|
||||
if (!this.canceled)
|
||||
{
|
||||
@@ -764,7 +777,14 @@
|
||||
|
||||
private void LogError(string error)
|
||||
{
|
||||
File.AppendAllText(this.errorLog, error);
|
||||
try
|
||||
{
|
||||
File.AppendAllText(this.errorLog, error);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
public class ExchangeHubContentVM : ContentVM
|
||||
{
|
||||
private readonly ExchangeHubSettings hubsettings;
|
||||
private readonly ExchangeConnection connection;
|
||||
|
||||
public ExchangeHubContentVM() : base()
|
||||
@@ -22,44 +21,12 @@
|
||||
this.Option.OptionSelected += this.NotifyOptionSelected;
|
||||
this.Connect = new Command(this.ConnectHubHandler);
|
||||
this.Disconnect = new Command(this.DisconnectHubHandler);
|
||||
this.hubsettings = new ExchangeHubSettings();
|
||||
this.connection = new ExchangeConnection();
|
||||
this.connection.StateChanged += Connection_StateChanged1;
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.LogContent));
|
||||
}
|
||||
|
||||
public string URL
|
||||
{
|
||||
get => this.hubsettings.ExchangeHubURL;
|
||||
set
|
||||
{
|
||||
this.hubsettings.ExchangeHubURL = value;
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.URL));
|
||||
}
|
||||
}
|
||||
|
||||
public string OutputDir
|
||||
{
|
||||
get
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(this.hubsettings.ExchangeHubOutputDir))
|
||||
{
|
||||
this.hubsettings.ExchangeHubOutputDir = App.Path;
|
||||
}
|
||||
|
||||
return this.hubsettings.ExchangeHubOutputDir;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.hubsettings.ExchangeHubOutputDir = value;
|
||||
|
||||
this.NotifyPropertyChanged(nameof(this.OutputDir));
|
||||
}
|
||||
}
|
||||
|
||||
private bool connected;
|
||||
public bool Connected
|
||||
{
|
||||
@@ -85,7 +52,7 @@
|
||||
{
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
this.connection.Connect(this.URL);
|
||||
this.connection.Connect(Appsettings.Current.ExchangeHubURL);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,17 +13,15 @@
|
||||
this.ContentSelected += this.SetContentSelected;
|
||||
this.Options = new ObservableCollection<OptionVM>();
|
||||
|
||||
var exchangeHubVM = new ExchangeHubContentVM();
|
||||
exchangeHubVM.ContentSelected += this.SetContentSelected;
|
||||
// var exchangeHubVM = new ExchangeHubContentVM();
|
||||
// exchangeHubVM.ContentSelected += this.SetContentSelected;
|
||||
// this.Options.Add(exchangeHubVM.Option);
|
||||
// this.Nodes.Add(exchangeHubVM);
|
||||
|
||||
var contentEOL = new EOLContentVM();
|
||||
contentEOL.ContentSelected += this.SetContentSelected;
|
||||
|
||||
this.Nodes.Add(exchangeHubVM);
|
||||
this.Nodes.Add(contentEOL);
|
||||
|
||||
this.Options.Add(exchangeHubVM.Option);
|
||||
this.Options.Add(contentEOL.Option);
|
||||
this.Nodes.Add(contentEOL);
|
||||
}
|
||||
|
||||
private ContentVM content;
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
namespace OMNIPruefung.ViewModels.Features
|
||||
{
|
||||
using OmniPlus;
|
||||
using OmniPlus.Features;
|
||||
using OmniPlus.Inspection;
|
||||
using OMNIPruefung.Models;
|
||||
using OMNIPruefung.ViewModels.Base;
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Windows;
|
||||
|
||||
public class OMNIPlusVM : VM<OMNIPlusVM>
|
||||
{
|
||||
public ObservableCollection<Result> Results { get; }
|
||||
= new ObservableCollection<Result>();
|
||||
// TODO: save all in database
|
||||
private readonly OmniDatabase database;
|
||||
|
||||
public OMNIPlusVM()
|
||||
{
|
||||
this.database = new OmniDatabase(Appsettings.Current.OmniDB);
|
||||
this.Results = new ObservableCollection<Result>();
|
||||
}
|
||||
|
||||
public ushort IntPart { get; internal set; }
|
||||
|
||||
@@ -21,25 +31,24 @@
|
||||
|
||||
public sbyte FactoryCorrection { get; internal set; }
|
||||
|
||||
public string BuildInfo { get; internal set; }
|
||||
public ObservableCollection<Result> Results { get; }
|
||||
|
||||
internal void AddResult(string key, string value)
|
||||
{
|
||||
this.Results.Add(new Result
|
||||
Application.Current.Dispatcher.Invoke(new Action(() =>
|
||||
{
|
||||
Key = key,
|
||||
Value = value
|
||||
});
|
||||
this.Results.Add(new Result
|
||||
{
|
||||
Key = key,
|
||||
Value = value
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
internal void Add(SystemParameters response)
|
||||
internal void Add(OmniPlus.Features.SystemParameters response)
|
||||
{
|
||||
this.AddResult("Reading System Parameters", $"{response.Status}");
|
||||
|
||||
if (response.Succeeded)
|
||||
{
|
||||
this.BuildInfo = response.BuildInfo.Value;
|
||||
|
||||
this.AddResult(nameof(response.VersionAndType), response.VersionAndType.Value);
|
||||
this.AddResult(nameof(response.BuildInfo), response.BuildInfo.Value);
|
||||
this.AddResult(nameof(response.BatteryVoltage), $"{(response.BatteryVoltage.Volts + 0.0001) / 1000:0.0000 V}");
|
||||
@@ -52,29 +61,32 @@
|
||||
|
||||
internal void Add(InputVolume response)
|
||||
{
|
||||
this.IntPart = response.IntPart;
|
||||
this.Fraction = response.Fraction;
|
||||
this.Size = response.Size;
|
||||
this.Range = response.Range;
|
||||
this.IntPart = response.IntPartFull;
|
||||
this.Fraction = response.Fraction;
|
||||
|
||||
this.AddResult("Setting ml/r", $"{response.MlPerRotation:0.0000 ml/r}");
|
||||
this.AddResult(nameof(response.Size), $"{response.Size}");
|
||||
this.AddResult(nameof(response.Range), $"{response.Range}");
|
||||
this.AddResult(nameof(response.Direction), $"{response.Direction}");
|
||||
this.AddResult(nameof(response.IntPart), $"{response.IntPart}");
|
||||
this.AddResult(nameof(response.Fraction), $"{response.Fraction}");
|
||||
}
|
||||
|
||||
internal void Add(OmniPlusTestPoint pp)
|
||||
{
|
||||
this.AddResult("", $"");
|
||||
this.AddResult("Test point:", $"{pp.Rotations}/{pp.Duration:0}");
|
||||
this.AddResult("Volume", $"{pp.VolumeM3H:0.0000 m³/h}");
|
||||
this.AddResult("Duration", $"{pp.Duration:0 sec.}");
|
||||
this.AddResult("ml/rotation", $"{pp.MlPerRotation:0.0000 ml/r}");
|
||||
this.AddResult("Volume", $"{pp.RequiredFlowM3H:0.00000000 m³/h}");
|
||||
this.AddResult("Validation frame", $"{pp.MinDiff:0.00}% - {pp.MaxDiff:0.00}%");
|
||||
}
|
||||
|
||||
internal void Add(OmniPlusTest test)
|
||||
{
|
||||
this.AddResult("Result", $"{test.DifferencePercentage:0.00}%");
|
||||
this.AddResult("Meter volume", $"{test.MeterVolume:0.0000 m³}");
|
||||
this.AddResult("Reference volume", $"{test.VolumeMessured:0.0000 m³}");
|
||||
this.AddResult("Test result", $"{test.Rotations}/{test.Duration:0}");
|
||||
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}%");
|
||||
}
|
||||
|
||||
internal void Add(ConfigurationParameters response)
|
||||
@@ -93,8 +105,7 @@
|
||||
{
|
||||
this.FactoryCorrection = (sbyte)(value * 10);
|
||||
|
||||
this.AddResult("Factory correction %", $"{value:0.00}%");
|
||||
this.AddResult("Factory correction", $"{this.FactoryCorrection:0}");
|
||||
this.AddResult("Correction", $"{value:0.00} %");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,9 +58,9 @@
|
||||
<Label Grid.Column="3" Grid.Row="3" Content="min %" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
|
||||
<Label Grid.Column="4" Grid.Row="3" Content="max %" HorizontalContentAlignment="Right" Grid.ColumnSpan="2" FontWeight="Bold" Margin="0" Padding="0, 5, 0, 0" />
|
||||
|
||||
<Label Grid.Column="2" Grid.Row="4" Content="{Binding OmniDefaults.TestPoints[0].VolumeM3H}" ContentStringFormat="{}{0:0.0000} m³/h" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
|
||||
<Label Grid.Column="2" Grid.Row="5" Content="{Binding OmniDefaults.TestPoints[1].VolumeM3H}" ContentStringFormat="{}{0:0.0000} m³/h" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
|
||||
<Label Grid.Column="2" Grid.Row="6" Content="{Binding OmniDefaults.TestPoints[2].VolumeM3H}" ContentStringFormat="{}{0:0.0000} m³/h" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
|
||||
<Label Grid.Column="2" Grid.Row="4" Content="{Binding OmniDefaults.TestPoints[0].RequiredFlowM3H}" ContentStringFormat="{}{0:0.0000} m³/h" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
|
||||
<Label Grid.Column="2" Grid.Row="5" Content="{Binding OmniDefaults.TestPoints[1].RequiredFlowM3H}" ContentStringFormat="{}{0:0.0000} m³/h" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
|
||||
<Label Grid.Column="2" Grid.Row="6" Content="{Binding OmniDefaults.TestPoints[2].RequiredFlowM3H}" ContentStringFormat="{}{0:0.0000} m³/h" HorizontalContentAlignment="Right" FontWeight="Bold" Margin="0" Padding="0, 5, 21, 0"/>
|
||||
|
||||
<Label Grid.Column="3" Grid.Row="4" Content="{Binding OmniDefaults.TestPoints[0].MinDiff}" ContentStringFormat="{}{0:0.00} %" HorizontalContentAlignment="Right" Margin="0" Padding="0, 5, 21, 0" />
|
||||
<Label Grid.Column="3" Grid.Row="5" Content="{Binding OmniDefaults.TestPoints[1].MinDiff}" ContentStringFormat="{}{0:0.00} %" HorizontalContentAlignment="Right" Margin="0" Padding="0, 5, 21, 0" />
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
internal class IrdaEncoder : SerialDataEncoder
|
||||
{
|
||||
public byte Device2PC { get; } = SerialDataExtensions.IRDA_REG2PC;
|
||||
|
||||
public override bool TryDecode(byte[] encoded, out byte[] decoded)
|
||||
{
|
||||
decoded = encoded.FromIrdaMessage();
|
||||
|
||||
return decoded.Length > 0;
|
||||
}
|
||||
|
||||
public override bool TryEncode(byte[] decoded, out byte[] encoded)
|
||||
{
|
||||
encoded = decoded.ToIrdaMessage();
|
||||
|
||||
return encoded.Length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
internal class IrdaStream : SerialDataReader
|
||||
{
|
||||
private readonly IrdaEncoder encoder;
|
||||
|
||||
public IrdaStream(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
this.encoder = new IrdaEncoder();
|
||||
}
|
||||
|
||||
protected override void WriteBytes(params byte[] bytes)
|
||||
{
|
||||
if (this.encoder.TryEncode(bytes, out byte[] message))
|
||||
{
|
||||
base.WriteBytes(1, 1, 1, 1);
|
||||
|
||||
Thread.Sleep(1);
|
||||
|
||||
base.WriteBytes(message);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void BeginRead(byte[] bytes)
|
||||
{
|
||||
if (bytes is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var start = Array.IndexOf(bytes, this.encoder.Device2PC);
|
||||
|
||||
if (start >= 0)
|
||||
{
|
||||
if (this.encoder.TryDecode(bytes, out byte[] message))
|
||||
{
|
||||
this.EnqueueMessage(message);
|
||||
this.RemoveRange(message.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.RemoveRange(bytes.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
internal sealed class OmniIrdaEncoder : SerialDataEncoder
|
||||
{
|
||||
public override bool TryDecode(byte[] data, out byte[] message, out int start, out int length)
|
||||
{
|
||||
message = default(byte[]);
|
||||
|
||||
if (data.FromIrdaMessage(out byte[] payload, out start, out length))
|
||||
{
|
||||
if (payload.FromUI1236Message(out message, out start, out length))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool TryEncode(byte[] data, out byte[] message)
|
||||
{
|
||||
message = data
|
||||
.ToUI1236Message()
|
||||
.ToIrdaMessage();
|
||||
|
||||
return message != null && message.Length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System.Threading;
|
||||
|
||||
internal sealed class OmniIrdaStream : SerialDataStream
|
||||
{
|
||||
private readonly ManualResetEventSlim waitHandle;
|
||||
|
||||
public OmniIrdaStream(SerialDataEncoder encoder, SerialPortSettings settings) : base(encoder, settings)
|
||||
{
|
||||
this.waitHandle = new ManualResetEventSlim();
|
||||
}
|
||||
|
||||
public override byte[] Send(params byte[] message)
|
||||
{
|
||||
var response = new byte[0];
|
||||
|
||||
void DataReceived(byte[] data)
|
||||
{
|
||||
response = data;
|
||||
|
||||
this.waitHandle.Set();
|
||||
}
|
||||
|
||||
this.DataReceived += DataReceived;
|
||||
|
||||
this.StartListening();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (response != null && response.Length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.WritePlain(1, 1, 1, 1);
|
||||
|
||||
this.waitHandle.Wait(1);
|
||||
this.waitHandle.Reset();
|
||||
|
||||
this.WriteEncoded(message);
|
||||
|
||||
this.waitHandle.Wait(3000);
|
||||
this.waitHandle.Reset();
|
||||
}
|
||||
|
||||
this.StopListening();
|
||||
|
||||
this.DataReceived -= DataReceived;
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
internal class OmniUniProEncoder : SerialDataEncoder
|
||||
{
|
||||
public override bool TryDecode(byte[] data, out byte[] message, out int start, out int length)
|
||||
{
|
||||
return data.FromUniProMessage(out message, out start, out length);
|
||||
}
|
||||
|
||||
public override bool TryEncode(byte[] data, out byte[] message)
|
||||
{
|
||||
message = new byte[0];
|
||||
|
||||
if (data != null && data.Length > 0)
|
||||
{
|
||||
message = data.ToUniProMessage();
|
||||
}
|
||||
|
||||
return message != null && message.Length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System.Threading;
|
||||
|
||||
internal class OmniUniProStream : SerialDataStream
|
||||
{
|
||||
private readonly ManualResetEventSlim waitHandle;
|
||||
|
||||
public OmniUniProStream(SerialDataEncoder encoder, SerialPortSettings settings) : base(encoder, settings)
|
||||
{
|
||||
this.waitHandle = new ManualResetEventSlim();
|
||||
}
|
||||
|
||||
public override byte[] Send(params byte[] message)
|
||||
{
|
||||
var response = new byte[0];
|
||||
|
||||
void DataReceived(byte[] data)
|
||||
{
|
||||
response = data;
|
||||
|
||||
this.waitHandle.Set();
|
||||
}
|
||||
|
||||
this.DataReceived += DataReceived;
|
||||
|
||||
this.StartListening();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (response != null && response.Length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.WriteEncoded(message);
|
||||
|
||||
this.waitHandle.Wait(3000);
|
||||
this.waitHandle.Reset();
|
||||
}
|
||||
|
||||
this.StopListening();
|
||||
|
||||
this.DataReceived -= DataReceived;
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,110 +0,0 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Text;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
var number = "81623241198";
|
||||
var last = number.Length - 1;
|
||||
var line = string.Empty;
|
||||
|
||||
while (!string.IsNullOrEmpty(line = Console.ReadLine()))
|
||||
{
|
||||
Console.WriteLine();
|
||||
|
||||
var next = number + line[0];
|
||||
var request = new byte[] { };
|
||||
var response = new byte[] { };
|
||||
var settings = new SerialPortSettings
|
||||
{
|
||||
BaudRate = 115200,
|
||||
DataBits = 8,
|
||||
Parity = Parity.None,
|
||||
PortName = "COM1",
|
||||
StopBits = StopBits.One,
|
||||
};
|
||||
var foreground = Console.ForegroundColor;
|
||||
|
||||
using (var stream = new UI1236Stream(settings))
|
||||
{
|
||||
stream.Open();
|
||||
|
||||
request = new byte[] { 0x05 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[] { 0x01 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[14];
|
||||
request[0] = 0x02;
|
||||
Encoding.ASCII.GetBytes(next).CopyTo(request, 1);
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[] { 0x01 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[] { 0x03 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[22];
|
||||
request[0] = 0x04;
|
||||
Encoding.ASCII.GetBytes($"SEN{next}").CopyTo(request, 1);
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
request = new byte[] { 0x03 };
|
||||
Console.ForegroundColor = ConsoleColor.DarkYellow;
|
||||
Console.WriteLine($">>> {BitConverter.ToString(request)}");
|
||||
response = stream.Write(request);
|
||||
Console.ForegroundColor = ConsoleColor.DarkGreen;
|
||||
Console.WriteLine($"<<< {BitConverter.ToString(response)}");
|
||||
Console.ForegroundColor = ConsoleColor.White;
|
||||
Console.WriteLine($"... {Encoding.ASCII.GetString(response).Trim('\0', '\r', '\n')}");
|
||||
|
||||
Console.ForegroundColor = foreground;
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,8 @@
|
||||
{
|
||||
internal abstract class SerialDataEncoder
|
||||
{
|
||||
public abstract bool TryDecode(byte[] encoded, out byte[] decoded);
|
||||
public abstract bool TryEncode(byte[] data, out byte[] message);
|
||||
|
||||
public abstract bool TryEncode(byte[] decoded, out byte[] encoded);
|
||||
public abstract bool TryDecode(byte[] data, out byte[] message, out int start, out int length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
using System;
|
||||
|
||||
internal static class SerialDataExtensions
|
||||
public static class SerialDataExtensions
|
||||
{
|
||||
public const int BYTE_BITS = 8;
|
||||
|
||||
@@ -18,13 +18,17 @@
|
||||
public const byte UNIPRO_MIN_LENGTH = 4;
|
||||
|
||||
public const byte UI1236_START = 0x0D;
|
||||
public const byte UI1236_LEN_INDEX = 1;
|
||||
public const byte UI1236_DATA_INDEX = 3;
|
||||
public const byte UI1236_MIN_LENGTH = 5;
|
||||
public const byte UI1236_HED_LENGTH = 3;
|
||||
public const byte UI1236_HEAD_LENGTH = 3;
|
||||
|
||||
public const byte IRDA_START = 0x9B;
|
||||
public const byte IRDA_PING = 0x82;
|
||||
public const byte IRDA_PC2REG = 0x33;
|
||||
public const byte IRDA_REG2PC = 0x43;
|
||||
public const byte IRDA_LEN_INDEX = 2;
|
||||
public const byte IRDA_DATA_INDEX = 3;
|
||||
public const byte IRDA_MIN_LENGTH = 5;
|
||||
public const byte IRDA_CRC_LENGTH = 2;
|
||||
|
||||
@@ -39,14 +43,27 @@
|
||||
/// </summary>
|
||||
public static byte[] ToUI1236Message(this byte[] bytes)
|
||||
{
|
||||
var message = new byte[0];
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
var bytesLength = bytes.Length;
|
||||
var payloadLength = bytes.Length + UI1236_MIN_LENGTH;
|
||||
payloadLength += payloadLength % OxO2;
|
||||
|
||||
if (bytesLength == 0)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
var messageLength = bytes.Length + UI1236_MIN_LENGTH;
|
||||
messageLength += messageLength % OxO2;
|
||||
|
||||
var index = OxOO;
|
||||
var message = new byte[payloadLength];
|
||||
message = new byte[messageLength];
|
||||
message[index++] = UI1236_START;
|
||||
message[index++] = (byte)(bytesLength + UI1236_HED_LENGTH);
|
||||
message[index++] = (byte)(bytesLength + UI1236_HEAD_LENGTH);
|
||||
|
||||
UI1236Control control = OxOO;
|
||||
control.ReturnResponse = true;
|
||||
@@ -55,45 +72,13 @@
|
||||
bytes.CopyTo(message, index);
|
||||
|
||||
var checksum = message.CalculateCheckSUM(message.Length - OxO2);
|
||||
var checksumIndex = bytesLength + UI1236_HED_LENGTH;
|
||||
var checksumIndex = bytesLength + UI1236_HEAD_LENGTH;
|
||||
message[checksumIndex++] = checksum[OxO1];
|
||||
message[checksumIndex++] = checksum[OxOO];
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>UI1236 structure:</para>
|
||||
/// <para> 0. 0x0D - Start byte</para>
|
||||
/// <para> 1. .... - Length: max. 254</para>
|
||||
/// <para> 2. .... - Control byte</para>
|
||||
/// <para>3+n. .... - Payload</para>
|
||||
/// <para>n-2. .... - Checksum 0 </para>
|
||||
/// <para>n-1. .... - Checksum 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] FromUI1236Message(this byte[] bytes)
|
||||
{
|
||||
var payload = new byte[OxOO];
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
var payloadLength = bytes.Length - UI1236_MIN_LENGTH;
|
||||
|
||||
if (payloadLength <= OxOO)
|
||||
{
|
||||
return payload;
|
||||
}
|
||||
|
||||
payload = new byte[payloadLength];
|
||||
|
||||
Buffer.BlockCopy(bytes, OxO3, payload, OxOO, payloadLength);
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>UniPro structure:</para>
|
||||
/// <para> 0. .... - Start byte</para>
|
||||
@@ -126,27 +111,56 @@
|
||||
/// <para> .. .... - Payload</para>
|
||||
/// <para>n-1. .... - Stop byte</para>
|
||||
/// </summary>
|
||||
public static byte[] FromUniProMessage(this byte[] bytes)
|
||||
public static bool FromUniProMessage(this byte[] bytes, out byte[] message, out int start, out int length)
|
||||
{
|
||||
var payload = new byte[OxOO];
|
||||
message = default(byte[]);
|
||||
length = default(int);
|
||||
start = default(int);
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return payload;
|
||||
return false;
|
||||
}
|
||||
|
||||
var payloadLength = bytes.Length - UNIPRO_MIN_LENGTH;
|
||||
var bytesLength = bytes.Length;
|
||||
|
||||
if (payloadLength <= OxOO)
|
||||
while (start < bytesLength)
|
||||
{
|
||||
return payload;
|
||||
start = Array.IndexOf(bytes, UNIPRO_REG2PC) - 1;
|
||||
|
||||
if (start < 0 || bytes[start] == UNIPRO_START)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
start += 2;
|
||||
}
|
||||
|
||||
payload = new byte[payloadLength];
|
||||
if (start < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(bytes, OxO3, payload, OxOO, payloadLength);
|
||||
start += 2;
|
||||
|
||||
return payload;
|
||||
if (start >= bytesLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
length = bytes[start] - UNIPRO_MIN_LENGTH;
|
||||
|
||||
if (start + length >= bytesLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
start += 1;
|
||||
message = new byte[length];
|
||||
|
||||
Buffer.BlockCopy(bytes, start, message, 0, length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -161,21 +175,35 @@
|
||||
/// </summary>
|
||||
public static byte[] ToIrdaMessage(this byte[] bytes)
|
||||
{
|
||||
var payloadLength = bytes.Length;
|
||||
payloadLength += payloadLength % OxO2;
|
||||
var message = new byte[0];
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
var bytesLength = bytes.Length;
|
||||
|
||||
if (bytesLength == 0)
|
||||
{
|
||||
return message;
|
||||
}
|
||||
|
||||
var messageLength = bytesLength;
|
||||
messageLength += messageLength % OxO2;
|
||||
|
||||
var index = OxOO;
|
||||
var message = new byte[payloadLength + IRDA_MIN_LENGTH];
|
||||
message = new byte[messageLength + IRDA_MIN_LENGTH];
|
||||
message[index++] = IRDA_START;
|
||||
message[index++] = IRDA_PC2REG;
|
||||
message[index++] = (byte)(payloadLength / OxO2);
|
||||
message[index++] = (byte)(messageLength / OxO2);
|
||||
|
||||
bytes.CopyTo(message, index);
|
||||
|
||||
var messageLength = message.Length;
|
||||
var crc16 = message.CalculateCRC8408(1, messageLength - IRDA_CRC_LENGTH);
|
||||
message[messageLength - OxO2] = crc16[OxOO];
|
||||
message[messageLength - OxO1] = crc16[OxO1];
|
||||
var _length = message.Length;
|
||||
var crc16 = message.CalculateCRC8408(1, _length - IRDA_CRC_LENGTH);
|
||||
message[_length - OxO2] = crc16[OxOO];
|
||||
message[_length - OxO1] = crc16[OxO1];
|
||||
|
||||
return message;
|
||||
}
|
||||
@@ -190,106 +218,111 @@
|
||||
/// <para>n-2. .... - CRC16 0 </para>
|
||||
/// <para>n-1. .... - CRC16 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] FromIrdaMessage(this byte[] bytes)
|
||||
public static bool FromIrdaMessage(this byte[] bytes, out byte[] message, out int start, out int length)
|
||||
{
|
||||
var payload = new byte[OxOO];
|
||||
message = default(byte[]);
|
||||
length = default(int);
|
||||
start = default(int);
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return payload;
|
||||
return false;
|
||||
}
|
||||
|
||||
var payloadLength = bytes.Length - IRDA_MIN_LENGTH;
|
||||
var bytesLength = bytes.Length;
|
||||
|
||||
if (payloadLength <= OxOO)
|
||||
while (start < bytesLength)
|
||||
{
|
||||
return payload;
|
||||
start = Array.IndexOf(bytes, IRDA_REG2PC, start) - 1;
|
||||
|
||||
if (start < 0 || bytes[start] == IRDA_START)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
start += 2;
|
||||
}
|
||||
|
||||
payload = new byte[payloadLength];
|
||||
if (start < 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Buffer.BlockCopy(bytes, OxO3, payload, OxOO, payloadLength);
|
||||
start += 2;
|
||||
|
||||
return payload;
|
||||
if (start >= bytesLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
length = bytes[start] * 2;
|
||||
|
||||
if (start + length >= bytesLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
start += 1;
|
||||
message = new byte[length];
|
||||
|
||||
Buffer.BlockCopy(bytes, start, message, 0, length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Irda structure:</para>
|
||||
/// <para> 0. .... - Start byte</para>
|
||||
/// <para> 1. .... - Direction</para>
|
||||
/// <para> 2. .... - Length / 2</para>
|
||||
/// <para>UI1236 structure:</para>
|
||||
/// <para> 0. 0x0D - Start byte</para>
|
||||
/// <para> 1. .... - Length: max. 254</para>
|
||||
/// <para> 2. .... - Control byte</para>
|
||||
/// <para>3+n. .... - Payload</para>
|
||||
/// <para>n-3. .... - aligned byte</para>
|
||||
/// <para>n-2. .... - CRC16 0 </para>
|
||||
/// <para>n-1. .... - CRC16 1 </para>
|
||||
/// <para>n-2. .... - Checksum 0 </para>
|
||||
/// <para>n-1. .... - Checksum 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] FromIrdaMessage(this byte[] bytes, int start, out int length)
|
||||
public static bool FromUI1236Message(this byte[] bytes, out byte[] message, out int start, out Int32 length)
|
||||
{
|
||||
length = OxOO;
|
||||
|
||||
var payload = new byte[length];
|
||||
message = default(byte[]);
|
||||
length = default(int);
|
||||
start = default(int);
|
||||
|
||||
if (bytes is null)
|
||||
{
|
||||
return payload;
|
||||
return false;
|
||||
}
|
||||
|
||||
var bytesLength = bytes.Length;
|
||||
var payloadLengthIndex = start + 2;
|
||||
start = Array.IndexOf(bytes, UI1236_START);
|
||||
|
||||
if (bytesLength <= payloadLengthIndex)
|
||||
if (start < 0)
|
||||
{
|
||||
return payload;
|
||||
return false;
|
||||
}
|
||||
|
||||
var payloadLength = bytes[payloadLengthIndex] * 2;
|
||||
length = payloadLength + IRDA_MIN_LENGTH;
|
||||
start += 1;
|
||||
|
||||
if (payloadLength <= OxOO)
|
||||
if (start >= bytes.Length)
|
||||
{
|
||||
return payload;
|
||||
return false;
|
||||
}
|
||||
|
||||
payload = new byte[payloadLength];
|
||||
var payloadStart = payloadLengthIndex + 1;
|
||||
length = bytes[start] - UI1236_HEAD_LENGTH;
|
||||
|
||||
Buffer.BlockCopy(bytes, payloadStart, payload, 0, payloadLength);
|
||||
|
||||
return payload;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>Irda structure:</para>
|
||||
/// <para> 0. .... - Start byte</para>
|
||||
/// <para> 1. .... - Direction</para>
|
||||
/// <para> 2. .... - Length / 2</para>
|
||||
/// <para>3+n. .... - Payload</para>
|
||||
/// <para>n-3. .... - aligned byte</para>
|
||||
/// <para>n-2. .... - CRC16 0 </para>
|
||||
/// <para>n-1. .... - CRC16 1 </para>
|
||||
/// </summary>
|
||||
public static byte[] FromIrdaMessage(this byte[] bytes, int start)
|
||||
{
|
||||
var bytesLength = bytes.Length;
|
||||
|
||||
if (bytes is null || bytesLength <= start)
|
||||
if (length <= 0)
|
||||
{
|
||||
return new byte[] { };
|
||||
return false;
|
||||
}
|
||||
|
||||
var _length = bytes[start + 2] * 2;
|
||||
var _start = start + 3;
|
||||
start += 2;
|
||||
|
||||
if (_start + _length >= bytesLength)
|
||||
if (start + length >= bytes.Length)
|
||||
{
|
||||
return new byte[] { };
|
||||
return false;
|
||||
}
|
||||
|
||||
var data = new byte[_length];
|
||||
message = new byte[length];
|
||||
|
||||
Buffer.BlockCopy(bytes, _start, data, 0, _length);
|
||||
Buffer.BlockCopy(bytes, start, message, 0, length);
|
||||
|
||||
return data;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static byte[] CalculateCRC8408(this byte[] message, int start, int length)
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
internal abstract class SerialDataReader : SerialDataStream
|
||||
{
|
||||
protected bool read;
|
||||
private Thread thread;
|
||||
private List<byte> stream;
|
||||
private Queue<byte[]> messages;
|
||||
protected ManualResetEventSlim awaiter;
|
||||
|
||||
protected SerialDataReader(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
}
|
||||
|
||||
public bool IsAlive
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.thread is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.thread.IsAlive;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.messages = null;
|
||||
this.stream = null;
|
||||
|
||||
this.thread?.Abort();
|
||||
this.thread = null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e.ToString());
|
||||
}
|
||||
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
protected virtual void BeginRead(byte[] bytes)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected void ClearMessages()
|
||||
{
|
||||
if (this.messages != null)
|
||||
{
|
||||
this.messages.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] DequeueMessage()
|
||||
{
|
||||
if (this.messages != null && this.messages.Count > 0)
|
||||
{
|
||||
return this.messages.Dequeue();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void EnqueueMessage(byte[] message)
|
||||
{
|
||||
if (this.messages != null)
|
||||
{
|
||||
this.messages.Enqueue(message);
|
||||
}
|
||||
}
|
||||
|
||||
protected void RemoveRange(int length)
|
||||
{
|
||||
if (this.stream != null)
|
||||
{
|
||||
this.stream.RemoveRange(0, length);
|
||||
}
|
||||
}
|
||||
|
||||
protected void StartListening()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!this.IsOpen)
|
||||
{
|
||||
base.Open();
|
||||
}
|
||||
|
||||
if (!this.IsAlive)
|
||||
{
|
||||
this.stream = new List<byte>();
|
||||
this.messages = new Queue<byte[]>();
|
||||
this.thread = new Thread(this.BeginRead);
|
||||
this.thread.Start();
|
||||
}
|
||||
|
||||
if (this.awaiter?.IsSet == true)
|
||||
{
|
||||
this.awaiter.Set();
|
||||
}
|
||||
|
||||
this.awaiter = new ManualResetEventSlim();
|
||||
this.read = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void StopListening()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.stream.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.messages.Clear();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
|
||||
this.read = false;
|
||||
this.awaiter.Set();
|
||||
}
|
||||
|
||||
private void BeginRead()
|
||||
{
|
||||
this.NotifyStateChanged($"{nameof(IrdaStream)} - reading thread started.");
|
||||
|
||||
while (this.IsAlive)
|
||||
{
|
||||
if (!this.read)
|
||||
{
|
||||
this.awaiter.Wait();
|
||||
}
|
||||
|
||||
var bytes = this.ReadBytes();
|
||||
|
||||
if (bytes.Length > 0)
|
||||
{
|
||||
this.stream.AddRange(bytes);
|
||||
}
|
||||
|
||||
this.BeginRead(this.stream?.ToArray());
|
||||
}
|
||||
|
||||
this.NotifyStateChanged($"{nameof(IrdaStream)} - reading thread stoped.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +1,36 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class SerialDataStream : SerialPortStream
|
||||
internal abstract class SerialDataStream : SerialPortStream
|
||||
{
|
||||
public SerialDataStream(SerialPortSettings settings) : base(settings)
|
||||
private readonly ManualResetEventSlim waitHandle;
|
||||
private readonly SerialDataEncoder encoder;
|
||||
private readonly List<byte> buffer;
|
||||
|
||||
private CancellationTokenSource cancellationTokenSource;
|
||||
private CancellationToken cancellationToken;
|
||||
private Task readingTask;
|
||||
|
||||
protected SerialDataStream(SerialDataEncoder encoder, SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
this.encoder = encoder;
|
||||
this.buffer = new List<byte>();
|
||||
this.waitHandle = new ManualResetEventSlim();
|
||||
}
|
||||
|
||||
protected virtual byte[] ReadBytes()
|
||||
{
|
||||
var bytes = new byte[0];
|
||||
protected event Action<byte[]> DataReceived;
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (this.IsOpen)
|
||||
if (this.cancellationTokenSource != null)
|
||||
{
|
||||
var length = this.serialPort.BytesToRead;
|
||||
|
||||
if (length > 1)
|
||||
{
|
||||
bytes = new byte[length];
|
||||
|
||||
this.serialPort.Read(bytes, 0, length);
|
||||
}
|
||||
this.cancellationTokenSource.Cancel();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -31,27 +38,161 @@
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
base.Close();
|
||||
}
|
||||
|
||||
protected virtual void WriteBytes(params byte[] bytes)
|
||||
public override void Open()
|
||||
{
|
||||
base.Open();
|
||||
|
||||
try
|
||||
{
|
||||
if (this.IsOpen)
|
||||
{
|
||||
var _lock = new object();
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
this.serialPort.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
}
|
||||
this.StartReading();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void StartListening()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.buffer.Clear();
|
||||
this.waitHandle.Set();
|
||||
this.NotifyStateChanged($"--- start listening");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void StopListening()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.waitHandle.Reset();
|
||||
this.buffer.Clear();
|
||||
this.NotifyStateChanged($"--- stop listening");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void WriteEncoded(params byte[] bytes)
|
||||
{
|
||||
this.EnsureOpened();
|
||||
|
||||
try
|
||||
{
|
||||
if (this.encoder.TryEncode(bytes, out byte[] message))
|
||||
{
|
||||
this.Write(message, 0, message.Length);
|
||||
}
|
||||
|
||||
this.NotifyStateChanged($">>> {BitConverter.ToString(bytes)}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void WritePlain(params byte[] bytes)
|
||||
{
|
||||
this.EnsureOpened();
|
||||
|
||||
try
|
||||
{
|
||||
this.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnsureOpened()
|
||||
{
|
||||
if (this.serialPort is null)
|
||||
{
|
||||
this.Open();
|
||||
}
|
||||
else if (!this.serialPort.IsOpen)
|
||||
{
|
||||
this.Close();
|
||||
this.Open();
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadingTaskHandler()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
this.waitHandle.Wait();
|
||||
|
||||
try
|
||||
{
|
||||
var size = this.serialPort.BytesToRead;
|
||||
|
||||
if (size > 0)
|
||||
{
|
||||
var buffer = new byte[size];
|
||||
|
||||
this.serialPort.Read(buffer, 0, size);
|
||||
this.buffer.AddRange(buffer);
|
||||
|
||||
var data = this.buffer.ToArray();
|
||||
|
||||
if (this.encoder.TryDecode(data, out byte[] message, out int start, out int _))
|
||||
{
|
||||
this.DataReceived?.Invoke(message);
|
||||
|
||||
this.NotifyStateChanged($"<<< {BitConverter.ToString(message)}");
|
||||
}
|
||||
|
||||
if (start < 0)
|
||||
{
|
||||
this.buffer.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.NotifyStateChanged(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void StartReading()
|
||||
{
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
this.readingTask = Task.Factory
|
||||
.StartNew(this.ReadingTaskHandler, this.cancellationToken);
|
||||
this.readingTask.ContinueWith(task =>
|
||||
{
|
||||
if (task.Exception != null)
|
||||
{
|
||||
this.NotifyStateChanged(task.Exception);
|
||||
}
|
||||
|
||||
this.StartReading();
|
||||
});
|
||||
}
|
||||
|
||||
private void Write(byte[] bytes, int start, int length)
|
||||
{
|
||||
var _lock = new object();
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
this.serialPort.Write(bytes, 0, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
|
||||
internal abstract class SerialPortStream : IDisposable
|
||||
public delegate void StateChanged(object state);
|
||||
|
||||
internal abstract class SerialPortStream
|
||||
{
|
||||
protected SerialPort serialPort;
|
||||
|
||||
@@ -11,27 +13,17 @@
|
||||
|
||||
protected SerialPortStream(SerialPortSettings settings)
|
||||
{
|
||||
if (settings is null)
|
||||
{
|
||||
throw new ArgumentNullException($"{nameof(SerialPortSettings)} are required.");
|
||||
}
|
||||
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public event StateChanged StateChanged;
|
||||
|
||||
public event Action Connected;
|
||||
public event Action Disconnected;
|
||||
public event Action<object> StateChanged;
|
||||
|
||||
public bool IsOpen
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.serialPort is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.serialPort.IsOpen;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
public virtual void Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -40,9 +32,8 @@
|
||||
this.serialPort.Close();
|
||||
this.serialPort.Dispose();
|
||||
this.serialPort = null;
|
||||
|
||||
this.NotifyStateChanged($"{this} - disposed.");
|
||||
this.Disconnected?.Invoke();
|
||||
|
||||
this.NotifyStateChanged($"--- {this} - disconnected.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -53,11 +44,6 @@
|
||||
|
||||
public virtual void Open()
|
||||
{
|
||||
if (this.serialPort != null)
|
||||
{
|
||||
this.Dispose();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
this.serialPort = new SerialPort
|
||||
@@ -67,15 +53,12 @@
|
||||
Parity = this.settings.Parity,
|
||||
PortName = this.settings.PortName,
|
||||
StopBits = this.settings.StopBits,
|
||||
DtrEnable = true
|
||||
};
|
||||
|
||||
this.serialPort.Open();
|
||||
|
||||
if (this.IsOpen)
|
||||
{
|
||||
this.NotifyStateChanged($"{this} - connected.");
|
||||
this.Connected?.Invoke();
|
||||
}
|
||||
this.NotifyStateChanged($"--- {this} - connected.");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -93,7 +76,7 @@
|
||||
$"{this.settings.Parity}, " +
|
||||
$"{this.settings.StopBits}";
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
return $"{this.serialPort.PortName}, " +
|
||||
$"{this.serialPort.BaudRate}, " +
|
||||
@@ -103,6 +86,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
public abstract byte[] Send(params byte[] message);
|
||||
|
||||
protected void NotifyStateChanged(object state)
|
||||
{
|
||||
this.StateChanged?.Invoke(state);
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
internal class UI1236Encoder : SerialDataEncoder
|
||||
{
|
||||
public override bool TryDecode(byte[] encoded, out byte[] decoded)
|
||||
{
|
||||
decoded = encoded.FromUI1236Message();
|
||||
|
||||
return decoded.Length > 0;
|
||||
}
|
||||
|
||||
public override bool TryEncode(byte[] decoded, out byte[] encoded)
|
||||
{
|
||||
encoded = decoded.ToUI1236Message();
|
||||
|
||||
return encoded.Length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
|
||||
internal class UI1236Stream : IrdaStream
|
||||
{
|
||||
private readonly string fileName;
|
||||
private readonly UI1236Encoder encoder;
|
||||
|
||||
public UI1236Stream(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
var directiry = Directory.CreateDirectory(".\\UI1236");
|
||||
this.fileName = Path.Combine(directiry.FullName, $"[{settings.PortName}].txt");
|
||||
this.encoder = new UI1236Encoder();
|
||||
|
||||
File.AppendAllText(Path.Combine(directiry.FullName, $"[{settings.PortName}].txt"), string.Empty);
|
||||
|
||||
this.StateChanged += this.UI1236Stream_StateChanged;
|
||||
}
|
||||
|
||||
public byte[] Write(params byte[] bytes)
|
||||
{
|
||||
this.LogToFile($">>> {BitConverter.ToString(bytes)}");
|
||||
this.StartListening();
|
||||
|
||||
Thread.Sleep(500);
|
||||
|
||||
this.WriteBytes(bytes);
|
||||
|
||||
var response = new byte[0];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
var message = this.DequeueMessage();
|
||||
|
||||
if (message != null)
|
||||
{
|
||||
if (this.encoder.TryDecode(message, out response))
|
||||
{
|
||||
this.ClearMessages();
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
if (response.Length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
this.LogToFile($"<<< {BitConverter.ToString(response)}");
|
||||
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
|
||||
this.StopListening();
|
||||
|
||||
this.LogToFile($"<<< {BitConverter.ToString(response)}");
|
||||
this.LogToFile(string.Empty);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
protected override void WriteBytes(params byte[] bytes)
|
||||
{
|
||||
if (this.encoder.TryEncode(bytes, out byte[] message))
|
||||
{
|
||||
base.WriteBytes(message);
|
||||
}
|
||||
}
|
||||
|
||||
private void LogToFile(string value)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.AppendAllText(this.fileName, $"{value}{Environment.NewLine}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void UI1236Stream_StateChanged(object state)
|
||||
{
|
||||
this.LogToFile($"{state}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
internal class UniProEncoder : SerialDataEncoder
|
||||
{
|
||||
public object Device2PC { get; } = SerialDataExtensions.UNIPRO_REG2PC;
|
||||
|
||||
public override bool TryDecode(byte[] encoded, out byte[] decoded)
|
||||
{
|
||||
decoded = encoded.FromUniProMessage();
|
||||
|
||||
return decoded.Length > 0;
|
||||
}
|
||||
|
||||
public override bool TryEncode(byte[] decoded, out byte[] encoded)
|
||||
{
|
||||
encoded = decoded.FromUniProMessage();
|
||||
|
||||
return encoded.Length > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
namespace OmniPlus.Connections
|
||||
{
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
internal class UniProStream : SerialDataReader
|
||||
{
|
||||
private readonly UniProEncoder encoder;
|
||||
|
||||
public UniProStream(SerialPortSettings settings) : base(settings)
|
||||
{
|
||||
this.encoder = new UniProEncoder();
|
||||
}
|
||||
|
||||
public byte[] Write(params byte[] bytes)
|
||||
{
|
||||
this.StartListening();
|
||||
this.WriteBytes(bytes);
|
||||
|
||||
var response = new byte[0];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
var message = this.DequeueMessage();
|
||||
|
||||
if (message != null)
|
||||
{
|
||||
if (this.encoder.TryDecode(message, out response))
|
||||
{
|
||||
this.ClearMessages();
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
}
|
||||
|
||||
if (response.Length > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
|
||||
this.StopListening();
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
protected override void WriteBytes(params byte[] bytes)
|
||||
{
|
||||
if (this.encoder.TryEncode(bytes, out byte[] message))
|
||||
{
|
||||
base.WriteBytes(message);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void BeginRead(byte[] buffer)
|
||||
{
|
||||
var start = Array.IndexOf(buffer, this.encoder.Device2PC);
|
||||
|
||||
if (start >= 0)
|
||||
{
|
||||
if (this.encoder.TryDecode(buffer, out byte[] message))
|
||||
{
|
||||
this.EnqueueMessage(message);
|
||||
this.RemoveRange(message.Length);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.RemoveRange(buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,8 +29,9 @@
|
||||
public void ToASCIIString(byte[] buffer, int start, int end)
|
||||
{
|
||||
var value = string.Empty;
|
||||
var length = buffer.Length;
|
||||
|
||||
while (start <= end)
|
||||
while (start < length && start <= end)
|
||||
{
|
||||
value += (char)buffer[start];
|
||||
start++;
|
||||
@@ -62,13 +63,12 @@
|
||||
{
|
||||
var buffer = ASCII.GetBytes(value);
|
||||
var bufferLength = buffer.Length;
|
||||
var i = 0;
|
||||
var bufferIndex = 0;
|
||||
var i = 1;
|
||||
|
||||
while (i < this.length && i < bufferLength)
|
||||
{
|
||||
this.bytes[i] = buffer[i];
|
||||
|
||||
i++;
|
||||
this.bytes[i++] = buffer[bufferIndex++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,9 +88,9 @@
|
||||
get => this.programmableID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 0, 20);
|
||||
this.SetASCIIBytes(value, 1, 20);
|
||||
|
||||
this.programmableID = this.bytes.ToASCIIString(0, 20);
|
||||
this.programmableID = this.bytes.ToASCIIString(1, 20);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,9 +105,9 @@
|
||||
get => this.factoryID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 21, 13);
|
||||
this.SetASCIIBytes(value, 22, 33);
|
||||
|
||||
this.factoryID = this.bytes.ToASCIIString(21, 13);
|
||||
this.factoryID = this.bytes.ToASCIIString(22, 33);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,9 +139,9 @@
|
||||
get => this.readingPreset;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 38, 9);
|
||||
this.SetASCIIBytes(value, 39, 47);
|
||||
|
||||
this.readingPreset = this.bytes.ToASCIIString(38, 9);
|
||||
this.readingPreset = this.bytes.ToASCIIString(36, 47);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,9 +240,9 @@
|
||||
get => this.buildInfo;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 64, 14);
|
||||
this.SetASCIIBytes(value, 65, 79);
|
||||
|
||||
this.buildInfo = this.bytes.ToASCIIString(64, 14);
|
||||
this.buildInfo = this.bytes.ToASCIIString(65, 79);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,13 +257,13 @@
|
||||
get => this.deviceID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 80, 9);
|
||||
this.SetASCIIBytes(value, 81, 89);
|
||||
|
||||
this.deviceID = this.bytes.ToASCIIString(80, 9);
|
||||
this.deviceID = this.bytes.ToASCIIString(81, 89);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetASCIIBytes(string value, int start, int length)
|
||||
private void SetASCIIBytes(string value, int start, int end)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
@@ -276,9 +276,7 @@
|
||||
var asciiLength = asciiBytes.Length;
|
||||
var asciiIndex = 0;
|
||||
|
||||
length += start;
|
||||
|
||||
while (start >= 0 && start < length && asciiIndex < asciiLength)
|
||||
while (start >= 0 && start <= end && asciiIndex < asciiLength)
|
||||
{
|
||||
this.bytes[start++] = asciiBytes[asciiIndex++];
|
||||
}
|
||||
|
||||
@@ -28,6 +28,6 @@
|
||||
set => this.SecondsSince = (uint)(value - epoch).TotalSeconds;
|
||||
}
|
||||
|
||||
public static uint UTCNow => new Epoch20000101 { DateTime = DateTime.UtcNow }.SecondsSince + 10;
|
||||
public static uint UTCNow => new Epoch20000101 { DateTime = DateTime.UtcNow }.SecondsSince + 3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
this.Status = (Status)response[0];
|
||||
}
|
||||
|
||||
if (responseLength > this.length)
|
||||
if (responseLength > 1)
|
||||
{
|
||||
Array.Copy(response, 1, this.bytes, 0, this.length);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
internal class Features
|
||||
public class Features
|
||||
{
|
||||
/// <summary>
|
||||
/// The View Factory ID command shall cause the slave device to transmit the factory ID.
|
||||
|
||||
@@ -86,11 +86,11 @@
|
||||
return subarray;
|
||||
}
|
||||
|
||||
public static string ToASCIIString(this byte[] bytes, int start, int length)
|
||||
public static string ToASCIIString(this byte[] bytes, int start, int end)
|
||||
{
|
||||
var asciiString = string.Empty;
|
||||
|
||||
while (start >= 0 && start < bytes.Length)
|
||||
while (start >= 0 && end < bytes.Length && start < end)
|
||||
{
|
||||
asciiString += (char)bytes[start++];
|
||||
}
|
||||
|
||||
@@ -44,6 +44,6 @@
|
||||
set => this.bytes[5] = value;
|
||||
}
|
||||
|
||||
public double MlPerRotation { get; set; }
|
||||
public ushort IntPartFull => BitConverter.ToUInt16(this.bytes, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
using OmniPlus.Features.Enums;
|
||||
using System.Text;
|
||||
|
||||
/// <summary>
|
||||
/// Versions B1.24 of this command are supported. Total Forward and Total Reverse are not supported.
|
||||
@@ -18,10 +19,14 @@
|
||||
/// </summary>
|
||||
public class ReadingPreset : FeatureRequest
|
||||
{
|
||||
const int LENGTH = 2;
|
||||
const int LENGTH = 11;
|
||||
|
||||
public ReadingPreset() : base(LENGTH)
|
||||
{
|
||||
for (int i = 2; i < 11; i++)
|
||||
{
|
||||
this.bytes[i] = (byte)'0';
|
||||
}
|
||||
}
|
||||
|
||||
public byte SensorID
|
||||
|
||||
@@ -52,14 +52,54 @@
|
||||
|
||||
public byte FlowUnits
|
||||
{
|
||||
get => this.bytes[8].GetUint8(0, 4);
|
||||
set => FeaturesExtensions.SetUint8(ref this.bytes[8], 0, 4, value);
|
||||
get
|
||||
{
|
||||
var src = this.bytes[8].GetBits();
|
||||
var dst = new byte[8];
|
||||
|
||||
Array.Copy(src, 0, dst, 0, 4);
|
||||
|
||||
return dst.ToUint8();
|
||||
}
|
||||
set
|
||||
{
|
||||
var srcIndex = 0;
|
||||
var srcBits = value.GetBits();
|
||||
var dstBits = this.bytes[8].GetBits();
|
||||
|
||||
for (int dstIndex = 0; dstIndex < 4; dstIndex++)
|
||||
{
|
||||
dstBits[dstIndex] = srcBits[srcIndex++];
|
||||
}
|
||||
|
||||
this.bytes[8] = dstBits.ToUint8();
|
||||
}
|
||||
}
|
||||
|
||||
public byte FlowRate
|
||||
{
|
||||
get => this.bytes[8].GetUint8(4, 4);
|
||||
set => FeaturesExtensions.SetUint8(ref this.bytes[8], 4, 4, value);
|
||||
get
|
||||
{
|
||||
var src = this.bytes[8].GetBits();
|
||||
var dst = new byte[8];
|
||||
|
||||
Array.Copy(src, 4, dst, 0, 4);
|
||||
|
||||
return dst.ToUint8();
|
||||
}
|
||||
set
|
||||
{
|
||||
var srcIndex = 0;
|
||||
var srcBits = value.GetBits();
|
||||
var dstBits = this.bytes[8].GetBits();
|
||||
|
||||
for (int dstIndex = 4; dstIndex < 8; dstIndex++)
|
||||
{
|
||||
dstBits[dstIndex] = srcBits[srcIndex++];
|
||||
}
|
||||
|
||||
this.bytes[8] = dstBits.ToUint8();
|
||||
}
|
||||
}
|
||||
|
||||
public sbyte FactoryCorrection
|
||||
@@ -82,14 +122,54 @@
|
||||
|
||||
public byte PulseWidth
|
||||
{
|
||||
get => this.bytes[12].GetUint8(0, 3);
|
||||
set => FeaturesExtensions.SetUint8(ref this.bytes[12], 0, 3, value);
|
||||
get
|
||||
{
|
||||
var src = this.bytes[12].GetBits();
|
||||
var dst = new byte[8];
|
||||
|
||||
Array.Copy(src, 0, dst, 0, 3);
|
||||
|
||||
return dst.ToUint8();
|
||||
}
|
||||
set
|
||||
{
|
||||
var srcIndex = 0;
|
||||
var srcBits = value.GetBits();
|
||||
var dstBits = this.bytes[12].GetBits();
|
||||
|
||||
for (int dstIndex = 0; dstIndex < 3; dstIndex++)
|
||||
{
|
||||
dstBits[dstIndex] = srcBits[srcIndex++];
|
||||
}
|
||||
|
||||
this.bytes[12] = dstBits.ToUint8();
|
||||
}
|
||||
}
|
||||
|
||||
public byte PulseUpdate
|
||||
{
|
||||
get => this.bytes[12].GetUint8(3, 3);
|
||||
set => FeaturesExtensions.SetUint8(ref this.bytes[12], 3, 3, value);
|
||||
get
|
||||
{
|
||||
var src = this.bytes[12].GetBits();
|
||||
var dst = new byte[8];
|
||||
|
||||
Array.Copy(src, 3, dst, 0, 3);
|
||||
|
||||
return dst.ToUint8();
|
||||
}
|
||||
set
|
||||
{
|
||||
var srcIndex = 0;
|
||||
var srcBits = value.GetBits();
|
||||
var dstBits = this.bytes[12].GetBits();
|
||||
|
||||
for (int dstIndex = 3; dstIndex < 6; dstIndex++)
|
||||
{
|
||||
dstBits[dstIndex] = srcBits[srcIndex++];
|
||||
}
|
||||
|
||||
this.bytes[12] = dstBits.ToUint8();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
namespace OmniPlus.Inspection
|
||||
{
|
||||
using System;
|
||||
|
||||
internal static class OmniPlusExtensions
|
||||
{
|
||||
public static double MlPerRotation(byte intPart, ushort fraction, short correctionFactor)
|
||||
=> (intPart + (double)fraction / ushort.MaxValue) * correctionFactor;
|
||||
|
||||
public static double GPM2M3H(double value)
|
||||
=> value * 3785.411784 / 1000 / 1000 * 60;
|
||||
|
||||
public static double GetCorrectionFactor(this double[] points)
|
||||
{
|
||||
if (points?.Length != 3)
|
||||
{
|
||||
return double.MinValue;
|
||||
}
|
||||
|
||||
var min = points[0];
|
||||
var mid = points[1];
|
||||
var max = points[2];
|
||||
|
||||
if (Math.Abs(mid - max) <= 3 && Math.Max(mid, max) - min <= 6.5)
|
||||
{
|
||||
var avgMidMax = (mid + max) / 2;
|
||||
|
||||
if (100 - avgMidMax + min < 95)
|
||||
{
|
||||
return 95 - min;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 100 - avgMidMax;
|
||||
}
|
||||
}
|
||||
|
||||
return double.MaxValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,21 +4,85 @@
|
||||
|
||||
public static class OmniPlusFormulas
|
||||
{
|
||||
public static double MlPerRotation(byte intPart, ushort fraction, short correctionFactor)
|
||||
public static double MilliliterPerRotation(byte intPart, ushort fraction, short correctionFactor)
|
||||
{
|
||||
return (intPart + (double)fraction / ushort.MaxValue) * correctionFactor;
|
||||
const int FRACTION_FACTOR = ushort.MaxValue + 1;
|
||||
const int PULSES_PER_ROTATION = 8;
|
||||
|
||||
var fractionPart = (double)fraction / FRACTION_FACTOR;
|
||||
var mlPlain = intPart + fractionPart;
|
||||
var mlPulse = intPart + fractionPart;
|
||||
var mlr = mlPulse * PULSES_PER_ROTATION;
|
||||
|
||||
return mlr;
|
||||
}
|
||||
|
||||
public static double GPM2M3H(double value)
|
||||
public static double MilliliterPerRotation(this OmniPlusType type)
|
||||
{
|
||||
return value * 3785.411784 / 1000 / 1000 * 60;
|
||||
return MilliliterPerRotation(type.IntPart, type.Fraction, type.CorrectionFactor);
|
||||
}
|
||||
|
||||
public static double GPM2M3H(this double gal_min)
|
||||
{
|
||||
const double ML_IN_GAL = 3785.411784;
|
||||
|
||||
var ml_min = gal_min * ML_IN_GAL;
|
||||
var l_min = ml_min / 1000;
|
||||
var m3_min = l_min / 1000;
|
||||
var m3_h = m3_min * 60;
|
||||
|
||||
return m3_h;
|
||||
}
|
||||
|
||||
public static ushort DurationInSeconds(this ushort rotations, double mlr, double flowM3H)
|
||||
{
|
||||
var ml_h = flowM3H * 1000 * 1000;
|
||||
var ml_s = ml_h / 3600;
|
||||
var s_r = mlr / ml_s * 100;
|
||||
var duration = s_r * rotations;
|
||||
|
||||
return (ushort)(Math.Truncate(duration) + 1);
|
||||
}
|
||||
|
||||
public static ushort ResponseFlowM3H(this ushort rotations, double mlr, double flowM3H)
|
||||
{
|
||||
var ml_h = flowM3H * 1000 * 1000;
|
||||
var ml_s = ml_h / 3600;
|
||||
var s_r = mlr / ml_s * 100;
|
||||
var duration = s_r * rotations;
|
||||
|
||||
return (ushort)(Math.Truncate(duration) + 1);
|
||||
}
|
||||
|
||||
public static double DifferencePercentage(this OmniPlusTest test)
|
||||
{
|
||||
try
|
||||
{
|
||||
return 100 + (test.MeterFlowM3S - test.ReferenceFlowM3S) / test.ReferenceFlowM3S * 100;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static double MeterFlowM3S(double rotations, double mlr, double duration)
|
||||
{
|
||||
var seconds = duration * (1D / (short.MaxValue + 1));
|
||||
|
||||
return rotations * mlr / seconds / 1000D / 1000D * 100;
|
||||
}
|
||||
|
||||
public static double MeterFlowM3S(this OmniPlusTestPoint point, OmniPlusTest test)
|
||||
{
|
||||
return MeterFlowM3S(test.Rotations, point.MLR, test.Duration);
|
||||
}
|
||||
|
||||
public static double GetCorrectionFactor(this double[] points)
|
||||
{
|
||||
if (points?.Length != 3)
|
||||
if (points is null || points.Length != 3)
|
||||
{
|
||||
return double.MinValue;
|
||||
return -1;
|
||||
}
|
||||
|
||||
var min = points[0];
|
||||
@@ -39,7 +103,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
return double.MaxValue;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,23 +6,8 @@
|
||||
|
||||
public double Duration { get; set; }
|
||||
|
||||
public double MeterVolume { get; set; }
|
||||
public double MeterFlowM3S { get; set; }
|
||||
|
||||
public double VolumeMessured { get; set; }
|
||||
|
||||
public double DifferencePercentage
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
return 100 + (this.MeterVolume - this.VolumeMessured) / this.VolumeMessured;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
public double ReferenceFlowM3S { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -4,9 +4,29 @@
|
||||
|
||||
public struct OmniPlusTestPoint : IComparable<OmniPlusTestPoint>
|
||||
{
|
||||
public double GalPerMin { get; set; }
|
||||
private double gpm;
|
||||
public double GPM
|
||||
{
|
||||
get => this.gpm;
|
||||
set
|
||||
{
|
||||
this.gpm = value;
|
||||
this.RequiredFlowM3H = this.gpm.GPM2M3H();
|
||||
}
|
||||
}
|
||||
|
||||
public ushort Rotations { get; set; }
|
||||
public ushort rotations;
|
||||
public ushort Rotations
|
||||
{
|
||||
get => this.rotations;
|
||||
set
|
||||
{
|
||||
this.rotations = value;
|
||||
this.Duration = this.rotations.DurationInSeconds(this.MLR, this.RequiredFlowM3H);
|
||||
}
|
||||
}
|
||||
|
||||
public double MLR { get; set; }
|
||||
|
||||
public ushort Duration { get; set; }
|
||||
|
||||
@@ -14,25 +34,11 @@
|
||||
|
||||
public double MaxDiff { get; set; }
|
||||
|
||||
public double MlPerRotation { get; set; }
|
||||
public double RequiredFlowM3H { get; private set; }
|
||||
|
||||
public double VolumeM3H
|
||||
=> OmniPlusExtensions.GPM2M3H(this.GalPerMin);
|
||||
|
||||
public int CompareTo(OmniPlusTestPoint other)
|
||||
=> this.Rotations.CompareTo(other.Rotations);
|
||||
|
||||
public double VolumeM3(double rotations, double duration)
|
||||
public int CompareTo(OmniPlusTestPoint other)
|
||||
{
|
||||
var seconds = duration / 32768;
|
||||
var milliliter = rotations * this.MlPerRotation;
|
||||
|
||||
return seconds * milliliter / 1000 / 1000;
|
||||
}
|
||||
|
||||
public double VolumeM3(OmniPlusTest test)
|
||||
{
|
||||
return this.VolumeM3(test.Rotations, test.Duration);
|
||||
return this.GPM.CompareTo(other.GPM);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -42,18 +42,6 @@
|
||||
|
||||
public short CorrectionFactor { get; set; }
|
||||
|
||||
public double MlPerRotation
|
||||
{
|
||||
get
|
||||
{
|
||||
var mlPerRotation = OmniPlusExtensions.MlPerRotation(this.IntPart, this.Fraction, this.CorrectionFactor);
|
||||
|
||||
this.InputVolume.MlPerRotation = mlPerRotation;
|
||||
|
||||
return OmniPlusExtensions.MlPerRotation(this.IntPart, this.Fraction, this.CorrectionFactor);
|
||||
}
|
||||
}
|
||||
|
||||
public InputVolume InputVolume { get; }
|
||||
= new InputVolume();
|
||||
|
||||
|
||||
+14
-61
@@ -1,73 +1,19 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using OmniPlus.Connections;
|
||||
using OmniPlus.Features;
|
||||
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
|
||||
using static OmniPlus.Features.Features;
|
||||
|
||||
internal delegate byte[] MessageHandler(params byte[] bytes);
|
||||
public delegate byte[] MessageHandler(params byte[] bytes);
|
||||
public delegate void StateChanged(object state);
|
||||
|
||||
public sealed class OmniPlusConnection
|
||||
public abstract class OmniConnection
|
||||
{
|
||||
private Func<bool> connected;
|
||||
private readonly UI1236Stream ui1236;
|
||||
private readonly UniProStream unipro;
|
||||
protected MessageHandler MessageHandler { get; set; }
|
||||
|
||||
public OmniPlusConnection(string portName)
|
||||
{
|
||||
this.ui1236 = new UI1236Stream(new SerialPortSettings
|
||||
{
|
||||
BaudRate = 115200,
|
||||
DataBits = 8,
|
||||
Parity = Parity.None,
|
||||
PortName = portName,
|
||||
StopBits = StopBits.One
|
||||
});
|
||||
this.unipro = new UniProStream(new SerialPortSettings
|
||||
{
|
||||
BaudRate = 2400,
|
||||
DataBits = 8,
|
||||
Parity = Parity.None,
|
||||
PortName = portName,
|
||||
StopBits = StopBits.One
|
||||
});
|
||||
}
|
||||
public abstract void Close();
|
||||
|
||||
internal MessageHandler MessageHandler;
|
||||
|
||||
public bool Connected
|
||||
=> this.connected?.Invoke() ?? false;
|
||||
|
||||
public bool ConnectIrda()
|
||||
{
|
||||
this.unipro.Dispose();
|
||||
this.ui1236.Open();
|
||||
|
||||
this.connected = () => this.ui1236.IsOpen;
|
||||
this.MessageHandler = this.ui1236.Write;
|
||||
|
||||
return this.ui1236.IsOpen;
|
||||
}
|
||||
|
||||
public bool ConnectUniPro()
|
||||
{
|
||||
this.ui1236.Dispose();
|
||||
this.unipro.Open();
|
||||
|
||||
this.connected = () => this.unipro.IsOpen;
|
||||
this.MessageHandler = this.unipro.Write;
|
||||
|
||||
return this.unipro.IsOpen;
|
||||
}
|
||||
|
||||
public void Disconnect()
|
||||
{
|
||||
this.unipro.Dispose();
|
||||
this.ui1236.Dispose();
|
||||
}
|
||||
public abstract void Open();
|
||||
|
||||
public FactoryID ViewFactoryID()
|
||||
{
|
||||
@@ -132,7 +78,7 @@
|
||||
return new RateResolution(response);
|
||||
}
|
||||
|
||||
public Readings ViewReadings(Readings reading)
|
||||
public Readings ViewReadings()
|
||||
{
|
||||
var response = this.MessageHandler.Invoke(VIEW_READINGS);
|
||||
|
||||
@@ -153,6 +99,13 @@
|
||||
return new BuildInfo(response);
|
||||
}
|
||||
|
||||
public ChamberCalibrationResponse Set(ChamberCalibrationRequest chamberCalibrationRequest)
|
||||
{
|
||||
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, CHAMBER_CALIBRATION);
|
||||
|
||||
return new ChamberCalibrationResponse(response);
|
||||
}
|
||||
|
||||
public SystemParameters ViewSystemParameters()
|
||||
{
|
||||
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, VIEW_SYSTEM_PARAMETERS);
|
||||
+6
-6
@@ -8,11 +8,11 @@
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
public class OmniPlusDatabase
|
||||
public class OmniDatabase
|
||||
{
|
||||
private readonly string connectionString;
|
||||
|
||||
public OmniPlusDatabase(string omniDatabase)
|
||||
public OmniDatabase(string omniDatabase)
|
||||
=> this.connectionString = omniDatabase;
|
||||
|
||||
public void AddOrUpdate(int position, SystemParameters parameters)
|
||||
@@ -144,7 +144,7 @@
|
||||
omniType.Direction = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.IntPart = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.Fraction = (ushort)sqlDataReader.GetValue<int>(field++);
|
||||
omniType.PulsePerRotation = sqlDataReader.GetValue<double>(field++);
|
||||
omniType.PulsePerRotation = sqlDataReader.GetValue<byte>(field++);
|
||||
omniType.CorrectionFactor = sqlDataReader.GetValue<short>(field++);
|
||||
}
|
||||
}
|
||||
@@ -168,7 +168,7 @@
|
||||
|
||||
using (var sqlDataReader = sqlCommand.ExecuteReader())
|
||||
{
|
||||
var mlPerRotation = omniType.MlPerRotation;
|
||||
var milliliterPerRotation = omniType.MilliliterPerRotation();
|
||||
|
||||
while (sqlDataReader.Read())
|
||||
{
|
||||
@@ -176,8 +176,8 @@
|
||||
|
||||
omniType.TestPoints.Add(new OmniPlusTestPoint
|
||||
{
|
||||
MlPerRotation = mlPerRotation,
|
||||
GalPerMin = sqlDataReader.GetValue<double>(field++),
|
||||
MLR = milliliterPerRotation,
|
||||
GPM = sqlDataReader.GetValue<double>(field++),
|
||||
Rotations = (ushort)sqlDataReader.GetValue<short>(field++),
|
||||
Duration = (ushort)sqlDataReader.GetValue<short>(field++),
|
||||
MinDiff = sqlDataReader.GetValue<double>(field++),
|
||||
@@ -0,0 +1,30 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using OmniPlus.Connections;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
|
||||
public sealed class OmniIrdaConnection : OmniConnection
|
||||
{
|
||||
private readonly OmniIrdaStream stream;
|
||||
private readonly string stateFile;
|
||||
|
||||
public OmniIrdaConnection(string portName)
|
||||
{
|
||||
this.stateFile = this.GetOrCreateStateFile(portName);
|
||||
this.stream = new OmniIrdaStream(
|
||||
encoder: new OmniIrdaEncoder(),
|
||||
settings: new SerialPortSettings
|
||||
{
|
||||
BaudRate = 115200,
|
||||
DataBits = 8,
|
||||
Parity = Parity.None,
|
||||
PortName = portName,
|
||||
StopBits = StopBits.One
|
||||
});
|
||||
this.stream.StateChanged += this.OnStateChanged;
|
||||
this.MessageHandler = this.stream.Send;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
this.stream.Close();
|
||||
}
|
||||
|
||||
public override void Open()
|
||||
{
|
||||
this.stream.Open();
|
||||
}
|
||||
|
||||
private void OnStateChanged(object state)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.AppendAllText(this.stateFile, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fffffff}] {state}{Environment.NewLine}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.AppendAllText(this.stateFile, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fffffff}] {e}");
|
||||
}
|
||||
catch (Exception _)
|
||||
{
|
||||
// TODO: throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string GetOrCreateStateFile(string portName)
|
||||
{
|
||||
var stateFile = $"{portName}_{DateTime.Now:yyyy_MM_dd}.txt";
|
||||
var directory = Directory.CreateDirectory(".\\OmniIrda");
|
||||
stateFile = Path.Combine(directory.FullName, stateFile);
|
||||
|
||||
File.AppendAllText(stateFile, string.Empty);
|
||||
|
||||
return stateFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
public class OmniMeter
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -46,19 +46,16 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Connections\IrdaEncoder.cs" />
|
||||
<Compile Include="Connections\IrdaStream.cs" />
|
||||
<Compile Include="Connections\Program.cs" />
|
||||
<Compile Include="Connections\OmniIrdaEncoder.cs" />
|
||||
<Compile Include="Connections\OmniIrdaStream.cs" />
|
||||
<Compile Include="Connections\OmniUniProEncoder.cs" />
|
||||
<Compile Include="Connections\OmniUniProStream.cs" />
|
||||
<Compile Include="Connections\SerialDataEncoder.cs" />
|
||||
<Compile Include="Connections\SerialDataExtensions.cs" />
|
||||
<Compile Include="Connections\SerialDataReader.cs" />
|
||||
<Compile Include="Connections\SerialDataStream.cs" />
|
||||
<Compile Include="Connections\SerialPortSettings.cs" />
|
||||
<Compile Include="Connections\SerialPortStream.cs" />
|
||||
<Compile Include="Connections\UI1236Encoder.cs" />
|
||||
<Compile Include="Connections\UI1236Stream.cs" />
|
||||
<Compile Include="Connections\UniProEncoder.cs" />
|
||||
<Compile Include="Connections\UniProStream.cs" />
|
||||
<Compile Include="Connections\UI1236Control.cs" />
|
||||
<Compile Include="Features\Enums\MessurementUnits.cs" />
|
||||
<Compile Include="Features\Enums\ReadingSettings.cs" />
|
||||
<Compile Include="Features\Enums\Status.cs" />
|
||||
@@ -98,14 +95,16 @@
|
||||
<Compile Include="Features\SystemTime.cs" />
|
||||
<Compile Include="Features\VersionAndType.cs" />
|
||||
<Compile Include="Inspection\OmniPlusFormulas.cs" />
|
||||
<Compile Include="OmniPlusConnection.cs" />
|
||||
<Compile Include="OmniPlusConnectionsPool.cs" />
|
||||
<Compile Include="OmniPlusDatabase.cs" />
|
||||
<Compile Include="Inspection\OmniPlusExtensions.cs" />
|
||||
<Compile Include="OmniConnection.cs" />
|
||||
<Compile Include="OmniExchange.cs" />
|
||||
<Compile Include="OmniIrdaEOL.cs" />
|
||||
<Compile Include="OmniIrdaConnection.cs" />
|
||||
<Compile Include="OmniMeter.cs" />
|
||||
<Compile Include="OmniDatabase.cs" />
|
||||
<Compile Include="Inspection\OmniPlusTest.cs" />
|
||||
<Compile Include="Inspection\OmniPlusTestPoint.cs" />
|
||||
<Compile Include="Inspection\OmniPlusType.cs" />
|
||||
<Compile Include="Connections\UI1236Control.cs" />
|
||||
<Compile Include="OmniUniProConnection.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -115,6 +114,11 @@
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ExchangeHub\ExchangeHub.csproj">
|
||||
<Project>{6033FF0C-CF32-4BC5-8EFE-4774CCDC663D}</Project>
|
||||
<Name>ExchangeHub</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,498 +0,0 @@
|
||||
using OmniPlus.Features;
|
||||
using OmniPlus.Inspection;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.ComponentModel;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace OmniPlus
|
||||
{
|
||||
public class OmniPlusConnectionsPool : IDisposable
|
||||
{
|
||||
public event Action Done;
|
||||
|
||||
private readonly ConcurrentDictionary<int, OmniPlusConnection> connections;
|
||||
private readonly ConcurrentDictionary<int, OmniPlusMeter> meters;
|
||||
private readonly CancellationTokenSource cancellationTokenSource;
|
||||
private readonly CancellationToken cancellationToken;
|
||||
private readonly OmniPlusExchangeSlave exchangeSlave;
|
||||
private readonly OmniPlusDatabase database;
|
||||
private readonly OmniPlusType omniType;
|
||||
|
||||
private byte size;
|
||||
private string variant;
|
||||
private BackgroundWorker background;
|
||||
|
||||
public OmniPlusConnectionsPool(string dbConnectionString, string signalRURL)
|
||||
{
|
||||
this.connections = new ConcurrentDictionary<int, OmniPlusConnection>();
|
||||
this.meters = new ConcurrentDictionary<int, OmniPlusMeter>();
|
||||
this.cancellationTokenSource = new CancellationTokenSource();
|
||||
this.exchangeSlave = new OmniPlusExchangeSlave(signalRURL);
|
||||
this.database = new OmniPlusDatabase(dbConnectionString);
|
||||
this.omniType = new OmniPlusType();
|
||||
|
||||
this.size = 5;
|
||||
this.variant = "C2";
|
||||
this.cancellationToken = this.cancellationTokenSource.Token;
|
||||
this.cancellationToken.Register(this.CancellationCallback);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.exchangeSlave.Dispose();
|
||||
|
||||
// Disposes all OmniPlus connections.
|
||||
foreach (var connectionKVP in this.connections)
|
||||
{
|
||||
connectionKVP.Value?.Disconnect();
|
||||
}
|
||||
|
||||
// Clears collected connections and their meters.
|
||||
this.connections.Clear();
|
||||
this.meters.Clear();
|
||||
}
|
||||
|
||||
public void InitializeInspection(params string[] portNames)
|
||||
{
|
||||
OmniPlusConnection connection;
|
||||
OmniPlusMeter meter;
|
||||
int position = 1;
|
||||
bool connected;
|
||||
|
||||
foreach (var portName in portNames)
|
||||
{
|
||||
connection = new OmniPlusConnection(portName);
|
||||
connected = connection.ConnectIrda();
|
||||
|
||||
if (connected)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
connection.Disconnect();
|
||||
connection = default(OmniPlusConnection);
|
||||
meter = default(OmniPlusMeter);
|
||||
}
|
||||
|
||||
this.connections.TryAdd(position, connection);
|
||||
|
||||
position++;
|
||||
}
|
||||
|
||||
this.database.LoadOmniDefaults(this.size, this.variant, this.omniType);
|
||||
}
|
||||
|
||||
public void CancelExecution()
|
||||
=> this.cancellationTokenSource.Cancel(false);
|
||||
|
||||
//public void StartInspection()
|
||||
//{
|
||||
// foreach (var position in this.connections.Keys)
|
||||
// {
|
||||
// this.StartOmniInitialization(position);
|
||||
|
||||
// //foreach (var point in this.omniType.TestPoints)
|
||||
// //{
|
||||
// // this.StartOmniInspection(position, point);
|
||||
// //}
|
||||
|
||||
// //this.CalculateCorrectionFactor(position);
|
||||
|
||||
// this.FinishOmniInspection(position);
|
||||
// }
|
||||
//}
|
||||
|
||||
public void StartInspection()
|
||||
{
|
||||
this.background = new BackgroundWorker();
|
||||
|
||||
this.background.DoWork += this.StartInspection;
|
||||
|
||||
this.background.RunWorkerAsync();
|
||||
}
|
||||
|
||||
private void StartInspection(object sender, EventArgs args)
|
||||
{
|
||||
var connectionsCount = this.connections.Count;
|
||||
var tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.StartOmniInitialization(position), this.cancellationToken);
|
||||
}
|
||||
|
||||
foreach (var point in this.omniType.TestPoints)
|
||||
{
|
||||
// TODO: 600 = 10min * 60sec - change for production.
|
||||
|
||||
//if (!this.exchangeSlave.SetQAndWaitUntilReached(point.VolumeM3H))
|
||||
//{
|
||||
// this.CancelExecution();
|
||||
|
||||
// break;
|
||||
//}
|
||||
|
||||
tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.StartOmniInspection(position, point), this.cancellationToken);
|
||||
}
|
||||
|
||||
//var volume = this.exchangeSlave.RequestRefV();
|
||||
|
||||
//foreach (var position in this.connections.Keys)
|
||||
//{
|
||||
// this.SetPointDifference(position, point, volume);
|
||||
//}
|
||||
}
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
this.CalculateCorrectionFactor(position);
|
||||
}
|
||||
|
||||
tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.FinishOmniInspection(position), this.cancellationToken);
|
||||
}
|
||||
|
||||
this.Done?.Invoke();
|
||||
}
|
||||
|
||||
private void StartOmniInitialization(int position)
|
||||
{
|
||||
if (this.TryGetOmni(position, out var connection, out var meter))
|
||||
{
|
||||
var systemParameters = connection.ViewSystemParameters();
|
||||
|
||||
// connection.Set(this.omniType.InputVolume).Succeeded;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void StartOmniInspection(int position, OmniPlusTestPoint point)
|
||||
{
|
||||
var header = $"{point.VolumeM3H:0.0000}m³/h";
|
||||
|
||||
if (this.TryGetOmni(position, out var connection, out var meter) /*&& meter.Initialized && meter.CanCalibrate*/)
|
||||
{
|
||||
var activationResponse = connection.StartChamberCalibration(point.Rotations, point.Duration);
|
||||
|
||||
if (activationResponse.Succeeded)
|
||||
{
|
||||
var calibrationResult = new ChamberCalibrationResponse();
|
||||
var duration = point.Duration + 3;
|
||||
|
||||
this.NotifyWhileThreadSleep(position, header, point.Duration + 3);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
calibrationResult = connection.ViewChamberCalibration();
|
||||
|
||||
if (calibrationResult.Succeeded)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
else // activation failed
|
||||
{
|
||||
}
|
||||
}
|
||||
else // not connected
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPointDifference(int position, OmniPlusTestPoint point, double volume)
|
||||
{
|
||||
//var header = $"{point.VolumeM3H:0.0000}m³/h";
|
||||
|
||||
//if (this.TryGetOmni(position, out var _, out var meter) && meter.Initialized && meter.CanCalibrate)
|
||||
//{
|
||||
// var difference = meter.AddCalibrationVolume(point, volume);
|
||||
|
||||
// this.StateChanged?.Invoke(position, 0, header, $"{difference:0.00}%");
|
||||
//}
|
||||
//else // not connected
|
||||
//{
|
||||
// this.StateChanged?.Invoke(position, 0, header, null);
|
||||
//}
|
||||
}
|
||||
|
||||
private void CalculateCorrectionFactor(int position)
|
||||
{
|
||||
//if (this.TryGetOmni(position, out var _, out var meter) && meter.Initialized && meter.CanCalibrate)
|
||||
//{
|
||||
// var correctionFactor = meter.GetCorrectionFactor();
|
||||
|
||||
// this.StateChanged?.Invoke(position, meter.CanCalibrate ? 1 : -1, CORRECTION, $"{correctionFactor:0.00}%");
|
||||
//}
|
||||
//else // not connected
|
||||
//{
|
||||
// this.StateChanged?.Invoke(position, 0, CORRECTION, null);
|
||||
//}
|
||||
}
|
||||
|
||||
private void FinishOmniInspection(int position)
|
||||
{
|
||||
//if (this.TryGetOmni(position, out var connection, out var meter)/* && meter.Calibrated*/)
|
||||
//{
|
||||
// var configurationParameters = connection.ViewConfigurationParameters();
|
||||
// var canContinue = configurationParameters.Succeeded;
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// meter.AddConfigurationParameters(configurationParameters);
|
||||
// this.database.AddOrUpdate(position, configurationParameters);
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// // TODO: Uncomment in production
|
||||
// //var systemTimeReset = connection.SetSystemTime();
|
||||
// //canContinue = systemTimeReset.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var registerSettings = new RegisterSettings();
|
||||
|
||||
// registerSettings.IntPart = this.omniType.IntPart;
|
||||
// registerSettings.Fraction = this.omniType.Fraction;
|
||||
// registerSettings.Size = this.omniType.Size;
|
||||
// registerSettings.Range = this.omniType.Range;
|
||||
// registerSettings.VolumePerPulseUnit = 0x00;
|
||||
// registerSettings.MeterUnits = (byte)MessurementUnits.USGallons;
|
||||
// registerSettings.FlowUnits = (byte)MessurementUnits.USGallons;
|
||||
// registerSettings.FlowRate = (byte)TimeUnits.Minutes;
|
||||
// registerSettings.FactoryCorrection = meter.FactoryCorrection;
|
||||
// registerSettings.FieldCorrection = 0x00;
|
||||
// registerSettings.PulseWeight = 0x01;
|
||||
// registerSettings.PulseWidth = 0x02;
|
||||
// registerSettings.PulseUpdate = 0x00;
|
||||
|
||||
// var response = connection.Set(registerSettings);
|
||||
// canContinue = response.Succeeded;
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// meter.AddRegisterSettings(registerSettings);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var configurationParametersSet = new ConfigurationParametersSet();
|
||||
// configurationParametersSet.ProgrammableID = "816232411983";
|
||||
// configurationParametersSet.FactoryID = "816232411983";
|
||||
// configurationParametersSet.NumberOfReadingDigits = 8; // meter.ReadingDigits;
|
||||
// configurationParametersSet.ReadingPreset = "000000000";
|
||||
// configurationParametersSet.OptionalUniDirFields = 1; // meter.OptionalUniDirFields;
|
||||
// configurationParametersSet.AlarmPercistancePeriodDays = 31;
|
||||
// configurationParametersSet.DataLogIntervalMinutes = 60;
|
||||
// configurationParametersSet.ManifacturingTime = Epoch20000101.UTCNow - 30000; // meter.ManifacturingTime;
|
||||
// configurationParametersSet.SystemTime = Epoch20000101.UTCNow;
|
||||
// configurationParametersSet.RebootCount = 0;
|
||||
// configurationParametersSet.BuildInfo = "816232411983"; // meter.BuildInfo;
|
||||
// // configurationParametersSet.DeviceID = "OMNI-01";
|
||||
|
||||
// var response = connection.Set(configurationParametersSet);
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ClearDisplay();
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.Set(new LeakAlarm
|
||||
// {
|
||||
// FlowRateGal = 0.25F, // 0.25 gpm
|
||||
// TimeLimit = 24 * 60 * 60 // 24 hours => 86400sec
|
||||
// });
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.Set(new HighFlowAlarm
|
||||
// {
|
||||
// FlowRateGal = 25F, // 25 gpm
|
||||
// TimeLimit = 1 * 60 * 60 // 1 hours => 86400sec
|
||||
// });
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.Set(new ReverseFlowAlarm
|
||||
// {
|
||||
// FlowRateGal = -1F, // -1 gpm
|
||||
// TimeLimit = 60 // 1 hours => 86400sec
|
||||
// });
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ClearAlarms();
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var alarmsState = connection.ViewAlarmsState();
|
||||
// canContinue = alarmsState.Succeeded;
|
||||
// //&& alarmsState.UsrEnabled
|
||||
// //&& alarmsState.PreEnabledInactive;
|
||||
// //TODO: Check alarms
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.EnableNFC();
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var registerSettingsAfter = connection.ViewRegisterSettings();
|
||||
// canContinue = registerSettingsAfter.Succeeded
|
||||
// && meter.Compare(registerSettingsAfter);
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var systemParametersAfter = connection.ViewSystemParameters();
|
||||
// canContinue = systemParametersAfter.Succeeded;
|
||||
// //&& meter.Compare(systemParametersAfter);
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var configurationParametersAfter = connection.ViewConfigurationParameters();
|
||||
// canContinue = configurationParametersAfter.Succeeded;
|
||||
// //&& meter.Compare(configurationParametersAfter);
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var alarmsState = connection.ViewAlarmsState();
|
||||
// canContinue = alarmsState.Succeeded;
|
||||
// //&& alarmsState.UsrEnabled
|
||||
// //&& alarmsState.PreEnabledInactive;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ViewAlarmSettings(0x01);
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ViewAlarmSettings(0x02);
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// var response = connection.ViewAlarmSettings(0x04);
|
||||
// canContinue = response.Succeeded;
|
||||
// }
|
||||
|
||||
// if (canContinue)
|
||||
// {
|
||||
// //connection.Set(new FactorySeal
|
||||
// //{
|
||||
// // Sealed = true,
|
||||
// //});
|
||||
|
||||
// //var factorySeal = connection.ViewFactorySeal();
|
||||
// //canContinue = factorySeal.Succeeded && factorySeal.Sealed;
|
||||
// }
|
||||
//}
|
||||
//else // meter or connection not in use
|
||||
//{
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns only connected connections and meters.
|
||||
/// </summary>
|
||||
/// <param name="position">The position of connection and meter.</param>
|
||||
/// <param name="connection"><see cref="OmniPlusConnection"/></param>
|
||||
/// <param name="meter"><see cref="OmniPlusMeter"/></param>
|
||||
/// <returns>Returns true if connection and meter are found and are not null and the meter is connected, otherwise false.</returns>
|
||||
private bool TryGetOmni(int position, out OmniPlusConnection connection, out OmniPlusMeter meter)
|
||||
{
|
||||
var connectionFound = this.connections.TryGetValue(position, out connection);
|
||||
var meterFound = this.meters.TryGetValue(position, out meter);
|
||||
|
||||
return connectionFound
|
||||
&& connection != null
|
||||
&& meterFound
|
||||
&& meter != null;
|
||||
}
|
||||
|
||||
private void NotifyWhileThreadSleep(int position, string header, int duration)
|
||||
{
|
||||
//var seconds = 0;
|
||||
//var timer = new System.Timers.Timer(1000)
|
||||
//{
|
||||
// Enabled = true,
|
||||
// AutoReset = true,
|
||||
//};
|
||||
//timer.Elapsed += (_, _1) =>
|
||||
//{
|
||||
// this.StateChanged?.Invoke(position, 0, header, $"{seconds++}/{duration}");
|
||||
//};
|
||||
|
||||
//timer.Start();
|
||||
|
||||
//Thread.Sleep(duration * 1000);
|
||||
|
||||
//timer.Stop();
|
||||
}
|
||||
|
||||
private void CancellationCallback()
|
||||
{
|
||||
// TODO: Update database.
|
||||
this.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal class OmniPlusExchangeSlave
|
||||
{
|
||||
private String signalRURL;
|
||||
|
||||
public OmniPlusExchangeSlave(String signalRURL)
|
||||
{
|
||||
this.signalRURL = signalRURL;
|
||||
}
|
||||
|
||||
internal void Dispose()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
internal class OmniPlusMeter
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -45,119 +45,37 @@ CREATE TABLE [OmniTestPoints] (
|
||||
INSERT INTO [OmniTestPoints]
|
||||
([OmniTypeId], [OmniVariant], [GalPerMin], [Rotations], [Duration], [MinDiff], [MaxDiff])
|
||||
------------------------------------------------------------------------------------------
|
||||
VALUES ( 1, 'C2', 200.00, 900, 36, NULL, NULL)
|
||||
, ( 1, 'C2', 160.00, 700, 35, 98.5, 101.5)
|
||||
, ( 1, 'C2', 150.00, 600, 32, NULL, NULL)
|
||||
, ( 1, 'C2', 2.50, 10, 32, NULL, NULL)
|
||||
, ( 1, 'C2', 2.00, 8, 32, NULL, NULL)
|
||||
, ( 1, 'C2', 1.50, 6, 32, NULL, NULL)
|
||||
, ( 1, 'C2', 1.25, 6, 38, NULL, NULL)
|
||||
VALUES ( 1, 'C2', 160.00, 700, 35, 98.5, 101.5)
|
||||
, ( 1, 'C2', 1.00, 4, 32, 98.5, 101.5)
|
||||
, ( 1, 'C2', 0.75, 4, 43, NULL, NULL)
|
||||
, ( 1, 'C2', 0.25, 4, 127, 95.0, 101.5)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 1, 'F2', 200.00, 900, 36, NULL, NULL)
|
||||
, ( 1, 'F2', 160.00, 700, 35, 98.5, 101.5)
|
||||
, ( 1, 'F2', 150.00, 600, 32, NULL, NULL)
|
||||
, ( 1, 'F2', 2.50, 10, 32, NULL, NULL)
|
||||
, ( 1, 'F2', 2.00, 8, 32, NULL, NULL)
|
||||
, ( 1, 'F2', 1.50, 6, 32, NULL, NULL)
|
||||
, ( 1, 'F2', 1.25, 6, 38, NULL, NULL)
|
||||
, ( 1, 'F2', 160.00, 700, 35, 98.5, 101.5)
|
||||
, ( 1, 'F2', 1.00, 4, 32, 98.5, 101.5)
|
||||
, ( 1, 'F2', 0.75, 4, 43, NULL, NULL)
|
||||
, ( 1, 'F2', 0.25, 4, 127, 95.0, 101.5)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 1, 'R2', 200.00, 900, 36, NULL, NULL)
|
||||
, ( 1, 'R2', 160.00, 700, 35, NULL, NULL)
|
||||
, ( 1, 'R2', 150.00, 600, 32, 98.5, 101.5)
|
||||
, ( 1, 'R2', 2.50, 10, 32, NULL, NULL)
|
||||
, ( 1, 'R2', 2.00, 8, 32, 98.5, 101.5)
|
||||
, ( 1, 'R2', 1.50, 6, 32, NULL, NULL)
|
||||
, ( 1, 'R2', 1.25, 6, 38, NULL, NULL)
|
||||
, ( 1, 'R2', 1.00, 4, 32, NULL, NULL)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 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, 'R2', 0.25, 4, 127, NULL, NULL)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 1, 'T2', 200.00, 900, 36, NULL, NULL)
|
||||
, ( 1, 'T2', 160.00, 700, 35, 98.5, 101.5)
|
||||
, ( 1, 'T2', 150.00, 600, 32, NULL, NULL)
|
||||
, ( 1, 'T2', 2.50, 10, 32, NULL, NULL)
|
||||
, ( 1, 'T2', 2.00, 8, 32, NULL, NULL)
|
||||
, ( 1, 'T2', 1.50, 6, 32, NULL, NULL)
|
||||
, ( 1, 'T2', 160.00, 700, 35, 98.5, 101.5)
|
||||
, ( 1, 'T2', 1.25, 6, 38, 98.5, 101.5)
|
||||
, ( 1, 'T2', 1.00, 4, 32, NULL, NULL)
|
||||
, ( 1, 'T2', 0.75, 4, 43, 95.0, 101.5)
|
||||
, ( 1, 'T2', 0.25, 4, 127, NULL, NULL)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 2, 'C2', 200.00, 1000, 40, NULL, NULL)
|
||||
, ( 2, 'C2', 160.00, 800, 40, 98.5, 101.5)
|
||||
, ( 2, 'C2', 2.50, 10, 32, NULL, NULL)
|
||||
, ( 2, 'C2', 1.50, 8, 43, NULL, NULL)
|
||||
, ( 2, 'C2', 1.00, 4, 32, 98.5, 101.5)
|
||||
, ( 2, 'C2', 0.25, 4, 127, 95.0, 101.5)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 2, 'F2', 200.00, 1000, 40, NULL, NULL)
|
||||
, ( 2, 'F2', 160.00, 800, 40, 98.5, 101.5)
|
||||
, ( 2, 'F2', 2.50, 10, 32, NULL, NULL)
|
||||
, ( 2, 'F2', 1.50, 8, 43, NULL, NULL)
|
||||
, ( 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', 160.00, 800, 40, NULL, NULL)
|
||||
, ( 2, 'R2', 2.50, 10, 32, 98.5, 101.5)
|
||||
, ( 2, 'R2', 1.50, 8, 43, NULL, NULL)
|
||||
, ( 2, 'R2', 1.00, 4, 32, 95.0, 101.5)
|
||||
, ( 2, 'R2', 0.25, 4, 127, NULL, NULL)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 2, 'T2', 200.00, 1000, 40, 98.5, 101.5)
|
||||
, ( 2, 'T2', 160.00, 800, 40, NULL, NULL)
|
||||
, ( 2, 'T2', 2.50, 10, 32, NULL, NULL)
|
||||
, ( 2, 'T2', 1.50, 8, 43, 98.5, 101.5)
|
||||
, ( 2, 'T2', 1.00, 4, 32, 95.0, 101.5)
|
||||
, ( 2, 'T2', 0.25, 4, 127, NULL, NULL)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 3, NULL, 500.00, 700, 38, NULL, NULL)
|
||||
, ( 3, NULL, 400.00, 580, 40, NULL, NULL)
|
||||
, ( 3, NULL, 350.00, 450, 35, NULL, NULL)
|
||||
, ( 3, NULL, 20.00, 30, 41, NULL, NULL)
|
||||
, ( 3, NULL, 10.00, 16, 44, NULL, NULL)
|
||||
, ( 3, NULL, 2.50, 4, 44, NULL, NULL)
|
||||
, ( 3, NULL, 2.00, 4, 55, NULL, NULL)
|
||||
, ( 3, NULL, 1.50, 4, 73, NULL, NULL)
|
||||
, ( 3, NULL, 0.50, 4, 217, NULL, NULL)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 4, NULL, 1000.00, 1200, 33, NULL, NULL)
|
||||
, ( 4, NULL, 800.00, 1100, 38, NULL, NULL)
|
||||
, ( 4, NULL, 30.00, 40, 37, NULL, NULL)
|
||||
, ( 4, NULL, 3.00, 4, 37, NULL, NULL)
|
||||
, ( 4, NULL, 2.00, 4, 55, NULL, NULL)
|
||||
, ( 4, NULL, 1.50, 4, 73, NULL, NULL)
|
||||
, ( 4, NULL, 0.75, 4, 145, NULL, NULL)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 5, NULL, 2000.00, 800, 39, NULL, NULL)
|
||||
, ( 5, NULL, 1600.00, 660, 40, NULL, NULL)
|
||||
, ( 5, NULL, 50.00, 20, 39, NULL, NULL)
|
||||
, ( 5, NULL, 5.00, 4, 77, NULL, NULL)
|
||||
, ( 5, NULL, 4.00, 4, 96, NULL, NULL)
|
||||
, ( 5, NULL, 3.00, 4, 127, NULL, NULL)
|
||||
, ( 5, NULL, 2.50, 4, 153, NULL, NULL)
|
||||
, ( 5, NULL, 1.50, 4, 254, NULL, NULL)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 6, NULL, 3500.00, 500, 34, NULL, NULL)
|
||||
, ( 6, NULL, 2700.00, 400, 36, NULL, NULL)
|
||||
, ( 6, NULL, 7.00, 4, 136, NULL, NULL)
|
||||
, ( 6, NULL, 5.00, 4, 191, NULL, NULL)
|
||||
, ( 6, NULL, 4.00, 4, 238, NULL, NULL)
|
||||
, ( 6, NULL, 3.00, 4, 317, NULL, NULL)
|
||||
, ( 6, NULL, 2.50, 4, 381, NULL, NULL)
|
||||
------------------------------------------------------------------------------------------
|
||||
, ( 7, NULL, 5500.00, 550, 36, NULL, NULL)
|
||||
, ( 7, NULL, 4000.00, 400, 36, NULL, NULL)
|
||||
, ( 7, NULL, 2500.00, 260, 37, NULL, NULL)
|
||||
, ( 7, NULL, 14.00, 4, 102, NULL, NULL)
|
||||
, ( 7, NULL, 5.00, 4, 284, NULL, NULL)
|
||||
, ( 7, NULL, 3.50, 4, 406, NULL, NULL);
|
||||
, ( 2, 'T2', 1.00, 4, 32, 95.0, 101.5);
|
||||
|
||||
CREATE TABLE [OmniTestStates] (
|
||||
[Position] INT NOT NULL,
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using OmniPlus.Connections;
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
|
||||
public class OmniUniProConnection : OmniConnection
|
||||
{
|
||||
private readonly OmniUniProStream stream;
|
||||
private readonly string stateFile;
|
||||
|
||||
public OmniUniProConnection(string portName)
|
||||
{
|
||||
this.stateFile = this.GetOrCreateStateFile(portName);
|
||||
this.stream = new OmniUniProStream(
|
||||
encoder: new OmniUniProEncoder(),
|
||||
settings: new SerialPortSettings
|
||||
{
|
||||
BaudRate = 2400,
|
||||
DataBits = 8,
|
||||
Parity = Parity.None,
|
||||
PortName = portName,
|
||||
StopBits = StopBits.One
|
||||
});
|
||||
this.stream.StateChanged += this.OnStateChanged;
|
||||
this.MessageHandler = this.stream.Send;
|
||||
}
|
||||
|
||||
public override void Close()
|
||||
{
|
||||
this.stream.Close();
|
||||
}
|
||||
|
||||
public override void Open()
|
||||
{
|
||||
this.stream.Open();
|
||||
}
|
||||
|
||||
private void OnStateChanged(object state)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.AppendAllText(this.stateFile, $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff}] {state}{Environment.NewLine}");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
// TODO: throw;
|
||||
}
|
||||
}
|
||||
|
||||
private string GetOrCreateStateFile(string portName)
|
||||
{
|
||||
var stateFile = $"{portName}_{DateTime.Now:yyyy_MM_dd}.txt";
|
||||
var directory = Directory.CreateDirectory(".\\OmniUniPro");
|
||||
stateFile = Path.Combine(directory.FullName, stateFile);
|
||||
|
||||
File.AppendAllText(stateFile, string.Empty);
|
||||
|
||||
return stateFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user