progress over omnis
This commit is contained in:
@@ -26,7 +26,7 @@ namespace OmniPlus
|
||||
var response = new byte[0];
|
||||
var received = false;
|
||||
|
||||
if (command is null)
|
||||
if (command?.Length <= 0)
|
||||
{
|
||||
return response;
|
||||
}
|
||||
@@ -36,22 +36,31 @@ namespace OmniPlus
|
||||
response = bytes
|
||||
.FromIrdaMessage()
|
||||
.FromUI1236Message();
|
||||
received = true;
|
||||
|
||||
this.InvokeLogMessage($"RX: {BitConverter.ToString(response)}");
|
||||
|
||||
received = response.Length > 0 && response[0] > 0;
|
||||
|
||||
if (received)
|
||||
{
|
||||
this.MessageReceived -= MessageReceivedHandler;
|
||||
}
|
||||
}
|
||||
|
||||
this.MessageReceived += MessageReceivedHandler;
|
||||
|
||||
this.Write(1, 1, 1, 1);
|
||||
|
||||
var request = command
|
||||
.ToUI1236Message()
|
||||
.ToIrdaMessage();
|
||||
var sleep = 5000;
|
||||
var delay = 500;
|
||||
|
||||
this.Write(1, 1, 1, 1);
|
||||
Thread.Sleep(1);
|
||||
this.Write(request);
|
||||
this.InvokeLogMessage($"TX: {BitConverter.ToString(command)}");
|
||||
|
||||
while (!received && sleep >= 0)
|
||||
while (!received /*&& sleep >= 0*/)
|
||||
{
|
||||
sleep -= delay;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ using OmniPlus.Options;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
|
||||
namespace OmniPlus
|
||||
{
|
||||
@@ -16,6 +17,7 @@ namespace OmniPlus
|
||||
|
||||
private SerialPort serialPort;
|
||||
private SerialPortState state;
|
||||
private Thread readingThread;
|
||||
|
||||
protected SerialPortConnection()
|
||||
=> this.Options = new SerialPortOptions();
|
||||
@@ -26,11 +28,20 @@ namespace OmniPlus
|
||||
|
||||
public virtual void Close()
|
||||
{
|
||||
try
|
||||
{
|
||||
this.readingThread?.Abort();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.LogMessage?.Invoke(e.ToString());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (this.serialPort != null)
|
||||
{
|
||||
this.serialPort.DataReceived -= this.SerialPort_DataReceived;
|
||||
// this.serialPort.DataReceived -= this.SerialPort_DataReceived;
|
||||
this.serialPort.Disposed -= this.SerialPort_Disposed;
|
||||
this.serialPort.ErrorReceived -= this.SerialPort_ErrorReceived;
|
||||
this.serialPort.PinChanged -= this.SerialPort_PinChanged;
|
||||
@@ -42,6 +53,7 @@ namespace OmniPlus
|
||||
catch (Exception e)
|
||||
{
|
||||
this.StateChanged?.Invoke(SerialPortState.ErrorReceived, e.ToString());
|
||||
this.LogMessage?.Invoke(e.ToString());
|
||||
}
|
||||
|
||||
this.serialPort = null;
|
||||
@@ -64,9 +76,9 @@ namespace OmniPlus
|
||||
{
|
||||
foreach (var @delegate in this.StateChanged.GetInvocationList())
|
||||
{
|
||||
if (@delegate is LogMessageEventHandler eventHandler)
|
||||
if (@delegate is StateChangedEventHandler eventHandler)
|
||||
{
|
||||
this.LogMessage -= eventHandler;
|
||||
this.StateChanged -= eventHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,9 +87,9 @@ namespace OmniPlus
|
||||
{
|
||||
foreach (var @delegate in this.DataReceived.GetInvocationList())
|
||||
{
|
||||
if (@delegate is LogMessageEventHandler eventHandler)
|
||||
if (@delegate is DataReceivedHandler eventHandler)
|
||||
{
|
||||
this.LogMessage -= eventHandler;
|
||||
this.DataReceived -= eventHandler;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -101,6 +113,7 @@ namespace OmniPlus
|
||||
this.state = SerialPortState.ErrorReceived;
|
||||
|
||||
this.StateChanged?.Invoke(this.state, $"{this.Options.PortName}: {e}");
|
||||
this.LogMessage?.Invoke(e.ToString());
|
||||
}
|
||||
|
||||
try
|
||||
@@ -116,7 +129,7 @@ namespace OmniPlus
|
||||
DtrEnable = this.Options.DtrEnabled
|
||||
};
|
||||
|
||||
this.serialPort.DataReceived += this.SerialPort_DataReceived;
|
||||
// this.serialPort.DataReceived += this.SerialPort_DataReceived;
|
||||
this.serialPort.Disposed += this.SerialPort_Disposed;
|
||||
this.serialPort.ErrorReceived += this.SerialPort_ErrorReceived;
|
||||
this.serialPort.PinChanged += this.SerialPort_PinChanged;
|
||||
@@ -133,34 +146,106 @@ namespace OmniPlus
|
||||
+ $", {this.Options.DataBits}"
|
||||
+ $", {this.Options.Parity}"
|
||||
+ $", {this.Options.StopBits}");
|
||||
|
||||
if (this.serialPort.IsOpen)
|
||||
{
|
||||
this.readingThread = new Thread(this.SerialPortConnectionBeginRead);
|
||||
this.readingThread.Start(this.serialPort.BaseStream);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.state = SerialPortState.ErrorReceived;
|
||||
|
||||
this.StateChanged?.Invoke(this.state, $"{this.Options.PortName}: {e}");
|
||||
this.LogMessage?.Invoke(e.ToString());
|
||||
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
protected void InvokeLogMessage(string message)
|
||||
=> this.LogMessage?.Invoke(message);
|
||||
|
||||
protected void Write(params byte[] message)
|
||||
{
|
||||
if (this.Connected && message.Length > 0)
|
||||
{
|
||||
this.serialPort.Write(message, 0, message.Length);
|
||||
lock (this.serialPort)
|
||||
{
|
||||
this.serialPort.Write(message, 0, message.Length);
|
||||
}
|
||||
}
|
||||
|
||||
this.LogMessage?.Invoke($"TX: {BitConverter.ToString(message)}");
|
||||
}
|
||||
|
||||
protected abstract void SerialPortConnection_DataReceived(byte[] bytes);
|
||||
|
||||
private void SerialPortConnectionBeginRead(object parameter)
|
||||
{
|
||||
if (parameter is Stream stream && stream.CanRead)
|
||||
{
|
||||
byte[] data;
|
||||
byte[] buffer = new byte[128];
|
||||
AsyncCallback endReadHandler = _asyncResult =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_asyncResult.AsyncState is Stream _stream)
|
||||
{
|
||||
var bytesReaded = _stream.EndRead(_asyncResult);
|
||||
|
||||
if (bytesReaded > 0)
|
||||
{
|
||||
data = new byte[bytesReaded];
|
||||
|
||||
Array.Copy(buffer, 0, data, 0, bytesReaded);
|
||||
|
||||
this.DataReceived?.Invoke(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
this.LogMessage?.Invoke(e.ToString());
|
||||
}
|
||||
};
|
||||
|
||||
while (stream.CanRead)
|
||||
{
|
||||
stream
|
||||
.BeginRead(buffer, 0, buffer.Length, endReadHandler, stream)
|
||||
.AsyncWaitHandle
|
||||
.WaitOne();
|
||||
}
|
||||
}
|
||||
|
||||
this.Close();
|
||||
}
|
||||
|
||||
protected void SerialPortConnection_LogMessage(string message)
|
||||
=> File.AppendAllText(this.Options.LogFile, $"{message}{Environment.NewLine}");
|
||||
{
|
||||
try
|
||||
{
|
||||
File.AppendAllText(this.Options.LogFile, $"{message}{Environment.NewLine}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void SerialPortConnection_StateChanged(SerialPortState state, string message)
|
||||
=> File.AppendAllText(this.Options.LogFile, $"[{state}] {message}{Environment.NewLine}");
|
||||
{
|
||||
try
|
||||
{
|
||||
File.AppendAllText(this.Options.LogFile, $"[{state}] {message}{Environment.NewLine}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void SerialPort_PinChanged(object sender, SerialPinChangedEventArgs args)
|
||||
{
|
||||
@@ -189,21 +274,21 @@ namespace OmniPlus
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs args)
|
||||
{
|
||||
if (this.Connected && sender is SerialPort port && port.BytesToRead > 0)
|
||||
{
|
||||
var bytes = new byte[port.BytesToRead];
|
||||
var lock_object = new object();
|
||||
/// <summary>
|
||||
/// TODO: investigate the usage of port.Read... (may be its wrong)
|
||||
/// New approach implemented whit the base stream. See above!
|
||||
/// </summary>
|
||||
//private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs args)
|
||||
//{
|
||||
// if (this.Connected && sender is SerialPort port)
|
||||
// {
|
||||
// var bytes = new byte[port.BytesToRead];
|
||||
|
||||
lock (lock_object)
|
||||
{
|
||||
port.Read(bytes, 0, port.BytesToRead);
|
||||
}
|
||||
|
||||
this.DataReceived?.Invoke(bytes);
|
||||
this.LogMessage?.Invoke($"RX: {BitConverter.ToString(bytes)}");
|
||||
}
|
||||
}
|
||||
// port.Read(bytes, 0, port.BytesToRead);
|
||||
|
||||
// this.DataReceived?.Invoke(bytes);
|
||||
// this.LogMessage?.Invoke($"RX: {BitConverter.ToString(bytes)}");
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ namespace OmniPlus
|
||||
this.MessageReceived += MessageReceivedHandler;
|
||||
|
||||
var request = command.ToUniProMessage();
|
||||
var sleep = 5000;
|
||||
var delay = 500;
|
||||
var sleep = 33000;
|
||||
var delay = 1000;
|
||||
|
||||
this.Write(request);
|
||||
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
using System.Text;
|
||||
using System;
|
||||
using static System.Text.Encoding;
|
||||
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
public class ASCIIString : FeatureRequest
|
||||
{
|
||||
protected const char NULL = '\0';
|
||||
|
||||
public ASCIIString(int length) : base(length)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public ASCIIString(string value, int length) : base(length)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
value = value.Trim(NULL);
|
||||
|
||||
if (value.Length > length - 2)
|
||||
{
|
||||
value = value.Substring(0, length - 2);
|
||||
}
|
||||
|
||||
this.Value = $"{NULL}{value}{NULL}";
|
||||
}
|
||||
}
|
||||
|
||||
public ASCIIString(byte[] response, int length) : base(response, length)
|
||||
{
|
||||
|
||||
@@ -20,18 +38,48 @@
|
||||
set => this.SetValue(value);
|
||||
}
|
||||
|
||||
public void ToASCIIString(byte[] buffer, int start, int end)
|
||||
{
|
||||
var value = string.Empty;
|
||||
|
||||
while (start <= end)
|
||||
{
|
||||
value += (char)buffer[start];
|
||||
start++;
|
||||
}
|
||||
|
||||
this.SetValue(value);
|
||||
}
|
||||
|
||||
private string GetValue()
|
||||
=> Encoding.ASCII
|
||||
.GetString(this.bytes)
|
||||
.Trim();
|
||||
{
|
||||
if (this.bytes?.Length > 0)
|
||||
{
|
||||
return ASCII
|
||||
.GetString(this.bytes)
|
||||
.Trim('\0');
|
||||
}
|
||||
|
||||
return default(string);
|
||||
}
|
||||
|
||||
private void SetValue(string value)
|
||||
{
|
||||
this.bytes.Clear();
|
||||
|
||||
Encoding.ASCII
|
||||
.GetBytes(value?.Trim('\0', ' ') ?? string.Empty)
|
||||
.CopyTo(this.bytes, 0);
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
var buffer = ASCII.GetBytes(value);
|
||||
var bufferLength = buffer.Length;
|
||||
var i = 0;
|
||||
|
||||
while (i < this.length && i < bufferLength)
|
||||
{
|
||||
this.bytes[i] = buffer[i];
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
{
|
||||
}
|
||||
|
||||
public static implicit operator BuildInfo(string value)
|
||||
=> new BuildInfo
|
||||
{
|
||||
Value = value,
|
||||
};
|
||||
public BuildInfo(string value) : base(value, LENGTH)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static implicit operator BuildInfo(string value)
|
||||
=> new BuildInfo { Value = value };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
public class ChamberCalibration : FeatureRequest
|
||||
{
|
||||
public const byte ACTIVATE_TEST = 0x00;
|
||||
public const byte REQUEST_RESULTS = 0x01;
|
||||
|
||||
public const byte TEST_ACTIVATED = 0x00;
|
||||
public const byte TEST_FAILED = 0x01;
|
||||
public const byte TEST_COMPLETED = 0x02;
|
||||
|
||||
const int LENGTH = 5;
|
||||
|
||||
public ChamberCalibration() : base(LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
public ChamberCalibration(byte[] response) : base(response, LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Request Response
|
||||
/// 0 – Activate Factory Calibration Test Test Activation Successful
|
||||
/// 1 – Request Factory Calibration Test Results Test Failed (Timeout)
|
||||
/// 2 - ........................................ Test Successfully Completed
|
||||
/// </summary>
|
||||
public byte Control
|
||||
{
|
||||
get => this.bytes[0];
|
||||
set => this.bytes[0] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Request: Number of Rotations to collect. (not required if Requesting Calibration results) (Limited to 1 to 5000 rotations)
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Response: Number of rotations collected
|
||||
/// On Test Activation, this field echoes the number of rotations requested.
|
||||
/// On Test Failed and Test Successfully Completed, returns the number of rotations collected.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public ushort Rotations
|
||||
{
|
||||
get => BitConverter.ToUInt16(this.bytes, 1);
|
||||
set => BitConverter.GetBytes(value).CopyTo(this.bytes, 1);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Request: Maximum Time command is supposed to take to execute - 1 to 3600 Seconds.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Response: Total Time it took to collect the indicated rotations. Each count is equal to 30.5176us.
|
||||
/// On Test Activation Successful, returns number of seconds test is allowed to take.
|
||||
/// On Test Failed, this field will show 0 indicating that the tested failed.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public ushort Duration
|
||||
{
|
||||
get => BitConverter.ToUInt16(this.bytes, 3);
|
||||
set => BitConverter.GetBytes(value).CopyTo(this.bytes, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
using System;
|
||||
using System.Text;
|
||||
|
||||
public class ConfigurationParameters : FeatureRequest
|
||||
{
|
||||
@@ -20,11 +21,11 @@
|
||||
{
|
||||
this.ProgrammableID = new ProgrammableID();
|
||||
this.ProgrammableID.Status = this.Status;
|
||||
this.ProgrammableID.Value = this.bytes.ToASCIIString(0, 20);
|
||||
this.ProgrammableID.ToASCIIString(this.bytes, 0, 20);
|
||||
|
||||
this.FactoryID = new FactoryID();
|
||||
this.FactoryID.Status = this.Status;
|
||||
this.FactoryID.Value = this.bytes.ToASCIIString(21, 33);
|
||||
this.FactoryID.ToASCIIString(this.bytes, 21, 33);
|
||||
|
||||
this.ReadingDigits = new ReadingDigits();
|
||||
this.ReadingDigits.Status = this.Status;
|
||||
@@ -33,18 +34,18 @@
|
||||
|
||||
this.Readings = new Readings();
|
||||
this.Readings.Status = this.Status;
|
||||
this.Readings.Value = this.bytes.ToASCIIString(36, 45);
|
||||
this.Readings.ToASCIIString(this.bytes, 36, 45);
|
||||
|
||||
this.OptionalUniDirFields = new OptionalUniDirFields();
|
||||
this.OptionalUniDirFields.Status = this.Status;
|
||||
this.OptionalUniDirFields.Value = this.bytes.ToASCIIString(46, 49);
|
||||
this.OptionalUniDirFields.ToASCIIString(this.bytes, 46, 49);
|
||||
|
||||
this.AlartPersistenceDays = this.bytes[50];
|
||||
this.AlarmPersistenceDays = this.bytes[50];
|
||||
this.DataLogIntervalMins = BitConverter.ToUInt16(this.bytes, 51);
|
||||
|
||||
this.DeviceID = new DeviceID();
|
||||
this.DeviceID.Status = this.Status;
|
||||
this.DeviceID.Value = this.bytes.ToASCIIString(53, 61);
|
||||
this.DeviceID.ToASCIIString(this.bytes, 53, 61);
|
||||
}
|
||||
|
||||
public ProgrammableID ProgrammableID { get; set; }
|
||||
@@ -57,18 +58,221 @@
|
||||
|
||||
public OptionalUniDirFields OptionalUniDirFields { get; set; }
|
||||
|
||||
public byte AlartPersistenceDays { get; set; }
|
||||
public byte AlarmPersistenceDays { get; set; }
|
||||
|
||||
public ushort DataLogIntervalMins { get; set; }
|
||||
|
||||
public DeviceID DeviceID { get; set; }
|
||||
}
|
||||
|
||||
public ManifacturingTime ManifacturingTime { private get; set; }
|
||||
public class ConfigurationParametersSet : FeatureRequest
|
||||
{
|
||||
const int LENGTH = 85;
|
||||
|
||||
public SystemTime SystemTime { private get; set; }
|
||||
public ConfigurationParametersSet() : base(LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
public byte RebootCount { private get; set; }
|
||||
private ConfigurationParametersSet(byte[] response) : base(response, LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
public BuildInfo BuildInfo { private get; set; }
|
||||
/// <summary>
|
||||
/// <para>0 - 20</para>
|
||||
/// Set Programmable ID request, string is padded and terminated with '\0'
|
||||
/// +1
|
||||
/// </summary>
|
||||
private string programmableID;
|
||||
public string ProgrammableID
|
||||
{
|
||||
get => this.programmableID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 0, 20);
|
||||
|
||||
this.programmableID = this.bytes.ToASCIIString(0, 20);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>21 - 33</para>
|
||||
/// Set Factory ID request, string padded and terminated with '\0'
|
||||
/// +1
|
||||
/// </summary>
|
||||
private string factoryID;
|
||||
public string FactoryID
|
||||
{
|
||||
get => this.factoryID;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 21, 13);
|
||||
|
||||
this.factoryID = this.bytes.ToASCIIString(21, 13);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>34 - 35</para>
|
||||
/// Set Number of Reading Digits request
|
||||
/// </summary>
|
||||
private sbyte nrOfReadingDigits;
|
||||
public sbyte NumberOfReadingDigits
|
||||
{
|
||||
get => this.nrOfReadingDigits;
|
||||
set
|
||||
{
|
||||
BitConverter.GetBytes(value).CopyTo(this.bytes, 34);
|
||||
|
||||
this.nrOfReadingDigits = (sbyte)BitConverter.ToInt16(this.bytes, 34);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>36 - 47</para>
|
||||
/// Set Preset Reading (v1.24), string padded and terminated with '\0'.
|
||||
/// First Two Characters are set to 0x00 0x00 to indicate that we are programming Totalizer
|
||||
/// +1
|
||||
/// </summary>
|
||||
private string readingPreset;
|
||||
public string ReadingPreset
|
||||
{
|
||||
get => this.readingPreset;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 38, 10);
|
||||
|
||||
this.readingPreset = this.bytes.ToASCIIString(38, 10);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>48 - 49</para>
|
||||
/// Set Optional Uni-directional Fields request
|
||||
/// </summary>
|
||||
private ushort optionalFields;
|
||||
public ushort OptionalUniDirFields
|
||||
{
|
||||
get => this.optionalFields;
|
||||
set
|
||||
{
|
||||
BitConverter.GetBytes(value).CopyTo(bytes, 48);
|
||||
|
||||
this.optionalFields = BitConverter.ToUInt16(this.bytes, 48);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>50 - 51</para>
|
||||
/// Set Alarm Persistence Period request. First Byte is always set to 0x00 to indicate Volume Sensor
|
||||
/// </summary>
|
||||
public byte AlarmPercistancePeriodDays
|
||||
{
|
||||
get => this.bytes[51];
|
||||
set => this.bytes[51] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>52 - 54</para>
|
||||
/// Set Data Log Interval request. First Byte is always set to 0x00 to indicate Volume Sensor
|
||||
/// </summary>
|
||||
private ushort dataLogInterval;
|
||||
public ushort DataLogIntervalMinutes
|
||||
{
|
||||
get => this.dataLogInterval;
|
||||
set
|
||||
{
|
||||
BitConverter.GetBytes(value).CopyTo(this.bytes, 53);
|
||||
|
||||
this.dataLogInterval = BitConverter.ToUInt16(this.bytes, 53);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>55 - 58</para>
|
||||
/// Manufacturing Time request
|
||||
/// </summary>
|
||||
private uint manifactured;
|
||||
public uint ManifacturingTime
|
||||
{
|
||||
get => this.manifactured;
|
||||
set
|
||||
{
|
||||
BitConverter.GetBytes(value).CopyTo(this.bytes, 55);
|
||||
|
||||
this.manifactured = BitConverter.ToUInt16(this.bytes, 55);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>59 - 62</para>
|
||||
/// System Time request
|
||||
/// </summary>
|
||||
private uint timeDrift;
|
||||
public uint SystemTime
|
||||
{
|
||||
get => this.timeDrift;
|
||||
set
|
||||
{
|
||||
BitConverter.GetBytes(value).CopyTo(this.bytes, 59);
|
||||
|
||||
this.timeDrift = BitConverter.ToUInt16(this.bytes, 59);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>63</para>
|
||||
/// Set Reboot Count request
|
||||
/// </summary>
|
||||
public byte RebootCount
|
||||
{
|
||||
get => this.bytes[63];
|
||||
set => this.bytes[63] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>64-79</para>
|
||||
/// Build Information request, string padded and terminated with '\0'
|
||||
/// +1
|
||||
/// </summary>
|
||||
private string buildInfo;
|
||||
public string BuildInfo
|
||||
{
|
||||
get => this.buildInfo;
|
||||
set
|
||||
{
|
||||
this.SetASCIIBytes(value, 64, 16);
|
||||
|
||||
this.buildInfo = this.bytes.ToASCIIString(64, 16);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>80-89</para>
|
||||
/// Set Device ID String, string is padded and terminated with '\0'
|
||||
/// +1
|
||||
/// </summary>
|
||||
//public string DeviceID
|
||||
//{
|
||||
// set => this.SetASCIIBytes(value, 80, 10);
|
||||
//}
|
||||
|
||||
private void SetASCIIBytes(string value, int start, int length)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var asciiBytes = Encoding.ASCII.GetBytes(value);
|
||||
var asciiLength = asciiBytes.Length;
|
||||
var asciiIndex = 0;
|
||||
|
||||
length += start;
|
||||
|
||||
while (start >= 0 && start < length && asciiIndex < asciiLength)
|
||||
{
|
||||
this.bytes[start++] = asciiBytes[asciiIndex++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,5 +15,10 @@
|
||||
public CustomerText(byte[] response) : base(response, LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
public CustomerText(string value) : base(value, LENGTH)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,5 +11,10 @@
|
||||
public DeviceID(byte[] response) : base(response, LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
public DeviceID(string value) : base(value, LENGTH)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,5 +27,7 @@
|
||||
get => epoch.AddSeconds(this.SecondsSince);
|
||||
set => this.SecondsSince = (uint)(value - epoch).TotalSeconds;
|
||||
}
|
||||
|
||||
public static uint UTCNow => (uint)(DateTime.UtcNow - epoch).TotalSeconds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,5 +12,13 @@
|
||||
public FactoryID(byte[] response) : base(response, LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
public FactoryID(string value) : base(value, LENGTH)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static implicit operator FactoryID(string value)
|
||||
=> new FactoryID { Value = value };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace OmniPlus.Features
|
||||
using System;
|
||||
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
public class FeatureRequest : FeatureResponse
|
||||
{
|
||||
@@ -25,5 +27,8 @@
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
internal void CopyTo(byte[] bytes, int start)
|
||||
=> Array.Copy(this.bytes, 0, bytes, start, this.length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,14 +13,14 @@ namespace OmniPlus.Features
|
||||
|
||||
public FeatureResponse(byte[] response, int length = 0) : this(length)
|
||||
{
|
||||
if (response != null )
|
||||
if (response?.Length > 0)
|
||||
{
|
||||
this.Status = (Status)response[0];
|
||||
}
|
||||
|
||||
if (response.Length > 1 && response.Length >= length)
|
||||
{
|
||||
Array.Copy(response, 1, this.bytes, 0, length);
|
||||
}
|
||||
if (response?.Length > length)
|
||||
{
|
||||
Array.Copy(response, 1, this.bytes, 0, length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,16 @@ namespace OmniPlus.Features
|
||||
|
||||
public bool Succeeded => this.Status == Status.Completed;
|
||||
|
||||
public static implicit operator byte[](FeatureResponse response)
|
||||
=> response?.bytes ?? new byte[0];
|
||||
public override bool Equals(object obj)
|
||||
=> obj is FeatureResponse outer && outer.bytes == this.bytes;
|
||||
|
||||
public override int GetHashCode()
|
||||
=> this.bytes.GetHashCode();
|
||||
|
||||
public override string ToString()
|
||||
=> BitConverter.ToString(this.bytes);
|
||||
|
||||
//public static implicit operator byte[](FeatureResponse response)
|
||||
// => response?.bytes ?? new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,5 +16,13 @@
|
||||
public OptionalUniDirFields(byte[] response) : base(response, LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
public OptionalUniDirFields(string value) : base(value, LENGTH)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static implicit operator ushort(OptionalUniDirFields obj)
|
||||
=> BitConverter.ToUInt16(obj.bytes, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace OmniPlus.Features
|
||||
using System;
|
||||
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
public class ProgrammableID : ASCIIString
|
||||
{
|
||||
@@ -12,5 +14,13 @@
|
||||
public ProgrammableID(byte[] response) : base(response, LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
public ProgrammableID(string value) : base(value, LENGTH)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static implicit operator ProgrammableID(string value)
|
||||
=> new ProgrammableID { Value = value };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace OmniPlus.Features
|
||||
using System;
|
||||
|
||||
namespace OmniPlus.Features
|
||||
{
|
||||
public class ReadingDigits : FeatureRequest
|
||||
{
|
||||
@@ -23,5 +25,19 @@
|
||||
get => this.bytes[1];
|
||||
set => this.bytes[1] = value;
|
||||
}
|
||||
|
||||
public static implicit operator ReadingDigits(sbyte value)
|
||||
{
|
||||
var bytes = BitConverter.GetBytes(value);
|
||||
|
||||
return new ReadingDigits
|
||||
{
|
||||
Count = bytes[0],
|
||||
Offset = bytes[1]
|
||||
};
|
||||
}
|
||||
|
||||
public static implicit operator sbyte(ReadingDigits readingDigits)
|
||||
=> (sbyte)BitConverter.ToInt16(new[] { readingDigits?.Count ?? 0, readingDigits?.Offset ?? 0 }, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace OmniPlus.Features
|
||||
/// </summary>
|
||||
public class Readings : ASCIIString
|
||||
{
|
||||
const int LENGTH = 8;
|
||||
const int LENGTH = 12;
|
||||
|
||||
public Readings() : base(LENGTH)
|
||||
{
|
||||
@@ -43,10 +43,18 @@ namespace OmniPlus.Features
|
||||
{
|
||||
}
|
||||
|
||||
public Readings(string value) : base(value, LENGTH)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public byte SensorID => this.bytes[0];
|
||||
|
||||
public ReadingSettings Setting => (ReadingSettings)this.bytes[1];
|
||||
|
||||
public bool Include => this.bytes[2] == 1;
|
||||
|
||||
public static implicit operator Readings(string value)
|
||||
=> new Readings { Value = value };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,21 +91,5 @@ namespace OmniPlus.Features
|
||||
get => this.bytes[12].GetUint8(3, 3);
|
||||
set => OmniPlusExtensions.SetUint8(ref this.bytes[12], 3, 3, value);
|
||||
}
|
||||
|
||||
public override bool Equals(object other)
|
||||
=> other is RegisterSettings registerSettings
|
||||
&& registerSettings.IntPart == this.IntPart
|
||||
&& registerSettings.Fraction == this.Fraction
|
||||
&& registerSettings.Size == this.Size
|
||||
&& registerSettings.Range == this.Range
|
||||
&& registerSettings.VolumePerPulseUnit == this.VolumePerPulseUnit
|
||||
&& registerSettings.MeterUnits == this.MeterUnits
|
||||
&& registerSettings.FlowUnits == this.FlowUnits
|
||||
&& registerSettings.FlowRate == this.FlowRate
|
||||
&& registerSettings.FactoryCorrection == this.FactoryCorrection
|
||||
&& registerSettings.FieldCorrection == this.FieldCorrection
|
||||
&& registerSettings.PulseWeight == this.PulseWeight
|
||||
&& registerSettings.PulseWidth == this.PulseWidth
|
||||
&& registerSettings.PulseUpdate == this.PulseUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
{
|
||||
this.BuildInfo = new BuildInfo();
|
||||
this.BuildInfo.Status = this.Status;
|
||||
this.BuildInfo.Value = this.bytes.ToASCIIString(0, 15);
|
||||
this.BuildInfo.ToASCIIString(this.bytes, 0, 15);
|
||||
|
||||
this.ManifacturingTime = new ManifacturingTime();
|
||||
this.ManifacturingTime.Status = this.Status;
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
this.VersionAndType = new VersionAndType();
|
||||
this.VersionAndType.Status = this.Status;
|
||||
this.VersionAndType.Value = this.bytes.ToASCIIString(25, 51);
|
||||
this.VersionAndType.ToASCIIString(this.bytes, 25, 51);
|
||||
|
||||
this.BatteryVoltage = new BatteryVoltage();
|
||||
this.BatteryVoltage.Status = this.Status;
|
||||
|
||||
@@ -21,5 +21,10 @@
|
||||
public VersionAndType(byte[] response) : base(response, LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
public VersionAndType(string value) : base(value, LENGTH)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,10 +112,11 @@
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SignalRClient\SignalRClient.csproj">
|
||||
<Project>{5C16DAC4-71E5-49B4-A087-36C704AADCF1}</Project>
|
||||
<Name>SignalRClient</Name>
|
||||
<ProjectReference Include="..\ExchangeHub\ExchangeHub.csproj">
|
||||
<Project>{6033FF0C-CF32-4BC5-8EFE-4774CCDC663D}</Project>
|
||||
<Name>ExchangeHub</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
@@ -1,12 +1,15 @@
|
||||
using OmniPlus.Features;
|
||||
using System;
|
||||
using OmniPlus.Features;
|
||||
using OmniPlus.Hanlers;
|
||||
|
||||
using static OmniPlus.Features.Features;
|
||||
|
||||
namespace OmniPlus
|
||||
{
|
||||
public class OmniPlusConnection
|
||||
public sealed class OmniPlusConnection
|
||||
{
|
||||
private uint secondsToWait;
|
||||
private Func<bool> connected;
|
||||
private readonly IrdaConnection irdaConnection;
|
||||
private readonly UniProConnection uniProConnection;
|
||||
|
||||
@@ -18,11 +21,15 @@ namespace OmniPlus
|
||||
|
||||
internal MessageHandler MessageHandler;
|
||||
|
||||
public bool Connected
|
||||
=> this.connected?.Invoke() == true;
|
||||
|
||||
public bool ConnectIrda()
|
||||
{
|
||||
this.uniProConnection.Close();
|
||||
this.irdaConnection.Open();
|
||||
|
||||
this.connected = () => this.irdaConnection.Connected;
|
||||
this.MessageHandler = this.irdaConnection.SendMessage;
|
||||
|
||||
return this.irdaConnection.Connected;
|
||||
@@ -33,6 +40,7 @@ namespace OmniPlus
|
||||
this.irdaConnection.Close();
|
||||
this.uniProConnection.Open();
|
||||
|
||||
this.connected = () => this.uniProConnection.Connected;
|
||||
this.MessageHandler = this.uniProConnection.SendMessage;
|
||||
|
||||
return this.irdaConnection.Connected;
|
||||
@@ -137,7 +145,7 @@ namespace OmniPlus
|
||||
|
||||
public ConfigurationParameters ViewConfigurationParameters()
|
||||
{
|
||||
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, VIEW_CONFIGURATION_PARAMETERS, 0x01);
|
||||
var response = this.MessageHandler.Invoke(DEVICE_SPECIFIC, VIEW_CONFIGURATION_PARAMETERS/*, 0x01*/);
|
||||
|
||||
return new ConfigurationParameters(response);
|
||||
}
|
||||
@@ -245,7 +253,7 @@ namespace OmniPlus
|
||||
return new FeatureResponse(response);
|
||||
}
|
||||
|
||||
public FeatureResponse Set(ConfigurationParameters configurationParameters)
|
||||
public FeatureResponse Set(ConfigurationParametersSet configurationParameters)
|
||||
{
|
||||
var response = this.MessageHandler.Invoke(configurationParameters[DEVICE_SPECIFIC, SET_CONFIGURATION_PARAMETERS]);
|
||||
|
||||
@@ -383,5 +391,13 @@ namespace OmniPlus
|
||||
|
||||
return new FeatureResponse();
|
||||
}
|
||||
|
||||
private void WaitBeforeNextExecution()
|
||||
{
|
||||
while (this.secondsToWait > 0)
|
||||
{
|
||||
this.secondsToWait--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using OmniPlus;
|
||||
using OmniPlus.Enums;
|
||||
using OmniPlus.Enums;
|
||||
using OmniPlus.Features;
|
||||
|
||||
using System;
|
||||
@@ -12,8 +11,9 @@ using static OmniPlus.OmniPlusConstants;
|
||||
|
||||
namespace OmniPlus
|
||||
{
|
||||
public class OmniPlusConnectionsPool
|
||||
public class OmniPlusConnectionsPool : IDisposable
|
||||
{
|
||||
public event Action Done;
|
||||
public event OmniPlusStateChanged StateChanged;
|
||||
|
||||
private readonly ConcurrentDictionary<int, OmniPlusConnection> connections;
|
||||
@@ -45,6 +45,8 @@ namespace OmniPlus
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.signalRConnection.Dispose();
|
||||
|
||||
// Disposes all OmniPlus connections.
|
||||
foreach (var connectionKVP in this.connections)
|
||||
{
|
||||
@@ -117,13 +119,30 @@ namespace OmniPlus
|
||||
|
||||
public void StartInspection()
|
||||
{
|
||||
this.background = new BackgroundWorker();
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
//this.StartOmniInitialization(position);
|
||||
|
||||
this.background.DoWork += this.StartInspection;
|
||||
//foreach (var point in this.omniType.TestPoints)
|
||||
//{
|
||||
// this.StartOmniInspection(position, point);
|
||||
//}
|
||||
|
||||
this.background.RunWorkerAsync();
|
||||
//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;
|
||||
@@ -131,7 +150,7 @@ namespace OmniPlus
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.StartOmniInitialization(position));
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.StartOmniInitialization(position), this.cancellationToken);
|
||||
}
|
||||
|
||||
tasks.ContinueWhenAll();
|
||||
@@ -139,38 +158,46 @@ namespace OmniPlus
|
||||
foreach (var point in this.omniType.TestPoints)
|
||||
{
|
||||
// TODO: 600 = 10min * 60sec - change for production.
|
||||
this.signalRConnection.SetQAndWaitUntilReached(point.VolumeM3H, 600);
|
||||
|
||||
if (!this.signalRConnection.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));
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.StartOmniInspection(position, point), this.cancellationToken);
|
||||
}
|
||||
|
||||
tasks.ContinueWhenAll();
|
||||
|
||||
var volumeMessured = 0.1D; // TODO: this.GetM3();
|
||||
var volume = this.signalRConnection.RequestRefV();
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
this.SetPointDifference(position, point, volumeMessured);
|
||||
this.SetPointDifference(position, point, volume);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
this.GetCorrectionFactor(position);
|
||||
this.CalculateCorrectionFactor(position);
|
||||
}
|
||||
|
||||
tasks = new Task[connectionsCount];
|
||||
|
||||
foreach (var position in this.connections.Keys)
|
||||
{
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.FinishOmniInspection(position));
|
||||
tasks[position - 1] = Task.Factory.StartNew(() => this.FinishOmniInspection(position), this.cancellationToken);
|
||||
}
|
||||
|
||||
tasks.ContinueWhenAll();
|
||||
|
||||
this.Done?.Invoke();
|
||||
}
|
||||
|
||||
private void StartOmniInitialization(int position)
|
||||
@@ -204,7 +231,7 @@ namespace OmniPlus
|
||||
{
|
||||
var header = $"{point.VolumeM3H:0.0000}m³/h";
|
||||
|
||||
if (this.TryGetOmni(position, out var connection, out var meter) && meter.Initialized && meter.CanCalibrate)
|
||||
if (this.TryGetOmni(position, out var connection, out var meter) /*&& meter.Initialized && meter.CanCalibrate*/)
|
||||
{
|
||||
this.StateChanged?.Invoke(position, 0, header, TBD);
|
||||
|
||||
@@ -231,11 +258,14 @@ namespace OmniPlus
|
||||
|
||||
if (!calibrationResult.Succeeded)
|
||||
{
|
||||
this.StateChanged?.Invoke(position, -1, header, $"CC: {calibrationResult.Status}");
|
||||
this.StateChanged?.Invoke(position, -1, header, $"CC: {calibrationResult.Status.ToString()}");
|
||||
}
|
||||
else if (calibrationResult.Control != ChamberCalibrationResponse.TEST_COMPLETED)
|
||||
{
|
||||
this.StateChanged?.Invoke(position, -1, header, $"CC: {calibrationResult.Control}");
|
||||
var control = calibrationResult.Control == ChamberCalibrationResponse.TEST_ACTIVATED
|
||||
? nameof(ChamberCalibrationResponse.TEST_ACTIVATED)
|
||||
: nameof(ChamberCalibrationResponse.TEST_FAILED);
|
||||
this.StateChanged?.Invoke(position, -1, header, $"CC: {control}");
|
||||
}
|
||||
else // process calibration
|
||||
{
|
||||
@@ -271,7 +301,7 @@ namespace OmniPlus
|
||||
}
|
||||
}
|
||||
|
||||
private void GetCorrectionFactor(int position)
|
||||
private void CalculateCorrectionFactor(int position)
|
||||
{
|
||||
if (this.TryGetOmni(position, out var _, out var meter) && meter.Initialized && meter.CanCalibrate)
|
||||
{
|
||||
@@ -287,7 +317,7 @@ namespace OmniPlus
|
||||
|
||||
private void FinishOmniInspection(int position)
|
||||
{
|
||||
if (this.TryGetOmni(position, out var connection, out var meter) && meter.Calibrated)
|
||||
if (this.TryGetOmni(position, out var connection, out var meter)/* && meter.Calibrated*/)
|
||||
{
|
||||
var configurationParameters = connection.ViewConfigurationParameters();
|
||||
var canContinue = configurationParameters.Succeeded;
|
||||
@@ -305,49 +335,50 @@ namespace OmniPlus
|
||||
//canContinue = systemTimeReset.Succeeded;
|
||||
}
|
||||
|
||||
if (canContinue)
|
||||
{
|
||||
var registerSettings = connection.ViewRegisterSettings();
|
||||
//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;
|
||||
// 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;
|
||||
// var response = connection.Set(registerSettings);
|
||||
// canContinue = response.Succeeded;
|
||||
|
||||
if (canContinue)
|
||||
{
|
||||
meter.AddRegisterSettings(registerSettings);
|
||||
}
|
||||
}
|
||||
// if (canContinue)
|
||||
// {
|
||||
// meter.AddRegisterSettings(registerSettings);
|
||||
// }
|
||||
//}
|
||||
|
||||
if (canContinue)
|
||||
{
|
||||
configurationParameters.ProgrammableID = meter.ProgrammableID;
|
||||
configurationParameters.FactoryID = meter.FactoryID;
|
||||
configurationParameters.ReadingDigits = meter.ReadingDigits;
|
||||
configurationParameters.Readings = meter.Readings;
|
||||
configurationParameters.OptionalUniDirFields = meter.OptionalUniDirFields;
|
||||
configurationParameters.AlartPersistenceDays = meter.AlartPersistenceDays;
|
||||
configurationParameters.DataLogIntervalMins = meter.DataLogIntervalMins;
|
||||
configurationParameters.ManifacturingTime = meter.ManifacturingTime;
|
||||
configurationParameters.SystemTime = DateTime.UtcNow;
|
||||
configurationParameters.RebootCount = 0;
|
||||
configurationParameters.BuildInfo = meter.BuildInfo;
|
||||
configurationParameters.DeviceID = meter.DeviceID;
|
||||
var configurationParametersSet = new ConfigurationParametersSet();
|
||||
configurationParametersSet.ProgrammableID = "816232411982";
|
||||
configurationParametersSet.FactoryID = "816232411982";
|
||||
configurationParametersSet.NumberOfReadingDigits = 8; // meter.ReadingDigits;
|
||||
configurationParametersSet.ReadingPreset = "0000000000";
|
||||
configurationParametersSet.OptionalUniDirFields = 0; // meter.OptionalUniDirFields;
|
||||
configurationParametersSet.AlarmPercistancePeriodDays = 31;
|
||||
configurationParametersSet.DataLogIntervalMinutes = 60;
|
||||
configurationParametersSet.ManifacturingTime = Epoch20000101.UTCNow - 30000; // meter.ManifacturingTime;
|
||||
configurationParametersSet.SystemTime = Epoch20000101.UTCNow;
|
||||
configurationParametersSet.RebootCount = 0;
|
||||
configurationParametersSet.BuildInfo = "816232411982"; // meter.BuildInfo;
|
||||
// configurationParametersSet.DeviceID = "OMNI-01";
|
||||
|
||||
var response = connection.Set(configurationParameters);
|
||||
var response = connection.Set(configurationParametersSet);
|
||||
canContinue = response.Succeeded;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
using OmniPlus.Features;
|
||||
|
||||
using System;
|
||||
using System.Data.SqlClient;
|
||||
|
||||
namespace OmniPlus
|
||||
@@ -75,9 +75,8 @@ namespace OmniPlus
|
||||
, [ReadingDigitsOffsest] = @{nameof(parameters.ReadingDigits.Offset)}
|
||||
, [Readings] = @{nameof(parameters.Readings)}
|
||||
, [OptionalUniDirFields] = @{nameof(parameters.OptionalUniDirFields)}
|
||||
, [AlarmPersitenceDays] = @{nameof(parameters.AlartPersistenceDays)}
|
||||
, [AlarmPersitenceDays] = @{nameof(parameters.AlarmPersistenceDays)}
|
||||
, [DataLogIntervalMins] = @{nameof(parameters.DataLogIntervalMins)}
|
||||
, [DeviceID] = @{nameof(parameters.DeviceID)}
|
||||
WHERE [Position] = @{nameof(position)}";
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(position), position));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.ProgrammableID), parameters.ProgrammableID.Value));
|
||||
@@ -85,12 +84,19 @@ namespace OmniPlus
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.ReadingDigits.Count), parameters.ReadingDigits.Count));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.ReadingDigits.Offset), parameters.ReadingDigits.Offset));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.Readings), parameters.Readings.Value));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.OptionalUniDirFields), parameters.OptionalUniDirFields));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.AlartPersistenceDays), parameters.AlartPersistenceDays));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.DataLogIntervalMins), parameters.DataLogIntervalMins));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.DeviceID), parameters.DeviceID.Value));
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
sqlCommand.Parameters.Clear();
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.OptionalUniDirFields), parameters.OptionalUniDirFields.Value));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.AlarmPersistenceDays), parameters.AlarmPersistenceDays));
|
||||
sqlCommand.Parameters.Add(new SqlParameter(nameof(parameters.DataLogIntervalMins), BitConverter.GetBytes(parameters.DataLogIntervalMins).Reverse()));
|
||||
|
||||
try
|
||||
{
|
||||
sqlCommand.ExecuteNonQuery();
|
||||
sqlCommand.Parameters.Clear();
|
||||
}
|
||||
catch (System.Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace OmniPlus
|
||||
control.ReturnResponse = true;
|
||||
message[index++] = control;
|
||||
|
||||
bytes.CopyTo(message, index--);
|
||||
bytes.CopyTo(message, index);
|
||||
|
||||
var checksum = message.CalculateCheckSUM(message.Length - OxO2);
|
||||
var checksumIndex = bytesLength + UI1236_HED_LENGTH;
|
||||
@@ -264,17 +264,16 @@ namespace OmniPlus
|
||||
}
|
||||
}
|
||||
|
||||
public static string ToASCIIString(this byte[] bytes, int start, int end)
|
||||
public static string ToASCIIString(this byte[] bytes, int start, int length)
|
||||
{
|
||||
var asciiString = string.Empty;
|
||||
|
||||
while (start <= end)
|
||||
while (start >= 0 && start < bytes.Length)
|
||||
{
|
||||
asciiString += (char)bytes[start];
|
||||
start++;
|
||||
asciiString += (char)bytes[start++];
|
||||
}
|
||||
|
||||
return asciiString.Trim();
|
||||
return asciiString;
|
||||
}
|
||||
|
||||
public static void ContinueWhenAll(this Task[] tasks)
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OmniPlus
|
||||
{
|
||||
this.Connected = connected;
|
||||
this.systemParameters = new SystemParameters();
|
||||
this.configurationParameters = new ConfigurationParameters();
|
||||
this.testPoints = new Dictionary<OmniPlusTestPoint, OmniPlusTest>();
|
||||
}
|
||||
|
||||
@@ -37,22 +38,22 @@ namespace OmniPlus
|
||||
|
||||
public string BuildInfo
|
||||
{
|
||||
get => this.systemParameters.BuildInfo.Value.Trim('\0');
|
||||
get => this.systemParameters.BuildInfo.Value;
|
||||
set => this.systemParameters.BuildInfo.Value = value;
|
||||
}
|
||||
|
||||
public DateTime ManifacturingTime
|
||||
public uint ManifacturingTime
|
||||
{
|
||||
get => this.systemParameters.ManifacturingTime.DateTime;
|
||||
set => this.systemParameters.ManifacturingTime.DateTime = value;
|
||||
get => this.systemParameters.ManifacturingTime.SecondsSince;
|
||||
set => this.systemParameters.ManifacturingTime.SecondsSince = value;
|
||||
}
|
||||
|
||||
public bool ManifacturingTimeInRange { get; private set; }
|
||||
|
||||
public DateTime SystemTime
|
||||
public uint SystemTime
|
||||
{
|
||||
get => this.systemParameters.SystemTime.DateTime;
|
||||
set => this.systemParameters.SystemTime.DateTime = value;
|
||||
get => this.systemParameters.SystemTime.SecondsSince;
|
||||
set => this.systemParameters.SystemTime.SecondsSince = value;
|
||||
}
|
||||
|
||||
public int SystemTimeDrift { get; private set; }
|
||||
@@ -67,7 +68,7 @@ namespace OmniPlus
|
||||
|
||||
public string Firmware
|
||||
{
|
||||
get => this.systemParameters.VersionAndType.Value.Trim('\0');
|
||||
get => this.systemParameters.VersionAndType.Value;
|
||||
set => this.systemParameters.VersionAndType.Value = value;
|
||||
}
|
||||
|
||||
@@ -100,8 +101,8 @@ namespace OmniPlus
|
||||
public FactoryID FactoryID
|
||||
=> this.configurationParameters.FactoryID;
|
||||
|
||||
public ReadingDigits ReadingDigits
|
||||
=> this.configurationParameters.ReadingDigits;
|
||||
public sbyte ReadingDigits
|
||||
=> this.configurationParameters?.ReadingDigits ?? 0;
|
||||
|
||||
public Readings Readings
|
||||
=> this.configurationParameters.Readings;
|
||||
@@ -110,14 +111,11 @@ namespace OmniPlus
|
||||
=> this.configurationParameters.OptionalUniDirFields;
|
||||
|
||||
public byte AlartPersistenceDays
|
||||
=> this.configurationParameters.AlartPersistenceDays;
|
||||
=> this.configurationParameters.AlarmPersistenceDays;
|
||||
|
||||
public ushort DataLogIntervalMins
|
||||
=> this.configurationParameters.DataLogIntervalMins;
|
||||
|
||||
public DeviceID DeviceID
|
||||
=> this.configurationParameters.DeviceID;
|
||||
|
||||
internal double AddCalibrationResult(OmniPlusTestPoint point, ChamberCalibrationResponse result)
|
||||
{
|
||||
this.testPoints[point] = new OmniPlusTest
|
||||
@@ -149,16 +147,29 @@ namespace OmniPlus
|
||||
{
|
||||
this.systemParameters = systemParameters;
|
||||
|
||||
this.SystemTimeDrift = (DateTime.UtcNow - this.SystemTime).Seconds;
|
||||
this.SystemTimeDrift = (DateTime.UtcNow - this.systemParameters.SystemTime.DateTime).Seconds;
|
||||
this.SystemTimeInRange = Math.Abs(this.SystemTimeDrift) <= 700;
|
||||
this.ManifacturingTimeInRange = Math.Abs((DateTime.UtcNow - this.ManifacturingTime).Days) <= 365;
|
||||
this.ManifacturingTimeInRange = Math.Abs((DateTime.UtcNow - this.systemParameters.ManifacturingTime.DateTime).Days) <= 365;
|
||||
|
||||
var firmwareTokens = this.Firmware
|
||||
?.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
?? new string[2];
|
||||
var versionString = firmwareTokens[0]?.Substring(1) ?? string.Empty;
|
||||
|
||||
var versionString = string.Empty;
|
||||
|
||||
if (firmwareTokens?.Length > 0 && firmwareTokens[0]?.Length > 0)
|
||||
{
|
||||
versionString = firmwareTokens[0].Substring(1);
|
||||
}
|
||||
|
||||
var versionParsed = double.TryParse(versionString, out var version);
|
||||
var typeString = firmwareTokens[1]?.ToUpper() ?? string.Empty;
|
||||
var typeString = string.Empty;
|
||||
|
||||
if (firmwareTokens?.Length > 1 && firmwareTokens[1]?.Length > 0)
|
||||
{
|
||||
typeString = firmwareTokens[1].ToUpper();
|
||||
}
|
||||
|
||||
var isOmni = typeString == "OMNI-01" || typeString == "OMNI-02";
|
||||
|
||||
this.FirmwareInRange = versionParsed && version >= 1.23 && isOmni;
|
||||
|
||||
@@ -1,39 +1,91 @@
|
||||
namespace OmniPlus
|
||||
{
|
||||
using SignalRClient;
|
||||
using System.Threading;
|
||||
using ExchangeHub;
|
||||
|
||||
public class SignalRConnection
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace OmniPlus
|
||||
{
|
||||
public class SignalRConnection : IDisposable
|
||||
{
|
||||
private readonly ExchangeHub exchangeHub;
|
||||
private readonly ExchangeConnection slave;
|
||||
private readonly string url;
|
||||
|
||||
public SignalRConnection(string url)
|
||||
{
|
||||
this.url = url;
|
||||
this.exchangeHub = new ExchangeHub();
|
||||
this.slave = new ExchangeConnection();
|
||||
}
|
||||
|
||||
internal void Connect()
|
||||
=> this.exchangeHub.Connect(this.url);
|
||||
=> this.slave.Connect(this.url);
|
||||
|
||||
public bool SetQAndWaitUntilReached(double value, int seconds)
|
||||
internal bool SetQAndWaitUntilReached(double value, int seconds = 300)
|
||||
{
|
||||
var reachSeconds = seconds;
|
||||
var reached = false;
|
||||
var started = false;
|
||||
|
||||
void WaitUntilReached(double _) => reached = true;
|
||||
this.exchangeHub.ExchangeQ += WaitUntilReached;
|
||||
void waitQReached(double _) => reached = true;
|
||||
this.slave.StartQ += waitQReached;
|
||||
|
||||
this.exchangeHub.SendExchangeQ(value);
|
||||
this.slave.NotifyStartQ(value);
|
||||
|
||||
while (!reached && seconds >= 0)
|
||||
while (!reached && reachSeconds >= 0)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
|
||||
reachSeconds--;
|
||||
}
|
||||
|
||||
if (reached)
|
||||
{
|
||||
var startSeconds = seconds;
|
||||
|
||||
void waitRefStarted() => started = true;
|
||||
this.slave.StartRef += waitRefStarted;
|
||||
|
||||
this.slave.NotifyStartRef();
|
||||
|
||||
while (!started && startSeconds >= 0)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
|
||||
startSeconds--;
|
||||
}
|
||||
}
|
||||
|
||||
return reached && started;
|
||||
}
|
||||
|
||||
internal void StopRunning()
|
||||
=> this.slave.NotifyStopQ();
|
||||
|
||||
internal double RequestRefV(int seconds = 300)
|
||||
{
|
||||
var received = false;
|
||||
var referenceV = 0D;
|
||||
|
||||
void waitRefV(double value)
|
||||
{
|
||||
referenceV = value;
|
||||
received = true;
|
||||
}
|
||||
|
||||
this.slave.StopRef += waitRefV;
|
||||
this.slave.NotifyStopRef();
|
||||
|
||||
while (!received && seconds >= 0)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
|
||||
seconds--;
|
||||
}
|
||||
|
||||
return reached;
|
||||
|
||||
return referenceV;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> this.slave.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user