Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5936c8f19 | ||
|
|
2842425673 | ||
|
|
06a401a1ff | ||
|
|
3a2fc50fec | ||
|
|
38a58ed8b7 | ||
|
|
c7cba20de0 | ||
|
|
6311df49c3 | ||
|
|
f1d32a39ba | ||
|
|
224b53f774 | ||
|
|
1e2777c5e7 | ||
|
|
c3c21649fb | ||
|
|
99ccabc142 | ||
|
|
f1e6e94450 | ||
|
|
320cddb177 | ||
|
|
42002e3fa4 | ||
|
|
77cabfd712 | ||
|
|
c933e2d759 | ||
|
|
f3f0a46627 | ||
|
|
b5fb4c2947 | ||
|
|
f6cce9df3c |
@@ -311,6 +311,9 @@ namespace Common
|
||||
(userName.Equals("jan") && password.Equals("jaugust")) ||
|
||||
(userName.Equals("JCermak") && password.Equals("Zt6911")) ||
|
||||
(userName.Equals("gilles") && password.Equals("alibaba")) ||
|
||||
#if DEBUG
|
||||
(userName.Equals("Sensus Developers") && password.Equals("5fbg12gf5hn8nhy1fr")) ||
|
||||
#endif
|
||||
(userName.Equals(passwordOfDay) && password.Equals(passwordOfDay));
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;HEAT_METERS;</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
|
||||
@@ -30,7 +30,7 @@
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;JUZNA_AFRIKA_NEW;HEAT_METERS;</DefineConstants>
|
||||
<DefineConstants>TRACE;JUZNA_AFRIKA_NEW;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE;HEAT_METERS;</DefineConstants>
|
||||
<DefineConstants>DEBUG;TRACE;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
@@ -32,7 +32,7 @@
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;HEAT_METERS;</DefineConstants>
|
||||
<DefineConstants>TRACE;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using NfcC7_DLL.NfcHanler;
|
||||
using NfcC7_DLL.NfcHanler.Protocols;
|
||||
using NfcC7_DLL.NfcHanler.Utils;
|
||||
using NfcC7_DLL.NfcHandler;
|
||||
using NfcC7_DLL.NfcHandler.Protocols;
|
||||
using NfcC7_DLL.NfcHandler.Utils;
|
||||
using NfcC7_DLL.NfcHandler;
|
||||
|
||||
namespace NfcC7_DLL.Tests.NfcHanler;
|
||||
|
||||
[TestClass]
|
||||
[TestSubject(typeof(NFCHeadService))]
|
||||
public class NFCHeadServiceTest
|
||||
[TestSubject(typeof(NfcHeadService))]
|
||||
public class NfcHeadServiceTest
|
||||
{
|
||||
|
||||
[TestMethod]
|
||||
@@ -20,7 +21,7 @@ public class NFCHeadServiceTest
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NFCHeadService service = new NFCHeadService(serialPortData);
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.SetTestingMode(OptoHeadStatus.OptoHeadC7);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadC7, status);
|
||||
}
|
||||
@@ -33,7 +34,7 @@ public class NFCHeadServiceTest
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NFCHeadService service = new NFCHeadService(serialPortData);
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.SetTestingMode(OptoHeadStatus.OptoHeadDisabled);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadDisabled, status);
|
||||
}
|
||||
@@ -46,7 +47,7 @@ public class NFCHeadServiceTest
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NFCHeadService service = new NFCHeadService(serialPortData);
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.SetTestingMode(OptoHeadStatus.OptoHeadC2);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadC2, status);
|
||||
|
||||
@@ -65,12 +66,26 @@ public class NFCHeadServiceTest
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NFCHeadService service = new NFCHeadService(serialPortData);
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
string? serialNr = service.GetSerialNr();
|
||||
Assert.IsFalse(string.IsNullOrEmpty(serialNr));
|
||||
Console.WriteLine("Found serial no: {0}",serialNr);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetSerialNrAsync_LiveMeterTest()
|
||||
{
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
"COM5",
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
string? serialNr = service.GetSerialNrAsync().GetAwaiter().GetResult();
|
||||
Assert.IsFalse(string.IsNullOrEmpty(serialNr));
|
||||
Console.WriteLine("Found serial no: {0}",serialNr);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetTestingMode_LiveMeterTest()
|
||||
{
|
||||
@@ -79,7 +94,7 @@ public class NFCHeadServiceTest
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NFCHeadService service = new NFCHeadService(serialPortData);
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.GetTestingMode();
|
||||
Assert.IsFalse(OptoHeadStatus.Unknown == status);
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestPlatform.CoreUtilities.Helpers;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using NfcC7_DLL.NfcHanler;
|
||||
using NfcC7_DLL.NfcHanler.Protocols;
|
||||
using NfcC7_DLL.NfcHanler.Utils;
|
||||
using NfcC7_DLL.NfcHandler;
|
||||
using NfcC7_DLL.NfcHandler.Protocols;
|
||||
using NfcC7_DLL.NfcHandler.Utils;
|
||||
|
||||
namespace NfcC7_DLL.Tests.NfcHanler;
|
||||
|
||||
@@ -21,7 +20,7 @@ public class OptoHeadServiceTest
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NFCHeadService service = new NFCHeadService(serialPortData);
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.SetTestingMode(OptoHeadStatus.OptoHeadC7);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadC7, status);
|
||||
//Open serial connection to Optohead
|
||||
|
||||
@@ -2,11 +2,11 @@ using System;
|
||||
using System.IO.Ports;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using NfcC7_DLL.NfcHanler.Utils;
|
||||
using NfcC7_DLL.NfcHandler.Utils;
|
||||
|
||||
namespace NfcC7_DLL.Tests.NfcHanler.Utils;
|
||||
|
||||
[TestClass]
|
||||
//[TestClass]
|
||||
[TestSubject(typeof(SERIAL_Driver))]
|
||||
public class SERIAL_DriverTest
|
||||
{
|
||||
@@ -22,15 +22,15 @@ public class SERIAL_DriverTest
|
||||
}
|
||||
|
||||
private readonly byte[] Open =
|
||||
{ 107 ,128 ,1 ,16 ,0 ,48 ,0 ,71 ,108 ,111 ,98 ,97 ,108 ,73 ,80 ,101 ,114
|
||||
,108 ,85 ,116 ,105 ,108 ,105 ,116 ,121 ,0 ,0 ,39 ,215 };
|
||||
{ 0x6B, 0x80, 0x01, 0x10, 0x00, 0x30, 0x00, 0x47, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x49, 0x50, 0x65, 0x72,
|
||||
0x6C, 0x55, 0x74, 0x69, 0x6C, 0x69, 0x74, 0x79, 0x00, 0x00, 0x27, 0xD7 };
|
||||
private readonly byte[] CommDeviceSessionEnd = { 0x6B, 0x61, 0x00, 0x10, 0x05, 0x31, 0x00, 0x1F, 0x29, 0xF9, 0xC5 };
|
||||
|
||||
private readonly byte[] ProductDetails =
|
||||
{ 107, 48, 1, 16, 3, 33, 1, 2, 107, 144, 0, 0, 17, 64, 5, 0, 2, 4, 96, 98, 66, 4, 165, 100 };
|
||||
{ 0x6B, 0x30, 0x01, 0x10, 0x03, 0x21, 0x01, 0x02, 0x6B, 0x90, 0x00, 0x00, 0x11, 0x40, 0x05, 0x00, 0x02, 0x04, 0x60, 0x62, 0x42, 0x04, 0xA5, 0x64 };
|
||||
|
||||
private readonly byte[] ProductDetails2 =
|
||||
{ 107, 48, 1, 16, 3, 33, 1, 2, 107, 144, 0, 0, 17, 64, 5, 0, 2, 4, 96 };
|
||||
{ 0x6B, 0x30, 0x01, 0x10, 0x03, 0x21, 0x01, 0x02, 0x6B, 0x90, 0x00, 0x00, 0x11, 0x40, 0x05, 0x00, 0x02, 0x04, 0x60 };
|
||||
|
||||
static Con con5 = new Con(){
|
||||
com = "COM5",
|
||||
@@ -54,10 +54,10 @@ public class SERIAL_DriverTest
|
||||
|
||||
|
||||
|
||||
[TestMethod]
|
||||
//[TestMethod]
|
||||
public void SendMessage_Test()
|
||||
{
|
||||
Con con = con6;
|
||||
Con con = con5;
|
||||
|
||||
byte[] message = Open;
|
||||
byte[] bytesReceived;
|
||||
@@ -75,13 +75,36 @@ public class SERIAL_DriverTest
|
||||
driver.SendMessage(message, message.Length);
|
||||
//Assert.IsTrue(driver.GetRawData().Length == 0);
|
||||
bytesReceived = driver.GetRawData();
|
||||
Assert.IsTrue(bytesReceived.Length > 0);
|
||||
//Assert.IsTrue(bytesReceived.Length > 0);
|
||||
Console.WriteLine("IsOpened: {0}", driver.isOpen());
|
||||
// Display raw bytes (as hex or byte count)
|
||||
Console.WriteLine(string.Format("Bytes received: {0}", bytesReceived.Length));
|
||||
Console.WriteLine(string.Format("Bytes (hex): {0}", BitConverter.ToString(bytesReceived)));
|
||||
string response = System.Text.Encoding.UTF8.GetString(bytesReceived);
|
||||
Console.WriteLine("Bytes string: {0}",response);
|
||||
if (bytesReceived != null)
|
||||
{
|
||||
Console.WriteLine(string.Format("Bytes received: {0}", bytesReceived.Length));
|
||||
Console.WriteLine(string.Format("Bytes (hex): {0}", BitConverter.ToString(bytesReceived)));
|
||||
string response = System.Text.Encoding.UTF8.GetString(bytesReceived);
|
||||
Console.WriteLine("Bytes string: {0}", response);
|
||||
}
|
||||
|
||||
// --- Get Serial No ---
|
||||
message = ProductDetails;
|
||||
// Send Open message
|
||||
bool sendSuccess = driver.SendMessage(message, message.Length);
|
||||
Assert.IsTrue(sendSuccess, "Failed to send Open message");
|
||||
Console.WriteLine("Sent message for product details: {0}", message.ToString());
|
||||
bytesReceived = driver.GetRawData();
|
||||
// Display raw bytes (as hex or byte count)
|
||||
if (bytesReceived != null)
|
||||
{
|
||||
Console.WriteLine(string.Format("Bytes received: {0}", bytesReceived.Length));
|
||||
Console.WriteLine(string.Format("Bytes (hex): {0}", BitConverter.ToString(bytesReceived)));
|
||||
string response = System.Text.Encoding.UTF8.GetString(bytesReceived);
|
||||
Console.WriteLine("Bytes string: {0}", response);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Response not received!");
|
||||
}
|
||||
|
||||
message = CommDeviceSessionEnd;
|
||||
driver.SendMessage(message, message.Length);
|
||||
@@ -91,7 +114,7 @@ public class SERIAL_DriverTest
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
//[TestMethod]
|
||||
public void SendMessage_TestLoop()
|
||||
{
|
||||
Con con = con6;
|
||||
@@ -132,7 +155,7 @@ public class SERIAL_DriverTest
|
||||
}
|
||||
|
||||
|
||||
[TestMethod]
|
||||
//[TestMethod]
|
||||
public void SendMessage_TestGetSerialNo()
|
||||
{
|
||||
Con con = con6;
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>false</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<Copyright>Copyright © 2025</Copyright>
|
||||
<AssemblyVersion>1.1.0.0</AssemblyVersion>
|
||||
<FileVersion>1.1.0.0</FileVersion>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
<DefineConstants>TRACE;IPERL;</DefineConstants>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<DebugType>full</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
<DefineConstants>TRACE;IPERL;</DefineConstants>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -26,6 +30,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Build.Utilities.v4.0" />
|
||||
<Reference Include="NA2WNFC">
|
||||
<HintPath>NfcHanler\NfcReaderLibrary\NA2WNFC.dll</HintPath>
|
||||
</Reference>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using NfcC7_DLL.NfcHandler.Protocols;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler
|
||||
{
|
||||
public class HeadInfo
|
||||
{
|
||||
string SerialNr { get; set; }
|
||||
OptoHeadStatus OptoHeadStatus { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler
|
||||
namespace NfcC7_DLL.NfcHandler
|
||||
{
|
||||
public class JsonDataFromPoseidon
|
||||
{
|
||||
@@ -0,0 +1,247 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NfcC7_DLL.NfcHandler.Protocols;
|
||||
using NfcC7_DLL.NfcHandler.Utils;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler
|
||||
{
|
||||
public class NfcHeadService
|
||||
{
|
||||
|
||||
private bool activeHandlerSessioEnabled = false;
|
||||
private CliRunner _cliRunner;
|
||||
|
||||
private SerialPortData serialPort;
|
||||
|
||||
public NfcHeadService(SerialPortData serialPort)
|
||||
{
|
||||
this.serialPort = serialPort;
|
||||
this._cliRunner = null;
|
||||
ValidateCliFileExistence(true);
|
||||
}
|
||||
|
||||
private CliRunner CliRunner
|
||||
{
|
||||
get { return (_cliRunner != null ? _cliRunner : (_cliRunner = new CliRunner(CliLogging))); }
|
||||
}
|
||||
|
||||
private bool CliLogging
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
private static readonly Regex OpticalDataModeRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*OpticalDataMode\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
@"|" +
|
||||
@"""OpticalDataMode""\s*:\s*""?(0x[0-9A-Fa-f]+|\d+)""?" + // JSON format (handles hex and decimal)
|
||||
@")",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
public bool TryGetOpticalDataMode(string result, out string s)
|
||||
{
|
||||
s = null;
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return false;
|
||||
|
||||
var m = OpticalDataModeRegex.Match(result);
|
||||
if (!m.Success)
|
||||
return false;
|
||||
|
||||
// one of the groups will be filled
|
||||
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
||||
? m.Groups[1].Value.Trim()
|
||||
: m.Groups[2].Value.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static readonly Regex DeviceIdRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*Device\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
@"|" +
|
||||
@"""DeviceId""\s*:\s*""?([0-9]+)""?" + // JSON format
|
||||
@")",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
public bool TryGetDeviceId(string result, out string s)
|
||||
{
|
||||
s = null;
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return false;
|
||||
|
||||
var m = DeviceIdRegex.Match(result);
|
||||
if (!m.Success)
|
||||
return false;
|
||||
|
||||
// one of the groups will be filled
|
||||
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
||||
? m.Groups[1].Value.Trim()
|
||||
: m.Groups[2].Value.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void ValidateCliFileExistence(bool showErrorIfMissing)
|
||||
{
|
||||
if (serialPort != null)
|
||||
{
|
||||
if (!serialPort.CliExists)
|
||||
{
|
||||
throw new Exception("CLI file " + serialPort.SerialPortCmdClientPath +
|
||||
" does not exist! Current path: " + Environment.CurrentDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ////////////
|
||||
/// </summary>
|
||||
public string GetSerialNr()
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task optoheadDeviceIdTask = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
|
||||
var timeOut = CliRunner.AddTimeOut(5000);
|
||||
var doneTask = CliRunner.WaitAnyFinished(optoheadDeviceIdTask, timeOut);
|
||||
if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadDeviceIdTask is Task<string>)
|
||||
{
|
||||
string serialNr;
|
||||
if (optoheadDeviceIdTask.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
string result = (optoheadDeviceIdTask as Task<string>).Result;
|
||||
if (TryGetDeviceId(result, out serialNr))
|
||||
{
|
||||
return serialNr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<string> GetSerialNrAsync()
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
var cts = new CancellationTokenSource(); // we own the token
|
||||
var sendTask = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId, cts.Token);
|
||||
|
||||
string output;
|
||||
try
|
||||
{
|
||||
output = await CliRunner.WithTimeout(sendTask, TimeSpan.FromSeconds(15), cts);
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
|
||||
if (TryGetDeviceId(output, out var serialNr))
|
||||
return serialNr;
|
||||
|
||||
throw new Exception("Failed to parse DeviceId from output.");
|
||||
}
|
||||
|
||||
public OptoHeadStatus SetTestingMode(OptoHeadStatus status)
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task optoheadMode =
|
||||
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead, $"0x{((byte)status):X2}");
|
||||
var timeOut = CliRunner.AddTimeOut(5000);
|
||||
var doneTask = CliRunner.WhenAny();
|
||||
if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadMode is Task<string>)
|
||||
{
|
||||
string strOpticalDataMode;
|
||||
if (optoheadMode.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
string result = (optoheadMode as Task<string>).Result;
|
||||
if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
||||
{
|
||||
byte value;
|
||||
|
||||
if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
||||
else
|
||||
value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
||||
|
||||
OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
||||
return optoheadStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OptoHeadStatus.Unknown;
|
||||
}
|
||||
|
||||
public OptoHeadStatus GetTestingMode()
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task optoheadMode = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead);
|
||||
var timeOut = CliRunner.AddTimeOut(5000);
|
||||
var doneTask = CliRunner.WhenAny();
|
||||
if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadMode is Task<string>)
|
||||
{
|
||||
string strOpticalDataMode;
|
||||
if (optoheadMode.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
string result = (optoheadMode as Task<string>).Result;
|
||||
if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
||||
{
|
||||
byte value;
|
||||
|
||||
if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
||||
else
|
||||
value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
||||
|
||||
OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
||||
return optoheadStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OptoHeadStatus.Unknown;
|
||||
}
|
||||
|
||||
private void SendCommand()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private string RawDataAnswer()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Threading.Tasks;
|
||||
using NfcC7_DLL.NfcHandler.Protocols;
|
||||
using NfcC7_DLL.NfcHandler.Utils;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler
|
||||
{
|
||||
public class OptoHeadService
|
||||
{
|
||||
|
||||
public class Con
|
||||
{
|
||||
public string com = "COM5";
|
||||
public int baudrate = 38400;
|
||||
public int dataBits = 8;
|
||||
public Parity parity = Parity.None;
|
||||
public StopBits stopbits = StopBits.Two;
|
||||
public int readTimeout = 5000;
|
||||
public int writeTimeout = 1000;
|
||||
}
|
||||
|
||||
private Con Connection { get; set; }
|
||||
private SERIAL_Driver driver;
|
||||
/// <summary>
|
||||
/// Filed After Run() is called.
|
||||
/// </summary>
|
||||
public WaterMetrologyData WaterMetrologyData { get; private set; }
|
||||
|
||||
public OptoHeadService(Con con)
|
||||
{
|
||||
Connection = con;
|
||||
driver = new SERIAL_Driver();
|
||||
}
|
||||
|
||||
public bool CreateSerialConnection()
|
||||
{
|
||||
bool isopen = false;
|
||||
Con con = Connection;
|
||||
|
||||
byte[] message = {0x00};
|
||||
byte[] bytesReceived;
|
||||
|
||||
if (!driver.isOpen())
|
||||
{
|
||||
|
||||
isopen = driver.OpenConnection(
|
||||
con.com,
|
||||
con.baudrate,
|
||||
con.dataBits,
|
||||
con.parity,
|
||||
con.stopbits,
|
||||
con.readTimeout,
|
||||
con.writeTimeout);
|
||||
}
|
||||
|
||||
return isopen;
|
||||
}
|
||||
|
||||
public void CloseSerialConnection()
|
||||
{
|
||||
dissableRunLoop = true;
|
||||
driver.Close();
|
||||
}
|
||||
|
||||
public void RunLoop()
|
||||
{
|
||||
Task.Run(() => Run());
|
||||
}
|
||||
|
||||
|
||||
private bool dissableRunLoop = false;
|
||||
/// <summary>
|
||||
/// Run the service. Catch one communication to WaterMetrologyData field.
|
||||
/// </summary>
|
||||
public void Run()
|
||||
{
|
||||
while (!dissableRunLoop)
|
||||
{
|
||||
WaterMetrologyData = ParseData(RunReading());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
byte[] RunReading()
|
||||
{
|
||||
if (driver.isOpen())
|
||||
{
|
||||
driver.SendMessage(new byte[] {0x00}, 1);
|
||||
return driver.GetRawData();
|
||||
}
|
||||
else
|
||||
{
|
||||
dissableRunLoop = true;
|
||||
}
|
||||
|
||||
return new byte[] {0xFF};
|
||||
}
|
||||
|
||||
public WaterMetrologyData ParseData(byte[] data)
|
||||
{
|
||||
try
|
||||
{
|
||||
return WaterMetrologyData.Parse(data, DateTime.Now, "");
|
||||
}catch(Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace NfcC7_DLL.NfcHandler.Protocols
|
||||
{
|
||||
public enum OptoHeadStatus : byte
|
||||
{
|
||||
Unknown = 0xFF,
|
||||
OptoHeadDisabled = 0x00,
|
||||
OptoHeadC2 = 0xC2,
|
||||
OptoHeadC7 = 0xC7,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler.Protocols
|
||||
{
|
||||
public class WaterMetrologyData
|
||||
{
|
||||
private OptoHeadStatus _optoHeadStatus;
|
||||
private WaterMetrologyDataC7 c7Data;
|
||||
private WaterMetrologyDataC2 c2Data;
|
||||
|
||||
public WaterMetrologyDataC7 C7Data { get => c7Data; }
|
||||
public WaterMetrologyDataC2 C2Data { get => c2Data; }
|
||||
public OptoHeadStatus OptoHeadStatus { get => _optoHeadStatus; }
|
||||
|
||||
public static WaterMetrologyData Parse(byte[] data, DateTime dt, string dutinfo)
|
||||
{
|
||||
if (data.Length < 24)
|
||||
{
|
||||
throw new ArgumentException("Invalid data length for WaterMetrologyData C2.");
|
||||
}
|
||||
WaterMetrologyData waterMetrologyData = new WaterMetrologyData();
|
||||
waterMetrologyData._optoHeadStatus = OptoHeadStatus.Unknown;
|
||||
// Probably C2
|
||||
if(data.Length > 24 && data.Length < 48)
|
||||
{
|
||||
waterMetrologyData.c2Data = WaterMetrologyDataC2.Parse(data, dt, dutinfo);
|
||||
waterMetrologyData._optoHeadStatus = OptoHeadStatus.OptoHeadC2;
|
||||
}
|
||||
// Probably C7
|
||||
else if(data.Length >= 48)
|
||||
{
|
||||
waterMetrologyData.c7Data = WaterMetrologyDataC7.Parse(data, dt, dutinfo);
|
||||
waterMetrologyData._optoHeadStatus = OptoHeadStatus.OptoHeadC7;
|
||||
}
|
||||
|
||||
return waterMetrologyData;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Status: {_optoHeadStatus}, C7Data: {c7Data}, C2Data: {c2Data}";
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -1,4 +1,6 @@
|
||||
namespace NfcC7_DLL.NfcHanler.Protocols
|
||||
using System;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler.Protocols
|
||||
{
|
||||
public class WaterMetrologyDataC2
|
||||
{
|
||||
@@ -87,5 +89,6 @@
|
||||
$"Fast HPFC: {FastHPFC}, Field Polarity: {FieldPolarity}, Impedance Polarity: {ImpedancePolarity}, " +
|
||||
$"Calc Flow mL/s: {CalcFlowmLps:F2}, Calc Flow GPM: {CalcFlowGPM:F2}, Calc Acc Gal: {CalcAccGal:F2}";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -1,4 +1,6 @@
|
||||
namespace NfcC7_DLL.NfcHanler.Protocols
|
||||
using System;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler.Protocols
|
||||
{
|
||||
public class WaterMetrologyDataC7 : WaterMetrologyDataC2
|
||||
{
|
||||
@@ -1,10 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler.Utils
|
||||
namespace NfcC7_DLL.NfcHandler.Utils
|
||||
{
|
||||
public class CliRunner
|
||||
{
|
||||
@@ -32,7 +36,68 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
/// mainly used for time out additional task to compare results
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task WhenAny() { return Task.WhenAny(taskPool.ToArray()); }
|
||||
|
||||
|
||||
[Obsolete("Use async/await instead - WaitAnyFinished()")]
|
||||
public async Task<Task> WhenAny() { return await Task.WhenAny(taskPool.ToArray()); }
|
||||
|
||||
public Task WaitAnyFinished(Task task, Task timeOut)
|
||||
{
|
||||
Task.WhenAny(task, timeOut);
|
||||
while (true)
|
||||
{
|
||||
if (task.IsCompleted) break;
|
||||
if (task.IsFaulted) break;
|
||||
if (task.IsCanceled) break;
|
||||
|
||||
if(timeOut.IsCompleted) break;
|
||||
if(timeOut.IsFaulted) break;
|
||||
if(timeOut.IsCanceled) break;
|
||||
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
|
||||
var waitAny = Task.WaitAny(task, timeOut);
|
||||
return waitAny == 0 ? task : timeOut;
|
||||
}
|
||||
|
||||
public static async Task<T> WithTimeout<T>(Task<T> task, TimeSpan timeout, CancellationTokenSource externalCts = null)
|
||||
{
|
||||
var localCts = externalCts == null ? externalCts : new CancellationTokenSource();
|
||||
var timeoutCts = new CancellationTokenSource(timeout);
|
||||
var linked = CancellationTokenSource.CreateLinkedTokenSource(localCts.Token, timeoutCts.Token);
|
||||
|
||||
var completion = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
// Observe the task
|
||||
_ = task.ContinueWith(_ => completion.TrySetResult(true), TaskScheduler.Default);
|
||||
|
||||
// Observe the timeout
|
||||
_ = Task.Delay(Timeout.InfiniteTimeSpan, timeoutCts.Token)
|
||||
.ContinueWith(_ => completion.TrySetResult(true), TaskScheduler.Default);
|
||||
|
||||
await completion.Task.ConfigureAwait(false);
|
||||
|
||||
if (timeoutCts.IsCancellationRequested == false && task.IsCompleted) // task finished first
|
||||
return await task.ConfigureAwait(false);
|
||||
|
||||
// timeout won → cancel & throw TimeoutException
|
||||
localCts.Cancel(); // triggers your SendAsync to kill process
|
||||
throw new TimeoutException();
|
||||
}
|
||||
|
||||
public Task<string> AddSendAsync(SerialPortData data, SerialPortData.EMeterArg eMeterArg, CancellationToken ct = default)
|
||||
{
|
||||
var task = SendAsync(data.SerialPortCmdClientPath, data.DefaultArgSettingsRead(eMeterArg), ct);
|
||||
taskPool.Add(task); // List<Task> is okay because Task<string> : Task
|
||||
return task;
|
||||
}
|
||||
|
||||
public Task WaitAnyFinished()
|
||||
{
|
||||
int xTask = Task.WaitAny(taskPool.ToArray());
|
||||
return taskPool[xTask];
|
||||
}
|
||||
|
||||
public void Clear() { taskPool.Clear(); }
|
||||
public void CancelAll() { Task.WhenAll(taskPool).ContinueWith(t => { }); }
|
||||
@@ -123,29 +188,36 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
process.Start();
|
||||
|
||||
Task<string> stdOutTask = process.StandardOutput.ReadToEndAsync();
|
||||
Task<string> stdErrTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
try
|
||||
{
|
||||
await Task.WhenAll(stdOutTask, stdErrTask, process.WaitForExitAsync(ct));
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
if (!process.HasExited)
|
||||
process.Start();
|
||||
|
||||
Task<string> stdOutTask = process.StandardOutput.ReadToEndAsync();
|
||||
Task<string> stdErrTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
try
|
||||
{
|
||||
process.Kill();
|
||||
await Task.WhenAll(stdOutTask, stdErrTask, process.WaitForExitAsync(ct));
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
if (!process.HasExited)
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
throw;
|
||||
string allOutput = (stdOutTask.Result ?? "") + (stdErrTask.Result ?? "");
|
||||
//log?.Debug(allOutput);
|
||||
return allOutput;
|
||||
}
|
||||
finally
|
||||
{
|
||||
process?.Dispose();
|
||||
}
|
||||
|
||||
string allOutput = (stdOutTask.Result ?? "") + (stdErrTask.Result ?? "");
|
||||
//log?.Debug(allOutput);
|
||||
return allOutput;
|
||||
}
|
||||
|
||||
public Task<T> AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg) where T : new()
|
||||
@@ -167,20 +239,27 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
using var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
process.Start();
|
||||
var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
|
||||
var stdoutTask = process.StandardOutput.ReadToEndAsync();
|
||||
var stderrTask = process.StandardError.ReadToEndAsync();
|
||||
var stdoutTask = process.StandardOutput.ReadToEndAsync();
|
||||
var stderrTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
await Task.WhenAll(stdoutTask, stderrTask, process.WaitForExitAsync(ct));
|
||||
await Task.WhenAll(stdoutTask, stderrTask, process.WaitForExitAsync(ct));
|
||||
|
||||
string allOutput = (stdoutTask.Result ?? "") + (stderrTask.Result ?? "");
|
||||
//log?.Debug(allOutput);
|
||||
string allOutput = (stdoutTask.Result ?? "") + (stderrTask.Result ?? "");
|
||||
//log?.Debug(allOutput);
|
||||
|
||||
string json = ExtractJson(allOutput);
|
||||
if (TryJsonStringDeserialize(json, out T result)) return result;
|
||||
return default;
|
||||
string json = ExtractJson(allOutput);
|
||||
if (TryJsonStringDeserialize(json, out T result)) return result;
|
||||
return default;
|
||||
}
|
||||
finally
|
||||
{
|
||||
process?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryJsonStringDeserialize<T>(string json, out T runAndCaptureJsonAsync) where T : new()
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler.Utils
|
||||
{
|
||||
public static class ProcessExtensions
|
||||
{
|
||||
public static Task<object> WaitForExitAsync(this Process process, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (process == null) throw new ArgumentNullException(nameof(process));
|
||||
if (process.HasExited) return Task.FromResult<object>(null);
|
||||
|
||||
var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
EventHandler handler = null;
|
||||
handler = (s, e) =>
|
||||
{
|
||||
try { tcs.TrySetResult(null); }
|
||||
finally { process.Exited -= handler; }
|
||||
};
|
||||
|
||||
process.EnableRaisingEvents = true;
|
||||
process.Exited += handler;
|
||||
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationToken.Register(() =>
|
||||
{
|
||||
tcs.TrySetCanceled(cancellationToken);
|
||||
process.Exited -= handler;
|
||||
});
|
||||
}
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -1,13 +1,17 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
//*****************************************************************************
|
||||
// Copyright 2020 Sensus GmbH Ludwigshafen. All rights reserved.
|
||||
// Author: Venkat, Rajeshwar
|
||||
//*****************************************************************************
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler.Utils
|
||||
namespace NfcC7_DLL.NfcHandler.Utils
|
||||
{
|
||||
public class SERIAL_Driver
|
||||
{
|
||||
+23
-7
@@ -1,4 +1,7 @@
|
||||
namespace NfcC7_DLL.NfcHanler.Utils
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler.Utils
|
||||
{
|
||||
public class SerialPortData
|
||||
{
|
||||
@@ -13,7 +16,7 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
public string SerialPortCmdClientPath {
|
||||
get {
|
||||
#if DEBUG
|
||||
return Path.Combine("C:","TBF","Cli", CmdClientName);
|
||||
return Path.Combine("C:\\","TBF","Cli", CmdClientName);
|
||||
#else
|
||||
return Path.Combine("..","Cli", CmdClientName);
|
||||
#endif
|
||||
@@ -22,6 +25,7 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
public string CmdClientName { get; set; } = "HalCli.exe";
|
||||
public string PortName { get; set; }
|
||||
public int MeterType { get; set; }
|
||||
public string MeterTypeStr { get; set; }
|
||||
|
||||
public enum EMeterArg {
|
||||
Calibration = 0,
|
||||
@@ -33,14 +37,15 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
|
||||
public string DefaultArgSettingsRead(EMeterArg eMeterArg)
|
||||
{
|
||||
string meterTypeInsert = !string.IsNullOrEmpty(MeterTypeStr) ? MeterTypeStr : MeterType.ToString();
|
||||
switch (eMeterArg)
|
||||
{
|
||||
case EMeterArg.AllParams:
|
||||
return $"-p {PortName} -m {MeterType} --operation readall";
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation readall";
|
||||
case EMeterArg.DeviceId:
|
||||
return $"-p {PortName} -m {MeterType} --operation read --parameter DeviceId";
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation read --parameter DeviceId";
|
||||
case EMeterArg.Optohead:
|
||||
return $"-p {PortName} -m {MeterType} --operation read --parameter \"OpticalDataMode\"";
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation read --parameter \"OpticalDataMode\"";
|
||||
default:
|
||||
throw new Exception("Not implemented correct command!");
|
||||
}
|
||||
@@ -48,12 +53,13 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
|
||||
public string DefaultArgSettingsWrite(EMeterArg eMeterArg, string arg)
|
||||
{
|
||||
string meterTypeInsert = !string.IsNullOrEmpty(MeterTypeStr) ? MeterTypeStr : MeterType.ToString();
|
||||
switch (eMeterArg)
|
||||
{
|
||||
case EMeterArg.Calibration:
|
||||
return $"-p {PortName} -m {MeterType} --operation write --parameter Calibration --value {arg}";
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation write --parameter Calibration --value {arg}";
|
||||
case EMeterArg.Optohead:
|
||||
return $"-p {PortName} -m {MeterType} --operation write --parameter \"OpticalDataMode\" --value {arg}";
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation write --parameter \"OpticalDataMode\" --value {arg}";
|
||||
default:
|
||||
throw new Exception("Not implemented correct command!");
|
||||
}
|
||||
@@ -68,5 +74,15 @@ namespace NfcC7_DLL.NfcHanler.Utils
|
||||
CmdClientName = cmdClientName;
|
||||
MeterType = meterType;
|
||||
}
|
||||
|
||||
public SerialPortData(
|
||||
string portName,
|
||||
string cmdClientName,
|
||||
string meterType)
|
||||
{
|
||||
PortName = portName;
|
||||
CmdClientName = cmdClientName;
|
||||
MeterTypeStr = meterType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
using System.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
//*****************************************************************************
|
||||
// Copyright 2020 Sensus GmbH Ludwigshafen. All rights reserved.
|
||||
// Author: Venkat, Rajeshwar
|
||||
//*****************************************************************************
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler.Utils
|
||||
namespace NfcC7_DLL.NfcHandler.Utils
|
||||
{
|
||||
public static class Tools
|
||||
{
|
||||
@@ -1,9 +0,0 @@
|
||||
using NfcC7_DLL.NfcHanler.Protocols;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler;
|
||||
|
||||
public class HeadInfo
|
||||
{
|
||||
string SerialNr { get; set; }
|
||||
OptoHeadStatus OptoHeadStatus { get; set; }
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using NfcC7_DLL.NfcHanler.Protocols;
|
||||
using NfcC7_DLL.NfcHanler.Utils;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler;
|
||||
|
||||
public class NFCHeadService
|
||||
{
|
||||
|
||||
private bool activeHandlerSessioEnabled = false;
|
||||
private CliRunner _cliRunner;
|
||||
|
||||
private SerialPortData serialPort;
|
||||
|
||||
public NFCHeadService(SerialPortData serialPort)
|
||||
{
|
||||
this.serialPort = serialPort;
|
||||
ValidateCliFileExistence(true);
|
||||
}
|
||||
|
||||
private CliRunner CliRunner
|
||||
{
|
||||
get
|
||||
{
|
||||
return (_cliRunner != null ?
|
||||
_cliRunner :
|
||||
(_cliRunner = new CliRunner(CliLogging)));
|
||||
}
|
||||
}
|
||||
|
||||
private bool CliLogging{get {return false; }}
|
||||
|
||||
private static readonly Regex OpticalDataModeRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*OpticalDataMode\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
@"|" +
|
||||
@"""OpticalDataMode""\s*:\s*""?(0x[0-9A-Fa-f]+|\d+)""?" + // JSON format (handles hex and decimal)
|
||||
@")",
|
||||
RegexOptions.Compiled);
|
||||
public bool TryGetOpticalDataMode(string result, out string s)
|
||||
{
|
||||
s = null;
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return false;
|
||||
|
||||
var m = OpticalDataModeRegex.Match(result);
|
||||
if (!m.Success)
|
||||
return false;
|
||||
|
||||
// one of the groups will be filled
|
||||
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
||||
? m.Groups[1].Value.Trim()
|
||||
: m.Groups[2].Value.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static readonly Regex DeviceIdRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*Device\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
@"|" +
|
||||
@"""DeviceId""\s*:\s*""?([0-9]+)""?" + // JSON format
|
||||
@")",
|
||||
RegexOptions.Compiled);
|
||||
public bool TryGetDeviceId(string result, out string s)
|
||||
{
|
||||
s = null;
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return false;
|
||||
|
||||
var m = DeviceIdRegex.Match(result);
|
||||
if (!m.Success)
|
||||
return false;
|
||||
|
||||
// one of the groups will be filled
|
||||
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
||||
? m.Groups[1].Value.Trim()
|
||||
: m.Groups[2].Value.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void ValidateCliFileExistence(bool showErrorIfMissing)
|
||||
{
|
||||
if (serialPort != null)
|
||||
{
|
||||
if (!serialPort.CliExists)
|
||||
{
|
||||
throw new Exception("CLI file " + serialPort.SerialPortCmdClientPath + " does not exist! Current path: " + Environment.CurrentDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ////////////
|
||||
/// </summary>
|
||||
public string? GetSerialNr()
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task optoheadDeviceIdTask = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
|
||||
var timeOut = CliRunner.AddTimeOut(5000);
|
||||
var doneTask = CliRunner.WhenAny();
|
||||
if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadDeviceIdTask is Task<string>)
|
||||
{
|
||||
string serialNr;
|
||||
if (optoheadDeviceIdTask.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
string result = (optoheadDeviceIdTask as Task<string>).Result;
|
||||
if (TryGetDeviceId(result, out serialNr))
|
||||
{
|
||||
return serialNr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public OptoHeadStatus SetTestingMode(OptoHeadStatus status)
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task optoheadMode = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead, $"0x{((byte)status):X2}");
|
||||
var timeOut = CliRunner.AddTimeOut(5000);
|
||||
var doneTask = CliRunner.WhenAny();
|
||||
if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadMode is Task<string>)
|
||||
{
|
||||
string strOpticalDataMode;
|
||||
if (optoheadMode.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
string result = (optoheadMode as Task<string>).Result;
|
||||
if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
||||
{
|
||||
byte value;
|
||||
|
||||
if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
||||
else
|
||||
value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
||||
|
||||
OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
||||
return optoheadStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OptoHeadStatus.Unknown;
|
||||
}
|
||||
|
||||
public OptoHeadStatus GetTestingMode()
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task optoheadMode = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead);
|
||||
var timeOut = CliRunner.AddTimeOut(5000);
|
||||
var doneTask = CliRunner.WhenAny();
|
||||
if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadMode is Task<string>)
|
||||
{
|
||||
string strOpticalDataMode;
|
||||
if (optoheadMode.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
string result = (optoheadMode as Task<string>).Result;
|
||||
if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
||||
{
|
||||
byte value;
|
||||
|
||||
if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
||||
else
|
||||
value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
||||
|
||||
OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
||||
return optoheadStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OptoHeadStatus.Unknown;
|
||||
}
|
||||
|
||||
private void SendCommand()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private string RawDataAnswer()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
using System.IO.Ports;
|
||||
using System.Windows.Documents;
|
||||
using NfcC7_DLL.NfcHanler.Protocols;
|
||||
using NfcC7_DLL.NfcHanler.Utils;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler;
|
||||
|
||||
public class OptoHeadService
|
||||
{
|
||||
|
||||
public class Con
|
||||
{
|
||||
public string com = "COM5";
|
||||
public int baudrate = 38400;
|
||||
public int dataBits = 8;
|
||||
public Parity parity = Parity.None;
|
||||
public StopBits stopbits = StopBits.Two;
|
||||
public int readTimeout = 5000;
|
||||
public int writeTimeout = 1000;
|
||||
}
|
||||
|
||||
private Con Connection { get; set; }
|
||||
private SERIAL_Driver driver;
|
||||
/// <summary>
|
||||
/// Filed After Run() is called.
|
||||
/// </summary>
|
||||
public WaterMetrologyData? WaterMetrologyData { get; private set; }
|
||||
|
||||
public OptoHeadService(Con con)
|
||||
{
|
||||
Connection = con;
|
||||
driver = new SERIAL_Driver();
|
||||
}
|
||||
|
||||
public bool CreateSerialConnection()
|
||||
{
|
||||
bool isopen = false;
|
||||
Con con = Connection;
|
||||
|
||||
byte[] message = {0x00};
|
||||
byte[] bytesReceived;
|
||||
|
||||
if (!driver.isOpen())
|
||||
{
|
||||
|
||||
isopen = driver.OpenConnection(
|
||||
con.com,
|
||||
con.baudrate,
|
||||
con.dataBits,
|
||||
con.parity,
|
||||
con.stopbits,
|
||||
con.readTimeout,
|
||||
con.writeTimeout);
|
||||
}
|
||||
|
||||
return isopen;
|
||||
}
|
||||
|
||||
public void CloseSerialConnection()
|
||||
{
|
||||
dissableRunLoop = true;
|
||||
driver.Close();
|
||||
}
|
||||
|
||||
public void RunLoop()
|
||||
{
|
||||
Task.Run(() => Run());
|
||||
}
|
||||
|
||||
|
||||
private bool dissableRunLoop = false;
|
||||
/// <summary>
|
||||
/// Run the service. Catch one communication to WaterMetrologyData field.
|
||||
/// </summary>
|
||||
public void Run()
|
||||
{
|
||||
while (!dissableRunLoop)
|
||||
{
|
||||
WaterMetrologyData = ParseData(RunReading());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
byte[] RunReading()
|
||||
{
|
||||
if (driver.isOpen())
|
||||
{
|
||||
driver.SendMessage(new byte[] {0x00}, 1);
|
||||
return driver.GetRawData();
|
||||
}
|
||||
else
|
||||
{
|
||||
dissableRunLoop = true;
|
||||
}
|
||||
|
||||
return [0xFF];
|
||||
}
|
||||
|
||||
public WaterMetrologyData? ParseData(byte[] data)
|
||||
{
|
||||
try
|
||||
{
|
||||
return WaterMetrologyData.Parse(data, DateTime.Now, "");
|
||||
}catch(Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace NfcC7_DLL.NfcHanler.Protocols;
|
||||
|
||||
public enum OptoHeadStatus : byte
|
||||
{
|
||||
Unknown = 0xFF,
|
||||
OptoHeadDisabled = 0x00,
|
||||
OptoHeadC2 = 0xC2,
|
||||
OptoHeadC7 = 0xC7,
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
namespace NfcC7_DLL.NfcHanler.Protocols;
|
||||
|
||||
public class WaterMetrologyData
|
||||
{
|
||||
private OptoHeadStatus _optoHeadStatus;
|
||||
private WaterMetrologyDataC7 c7Data;
|
||||
private WaterMetrologyDataC2 c2Data;
|
||||
|
||||
public WaterMetrologyDataC7 C7Data { get => c7Data; }
|
||||
public WaterMetrologyDataC2 C2Data { get => c2Data; }
|
||||
public OptoHeadStatus OptoHeadStatus { get => _optoHeadStatus; }
|
||||
|
||||
public static WaterMetrologyData? Parse(byte[] data, DateTime dt, string dutinfo)
|
||||
{
|
||||
if (data.Length < 24)
|
||||
{
|
||||
throw new ArgumentException("Invalid data length for WaterMetrologyData C2.");
|
||||
}
|
||||
WaterMetrologyData waterMetrologyData = new WaterMetrologyData();
|
||||
waterMetrologyData._optoHeadStatus = OptoHeadStatus.Unknown;
|
||||
// Probably C2
|
||||
if(data.Length > 24 && data.Length < 48)
|
||||
{
|
||||
waterMetrologyData.c2Data = WaterMetrologyDataC2.Parse(data, dt, dutinfo);
|
||||
waterMetrologyData._optoHeadStatus = OptoHeadStatus.OptoHeadC2;
|
||||
}
|
||||
// Probably C7
|
||||
else if(data.Length >= 48)
|
||||
{
|
||||
waterMetrologyData.c7Data = WaterMetrologyDataC7.Parse(data, dt, dutinfo);
|
||||
waterMetrologyData._optoHeadStatus = OptoHeadStatus.OptoHeadC7;
|
||||
}
|
||||
|
||||
return waterMetrologyData;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Status: {_optoHeadStatus}, C7Data: {c7Data}, C2Data: {c2Data}";
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;IPERL;HEAT_METERS;</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;IPERL;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -29,7 +29,7 @@
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;IPERL;HEAT_METERS;</DefineConstants>
|
||||
<DefineConstants>TRACE;IPERL;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;LANG_PL;HEAT_METERS;</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;LANG_PL;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
@@ -25,7 +25,7 @@
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;HEAT_METERS;</DefineConstants>
|
||||
<DefineConstants>TRACE;</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("3.9.2149.0")]
|
||||
[assembly: AssemblyFileVersion("3.9.2149.0")]
|
||||
[assembly: AssemblyVersion("3.9.2149.4")]
|
||||
[assembly: AssemblyFileVersion("3.9.2149.4")]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using Common;
|
||||
using log4net;
|
||||
using TBF.Rig.Sequences;
|
||||
|
||||
@@ -11,6 +12,10 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(FlyingStartStopTestOp));
|
||||
public override string ToString() { return string.Format("FlyingStartStopTestOp()"); }
|
||||
|
||||
private DateTime startTimeForSimulation;
|
||||
private bool simulationTimerStarted = false;
|
||||
|
||||
|
||||
/// Arguments of the constructor
|
||||
readonly UniCB uniCB;
|
||||
@@ -123,6 +128,28 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
{
|
||||
log.DebugFormat("Op.Run() opState={0}", opState);
|
||||
|
||||
//Simulation of processing time 25 seconds
|
||||
if (uniCB.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
if (opState == OpState.StartingTest)
|
||||
{
|
||||
startTimeForSimulation = DateTime.Now;
|
||||
simulationTimerStarted = false;
|
||||
}
|
||||
if (opState == OpState.TestInProgress)
|
||||
{
|
||||
if (!simulationTimerStarted)
|
||||
{
|
||||
startTimeForSimulation = DateTime.Now;
|
||||
simulationTimerStarted = true;
|
||||
}
|
||||
else if (DateTime.Now - startTimeForSimulation > TimeSpan.FromSeconds(25))
|
||||
{
|
||||
return Event.TestCompleted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (opState)
|
||||
{
|
||||
case OpState.StartingTest:
|
||||
|
||||
@@ -8,10 +8,9 @@ using System.Windows.Forms;
|
||||
using log4net;
|
||||
using Common;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.Output.DB.SensusOracle;
|
||||
using TBF.Resources;
|
||||
using System.Drawing;
|
||||
using NHibernate;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
{
|
||||
@@ -220,6 +219,25 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
orderComboBox.Text = orderComboBox.Items[0].ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public void AutoClickOkAfterDelay(int delayMs = 10000)
|
||||
{
|
||||
_ = AutoClickInternal(okButton, delayMs);
|
||||
}
|
||||
|
||||
private async Task AutoClickInternal(Button clickButton, int delayMs)
|
||||
{
|
||||
await Task.Delay(delayMs);
|
||||
|
||||
if (clickButton.IsHandleCreated && clickButton.Enabled && clickButton.Visible)
|
||||
{
|
||||
// Invoke on UI thread
|
||||
if (clickButton.InvokeRequired)
|
||||
clickButton.BeginInvoke(new Action(() => clickButton.PerformClick()));
|
||||
else
|
||||
clickButton.PerformClick();
|
||||
}
|
||||
}
|
||||
|
||||
private void okButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
@@ -61,6 +61,15 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
|
||||
CurrentOp currentOp;
|
||||
|
||||
public enum ReadDataOp
|
||||
{
|
||||
None,
|
||||
Start,
|
||||
Busy,
|
||||
Done,
|
||||
}
|
||||
ReadDataOp readDataOp;
|
||||
|
||||
|
||||
public EntryForm() { }
|
||||
|
||||
@@ -112,6 +121,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
|| currentOp == CurrentOp.SendStartDataStream)
|
||||
) throw new Exception("Sequence error");
|
||||
currentOp = CurrentOp.ReadDatastream_StartStates;
|
||||
readDataOp = ReadDataOp.None;
|
||||
//TODO BUMI apply show data in dialog if config required
|
||||
//entryFormCfg.Direction = Direction.S640;
|
||||
//currentOp = CurrentOp.EnterTestStartStates;
|
||||
@@ -122,10 +132,10 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
if (reader != null && reader is PoseidonReader)
|
||||
{
|
||||
PoseidonReader poseidonReader = (reader as PoseidonReader);
|
||||
if (!string.IsNullOrEmpty(poseidonReader.SerialNr)
|
||||
&& waterMeters.Count > iterator)
|
||||
if (waterMeters.Count > iterator)
|
||||
{
|
||||
waterMeters[iterator].SerialNr = poseidonReader.SerialNr;
|
||||
if(!string.IsNullOrEmpty(poseidonReader.SerialNr))
|
||||
waterMeters[iterator].SerialNr = poseidonReader.SerialNr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,8 +145,17 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
|
||||
/// <returns>null (not implemented)</returns>
|
||||
public IOperation ShowAdvancedTestStartFormOp(IRegReader[] regReaders, IList<Results.Entities.WaterMeter> waterMeters, bool isCondOp) { return null; }
|
||||
public IOperation ShowTestCollectFormOp(IRegReader[] regReaders, double volumeRef, double errLimLo, double errLimHi) { return null; }
|
||||
public IOperation ShowAdvancedTestStartFormOp(IRegReader[] regReaders,
|
||||
IList<Results.Entities.WaterMeter> waterMeters, bool isCondOp)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public IOperation ShowTestCollectFormOp(IRegReader[] regReaders, double volumeRef, double errLimLo,
|
||||
double errLimHi)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ShowTestEndFormOp(IRegReader[] regReaders, double refVolume, double errLimLo, double errLimHi)
|
||||
@@ -155,16 +174,17 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
///
|
||||
void OpenBeginningDlg(EntryForm myRef)
|
||||
{
|
||||
if (!ShowForm)
|
||||
if (ShowForm == 0)
|
||||
return;
|
||||
myRef.modelessDlg = new CycleBeginningForm(TBF.Data.WMsCount, myRef.entryFormCfg,
|
||||
ProcessData.SelectedProcedure.OrderInfo != null ? ProcessData.SelectedProcedure.OrderInfo.POName : string.Empty);
|
||||
(myRef.modelessDlg as CycleBeginningForm)?.AutoClickOkAfterDelay();
|
||||
modelessDlg.Show();
|
||||
}
|
||||
///
|
||||
void OpenTestStartStatesDlg(EntryForm myRef)
|
||||
{
|
||||
if (!ShowForm)
|
||||
if (ShowForm == 0)
|
||||
return;
|
||||
myRef.modelessDlg = new TestStartEndForm(myRef.waterMeters.Count, myRef.regReaders, disabled);
|
||||
modelessDlg.Show();
|
||||
@@ -172,7 +192,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
///
|
||||
void OpenTestEndStatesDlg(EntryForm myRef)
|
||||
{
|
||||
if (!ShowForm)
|
||||
if (ShowForm == 0)
|
||||
return;
|
||||
myRef.modelessDlg = new TestStartEndForm(TBF.Data.WMsCount, myRef.regReaders, wmStartStateStr, disabled, refVolume, errLimLo, errLimHi);
|
||||
modelessDlg.Show();
|
||||
@@ -181,15 +201,19 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
if (!ShowForm)
|
||||
readDataOp = ReadDataOp.None;
|
||||
readAndSetDataToMeters = false;
|
||||
filedDataToMeters = false;
|
||||
|
||||
if (ShowForm == 0)
|
||||
return ;
|
||||
|
||||
resultSaved = false;
|
||||
switch (currentOp)
|
||||
{
|
||||
case CurrentOp.SendStartDataStream:
|
||||
ReadAndSetDataToMeters();
|
||||
if (ProcessData.SelectedProcedure.OrderInfo == null || entryFormCfg.Direction != Direction.S640)
|
||||
//ReadAndSetDataToMeters();
|
||||
if (ProcessData.SelectedProcedure.OrderInfo == null)
|
||||
{
|
||||
Program.MainWnd.Invoke(new EntryFormDlgt(OpenBeginningDlg), this);
|
||||
}
|
||||
@@ -209,28 +233,81 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
}
|
||||
|
||||
private bool readAndSetDataToMeters = false;
|
||||
private bool filedDataToMeters = false;
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>Event.ResultsPrinted</returns>
|
||||
public Event Run()
|
||||
{
|
||||
ReadAndSetDataToMeters();
|
||||
if (!readAndSetDataToMeters) // run until not finished
|
||||
readAndSetDataToMeters = ReadAndSetDataToMeters();
|
||||
|
||||
if (!ShowForm)
|
||||
return Event.ModelessFormClosed;
|
||||
|
||||
if (ProcessData.SelectedProcedure.OrderInfo != null && entryFormCfg.Direction == Direction.S640)
|
||||
{
|
||||
for (int i = 0; i < waterMeters.Count; i++)
|
||||
{
|
||||
if (waterMeters[i] != null)
|
||||
waterMeters[i].PurchaseOrder = ProcessData.SelectedProcedure.OrderInfo.POName;
|
||||
}
|
||||
return Event.ModelessFormClosed;
|
||||
}
|
||||
if (ShowForm == 0)
|
||||
if(readAndSetDataToMeters)
|
||||
return Event.ModelessFormClosed;
|
||||
else
|
||||
{
|
||||
return Event.ModelessFormIsOpen;
|
||||
}
|
||||
|
||||
if ((modelessDlg is IHasCompleted) && !(modelessDlg as IHasCompleted).Completed)
|
||||
if (readAndSetDataToMeters && !filedDataToMeters)
|
||||
{
|
||||
return Event.ModelessFormIsOpen;
|
||||
if (regReaders != null)
|
||||
{
|
||||
//add data into dialog
|
||||
int item = 0;
|
||||
TestStartEndForm dlg = (modelessDlg as TestStartEndForm);
|
||||
foreach (var iRegReader in regReaders)
|
||||
{
|
||||
if (iRegReader is PoseidonReader poseidonReader)
|
||||
{
|
||||
if (dlg != null)
|
||||
{
|
||||
if (currentOp == CurrentOp.ReadDatastream_StartStates)
|
||||
{
|
||||
dlg.WMStartState[item] = poseidonReader.BeginWMState;
|
||||
dlg.WMStartStateStr[item] = poseidonReader.BeginWMState.ToString();
|
||||
}
|
||||
|
||||
if (currentOp == CurrentOp.ReadDatastream_EndStates)
|
||||
dlg.WMEndState[item] = poseidonReader.EndWMState;
|
||||
}
|
||||
}
|
||||
|
||||
item++;
|
||||
}
|
||||
|
||||
if (dlg != null)
|
||||
{
|
||||
if (dlg.InvokeRequired)
|
||||
{
|
||||
dlg.BeginInvoke(new Action(() =>
|
||||
{
|
||||
dlg.UpdateValues(currentOp == CurrentOp.ReadDatastream_StartStates, true);
|
||||
if (entryFormCfg.ShowDialogType == ShowDialogType.ContinueAutomatically)
|
||||
{
|
||||
dlg.AutoClickOkAfterDelay();
|
||||
}
|
||||
}));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
dlg.UpdateValues(currentOp == CurrentOp.ReadDatastream_StartStates, true);
|
||||
if (entryFormCfg.ShowDialogType == ShowDialogType.ContinueAutomatically)
|
||||
{
|
||||
dlg.AutoClickOkAfterDelay();
|
||||
}
|
||||
}
|
||||
}
|
||||
filedDataToMeters = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((modelessDlg is IHasCompleted) && !(modelessDlg as IHasCompleted).Completed)
|
||||
{
|
||||
return Event.ModelessFormIsOpen; //ModelessFormClosed ??
|
||||
}
|
||||
|
||||
if (!resultSaved) /// This is to save the result only once
|
||||
@@ -290,11 +367,13 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
modelessDlg = null;
|
||||
}
|
||||
currentOp = CurrentOp.None;
|
||||
readAndSetDataToMeters = false;
|
||||
filedDataToMeters = false;
|
||||
}
|
||||
|
||||
public bool ShowForm
|
||||
public int ShowForm
|
||||
{
|
||||
get { return entryFormCfg == null ? false : entryFormCfg.ShowDialog; }
|
||||
get { return entryFormCfg == null ? ShowDialogType.Hide.GetHashCode() : entryFormCfg.ShowDialogType.GetHashCode(); }
|
||||
set {} // only for read - svia dilalog
|
||||
}
|
||||
|
||||
@@ -303,13 +382,15 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
get { return entryFormCfg == null ? false : entryFormCfg.SaveCommunication;}
|
||||
}
|
||||
|
||||
//private long GetMaxtime()
|
||||
|
||||
public bool ReadAndSetDataToMeters()
|
||||
{
|
||||
bool bOperationSuccess = false;
|
||||
if (currentOp == CurrentOp.SendStartDataStream)
|
||||
{
|
||||
bool finishedReading = regReaders == null; // we can work only with register readers
|
||||
while (!finishedReading)
|
||||
while (!finishedReading) //TODO BUMI lock - fuck ?
|
||||
{
|
||||
bool bAllReadersFinished = true;
|
||||
foreach (var iRegReader in regReaders )
|
||||
@@ -326,6 +407,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
/// Send start data stream
|
||||
poseidonReader.Run();
|
||||
readDataOp = ReadDataOp.Start;
|
||||
if (!(poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Done
|
||||
|| poseidonReader.CurrentOp == PoseidonReader.CurrentPoseidonOp.Error))
|
||||
{
|
||||
@@ -337,10 +419,11 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
if (bAllReadersFinished)
|
||||
{
|
||||
finishedReading = true;
|
||||
readDataOp = ReadDataOp.Done;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -350,7 +433,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
|| (currentOp == CurrentOp.ReadDatastream_EndStates))
|
||||
{
|
||||
bool finishedReading = regReaders == null; // we can work only with register readers
|
||||
while (!finishedReading)
|
||||
while (!finishedReading) //TODO BUMI lock - fuck ?
|
||||
{
|
||||
bool bAllReadersFinished = true;
|
||||
foreach (var iRegReader in regReaders )
|
||||
@@ -383,7 +466,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Threading.Thread.Sleep(100);
|
||||
System.Threading.Thread.Sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
@@ -52,6 +53,15 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
#endif
|
||||
Count,
|
||||
}
|
||||
|
||||
public enum ShowDialogType
|
||||
{
|
||||
[Description("Do not Show")] Hide,
|
||||
[Description("Continue Automatically")] ContinueAutomatically,
|
||||
[Description("Continue Manually")] ContinueManually,
|
||||
Count,
|
||||
|
||||
}
|
||||
|
||||
public class EntryFormCfg : ComponentCfgBase, IComponentCfg, IParamsProvider
|
||||
{
|
||||
@@ -69,6 +79,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
public Direction Direction;
|
||||
public Orders Orders;
|
||||
public bool ShowDialog;
|
||||
public ShowDialogType ShowDialogType;
|
||||
public bool SaveCommunication;
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
@@ -89,7 +100,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
{
|
||||
Direction = Direction.Forward_RL;
|
||||
Orders = Orders.Arbitrary;
|
||||
ShowDialog = false;
|
||||
ShowDialogType = ShowDialogType.Hide;
|
||||
SaveCommunication = false;
|
||||
}
|
||||
|
||||
@@ -115,8 +126,9 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
for (Orders o = 0; o < Orders.Count; o++) list.Add(o.ToDescription());
|
||||
return list;
|
||||
case 2:
|
||||
list.Add("True");
|
||||
list.Add("False");
|
||||
list.Add(ShowDialogType.Hide.ToDescription());
|
||||
list.Add(ShowDialogType.ContinueAutomatically.ToDescription());
|
||||
list.Add(ShowDialogType.ContinueManually.ToDescription());
|
||||
return list;
|
||||
case 3:
|
||||
list.Add("True");
|
||||
@@ -126,6 +138,19 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryFromInt<TEnum>(int value, out TEnum result)
|
||||
where TEnum : struct, Enum
|
||||
{
|
||||
if (Enum.IsDefined(typeof(TEnum), value))
|
||||
{
|
||||
result = (TEnum)(object)value;
|
||||
return true;
|
||||
}
|
||||
|
||||
result = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public string ToString(int i)
|
||||
@@ -134,10 +159,10 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
{
|
||||
case 0: return Direction.ToDescription();
|
||||
case 1: return Orders.ToDescription();
|
||||
case 2: return ShowDialog.ToString();
|
||||
case 2: return ShowDialogType.ToDescription();
|
||||
case 3: return SaveCommunication.ToString();
|
||||
default:
|
||||
return string.Format("Name={0}, Direction={1}, Orders={2}, ShowDialog={3}, StoreCommunication={4}", Name, Direction, Orders, ShowDialog, SaveCommunication);
|
||||
return string.Format("Name={0}, Direction={1}, Orders={2}, ShowDialog={3}, StoreCommunication={4}", Name, Direction, Orders, ShowDialogType, SaveCommunication);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,11 +189,14 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
bool lastSetting = ShowDialog;
|
||||
if (str == "True") ShowDialog = true;
|
||||
else ShowDialog = false;
|
||||
if (lastSetting != ShowDialog)
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
ShowDialogType lastSetting = ShowDialogType;
|
||||
for (ShowDialogType s = 0; s < ShowDialogType.Count; s++)
|
||||
if (s.ToDescription() == str)
|
||||
{
|
||||
ShowDialogType = s;
|
||||
if (lastSetting != ShowDialogType)
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@@ -196,6 +224,11 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
if (ParamValues(i).Contains(str)) return true;
|
||||
break;
|
||||
case 2:
|
||||
bool exists = Enum.GetValues(typeof(ShowDialogType))
|
||||
.Cast<ShowDialogType>()
|
||||
.Any(d => d.ToDescription() == str);
|
||||
if (exists) return true;
|
||||
break;
|
||||
case 3:
|
||||
if (str == "True" || str == "False") return true;
|
||||
break;
|
||||
@@ -212,7 +245,7 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
{
|
||||
prms.Direction = this.Direction;
|
||||
prms.Orders = this.Orders;
|
||||
prms.ShowDialog = this.ShowDialog;
|
||||
prms.ShowDialogType = this.ShowDialogType;
|
||||
prms.SaveCommunication = this.SaveCommunication;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using log4net;
|
||||
using TBF.Rig.GenericDevices;
|
||||
@@ -99,9 +100,12 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
this.disabled = disabled;
|
||||
|
||||
ShuffleTextBoxes();
|
||||
ResizeDlgToFitEnabledControls();
|
||||
|
||||
WMStartState = new double[waterMetersCount];
|
||||
WMStartStateStr = new string[waterMetersCount];
|
||||
|
||||
SetUiBusy(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -130,8 +134,41 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
this.warningLimHi = 2 * errLimHi;
|
||||
|
||||
ShuffleTextBoxes();
|
||||
ResizeDlgToFitEnabledControls();
|
||||
|
||||
|
||||
WMEndState = new double[waterMetersCount];
|
||||
|
||||
SetUiBusy(true);
|
||||
}
|
||||
|
||||
private void SetUiBusy(bool busy, long deltaTime = -1)
|
||||
{
|
||||
// show wait cursor for form and children
|
||||
this.UseWaitCursor = busy;
|
||||
|
||||
// block editing textboxes
|
||||
for (int i = 0; i < enabledTextBoxes.Count; i++)
|
||||
{
|
||||
enabledTextBoxes[i].Enabled = !busy;
|
||||
}
|
||||
|
||||
// disable buttons while busy
|
||||
if (okButton != null) okButton.Enabled = !busy;
|
||||
|
||||
|
||||
// show/hide "loading..." label
|
||||
if (loadingLabel != null)
|
||||
{
|
||||
loadingLabel.Visible = busy;
|
||||
loadingLabel.Text = "Loading...";
|
||||
if (deltaTime > 0)
|
||||
{
|
||||
//show delta time in label
|
||||
loadingLabel.Visible = true;
|
||||
loadingLabel.Text = string.Format("Get: {0} s", deltaTime/1000.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -159,6 +196,43 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
TextBoxesCount = TBF.Data.WMsCount;
|
||||
}
|
||||
}
|
||||
|
||||
void ResizeDlgToFitEnabledControls()
|
||||
{
|
||||
int xMax = 0;
|
||||
int yMax = 0;
|
||||
GetMaxDimensions(startTextBoxes,WaterMetersCount,ref xMax, ref yMax);
|
||||
GetMaxDimensions(endTextBoxes,WaterMetersCount, ref xMax, ref yMax);
|
||||
|
||||
int shapeGap = 50;
|
||||
okButton.Left = xMax + shapeGap;
|
||||
xMax = okButton.Left + okButton.Width;
|
||||
|
||||
Width = xMax + shapeGap;
|
||||
Height = yMax + shapeGap;
|
||||
}
|
||||
|
||||
private void GetMaxDimensions(TextBox[] textBoxes, int waterMetersCount, ref int xMax, ref int yMax)
|
||||
{
|
||||
for (int i = 0; i < waterMetersCount; i++)
|
||||
{
|
||||
if (textBoxes[i].Left + textBoxes[i].Width > xMax)
|
||||
xMax = textBoxes[i].Left + textBoxes[i].Width;
|
||||
if (textBoxes[i].Top + textBoxes[i].Height > yMax)
|
||||
yMax = textBoxes[i].Top + textBoxes[i].Height;
|
||||
}
|
||||
}
|
||||
|
||||
// private void GetMaxDimensions(TextBox[] textBoxes, ref int xMax, ref int yMax)
|
||||
// {
|
||||
// for (int i = 0; i < textBoxes.Length; i++)
|
||||
// {
|
||||
// if(!textBoxes[i].Visible)
|
||||
// continue;
|
||||
// if (textBoxes[i].Left + textBoxes[i].Width > xMax) xMax = textBoxes[i].Left + textBoxes[i].Width;
|
||||
// if (textBoxes[i].Top + textBoxes[i].Height > yMax) yMax = textBoxes[i].Top + textBoxes[i].Height;
|
||||
// }
|
||||
// }
|
||||
|
||||
private void CycleEndForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
@@ -211,6 +285,43 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateValues(bool stratValue = true, bool enableEdit = false, long deltaTime = -1)
|
||||
{
|
||||
// Ensure we are on the UI thread
|
||||
if (InvokeRequired)
|
||||
{
|
||||
BeginInvoke(new Action(() => UpdateValues(stratValue, enableEdit)));
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < TextBoxesCount; i++)
|
||||
{
|
||||
if (stratValue)
|
||||
{
|
||||
if (WMStartStateStr != null && i < WMStartStateStr.Length)
|
||||
{
|
||||
startTextBoxes[i].Text = WMStartStateStr[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// small bugfix: check WMEndState, not WMStartStateStr
|
||||
if ((WMEndState != null && i < WMEndState.Length) &&
|
||||
(WMStartStateStr != null && i < WMStartStateStr.Length && WMStartStateStr[i] != ""))
|
||||
{
|
||||
endTextBoxes[i].Text = WMEndState[i].ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (enableEdit)
|
||||
{
|
||||
SetUiBusy(false, deltaTime);
|
||||
}
|
||||
// if you also need to enable/disable editing, do it here,
|
||||
// it's now safely on the UI thread.
|
||||
}
|
||||
|
||||
void Localize()
|
||||
{
|
||||
Text = Strings.Water_Meter_States;
|
||||
@@ -258,6 +369,26 @@ namespace TBF.Rig.DataEntry.PoseidonCmd
|
||||
completed = true;
|
||||
Close();
|
||||
}
|
||||
|
||||
public void AutoClickOkAfterDelay(int delayMs = 10000)
|
||||
{
|
||||
_ = AutoClickInternal(okButton, delayMs);
|
||||
}
|
||||
|
||||
private async Task AutoClickInternal(Button okButton, int delayMs)
|
||||
{
|
||||
await Task.Delay(delayMs);
|
||||
|
||||
if (okButton.IsHandleCreated && okButton.Enabled && okButton.Visible)
|
||||
{
|
||||
// Invoke on UI thread
|
||||
if (okButton.InvokeRequired)
|
||||
okButton.BeginInvoke(new Action(() => okButton.PerformClick()));
|
||||
else
|
||||
okButton.PerformClick();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region Forced close handling
|
||||
|
||||
|
||||
+610
-397
File diff suppressed because it is too large
Load Diff
@@ -21,6 +21,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
public partial class CycleBeginningForm : Form, GenericDevices.IHasCompleted
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(CycleBeginningForm));
|
||||
private static readonly ILog log_selected = LogManager.GetLogger("PurchaseOrderHistory");
|
||||
|
||||
/// <summary> Number of water meters </summary>
|
||||
public readonly int WaterMetersCount;
|
||||
@@ -264,6 +265,11 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
Disabled[i] = !checkBoxes[i].Checked;
|
||||
}
|
||||
|
||||
//TODO create logger to log selected items and their order and Order number
|
||||
string snTextArrString = SNText != null ? string.Join(", ", SNText) : string.Empty;
|
||||
log_selected.DebugFormat("Purchase DLG - Selected Order: {0}, Last selected Box: {1}, All items: {2}",
|
||||
orderComboBox.Text, purchaseBoxComboBox.Text,snTextArrString);
|
||||
|
||||
completed = true;
|
||||
Close();
|
||||
}
|
||||
@@ -718,6 +724,17 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
.SelectMany(pBox => pBox.PurchaseWaterMeterDataList)
|
||||
.Select(pWM => pWM.SerialNo);
|
||||
|
||||
try
|
||||
{
|
||||
string[] iEnumerable = serialNumbers as string[] ?? serialNumbers.ToArray();
|
||||
log_selected.Debug(
|
||||
$"Selected order: {choosenOrder} box: {choosenBox} possible serial numbers (form DB): {string.Join(", ", iEnumerable)}");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log_selected.Error("Error loading serial numbers: " + e);
|
||||
}
|
||||
|
||||
//enable behaviour type
|
||||
bool addOnEndOnly = false;
|
||||
|
||||
@@ -726,6 +743,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
|
||||
if (countOfFreeBoxes < serialNumbers.Count())
|
||||
{
|
||||
log_selected.Debug(">" + serialNumbers.Count() + " Serial Numbers in box as we have free positions!");
|
||||
MessageBox.Show(this, "We have more Serial Numbers in box as we have free positions!", "Warning",
|
||||
MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
return;
|
||||
@@ -753,6 +771,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
if (lastComboBoxSerialNo >= 0 || lastComboBoxSerialNo < enabledComboBoxes.Count)
|
||||
{
|
||||
comboBoxes[lastComboBoxSerialNo].Text = serialNumber;
|
||||
log_selected.Debug($"Added serial no: {serialNumber} to pos: {lastComboBoxSerialNo}");
|
||||
lastComboBoxSerialNo++;
|
||||
}
|
||||
}
|
||||
@@ -762,6 +781,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
if (iNextFreeNumber >= 0 || iNextFreeNumber < enabledComboBoxes.Count)
|
||||
{
|
||||
comboBoxes[iNextFreeNumber].Text = serialNumber;
|
||||
log_selected.Debug($"Added serial no: {serialNumber} to pos: {iNextFreeNumber}");
|
||||
lastComboBoxSerialNo = iNextFreeNumber;
|
||||
}
|
||||
}
|
||||
@@ -774,6 +794,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
|
||||
|
||||
if (!noImplementedSerialNumbers.IsEmpty())
|
||||
{
|
||||
log_selected.Debug("No implemented serial numbers: " + noImplementedSerialNumbers);
|
||||
MessageBox.Show(this,
|
||||
string.Format("The following serial numbers were not implemented: {0}", noImplementedSerialNumbers),
|
||||
"Serial Numbers repeating!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
||||
|
||||
@@ -2,7 +2,10 @@ namespace TBF.Rig.GenericDevices
|
||||
{
|
||||
public interface IHasFromUNIDisablePossibility
|
||||
{
|
||||
bool ShowForm { get; set; }
|
||||
/// <summary>
|
||||
/// 0 - disabled, > 1 - enabled but can have variable uses how form is shown
|
||||
/// </summary>
|
||||
int ShowForm { get; set; }
|
||||
|
||||
bool ReadAndSetDataToMeters();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/// Copyright (c) 2013-2022 Sensus Slovensko a.s.
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
|
||||
namespace TBF.Rig
|
||||
@@ -25,7 +26,8 @@ namespace TBF.Rig
|
||||
{
|
||||
for (int i = 0; i < Sequences.ProcessData.WMsCount; i++)
|
||||
{
|
||||
RegisterReaders[i] = TbfComponents.FindComponent(entity.GetSensor(i), components) as IRegReader;
|
||||
IComponent findComponent = TbfComponents.FindComponent(entity.GetSensor(i), components);
|
||||
RegisterReaders[i] = findComponent as IRegReader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
/// Copyright (c) 2015-2021 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR
|
||||
{
|
||||
public enum MessageID
|
||||
@@ -103,7 +105,7 @@ namespace TBF.Rig.RegisterReaders.CommonRR
|
||||
|
||||
public enum CommunicationInterface
|
||||
{
|
||||
RFID,
|
||||
NFC
|
||||
[Description("RFID")] RFID,
|
||||
[Description("NFC")] NFC
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
@@ -13,12 +14,12 @@ namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
public int ThreadId;
|
||||
public int WMNr0; /// 0-based water meter position
|
||||
public IPerlReader Ihead;
|
||||
public ISmartReader Ihead;
|
||||
public Results.Entities.WaterMeter Wm;
|
||||
public string CommMessage;
|
||||
public CommErr CommErr;
|
||||
|
||||
public CommCompletedEventArgs(int threadId, int wmNr0, IPerlReader ihead, Results.Entities.WaterMeter wm, string commMessage, CommErr commErr)
|
||||
public CommCompletedEventArgs(int threadId, int wmNr0, ISmartReader ihead, Results.Entities.WaterMeter wm, string commMessage, CommErr commErr)
|
||||
{
|
||||
this.ThreadId = threadId;
|
||||
this.WMNr0 = wmNr0;
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
internal class NfcServices
|
||||
{
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
internal static int ReadRequest(ITestMethodCfg cfg, IntIPerlReader iperlHead, MCI_Protocol.StructName structName, int offset, int length, out byte[] buffer)
|
||||
internal static int ReadRequest(ITestMethodCfg cfg, ISmartReader iperlHead, MCI_Protocol.StructName structName, int offset, int length, out byte[] buffer)
|
||||
{
|
||||
for (int i = 0; i < cfg.MaxCommRetries; i++)
|
||||
{
|
||||
@@ -59,7 +59,7 @@ namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
return 3;
|
||||
}
|
||||
|
||||
internal static int WriteRequest(ITestMethodCfg cfg, IntIPerlReader iperlHead, MCI_Protocol.StructName structName, int offset, int length, byte[] buffer)
|
||||
internal static int WriteRequest(ITestMethodCfg cfg, ISmartReader iperlHead, MCI_Protocol.StructName structName, int offset, int length, byte[] buffer)
|
||||
{
|
||||
NfcDataHandler _nfcDataHandler = new NfcDataHandler();
|
||||
MessageEventHandlers(_nfcDataHandler);
|
||||
@@ -85,7 +85,7 @@ namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
}
|
||||
}
|
||||
|
||||
private static void OpenConnection(NfcDataHandler nfcDataHandler, ITestMethodCfg cfg, IntIPerlReader iperlHead)
|
||||
private static void OpenConnection(NfcDataHandler nfcDataHandler, ITestMethodCfg cfg, ISmartReader iperlHead)
|
||||
{
|
||||
string comPort = $"COM{iperlHead.RfidComPortNr}";
|
||||
int retryCount = 0 ;
|
||||
|
||||
@@ -3,16 +3,42 @@
|
||||
///
|
||||
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
public class OptoReceivedEventArgs : EventArgs
|
||||
{
|
||||
public string Data;
|
||||
public WaterMetrologyData WaterMetrologyData;
|
||||
public byte[] RawData;
|
||||
|
||||
public OptoReceivedEventArgs(string data)
|
||||
{
|
||||
this.Data = data;
|
||||
WaterMetrologyData = null;
|
||||
RawData = null;
|
||||
}
|
||||
|
||||
public OptoReceivedEventArgs(string data, WaterMetrologyData waterMetrologyData)
|
||||
{
|
||||
this.Data = data;
|
||||
this.WaterMetrologyData = waterMetrologyData;
|
||||
RawData = null;
|
||||
}
|
||||
|
||||
public OptoReceivedEventArgs(byte[] data)
|
||||
{
|
||||
this.RawData = data;
|
||||
Data = null;
|
||||
WaterMetrologyData = null;
|
||||
}
|
||||
|
||||
public OptoReceivedEventArgs(WaterMetrologyData data)
|
||||
{
|
||||
WaterMetrologyData = data;
|
||||
Data = null;
|
||||
RawData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(SmartCommunicationForm));
|
||||
|
||||
internal static int ReadRequest(ITestMethodCfg cfg, IntIPerlReader iperlHead, MessageID messageID, int offset, int length, out byte[] buffer)
|
||||
internal static int ReadRequest(ITestMethodCfg cfg, ISmartReader iperlHead, MessageID messageID, int offset, int length, out byte[] buffer)
|
||||
{
|
||||
for (int i = 0; i < cfg.MaxCommRetries; i++)
|
||||
{
|
||||
@@ -83,7 +83,7 @@ namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
return 3;
|
||||
}
|
||||
|
||||
internal static int WriteRequest(ITestMethodCfg cfg, IntIPerlReader iperlHead, MessageID messageID, int offset, int length, byte[] buffer)
|
||||
internal static int WriteRequest(ITestMethodCfg cfg, ISmartReader iperlHead, MessageID messageID, int offset, int length, byte[] buffer)
|
||||
{
|
||||
RfidLogic writer = new RfidLogic($"COM{iperlHead.RfidComPortNr}");
|
||||
string payload = RfidHelper.ConvertByteArrayToHexString(buffer);
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
const int Q2CorrFactorsAddr = iPerlCommunicationConstants.Q2CorrFactorsAddr;
|
||||
|
||||
internal static int ReadRequest(IntIPerlReader iperlHead, MessageID messageID, int offset, int length, out byte[] buffer)
|
||||
internal static int ReadRequest(ISmartReader iperlHead, MessageID messageID, int offset, int length, out byte[] buffer)
|
||||
{
|
||||
byte[] configurationBuffer = new byte[ConfigStruct.Length] { 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
byte[] calibrationBuffer = new byte[CalibrationStructV4.Length] { 3, 0, 150, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 150, 10 };
|
||||
@@ -37,13 +37,13 @@ namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
return iperlHead.Name.Equals("iPerl13") ? 2 : 0; /// Simulates an error on position 13
|
||||
}
|
||||
|
||||
internal static int WriteRequest(ITestMethodCfg cfg, IntIPerlReader iperlHead, MessageID messageID, int offset,
|
||||
internal static int WriteRequest(ITestMethodCfg cfg, ISmartReader iperlHead, MessageID messageID, int offset,
|
||||
int length, byte[] buffer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Array GetPCB(IntIPerlReader iperlHead)
|
||||
private static Array GetPCB(ISmartReader iperlHead)
|
||||
{
|
||||
string pcbStr = iperlHead.RfidComPortNr.ToString().PadRight(10,'0') + iperlHead.Position.ToString("D2");
|
||||
long decVal = Convert.ToInt64(pcbStr);
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.IPerlReader.implementations;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
{
|
||||
public class Factory: IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return this.GetType().Namespace.Substring(8); } }
|
||||
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
public IComponent DummyComponent() { return new SmartReader(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new SmartReader(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new iPerlReaderUNI.IPerlCfg(this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(iPerlReaderUNI.IPerlCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -6,7 +6,7 @@ using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
{
|
||||
public class IPerlCfg : ComponentCfgBase, Generic.IComponentCfg
|
||||
{
|
||||
@@ -14,7 +14,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
public IComponentCfgCtrl GetControl(IList<Component> cmpntEntities)
|
||||
{
|
||||
return new IPerlCfgCtrl();
|
||||
return new IPerlUniCfgCtrl();
|
||||
}
|
||||
|
||||
|
||||
+6
-6
@@ -11,24 +11,24 @@ using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
{
|
||||
public partial class IPerlCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
public partial class IPerlUniCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
IPerlCfg config;
|
||||
iPerlReaderUNI.IPerlCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as IPerlCfg;
|
||||
config = value as iPerlReaderUNI.IPerlCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public IPerlCfgCtrl()
|
||||
public IPerlUniCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
@@ -58,7 +58,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
muxBoardNrTextBox.Text = config.MuxBoardNr.ToString();
|
||||
groupTextBox.Text = config.Group.ToString();
|
||||
comboBoxCommunicationInterface.SelectedItem = config.CommunicationInterface.ToString();
|
||||
tabPage2.Controls.Add(new IperlHeadTestCtrl(config));
|
||||
tabPage2.Controls.Add(new IperlUniHeadTestCtrl(config));
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
{
|
||||
partial class IPerlCfgCtrl
|
||||
partial class IPerlUniCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -390,7 +390,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.tabControl1);
|
||||
this.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.Name = "IPerlCfgCtrl";
|
||||
this.Name = "IPerlUniCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(617, 438);
|
||||
this.Load += new System.EventHandler(this.WaterMeterCfgCtrl_Load);
|
||||
this.tabControl1.ResumeLayout(false);
|
||||
@@ -0,0 +1,137 @@
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
{
|
||||
partial class IperlUniHeadTestCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.optoTestGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.optoListBox = new System.Windows.Forms.ListBox();
|
||||
this.rfidOutputListBox = new System.Windows.Forms.ListBox();
|
||||
this.RfidTestGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.rfidCommandComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.commandTestButton = new System.Windows.Forms.Button();
|
||||
this.optoTestGroupBox.SuspendLayout();
|
||||
this.RfidTestGroupBox.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// optoTestGroupBox
|
||||
//
|
||||
this.optoTestGroupBox.Controls.Add(this.optoListBox);
|
||||
this.optoTestGroupBox.Location = new System.Drawing.Point(5, 4);
|
||||
this.optoTestGroupBox.Name = "optoTestGroupBox";
|
||||
this.optoTestGroupBox.Size = new System.Drawing.Size(591, 161);
|
||||
this.optoTestGroupBox.TabIndex = 2;
|
||||
this.optoTestGroupBox.TabStop = false;
|
||||
this.optoTestGroupBox.Text = "Opto-data";
|
||||
//
|
||||
// optoListBox
|
||||
//
|
||||
this.optoListBox.FormattingEnabled = true;
|
||||
this.optoListBox.ItemHeight = 16;
|
||||
this.optoListBox.Location = new System.Drawing.Point(7, 22);
|
||||
this.optoListBox.Name = "optoListBox";
|
||||
this.optoListBox.Size = new System.Drawing.Size(573, 132);
|
||||
this.optoListBox.TabIndex = 0;
|
||||
//
|
||||
// rfidOutputListBox
|
||||
//
|
||||
this.rfidOutputListBox.FormattingEnabled = true;
|
||||
this.rfidOutputListBox.ItemHeight = 16;
|
||||
this.rfidOutputListBox.Location = new System.Drawing.Point(5, 54);
|
||||
this.rfidOutputListBox.Name = "rfidOutputListBox";
|
||||
this.rfidOutputListBox.SelectionMode = System.Windows.Forms.SelectionMode.None;
|
||||
this.rfidOutputListBox.Size = new System.Drawing.Size(575, 164);
|
||||
this.rfidOutputListBox.TabIndex = 3;
|
||||
//
|
||||
// RfidTestGroupBox
|
||||
//
|
||||
this.RfidTestGroupBox.Controls.Add(this.rfidOutputListBox);
|
||||
this.RfidTestGroupBox.Controls.Add(this.label2);
|
||||
this.RfidTestGroupBox.Controls.Add(this.rfidCommandComboBox);
|
||||
this.RfidTestGroupBox.Controls.Add(this.commandTestButton);
|
||||
this.RfidTestGroupBox.Location = new System.Drawing.Point(5, 171);
|
||||
this.RfidTestGroupBox.Name = "RfidTestGroupBox";
|
||||
this.RfidTestGroupBox.Size = new System.Drawing.Size(591, 224);
|
||||
this.RfidTestGroupBox.TabIndex = 3;
|
||||
this.RfidTestGroupBox.TabStop = false;
|
||||
this.RfidTestGroupBox.Text = "RFID / NFC data";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(2, 25);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(69, 16);
|
||||
this.label2.TabIndex = 2;
|
||||
this.label2.Text = "Command";
|
||||
//
|
||||
// rfidCommandComboBox
|
||||
//
|
||||
this.rfidCommandComboBox.FormattingEnabled = true;
|
||||
this.rfidCommandComboBox.Location = new System.Drawing.Point(86, 19);
|
||||
this.rfidCommandComboBox.Name = "rfidCommandComboBox";
|
||||
this.rfidCommandComboBox.Size = new System.Drawing.Size(341, 24);
|
||||
this.rfidCommandComboBox.TabIndex = 1;
|
||||
//
|
||||
// commandTestButton
|
||||
//
|
||||
this.commandTestButton.Location = new System.Drawing.Point(449, 19);
|
||||
this.commandTestButton.Name = "commandTestButton";
|
||||
this.commandTestButton.Size = new System.Drawing.Size(126, 24);
|
||||
this.commandTestButton.TabIndex = 0;
|
||||
this.commandTestButton.Text = "Send command";
|
||||
this.commandTestButton.UseVisualStyleBackColor = true;
|
||||
this.commandTestButton.MouseClick += new System.Windows.Forms.MouseEventHandler(this.CommandTestButtonClick);
|
||||
//
|
||||
// IperlHeadTestCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.optoTestGroupBox);
|
||||
this.Controls.Add(this.RfidTestGroupBox);
|
||||
this.Name = "IperlUniHeadTestCtrl";
|
||||
this.Size = new System.Drawing.Size(611, 432);
|
||||
this.Load += new System.EventHandler(this.UserControl_Load);
|
||||
this.optoTestGroupBox.ResumeLayout(false);
|
||||
this.RfidTestGroupBox.ResumeLayout(false);
|
||||
this.RfidTestGroupBox.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox optoTestGroupBox;
|
||||
private System.Windows.Forms.ListBox rfidOutputListBox;
|
||||
private System.Windows.Forms.GroupBox RfidTestGroupBox;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.ComboBox rfidCommandComboBox;
|
||||
private System.Windows.Forms.Button commandTestButton;
|
||||
private System.Windows.Forms.ListBox optoListBox;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl.communication;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.implementations;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
{
|
||||
public partial class IperlUniHeadTestCtrl : UserControl
|
||||
{
|
||||
private IUniHeadTestCtrl _ctrl;
|
||||
private IUniHeadTestCtrl Ctrl { get => _ctrl; }
|
||||
|
||||
|
||||
|
||||
|
||||
public IperlUniHeadTestCtrl(iPerlReaderUNI.IPerlCfg config)
|
||||
{
|
||||
this._ctrl = new PoseidonImplHeadTestCtrl();
|
||||
Ctrl.config = config;
|
||||
InitializeComponent();
|
||||
if (config == null) return;
|
||||
|
||||
SmartCommunicationForm.TestMethodCfg = new TestMethodCfg(null); // default values for iPerlCommunication
|
||||
|
||||
foreach(var head in ProcessData.SmartHeadsUni)
|
||||
{
|
||||
if (head != null && head.Name == config.Name) { Ctrl.ISmartReader = head; }
|
||||
}
|
||||
|
||||
rfidCommandComboBox.DisplayMember = "Name";
|
||||
rfidCommandComboBox.ValueMember = "Value";
|
||||
var items = Ctrl.GetComboOperationsPairs();
|
||||
/*
|
||||
// CTRL+ALT+double click - hidden poweruser menu
|
||||
if (((Keyboard.ModifierKeys & Keys.Control) == Keys.Control) && ((Keyboard.ModifierKeys & Keys.Alt) == Keys.Alt) && Users.CurrentUser.AuthorizedAs == AuthorizedAs.PowerUser)
|
||||
{
|
||||
Array.Resize(ref items, items.Length + 1);
|
||||
items[items.Length - 1] = new { Name = "Kluc", Value = "Kluc" };
|
||||
}
|
||||
*/
|
||||
rfidCommandComboBox.DataSource = items.Select(i => i.Name).ToArray();
|
||||
|
||||
Ctrl.Initialize();
|
||||
|
||||
Ctrl.OptoReceivedHandler += (EventHandler<OptoReceivedEventArgs>)((sndr, args) =>
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
this.Invoke((Delegate)new EventHandler<OptoReceivedEventArgs>(this.OnOptoReceived2), sndr, (object)args);
|
||||
else
|
||||
this.OnOptoReceived2(sndr, args);
|
||||
});
|
||||
}
|
||||
|
||||
public void OnOptoReceived2(object sender, OptoReceivedEventArgs args)
|
||||
{
|
||||
optoListBox.Items.Insert(0,args.Data);
|
||||
}
|
||||
|
||||
private void CommandTestButtonClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
Ctrl.CommandTestButtonClick(sender, e, new Arguments()
|
||||
{
|
||||
ISmartReader = Ctrl.ISmartReader,
|
||||
OptoListBox = optoListBox,
|
||||
RfidCommandComboBox = rfidCommandComboBox,
|
||||
RfidOutputListBox = rfidOutputListBox
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void UserControl_Load(object sender, EventArgs e)
|
||||
{
|
||||
this.ParentForm.FormClosing += new FormClosingEventHandler(ParentForm_FormClosing);
|
||||
}
|
||||
|
||||
void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
//OnHandleDestroyed(new EventArgs());
|
||||
Ctrl.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Windows.Forms;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl.communication;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.test;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader.implementations
|
||||
{
|
||||
public class IPerlImplHeadTestCtrl : IUniHeadTestCtrl
|
||||
{
|
||||
Thread optoThread;
|
||||
public ISmartReader ISmartReader { get; set; }
|
||||
public bool stopWorkerThread { get; set; }
|
||||
public event EventHandler<OptoReceivedEventArgs> OptoReceivedHandler;
|
||||
|
||||
public IComponentCfg
|
||||
|
||||
|
||||
config { get; set; }
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
stopWorkerThread = false;
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
stopWorkerThread = true;
|
||||
if (optoThread != null)
|
||||
{
|
||||
optoThread.Abort();
|
||||
}
|
||||
}
|
||||
|
||||
private const string ReadPCBCmd = "ReadPCB";
|
||||
private const string SetTestModeCmd = "SetTestMode";
|
||||
private const string SetActiveModeCmd = "SetActiveMode";
|
||||
private const string ReadOptoDataCmd = "ReadOptoData";
|
||||
private const string StopReadOptoDataCmd = "StopReadOptoData";
|
||||
private const string ResetNfcHeadCmd = "ResetNfcHead";
|
||||
private const string SetNfcHeadCmd = "SetNfcHead";
|
||||
private const string SetRfidHeadCmd = "SetRfidHead";
|
||||
private const string EmptyCmd = "";
|
||||
|
||||
private static readonly Dictionary<string, string> ItemsForIperlOperations = new Dictionary<string, string>
|
||||
{
|
||||
{"Read PCB", ReadPCBCmd},
|
||||
{"Set Test Mode", SetTestModeCmd},
|
||||
{"Set Active Mode", SetActiveModeCmd},
|
||||
#if DEBUG
|
||||
{"Start Read Opto Data", ReadOptoDataCmd},
|
||||
{"Stop Read Opto Data", StopReadOptoDataCmd},
|
||||
#endif
|
||||
{" ", EmptyCmd},
|
||||
{"Reset NFC Head", ResetNfcHeadCmd},
|
||||
{"Set NFC Head Interface", SetNfcHeadCmd},
|
||||
{"Set RFID Head interface", SetRfidHeadCmd}
|
||||
};
|
||||
|
||||
public (string Name, string Value)[] GetComboOperationsPairs()
|
||||
{
|
||||
return ItemsForIperlOperations.Select(kvp => (kvp.Key, kvp.Value)).ToArray();
|
||||
}
|
||||
|
||||
public void CommandTestButtonClick(object sender, MouseEventArgs e, Arguments a)
|
||||
{
|
||||
a.RfidOutputListBox.Items.Clear();
|
||||
|
||||
using (Tools.LogChecker logChecker = new Tools.LogChecker("RfidData", log4net.Core.Level.Debug))
|
||||
{
|
||||
ListItem rfidListItem = new ListItem();
|
||||
rfidListItem.Attributes.Add("style", "font-weight:bold");
|
||||
switch (a.RfidCommandComboBox.SelectedValue)
|
||||
{
|
||||
case ReadPCBCmd:
|
||||
rfidListItem.Text = $"PCB: {OpticalHeadTest.ReadRequest_PCB(a.ISmartReader)}";
|
||||
break;
|
||||
case SetTestModeCmd:
|
||||
rfidListItem.Text = OpticalHeadTest.SetTestMode(a.ISmartReader);
|
||||
a.OptoListBox.Items.Clear();
|
||||
stopWorkerThread = false;
|
||||
optoThread = new Thread(OptoWorker);
|
||||
if (!optoThread.IsAlive)
|
||||
{
|
||||
a.ISmartReader.StartDataStreamProcessing(); // open opto port
|
||||
optoThread.Start();
|
||||
}
|
||||
break;
|
||||
case SetActiveModeCmd:
|
||||
rfidListItem.Text = OpticalHeadTest.SetActiveMode(a.ISmartReader);
|
||||
stopWorkerThread = true;
|
||||
a.ISmartReader.StopDataStreamProcessing(); // close opto port
|
||||
break;
|
||||
case ResetNfcHeadCmd:
|
||||
a.ISmartReader.ResetNfcInterface();
|
||||
break;
|
||||
case SetNfcHeadCmd:
|
||||
a.ISmartReader.SetNfcInterface();
|
||||
break;
|
||||
case SetRfidHeadCmd:
|
||||
a.ISmartReader.SetRfidInterface();
|
||||
break;
|
||||
case ReadOptoDataCmd:
|
||||
a.OptoListBox.Items.Clear();
|
||||
stopWorkerThread = false;
|
||||
optoThread = new Thread(OptoWorker);
|
||||
if (optoThread.IsAlive)
|
||||
{
|
||||
stopWorkerThread = true;
|
||||
a.ISmartReader.StopDataStreamProcessing(); // close opto port
|
||||
}
|
||||
if (!optoThread.IsAlive)
|
||||
{
|
||||
a.ISmartReader.StartDataStreamProcessing(); // open opto port
|
||||
optoThread.Start();
|
||||
}
|
||||
break;
|
||||
case StopReadOptoDataCmd:
|
||||
stopWorkerThread = true;
|
||||
a.ISmartReader.StopDataStreamProcessing(); // close opto port
|
||||
break;
|
||||
}
|
||||
a.RfidOutputListBox.Items.Add(rfidListItem);
|
||||
a.RfidOutputListBox.Items.AddRange(logChecker.Messages.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
private void OptoWorker()
|
||||
{
|
||||
while (!this.stopWorkerThread)
|
||||
{
|
||||
Thread.Sleep(250);
|
||||
if (this.stopWorkerThread)
|
||||
break;
|
||||
|
||||
try
|
||||
{
|
||||
string buffer = ISmartReader.ReadOptoData();
|
||||
if (string.IsNullOrEmpty(buffer))
|
||||
{
|
||||
this.OnOptoReceived((object)this, new OptoReceivedEventArgs("."));
|
||||
}
|
||||
else
|
||||
OnOptoReceived((object)this, new OptoReceivedEventArgs(buffer));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.OnOptoReceived((object)this, new OptoReceivedEventArgs(ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOptoReceived(object sender, OptoReceivedEventArgs args)
|
||||
{
|
||||
if (this.OptoReceivedHandler == null)
|
||||
return;
|
||||
try
|
||||
{
|
||||
this.OptoReceivedHandler(sender, args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
-21
@@ -20,15 +20,15 @@ using ConfigStruct = TBF.Rig.RegisterReaders.CommonRR.IPerl.communication.Config
|
||||
using MeterType = TBF.Rig.RegisterReaders.CommonRR.MeterType;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader.implementations
|
||||
{
|
||||
/// <summary>
|
||||
/// based on IPerlReader class
|
||||
/// </summary>
|
||||
public class IPerlReader : ComponentBase, IDevice, IRegReaderDatastream, ISessionDataMngmnt, IOperation, IntIPerlReader
|
||||
public class SmartReader : ComponentBase, IDevice, IRegReaderDatastream, ISessionDataMngmnt, IOperation, ISmartReader
|
||||
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(IPerlReader));
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(SmartReader));
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
@@ -52,7 +52,9 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
/// StartEndFilterSamplesCount = 2 * StartEndFilterSamplesCount2 + 1
|
||||
public const int FeatureVectorSize = 9;
|
||||
|
||||
readonly IPerlCfg _iPerlCfg;
|
||||
readonly iPerlReaderUNI.IPerlCfg _iPerlCfg;
|
||||
|
||||
string ISmartReader.CommInterface => _commInterface;
|
||||
|
||||
public int RfidComPortNr
|
||||
{
|
||||
@@ -60,6 +62,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
}
|
||||
|
||||
public bool CommFailed { get; set; }
|
||||
public bool Disabled { get; set; }
|
||||
|
||||
public int OptoComPortNr
|
||||
{
|
||||
@@ -130,8 +133,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
simulatedPcbNr = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Disabled;
|
||||
|
||||
public int ResultCode;
|
||||
|
||||
|
||||
@@ -344,14 +346,14 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
/// ///////////////////////////////////////////
|
||||
/// </summary>
|
||||
|
||||
public IPerlReader()
|
||||
public SmartReader()
|
||||
{
|
||||
}
|
||||
|
||||
public IPerlReader(Generic.IComponentCfg cfg)
|
||||
public SmartReader(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
_iPerlCfg = cfg as IPerlCfg;
|
||||
_iPerlCfg = cfg as iPerlReaderUNI.IPerlCfg;
|
||||
}
|
||||
|
||||
|
||||
@@ -477,6 +479,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
double endWMState;
|
||||
double wmVolume;
|
||||
double wmTestTime;
|
||||
private string _commInterface;
|
||||
|
||||
public double PulsesPerLtr
|
||||
{
|
||||
@@ -503,15 +506,9 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
get { return wmVolume; }
|
||||
}
|
||||
|
||||
public double BeginWMState
|
||||
{
|
||||
get { return beginWMState; }
|
||||
}
|
||||
public double BeginWMState { get { return beginWMState; } set { beginWMState = value; } }
|
||||
|
||||
public double EndWMState
|
||||
{
|
||||
get { return endWMState; }
|
||||
}
|
||||
public double EndWMState { get { return endWMState; } set { endWMState = value; } }
|
||||
|
||||
public IOperation ReadDatastreamOp()
|
||||
{
|
||||
@@ -1459,14 +1456,14 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
/// <returns>Index to the buffer</returns>
|
||||
public static int BufferIdx(int index)
|
||||
{
|
||||
if (index < IPerlReader.OptoDataBufferSize)
|
||||
if (index < SmartReader.OptoDataBufferSize)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
else
|
||||
{
|
||||
return IPerlReader.StartOptoDataCount +
|
||||
(index - IPerlReader.OptoDataBufferSize) % IPerlReader.EndOptoDataCount;
|
||||
return SmartReader.StartOptoDataCount +
|
||||
(index - SmartReader.OptoDataBufferSize) % SmartReader.EndOptoDataCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1571,7 +1568,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
ResetNfcInterface(false);
|
||||
}
|
||||
|
||||
public void SetCommunicationInterface(CommunicationInterface commInterface)
|
||||
public void SetCommunicationInterface(string commInterface)
|
||||
{
|
||||
//using (ISession session = TBF.DB.ConfigDBSessionFactory.OpenSession())
|
||||
// Replace the problematic line with the following code to fix the error:
|
||||
@@ -1,17 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using log4net;
|
||||
using log4net.Config;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using SharedDatabase;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
@@ -21,6 +17,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
private readonly ILog log;
|
||||
private List<Task> taskPool = new List<Task>();
|
||||
private long startTime;
|
||||
private long incommingTime;
|
||||
|
||||
public List<Task> TaskPool { get { return taskPool; } }
|
||||
public void AddTask(Task task) { taskPool.Add(task); }
|
||||
@@ -43,6 +40,11 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
get => startTime;
|
||||
}
|
||||
|
||||
public long IncommingTime
|
||||
{
|
||||
get => incommingTime;
|
||||
}
|
||||
|
||||
public bool TimeOutReceived(long timeout)
|
||||
{
|
||||
return (DateTime.Now.Ticks - startTime) > timeout;
|
||||
@@ -125,6 +127,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
throw;
|
||||
}
|
||||
|
||||
//comming answer from serial port - good place for time stamp
|
||||
incommingTime = DateTime.Now.Ticks;
|
||||
string allOutput = (stdOutTask.Result ?? "") + (stdErrTask.Result ?? "");
|
||||
log?.Debug(allOutput);
|
||||
return allOutput;
|
||||
|
||||
@@ -17,18 +17,21 @@ using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Rig.RegisterReaders.SerialStream;
|
||||
using TBF.Rig.RegisterReaders.StandingStartStop;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
public class PoseidonReader : ComponentBase, IDevice, IRegReaderDatastream, ISessionDataMngmnt, IOperation
|
||||
public class PoseidonReader : ComponentBase, IDevice, IRegReaderDatastream, ISessionDataMngmnt, IOperation, ICommonRegReader
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(PoseidonReader));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
readonly PoseidonCfg registerReaderCfg;
|
||||
readonly ControlBoard.IControlBoard controlBoard;
|
||||
|
||||
|
||||
|
||||
public int ComPortNr => registerReaderCfg?.ComPortNr ?? -1;
|
||||
public PoseidonCfg RegPoseidonCfg => registerReaderCfg;
|
||||
|
||||
private bool activeHandlerSessioEnabled = false;
|
||||
private CliRunner _cliRunner;
|
||||
|
||||
@@ -134,10 +137,10 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
public int WMPulses { get { return wmPulses; } }
|
||||
public int WMRefPulses { get { return wmRefPulses; } }
|
||||
public double WMVolume { get { return wmVolume; } }
|
||||
public double BeginWMState { get { return beginWMState; } }
|
||||
public double EndWMState { get { return endWMState; } }
|
||||
public double BeginWMState { get { return beginWMState; } set { beginWMState = value;} }
|
||||
public double EndWMState { get { return endWMState; } set { endWMState = value;} }
|
||||
public double WMTestTime { get { return wmTestTime; } }
|
||||
public string SerialNr { get => wmSerialNr; }
|
||||
public string SerialNr { get => wmSerialNr; set => wmSerialNr = value; }
|
||||
|
||||
|
||||
double beginWMState;
|
||||
@@ -147,6 +150,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
int wmRefPulses;
|
||||
double wmTestTime;
|
||||
private string wmSerialNr;
|
||||
|
||||
int timeFromStart; /// [s] Time from test start to determine when the test start sample should be taken
|
||||
|
||||
|
||||
public IOperation ReadDatastreamOp()
|
||||
@@ -314,7 +319,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|
||||
private void ReadPulses()
|
||||
{
|
||||
wmRefPulses = controlBoard.RefPulses;
|
||||
wmRefPulses = controlBoard?.RefPulses ?? 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -326,13 +331,25 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
/// <summary>
|
||||
/// for debug purposes what time will consume answer
|
||||
/// </summary>
|
||||
private long startTimeInMilis, fullTimeInMilis;
|
||||
private static long SafetyTimeOut = 30 * 1000; /// 30 seconds
|
||||
private long startTimeInMilis = -1, fullTimeInMilis = -1;
|
||||
private static long SafetyTimeOut = 30 * 1000;
|
||||
private long incommingTime = -1;
|
||||
|
||||
/// 30 seconds
|
||||
|
||||
public long DeltaTime { get{return fullTimeInMilis;}}
|
||||
public long IncommingTime { get{return incommingTime;}}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>eventDone</returns>
|
||||
public Event Run()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
timeFromStart += StateMachine.Period;
|
||||
ReadPulses();
|
||||
}
|
||||
|
||||
if (_currentOp == CurrentPoseidonOp.SendStartDataStream)
|
||||
{
|
||||
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
@@ -349,6 +366,20 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
}
|
||||
else if (_currentOp == CurrentPoseidonOp.SendStartDataStream_Done)
|
||||
{
|
||||
var firstTask = CliRunner.TaskPool.FindLast(t => t is Task<string>);
|
||||
|
||||
|
||||
if (firstTask != null && firstTask is Task<string>)
|
||||
{
|
||||
string data = null;
|
||||
data = (firstTask as Task<string>).Result;
|
||||
|
||||
if (data != null && TryGetDeviceId(data, out wmSerialNr))
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
_currentOp = CurrentPoseidonOp.Done;
|
||||
return Event.Done;
|
||||
}
|
||||
@@ -356,6 +387,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|| _currentOp == CurrentPoseidonOp.ReadDataStream_End)
|
||||
{
|
||||
startTimeInMilis = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
|
||||
incommingTime = -1;
|
||||
_isReadingStart = (_currentOp == CurrentPoseidonOp.ReadDataStream_Start);
|
||||
CliRunner.AddRunAndCaptureJsonAsync<JsonDataFromPoseidon>(serialPort, SerialPortData.EMeterArg.AllParams);
|
||||
_currentOp = CurrentPoseidonOp.ReadDatastream_Running;
|
||||
@@ -366,6 +398,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|| CliRunner.TimeOutReceived(SafetyTimeOut))
|
||||
{
|
||||
_currentOp = CurrentPoseidonOp.ReadDatastream_Done;
|
||||
//set time stamp - end of reading
|
||||
incommingTime = CliRunner.IncommingTime;
|
||||
}
|
||||
return Event.Busy;
|
||||
}
|
||||
@@ -379,6 +413,20 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
data = (first as Task<JsonDataFromPoseidon>).Result;
|
||||
|
||||
//GET serial number
|
||||
if (string.IsNullOrEmpty(wmSerialNr))
|
||||
{
|
||||
try
|
||||
{
|
||||
wmSerialNr = data?.DeviceId ?? wmSerialNr;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.Error("Serial Nr - parse error!");
|
||||
}
|
||||
}
|
||||
|
||||
//GET volume
|
||||
if (data != null && Double.TryParse(data.Reading, out double Volume))
|
||||
{
|
||||
double VolumeLi = Units.ConvertFrom(Unit.USgal, Volume);
|
||||
@@ -396,6 +444,8 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Finish reading and loop
|
||||
_currentOp = CurrentPoseidonOp.Done;
|
||||
return Event.Done;
|
||||
}
|
||||
@@ -457,34 +507,38 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|
||||
public void StartSession()
|
||||
{
|
||||
|
||||
ValidateCliFileExistence(false);
|
||||
if (DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
wmSerialNr = "777321";
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO BUMI start session - CMD send data to Poseidon
|
||||
|
||||
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
|
||||
CliRunner.WaitAll();
|
||||
foreach (Task task in CliRunner.TaskPool)
|
||||
{
|
||||
if (task is Task<string>)
|
||||
{
|
||||
string result = (task as Task<string>).Result;
|
||||
if (TryGetDeviceId(result, out wmSerialNr))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CliRunner.Clear();
|
||||
}
|
||||
//this is no place to get device id
|
||||
}
|
||||
|
||||
// private void RetrieveDeviceIdFromResponse()
|
||||
// {
|
||||
// if (DebugLevel == DebugMode.Simulate)
|
||||
// {
|
||||
// wmSerialNr = "777321";
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //TODO BUMI start session - CMD send data to Poseidon
|
||||
//
|
||||
// CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
|
||||
// CliRunner.WaitAll();
|
||||
// foreach (Task task in CliRunner.TaskPool)
|
||||
// {
|
||||
// if (task is Task<string>)
|
||||
// {
|
||||
// string result = (task as Task<string>).Result;
|
||||
// if (TryGetDeviceId(result, out wmSerialNr))
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// CliRunner.Clear();
|
||||
// }
|
||||
// }
|
||||
|
||||
private static readonly Regex DeviceIdRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*Device\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
{
|
||||
public static class ProcessExtensions
|
||||
{
|
||||
public static Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (process == null) throw new ArgumentNullException(nameof(process));
|
||||
if (process.HasExited) return Task.CompletedTask;
|
||||
|
||||
var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
EventHandler handler = null;
|
||||
handler = (s, e) =>
|
||||
{
|
||||
try { tcs.TrySetResult(null); }
|
||||
finally { process.Exited -= handler; }
|
||||
};
|
||||
|
||||
process.EnableRaisingEvents = true;
|
||||
process.Exited += handler;
|
||||
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationToken.Register(() =>
|
||||
{
|
||||
tcs.TrySetCanceled(cancellationToken);
|
||||
process.Exited -= handler;
|
||||
});
|
||||
}
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,11 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
return _cliExists.Value;
|
||||
} }
|
||||
public string SerialPortCmdClientPath {
|
||||
#if DEBUG
|
||||
get { return Path.Combine("C:\\","TBF","Cli", CmdClientName);}
|
||||
#else
|
||||
get { return Path.Combine("..","Cli", CmdClientName);}
|
||||
#endif
|
||||
}
|
||||
public string CmdClientName { get; set; } = "HalCli.exe";
|
||||
public string PortName { get; set; }
|
||||
|
||||
@@ -9,15 +9,15 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
public IComponent DummyComponent() { return new IPerlReader(); }
|
||||
public IComponent DummyComponent() { return new SmartReader(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new IPerlReader(cfg); }
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new SmartReader(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new IPerlCfg(this); }
|
||||
public IComponentCfg DefaultConfig() { return new PoseidonCfg(this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(IPerlCfg.Serializer, component, this);
|
||||
return ComponentCfgBase.CreateFromDbEntity(PoseidonCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
[XmlRoot("PoseidonCfg")]
|
||||
public class PoseidonCfg : ComponentCfgBase, Generic.IComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(PoseidonCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
public IComponentCfgCtrl GetControl(IList<Component> cmpntEntities)
|
||||
{
|
||||
return new PoseidonCfgCtrl();
|
||||
}
|
||||
|
||||
public static readonly string[] ValidMeterTypes = { "74", "touch" };
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public int HeadCommunicationComPortNr;
|
||||
public int OptoComPortNr;
|
||||
public int RfidComPortNr; /// 0 = use MuxBoardNr
|
||||
public ECommunicationInterface CommunicationInterface; /// Communication Interface: NFC, touch capl
|
||||
public string CliProgramName;
|
||||
public string CliMeterType;
|
||||
|
||||
|
||||
/// <summary> Procedure parameters </summary>
|
||||
[XmlIgnore]
|
||||
public ProcParams ProcParams;
|
||||
public override IParamsProvider GetRuntimeProcParamsProvider() { return ProcParams; }
|
||||
public override IParamsProvider CreateProcParamsProvider() { return new ProcParams(true); }
|
||||
|
||||
[XmlIgnore]
|
||||
public MeterType MeterType { get { return (ProcParams != null) ? ProcParams.MeterType : MeterType.AutoDetect; } }
|
||||
|
||||
|
||||
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
PoseidonCfg()
|
||||
{
|
||||
Name = "PoseidonReader";
|
||||
ParentName = string.Empty;
|
||||
OptoComPortNr = 5;
|
||||
RfidComPortNr = 0; /// = use mux. board
|
||||
ProcParams = CreateProcParamsProvider() as ProcParams;
|
||||
CommunicationInterface = ECommunicationInterface.None;
|
||||
HeadCommunicationComPortNr = 0;
|
||||
}
|
||||
|
||||
public PoseidonCfg(IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return $"{Name} Opto=Com{OptoComPortNr}, {CommunicationInterface}=Com{RfidComPortNr}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,273 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using log4net;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
public partial class PoseidonCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(PoseidonCfgCtrl));
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
PoseidonCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as PoseidonCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public PoseidonCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
InitComPortsComboByList(listOfComPoertsComboBox, GetAvailableComPorts());
|
||||
InitComboByList(cliProgramComboBox, GetAvailableCliPrograms());
|
||||
InitComboByList(meterTypeComboBox, PoseidonCfg.ValidMeterTypes.ToList());
|
||||
InitComboByEnum<ECommunicationInterface>(comboBoxCommunicationInterface);
|
||||
}
|
||||
|
||||
private List<string> GetAvailableCliPrograms()
|
||||
{
|
||||
try
|
||||
{
|
||||
string cliDirectory = Path.Combine("c:/","TBF","Cli");
|
||||
List<string> availableCliPrograms =
|
||||
Directory.GetFiles(cliDirectory, "*.exe").Select(Path.GetFileName).ToList();
|
||||
if (availableCliPrograms.Count == 0)
|
||||
{
|
||||
availableCliPrograms.Add("None");
|
||||
labelMissingInfo.Text = $"* Missing CLI programs in {cliDirectory}!";
|
||||
}
|
||||
|
||||
return availableCliPrograms;
|
||||
}catch(Exception ex)
|
||||
{
|
||||
log.Error("Problem with get cli programs list!", ex);
|
||||
return new List<string> { "None" };
|
||||
}
|
||||
}
|
||||
|
||||
private void WaterMeterCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
nameLabel.Text = Strings.Name;
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
nameTextBox.Text = config.Name;
|
||||
//radioButton1.Checked = config.UseTcpIP;
|
||||
//radioButton2.Checked = !config.UseTcpIP;
|
||||
//ipAddressTextBox.Text = (config.OptoIPAddress != null) ? config.OptoIPAddress : "0.0.0.0";
|
||||
//tcpipPortTextBox.Text = config.OptoTcpipPortNr.ToString();
|
||||
headPortNrTextBox.Text = config.HeadCommunicationComPortNr.ToString();
|
||||
optoSerialPortTextBox.Text = config.OptoComPortNr.ToString();
|
||||
rfidPortNrTextBox.Text = config.RfidComPortNr.ToString();
|
||||
//muxBoardNrTextBox.Text = config.MuxBoardNr.ToString();
|
||||
//groupTextBox.Text = config.Group.ToString();
|
||||
cliProgramComboBox.Text = config.CliProgramName;
|
||||
meterTypeComboBox.Text = config.CliMeterType;
|
||||
|
||||
comboBoxCommunicationInterface.Text = config.CommunicationInterface.ToDescription();
|
||||
tabPage2.Controls.Add(new UniHeadTestCtrl(config));
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
//radioButton1.Enabled = true;
|
||||
//radioButton2.Enabled = true;
|
||||
//ipAddressTextBox.Enabled = true;
|
||||
//tcpipPortTextBox.Enabled = true;
|
||||
optoSerialPortTextBox.Enabled = true;
|
||||
rfidPortNrTextBox.Enabled = true;
|
||||
headPortNrTextBox.Enabled = true;
|
||||
//muxBoardNrTextBox.Enabled = true;
|
||||
//groupTextBox.Enabled = true;
|
||||
comboBoxCommunicationInterface.Enabled = true;
|
||||
cliProgramComboBox.Enabled = true;
|
||||
meterTypeComboBox.Enabled = true;
|
||||
listOfComPoertsComboBox.Enabled = true;
|
||||
button_refreshComPorts.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
int dummy;
|
||||
|
||||
if (!int.TryParse(optoSerialPortTextBox.Text, out dummy) || dummy < 1 || dummy > 999)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Opto serial port nr.' is not valid";
|
||||
}
|
||||
|
||||
if (!int.TryParse(rfidPortNrTextBox.Text, out dummy) || dummy < 0 || dummy > 999)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'RFID serial port nr.' is not valid";
|
||||
}
|
||||
|
||||
if (!int.TryParse(headPortNrTextBox.Text, out dummy) || dummy < 0 || dummy > 999)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Head communication serial port nr.' is not valid";
|
||||
}
|
||||
|
||||
if (!ValidateEnumInput<ECommunicationInterface>(comboBoxCommunicationInterface))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Not a valid communication interface'";
|
||||
}
|
||||
|
||||
if (!IsValidProgramName(cliProgramComboBox.Text))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Not a valid CLI program name'";
|
||||
}
|
||||
|
||||
if (!IsValidCliMeterType(meterTypeComboBox.Text))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'Not a valid CLI meter type'";
|
||||
}
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
private bool ValidateEnumInput<T>(ComboBox comboBox) where T : Enum
|
||||
{
|
||||
if (comboBox.SelectedItem == null)
|
||||
return false;
|
||||
|
||||
T selectedInterface;
|
||||
|
||||
// Check if SelectedItem is already of type T
|
||||
if (comboBox.SelectedItem is T enumValueT)
|
||||
{
|
||||
selectedInterface = enumValueT;
|
||||
}
|
||||
// Otherwise, try to parse it as a string
|
||||
else
|
||||
{
|
||||
string selectedText = comboBox.Text;
|
||||
foreach (T enumValue in Enum.GetValues(typeof(T)))
|
||||
{
|
||||
if (enumValue.ToDescription() == selectedText)
|
||||
{
|
||||
selectedInterface = enumValue;
|
||||
return !selectedInterface.Equals(Enum.ToObject(typeof(T), 0));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the selected value is not the default (zero) value
|
||||
return !selectedInterface.Equals(Enum.ToObject(typeof(T), 0));
|
||||
}
|
||||
|
||||
|
||||
private bool IsValidCliMeterType(string text)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
return false;
|
||||
|
||||
return int.TryParse(text, out _) || PoseidonCfg.ValidMeterTypes.Contains(text);
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.RestartRqrd;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
config.Name = nameTextBox.Text;
|
||||
config.OptoComPortNr = int.Parse(optoSerialPortTextBox.Text);
|
||||
config.RfidComPortNr = int.Parse(rfidPortNrTextBox.Text);
|
||||
config.CommunicationInterface = (ECommunicationInterface)(comboBoxCommunicationInterface.SelectedIndex);
|
||||
config.HeadCommunicationComPortNr = int.Parse(headPortNrTextBox.Text);
|
||||
config.CliProgramName = cliProgramComboBox.Text;
|
||||
config.CliMeterType = meterTypeComboBox.Text;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private string[] GetAvailableComPorts()
|
||||
{
|
||||
string[] ports = SerialPort.GetPortNames();
|
||||
return ports;
|
||||
}
|
||||
|
||||
private void InitComboByList(ComboBox comboBox, List<string> list)
|
||||
{
|
||||
comboBox.Items.Clear();
|
||||
comboBox.Items.Add("..");
|
||||
comboBox.Items.AddRange(list.ToArray());
|
||||
comboBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private void InitComboByEnum<T>(ComboBox comboBox) where T : Enum
|
||||
{
|
||||
comboBox.Items.Clear();
|
||||
comboBox.Items.AddRange(Enum.GetValues(typeof(T)).Cast<T>().Select(x => x.ToDescription()).ToArray());
|
||||
if (comboBox.Text == "")
|
||||
{
|
||||
comboBox.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitComPortsComboByList(ComboBox comboBox, string[] list)
|
||||
{
|
||||
comboBox.Items.Clear();
|
||||
comboBox.Items.Add("List of ports ..");
|
||||
if( list.Length <= 0)
|
||||
comboBox.Items.Add("None");
|
||||
else
|
||||
{
|
||||
comboBox.Items.AddRange(list);
|
||||
}
|
||||
comboBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private void buttonRefreshComPorts_Click(object sender, EventArgs e)
|
||||
{
|
||||
button_refreshComPorts.Enabled = false;
|
||||
InitComPortsComboByList(listOfComPoertsComboBox, GetAvailableComPorts());
|
||||
button_refreshComPorts.Enabled = true;
|
||||
}
|
||||
|
||||
private bool IsValidProgramName(string programName)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(programName)
|
||||
&& Regex.IsMatch(programName, @"^[^\\/:*?""<>|]+\.exe$", RegexOptions.IgnoreCase);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,401 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
partial class PoseidonCfgCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.tabControl1 = new System.Windows.Forms.TabControl();
|
||||
this.tabPage1 = new System.Windows.Forms.TabPage();
|
||||
this.groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
this.button_refreshComPorts = new System.Windows.Forms.Button();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.listOfComPoertsComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.headPortNrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.labelMissingInfo = new System.Windows.Forms.Label();
|
||||
this.labelMeterType = new System.Windows.Forms.Label();
|
||||
this.meterTypeComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.cliProgramComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.labelCliProgramName = new System.Windows.Forms.Label();
|
||||
this.comboBoxCommunicationInterface = new System.Windows.Forms.ComboBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.rfidPortNrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.rfidSerialPortNrLabel = new System.Windows.Forms.Label();
|
||||
this.optoDataGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.optoSerialPortLabel = new System.Windows.Forms.Label();
|
||||
this.optoSerialPortTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.tabPage2 = new System.Windows.Forms.TabPage();
|
||||
this.tabControl1.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
this.groupBox3.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.optoDataGroupBox.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tabControl1
|
||||
//
|
||||
this.tabControl1.Controls.Add(this.tabPage1);
|
||||
this.tabControl1.Controls.Add(this.tabPage2);
|
||||
this.tabControl1.Location = new System.Drawing.Point(3, 4);
|
||||
this.tabControl1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.tabControl1.Name = "tabControl1";
|
||||
this.tabControl1.SelectedIndex = 0;
|
||||
this.tabControl1.Size = new System.Drawing.Size(687, 540);
|
||||
this.tabControl1.TabIndex = 0;
|
||||
//
|
||||
// tabPage1
|
||||
//
|
||||
this.tabPage1.Controls.Add(this.groupBox3);
|
||||
this.tabPage1.Controls.Add(this.groupBox2);
|
||||
this.tabPage1.Controls.Add(this.groupBox1);
|
||||
this.tabPage1.Controls.Add(this.optoDataGroupBox);
|
||||
this.tabPage1.Controls.Add(this.nameTextBox);
|
||||
this.tabPage1.Controls.Add(this.nameLabel);
|
||||
this.tabPage1.Controls.Add(this.classNameLabel);
|
||||
this.tabPage1.Location = new System.Drawing.Point(4, 29);
|
||||
this.tabPage1.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.tabPage1.Name = "tabPage1";
|
||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.tabPage1.Size = new System.Drawing.Size(679, 507);
|
||||
this.tabPage1.TabIndex = 0;
|
||||
this.tabPage1.Text = "Config";
|
||||
this.tabPage1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
this.groupBox3.Controls.Add(this.button_refreshComPorts);
|
||||
this.groupBox3.Controls.Add(this.label3);
|
||||
this.groupBox3.Controls.Add(this.listOfComPoertsComboBox);
|
||||
this.groupBox3.Location = new System.Drawing.Point(11, 99);
|
||||
this.groupBox3.Name = "groupBox3";
|
||||
this.groupBox3.Size = new System.Drawing.Size(620, 59);
|
||||
this.groupBox3.TabIndex = 27;
|
||||
this.groupBox3.TabStop = false;
|
||||
this.groupBox3.Text = "Ports Overview ";
|
||||
//
|
||||
// button_refreshComPorts
|
||||
//
|
||||
this.button_refreshComPorts.Enabled = false;
|
||||
this.button_refreshComPorts.Location = new System.Drawing.Point(466, 17);
|
||||
this.button_refreshComPorts.Name = "button_refreshComPorts";
|
||||
this.button_refreshComPorts.Size = new System.Drawing.Size(77, 33);
|
||||
this.button_refreshComPorts.TabIndex = 29;
|
||||
this.button_refreshComPorts.Text = "Refresh";
|
||||
this.button_refreshComPorts.UseVisualStyleBackColor = true;
|
||||
this.button_refreshComPorts.Click += new System.EventHandler(this.buttonRefreshComPorts_Click);
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.Location = new System.Drawing.Point(46, 23);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(149, 26);
|
||||
this.label3.TabIndex = 28;
|
||||
this.label3.Text = "Available ports:";
|
||||
//
|
||||
// listOfComPoertsComboBox
|
||||
//
|
||||
this.listOfComPoertsComboBox.FormattingEnabled = true;
|
||||
this.listOfComPoertsComboBox.Location = new System.Drawing.Point(234, 20);
|
||||
this.listOfComPoertsComboBox.Name = "listOfComPoertsComboBox";
|
||||
this.listOfComPoertsComboBox.Size = new System.Drawing.Size(202, 28);
|
||||
this.listOfComPoertsComboBox.TabIndex = 27;
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.headPortNrTextBox);
|
||||
this.groupBox2.Controls.Add(this.label2);
|
||||
this.groupBox2.Location = new System.Drawing.Point(11, 425);
|
||||
this.groupBox2.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.groupBox2.Size = new System.Drawing.Size(621, 62);
|
||||
this.groupBox2.TabIndex = 26;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Head Communication";
|
||||
//
|
||||
// headPortNrTextBox
|
||||
//
|
||||
this.headPortNrTextBox.Enabled = false;
|
||||
this.headPortNrTextBox.Location = new System.Drawing.Point(494, 19);
|
||||
this.headPortNrTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.headPortNrTextBox.Name = "headPortNrTextBox";
|
||||
this.headPortNrTextBox.Size = new System.Drawing.Size(49, 26);
|
||||
this.headPortNrTextBox.TabIndex = 8;
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(361, 22);
|
||||
this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(107, 20);
|
||||
this.label2.TabIndex = 7;
|
||||
this.label2.Text = "Serial port nr.:";
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
this.groupBox1.Controls.Add(this.labelMissingInfo);
|
||||
this.groupBox1.Controls.Add(this.labelMeterType);
|
||||
this.groupBox1.Controls.Add(this.meterTypeComboBox);
|
||||
this.groupBox1.Controls.Add(this.cliProgramComboBox);
|
||||
this.groupBox1.Controls.Add(this.labelCliProgramName);
|
||||
this.groupBox1.Controls.Add(this.comboBoxCommunicationInterface);
|
||||
this.groupBox1.Controls.Add(this.label1);
|
||||
this.groupBox1.Controls.Add(this.rfidPortNrTextBox);
|
||||
this.groupBox1.Controls.Add(this.rfidSerialPortNrLabel);
|
||||
this.groupBox1.Location = new System.Drawing.Point(11, 249);
|
||||
this.groupBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.groupBox1.Size = new System.Drawing.Size(621, 167);
|
||||
this.groupBox1.TabIndex = 23;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "RFID / NFC communication (in case mux. board is not used)";
|
||||
//
|
||||
// labelMissingInfo
|
||||
//
|
||||
this.labelMissingInfo.ForeColor = System.Drawing.Color.OrangeRed;
|
||||
this.labelMissingInfo.Location = new System.Drawing.Point(49, 138);
|
||||
this.labelMissingInfo.Name = "labelMissingInfo";
|
||||
this.labelMissingInfo.Size = new System.Drawing.Size(550, 24);
|
||||
this.labelMissingInfo.TabIndex = 14;
|
||||
this.labelMissingInfo.Text = "*";
|
||||
this.labelMissingInfo.Visible = false;
|
||||
//
|
||||
// labelMeterType
|
||||
//
|
||||
this.labelMeterType.Location = new System.Drawing.Point(46, 103);
|
||||
this.labelMeterType.Name = "labelMeterType";
|
||||
this.labelMeterType.Size = new System.Drawing.Size(149, 27);
|
||||
this.labelMeterType.TabIndex = 13;
|
||||
this.labelMeterType.Text = "Meter Type: ";
|
||||
//
|
||||
// meterTypeComboBox
|
||||
//
|
||||
this.meterTypeComboBox.Enabled = false;
|
||||
this.meterTypeComboBox.FormattingEnabled = true;
|
||||
this.meterTypeComboBox.Location = new System.Drawing.Point(234, 103);
|
||||
this.meterTypeComboBox.Name = "meterTypeComboBox";
|
||||
this.meterTypeComboBox.Size = new System.Drawing.Size(127, 28);
|
||||
this.meterTypeComboBox.TabIndex = 12;
|
||||
//
|
||||
// cliProgramComboBox
|
||||
//
|
||||
this.cliProgramComboBox.Enabled = false;
|
||||
this.cliProgramComboBox.FormattingEnabled = true;
|
||||
this.cliProgramComboBox.Location = new System.Drawing.Point(234, 69);
|
||||
this.cliProgramComboBox.Name = "cliProgramComboBox";
|
||||
this.cliProgramComboBox.Size = new System.Drawing.Size(127, 28);
|
||||
this.cliProgramComboBox.TabIndex = 11;
|
||||
//
|
||||
// labelCliProgramName
|
||||
//
|
||||
this.labelCliProgramName.Location = new System.Drawing.Point(46, 71);
|
||||
this.labelCliProgramName.Name = "labelCliProgramName";
|
||||
this.labelCliProgramName.Size = new System.Drawing.Size(146, 22);
|
||||
this.labelCliProgramName.TabIndex = 10;
|
||||
this.labelCliProgramName.Text = "Cli program name: ";
|
||||
//
|
||||
// comboBoxCommunicationInterface
|
||||
//
|
||||
this.comboBoxCommunicationInterface.Enabled = false;
|
||||
this.comboBoxCommunicationInterface.FormattingEnabled = true;
|
||||
this.comboBoxCommunicationInterface.Items.AddRange(new object[] { "Nfc", "Touch" });
|
||||
this.comboBoxCommunicationInterface.Location = new System.Drawing.Point(234, 34);
|
||||
this.comboBoxCommunicationInterface.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.comboBoxCommunicationInterface.Name = "comboBoxCommunicationInterface";
|
||||
this.comboBoxCommunicationInterface.Size = new System.Drawing.Size(79, 28);
|
||||
this.comboBoxCommunicationInterface.TabIndex = 9;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(46, 38);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(187, 20);
|
||||
this.label1.TabIndex = 8;
|
||||
this.label1.Text = "Communication Interface";
|
||||
//
|
||||
// rfidPortNrTextBox
|
||||
//
|
||||
this.rfidPortNrTextBox.Enabled = false;
|
||||
this.rfidPortNrTextBox.Location = new System.Drawing.Point(494, 32);
|
||||
this.rfidPortNrTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.rfidPortNrTextBox.Name = "rfidPortNrTextBox";
|
||||
this.rfidPortNrTextBox.Size = new System.Drawing.Size(49, 26);
|
||||
this.rfidPortNrTextBox.TabIndex = 7;
|
||||
//
|
||||
// rfidSerialPortNrLabel
|
||||
//
|
||||
this.rfidSerialPortNrLabel.AutoSize = true;
|
||||
this.rfidSerialPortNrLabel.Location = new System.Drawing.Point(361, 38);
|
||||
this.rfidSerialPortNrLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.rfidSerialPortNrLabel.Name = "rfidSerialPortNrLabel";
|
||||
this.rfidSerialPortNrLabel.Size = new System.Drawing.Size(107, 20);
|
||||
this.rfidSerialPortNrLabel.TabIndex = 6;
|
||||
this.rfidSerialPortNrLabel.Text = "Serial port nr.:";
|
||||
//
|
||||
// optoDataGroupBox
|
||||
//
|
||||
this.optoDataGroupBox.Controls.Add(this.optoSerialPortLabel);
|
||||
this.optoDataGroupBox.Controls.Add(this.optoSerialPortTextBox);
|
||||
this.optoDataGroupBox.Location = new System.Drawing.Point(11, 170);
|
||||
this.optoDataGroupBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.optoDataGroupBox.Name = "optoDataGroupBox";
|
||||
this.optoDataGroupBox.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.optoDataGroupBox.Size = new System.Drawing.Size(621, 68);
|
||||
this.optoDataGroupBox.TabIndex = 18;
|
||||
this.optoDataGroupBox.TabStop = false;
|
||||
this.optoDataGroupBox.Text = "Opto-data";
|
||||
//
|
||||
// optoSerialPortLabel
|
||||
//
|
||||
this.optoSerialPortLabel.AutoSize = true;
|
||||
this.optoSerialPortLabel.Location = new System.Drawing.Point(361, 26);
|
||||
this.optoSerialPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.optoSerialPortLabel.Name = "optoSerialPortLabel";
|
||||
this.optoSerialPortLabel.Size = new System.Drawing.Size(107, 20);
|
||||
this.optoSerialPortLabel.TabIndex = 6;
|
||||
this.optoSerialPortLabel.Text = "Serial port nr.:";
|
||||
//
|
||||
// optoSerialPortTextBox
|
||||
//
|
||||
this.optoSerialPortTextBox.Enabled = false;
|
||||
this.optoSerialPortTextBox.Location = new System.Drawing.Point(494, 22);
|
||||
this.optoSerialPortTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.optoSerialPortTextBox.Name = "optoSerialPortTextBox";
|
||||
this.optoSerialPortTextBox.Size = new System.Drawing.Size(49, 26);
|
||||
this.optoSerialPortTextBox.TabIndex = 7;
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(172, 50);
|
||||
this.nameTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(180, 26);
|
||||
this.nameTextBox.TabIndex = 17;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(7, 55);
|
||||
this.nameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(51, 20);
|
||||
this.nameLabel.TabIndex = 16;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(168, 14);
|
||||
this.classNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(90, 20);
|
||||
this.classNameLabel.TabIndex = 15;
|
||||
this.classNameLabel.Text = "ClassName";
|
||||
//
|
||||
// tabPage2
|
||||
//
|
||||
this.tabPage2.Location = new System.Drawing.Point(4, 29);
|
||||
this.tabPage2.Margin = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.tabPage2.Name = "tabPage2";
|
||||
this.tabPage2.Padding = new System.Windows.Forms.Padding(3, 4, 3, 4);
|
||||
this.tabPage2.Size = new System.Drawing.Size(679, 507);
|
||||
this.tabPage2.TabIndex = 1;
|
||||
this.tabPage2.Text = "Test";
|
||||
this.tabPage2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// PoseidonCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.tabControl1);
|
||||
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
|
||||
this.Name = "PoseidonCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(694, 548);
|
||||
this.Load += new System.EventHandler(this.WaterMeterCfgCtrl_Load);
|
||||
this.tabControl1.ResumeLayout(false);
|
||||
this.tabPage1.ResumeLayout(false);
|
||||
this.tabPage1.PerformLayout();
|
||||
this.groupBox3.ResumeLayout(false);
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.optoDataGroupBox.ResumeLayout(false);
|
||||
this.optoDataGroupBox.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
}
|
||||
|
||||
private System.Windows.Forms.Label labelMissingInfo;
|
||||
|
||||
private System.Windows.Forms.GroupBox groupBox3;
|
||||
private System.Windows.Forms.Button button_refreshComPorts;
|
||||
|
||||
private System.Windows.Forms.ComboBox listOfComPoertsComboBox;
|
||||
private System.Windows.Forms.Label label3;
|
||||
|
||||
private System.Windows.Forms.ComboBox cliProgramComboBox;
|
||||
private System.Windows.Forms.ComboBox meterTypeComboBox;
|
||||
|
||||
private System.Windows.Forms.Label labelCliProgramName;
|
||||
|
||||
private System.Windows.Forms.Label labelMeterType;
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TabControl tabControl1;
|
||||
private System.Windows.Forms.TabPage tabPage1;
|
||||
private System.Windows.Forms.GroupBox groupBox1;
|
||||
private System.Windows.Forms.ComboBox comboBoxCommunicationInterface;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox rfidPortNrTextBox;
|
||||
private System.Windows.Forms.Label rfidSerialPortNrLabel;
|
||||
private System.Windows.Forms.GroupBox optoDataGroupBox;
|
||||
private System.Windows.Forms.Label optoSerialPortLabel;
|
||||
private System.Windows.Forms.TextBox optoSerialPortTextBox;
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.TabPage tabPage2;
|
||||
private System.Windows.Forms.GroupBox groupBox2;
|
||||
private System.Windows.Forms.TextBox headPortNrTextBox;
|
||||
private System.Windows.Forms.Label label2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,137 @@
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
partial class PoseidonHeadTestCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.optoTestGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.optoListBox = new System.Windows.Forms.ListBox();
|
||||
this.rfidOutputListBox = new System.Windows.Forms.ListBox();
|
||||
this.RfidTestGroupBox = new System.Windows.Forms.GroupBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.rfidCommandComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.commandTestButton = new System.Windows.Forms.Button();
|
||||
this.optoTestGroupBox.SuspendLayout();
|
||||
this.RfidTestGroupBox.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// optoTestGroupBox
|
||||
//
|
||||
this.optoTestGroupBox.Controls.Add(this.optoListBox);
|
||||
this.optoTestGroupBox.Location = new System.Drawing.Point(5, 4);
|
||||
this.optoTestGroupBox.Name = "optoTestGroupBox";
|
||||
this.optoTestGroupBox.Size = new System.Drawing.Size(591, 161);
|
||||
this.optoTestGroupBox.TabIndex = 2;
|
||||
this.optoTestGroupBox.TabStop = false;
|
||||
this.optoTestGroupBox.Text = "Opto-data";
|
||||
//
|
||||
// optoListBox
|
||||
//
|
||||
this.optoListBox.FormattingEnabled = true;
|
||||
this.optoListBox.ItemHeight = 16;
|
||||
this.optoListBox.Location = new System.Drawing.Point(7, 22);
|
||||
this.optoListBox.Name = "optoListBox";
|
||||
this.optoListBox.Size = new System.Drawing.Size(573, 132);
|
||||
this.optoListBox.TabIndex = 0;
|
||||
//
|
||||
// rfidOutputListBox
|
||||
//
|
||||
this.rfidOutputListBox.FormattingEnabled = true;
|
||||
this.rfidOutputListBox.ItemHeight = 16;
|
||||
this.rfidOutputListBox.Location = new System.Drawing.Point(5, 54);
|
||||
this.rfidOutputListBox.Name = "rfidOutputListBox";
|
||||
this.rfidOutputListBox.SelectionMode = System.Windows.Forms.SelectionMode.None;
|
||||
this.rfidOutputListBox.Size = new System.Drawing.Size(575, 164);
|
||||
this.rfidOutputListBox.TabIndex = 3;
|
||||
//
|
||||
// RfidTestGroupBox
|
||||
//
|
||||
this.RfidTestGroupBox.Controls.Add(this.rfidOutputListBox);
|
||||
this.RfidTestGroupBox.Controls.Add(this.label2);
|
||||
this.RfidTestGroupBox.Controls.Add(this.rfidCommandComboBox);
|
||||
this.RfidTestGroupBox.Controls.Add(this.commandTestButton);
|
||||
this.RfidTestGroupBox.Location = new System.Drawing.Point(5, 171);
|
||||
this.RfidTestGroupBox.Name = "RfidTestGroupBox";
|
||||
this.RfidTestGroupBox.Size = new System.Drawing.Size(591, 224);
|
||||
this.RfidTestGroupBox.TabIndex = 3;
|
||||
this.RfidTestGroupBox.TabStop = false;
|
||||
this.RfidTestGroupBox.Text = "RFID / NFC data";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(2, 25);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(69, 16);
|
||||
this.label2.TabIndex = 2;
|
||||
this.label2.Text = "Command";
|
||||
//
|
||||
// rfidCommandComboBox
|
||||
//
|
||||
this.rfidCommandComboBox.FormattingEnabled = true;
|
||||
this.rfidCommandComboBox.Location = new System.Drawing.Point(86, 19);
|
||||
this.rfidCommandComboBox.Name = "rfidCommandComboBox";
|
||||
this.rfidCommandComboBox.Size = new System.Drawing.Size(341, 24);
|
||||
this.rfidCommandComboBox.TabIndex = 1;
|
||||
//
|
||||
// commandTestButton
|
||||
//
|
||||
this.commandTestButton.Location = new System.Drawing.Point(449, 19);
|
||||
this.commandTestButton.Name = "commandTestButton";
|
||||
this.commandTestButton.Size = new System.Drawing.Size(126, 24);
|
||||
this.commandTestButton.TabIndex = 0;
|
||||
this.commandTestButton.Text = "Send command";
|
||||
this.commandTestButton.UseVisualStyleBackColor = true;
|
||||
this.commandTestButton.MouseClick += new System.Windows.Forms.MouseEventHandler(this.CommandTestButtonClick);
|
||||
//
|
||||
// IperlHeadTestCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.optoTestGroupBox);
|
||||
this.Controls.Add(this.RfidTestGroupBox);
|
||||
this.Name = "PoseidonHeadTestCtrl";
|
||||
this.Size = new System.Drawing.Size(611, 432);
|
||||
this.Load += new System.EventHandler(this.UserControl_Load);
|
||||
this.optoTestGroupBox.ResumeLayout(false);
|
||||
this.RfidTestGroupBox.ResumeLayout(false);
|
||||
this.RfidTestGroupBox.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox optoTestGroupBox;
|
||||
private System.Windows.Forms.ListBox rfidOutputListBox;
|
||||
private System.Windows.Forms.GroupBox RfidTestGroupBox;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.ComboBox rfidCommandComboBox;
|
||||
private System.Windows.Forms.Button commandTestButton;
|
||||
private System.Windows.Forms.ListBox optoListBox;
|
||||
}
|
||||
}
|
||||
+13
-13
@@ -9,16 +9,16 @@ using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
public partial class IperlHeadTestCtrl : UserControl
|
||||
public partial class PoseidonHeadTestCtrl : UserControl
|
||||
{
|
||||
IPerlCfg config;
|
||||
IntIPerlReader _iPerlReader;
|
||||
PoseidonCfg config;
|
||||
ISmartReader _iSmartReader;
|
||||
Thread optoThread;
|
||||
|
||||
private bool stopWorkerThread;
|
||||
public event EventHandler<OptoReceivedEventArgs> OptoReceivedHandler;
|
||||
|
||||
public IperlHeadTestCtrl(IPerlCfg config)
|
||||
public PoseidonHeadTestCtrl(PoseidonCfg config)
|
||||
{
|
||||
this.config = config;
|
||||
InitializeComponent();
|
||||
@@ -27,9 +27,9 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
//TODO fix possibility set test method in config
|
||||
//iPerlCommunicationForm.cfg = new TestMethodCfg(null); // default values for iPerlCommunication
|
||||
|
||||
foreach(var head in ProcessData.IperlHeadsUni)
|
||||
foreach(var head in ProcessData.SmartHeadsUni)
|
||||
{
|
||||
if (head != null && head.Name == config.Name) { _iPerlReader = head; }
|
||||
if (head != null && head.Name == config.Name) { _iSmartReader = head; }
|
||||
}
|
||||
|
||||
rfidCommandComboBox.DisplayMember = "Name";
|
||||
@@ -104,13 +104,13 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
// _iPerlReader.StopDataStreamProcessing(); // close opto port
|
||||
break;
|
||||
case "ResetNfcHead":
|
||||
_iPerlReader.ResetNfcInterface();
|
||||
_iSmartReader.ResetNfcInterface();
|
||||
break;
|
||||
case "SetNfcHead":
|
||||
_iPerlReader.SetNfcInterface();
|
||||
_iSmartReader.SetNfcInterface();
|
||||
break;
|
||||
case "SetRfidHead":
|
||||
_iPerlReader.SetRfidInterface();
|
||||
_iSmartReader.SetRfidInterface();
|
||||
break;
|
||||
case "ReadOptoData":
|
||||
optoListBox.Items.Clear();
|
||||
@@ -119,17 +119,17 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
if (optoThread.IsAlive)
|
||||
{
|
||||
stopWorkerThread = true;
|
||||
_iPerlReader.StopDataStreamProcessing(); // close opto port
|
||||
_iSmartReader.StopDataStreamProcessing(); // close opto port
|
||||
}
|
||||
if (!optoThread.IsAlive)
|
||||
{
|
||||
_iPerlReader.StartDataStreamProcessing(); // open opto port
|
||||
_iSmartReader.StartDataStreamProcessing(); // open opto port
|
||||
optoThread.Start();
|
||||
}
|
||||
break;
|
||||
case "StopReadOptoData":
|
||||
stopWorkerThread = true;
|
||||
_iPerlReader.StopDataStreamProcessing(); // close opto port
|
||||
_iSmartReader.StopDataStreamProcessing(); // close opto port
|
||||
break;
|
||||
}
|
||||
rfidOutputListBox.Items.Add(rfidListItem);
|
||||
@@ -147,7 +147,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
|
||||
try
|
||||
{
|
||||
string buffer = _iPerlReader.ReadOptoData();
|
||||
string buffer = _iSmartReader.ReadOptoData();
|
||||
if (string.IsNullOrEmpty(buffer))
|
||||
{
|
||||
this.OnOptoReceived((object)this, new OptoReceivedEventArgs("."));
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -1,6 +1,6 @@
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
partial class IperlHeadTestCtrl
|
||||
partial class UniHeadTestCtrl
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
@@ -114,7 +114,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.optoTestGroupBox);
|
||||
this.Controls.Add(this.RfidTestGroupBox);
|
||||
this.Name = "IperlHeadTestCtrl";
|
||||
this.Name = "UniHeadTestCtrl";
|
||||
this.Size = new System.Drawing.Size(611, 432);
|
||||
this.Load += new System.EventHandler(this.UserControl_Load);
|
||||
this.optoTestGroupBox.ResumeLayout(false);
|
||||
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl.communication;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.implementations;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader
|
||||
{
|
||||
public partial class UniHeadTestCtrl : UserControl
|
||||
{
|
||||
private IUniHeadTestCtrl _ctrl;
|
||||
private IUniHeadTestCtrl Ctrl { get => _ctrl; }
|
||||
|
||||
public UniHeadTestCtrl(Generic.IComponentCfg config)
|
||||
{
|
||||
this._ctrl = new PoseidonImplHeadTestCtrl();
|
||||
Ctrl.config = config;
|
||||
InitializeComponent();
|
||||
if (config == null) return;
|
||||
|
||||
SmartCommunicationForm.TestMethodCfg = new iPerlReaderUNI.TestMethodCfg(null); // default values for iPerlCommunication
|
||||
|
||||
if (ProcessData.SmartHeadsUni != null)
|
||||
{
|
||||
foreach (var head in ProcessData.SmartHeadsUni)
|
||||
{
|
||||
if (head != null && head.Name == config.Name)
|
||||
{
|
||||
Ctrl.ISmartReader = head;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rfidCommandComboBox.DisplayMember = "Name";
|
||||
rfidCommandComboBox.ValueMember = "Value";
|
||||
var items = Ctrl.GetComboOperationsPairs();
|
||||
/*
|
||||
// CTRL+ALT+double click - hidden poweruser menu
|
||||
if (((Keyboard.ModifierKeys & Keys.Control) == Keys.Control) && ((Keyboard.ModifierKeys & Keys.Alt) == Keys.Alt) && Users.CurrentUser.AuthorizedAs == AuthorizedAs.PowerUser)
|
||||
{
|
||||
Array.Resize(ref items, items.Length + 1);
|
||||
items[items.Length - 1] = new { Name = "Kluc", Value = "Kluc" };
|
||||
}
|
||||
*/
|
||||
rfidCommandComboBox.DataSource = items.Select(i => i.Name).ToArray();
|
||||
|
||||
Ctrl.Initialize();
|
||||
|
||||
Ctrl.OptoReceivedHandler += (EventHandler<OptoReceivedEventArgs>)((sndr, args) =>
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
this.Invoke((Delegate)new EventHandler<OptoReceivedEventArgs>(this.OnOptoReceived2), sndr, (object)args);
|
||||
else
|
||||
this.OnOptoReceived2(sndr, args);
|
||||
});
|
||||
}
|
||||
|
||||
public void OnOptoReceived2(object sender, OptoReceivedEventArgs args)
|
||||
{
|
||||
optoListBox.Items.Insert(0,args.Data);
|
||||
}
|
||||
|
||||
public void CommandTestButtonClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
commandTestButton.Enabled = false;
|
||||
|
||||
Ctrl.CommandTestButtonClick(sender, e, new Arguments()
|
||||
{
|
||||
ISmartReader = Ctrl.ISmartReader,
|
||||
OptoListBox = optoListBox,
|
||||
RfidCommandComboBox = rfidCommandComboBox,
|
||||
RfidOutputListBox = rfidOutputListBox
|
||||
});
|
||||
}
|
||||
finally
|
||||
{
|
||||
commandTestButton.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void UserControl_Load(object sender, EventArgs e)
|
||||
{
|
||||
this.ParentForm.FormClosing += new FormClosingEventHandler(ParentForm_FormClosing);
|
||||
}
|
||||
|
||||
void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
//OnHandleDestroyed(new EventArgs());
|
||||
Ctrl.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
{
|
||||
public class JsonDataFromPoseidon
|
||||
{
|
||||
public bool? NfcTagDetected { get; set; }
|
||||
public int? ProductType { get; set; }
|
||||
public string ProductTypeVersion { get; set; }
|
||||
public string DeviceId { get; set; }
|
||||
public string Reading { get; set; }
|
||||
public string Reading_Totalizer { get; set; }
|
||||
public string Reading_Digits { get; set; }
|
||||
public string Reading_Shift { get; set; }
|
||||
public string Reading_Resolution { get; set; }
|
||||
public string Reading_Units { get; set; }
|
||||
public string Reading_FlowDirection { get; set; }
|
||||
public string Reading_FlowRate { get; set; }
|
||||
public string CalibrationFactor { get; set; }
|
||||
public bool? ReadingComplete { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CliRunner = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.CliRunner;
|
||||
using OptoHeadStatus = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.OptoHeadStatus;
|
||||
using SerialPortData = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.SerialPortData;
|
||||
using EMeterArg = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.SerialPortData.EMeterArg;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
{
|
||||
public class NfcHeadService
|
||||
{
|
||||
|
||||
private bool activeHandlerSessioEnabled = false;
|
||||
private CliRunner _cliRunner;
|
||||
|
||||
private SerialPortData serialPort;
|
||||
|
||||
public NfcHeadService(SerialPortData serialPort)
|
||||
{
|
||||
this.serialPort = serialPort;
|
||||
this._cliRunner = null;
|
||||
ValidateCliFileExistence(true);
|
||||
}
|
||||
|
||||
private CliRunner CliRunner
|
||||
{
|
||||
get { return (_cliRunner != null ? _cliRunner : (_cliRunner = new CliRunner(CliLogging))); }
|
||||
}
|
||||
|
||||
private bool CliLogging
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
private static readonly Regex OpticalDataModeRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*OpticalDataMode\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
@"|" +
|
||||
@"""OpticalDataMode""\s*:\s*""?(0x[0-9A-Fa-f]+|\d+)""?" + // JSON format (handles hex and decimal)
|
||||
@")",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
public bool TryGetOpticalDataMode(string result, out string s)
|
||||
{
|
||||
s = null;
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return false;
|
||||
|
||||
var m = OpticalDataModeRegex.Match(result);
|
||||
if (!m.Success)
|
||||
return false;
|
||||
|
||||
// one of the groups will be filled
|
||||
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
||||
? m.Groups[1].Value.Trim()
|
||||
: m.Groups[2].Value.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static readonly Regex DeviceIdRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*Device\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
@"|" +
|
||||
@"""DeviceId""\s*:\s*""?([0-9]+)""?" + // JSON format
|
||||
@")",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
public bool TryGetDeviceId(string result, out string s)
|
||||
{
|
||||
s = null;
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return false;
|
||||
|
||||
var m = DeviceIdRegex.Match(result);
|
||||
if (!m.Success)
|
||||
return false;
|
||||
|
||||
// one of the groups will be filled
|
||||
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
||||
? m.Groups[1].Value.Trim()
|
||||
: m.Groups[2].Value.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void ValidateCliFileExistence(bool showErrorIfMissing)
|
||||
{
|
||||
if (serialPort != null)
|
||||
{
|
||||
if (!serialPort.CliExists)
|
||||
{
|
||||
throw new Exception("CLI file " + serialPort.SerialPortCmdClientPath +
|
||||
" does not exist! Current path: " + Environment.CurrentDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ////////////
|
||||
/// </summary>
|
||||
public string GetSerialNr()
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task<string> optoheadDeviceIdTask = CliRunner.SendAsync(serialPort.SerialPortCmdClientPath, serialPort.DefaultArgSettingsRead(EMeterArg.DeviceId) );
|
||||
//var timeOut = CliRunner.AddTimeOut(15000);
|
||||
//optoheadDeviceIdTask.GetAwaiter().GetResult();
|
||||
//optoheadDeviceIdTask.Wait();
|
||||
int doneTask = Task.WaitAny(new Task[] { optoheadDeviceIdTask }, TimeSpan.FromMilliseconds(15000));
|
||||
if (doneTask != 0)
|
||||
//if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadDeviceIdTask is Task<string>)
|
||||
{
|
||||
string serialNr;
|
||||
if (optoheadDeviceIdTask.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
if (optoheadDeviceIdTask is Task<string> taskStr)
|
||||
{
|
||||
string result = taskStr.Result;
|
||||
if (TryGetDeviceId(result, out serialNr))
|
||||
{
|
||||
return serialNr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public async Task<string> GetSerialNrAsync()
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
var cts = new CancellationTokenSource(); // we own the token
|
||||
var sendTask = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId, cts.Token);
|
||||
|
||||
string output;
|
||||
try
|
||||
{
|
||||
output = await CliRunner.WithTimeout(sendTask, TimeSpan.FromSeconds(15), cts);
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
|
||||
if (TryGetDeviceId(output, out var serialNr))
|
||||
return serialNr;
|
||||
|
||||
throw new Exception("Failed to parse DeviceId from output.");
|
||||
}
|
||||
|
||||
public OptoHeadStatus SetTestingMode(OptoHeadStatus status)
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task optoheadMode =
|
||||
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead, $"0x{((byte)status):X2}");
|
||||
var timeOut = CliRunner.AddTimeOut(5000);
|
||||
var doneTask = CliRunner.WhenAny();
|
||||
if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadMode is Task<string>)
|
||||
{
|
||||
string strOpticalDataMode;
|
||||
if (optoheadMode.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
string result = (optoheadMode as Task<string>).Result;
|
||||
if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
||||
{
|
||||
byte value;
|
||||
|
||||
if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
||||
else
|
||||
value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
||||
|
||||
OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
||||
return optoheadStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception($"Failed to parse OptoHeadStatus from output. Result: {result}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OptoHeadStatus.Unknown;
|
||||
}
|
||||
|
||||
public OptoHeadStatus GetTestingMode()
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task optoheadMode = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead);
|
||||
var timeOut = CliRunner.AddTimeOut(5000);
|
||||
var doneTask = CliRunner.WhenAny();
|
||||
if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadMode is Task<string>)
|
||||
{
|
||||
string strOpticalDataMode;
|
||||
if (optoheadMode.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
string result = (optoheadMode as Task<string>).Result;
|
||||
if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
||||
{
|
||||
byte value;
|
||||
|
||||
if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
||||
else
|
||||
value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
||||
|
||||
OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
||||
return optoheadStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return OptoHeadStatus.Unknown;
|
||||
}
|
||||
|
||||
private void SendCommand()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private string RawDataAnswer()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,337 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using log4net;
|
||||
using TBF.Rig.Output.Printers.Label;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils;
|
||||
using CliRunner = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.CliRunnerOld;
|
||||
using OptoHeadStatus = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.OptoHeadStatus;
|
||||
using SerialPortData = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.SerialPortData;
|
||||
using EMeterArg = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.SerialPortData.EMeterArg;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
{
|
||||
public class NfcHeadServiceOld
|
||||
{
|
||||
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(NfcHeadServiceOld));
|
||||
private bool activeHandlerSessioEnabled = false;
|
||||
private CliRunner _cliRunner;
|
||||
|
||||
private SerialPortData serialPort;
|
||||
|
||||
public NfcHeadServiceOld(SerialPortData serialPort)
|
||||
{
|
||||
this.serialPort = serialPort;
|
||||
this._cliRunner = null;
|
||||
ValidateCliFileExistence(true);
|
||||
}
|
||||
|
||||
private CliRunner CliRunner
|
||||
{
|
||||
get { return (_cliRunner != null ? _cliRunner : (_cliRunner = new CliRunner(CliLogging))); }
|
||||
}
|
||||
|
||||
private bool CliLogging
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
private static readonly Regex OpticalDataModeRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*OpticalDataMode\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
@"|" +
|
||||
@"""OpticalDataMode""\s*:\s*""?(0x[0-9A-Fa-f]+|\d+)""?" + // JSON format (handles hex and decimal)
|
||||
@")",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
public bool TryGetOpticalDataMode(string result, out string s)
|
||||
{
|
||||
s = null;
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return false;
|
||||
|
||||
var m = OpticalDataModeRegex.Match(result);
|
||||
if (!m.Success)
|
||||
return false;
|
||||
|
||||
// one of the groups will be filled
|
||||
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
||||
? m.Groups[1].Value.Trim()
|
||||
: m.Groups[2].Value.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
private static readonly Regex DeviceIdRegex = new Regex(
|
||||
@"(?im)(?:" +
|
||||
@"^\s*Device\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
||||
@"|" +
|
||||
@"""DeviceId""\s*:\s*""?([0-9]+)""?" + // JSON format
|
||||
@")",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
public bool TryGetDeviceId(string result, out string s)
|
||||
{
|
||||
s = null;
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return false;
|
||||
|
||||
var m = DeviceIdRegex.Match(result);
|
||||
if (!m.Success)
|
||||
return false;
|
||||
|
||||
// one of the groups will be filled
|
||||
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
||||
? m.Groups[1].Value.Trim()
|
||||
: m.Groups[2].Value.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void ValidateCliFileExistence(bool showErrorIfMissing)
|
||||
{
|
||||
if (serialPort != null)
|
||||
{
|
||||
if (!serialPort.CliExists)
|
||||
{
|
||||
throw new Exception("CLI file " + serialPort.SerialPortCmdClientPath +
|
||||
" does not exist! Current path: " + Environment.CurrentDirectory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// ////////////
|
||||
/// </summary>
|
||||
public string GetSerialNr()
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
Task<string> optoheadDeviceIdTask = CliRunner.SendAsync(serialPort.SerialPortCmdClientPath, serialPort.DefaultArgSettingsRead(EMeterArg.DeviceId) );
|
||||
//Task<string> optoheadDeviceIdTask = CliRunner.SendAsync(serialPort.SerialPortCmdClientPath, serialPort.DefaultArgSettingsRead(EMeterArg.DeviceId) );
|
||||
//var timeOut = CliRunner.AddTimeOut(15000);
|
||||
//optoheadDeviceIdTask.GetAwaiter().GetResult();
|
||||
//optoheadDeviceIdTask.Wait();
|
||||
//CliRunner.StartAll();
|
||||
int doneTask = -1;
|
||||
DateTime time = DateTime.Now;
|
||||
while (true)
|
||||
{
|
||||
if (CliRunner.AreTasksDone())
|
||||
{
|
||||
doneTask = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(100);
|
||||
if (DateTime.Now.Subtract(time).TotalMilliseconds > 15000)
|
||||
{
|
||||
doneTask = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//int doneTask = Task.WaitAny(new Task[] { optoheadDeviceIdTask }, TimeSpan.FromMilliseconds(15000));
|
||||
if (doneTask != 0)
|
||||
//if (timeOut == doneTask)
|
||||
{
|
||||
throw new Exception("Timeout");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (optoheadDeviceIdTask is Task<string>)
|
||||
{
|
||||
string serialNr;
|
||||
if (optoheadDeviceIdTask.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
if (optoheadDeviceIdTask is Task<string> taskStr)
|
||||
{
|
||||
string result = taskStr.Result;
|
||||
if (TryGetDeviceId(result, out serialNr))
|
||||
{
|
||||
return serialNr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public OptoHeadStatus SetTestingMode(OptoHeadStatus status)
|
||||
{
|
||||
if (serialPort == null)
|
||||
throw new Exception("Serial port not initialized");
|
||||
|
||||
|
||||
//Task<string> optoheadMode = CliRunner.AddSendAsyncRead(serialPort, SerialPortData.EMeterArg.Optohead);
|
||||
Task<string> optoheadMode = CliRunner.AddSendAsyncWrite(serialPort, SerialPortData.EMeterArg.Optohead, $"0x{((byte)status):X2}");
|
||||
|
||||
int doneTask = -1;
|
||||
DateTime time = DateTime.Now;
|
||||
while (true)
|
||||
{
|
||||
if (CliRunner.AreTasksDone())
|
||||
{
|
||||
doneTask = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(100);
|
||||
if (DateTime.Now.Subtract(time).TotalMilliseconds > 15000)
|
||||
{
|
||||
doneTask = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (optoheadMode is Task<string>)
|
||||
{
|
||||
string strOpticalDataMode;
|
||||
if (optoheadMode.Status == TaskStatus.Faulted)
|
||||
throw new Exception("Error TaskStatus.Faulted");
|
||||
string result = (optoheadMode as Task<string>).Result;
|
||||
if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
||||
{
|
||||
byte value;
|
||||
|
||||
if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
||||
else
|
||||
value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
||||
|
||||
OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
||||
return optoheadStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Error($"Failed to parse OptoHeadStatus from output. Result: {result}");
|
||||
//throw new Exception($"Failed to parse OptoHeadStatus from output. Result: {result}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return OptoHeadStatus.Unknown;
|
||||
}
|
||||
|
||||
|
||||
// public async Task<string> GetSerialNrAsync()
|
||||
// {
|
||||
// if (serialPort == null)
|
||||
// throw new Exception("Serial port not initialized");
|
||||
//
|
||||
// var cts = new CancellationTokenSource(); // we own the token
|
||||
// var sendTask = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId, cts.Token);
|
||||
//
|
||||
// string output;
|
||||
// try
|
||||
// {
|
||||
// output = await CliRunner.WithTimeout(sendTask, TimeSpan.FromSeconds(15), cts);
|
||||
// }
|
||||
// catch (TimeoutException)
|
||||
// {
|
||||
// throw new Exception("Timeout");
|
||||
// }
|
||||
//
|
||||
// if (TryGetDeviceId(output, out var serialNr))
|
||||
// return serialNr;
|
||||
//
|
||||
// throw new Exception("Failed to parse DeviceId from output.");
|
||||
// }
|
||||
|
||||
// public OptoHeadStatus SetTestingMode(OptoHeadStatus status)
|
||||
// {
|
||||
// if (serialPort == null)
|
||||
// throw new Exception("Serial port not initialized");
|
||||
//
|
||||
//
|
||||
// Task optoheadMode =
|
||||
// CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead, $"0x{((byte)status):X2}");
|
||||
// var timeOut = CliRunner.AddTimeOut(5000);
|
||||
// var doneTask = CliRunner.WhenAny();
|
||||
// if (timeOut == doneTask)
|
||||
// {
|
||||
// throw new Exception("Timeout");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (optoheadMode is Task<string>)
|
||||
// {
|
||||
// string strOpticalDataMode;
|
||||
// if (optoheadMode.Status == TaskStatus.Faulted)
|
||||
// throw new Exception("Error TaskStatus.Faulted");
|
||||
// string result = (optoheadMode as Task<string>).Result;
|
||||
// if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
||||
// {
|
||||
// byte value;
|
||||
//
|
||||
// if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
// value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
||||
// else
|
||||
// value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
||||
//
|
||||
// OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
||||
// return optoheadStatus;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return OptoHeadStatus.Unknown;
|
||||
// }
|
||||
//
|
||||
// public OptoHeadStatus GetTestingMode()
|
||||
// {
|
||||
// if (serialPort == null)
|
||||
// throw new Exception("Serial port not initialized");
|
||||
//
|
||||
//
|
||||
// Task optoheadMode = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead);
|
||||
// var timeOut = CliRunner.AddTimeOut(5000);
|
||||
// var doneTask = CliRunner.WhenAny();
|
||||
// if (timeOut == doneTask)
|
||||
// {
|
||||
// throw new Exception("Timeout");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if (optoheadMode is Task<string>)
|
||||
// {
|
||||
// string strOpticalDataMode;
|
||||
// if (optoheadMode.Status == TaskStatus.Faulted)
|
||||
// throw new Exception("Error TaskStatus.Faulted");
|
||||
// string result = (optoheadMode as Task<string>).Result;
|
||||
// if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
||||
// {
|
||||
// byte value;
|
||||
//
|
||||
// if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
||||
// value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
||||
// else
|
||||
// value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
||||
//
|
||||
// OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
||||
// return optoheadStatus;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return OptoHeadStatus.Unknown;
|
||||
// }
|
||||
//
|
||||
// private void SendCommand()
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// private string RawDataAnswer()
|
||||
// {
|
||||
// return "";
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using System.Threading.Tasks;
|
||||
using Common;
|
||||
using log4net;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols;
|
||||
using TBF.Rig.Sequences;
|
||||
using SERIAL_Driver = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.SERIAL_Driver;
|
||||
using WaterMetrologyData = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.WaterMetrologyData;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7
|
||||
{
|
||||
public class OptoHeadService
|
||||
{
|
||||
static readonly ILog log = LogManager.GetLogger("PoseidonConnection");
|
||||
|
||||
public class Con
|
||||
{
|
||||
|
||||
public string com = "COM5";
|
||||
public int baudrate = 38400;
|
||||
public int dataBits = 8;
|
||||
public Parity parity = Parity.None;
|
||||
public StopBits stopbits = StopBits.Two;
|
||||
public int readTimeout = 5000;
|
||||
public int writeTimeout = 1000;
|
||||
private DebugMode _debugLevel;
|
||||
public DebugMode DebugModeSetting { get => _debugLevel; }
|
||||
|
||||
public Con(string com, int baudrate, int dataBits, Parity parity, StopBits stopbits, int readTimeout,
|
||||
int writeTimeout) : this(com)
|
||||
{
|
||||
this.baudrate = baudrate;
|
||||
this.dataBits = dataBits;
|
||||
this.parity = parity;
|
||||
this.stopbits = stopbits;
|
||||
this.readTimeout = readTimeout;
|
||||
this.writeTimeout = writeTimeout;
|
||||
}
|
||||
|
||||
public Con(DebugMode debugLevel,string com, int baudrate, int dataBits, Parity parity, StopBits stopbits, int readTimeout,
|
||||
int writeTimeout) : this(com)
|
||||
{
|
||||
this._debugLevel = debugLevel;
|
||||
this.baudrate = baudrate;
|
||||
this.dataBits = dataBits;
|
||||
this.parity = parity;
|
||||
this.stopbits = stopbits;
|
||||
this.readTimeout = readTimeout;
|
||||
this.writeTimeout = writeTimeout;
|
||||
}
|
||||
|
||||
public Con(string com, DebugMode debugLevel = DebugMode.Normal)
|
||||
{
|
||||
this.com = com;
|
||||
this._debugLevel = debugLevel;
|
||||
}
|
||||
}
|
||||
|
||||
private Con Connection { get; set; }
|
||||
private SERIAL_Driver driver;
|
||||
/// <summary>
|
||||
/// Filed After Run() is called.
|
||||
/// </summary>
|
||||
public WaterMetrologyData WaterMetrologyData { get; private set; }
|
||||
|
||||
public OptoHeadService(Con con)
|
||||
{
|
||||
Connection = con;
|
||||
driver = new SERIAL_Driver();
|
||||
OnOptoReceivedHandler = null;
|
||||
}
|
||||
|
||||
public bool CreateSerialConnection()
|
||||
{
|
||||
OnOptoReceivedHandler = null;
|
||||
bool isopen = false;
|
||||
Con con = Connection;
|
||||
if (con == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] message = {0x00};
|
||||
byte[] bytesReceived;
|
||||
|
||||
if (con?.DebugModeSetting == DebugMode.Simulate)
|
||||
{
|
||||
isopen = true;
|
||||
}
|
||||
else if (!driver.isOpen())
|
||||
{
|
||||
|
||||
isopen = driver.OpenConnection(
|
||||
con.com,
|
||||
con.baudrate,
|
||||
con.dataBits,
|
||||
con.parity,
|
||||
con.stopbits,
|
||||
con.readTimeout,
|
||||
con.writeTimeout);
|
||||
}
|
||||
|
||||
_bRunStarted = false;
|
||||
|
||||
return isopen;
|
||||
}
|
||||
|
||||
public void CloseSerialConnection()
|
||||
{
|
||||
dissableRunLoop = true;
|
||||
OnOptoReceivedHandler = null;
|
||||
if (Connection?.DebugModeSetting != DebugMode.Simulate)
|
||||
{
|
||||
driver.Close();
|
||||
}
|
||||
_bRunStarted = false;
|
||||
}
|
||||
|
||||
private EventHandler<CommonRR.IPerl.communication.OptoReceivedEventArgs> OnOptoReceivedHandler;
|
||||
|
||||
|
||||
|
||||
public bool IsRunning
|
||||
{
|
||||
get { return !dissableRunLoop
|
||||
&& ((Connection?.DebugModeSetting != DebugMode.Simulate) ? driver.isOpen() : true)
|
||||
&& _bRunStarted;}
|
||||
}
|
||||
|
||||
public void RunLoop(EventHandler<CommonRR.IPerl.communication.OptoReceivedEventArgs> onOptoReceivedHandler)
|
||||
{
|
||||
log.Debug("RunLoop started on event!");
|
||||
OnOptoReceivedHandler = onOptoReceivedHandler;
|
||||
Task.Run(() => Run());
|
||||
}
|
||||
|
||||
public void RunLoop()
|
||||
{
|
||||
log.Debug("RunLoop started!");
|
||||
Task.Run(() => Run());
|
||||
}
|
||||
|
||||
private bool dissableRunLoop = false;
|
||||
private bool _bRunStarted = false;
|
||||
/// <summary>
|
||||
/// Run the service. Catch one communication to WaterMetrologyData field.
|
||||
/// </summary>
|
||||
public void Run()
|
||||
{
|
||||
while (!dissableRunLoop)
|
||||
{
|
||||
_bRunStarted = true;
|
||||
WaterMetrologyData = ParseData(RunReading());
|
||||
if (OnOptoReceivedHandler != null && WaterMetrologyData != null)
|
||||
{
|
||||
log.Debug($"Received OptoData: {WaterMetrologyData}");
|
||||
OnOptoReceivedHandler?.Invoke(this, new CommonRR.IPerl.communication.OptoReceivedEventArgs(WaterMetrologyData?.ToString(), WaterMetrologyData));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
byte[] RunReading()
|
||||
{
|
||||
if (Connection?.DebugModeSetting != DebugMode.Simulate)
|
||||
{
|
||||
return new byte[] {0x00};
|
||||
}
|
||||
if (driver.isOpen())
|
||||
{
|
||||
driver.SendMessage(new byte[] {0x00}, 1);
|
||||
byte[] rawData = driver.GetRawData();
|
||||
log.Debug($"Received data size: {rawData?.Length ?? 0} bytes, raw data: {(rawData==null? "" :BitConverter.ToString(rawData))}");
|
||||
return rawData;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.Debug("Serial port is not open.");
|
||||
dissableRunLoop = true;
|
||||
}
|
||||
|
||||
return new byte[] {0xFF};
|
||||
}
|
||||
|
||||
public WaterMetrologyData ParseData(byte[] data)
|
||||
{
|
||||
if (Connection?.DebugModeSetting != DebugMode.Simulate)
|
||||
{
|
||||
return WaterMetrologyData.SimulateC7();
|
||||
}
|
||||
try
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
return null;
|
||||
return WaterMetrologyData.Parse(data, DateTime.Now, "");
|
||||
}catch(Exception e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols
|
||||
{
|
||||
public enum OptoHeadStatus : byte
|
||||
{
|
||||
Unknown = 0xFF,
|
||||
OptoHeadDisabled = 0x00,
|
||||
OptoHeadC2 = 0xC2,
|
||||
OptoHeadC7 = 0xC7,
|
||||
}
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using NfcC7_DLL.NfcHandler.Protocols;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols
|
||||
{
|
||||
public class WaterMetrologyData
|
||||
{
|
||||
private TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.OptoHeadStatus _optoHeadStatus;
|
||||
private WaterMetrologyDataC7 c7Data;
|
||||
private WaterMetrologyDataC2 c2Data;
|
||||
|
||||
public WaterMetrologyDataC7 C7Data { get => c7Data; }
|
||||
public WaterMetrologyDataC2 C2Data { get => c2Data; }
|
||||
public TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.OptoHeadStatus OptoHeadStatus { get => _optoHeadStatus; }
|
||||
|
||||
public static WaterMetrologyData Parse(byte[] data, DateTime dt, string dutinfo)
|
||||
{
|
||||
if (data.Length < 24)
|
||||
{
|
||||
throw new ArgumentException("Invalid data length for WaterMetrologyData C2.");
|
||||
}
|
||||
WaterMetrologyData waterMetrologyData = new WaterMetrologyData();
|
||||
waterMetrologyData._optoHeadStatus = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.OptoHeadStatus.Unknown;
|
||||
// Probably C2
|
||||
if(data.Length > 24 && data.Length < 48)
|
||||
{
|
||||
waterMetrologyData.c2Data = WaterMetrologyDataC2.Parse(data, dt, dutinfo);
|
||||
waterMetrologyData._optoHeadStatus = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.OptoHeadStatus.OptoHeadC2;
|
||||
}
|
||||
// Probably C7
|
||||
else if(data.Length >= 48)
|
||||
{
|
||||
waterMetrologyData.c7Data = WaterMetrologyDataC7.Parse(data, dt, dutinfo);
|
||||
waterMetrologyData._optoHeadStatus = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.OptoHeadStatus.OptoHeadC7;
|
||||
}
|
||||
|
||||
return waterMetrologyData;
|
||||
}
|
||||
|
||||
public static WaterMetrologyData SimulateC7()
|
||||
{
|
||||
WaterMetrologyData waterMetrologyData = new WaterMetrologyData();
|
||||
waterMetrologyData.c7Data = WaterMetrologyDataC7.Simulate();
|
||||
return waterMetrologyData;
|
||||
}
|
||||
|
||||
public static WaterMetrologyData SimulateC2()
|
||||
{
|
||||
WaterMetrologyData waterMetrologyData = new WaterMetrologyData();
|
||||
waterMetrologyData.c2Data = WaterMetrologyDataC2.Simulate();
|
||||
return waterMetrologyData;
|
||||
}
|
||||
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Status: {_optoHeadStatus}, C7Data: {c7Data}, C2Data: {c2Data}";
|
||||
}
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols
|
||||
{
|
||||
public class WaterMetrologyDataC2
|
||||
{
|
||||
public string DutInfo { get; set; }
|
||||
public DateTime Dt { get; set; }
|
||||
public int AdcSample { get; set; }
|
||||
public short LastField { get; set; }
|
||||
public short FlowRate { get; set; }
|
||||
public uint Accumulator { get; set; }
|
||||
public ushort FlipPeriod { get; set; }
|
||||
public ushort VinfStart { get; set; }
|
||||
public ushort VinfEnd { get; set; }
|
||||
public short ElectrodeDelta { get; set; }
|
||||
public ushort Impedance { get; set; }
|
||||
public byte FieldDriveTime { get; set; }
|
||||
public bool IsInLowFlow { get; set; }
|
||||
public bool IsInEmptyPipe { get; set; }
|
||||
public bool FastHPFC { get; set; }
|
||||
public bool FieldPolarity { get; set; }
|
||||
public bool ImpedancePolarity { get; set; }
|
||||
|
||||
|
||||
public double FlowRateLPerS // Flow Rate in L/s metric units
|
||||
{
|
||||
get
|
||||
{
|
||||
double flowRateGPM = FlowRate / 10000; //investigation flow meter GPM
|
||||
double flowRateLPerS = flowRateGPM * 0.063090196432096 ; // conversion factor from GPM to L/s with minimal digit lost
|
||||
return flowRateLPerS;
|
||||
}
|
||||
}
|
||||
public double CalcFlowmLps
|
||||
{
|
||||
get { return FlowRate / 4.0; } // FlowRate is in 1/4 mL/s
|
||||
}
|
||||
public double CalcFlowGPM
|
||||
{
|
||||
get { return CalcFlowmLps * 0.015850323141489; } // mL/s to gal/min conversion
|
||||
}
|
||||
public double CalcAccGal
|
||||
{
|
||||
get { return (Accumulator / 4.0) * 0.000264172; } // Accumulator is in 1/4 mL, convert to gallons
|
||||
}
|
||||
|
||||
public static WaterMetrologyDataC2 Parse(string base64Data, DateTime dt, string dutinfo)
|
||||
{
|
||||
byte[] data = Convert.FromBase64String(base64Data);
|
||||
return Parse(data, dt, dutinfo);
|
||||
}
|
||||
|
||||
public static WaterMetrologyDataC2 Simulate()
|
||||
{
|
||||
var result = new WaterMetrologyDataC2();
|
||||
|
||||
result.DutInfo = "dutinfo";
|
||||
result.Dt = DateTime.Now;
|
||||
result.AdcSample = 1;
|
||||
result.LastField = 2;
|
||||
result.FlowRate = 12456;
|
||||
result.Accumulator = 789465;
|
||||
result.FlipPeriod = 1;
|
||||
result.VinfStart = 0;
|
||||
result.VinfEnd = 0;
|
||||
result.ElectrodeDelta = 1;
|
||||
result.Impedance = 1;
|
||||
result.FieldDriveTime = 0x00 ;
|
||||
|
||||
result.IsInLowFlow = false;
|
||||
result.IsInEmptyPipe = false;
|
||||
result.FastHPFC = false; // Fast High Pass Filter Constant in bit 2
|
||||
result.FieldPolarity = false; // Field Polarity in bit 3
|
||||
result.ImpedancePolarity = false; // Impedance Polarity in bit 4
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static WaterMetrologyDataC2 Parse(byte[] data, DateTime dt, string dutinfo)
|
||||
{
|
||||
if (data.Length < 24)
|
||||
{
|
||||
throw new ArgumentException("Invalid data length for WaterMetrologyData C2.");
|
||||
}
|
||||
|
||||
|
||||
WaterMetrologyDataC2 result = new WaterMetrologyDataC2();
|
||||
|
||||
result.DutInfo = dutinfo;
|
||||
result.Dt = dt;
|
||||
result.AdcSample = BitConverter.ToInt32(data, 0);
|
||||
result.LastField = BitConverter.ToInt16(data, 4);
|
||||
result.FlowRate = BitConverter.ToInt16(data, 6);
|
||||
result.Accumulator = BitConverter.ToUInt32(data, 8);
|
||||
result.FlipPeriod = BitConverter.ToUInt16(data, 12);
|
||||
result.VinfStart = BitConverter.ToUInt16(data, 14);
|
||||
result.VinfEnd = BitConverter.ToUInt16(data, 16);
|
||||
result.ElectrodeDelta = BitConverter.ToInt16(data, 18);
|
||||
result.Impedance = BitConverter.ToUInt16(data, 20);
|
||||
result.FieldDriveTime = data[22];
|
||||
|
||||
byte flags = data[23];
|
||||
result.IsInLowFlow = (flags & 0x01) != 0;
|
||||
result.IsInEmptyPipe = (flags & 0x02) != 0;
|
||||
result.FastHPFC = (flags & 0x04) != 0; // Fast High Pass Filter Constant in bit 2
|
||||
result.FieldPolarity = (flags & 0x08) != 0; // Field Polarity in bit 3
|
||||
result.ImpedancePolarity = (flags & 0x10) != 0; // Impedance Polarity in bit 4
|
||||
return result;
|
||||
}
|
||||
|
||||
//public override string ToString()
|
||||
//{
|
||||
// return $"ADC Sample: {AdcSample}, Last Field: {LastField}, Flow Rate: {FlowRate}, Accumulator: {Accumulator}, " +
|
||||
// $"Flip Period Ticks: {FlipPeriodTicks}, Vinf Start: {VinfStart}, Vinf End: {VinfEnd}, Electrode Delta: {ElectrodeDelta}, " +
|
||||
// $"Impedance: {Impedance}, Field Drive Time: {FieldDriveTime}, Is Low Flow: {IsInLowFlow}, Is Empty Pipe: {IsInEmptyPipe}, " +
|
||||
// $"Fast High Pass Filter: {FastHighPassFilterConstant}, Field Polarity: {FieldPolarity}, Impedance Polarity: {ImpedancePolarity}";
|
||||
//}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"DutInfo: {DutInfo}, Dt: {Dt}, ADC Sample: {AdcSample}, Last Field: {LastField}, Flow Rate: {FlowRate}, Accumulator: {Accumulator}, " +
|
||||
$"Flip Period: {FlipPeriod}, Vinf Start: {VinfStart}, Vinf End: {VinfEnd}, Electrode Delta: {ElectrodeDelta}, " +
|
||||
$"Impedance: {Impedance}, Field Drive Time: {FieldDriveTime}, Is Low Flow: {IsInLowFlow}, Is Empty Pipe: {IsInEmptyPipe}, " +
|
||||
$"Fast HPFC: {FastHPFC}, Field Polarity: {FieldPolarity}, Impedance Polarity: {ImpedancePolarity}, " +
|
||||
$"Calc Flow mL/s: {CalcFlowmLps:F2}, Calc Flow GPM: {CalcFlowGPM:F2}, Calc Acc Gal: {CalcAccGal:F2}";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols
|
||||
{
|
||||
public class WaterMetrologyDataC7 : TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.WaterMetrologyDataC2
|
||||
{
|
||||
// New fields for C7
|
||||
public int LastFieldmilliGauss { get; set; }
|
||||
public int ImpedanceI { get; set; } // In-phase impedance
|
||||
public int ImpedanceQ { get; set; } // Out-of-phase impedance
|
||||
public int NoiseMetric { get; set; }
|
||||
public short LearningLockout { get; set; }
|
||||
public short ReverseBuffer { get; set; }
|
||||
public int ConditionedAdc { get; set; }
|
||||
public uint Totalalizer { get; set; }
|
||||
|
||||
//public bool IsInLowFlow { get; set; }
|
||||
//public bool IsInEmptyPipe { get; set; }
|
||||
//public bool FastHPFC { get; set; }
|
||||
//public bool FieldPolarity { get; set; }
|
||||
//public bool ImpedancePolarity { get; set; }
|
||||
public bool MagTamperState { get; set; }
|
||||
public bool IsLearningActive { get; set; }
|
||||
public bool AdcShiftsUpdated { get; set; }
|
||||
|
||||
public static WaterMetrologyDataC7 Simulate()
|
||||
{
|
||||
var result = new WaterMetrologyDataC7();
|
||||
|
||||
result.DutInfo = "dutinfo";
|
||||
result.Dt = DateTime.Now;
|
||||
result.AdcSample = 1;
|
||||
result.LastField = 2;
|
||||
result.FlowRate = 12456;
|
||||
result.Accumulator = 789465;
|
||||
result.FlipPeriod = 1;
|
||||
result.VinfStart = 0;
|
||||
result.VinfEnd = 0;
|
||||
result.ElectrodeDelta = 1;
|
||||
result.Impedance = 1;
|
||||
result.FieldDriveTime = 0x00 ;
|
||||
|
||||
result.IsInLowFlow = false;
|
||||
result.IsInEmptyPipe = false;
|
||||
result.FastHPFC = false; // Fast High Pass Filter Constant in bit 2
|
||||
result.FieldPolarity = false; // Field Polarity in bit 3
|
||||
result.ImpedancePolarity = false; // Impedance Polarity in bit 4
|
||||
|
||||
result.MagTamperState = true; // bits 5 and 6 represent MagTamperState
|
||||
result.IsLearningActive = true; // bit 7 represents IsLearningActive
|
||||
|
||||
|
||||
|
||||
result.AdcShiftsUpdated = false; // bit 0 represents AdcShiftsUpdated
|
||||
|
||||
result.LastFieldmilliGauss = 0;
|
||||
result.ImpedanceI = 0; // in phase
|
||||
result.ImpedanceQ = 0; // out of phase
|
||||
result.NoiseMetric = 0; //
|
||||
result.LearningLockout = 0;
|
||||
result.ReverseBuffer = 0;
|
||||
result.ConditionedAdc = 0;
|
||||
result.Totalalizer = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static WaterMetrologyDataC7 Parse(string base64Data, DateTime dt, string dutinfo)
|
||||
{
|
||||
byte[] data = Convert.FromBase64String(base64Data);
|
||||
return Parse(data, dt, dutinfo);
|
||||
}
|
||||
|
||||
public static WaterMetrologyDataC7 Parse(byte[] data, DateTime dt, string dutinfo)
|
||||
{
|
||||
|
||||
// You may want to check for the minimum length required for C7
|
||||
if (data.Length < 48) /* minimum required length for C7 */
|
||||
{
|
||||
throw new ArgumentException("Invalid data length for WaterMetrologyData C7.");
|
||||
}
|
||||
|
||||
var result = new WaterMetrologyDataC7();
|
||||
|
||||
// Parse base C2 fields
|
||||
var c2 = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.WaterMetrologyDataC2.Parse(data, dt, dutinfo);
|
||||
|
||||
//Copy base fields
|
||||
result.DutInfo = c2.DutInfo;
|
||||
result.Dt = c2.Dt;
|
||||
result.AdcSample = c2.AdcSample;
|
||||
result.LastField = c2.LastField;
|
||||
result.FlowRate = c2.FlowRate;
|
||||
result.Accumulator = c2.Accumulator;
|
||||
result.FlipPeriod = c2.FlipPeriod;
|
||||
result.VinfStart = c2.VinfStart;
|
||||
result.VinfEnd = c2.VinfEnd;
|
||||
result.ElectrodeDelta = c2.ElectrodeDelta;
|
||||
result.Impedance = c2.Impedance;
|
||||
result.FieldDriveTime = c2.FieldDriveTime;
|
||||
|
||||
|
||||
result.IsInLowFlow = c2.IsInLowFlow;
|
||||
result.IsInEmptyPipe = c2.IsInEmptyPipe;
|
||||
result.FieldPolarity = c2.FieldPolarity;
|
||||
result.ImpedancePolarity = c2.ImpedancePolarity;
|
||||
|
||||
|
||||
// Parse new C7 fields (replace ENUM_OptPack0xC7.FIELD_MILLI_GAUSS etc. with actual offsets)
|
||||
byte flags = data[23];
|
||||
result.MagTamperState = (flags & 0x60) != 0; // bits 5 and 6 represent MagTamperState
|
||||
result.IsLearningActive = (flags & 0x80) != 0; // bit 7 represents IsLearningActive
|
||||
|
||||
byte flagTwo = data[24];
|
||||
|
||||
result.AdcShiftsUpdated = (flagTwo & 0x01) != 0; // bit 0 represents AdcShiftsUpdated
|
||||
|
||||
result.LastFieldmilliGauss = BitConverter.ToInt32(data, 25);
|
||||
result.ImpedanceI = BitConverter.ToInt32(data, 29); // in phase
|
||||
result.ImpedanceQ = BitConverter.ToInt32(data, 33); // out of phase
|
||||
result.NoiseMetric = BitConverter.ToInt32(data, 37); //
|
||||
result.LearningLockout = BitConverter.ToInt16(data, 41);
|
||||
result.ReverseBuffer = BitConverter.ToInt16(data, 43);
|
||||
result.ConditionedAdc = BitConverter.ToInt32(data, 45);
|
||||
result.Totalalizer = BitConverter.ToUInt32(data, 49);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"C7: LastFieldmilliGauss={LastFieldmilliGauss}, ImpedanceI={ImpedanceI}, ImpedanceQ={ImpedanceQ}, NoiseMetric={NoiseMetric}, LearningLockout={LearningLockout}, ReverseBuffer={ReverseBuffer}, ConditionedAdc={ConditionedAdc}, Totalalizer={Totalalizer}, MagTamperState={MagTamperState}, IsLearningActive={IsLearningActive}, AdcShiftsUpdated={AdcShiftsUpdated}" + base.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NfcC7_DLL.NfcHandler.Utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils
|
||||
{
|
||||
public class CliRunner
|
||||
{
|
||||
//static readonly Logger log = LogManager.GetLogger(typeof(CliRunner));
|
||||
//private readonly ILog log;
|
||||
private List<Task> taskPool = new List<Task>();
|
||||
private long startTime;
|
||||
|
||||
public List<Task> TaskPool { get { return taskPool; } }
|
||||
public void AddTask(Task task) { taskPool.Add(task); }
|
||||
public void WaitAll() { Task.WaitAll(taskPool.ToArray()); }
|
||||
|
||||
/// <summary>
|
||||
/// continue with WhenAny() to commpare results if time out is reached
|
||||
/// </summary>
|
||||
/// <param name="timeout"></param>
|
||||
/// <returns></returns>
|
||||
public Task AddTimeOut(int timeout)
|
||||
{
|
||||
Task timeOut = Task.Delay(timeout);
|
||||
taskPool.Add(timeOut);
|
||||
return timeOut;
|
||||
}
|
||||
/// <summary>
|
||||
/// mainly used for time out additional task to compare results
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
|
||||
[Obsolete("Use async/await instead - WaitAnyFinished()")]
|
||||
public async Task<Task> WhenAny() { return await Task.WhenAny(taskPool.ToArray()); }
|
||||
|
||||
public Task WaitAnyFinished(Task task, Task timeOut)
|
||||
{
|
||||
// Task.WhenAny(task, timeOut);
|
||||
// while (true)
|
||||
// {
|
||||
// if (task.IsCompleted) break;
|
||||
// if (task.IsFaulted) break;
|
||||
// if (task.IsCanceled) break;
|
||||
//
|
||||
// if(timeOut.IsCompleted) break;
|
||||
// if(timeOut.IsFaulted) break;
|
||||
// if(timeOut.IsCanceled) break;
|
||||
//
|
||||
// Thread.Sleep(100);
|
||||
// }
|
||||
|
||||
var waitAny = Task.WaitAny(task, timeOut);
|
||||
return waitAny == 0 ? task : timeOut;
|
||||
}
|
||||
|
||||
public static async Task<T> WithTimeout<T>(Task<T> task, TimeSpan timeout, CancellationTokenSource externalCts = null)
|
||||
{
|
||||
var localCts = externalCts == null ? externalCts : new CancellationTokenSource();
|
||||
var timeoutCts = new CancellationTokenSource(timeout);
|
||||
var linked = CancellationTokenSource.CreateLinkedTokenSource(localCts.Token, timeoutCts.Token);
|
||||
|
||||
var completion = new TaskCompletionSource<bool>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
// Observe the task
|
||||
_ = task.ContinueWith(_ => completion.TrySetResult(true), TaskScheduler.Default);
|
||||
|
||||
// Observe the timeout
|
||||
_ = Task.Delay(Timeout.InfiniteTimeSpan, timeoutCts.Token)
|
||||
.ContinueWith(_ => completion.TrySetResult(true), TaskScheduler.Default);
|
||||
|
||||
await completion.Task.ConfigureAwait(false);
|
||||
|
||||
if (timeoutCts.IsCancellationRequested == false && task.IsCompleted) // task finished first
|
||||
return await task.ConfigureAwait(false);
|
||||
|
||||
// timeout won → cancel & throw TimeoutException
|
||||
localCts.Cancel(); // triggers your SendAsync to kill process
|
||||
throw new TimeoutException();
|
||||
}
|
||||
|
||||
public Task<string> AddSendAsync(SerialPortData data, SerialPortData.EMeterArg eMeterArg, CancellationToken ct = default)
|
||||
{
|
||||
var task = SendAsync(data.SerialPortCmdClientPath, data.DefaultArgSettingsRead(eMeterArg), ct);
|
||||
taskPool.Add(task); // List<Task> is okay because Task<string> : Task
|
||||
return task;
|
||||
}
|
||||
|
||||
public Task WaitAnyFinished()
|
||||
{
|
||||
int xTask = Task.WaitAny(taskPool.ToArray());
|
||||
return taskPool[xTask];
|
||||
}
|
||||
|
||||
public void Clear() { taskPool.Clear(); }
|
||||
public void CancelAll() { Task.WhenAll(taskPool).ContinueWith(t => { }); }
|
||||
|
||||
|
||||
public void StartAll()
|
||||
{
|
||||
taskPool.ForEach(t => t.Start());
|
||||
}
|
||||
|
||||
public bool AreTasksDone()
|
||||
{
|
||||
return taskPool.All(task => task.IsCompleted);
|
||||
}
|
||||
|
||||
public long StartTime
|
||||
{
|
||||
get => startTime;
|
||||
}
|
||||
|
||||
public bool TimeOutReceived(long timeout)
|
||||
{
|
||||
return (DateTime.Now.Ticks - startTime) > timeout;
|
||||
}
|
||||
|
||||
public CliRunner(bool isCliLogging)
|
||||
{
|
||||
startTime = DateTime.Now.Ticks;
|
||||
|
||||
if (isCliLogging)
|
||||
{
|
||||
try
|
||||
{
|
||||
/*log = new ScopedLoggerFactory().CreateLogger<CliRunner>(
|
||||
@"C:\TBF\Logs\CliRunner.txt",
|
||||
10, // maxFileSizeMB
|
||||
7, // maxBackups
|
||||
log4net.Core.Level.Debug,
|
||||
true, // zipRolledFiles
|
||||
true, // singleZipPerDay
|
||||
TimeSpan.FromMinutes(2) // zipScanInterval
|
||||
);*/
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Fallback to console or handle gracefully
|
||||
Console.WriteLine($"Failed to initialize logger: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public Task AddSendAsync(SerialPortData data, SerialPortData.EMeterArg eMeterArg)
|
||||
{
|
||||
var task = SendAsync(data.SerialPortCmdClientPath, data.DefaultArgSettingsRead(eMeterArg));
|
||||
taskPool.Add(task);
|
||||
var t = Task.Run(async () => { await task; }); // OK: Task
|
||||
return t;
|
||||
}
|
||||
|
||||
public Task AddSendAsync(SerialPortData data, SerialPortData.EMeterArg eMeterArg, string arg)
|
||||
{
|
||||
var task = SendAsync(data.SerialPortCmdClientPath, data.DefaultArgSettingsWrite(eMeterArg, arg));
|
||||
taskPool.Add(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public void AddSendAsync(string fileName, string args)
|
||||
{
|
||||
var task = SendAsync(fileName, args);
|
||||
taskPool.Add(task);
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> SendAsync(string fileName, string args, CancellationToken ct = default)
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = args,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
|
||||
Task<string> stdOutTask = process.StandardOutput.ReadToEndAsync();
|
||||
Task<string> stdErrTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
try
|
||||
{
|
||||
await Task.WhenAll(stdOutTask, stdErrTask, process.WaitForExitAsync(ct));
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
if (!process.HasExited)
|
||||
{
|
||||
process.Kill();
|
||||
}
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
string allOutput = (stdOutTask.Result ?? "") + (stdErrTask.Result ?? "");
|
||||
//log?.Debug(allOutput);
|
||||
return allOutput;
|
||||
}
|
||||
finally
|
||||
{
|
||||
process?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public Task<T> AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg) where T : new()
|
||||
{
|
||||
var task = RunAndCaptureJsonAsync<T>(data.SerialPortCmdClientPath, data.DefaultArgSettingsRead(eMeterArg));
|
||||
taskPool.Add(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args, CancellationToken ct = default) where T : new()
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = args,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
|
||||
var stdoutTask = process.StandardOutput.ReadToEndAsync();
|
||||
var stderrTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
await Task.WhenAll(stdoutTask, stderrTask, process.WaitForExitAsync(ct));
|
||||
|
||||
string allOutput = (stdoutTask.Result ?? "") + (stderrTask.Result ?? "");
|
||||
//log?.Debug(allOutput);
|
||||
|
||||
string json = ExtractJson(allOutput);
|
||||
if (TryJsonStringDeserialize(json, out T result)) return result;
|
||||
return default;
|
||||
}
|
||||
finally
|
||||
{
|
||||
process?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryJsonStringDeserialize<T>(string json, out T runAndCaptureJsonAsync) where T : new()
|
||||
{
|
||||
if (json != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
runAndCaptureJsonAsync = JsonConvert.DeserializeObject<T>(json);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// log.Debug(ex.Message);
|
||||
runAndCaptureJsonAsync = TryConvert<T>(json);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
runAndCaptureJsonAsync = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static T TryConvert<T>(string json) where T : new()
|
||||
{
|
||||
|
||||
T obj = new T();
|
||||
|
||||
try
|
||||
{
|
||||
JObject jObject = JObject.Parse(json);
|
||||
|
||||
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
if (!prop.CanWrite) continue;
|
||||
|
||||
JToken token;
|
||||
if (jObject.TryGetValue(prop.Name, StringComparison.OrdinalIgnoreCase, out token))
|
||||
{
|
||||
try
|
||||
{
|
||||
object value = token.ToObject(prop.PropertyType);
|
||||
prop.SetValue(obj, value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// leave default if conversion fails
|
||||
}
|
||||
}
|
||||
// else → keep default value
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"TryConvert failed: {ex.Message}");
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
public string ExtractJson(string text)
|
||||
{
|
||||
int start = text.IndexOf('{');
|
||||
int end = text.LastIndexOf('}');
|
||||
|
||||
if (start >= 0 && end > start)
|
||||
{
|
||||
return text.Substring(start, end - start + 1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using log4net;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using TBF.Rig.RegisterReaders.PoseidonCmdStartStop;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils
|
||||
{
|
||||
public class CliRunnerOld
|
||||
{
|
||||
|
||||
//static readonly ILog log = LogManager.GetLogger(typeof(CliRunner));
|
||||
private readonly ILog log;
|
||||
private List<Task> taskPool = new List<Task>();
|
||||
private long startTime;
|
||||
|
||||
public List<Task> TaskPool { get { return taskPool; } }
|
||||
public void AddTask(Task task) { taskPool.Add(task); }
|
||||
public void WaitAll() { Task.WaitAll(taskPool.ToArray()); }
|
||||
public void Clear() { taskPool.Clear(); }
|
||||
public void CancelAll() { Task.WhenAll(taskPool).ContinueWith(t => { }); }
|
||||
|
||||
public void StartAll()
|
||||
{
|
||||
taskPool.ForEach(t =>
|
||||
{
|
||||
try
|
||||
{
|
||||
t.Start();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Debug(ex.Message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public bool AreTasksDone()
|
||||
{
|
||||
return taskPool.All(task => task.IsCompleted);
|
||||
}
|
||||
|
||||
public long StartTime
|
||||
{
|
||||
get => startTime;
|
||||
}
|
||||
|
||||
public bool TimeOutReceived(long timeout)
|
||||
{
|
||||
return (DateTime.Now.Ticks - startTime) > timeout;
|
||||
}
|
||||
|
||||
public CliRunnerOld(bool isCliLogging)
|
||||
{
|
||||
startTime = DateTime.Now.Ticks;
|
||||
|
||||
if (isCliLogging)
|
||||
{
|
||||
log = new ScopedLoggerFactory().CreateLogger<CliRunnerOld>(
|
||||
@"C:\TBF\Logs\CliRunner.txt",
|
||||
10, // maxFileSizeMB
|
||||
7, // maxBackups
|
||||
log4net.Core.Level.Debug,
|
||||
true, // zipRolledFiles
|
||||
true, // singleZipPerDay
|
||||
TimeSpan.FromMinutes(2) // zipScanInterval
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public Task<string> AddSendAsyncRead(SerialPortData data, SerialPortData.EMeterArg eMeterArg)
|
||||
{
|
||||
var task = SendAsync(data.SerialPortCmdClientPath, data.DefaultArgSettingsRead(eMeterArg));
|
||||
taskPool.Add(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public Task<string> AddSendAsyncWrite(SerialPortData data, SerialPortData.EMeterArg eMeterArg, string arg)
|
||||
{
|
||||
var task = SendAsync(data.SerialPortCmdClientPath, data.DefaultArgSettingsWrite(eMeterArg, arg));
|
||||
taskPool.Add(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
public void AddSendAsync(string fileName, string args)
|
||||
{
|
||||
var task = SendAsync(fileName, args);
|
||||
taskPool.Add(task);
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> SendAsync(string fileName, string args)
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = args,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var process = new Process { StartInfo = psi };
|
||||
var sb = new StringBuilder();
|
||||
|
||||
process.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
if (e.Data != null)
|
||||
sb.AppendLine(e.Data);
|
||||
};
|
||||
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
|
||||
process.WaitForExit();
|
||||
|
||||
// Now all outputs are available
|
||||
string allOutput = sb.ToString();
|
||||
log?.Debug(allOutput);
|
||||
|
||||
return allOutput;
|
||||
}
|
||||
|
||||
public void AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg) where T : new()
|
||||
{
|
||||
var task = RunAndCaptureJsonAsync<T>(data.SerialPortCmdClientPath, data.DefaultArgSettingsRead(eMeterArg));
|
||||
taskPool.Add(task);
|
||||
}
|
||||
|
||||
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args) where T : new()
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = args,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var process = new Process { StartInfo = psi };
|
||||
var sb = new StringBuilder();
|
||||
|
||||
process.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
if (e.Data != null)
|
||||
sb.AppendLine(e.Data);
|
||||
};
|
||||
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
|
||||
process.WaitForExit();
|
||||
|
||||
// Now sb contains all output text
|
||||
string allOutput = sb.ToString();
|
||||
log?.Debug(allOutput);
|
||||
|
||||
// Extract JSON part
|
||||
string json = ExtractJson(allOutput);
|
||||
|
||||
if (TryJsonStringDeserialize(json, out T runAndCaptureJsonAsync)) return runAndCaptureJsonAsync;
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public bool TryJsonStringDeserialize<T>(string json, out T runAndCaptureJsonAsync) where T : new()
|
||||
{
|
||||
if (json != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
runAndCaptureJsonAsync = JsonConvert.DeserializeObject<T>(json);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Debug(ex.Message);
|
||||
runAndCaptureJsonAsync = TryConvert<T>(json);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
runAndCaptureJsonAsync = default;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static T TryConvert<T>(string json) where T : new()
|
||||
{
|
||||
|
||||
T obj = new T();
|
||||
|
||||
try
|
||||
{
|
||||
JObject jObject = JObject.Parse(json);
|
||||
|
||||
foreach (PropertyInfo prop in typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance))
|
||||
{
|
||||
if (!prop.CanWrite) continue;
|
||||
|
||||
JToken token;
|
||||
if (jObject.TryGetValue(prop.Name, StringComparison.OrdinalIgnoreCase, out token))
|
||||
{
|
||||
try
|
||||
{
|
||||
object value = token.ToObject(prop.PropertyType);
|
||||
prop.SetValue(obj, value);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// leave default if conversion fails
|
||||
}
|
||||
}
|
||||
// else → keep default value
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"TryConvert failed: {ex.Message}");
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
public string ExtractJson(string text)
|
||||
{
|
||||
int start = text.IndexOf('{');
|
||||
int end = text.LastIndexOf('}');
|
||||
|
||||
if (start >= 0 && end > start)
|
||||
{
|
||||
return text.Substring(start, end - start + 1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils
|
||||
{
|
||||
public static class ProcessExtensions
|
||||
{
|
||||
public static Task<object> WaitForExitAsync(this Process process, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (process == null) throw new ArgumentNullException(nameof(process));
|
||||
if (process.HasExited) return Task.FromResult<object>(null);
|
||||
|
||||
var tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
|
||||
EventHandler handler = null;
|
||||
handler = (s, e) =>
|
||||
{
|
||||
try { tcs.TrySetResult(null); }
|
||||
finally { process.Exited -= handler; }
|
||||
};
|
||||
|
||||
process.EnableRaisingEvents = true;
|
||||
process.Exited += handler;
|
||||
|
||||
if (cancellationToken.CanBeCanceled)
|
||||
{
|
||||
cancellationToken.Register(() =>
|
||||
{
|
||||
tcs.TrySetCanceled(cancellationToken);
|
||||
process.Exited -= handler;
|
||||
});
|
||||
}
|
||||
|
||||
return tcs.Task;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
//*****************************************************************************
|
||||
// Copyright 2020 Sensus GmbH Ludwigshafen. All rights reserved.
|
||||
// Author: Venkat, Rajeshwar
|
||||
//*****************************************************************************
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils
|
||||
{
|
||||
public class SERIAL_Driver
|
||||
{
|
||||
public string ErrorMessage { get; private set; }
|
||||
public Collection<byte> SerialPortReadBuffer = new Collection<byte>();
|
||||
private SerialPort _serialPort;
|
||||
|
||||
private List<byte[]> _binMessages = new List<byte[]>();
|
||||
private bool _isReading;
|
||||
private Parity Parity { get; set; }
|
||||
private StopBits StopBits { get; set; }
|
||||
|
||||
public SERIAL_Driver()
|
||||
{
|
||||
_serialPort = new SerialPort();
|
||||
}
|
||||
|
||||
public bool OpenConnection(string comPort, int baudrate, int dataBits, Parity parity, StopBits stopbits, int readTimeout=1000, int writeTimeout = 1000)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if ((_serialPort != null) && (_serialPort.IsOpen))
|
||||
{
|
||||
_serialPort.DataReceived -= DataReceivedHandler;
|
||||
_serialPort.Close();
|
||||
_serialPort.Dispose();
|
||||
_serialPort = null;
|
||||
}
|
||||
try
|
||||
{
|
||||
ErrorMessage = "";
|
||||
//_serialPort = new SerialPort(comPort, 57600, Parity.None, 8, StopBits.Two);
|
||||
_serialPort = new SerialPort(comPort, baudrate, parity, dataBits, stopbits);
|
||||
_serialPort.ReadTimeout = readTimeout;
|
||||
_serialPort.WriteTimeout = writeTimeout;
|
||||
_serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
|
||||
_serialPort.Open();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorMessage = String.Format("COM error: Open failed {0}.{1}", comPort, ex.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_serialPort.IsOpen)
|
||||
{
|
||||
ErrorMessage = String.Format("COM error: Can't Open {0}.", comPort);
|
||||
return false;
|
||||
}
|
||||
}//End Lock
|
||||
return true;
|
||||
}
|
||||
public bool SendMessage(byte[] sendDataBytes, int length, int readTimeout = 1000, int writeTimeout=1000)
|
||||
{
|
||||
if (!isOpen()) return false;
|
||||
if (sendDataBytes.Length == 0) return true; // nothing to send - no error
|
||||
try
|
||||
{
|
||||
PrepareReading(); //clear read buffer etc.
|
||||
_serialPort.WriteTimeout = writeTimeout;
|
||||
_serialPort.ReadTimeout = readTimeout;
|
||||
_serialPort.Write(sendDataBytes, 0, length);
|
||||
_isReading = true;
|
||||
Thread.Sleep(100);
|
||||
var stopWatch = Stopwatch.StartNew(); //start stop watch for data recevie timeout
|
||||
while (_isReading) //wait until reading finishes or timeout occur
|
||||
{
|
||||
if (stopWatch.ElapsedMilliseconds > readTimeout)
|
||||
{
|
||||
stopWatch.Stop();
|
||||
ErrorMessage = "COM error: Receive timeout";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorMessage = String.Format("COM error: Transmit timeout {0}.{1}", _serialPort.PortName, ex.Message);
|
||||
return false; // Exception in send function
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private void PrepareReading()
|
||||
{
|
||||
_serialPort.DiscardInBuffer();
|
||||
if(_binMessages != null) _binMessages.Clear();
|
||||
_isReading = true;
|
||||
}
|
||||
public byte[] GetRawData()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_binMessages.Count > 0)
|
||||
return _binMessages[0].ToArray();
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
byte[] err = { 0xFF };
|
||||
return err;
|
||||
}
|
||||
}
|
||||
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
// Check if port is still valid and open
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
|
||||
// Re-check after sleep - port might have been closed during sleep
|
||||
if (_serialPort == null || !_serialPort.IsOpen)
|
||||
return;
|
||||
|
||||
SerialPortReadBuffer = new Collection<byte>();
|
||||
|
||||
// Check before accessing BytesToRead
|
||||
while (_serialPort.IsOpen && _serialPort.BytesToRead > 0)
|
||||
{
|
||||
SerialPortReadBuffer.Add((byte)_serialPort.ReadByte());
|
||||
}
|
||||
|
||||
if (SerialPortReadBuffer.Count > 0)
|
||||
{
|
||||
_binMessages.Add(SerialPortReadBuffer.ToArray());
|
||||
}
|
||||
|
||||
_isReading = false;
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
// Port was closed during operation - this is expected during shutdown
|
||||
_isReading = false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log other unexpected errors
|
||||
_isReading = false;
|
||||
ErrorMessage = String.Format("COM error: Data receive error - {0}", ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseConnection()
|
||||
{
|
||||
if ((_serialPort != null) && (_serialPort.IsOpen))
|
||||
{
|
||||
_serialPort.DataReceived -= DataReceivedHandler;
|
||||
_serialPort.Close();
|
||||
_serialPort.Dispose();
|
||||
_serialPort = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (isOpen())
|
||||
{
|
||||
_serialPort.Close();
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
if (_serialPort != null)
|
||||
{
|
||||
_serialPort.Dispose();
|
||||
}
|
||||
}
|
||||
public bool isOpen()
|
||||
{
|
||||
if(_serialPort != null)
|
||||
return _serialPort.IsOpen;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils
|
||||
{
|
||||
public class SerialPortData
|
||||
{
|
||||
private Boolean? _cliExists;
|
||||
public bool CliExists { get {
|
||||
if (_cliExists == null || !_cliExists.HasValue)
|
||||
{
|
||||
_cliExists = File.Exists(SerialPortCmdClientPath);
|
||||
}
|
||||
return _cliExists.Value;
|
||||
} }
|
||||
public string SerialPortCmdClientPath {
|
||||
get {
|
||||
#if DEBUG
|
||||
return Path.Combine("C:\\","TBF","Cli", CmdClientName);
|
||||
#else
|
||||
return Path.Combine("..","Cli", CmdClientName);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
public string CmdClientName { get; set; } = "HalCli.exe";
|
||||
public string PortName { get; set; }
|
||||
public int MeterType { get; set; }
|
||||
public string MeterTypeStr { get; set; }
|
||||
|
||||
public enum EMeterArg {
|
||||
Calibration = 0,
|
||||
AllParams = 2,
|
||||
DeviceId = 3,
|
||||
Optohead = 4,
|
||||
}
|
||||
EMeterArg _eMeterArg = EMeterArg.AllParams;
|
||||
|
||||
public string DefaultArgSettingsRead(EMeterArg eMeterArg)
|
||||
{
|
||||
string meterTypeInsert = !string.IsNullOrEmpty(MeterTypeStr) ? MeterTypeStr : MeterType.ToString();
|
||||
switch (eMeterArg)
|
||||
{
|
||||
case EMeterArg.AllParams:
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation readall";
|
||||
case EMeterArg.DeviceId:
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation read --parameter DeviceId";
|
||||
case EMeterArg.Optohead:
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation read --parameter \"OpticalDataMode\"";
|
||||
default:
|
||||
throw new Exception("Not implemented correct command!");
|
||||
}
|
||||
}
|
||||
|
||||
public string DefaultArgSettingsWrite(EMeterArg eMeterArg, string arg)
|
||||
{
|
||||
string meterTypeInsert = !string.IsNullOrEmpty(MeterTypeStr) ? MeterTypeStr : MeterType.ToString();
|
||||
switch (eMeterArg)
|
||||
{
|
||||
case EMeterArg.Calibration:
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation write --parameter Calibration --value {arg}";
|
||||
case EMeterArg.Optohead:
|
||||
return $"-p {PortName} -m {meterTypeInsert} --operation write --parameter \"OpticalDataMode\" --value {arg}";
|
||||
default:
|
||||
throw new Exception("Not implemented correct command!");
|
||||
}
|
||||
}
|
||||
|
||||
public SerialPortData(
|
||||
string portName,
|
||||
string cmdClientName,
|
||||
int meterType)
|
||||
{
|
||||
PortName = portName;
|
||||
CmdClientName = cmdClientName;
|
||||
MeterType = meterType;
|
||||
}
|
||||
|
||||
public SerialPortData(
|
||||
string portName,
|
||||
string cmdClientName,
|
||||
string meterType)
|
||||
{
|
||||
PortName = portName;
|
||||
CmdClientName = cmdClientName;
|
||||
MeterTypeStr = meterType;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
//*****************************************************************************
|
||||
// Copyright 2020 Sensus GmbH Ludwigshafen. All rights reserved.
|
||||
// Author: Venkat, Rajeshwar
|
||||
//*****************************************************************************
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils
|
||||
{
|
||||
public static class Tools
|
||||
{
|
||||
public static bool ByteArrayCompare(byte[] a1, byte[] a2)
|
||||
{
|
||||
// thanks to https://stackoverflow.com/questions/43289/comparing-two-byte-arrays-in-net
|
||||
if (a1.Length != a2.Length)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < a1.Length; i++)
|
||||
if (a1[i] != a2[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
public static string SwapHex(string sHex)
|
||||
{
|
||||
string sResult = "";
|
||||
int iPos = sHex.Length - 2;
|
||||
while (iPos >= 0)
|
||||
{
|
||||
sResult += sHex.Substring(iPos, 2);
|
||||
sHex = sHex.Remove(iPos, 2);
|
||||
iPos = sHex.Length - 2;
|
||||
}
|
||||
return sResult;
|
||||
}
|
||||
public static string DecimalToHexString(string value, int size = 1)
|
||||
{
|
||||
try
|
||||
{
|
||||
long Lval = long.Parse(value);
|
||||
if (size == 1) return Lval.ToString("X2");
|
||||
if (size == 2) return Lval.ToString("X4");
|
||||
if (size == 4) return Lval.ToString("X8");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (size == 1) return "00";
|
||||
if (size == 2) return "0000";
|
||||
if (size == 4) return "00000000";
|
||||
}
|
||||
return "00";
|
||||
}
|
||||
public static string ByteToHexString(byte data)
|
||||
{
|
||||
List<byte> val = new List<byte>();
|
||||
val.Add(data);
|
||||
byte[] arr = val.ToArray();
|
||||
return BytesToHex(arr);
|
||||
}
|
||||
public static string BytesToHex(byte[] data)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach (byte b in data)
|
||||
sb.Append(b.ToString("X2"));
|
||||
|
||||
return sb.ToString();
|
||||
|
||||
}
|
||||
public static byte[] HexStringToByteArray(String hexString)
|
||||
{
|
||||
int numberChars = hexString.Length;
|
||||
byte[] bytes = new byte[numberChars / 2];
|
||||
for (int i = 0; i < numberChars; i += 2)
|
||||
{
|
||||
bytes[i / 2] = Convert.ToByte(hexString.Substring(i, 2), 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
public enum InitialCrcValue
|
||||
{
|
||||
Zeros,
|
||||
NonZero1 = 0xffff,
|
||||
NonZero2 = 0x1D0F
|
||||
}
|
||||
|
||||
public class Crc16Ccitt
|
||||
{
|
||||
private const ushort poly = 0x1021;
|
||||
ushort[] table = new ushort[256];
|
||||
ushort initialValue = 0;
|
||||
|
||||
public ushort ComputeChecksum(byte[] bytes)
|
||||
{
|
||||
ushort crc = this.initialValue;
|
||||
for (int i = 0; i < bytes.Length; ++i)
|
||||
{
|
||||
crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]);
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
public byte[] ComputeChecksumBytes(byte[] bytes)
|
||||
{
|
||||
ushort crc = ComputeChecksum(bytes);
|
||||
return BitConverter.GetBytes(crc);
|
||||
}
|
||||
public Crc16Ccitt(InitialCrcValue initialValue)
|
||||
{
|
||||
this.initialValue = (ushort) initialValue;
|
||||
ushort temp, a;
|
||||
for (int i = 0; i < table.Length; ++i)
|
||||
{
|
||||
temp = 0;
|
||||
a = (ushort) (i << 8);
|
||||
for (int j = 0; j < 8; ++j)
|
||||
{
|
||||
if (((temp ^ a) & 0x8000) != 0)
|
||||
{
|
||||
temp = (ushort) ((temp << 1) ^ poly);
|
||||
}
|
||||
else
|
||||
{
|
||||
temp <<= 1;
|
||||
}
|
||||
a <<= 1;
|
||||
}
|
||||
table[i] = temp;
|
||||
}
|
||||
}
|
||||
public byte[] calcCRCfromMessage(byte[] message)
|
||||
{
|
||||
// CRC calculation goes from MessageID to Password
|
||||
// For Read this means MsgID (1) + Offset (2) + PayloadLength (1) + Password (2) = 6
|
||||
// for write the length of the payload comes on top.
|
||||
// STX(1), length(1), CRC(2) and ETX(1) are excluded, in total 5 bytes.
|
||||
//
|
||||
// the method works both for sending messages (where the CRC and ETX are not in message)
|
||||
// and for receiving messages (where the CRC and ETX are included at the end)
|
||||
byte[] crc_msg = new byte[message[1]]; // message length is 2nd byte
|
||||
Array.Copy(message, 2, crc_msg, 0, crc_msg.Length);
|
||||
return ComputeChecksumBytes(crc_msg);
|
||||
}
|
||||
public string commentCRC(byte[] crc_meter, byte[] crc_computed)
|
||||
{
|
||||
bool crc_do_match = Tools.ByteArrayCompare(crc_meter, crc_computed);
|
||||
string crcComment = crc_do_match ? "ok." : "CRC DOESN'T MATCH!!";
|
||||
return "CRC Meter: " + Tools.BytesToHex(crc_meter) + (crc_do_match ? " == " : " != ")
|
||||
+ "CRC Computed: " + Tools.BytesToHex(crc_computed) + ". " + crcComment;
|
||||
}
|
||||
public bool crc_do_match(byte[] a, byte[] b)
|
||||
{
|
||||
return ByteArrayCompare(a, b);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,245 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2020 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.comminication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
{
|
||||
public class CalibrationStruct
|
||||
{
|
||||
public const int Length = 35;
|
||||
|
||||
public Byte Version;
|
||||
public MeterType MeterType;
|
||||
public UInt16 Calibration;
|
||||
public VolumeUnits VolumeUnits;
|
||||
public FlowArrow FlowArrow;
|
||||
public UInt16 FWVersion;
|
||||
public UInt16[] TargetField;
|
||||
public UInt16 RecipMeanCurrent;
|
||||
public UInt16 ThresholdVolume;
|
||||
public UInt16 ThresholdTime;
|
||||
public UInt16 FlowActivationThr;
|
||||
public UInt16 VolumeArrowThr;
|
||||
public UInt32 CalibrationTime;
|
||||
public ulong SerialNumber;
|
||||
public MeterSealed MeterSealed;
|
||||
public byte CheckSum;
|
||||
|
||||
|
||||
public CalibrationStruct()
|
||||
{
|
||||
TargetField = new UInt16[3];
|
||||
}
|
||||
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
byte[] result = new byte[Length];
|
||||
|
||||
result[0] = Version;
|
||||
result[1] = (byte)MeterType;
|
||||
|
||||
result[2] = (byte)(Calibration & 0x00FF);
|
||||
result[3] = (byte)((Calibration >> 8) & 0x00FF);
|
||||
|
||||
result[4] = (byte)VolumeUnits;
|
||||
|
||||
result[5] = (byte)FlowArrow;
|
||||
|
||||
result[6] = (byte)(FWVersion & 0x00FF);
|
||||
result[7] = (byte)((FWVersion >> 8) & 0x00FF);
|
||||
|
||||
result[8] = (byte)( TargetField[0] & 0x00FF);
|
||||
result[9] = (byte)((TargetField[0] >> 8) & 0x00FF);
|
||||
result[10] = (byte)( TargetField[1] & 0x00FF);
|
||||
result[11] = (byte)((TargetField[1] >> 8) & 0x00FF);
|
||||
result[12] = (byte)( TargetField[2] & 0x00FF);
|
||||
result[13] = (byte)((TargetField[2] >> 8) & 0x00FF);
|
||||
|
||||
result[14] = (byte)(RecipMeanCurrent & 0x00FF);
|
||||
result[15] = (byte)((RecipMeanCurrent >> 8) & 0x00FF);
|
||||
|
||||
result[16] = (byte)(ThresholdVolume & 0x00FF);
|
||||
result[17] = (byte)((ThresholdVolume >> 8) & 0x00FF);
|
||||
|
||||
result[18] = (byte)(ThresholdTime & 0x00FF);
|
||||
result[19] = (byte)((ThresholdTime >> 8) & 0x00FF);
|
||||
|
||||
result[20] = (byte)(FlowActivationThr & 0x00FF);
|
||||
result[21] = (byte)((FlowActivationThr >> 8) & 0x00FF);
|
||||
|
||||
result[22] = (byte)(VolumeArrowThr & 0x00FF);
|
||||
result[23] = (byte)((VolumeArrowThr >> 8) & 0x00FF);
|
||||
|
||||
result[24] = (byte)(CalibrationTime & 0x000000FF);
|
||||
result[25] = (byte)((CalibrationTime >> 8) & 0x000000FF);
|
||||
result[26] = (byte)((CalibrationTime >> 16) & 0x000000FF);
|
||||
result[27] = (byte)((CalibrationTime >> 24) & 0x000000FF);
|
||||
|
||||
result[28] = (byte)(SerialNumber & 0x00000000000000FF);
|
||||
result[29] = (byte)((SerialNumber >> 8) & 0x00000000000000FF);
|
||||
result[30] = (byte)((SerialNumber >> 16) & 0x00000000000000FF);
|
||||
result[31] = (byte)((SerialNumber >> 24) & 0x00000000000000FF);
|
||||
result[32] = (byte)((SerialNumber >> 32) & 0x00000000000000FF);
|
||||
|
||||
result[33] = (byte)MeterSealed;
|
||||
result[34] = CheckSum;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a calibration structure from a complete byte array
|
||||
/// </summary>
|
||||
/// <param name="data">A complete byte array data</param>
|
||||
/// <returns>CalibrationStruct or null when byte array was not complete</returns>
|
||||
public static CalibrationStruct FromByteArray(byte[] data)
|
||||
{
|
||||
if (data.Length != Length) return null;
|
||||
|
||||
CalibrationStruct result = new CalibrationStruct();
|
||||
|
||||
result.Version = data[0];
|
||||
result.MeterType = (MeterType)data[1];
|
||||
result.Calibration = (UInt16)(data[2] + 256 * data[3]);
|
||||
result.VolumeUnits = (VolumeUnits)data[4];
|
||||
result.FlowArrow = (FlowArrow)data[5];
|
||||
result.FWVersion = (UInt16)(data[6] + 256 * data[7]);
|
||||
result.TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
|
||||
result.TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
|
||||
result.TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
|
||||
result.RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
|
||||
result.ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
|
||||
result.ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
|
||||
result.FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
|
||||
result.VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
|
||||
result.CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
|
||||
result.SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
|
||||
result.MeterSealed = (MeterSealed)data[33];
|
||||
result.CheckSum = data[34];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the calibration structure from an incomplete byte array
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array data</param>
|
||||
/// <param name="offset">Offset of byte array data in CalibrationStruct</param>
|
||||
/// <returns>true when successful, false when data are not appropriate</returns>
|
||||
public bool Update(byte[] data, int offset)
|
||||
{
|
||||
if ((data.Length == 2) && (offset == 2))
|
||||
{
|
||||
/// Data containing iPerl calibration factor
|
||||
Calibration = (UInt16)(data[0] + 256 * data[1]);
|
||||
return true;
|
||||
}
|
||||
else if ((data.Length == Length) && (offset == 0))
|
||||
{
|
||||
/// Data containing a complete CalibrationStruct
|
||||
Version = data[0];
|
||||
MeterType = (MeterType)data[1];
|
||||
Calibration = (UInt16)(data[2] + 256 * data[3]);
|
||||
VolumeUnits = (VolumeUnits)data[4];
|
||||
FlowArrow = (FlowArrow)data[5];
|
||||
FWVersion = (UInt16)(data[6] + 256 * data[7]);
|
||||
TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
|
||||
TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
|
||||
TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
|
||||
RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
|
||||
ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
|
||||
ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
|
||||
FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
|
||||
VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
|
||||
CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
|
||||
SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
|
||||
MeterSealed = (MeterSealed)data[33];
|
||||
CheckSum = data[34];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public string FWVersionStr()
|
||||
{
|
||||
int d1 = (FWVersion >> 8) & 0x000F;
|
||||
int d2 = (FWVersion >> 12) & 0x000F;
|
||||
int d3 = (FWVersion >> 4) & 0x000F;
|
||||
int d4 = FWVersion & 0x000F;
|
||||
return string.Format("{0}.{1}{2}{3}", d1, d2, d3, d4);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Calibration: V{0} Type={1} Cal={2} Units={3} FlowArrow.{4} FW={5} Hi={6} Norm={7} Low={8} RMC={9} ThrVol={10} ThrTime={11} FlActThr={12} VolArrThr={13} CalTm={14} SN={15} MeterSealed={16} Chksum={17}",
|
||||
Version,
|
||||
MeterType,
|
||||
Calibration,
|
||||
VolumeUnits,
|
||||
FlowArrow,
|
||||
FWVersion,
|
||||
TargetField[0],
|
||||
TargetField[1],
|
||||
TargetField[2],
|
||||
RecipMeanCurrent,
|
||||
ThresholdVolume,
|
||||
ThresholdTime,
|
||||
FlowActivationThr,
|
||||
VolumeArrowThr,
|
||||
CalibrationTime,
|
||||
SerialNumber,
|
||||
MeterSealed,
|
||||
CheckSum.ToString("X2"));
|
||||
}
|
||||
|
||||
public virtual void WriteBinary(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(Version);
|
||||
writer.Write((byte)MeterType);
|
||||
writer.Write(Calibration);
|
||||
writer.Write((byte)VolumeUnits);
|
||||
writer.Write((byte)FlowArrow);
|
||||
writer.Write(FWVersion);
|
||||
writer.Write(TargetField[0]);
|
||||
writer.Write(TargetField[1]);
|
||||
writer.Write(TargetField[2]);
|
||||
writer.Write(RecipMeanCurrent);
|
||||
writer.Write(ThresholdVolume);
|
||||
writer.Write(ThresholdTime);
|
||||
writer.Write(FlowActivationThr);
|
||||
writer.Write(VolumeArrowThr);
|
||||
writer.Write(CalibrationTime);
|
||||
writer.Write(SerialNumber);
|
||||
writer.Write((byte)MeterSealed);
|
||||
writer.Write(CheckSum);
|
||||
}
|
||||
|
||||
public virtual void ReadBinary(BinaryReader reader)
|
||||
{
|
||||
Version = reader.ReadByte();
|
||||
MeterType = (MeterType)reader.ReadByte();
|
||||
Calibration = reader.ReadUInt16();
|
||||
VolumeUnits = (VolumeUnits)reader.ReadByte();
|
||||
FlowArrow = (FlowArrow)reader.ReadByte();
|
||||
FWVersion = reader.ReadUInt16();
|
||||
TargetField[0] = reader.ReadUInt16();
|
||||
TargetField[1] = reader.ReadUInt16();
|
||||
TargetField[2] = reader.ReadUInt16();
|
||||
RecipMeanCurrent = reader.ReadUInt16();
|
||||
ThresholdVolume = reader.ReadUInt16();
|
||||
ThresholdTime = reader.ReadUInt16();
|
||||
FlowActivationThr = reader.ReadUInt16();
|
||||
VolumeArrowThr = reader.ReadUInt16();
|
||||
CalibrationTime = reader.ReadUInt32();
|
||||
SerialNumber = reader.ReadUInt64();
|
||||
MeterSealed = (MeterSealed)reader.ReadByte();
|
||||
CheckSum = reader.ReadByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,261 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2018-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.comminication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
{
|
||||
public class CalibrationStructV4
|
||||
{
|
||||
public const int Length = 37;
|
||||
|
||||
public Byte Version;
|
||||
public MeterType MeterType;
|
||||
public UInt16 Calibration;
|
||||
public VolumeUnits VolumeUnits;
|
||||
public FlowArrow FlowArrow;
|
||||
public UInt16 FWVersion;
|
||||
public UInt16[] TargetField;
|
||||
public UInt16 RecipMeanCurrent;
|
||||
public UInt16 ThresholdVolume;
|
||||
public UInt16 ThresholdTime;
|
||||
public UInt16 FlowActivationThr;
|
||||
public UInt16 VolumeArrowThr;
|
||||
public UInt32 CalibrationTime;
|
||||
public ulong SerialNumber;
|
||||
public MeterSealed MeterSealed;
|
||||
public UInt16 CalibrationLNA;
|
||||
public byte CheckSum;
|
||||
|
||||
|
||||
public CalibrationStructV4()
|
||||
{
|
||||
TargetField = new UInt16[3];
|
||||
}
|
||||
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
byte[] result = new byte[Length];
|
||||
|
||||
result[0] = Version;
|
||||
result[1] = (byte)MeterType;
|
||||
|
||||
result[2] = (byte)(Calibration & 0x00FF);
|
||||
result[3] = (byte)((Calibration >> 8) & 0x00FF);
|
||||
|
||||
result[4] = (byte)VolumeUnits;
|
||||
|
||||
result[5] = (byte)FlowArrow;
|
||||
|
||||
result[6] = (byte)(FWVersion & 0x00FF);
|
||||
result[7] = (byte)((FWVersion >> 8) & 0x00FF);
|
||||
|
||||
result[8] = (byte)( TargetField[0] & 0x00FF);
|
||||
result[9] = (byte)((TargetField[0] >> 8) & 0x00FF);
|
||||
result[10] = (byte)( TargetField[1] & 0x00FF);
|
||||
result[11] = (byte)((TargetField[1] >> 8) & 0x00FF);
|
||||
result[12] = (byte)( TargetField[2] & 0x00FF);
|
||||
result[13] = (byte)((TargetField[2] >> 8) & 0x00FF);
|
||||
|
||||
result[14] = (byte)(RecipMeanCurrent & 0x00FF);
|
||||
result[15] = (byte)((RecipMeanCurrent >> 8) & 0x00FF);
|
||||
|
||||
result[16] = (byte)(ThresholdVolume & 0x00FF);
|
||||
result[17] = (byte)((ThresholdVolume >> 8) & 0x00FF);
|
||||
|
||||
result[18] = (byte)(ThresholdTime & 0x00FF);
|
||||
result[19] = (byte)((ThresholdTime >> 8) & 0x00FF);
|
||||
|
||||
result[20] = (byte)(FlowActivationThr & 0x00FF);
|
||||
result[21] = (byte)((FlowActivationThr >> 8) & 0x00FF);
|
||||
|
||||
result[22] = (byte)(VolumeArrowThr & 0x00FF);
|
||||
result[23] = (byte)((VolumeArrowThr >> 8) & 0x00FF);
|
||||
|
||||
result[24] = (byte)(CalibrationTime & 0x000000FF);
|
||||
result[25] = (byte)((CalibrationTime >> 8) & 0x000000FF);
|
||||
result[26] = (byte)((CalibrationTime >> 16) & 0x000000FF);
|
||||
result[27] = (byte)((CalibrationTime >> 24) & 0x000000FF);
|
||||
|
||||
result[28] = (byte)(SerialNumber & 0x00000000000000FF);
|
||||
result[29] = (byte)((SerialNumber >> 8) & 0x00000000000000FF);
|
||||
result[30] = (byte)((SerialNumber >> 16) & 0x00000000000000FF);
|
||||
result[31] = (byte)((SerialNumber >> 24) & 0x00000000000000FF);
|
||||
result[32] = (byte)((SerialNumber >> 32) & 0x00000000000000FF);
|
||||
|
||||
result[33] = (byte)MeterSealed;
|
||||
|
||||
result[34] = (byte)(CalibrationLNA & 0x00FF);
|
||||
result[35] = (byte)((CalibrationLNA >> 8) & 0x00FF);
|
||||
|
||||
result[36] = CheckSum;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a calibration structure from a complete byte array
|
||||
/// </summary>
|
||||
/// <param name="data">A complete byte array data</param>
|
||||
/// <returns>CalibrationStructV4 or null when byte array was not complete</returns>
|
||||
public static CalibrationStructV4 FromByteArray(byte[] data)
|
||||
{
|
||||
if (data.Length != Length) return null;
|
||||
|
||||
CalibrationStructV4 result = new CalibrationStructV4();
|
||||
|
||||
result.Version = data[0];
|
||||
result.MeterType = (MeterType)data[1];
|
||||
result.Calibration = (UInt16)(data[2] + 256 * data[3]);
|
||||
result.VolumeUnits = (VolumeUnits)data[4];
|
||||
result.FlowArrow = (FlowArrow)data[5];
|
||||
result.FWVersion = (UInt16)(data[6] + 256 * data[7]);
|
||||
result.TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
|
||||
result.TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
|
||||
result.TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
|
||||
result.RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
|
||||
result.ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
|
||||
result.ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
|
||||
result.FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
|
||||
result.VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
|
||||
result.CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
|
||||
result.SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
|
||||
result.MeterSealed = (MeterSealed)data[33];
|
||||
result.CalibrationLNA = (UInt16)(data[34] + 256 * data[35]);
|
||||
result.CheckSum = data[36];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the calibration structure from an incomplete byte array
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array data</param>
|
||||
/// <param name="offset">Offset of byte array data in CalibrationStructV2</param>
|
||||
/// <returns>true when successful, false when data are not appropriate</returns>
|
||||
public bool Update(byte[] data, int offset)
|
||||
{
|
||||
if ((data.Length == 2) && (offset == 2))
|
||||
{
|
||||
/// Data containing iPerl calibration factor
|
||||
Calibration = (UInt16)(data[0] + 256 * data[1]);
|
||||
return true;
|
||||
}
|
||||
else if ((data.Length == 2) && (offset == 34))
|
||||
{
|
||||
/// Data containing iPerl calibration factor
|
||||
CalibrationLNA = (UInt16)(data[0] + 256 * data[1]);
|
||||
return true;
|
||||
}
|
||||
else if ((data.Length == Length) && (offset == 0))
|
||||
{
|
||||
/// Data containing a complete CalibrationStruct
|
||||
Version = data[0];
|
||||
MeterType = (MeterType)data[1];
|
||||
Calibration = (UInt16)(data[2] + 256 * data[3]);
|
||||
VolumeUnits = (VolumeUnits)data[4];
|
||||
FlowArrow = (FlowArrow)data[5];
|
||||
FWVersion = (UInt16)(data[6] + 256 * data[7]);
|
||||
TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
|
||||
TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
|
||||
TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
|
||||
RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
|
||||
ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
|
||||
ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
|
||||
FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
|
||||
VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
|
||||
CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
|
||||
SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
|
||||
MeterSealed = (MeterSealed)data[33];
|
||||
CalibrationLNA = (UInt16)(data[34] + 256 * data[35]);
|
||||
CheckSum = data[36];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public string FWVersionStr()
|
||||
{
|
||||
int d1 = (FWVersion >> 8) & 0x000F;
|
||||
int d2 = (FWVersion >> 12) & 0x000F;
|
||||
int d3 = (FWVersion >> 4) & 0x000F;
|
||||
int d4 = FWVersion & 0x000F;
|
||||
return string.Format("{0}.{1}{2}{3}", d1, d2, d3, d4);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Calibration: V{0} Type={1} Cal={2} Units={3} FlowArrow.{4} FW={5} Hi={6} Norm={7} Low={8} RMC={9} ThrVol={10} ThrTime={11} FlActThr={12} VolArrThr={13} CalTm={14} SN={15} MeterSealed={16} CalLNA={17} Chksum={18}",
|
||||
Version,
|
||||
MeterType,
|
||||
Calibration,
|
||||
VolumeUnits,
|
||||
FlowArrow,
|
||||
FWVersion,
|
||||
TargetField[0],
|
||||
TargetField[1],
|
||||
TargetField[2],
|
||||
RecipMeanCurrent,
|
||||
ThresholdVolume,
|
||||
ThresholdTime,
|
||||
FlowActivationThr,
|
||||
VolumeArrowThr,
|
||||
CalibrationTime,
|
||||
SerialNumber,
|
||||
MeterSealed,
|
||||
CalibrationLNA,
|
||||
CheckSum.ToString("X2"));
|
||||
}
|
||||
|
||||
public virtual void WriteBinary(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(Version);
|
||||
writer.Write((byte)MeterType);
|
||||
writer.Write(Calibration);
|
||||
writer.Write((byte)VolumeUnits);
|
||||
writer.Write((byte)FlowArrow);
|
||||
writer.Write(FWVersion);
|
||||
writer.Write(TargetField[0]);
|
||||
writer.Write(TargetField[1]);
|
||||
writer.Write(TargetField[2]);
|
||||
writer.Write(RecipMeanCurrent);
|
||||
writer.Write(ThresholdVolume);
|
||||
writer.Write(ThresholdTime);
|
||||
writer.Write(FlowActivationThr);
|
||||
writer.Write(VolumeArrowThr);
|
||||
writer.Write(CalibrationTime);
|
||||
writer.Write(SerialNumber);
|
||||
writer.Write((byte)MeterSealed);
|
||||
writer.Write(CalibrationLNA);
|
||||
writer.Write(CheckSum);
|
||||
}
|
||||
|
||||
public virtual void ReadBinary(BinaryReader reader)
|
||||
{
|
||||
Version = reader.ReadByte();
|
||||
MeterType = (MeterType)reader.ReadByte();
|
||||
Calibration = reader.ReadUInt16();
|
||||
VolumeUnits = (VolumeUnits)reader.ReadByte();
|
||||
FlowArrow = (FlowArrow)reader.ReadByte();
|
||||
FWVersion = reader.ReadUInt16();
|
||||
TargetField[0] = reader.ReadUInt16();
|
||||
TargetField[1] = reader.ReadUInt16();
|
||||
TargetField[2] = reader.ReadUInt16();
|
||||
RecipMeanCurrent = reader.ReadUInt16();
|
||||
ThresholdVolume = reader.ReadUInt16();
|
||||
ThresholdTime = reader.ReadUInt16();
|
||||
FlowActivationThr = reader.ReadUInt16();
|
||||
VolumeArrowThr = reader.ReadUInt16();
|
||||
CalibrationTime = reader.ReadUInt32();
|
||||
SerialNumber = reader.ReadUInt64();
|
||||
MeterSealed = (MeterSealed)reader.ReadByte();
|
||||
CalibrationLNA = reader.ReadUInt16();
|
||||
CheckSum = reader.ReadByte();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,12 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
{
|
||||
public int ThreadId;
|
||||
public int WMNr0; /// 0-based water meter position
|
||||
public IPerlReader Ihead;
|
||||
public SmartReader Ihead;
|
||||
public Results.Entities.WaterMeter Wm;
|
||||
public string CommMessage;
|
||||
public CommErr CommErr;
|
||||
|
||||
public CommCompletedEventArgs(int threadId, int wmNr0, IPerlReader ihead, Results.Entities.WaterMeter wm, string commMessage, CommErr commErr)
|
||||
public CommCompletedEventArgs(int threadId, int wmNr0, SmartReader ihead, Results.Entities.WaterMeter wm, string commMessage, CommErr commErr)
|
||||
{
|
||||
this.ThreadId = threadId;
|
||||
this.WMNr0 = wmNr0;
|
||||
|
||||
@@ -1,269 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2020 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.comminication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
{
|
||||
public class ConfigStruct
|
||||
{
|
||||
public const int Length = 32;
|
||||
|
||||
public Byte Version; /// 0: 1 byte
|
||||
public MeterState MeterState; /// 1: 1 byte
|
||||
public UInt32 TargetTimeVeryLowBatt; /// 2: 4 bytes in seconds
|
||||
public UInt32 TargetTimeLowBatt; /// 6: 4 bytes, in seconds
|
||||
public UInt32 TestModeTime; /// 10: 4 bytes, Max. test mode time in seconds
|
||||
public UInt16 EmptyPipeThreshold; /// 14: 2 bytes
|
||||
public byte[] PCBNumber; /// 16: 5 bytes
|
||||
public byte TestModeConfig; /// 21: 1 byte
|
||||
public UInt32 RadioAddress; /// 22: 4 bytes
|
||||
public UInt16 TempCalibration; /// 26: 2 bytes
|
||||
public UInt16 AlarmMask; /// 28: 2 bytes, Default 0xA3F7
|
||||
public UInt16 ConfigCheckSum; /// 30: 2 bytes
|
||||
|
||||
public ConfigStruct()
|
||||
{
|
||||
PCBNumber = new byte[5];
|
||||
}
|
||||
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
byte[] result = new byte[Length];
|
||||
|
||||
result[0] = Version;
|
||||
result[1] = (byte)MeterState;
|
||||
|
||||
result[2] = (byte)(TargetTimeVeryLowBatt & 0x000000FF);
|
||||
result[3] = (byte)((TargetTimeVeryLowBatt >> 8) & 0x000000FF);
|
||||
result[4] = (byte)((TargetTimeVeryLowBatt >> 16) & 0x000000FF);
|
||||
result[5] = (byte)((TargetTimeVeryLowBatt >> 24) & 0x000000FF);
|
||||
|
||||
result[6] = (byte)(TargetTimeLowBatt & 0x000000FF);
|
||||
result[7] = (byte)((TargetTimeLowBatt >> 8) & 0x000000FF);
|
||||
result[8] = (byte)((TargetTimeLowBatt >> 16) & 0x000000FF);
|
||||
result[9] = (byte)((TargetTimeLowBatt >> 24) & 0x000000FF);
|
||||
|
||||
result[10] = (byte)(TestModeTime & 0x000000FF);
|
||||
result[11] = (byte)((TestModeTime >> 8) & 0x000000FF);
|
||||
result[12] = (byte)((TestModeTime >> 16) & 0x000000FF);
|
||||
result[13] = (byte)((TestModeTime >> 24) & 0x000000FF);
|
||||
|
||||
result[14] = (byte)(EmptyPipeThreshold & 0x00FF);
|
||||
result[15] = (byte)((EmptyPipeThreshold >> 8) & 0x00FF);
|
||||
|
||||
result[16] = PCBNumber[0];
|
||||
result[17] = PCBNumber[1];
|
||||
result[18] = PCBNumber[2];
|
||||
result[19] = PCBNumber[3];
|
||||
result[20] = PCBNumber[4];
|
||||
|
||||
result[21] = TestModeConfig;
|
||||
|
||||
result[22] = (byte)(RadioAddress & 0x000000FF);
|
||||
result[23] = (byte)((RadioAddress >> 8) & 0x000000FF);
|
||||
result[24] = (byte)((RadioAddress >> 16) & 0x000000FF);
|
||||
result[25] = (byte)((RadioAddress >> 24) & 0x000000FF);
|
||||
|
||||
result[26] = (byte)(TempCalibration & 0x00FF);
|
||||
result[27] = (byte)((TempCalibration >> 8) & 0x00FF);
|
||||
|
||||
result[28] = (byte)(AlarmMask & 0x00FF);
|
||||
result[29] = (byte)((AlarmMask >> 8) & 0x00FF);
|
||||
|
||||
result[30] = (byte)(ConfigCheckSum & 0x00FF);
|
||||
result[31] = (byte)((ConfigCheckSum >> 8) & 0x00FF);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a configuration structure from a complete byte array
|
||||
/// </summary>
|
||||
/// <param name="data">A complete byte array data</param>
|
||||
/// <returns>ConfigStruct or null when byte array was not complete</returns>
|
||||
public static ConfigStruct FromByteArray(byte[] data)
|
||||
{
|
||||
if (data.Length != Length) return null;
|
||||
|
||||
ConfigStruct result = new ConfigStruct();
|
||||
|
||||
result.Version = data[0];
|
||||
result.MeterState = (MeterState)data[1];
|
||||
result.TargetTimeVeryLowBatt = (((UInt32)data[5] * 256 + data[4]) * 256 + data[3]) * 256 + data[2];
|
||||
result.TargetTimeLowBatt = (((UInt32)data[9] * 256 + data[8]) * 256 + data[7]) * 256 + data[6];
|
||||
result.TestModeTime = (((UInt32)data[13] * 256 + data[12]) * 256 + data[11]) * 256 + data[10];
|
||||
result.EmptyPipeThreshold = (UInt16)(data[15] * 256 + data[14]);
|
||||
result.PCBNumber[0] = data[16];
|
||||
result.PCBNumber[1] = data[17];
|
||||
result.PCBNumber[2] = data[18];
|
||||
result.PCBNumber[3] = data[19];
|
||||
result.PCBNumber[4] = data[20];
|
||||
result.TestModeConfig = data[21];
|
||||
result.RadioAddress = (((UInt32)data[25] * 256 + data[24]) * 256 + data[23]) * 256 + data[22];
|
||||
result.TempCalibration = (UInt16)(data[27] * 256 + data[26]);
|
||||
result.AlarmMask = (UInt16)(data[29] * 256 + data[28]);
|
||||
result.ConfigCheckSum = (UInt16)(data[31] * 256 + data[30]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the configuration structure from an incomplete byte array
|
||||
/// </summary>
|
||||
/// <param name="offset">Offset of byte array data in ConfigStruct</param>
|
||||
/// <param name="data">Byte array data</param>
|
||||
/// <returns>true when successful, false when data are not appropriate</returns>
|
||||
public bool Update(int offset, byte[] data)
|
||||
{
|
||||
if (offset == 0 && data.Length == 2)
|
||||
{
|
||||
/// iPerl mode of function
|
||||
Version = data[0];
|
||||
MeterState = (MeterState)data[1];
|
||||
return true;
|
||||
}
|
||||
else if (offset == 0 && data.Length == 4)
|
||||
{
|
||||
/// iPerl mode of function and extra 2 bytes
|
||||
Version = data[0];
|
||||
MeterState = (MeterState)data[1];
|
||||
return true;
|
||||
}
|
||||
else if (offset == 21 && data.Length == 1)
|
||||
{
|
||||
/// TestModeConfig value
|
||||
TestModeConfig = data[21 - offset];
|
||||
return true;
|
||||
}
|
||||
else if (offset == 0 && data.Length == Length)
|
||||
{
|
||||
/// Complete ConfigStruct
|
||||
Version = data[0];
|
||||
MeterState = (MeterState)data[1];
|
||||
TargetTimeVeryLowBatt = (((UInt32)data[5] * 256 + data[4]) * 256 + data[3]) * 256 + data[2];
|
||||
TargetTimeLowBatt = (((UInt32)data[9] * 256 + data[8]) * 256 + data[7]) * 256 + data[6];
|
||||
TestModeTime = (((UInt32)data[13] * 256 + data[12]) * 256 + data[11]) * 256 + data[10];
|
||||
EmptyPipeThreshold = (UInt16)(data[15] * 256 + data[14]);
|
||||
PCBNumber[0] = data[16];
|
||||
PCBNumber[1] = data[17];
|
||||
PCBNumber[2] = data[18];
|
||||
PCBNumber[3] = data[19];
|
||||
PCBNumber[4] = data[20];
|
||||
TestModeConfig = data[21];
|
||||
RadioAddress = (((UInt32)data[25] * 256 + data[24]) * 256 + data[23]) * 256 + data[22];
|
||||
TempCalibration = (UInt16)(data[27] * 256 + data[26]);
|
||||
AlarmMask = (UInt16)(data[29] * 256 + data[28]);
|
||||
ConfigCheckSum = (UInt16)(data[31] * 256 + data[30]);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns PCB number string (12 characters, 12 decimal digits)
|
||||
/// </summary>
|
||||
/// <returns>PCB number STRING</returns>
|
||||
public string GetPcbNrString()
|
||||
{
|
||||
return PCBNumber2String(this.PCBNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts PCBNumber to string (12 characters, 12 decimal digits)
|
||||
/// </summary>
|
||||
/// <param name="pcbNumber"></param>
|
||||
/// <returns>PCB number string</returns>
|
||||
public static string PCBNumber2String(byte[] pcbNumber)
|
||||
{
|
||||
if (pcbNumber.Length != 5) return string.Empty;
|
||||
|
||||
Int64 number = 0;
|
||||
for (int i = 4; i >= 0; i--)
|
||||
{
|
||||
number = 256 * number + (Int64)pcbNumber[i];
|
||||
}
|
||||
|
||||
return number.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Config: V{0} State={1} VLoBattT={2}s LoBattT={3}s TestModeT={4}s EPThld={5} PCB#={6} TMCfg={7} RadioAddr={8} TempCalib={9} AlarmMask={10} CfgCheckSum={11}",
|
||||
Version,
|
||||
MeterState,
|
||||
TargetTimeVeryLowBatt,
|
||||
TargetTimeLowBatt,
|
||||
TestModeTime,
|
||||
EmptyPipeThreshold,
|
||||
GetPcbNrString(),
|
||||
TestModeConfig.ToString("X2"),
|
||||
RadioAddress,
|
||||
TempCalibration,
|
||||
AlarmMask.ToString("X4"),
|
||||
ConfigCheckSum.ToString("X4"));
|
||||
}
|
||||
|
||||
public string ToString(int sel)
|
||||
{
|
||||
return string.Format("{1} PCB#={6} TMCfg={7}",
|
||||
Version,
|
||||
MeterState,
|
||||
TargetTimeVeryLowBatt,
|
||||
TargetTimeLowBatt,
|
||||
TestModeTime,
|
||||
EmptyPipeThreshold,
|
||||
GetPcbNrString(),
|
||||
TestModeConfig.ToString("X2"),
|
||||
RadioAddress,
|
||||
TempCalibration,
|
||||
AlarmMask.ToString("X4"),
|
||||
ConfigCheckSum.ToString("X4"));
|
||||
}
|
||||
|
||||
public virtual void WriteBinary(BinaryWriter writer)
|
||||
{
|
||||
writer.Write(Version);
|
||||
writer.Write((byte)MeterState);
|
||||
writer.Write(TargetTimeVeryLowBatt);
|
||||
writer.Write(TargetTimeLowBatt);
|
||||
writer.Write(TestModeTime);
|
||||
writer.Write(EmptyPipeThreshold);
|
||||
writer.Write(PCBNumber[0]);
|
||||
writer.Write(PCBNumber[1]);
|
||||
writer.Write(PCBNumber[2]);
|
||||
writer.Write(PCBNumber[3]);
|
||||
writer.Write(PCBNumber[4]);
|
||||
writer.Write(TestModeConfig);
|
||||
writer.Write(RadioAddress);
|
||||
writer.Write(TempCalibration);
|
||||
writer.Write(AlarmMask);
|
||||
writer.Write(ConfigCheckSum);
|
||||
}
|
||||
|
||||
public virtual void ReadBinary(BinaryReader reader)
|
||||
{
|
||||
Version = reader.ReadByte();
|
||||
MeterState = (MeterState)reader.ReadByte();
|
||||
TargetTimeVeryLowBatt = reader.ReadUInt32();
|
||||
TargetTimeLowBatt = reader.ReadUInt32();
|
||||
TestModeTime = reader.ReadUInt32();
|
||||
EmptyPipeThreshold = reader.ReadUInt16();
|
||||
PCBNumber[0] = reader.ReadByte();
|
||||
PCBNumber[1] = reader.ReadByte();
|
||||
PCBNumber[2] = reader.ReadByte();
|
||||
PCBNumber[3] = reader.ReadByte();
|
||||
PCBNumber[4] = reader.ReadByte();
|
||||
TestModeConfig = reader.ReadByte();
|
||||
RadioAddress = reader.ReadUInt32();
|
||||
TempCalibration = reader.ReadUInt16();
|
||||
AlarmMask = reader.ReadUInt16();
|
||||
ConfigCheckSum = reader.ReadUInt16();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
{
|
||||
public enum ECommunicationInterface
|
||||
{
|
||||
[Description("..")] None,
|
||||
[Description("Nfc")] Nfc,
|
||||
[Description("cTouchRead")]Touched,
|
||||
}
|
||||
}
|
||||
@@ -1,315 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Sensus.iPerl.NfcHandler;
|
||||
using Sensus.iPerl.RfidCom.Exceptions;
|
||||
using static Sensus.iPerl.NfcHandler.MCI_Protocol;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
{
|
||||
internal class NfcServices
|
||||
{
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
internal static int ReadRequest(TestMethodCfg cfg, IPerlReader iperlHead, MCI_Protocol.StructName structName, int offset, int length, out byte[] buffer)
|
||||
{
|
||||
for (int i = 0; i < cfg.MaxCommRetries; i++)
|
||||
{
|
||||
|
||||
NfcDataHandler _nfcDataHandler = new NfcDataHandler();
|
||||
MessageEventHandlers(_nfcDataHandler);
|
||||
CR95HF_MessageEventHandlers(_nfcDataHandler._CR95HF_Reader);
|
||||
ST25DV_MessageEventHandlers(_nfcDataHandler._ST25DV_Device);
|
||||
MCI_MessageEventHandlers(_nfcDataHandler._MCI_Protocol);
|
||||
NFCHeadConfig_MessageEventHandlers(_nfcDataHandler._NFCHead_Config);
|
||||
try
|
||||
{
|
||||
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} ReadRequest : {structName}, {offset}, {length}");
|
||||
OpenConnection(_nfcDataHandler, cfg, iperlHead);
|
||||
|
||||
buffer = MciRead(_nfcDataHandler, cfg, structName, (ushort)offset, length);
|
||||
_nfcDataHandler.RFProtocolOFF(); // turn off rf antenna due to possible interference
|
||||
|
||||
CloseComPort(_nfcDataHandler);
|
||||
|
||||
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} ReadRequest : {structName}, {offset}, {length} ; Response= {ByteArrayToHexString(buffer)} ; Error: {_nfcDataHandler.LastErrorMessage}");
|
||||
|
||||
if (_nfcDataHandler.LastErrorCode != 0)
|
||||
{
|
||||
throw new RfidValidationException(_nfcDataHandler.LastErrorMessage);
|
||||
}
|
||||
|
||||
return Convert.ToInt32(_nfcDataHandler.LastErrorCode); //return 0;
|
||||
}
|
||||
catch (RfidValidationException)
|
||||
{
|
||||
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} ReadRequest Error: {ex.Message}");
|
||||
buffer = new byte[length];
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
buffer = new byte[length];
|
||||
return 3;
|
||||
}
|
||||
|
||||
internal static int WriteRequest(TestMethodCfg cfg, IPerlReader iperlHead, MCI_Protocol.StructName structName, int offset, int length, byte[] buffer)
|
||||
{
|
||||
NfcDataHandler _nfcDataHandler = new NfcDataHandler();
|
||||
MessageEventHandlers(_nfcDataHandler);
|
||||
CR95HF_MessageEventHandlers(_nfcDataHandler._CR95HF_Reader);
|
||||
ST25DV_MessageEventHandlers(_nfcDataHandler._ST25DV_Device);
|
||||
MCI_MessageEventHandlers(_nfcDataHandler._MCI_Protocol);
|
||||
NFCHeadConfig_MessageEventHandlers(_nfcDataHandler._NFCHead_Config);
|
||||
try
|
||||
{
|
||||
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} WriteRequest : {structName}, {offset}, {length}, {ByteArrayToHexString(buffer)}");
|
||||
OpenConnection(_nfcDataHandler, cfg, iperlHead);
|
||||
|
||||
MciWrite(_nfcDataHandler, cfg, structName, (ushort)offset, length, buffer);
|
||||
_nfcDataHandler.RFProtocolOFF(); // turn off rf antenna due to possible interference
|
||||
|
||||
CloseComPort(_nfcDataHandler);
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} WriteRequest Error: {ex.Message}");
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
private static void OpenConnection(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, IPerlReader iperlHead)
|
||||
{
|
||||
string comPort = $"COM{iperlHead.RfidComPortNr}";
|
||||
int retryCount = 0 ;
|
||||
Open:
|
||||
nfcDataHandler.Close();
|
||||
Thread.Sleep(100);
|
||||
if (nfcDataHandler.OpenConnection(comPort, cfg.BaudRate, cfg.DataBits, cfg.ParityBit, cfg.StopBits))
|
||||
{
|
||||
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} Port Open");
|
||||
|
||||
if (nfcDataHandler.ConnectReader())
|
||||
{
|
||||
rfidDataLogger.Info($"NFC COM{iperlHead.RfidComPortNr} Reader connected");
|
||||
if (!nfcDataHandler.ConnectDevice())
|
||||
{
|
||||
rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} Error connect device.");
|
||||
for (int i = 0; i < cfg.MaxCommRetries; i++)
|
||||
{
|
||||
if (nfcDataHandler.Echo()) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
retryCount++;
|
||||
rfidDataLogger.Error($"NFC COM{iperlHead.RfidComPortNr} Error connect reader. Reconnect comport {retryCount}");
|
||||
if (retryCount < cfg.MaxCommRetries)
|
||||
{
|
||||
nfcDataHandler.Close();
|
||||
iperlHead.ResetNfcInterface(); // reset NFC head via optoport - switch to RFID and back to NFC interface
|
||||
goto Open;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
rfidDataLogger.Error($"Open NFC COM{iperlHead.RfidComPortNr} Port Failed");
|
||||
}
|
||||
|
||||
private static void CloseComPort(NfcDataHandler nfcDataHandler)
|
||||
{
|
||||
nfcDataHandler.Close();
|
||||
}
|
||||
|
||||
private static byte[] MciRead(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, StructName structName, ushort offset, int length)
|
||||
{
|
||||
bool isReadValues = false;
|
||||
int retryCount = 0;
|
||||
Read:
|
||||
try
|
||||
{
|
||||
isReadValues = false;
|
||||
long num1 = (long)length;
|
||||
int timeoutMs = 4000;
|
||||
byte payloadlength = Convert.ToByte(num1.ToString("X2"), 16);
|
||||
if (nfcDataHandler.MCI_Read(structName, offset, payloadlength, timeoutMs))
|
||||
{
|
||||
byte[] lastData = nfcDataHandler.LastData;
|
||||
if ((long)lastData.Length >= num1)
|
||||
{
|
||||
rfidDataLogger.Info($"COM: MciRead ({structName},{offset},{length}) = {ByteArrayToHexString(lastData)}");
|
||||
return lastData;
|
||||
}
|
||||
else
|
||||
rfidDataLogger.Info($"COM: MciRead ({structName},{offset},{length}) = {ByteArrayToHexString(lastData)}");
|
||||
}
|
||||
else if (nfcDataHandler.LastErrorCode == (byte)0)
|
||||
{
|
||||
rfidDataLogger.Info($"MCI Error: Unidentified");
|
||||
retryCount++;
|
||||
if (retryCount < cfg.MaxCommRetries)
|
||||
goto Read;
|
||||
}
|
||||
else
|
||||
{
|
||||
rfidDataLogger.Info("Last error message: " + nfcDataHandler.LastErrorMessage);
|
||||
retryCount++;
|
||||
if (retryCount < cfg.MaxCommRetries)
|
||||
goto Read;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
rfidDataLogger.Error("MciRead Last error message: " + ex.Message);
|
||||
retryCount++;
|
||||
if (retryCount < cfg.MaxCommRetries)
|
||||
goto Read;
|
||||
}
|
||||
return new byte[length];
|
||||
}
|
||||
|
||||
private static void MciWrite(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, MCI_Protocol.StructName structName, ushort offset, int length, byte[] payload)
|
||||
{
|
||||
int retryCount = 0;
|
||||
Write:
|
||||
try
|
||||
{
|
||||
long num1 = (long)length;
|
||||
int timeoutMs = 4000;
|
||||
byte payloadlength = Convert.ToByte(num1);
|
||||
if ((int)payloadlength != payload.Length)
|
||||
rfidDataLogger.Error("Insufficient Payload -- Payload lenth : " + (object)payload.Length);
|
||||
else if (nfcDataHandler.MCI_Write(structName, offset, payloadlength, payload, timeoutMs))
|
||||
{
|
||||
// OK
|
||||
}
|
||||
else if (nfcDataHandler.LastErrorCode > (byte)0)
|
||||
{
|
||||
rfidDataLogger.Error("Last error message: " + nfcDataHandler.LastErrorMessage);
|
||||
//int num2 = (int)MessageBox.Show(this._nfcDataHandler.LastErrorMessage);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
rfidDataLogger.Error("MciWrite error message: " + ex.Message);
|
||||
retryCount++;
|
||||
if (retryCount < cfg.MaxCommRetries)
|
||||
goto Write;
|
||||
}
|
||||
}
|
||||
|
||||
private static void MciWriteCommand(NfcDataHandler nfcDataHandler, byte commandcode)
|
||||
{
|
||||
try
|
||||
{
|
||||
ushort offset = 0;
|
||||
int timeoutMs = 4000;
|
||||
byte payloadlength = 1;
|
||||
byte[] payload = new byte[1] { commandcode };
|
||||
if (nfcDataHandler.MCI_Write(MCI_Protocol.StructName.Command, offset, payloadlength, payload, timeoutMs) || nfcDataHandler.LastErrorCode <= (byte)0)
|
||||
return;
|
||||
rfidDataLogger.Error("MciWriteCommand Last error message: " + nfcDataHandler.LastErrorMessage);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
rfidDataLogger.Error("MciWriteCommand Last error message: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static string ByteArrayToHexString(byte[] data)
|
||||
{
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
foreach (byte num in data)
|
||||
stringBuilder.Append(num.ToString("X2"));
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
private static byte[] BuildPayLoad(string strPayLoad, int length)
|
||||
{
|
||||
byte[] collection;
|
||||
|
||||
if (strPayLoad.Split(':').Length > 1)
|
||||
{
|
||||
uint timestamp = ConvertDateTimeToTimestamp(Convert.ToDateTime(DateTime.ParseExact(strPayLoad, "HH:mm:ss dd/MM/yyyy", (IFormatProvider)CultureInfo.InvariantCulture)));
|
||||
byte[] bytes = BitConverter.GetBytes(timestamp);
|
||||
return bytes;
|
||||
}
|
||||
else if (strPayLoad.Split(',').Length > 1)
|
||||
{
|
||||
string[] strArray = strPayLoad.Split(',');
|
||||
collection = new byte[strArray.Length];
|
||||
for (int index3 = 0; index3 < strArray.Length; ++index3)
|
||||
collection[index3] = Convert.ToByte(strArray[index3], 16);
|
||||
return collection;
|
||||
}
|
||||
else
|
||||
{
|
||||
//int num = strPayLoad.Split(',').Length;
|
||||
collection = HexStringToByteArray(strPayLoad.Substring(strPayLoad.Length - length * 2).ToUpper());
|
||||
Array.Reverse((Array)collection);
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] HexStringToByteArray(string hexString)
|
||||
{
|
||||
int length = hexString.Length;
|
||||
byte[] byteArray = new byte[length / 2];
|
||||
for (int startIndex = 0; startIndex < length; startIndex += 2)
|
||||
byteArray[startIndex / 2] = Convert.ToByte(hexString.Substring(startIndex, 2), 16);
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
private static uint ConvertDateTimeToTimestamp(DateTime datetime)
|
||||
{
|
||||
TimeSpan utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(DateTime.Now);
|
||||
return (uint)((datetime - new DateTime(2000, 1, 1, 0, 0, 0).ToLocalTime()).TotalSeconds + utcOffset.TotalSeconds);
|
||||
}
|
||||
|
||||
#region EventHandlers
|
||||
public static void MCI_MessageEventHandlers(MCI_Protocol e)
|
||||
{
|
||||
DelNfc_MCI_MessageHandler mciMessageHandler = new DelNfc_MCI_MessageHandler(OnHandler);
|
||||
e.MessageEvent += mciMessageHandler;
|
||||
}
|
||||
|
||||
public static void ST25DV_MessageEventHandlers(ST25DV_Device e)
|
||||
{
|
||||
DelNfc_ST25DV_MessageHandler dvMessageHandler = new DelNfc_ST25DV_MessageHandler(OnHandler);
|
||||
e.MessageEvent += dvMessageHandler;
|
||||
}
|
||||
|
||||
public static void CR95HF_MessageEventHandlers(CR95HF_Reader e)
|
||||
{
|
||||
DelNfc_CR95HF_MessageHandler hfMessageHandler = new DelNfc_CR95HF_MessageHandler(OnHandler);
|
||||
e.MessageEvent += hfMessageHandler;
|
||||
}
|
||||
|
||||
public static void NFCHeadConfig_MessageEventHandlers(NFCHeadConfig e)
|
||||
{
|
||||
DelNfc_NFCHeadConfig_MessageHandler configMessageHandler = new DelNfc_NFCHeadConfig_MessageHandler(OnHandler);
|
||||
e.MessageEvent += configMessageHandler;
|
||||
}
|
||||
|
||||
public static void MessageEventHandlers(NfcDataHandler e)
|
||||
{
|
||||
DelNfcMessageHandler nfcMessageHandler = new DelNfcMessageHandler(OnHandler);
|
||||
e.MessageEvent += nfcMessageHandler;
|
||||
}
|
||||
|
||||
public static void OnHandler(object sender, NfcMessageEventArgs e)
|
||||
{
|
||||
if (e.Message == null)
|
||||
return;
|
||||
string message = e.Message.Replace("\n", " ").Replace("\r", "");
|
||||
rfidDataLogger.Debug(message);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,15 @@
|
||||
using System;
|
||||
using Common;
|
||||
using Config.Resources;
|
||||
using log4net;
|
||||
using Sensus.iPerl.RfidCom.Helper;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations;
|
||||
using static Sensus.iPerl.NfcHandler.MCI_Protocol;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
@@ -11,50 +17,89 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
internal class OpticalHeadTest
|
||||
{
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
|
||||
DebugMode _debugMode;
|
||||
public DebugMode DebugMode { get => _debugMode; set => _debugMode = value; }
|
||||
|
||||
internal static string OpenSealing(IPerlReader iHead)
|
||||
internal static string OpenSealing(ISmartReader iHead)
|
||||
{
|
||||
if (RfidCommands.OpenSealing($"COM{iHead.RfidComPortNr}")) return "OK";
|
||||
return "Error Open Sealing";
|
||||
}
|
||||
|
||||
internal static string ReadRequest_PCB(IPerlReader iHead)
|
||||
internal static string ReadRequest_SerialNo(PoseidonCfg iHeadCfg)
|
||||
{
|
||||
if (iHeadCfg != null && iHeadCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return "1111";
|
||||
}
|
||||
|
||||
string serialNo = null;
|
||||
try
|
||||
{
|
||||
byte[] pcb = null;
|
||||
int readRetVal = IPerlCorrections.ReadRequestPort(SmartCommunicationForm.TestMethodCfg, iHead, CommonRR.MessageID.Configuration, Sensus.iPerl.NfcHandler.MCI_Protocol.StructName.Configuration, 16, 5, out pcb);
|
||||
if (readRetVal == 0)
|
||||
if (iHeadCfg != null)
|
||||
{
|
||||
return RfidHelper.HexLiteral2Unsigned(RfidHelper.SwapHexcode(BitConverter.ToString(pcb).Replace("-", string.Empty))).ToString();
|
||||
// TODO BUMI set correct val !!!!!!!!
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
$"COM{iHeadCfg.HeadCommunicationComPortNr}",
|
||||
iHeadCfg.CliProgramName,
|
||||
iHeadCfg.CliMeterType);
|
||||
NfcHeadServiceOld headService = new NfcHeadServiceOld(serialPortData);
|
||||
serialNo = headService.GetSerialNr();
|
||||
}
|
||||
rfidDataLogger.Error($"COM{iHead.RfidComPortNr}: ReadRequest_PCB ({CommonRR.MessageID.Configuration},16,5...) <- Error: {readRetVal}");
|
||||
return "Error";
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (ex.Message.ToString());
|
||||
}
|
||||
|
||||
|
||||
return serialNo;
|
||||
}
|
||||
|
||||
internal static string ReadRequest_SerialNoAsynch(PoseidonCfg iHeadCfg)
|
||||
{
|
||||
string serialNo = null;
|
||||
try
|
||||
{
|
||||
if (iHeadCfg != null)
|
||||
{
|
||||
// TODO BUMI set correct val !!!!!!!!
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
$"COM{iHeadCfg.HeadCommunicationComPortNr}",
|
||||
iHeadCfg.CliProgramName,
|
||||
iHeadCfg.CliMeterType);
|
||||
NfcHeadService headService = new NfcHeadService(serialPortData);
|
||||
// Wait synchronously
|
||||
serialNo = headService.GetSerialNrAsync().GetAwaiter().GetResult();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (ex.Message.ToString());
|
||||
}
|
||||
|
||||
|
||||
return serialNo;
|
||||
}
|
||||
|
||||
internal static string SetActiveMode(IPerlReader iHead)
|
||||
internal static string SetActiveMode(PoseidonCfg iHeadCfg)
|
||||
{
|
||||
byte[] cmd = new byte[1] { (byte)CommonRR.Command.SetActiveMode };
|
||||
if (0 == IPerlCorrections.WriteRequestPort(SmartCommunicationForm.TestMethodCfg, iHead, CommonRR.MessageID.Command, StructName.Command, 0, 1, cmd))
|
||||
if (iHeadCfg != null && iHeadCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return "OK";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Error Set Active Mode";
|
||||
}
|
||||
}
|
||||
|
||||
internal static string SetTestMode(IPerlReader iHead)
|
||||
{
|
||||
byte[] cmd = new byte[1] { (byte)CommonRR.Command.SetTestMode };
|
||||
if (0 == IPerlCorrections.WriteRequestPort(SmartCommunicationForm.TestMethodCfg, iHead, CommonRR.MessageID.Command, StructName.Command, 0, 1, cmd))
|
||||
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
$"COM{iHeadCfg.RfidComPortNr}",
|
||||
iHeadCfg.CliProgramName,
|
||||
iHeadCfg.CliMeterType);
|
||||
NfcHeadServiceOld headService = new NfcHeadServiceOld(serialPortData);
|
||||
// Wait synchronously
|
||||
OptoHeadStatus optoHeadStatus = headService.SetTestingMode(OptoHeadStatus.OptoHeadDisabled);
|
||||
if (optoHeadStatus == OptoHeadStatus.OptoHeadDisabled)
|
||||
{
|
||||
_lastOptoHeadStatus = optoHeadStatus;
|
||||
return "OK";
|
||||
}
|
||||
else
|
||||
@@ -63,8 +108,91 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
}
|
||||
}
|
||||
|
||||
private static OptoHeadStatus _lastOptoHeadStatus = OptoHeadStatus.Unknown;
|
||||
private static PoseidonCfg _lastIHeadCfg;
|
||||
|
||||
internal static string SetTestMode(PoseidonCfg iHeadCfg)
|
||||
{
|
||||
if (iHeadCfg != null && iHeadCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return "OK";
|
||||
}
|
||||
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
$"COM{iHeadCfg.RfidComPortNr}",
|
||||
iHeadCfg.CliProgramName,
|
||||
iHeadCfg.CliMeterType);
|
||||
NfcHeadServiceOld headService = new NfcHeadServiceOld(serialPortData);
|
||||
// Wait synchronously
|
||||
OptoHeadStatus optoHeadStatus = headService.SetTestingMode(OptoHeadStatus.OptoHeadC7);
|
||||
if (optoHeadStatus == OptoHeadStatus.OptoHeadC7)
|
||||
{
|
||||
_lastOptoHeadStatus = optoHeadStatus;
|
||||
_lastIHeadCfg = iHeadCfg;
|
||||
return "OK";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Error Set Test Mode";
|
||||
}
|
||||
}
|
||||
|
||||
private static OptoHeadService optoHeadService;
|
||||
|
||||
public static void Deactivate()
|
||||
{
|
||||
if (_lastIHeadCfg != null && _lastIHeadCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return;
|
||||
}
|
||||
StopOptoTestInputLoop();
|
||||
if (_lastOptoHeadStatus != OptoHeadStatus.Unknown &&
|
||||
_lastOptoHeadStatus != OptoHeadStatus.OptoHeadDisabled &&
|
||||
_lastIHeadCfg != null
|
||||
)
|
||||
{
|
||||
SetActiveMode(_lastIHeadCfg);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool StartOptotestInputLoop(PoseidonCfg iHeadCfg,
|
||||
EventHandler<CommonRR.IPerl.communication.OptoReceivedEventArgs> onOptoReceivedHandler)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (iHeadCfg != null)
|
||||
{
|
||||
if (optoHeadService != null) return false;
|
||||
|
||||
OptoHeadService.Con connection = new OptoHeadService.Con($"COM{iHeadCfg.OptoComPortNr}", iHeadCfg.DebugLevel);
|
||||
optoHeadService = new OptoHeadService(connection);
|
||||
optoHeadService.CreateSerialConnection();
|
||||
optoHeadService.RunLoop(onOptoReceivedHandler);
|
||||
//run loop runstate = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw ex;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void StopOptoTestInputLoop()
|
||||
{
|
||||
try
|
||||
{
|
||||
optoHeadService?.CloseSerialConnection();
|
||||
}
|
||||
finally
|
||||
{
|
||||
optoHeadService = null;
|
||||
}
|
||||
}
|
||||
|
||||
#if IPERL
|
||||
internal static string TurnOffRadio(IPerlReader iHead)
|
||||
internal static string TurnOffRadio(ISmartReader iHead)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -77,7 +205,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
}
|
||||
}
|
||||
|
||||
internal static string SetProductionMode(IPerlReader iHead)
|
||||
internal static string SetProductionMode(ISmartReader iHead)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -90,7 +218,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
}
|
||||
}
|
||||
|
||||
internal static string WriteRequestPort_u8_Customer_Text(IPerlReader iHead)
|
||||
internal static string WriteRequestPort_u8_Customer_Text(ISmartReader iHead)
|
||||
{
|
||||
string custText = "FF0123456789ABCDEF"; // Sample text to test write function
|
||||
/*try
|
||||
@@ -110,17 +238,17 @@ namespace TBF.Rig.RegisterReaders.PoseidonReader.communication
|
||||
return $"Error COM{iHead.RfidComPortNr}";
|
||||
}
|
||||
|
||||
internal static string SetRfidMode(IPerlReader iHead)
|
||||
internal static string SetTouchedMode(ISmartReader iHead)
|
||||
{
|
||||
iHead.SetRfidInterface();
|
||||
iHead.SetCommunicationInterface(CommunicationInterface.RFID);
|
||||
iHead.SetCommunicationInterface(ECommunicationInterface.Touched.ToDescription());
|
||||
return ($"OK - {Strings.Program_restart_is_required_to_apply_some_settings}");
|
||||
}
|
||||
|
||||
internal static string SetNfcMode(IPerlReader iHead)
|
||||
internal static string SetNfcMode(ISmartReader iHead)
|
||||
{
|
||||
iHead.SetNfcInterface();
|
||||
iHead.SetCommunicationInterface(CommunicationInterface.NFC);
|
||||
iHead.SetCommunicationInterface(ECommunicationInterface.Nfc.ToDescription());
|
||||
return ($"OK - {Strings.Program_restart_is_required_to_apply_some_settings}");
|
||||
}
|
||||
#endif /// IPERL
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Sensus.iPerl.RfidCom;
|
||||
using Sensus.iPerl.RfidCom.Exceptions;
|
||||
using Sensus.iPerl.RfidCom.Helper;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.comminication
|
||||
{
|
||||
internal class RfidServices
|
||||
{
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(SmartCommunicationForm));
|
||||
|
||||
internal static int ReadRequest(TestMethodCfg cfg, IPerlReader iperlHead, MessageID messageID, int offset, int length, out byte[] buffer)
|
||||
{
|
||||
for (int i = 0; i < cfg.MaxCommRetries; i++)
|
||||
{
|
||||
rfidDataLogger.Error($"{iperlHead.CommInterface} Start {i} reading: COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},{offset}, {length}... timeout {cfg.CommTimeout})");
|
||||
using (RfidLogic writer = new RfidLogic($"COM{iperlHead.RfidComPortNr}"))
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] response = writer.ReadRequest((byte)messageID, offset, length, cfg.CommTimeout);
|
||||
string hexString = RfidHelper.ConvertByteArrayToHexString(response);
|
||||
string swapHexString = RfidHelper.SwapHexcode(hexString);
|
||||
string decString = RfidHelper.HexLiteral2Unsigned(RfidHelper.SwapHexcode(hexString)).ToString();
|
||||
|
||||
if (length > 10)
|
||||
{
|
||||
//if the result only contains "00"s we are working on the wrong COM port
|
||||
// or the module just isn't connected
|
||||
if (Regex.IsMatch(hexString, @"^(00)\1+$"))
|
||||
{
|
||||
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) <- Error: No RFID signal.");
|
||||
throw new RfidValidationException("Error_Rfid_NoSignal");
|
||||
}
|
||||
|
||||
//if the result only contains "03"s the meter did not answer.
|
||||
// Might be due to the module being positioned incorrectly.
|
||||
if (Regex.IsMatch(hexString, @"^(03)\1+$"))
|
||||
{
|
||||
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) <- Error: No meter signal.");
|
||||
throw new RfidValidationException("Error_Rfid_NoAnswerFromMeter");
|
||||
}
|
||||
}
|
||||
|
||||
writer.ClosePort();
|
||||
buffer = response;
|
||||
rfidDataLogger.Info($"{iperlHead.Name} ({iperlHead.SerialNr}): ReadRequestPort(COM{iperlHead.RfidComPortNr},...) returned HEX: {hexString}; SwapHexCodeToDecimal: {decString}");
|
||||
return 0;
|
||||
}
|
||||
catch (RfidDataNotAvailableException)
|
||||
{
|
||||
if (/*RfidHelper.IsPassThrough(messageID)*/ messageID == MessageID.ASICRegisterReadTest || messageID == MessageID.RadioPassthrough)
|
||||
{
|
||||
rfidDataLogger.Info($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) {(i > 0 ? "<- Error: Invalid Pass-Through data." : "<- Info: Wait for Pass-Through data.")}");
|
||||
Thread.Sleep(cfg.PassThroughWaitTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||
}
|
||||
}
|
||||
catch (RfidValidationException)
|
||||
{
|
||||
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...) {ex.Message}");
|
||||
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||
}
|
||||
}
|
||||
}
|
||||
rfidDataLogger.Error($"{iperlHead.CommInterface} reading failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...)");
|
||||
log.Error($"{iperlHead.CommInterface} reading failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: ReadRequestPort ({messageID},...)");
|
||||
buffer = new byte[length];
|
||||
return 3;
|
||||
}
|
||||
|
||||
internal static int WriteRequest(TestMethodCfg cfg, IPerlReader iperlHead, MessageID messageID, int offset, int length, byte[] buffer)
|
||||
{
|
||||
RfidLogic writer = new RfidLogic($"COM{iperlHead.RfidComPortNr}");
|
||||
string payload = RfidHelper.ConvertByteArrayToHexString(buffer);
|
||||
|
||||
for (var i = 0; i < cfg.MaxCommRetries; i++)
|
||||
{
|
||||
rfidDataLogger.Error($"{iperlHead.CommInterface} Start {i} writting: COM{iperlHead.RfidComPortNr}: WriteRequest ({messageID},{offset}, {length}, {payload}... timeout {cfg.CommTimeout})");
|
||||
try
|
||||
{
|
||||
if (writer.ClosePort()) writer.OpenPort();
|
||||
writer.WriteRequest((byte)messageID, offset, length, buffer, cfg.CommTimeout, false);
|
||||
writer.ClosePort();
|
||||
rfidDataLogger.InfoFormat($"{iperlHead.Name}({iperlHead.SerialNr},COM{iperlHead.RfidComPortNr}): WriteRequestPort({messageID}, {offset}, {length}, {payload})");
|
||||
return 0;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (messageID == MessageID.RadioPassthrough || messageID == MessageID.ASICRegisterReadTest)
|
||||
{
|
||||
Thread.Sleep(1500);
|
||||
}
|
||||
else
|
||||
{
|
||||
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: Error: {ex.Message}");
|
||||
Thread.Sleep(cfg.WaitTimeAfterFailure);
|
||||
if (i > 1)
|
||||
{
|
||||
rfidDataLogger.Error($"COM{iperlHead.RfidComPortNr}: Reopen the com port.");
|
||||
writer.ClosePort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.ClosePort();
|
||||
rfidDataLogger.Error($"RFID writing failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: WriteRequestPort ({messageID},...) {System.Text.Encoding.UTF8.GetString(buffer)}");
|
||||
log.Error($"RFID writing failed after {cfg.MaxCommRetries} retries: COM{iperlHead.RfidComPortNr}: WriteRequestPort ({messageID},...) {System.Text.Encoding.UTF8.GetString(buffer)}");
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl.communication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.comminication
|
||||
{
|
||||
internal class SimulationServices
|
||||
{
|
||||
const int Q2CorrFactorsAddr = iPerlCommunicationConstants.Q2CorrFactorsAddr;
|
||||
|
||||
internal static int ReadRequest(IPerlReader iperlHead, MessageID messageID, int offset, int length, out byte[] buffer)
|
||||
{
|
||||
byte[] configurationBuffer = new byte[ConfigStruct.Length] { 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
byte[] calibrationBuffer = new byte[CalibrationStructV4.Length] { 3, 0, 150, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 0, 0, 150, 10 };
|
||||
buffer = new byte[length];
|
||||
|
||||
if (messageID == MessageID.Configuration)
|
||||
{
|
||||
Array.Copy(GetPCB(iperlHead), 0, configurationBuffer, 16, 5); // set PCB Number according to iPerlHead configuration
|
||||
Array.Copy(configurationBuffer,offset,buffer,0,length);
|
||||
}
|
||||
else if (messageID == MessageID.Calibration)
|
||||
{
|
||||
Array.Copy(calibrationBuffer, offset, buffer, 0, length);
|
||||
}
|
||||
else if ((messageID == MessageID.MetrologyMemory) && (offset == Q2CorrFactorsAddr) && (length == 2))
|
||||
{
|
||||
buffer = new byte[2] { 0, 0 };
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = new byte[length];
|
||||
}
|
||||
|
||||
return iperlHead.Name.Equals("iPerl13") ? 2 : 0; /// Simulates an error on position 13
|
||||
}
|
||||
|
||||
internal static int WriteRequest(TestMethodCfg cfg, IPerlReader iperlHead, MessageID messageID, int offset,
|
||||
int length, byte[] buffer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Array GetPCB(IPerlReader iperlHead)
|
||||
{
|
||||
string pcbStr = iperlHead.RfidComPortNr.ToString().PadRight(10,'0') + iperlHead.Position.ToString("D2");
|
||||
long decVal = Convert.ToInt64(pcbStr);
|
||||
string nHexStr = decVal.ToString("X4");
|
||||
|
||||
string hexStr = "";
|
||||
for (int a = nHexStr.Length; a >= 1; a = a - 2)
|
||||
{
|
||||
hexStr = hexStr + nHexStr.Substring(a - 2, 2);
|
||||
}
|
||||
|
||||
return Enumerable.Range(0, hexStr.Length)
|
||||
.Where(x => x % 2 == 0)
|
||||
.Select(x => Convert.ToByte(hexStr.Substring(x, 2), 16))
|
||||
.ToArray();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
using OptoReceivedEventArgs = TBF.Rig.RegisterReaders.CommonRR.IPerl.communication.OptoReceivedEventArgs;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.implementations
|
||||
{
|
||||
public class PoseidonImplHeadTestCtrl : IUniHeadTestCtrl
|
||||
{
|
||||
// ----------MEMBER VARIABLES--------------
|
||||
Thread optoThread;
|
||||
|
||||
|
||||
public enum Operations
|
||||
{
|
||||
[Description("ReadSerialNo")]ReadSerialNo,
|
||||
[Description("SetTestModeON")]SetTestModeOn,
|
||||
[Description("SetTestModeOFF")]SetTestModeOff,
|
||||
[Description("")]Empty
|
||||
}
|
||||
|
||||
public static readonly Dictionary<string, Operations> ItemsOperations = new Dictionary<string, Operations>
|
||||
{
|
||||
{"Read Serial No", Operations.ReadSerialNo},
|
||||
{"Set Test Mode ON", Operations.SetTestModeOn},
|
||||
{"Set Test Mode OFF", Operations.SetTestModeOff},
|
||||
{"", Operations.Empty}
|
||||
};
|
||||
|
||||
// ----------IMPLEMENTATION INTERFACE--------------
|
||||
public IComponentCfg config { get; set; }
|
||||
public ISmartReader ISmartReader { get; set; }
|
||||
public bool stopWorkerThread { get; set; }
|
||||
public event EventHandler<OptoReceivedEventArgs> OptoReceivedHandler;
|
||||
public void Initialize()
|
||||
{
|
||||
stopWorkerThread = false;
|
||||
}
|
||||
|
||||
public void Destroy()
|
||||
{
|
||||
stopWorkerThread = true;
|
||||
if (optoThread != null)
|
||||
{
|
||||
optoThread.Abort();
|
||||
}
|
||||
|
||||
OpticalHeadTest.StopOptoTestInputLoop(); // close opto port
|
||||
if (this.config is PoseidonCfg poseidonCfg)
|
||||
{
|
||||
OpticalHeadTest.SetActiveMode(poseidonCfg);
|
||||
}
|
||||
}
|
||||
|
||||
public (string Name, string Value)[] GetComboOperationsPairs()
|
||||
{
|
||||
//return ItemsForIperlOperations.Select(kvp => (kvp.Key, kvp.Value)).ToArray();
|
||||
return ItemsOperations.Select(kvp => (kvp.Key, kvp.Value.ToDescription())).ToArray();
|
||||
}
|
||||
|
||||
public void CommandTestButtonClick(object sender, MouseEventArgs e, Arguments a)
|
||||
{
|
||||
a.RfidOutputListBox.Items.Clear();
|
||||
|
||||
using (Tools.LogChecker logChecker = new Tools.LogChecker("RfidData", log4net.Core.Level.Debug))
|
||||
{
|
||||
ListItem rfidListItem = new ListItem();
|
||||
rfidListItem.Attributes.Add("style", "font-weight:bold");
|
||||
Operations selectedOperation;
|
||||
if(!ItemsOperations.TryGetValue((string)a.RfidCommandComboBox.SelectedValue, out selectedOperation))
|
||||
selectedOperation = Operations.Empty;
|
||||
if (this.config is PoseidonCfg poseidonCfg)
|
||||
{
|
||||
switch (selectedOperation)
|
||||
{
|
||||
case Operations.ReadSerialNo:
|
||||
rfidListItem.Text = $"ReadSerialNo: {OpticalHeadTest.ReadRequest_SerialNo(poseidonCfg)}";
|
||||
break;
|
||||
case Operations.SetTestModeOn:
|
||||
rfidListItem.Text = $"SetTestMode: {OpticalHeadTest.SetTestMode(poseidonCfg)}";
|
||||
//Do start thread
|
||||
|
||||
a.OptoListBox.Items.Clear();
|
||||
stopWorkerThread = false;
|
||||
optoThread = new Thread(OptoWorker);
|
||||
if (!optoThread.IsAlive)
|
||||
{
|
||||
OpticalHeadTest.StartOptotestInputLoop(poseidonCfg,OptoReceivedHandler); // open opto port
|
||||
optoThread.Start();
|
||||
}
|
||||
|
||||
break;
|
||||
case Operations.SetTestModeOff:
|
||||
//Do stop thread
|
||||
// rfidListItem.Text = OpticalHeadTest.SetActiveMode(_iPerlReader);
|
||||
stopWorkerThread = true;
|
||||
OpticalHeadTest.StopOptoTestInputLoop(); // close opto port
|
||||
|
||||
//Do switch off test mode
|
||||
rfidListItem.Text = $"SetActiveMode: {OpticalHeadTest.SetActiveMode(poseidonCfg)}";
|
||||
break;
|
||||
default:
|
||||
rfidListItem.Text = @"--";
|
||||
break;
|
||||
}
|
||||
}
|
||||
a.RfidOutputListBox.Items.Add(rfidListItem);
|
||||
a.RfidOutputListBox.Items.AddRange(logChecker.Messages.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
public void OptoWorker()
|
||||
{
|
||||
while (!this.stopWorkerThread)
|
||||
{
|
||||
Thread.Sleep(250);
|
||||
|
||||
if (this.stopWorkerThread)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseOptoWorker()
|
||||
{
|
||||
this.stopWorkerThread = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
using System.IO;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.implementations
|
||||
{
|
||||
public enum CommunicationInterface
|
||||
{
|
||||
Nfc,
|
||||
Touched,
|
||||
}
|
||||
public class PoseidonReader : ComponentBase, IDevice, IRegReaderDatastream, ISessionDataMngmnt, IOperation, ISmartReader
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(PoseidonReader));
|
||||
|
||||
public PoseidonReader()
|
||||
{
|
||||
_pulsesPerLtr = 0;
|
||||
_ltrsPerPulse = 0;
|
||||
_wmPulses = 0;
|
||||
_wmRefPulses = 0;
|
||||
_wmVolume = 0;
|
||||
_beginWmState = 0;
|
||||
_endWmState = 0;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}({1})", ClassName, Cfg.ToString(-1));
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void StopDevice()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void StopDevice2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public bool Disabled { get; set; }
|
||||
public RegisterReaderType RegisterReaderType { get; }
|
||||
public string SerialNr { get; set; }
|
||||
public int Position { get; }
|
||||
public string CommInterface { get; }
|
||||
public int RfidComPortNr { get; }
|
||||
public bool CommFailed { get; set; }
|
||||
public void ResetNfcInterface(bool? nfc_on = null)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public string ReadOptoData()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetNfcInterface()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetRfidInterface()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void StopDataStreamProcessing()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void StartDataStreamProcessing()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SetCommunicationInterface(string commInterface)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void WriteBinary(BinaryWriter writer)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void ReadBinary(BinaryReader reader)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
private double _pulsesPerLtr ;
|
||||
private double _ltrsPerPulse ;
|
||||
private int _wmPulses ;
|
||||
private int _wmRefPulses ;
|
||||
private double _wmVolume ;
|
||||
private double _beginWmState ;
|
||||
private double _endWmState ;
|
||||
|
||||
|
||||
public double PulsesPerLtr { get => _pulsesPerLtr; }
|
||||
public double LtrsPerPulse { get => _ltrsPerPulse; }
|
||||
public int WMPulses { get => _wmPulses; }
|
||||
public int WMRefPulses { get =>_wmRefPulses; }
|
||||
public double WMVolume { get =>_wmVolume; }
|
||||
public double BeginWMState { get => _beginWmState; set => _beginWmState = value; }
|
||||
public double EndWMState { get => _endWmState; set => _endWmState = value; }
|
||||
|
||||
public IOperation ReadDatastreamOp()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void TestIsGoingToStartSoon(Test test, int repetitionNr)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public bool NoSamples { get; }
|
||||
public double VolumeLtrStart { get; }
|
||||
public double VolumeLtrEnd { get; }
|
||||
public double TimestampSecStart { get; }
|
||||
public double TimestampSecEnd { get; }
|
||||
public void StartSession()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void SaveMark(object mark)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void EndSession()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public Event Run()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using TBF.Rig.Generic;
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.TestMethods.iPerlCommunication.iPerlHead;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
{
|
||||
@@ -9,9 +10,9 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
public IComponent DummyComponent() { return new IPerlReader(); }
|
||||
public IComponent DummyComponent() { return new IperlHead(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new IPerlReader(cfg); }
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return null; }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new IPerlCfg(this); }
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
public IComponentCfgCtrl GetControl(IList<Component> cmpntEntities)
|
||||
{
|
||||
return new RegisterReaders.iPerlReaderUNI.IPerlUniCfgCtrl();
|
||||
return new IPerlReader.IPerlUniCfgCtrl();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
muxBoardNrTextBox.Text = config.MuxBoardNr.ToString();
|
||||
groupTextBox.Text = config.Group.ToString();
|
||||
comboBoxCommunicationInterface.SelectedItem = config.CommunicationInterface.ToString();
|
||||
tabPage2.Controls.Add(new IperlUniHeadTestCtrl(config));
|
||||
tabPage2.Controls.Add(new IPerlReader.IperlUniHeadTestCtrl(config));
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
|
||||
@@ -1,53 +1,43 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Windows.Forms;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl.communication;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.test;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.implementations;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
{
|
||||
public partial class IperlUniHeadTestCtrl : UserControl
|
||||
{
|
||||
IPerlCfg config;
|
||||
IntIPerlReader _iPerlReader;
|
||||
Thread optoThread;
|
||||
private IUniHeadTestCtrl _ctrl;
|
||||
private IUniHeadTestCtrl Ctrl { get => _ctrl; }
|
||||
|
||||
|
||||
|
||||
private bool stopWorkerThread;
|
||||
public event EventHandler<OptoReceivedEventArgs> OptoReceivedHandler;
|
||||
|
||||
public IperlUniHeadTestCtrl(IPerlCfg config)
|
||||
{
|
||||
this.config = config;
|
||||
this._ctrl = new PoseidonImplHeadTestCtrl();
|
||||
Ctrl.config = config;
|
||||
InitializeComponent();
|
||||
if (config == null) return;
|
||||
|
||||
SmartCommunicationForm.TestMethodCfg = new TestMethodCfg(null); // default values for iPerlCommunication
|
||||
|
||||
//TODO fix possibility set test method in config
|
||||
//iPerlCommunicationForm.cfg = new TestMethodCfg(null); // default values for iPerlCommunication
|
||||
|
||||
foreach(var head in ProcessData.IperlHeadsUni)
|
||||
foreach(var head in ProcessData.SmartHeadsUni)
|
||||
{
|
||||
if (head != null && head.Name == config.Name) { _iPerlReader = head; }
|
||||
if (head != null && head.Name == config.Name) { Ctrl.ISmartReader = head; }
|
||||
}
|
||||
|
||||
rfidCommandComboBox.DisplayMember = "Name";
|
||||
rfidCommandComboBox.ValueMember = "Value";
|
||||
var items = new[]
|
||||
{
|
||||
new {Name = "Read PCB", Value = "ReadPCB" },
|
||||
new {Name = "Set Test Mode", Value = "SetTestMode" },
|
||||
new {Name = "Set Active Mode", Value = "SetActiveMode" },
|
||||
#if DEBUG
|
||||
new {Name = "Start Read Opto Data", Value = "ReadOptoData" },
|
||||
new {Name = "Stop Read Opto Data", Value = "StopReadOptoData" },
|
||||
#endif
|
||||
new {Name = " ", Value = "" },
|
||||
new {Name = "Reset NFC Head", Value = "ResetNfcHead" },
|
||||
new {Name = "Set NFC Head Interface", Value = "SetNfcHead" },
|
||||
new {Name = "Set RFID Head interface", Value = "SetRfidHead" }
|
||||
};
|
||||
var items = Ctrl.GetComboOperationsPairs();
|
||||
/*
|
||||
// CTRL+ALT+double click - hidden poweruser menu
|
||||
if (((Keyboard.ModifierKeys & Keys.Control) == Keys.Control) && ((Keyboard.ModifierKeys & Keys.Alt) == Keys.Alt) && Users.CurrentUser.AuthorizedAs == AuthorizedAs.PowerUser)
|
||||
@@ -56,11 +46,11 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
items[items.Length - 1] = new { Name = "Kluc", Value = "Kluc" };
|
||||
}
|
||||
*/
|
||||
rfidCommandComboBox.DataSource = items;
|
||||
rfidCommandComboBox.DataSource = items.Select(i => i.Name).ToArray();
|
||||
|
||||
stopWorkerThread = false;
|
||||
Ctrl.Initialize();
|
||||
|
||||
OptoReceivedHandler += (EventHandler<OptoReceivedEventArgs>)((sndr, args) =>
|
||||
Ctrl.OptoReceivedHandler += (EventHandler<OptoReceivedEventArgs>)((sndr, args) =>
|
||||
{
|
||||
if (this.InvokeRequired)
|
||||
this.Invoke((Delegate)new EventHandler<OptoReceivedEventArgs>(this.OnOptoReceived2), sndr, (object)args);
|
||||
@@ -76,104 +66,16 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
|
||||
private void CommandTestButtonClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
rfidOutputListBox.Items.Clear();
|
||||
|
||||
using (Tools.LogChecker logChecker = new Tools.LogChecker("RfidData", log4net.Core.Level.Debug))
|
||||
Ctrl.CommandTestButtonClick(sender, e, new Arguments()
|
||||
{
|
||||
ListItem rfidListItem = new ListItem();
|
||||
rfidListItem.Attributes.Add("style", "font-weight:bold");
|
||||
switch (rfidCommandComboBox.SelectedValue)
|
||||
{
|
||||
case "ReadPCB":
|
||||
rfidListItem.Text = $"PCB: {OpticalHeadTest.ReadRequest_PCB(_iPerlReader)}";
|
||||
break;
|
||||
case "SetTestMode":
|
||||
rfidListItem.Text = OpticalHeadTest.SetTestMode(_iPerlReader);
|
||||
optoListBox.Items.Clear();
|
||||
stopWorkerThread = false;
|
||||
optoThread = new Thread(OptoWorker);
|
||||
if (!optoThread.IsAlive)
|
||||
{
|
||||
_iPerlReader.StartDataStreamProcessing(); // open opto port
|
||||
optoThread.Start();
|
||||
}
|
||||
break;
|
||||
case "SetActiveMode":
|
||||
rfidListItem.Text = OpticalHeadTest.SetActiveMode(_iPerlReader);
|
||||
stopWorkerThread = true;
|
||||
_iPerlReader.StopDataStreamProcessing(); // close opto port
|
||||
break;
|
||||
case "ResetNfcHead":
|
||||
_iPerlReader.ResetNfcInterface();
|
||||
break;
|
||||
case "SetNfcHead":
|
||||
_iPerlReader.SetNfcInterface();
|
||||
break;
|
||||
case "SetRfidHead":
|
||||
_iPerlReader.SetRfidInterface();
|
||||
break;
|
||||
case "ReadOptoData":
|
||||
optoListBox.Items.Clear();
|
||||
stopWorkerThread = false;
|
||||
optoThread = new Thread(OptoWorker);
|
||||
if (optoThread.IsAlive)
|
||||
{
|
||||
stopWorkerThread = true;
|
||||
_iPerlReader.StopDataStreamProcessing(); // close opto port
|
||||
}
|
||||
if (!optoThread.IsAlive)
|
||||
{
|
||||
_iPerlReader.StartDataStreamProcessing(); // open opto port
|
||||
optoThread.Start();
|
||||
}
|
||||
break;
|
||||
case "StopReadOptoData":
|
||||
stopWorkerThread = true;
|
||||
_iPerlReader.StopDataStreamProcessing(); // close opto port
|
||||
break;
|
||||
}
|
||||
rfidOutputListBox.Items.Add(rfidListItem);
|
||||
rfidOutputListBox.Items.AddRange(logChecker.Messages.ToArray());
|
||||
}
|
||||
ISmartReader = Ctrl.ISmartReader,
|
||||
OptoListBox = optoListBox,
|
||||
RfidCommandComboBox = rfidCommandComboBox,
|
||||
RfidOutputListBox = rfidOutputListBox
|
||||
});
|
||||
}
|
||||
|
||||
private void OptoWorker()
|
||||
{
|
||||
while (!this.stopWorkerThread)
|
||||
{
|
||||
Thread.Sleep(250);
|
||||
if (this.stopWorkerThread)
|
||||
break;
|
||||
|
||||
try
|
||||
{
|
||||
string buffer = _iPerlReader.ReadOptoData();
|
||||
if (string.IsNullOrEmpty(buffer))
|
||||
{
|
||||
this.OnOptoReceived((object)this, new OptoReceivedEventArgs("."));
|
||||
}
|
||||
else
|
||||
OnOptoReceived((object)this, new OptoReceivedEventArgs(buffer));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
this.OnOptoReceived((object)this, new OptoReceivedEventArgs(ex.Message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnOptoReceived(object sender, OptoReceivedEventArgs args)
|
||||
{
|
||||
if (this.OptoReceivedHandler == null)
|
||||
return;
|
||||
try
|
||||
{
|
||||
this.OptoReceivedHandler(sender, args);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void UserControl_Load(object sender, EventArgs e)
|
||||
{
|
||||
@@ -183,11 +85,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
void ParentForm_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
//OnHandleDestroyed(new EventArgs());
|
||||
stopWorkerThread = true;
|
||||
if (optoThread != null)
|
||||
{
|
||||
optoThread.Abort();
|
||||
}
|
||||
Ctrl.Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
{
|
||||
public class PoseidonCfg
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user