Compare commits
41
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1bb1ff079 | ||
|
|
db4ac6a838 | ||
|
|
a0201427ca | ||
|
|
202eef0d46 | ||
|
|
988a8c6642 | ||
|
|
42ee9eaee3 | ||
|
|
3f28051d79 | ||
|
|
65f13cc868 | ||
|
|
cd8ba3cda3 | ||
|
|
a5936c8f19 | ||
|
|
2842425673 | ||
|
|
06a401a1ff | ||
|
|
3a2fc50fec | ||
|
|
38a58ed8b7 | ||
|
|
c7cba20de0 | ||
|
|
6311df49c3 | ||
|
|
f1d32a39ba | ||
|
|
224b53f774 | ||
|
|
1e2777c5e7 | ||
|
|
c3c21649fb | ||
|
|
99ccabc142 | ||
|
|
f1e6e94450 | ||
|
|
320cddb177 | ||
|
|
42002e3fa4 | ||
|
|
77cabfd712 | ||
|
|
c933e2d759 | ||
|
|
f3f0a46627 | ||
|
|
b5fb4c2947 | ||
|
|
f6cce9df3c | ||
|
|
c0385c0782 | ||
|
|
db43bdb652 | ||
|
|
6bdc10f4a7 | ||
|
|
6795793858 | ||
|
|
a2c564d789 | ||
|
|
3bc9e731e8 | ||
|
|
95c5f09238 | ||
|
|
0a45d66c0b | ||
|
|
96408eaef3 | ||
|
|
4395516216 | ||
|
|
9281b52464 | ||
|
|
daad73ff81 |
@@ -34,6 +34,8 @@ MergeResultsDBs/bin/
|
||||
MergeResultsDBs/obj/
|
||||
NfcC7_Dll/bin/
|
||||
NfcC7_Dll/obj/
|
||||
NfcC7_DLL.Tests/bin/
|
||||
NfcC7_DLL.Tests/obj/
|
||||
OrderManagement/bin/
|
||||
OrderManagement/obj/
|
||||
ProductionTracing/bin/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using SharedComponents;
|
||||
using SharedComponents;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using SharedComponents;
|
||||
using SharedComponents;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
Generated
+1
-1
@@ -1,4 +1,4 @@
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace AppDiagnostic
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using log4net.Config;
|
||||
using log4net.Config;
|
||||
using log4net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Reflection;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
|
||||
+197
-1
@@ -33,6 +33,18 @@
|
||||
<Reference Include="log4net, Version=2.0.15.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Logic.ProductionToProductMapper, Version=1.0.3.24128, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Logic.ProductionToProductMapper.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\NLog.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PdfSharp.resources, Version=1.50.5147.0, Culture=de, PublicKeyToken=f94615aa0424f9eb, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\de\PdfSharp.resources.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
@@ -42,6 +54,90 @@
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.Applications.resources, Version=1.0.3.24125, Culture=de, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\de\Xylem.Common.Hardware.WaterMeter.Genesis.Applications.resources.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.resources, Version=1.0.3.24134, Culture=de, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\de\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.resources.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.resources, Version=1.0.3.24134, Culture=de, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\de\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.resources.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.ProtocolCore, Version=1.0.3.24127, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.ProtocolCore.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol, Version=1.0.3.24127, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol, Version=1.0.3.24127, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.Registers, Version=1.0.3.24126, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Registers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Hardware.WaterMeter.WaterMeterCore, Version=1.0.3.24126, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Hardware.WaterMeter.WaterMeterCore.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters, Version=1.0.3.24125, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Logic.ProductionOrderCore, Version=1.0.3.24128, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Logic.ProductionOrderCore.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Logic.RelatePcb, Version=1.0.3.24125, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Logic.RelatePcb.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Logic.ServiceCore, Version=1.0.3.24125, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Logic.ServiceCore.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Logic.SoftwareAccessHelper, Version=1.0.3.24125, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Logic.SoftwareAccessHelper.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Metrology.Measurements, Version=1.0.3.24125, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Metrology.Measurements.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Ui.CordonelPreadjustmentUi, Version=2.1.7944.24134, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Ui.CordonelPreadjustmentUi.exe</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Ui.GenesisToolBox, Version=1.0.3.24135, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Ui.GenesisToolBox.exe</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Utils.ByteArrayStyle, Version=1.0.3.24125, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Utils.ByteArrayStyle.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Utils.Crc16Ccitt, Version=1.0.3.24125, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Utils.Crc16Ccitt.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Utils.Logging, Version=1.0.3.24125, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Utils.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Xylem.Common.Utils.ProcessExec, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\Xylem.Common.Utils.ProcessExec.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="XylemCommonUiLegacyGenCtl, Version=1.0.3.24134, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>Cordonel\Common\XylemCommonUiLegacyGenCtl.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BackgroundBeep.cs" />
|
||||
@@ -90,7 +186,19 @@
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<None Include="Cordonel\Common\configuration.json" />
|
||||
<None Include="Cordonel\Common\Logic.ProductionToProductMapper.dll.config" />
|
||||
<None Include="Cordonel\Common\meterconfig.json" />
|
||||
<None Include="Cordonel\Common\MeterFilesEraseRestore.json" />
|
||||
<None Include="Cordonel\Common\status.json" />
|
||||
<None Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Applications.dll.config" />
|
||||
<None Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.dll.config" />
|
||||
<None Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.dll.config" />
|
||||
<None Include="Cordonel\Common\Xylem.Common.Ui.CordonelPreadjustmentUi.exe.config" />
|
||||
<None Include="Cordonel\Common\Xylem.Common.Ui.GenesisToolBox.exe.config" />
|
||||
<None Include="Cordonel\Common\XylemCommonUiLegacyGenCtl.dll.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Forms\ListViewEx.resx">
|
||||
<DependentUpon>ListViewEx.cs</DependentUpon>
|
||||
@@ -99,6 +207,94 @@
|
||||
<DependentUpon>ModelessForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Cordonel\Common\de\PdfSharp.resources.dll" />
|
||||
<Content Include="Cordonel\Common\de\Xylem.Common.Hardware.WaterMeter.Genesis.Applications.resources.dll" />
|
||||
<Content Include="Cordonel\Common\de\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.resources.dll" />
|
||||
<Content Include="Cordonel\Common\de\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.resources.dll" />
|
||||
<Content Include="Cordonel\Common\Logic.ProductionToProductMapper.dll" />
|
||||
<Content Include="Cordonel\Common\Logic.ProductionToProductMapper.pdb" />
|
||||
<Content Include="Cordonel\Common\Newtonsoft.Json.dll" />
|
||||
<Content Include="Cordonel\Common\Newtonsoft.Json.xml" />
|
||||
<Content Include="Cordonel\Common\NLog.dll" />
|
||||
<Content Include="Cordonel\Common\NLog.xml" />
|
||||
<Content Include="Cordonel\Common\NlogConfig.xml" />
|
||||
<Content Include="Cordonel\Common\PdfSharp.dll" />
|
||||
<Content Include="Cordonel\Common\PdfSharp.xml" />
|
||||
<Content Include="Cordonel\Common\RestSharp.dll" />
|
||||
<Content Include="Cordonel\Common\RestSharp.xml" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.CommonCore.Configuration.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.CommonCore.Configuration.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.CommonCore.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.CommonCore.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.CommonCore.ThreadWatcher.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.CommonCore.ThreadWatcher.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.Interfaces.Ports.PortCore.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.Interfaces.Ports.PortCore.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.Interfaces.Ports.PortCore.xml" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.Interfaces.Ports.SerialPorts.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.Interfaces.Ports.SerialPorts.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.Interfaces.Protocols.TransmitProtocol.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Applications.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Applications.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.xml" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.xml" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisFile.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisPwd.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.ProtocolCore.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.ProtocolCore.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.RequestProtocol.xml" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol.xml" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Registers.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Registers.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.WaterMeterCore.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.WaterMeterCore.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.WaterMeterCore.xml" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Logic.ProductionOrderCore.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Logic.ProductionOrderCore.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Logic.RelatePcb.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Logic.RelatePcb.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Logic.ServiceCore.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Logic.ServiceCore.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Logic.SoftwareAccessHelper.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Logic.SoftwareAccessHelper.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Metrology.Measurements.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Metrology.Measurements.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Metrology.Measurements.xml" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Ui.CordonelPreadjustmentUi.exe" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Ui.CordonelPreadjustmentUi.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Ui.GenesisToolBox.exe" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Ui.GenesisToolBox.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Utils.ByteArrayStyle.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Utils.ByteArrayStyle.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Utils.Crc16Ccitt.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Utils.Crc16Ccitt.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Utils.Logging.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Utils.Logging.pdb" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Utils.ProcessExec.dll" />
|
||||
<Content Include="Cordonel\Common\Xylem.Common.Utils.ProcessExec.pdb" />
|
||||
<Content Include="Cordonel\Common\XylemCommonUiLegacyGenCtl.dll" />
|
||||
<Content Include="Cordonel\Common\XylemCommonUiLegacyGenCtl.pdb" />
|
||||
<Content Include="Cordonel\Greisinger\GMH3x32E.dll" />
|
||||
<Content Include="Cordonel\Greisinger\RegAsm4.exe" />
|
||||
<Content Include="Cordonel\Sirt\SIRTCOM.dll" />
|
||||
<Content Include="Cordonel\Sirt\SIRT_Driver_Win32_PC.dll" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="3.10.4" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="3.10.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NfcC7_DLL\NfcC7_DLL.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
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
|
||||
{
|
||||
|
||||
[TestMethod]
|
||||
public void SetTestingMode_Optohead_C7_ON_LiveMeterTest()
|
||||
{
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
"COM5",
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.SetTestingMode(OptoHeadStatus.OptoHeadC7);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadC7, status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SetTestingMode_Optohead_OFF_LiveMeterTest()
|
||||
{
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
"COM5",
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.SetTestingMode(OptoHeadStatus.OptoHeadDisabled);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadDisabled, status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SetTestingMode_LiveMeterTest()
|
||||
{
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
"COM5",
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.SetTestingMode(OptoHeadStatus.OptoHeadC2);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadC2, status);
|
||||
|
||||
status = service.SetTestingMode(OptoHeadStatus.OptoHeadC7);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadC7, status);
|
||||
|
||||
status = service.SetTestingMode(OptoHeadStatus.OptoHeadDisabled);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadDisabled, status);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetSerialNr_LiveMeterTest()
|
||||
{
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
"COM5",
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
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()
|
||||
{
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
"COM5",
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.GetTestingMode();
|
||||
Assert.IsFalse(OptoHeadStatus.Unknown == status);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using NfcC7_DLL.NfcHandler;
|
||||
using NfcC7_DLL.NfcHandler.Protocols;
|
||||
using NfcC7_DLL.NfcHandler.Utils;
|
||||
|
||||
namespace NfcC7_DLL.Tests.NfcHanler;
|
||||
|
||||
[TestClass]
|
||||
[TestSubject(typeof(OptoHeadService))]
|
||||
public class OptoHeadServiceTest
|
||||
{
|
||||
|
||||
[TestMethod]
|
||||
public void RunLoop_Test()
|
||||
{
|
||||
//Switch meter to Optohead C7 testing mode
|
||||
SerialPortData serialPortData = new SerialPortData(
|
||||
"COM5",
|
||||
"HatCliDemo.exe",
|
||||
74);
|
||||
|
||||
NfcHeadService service = new NfcHeadService(serialPortData);
|
||||
OptoHeadStatus status = service.SetTestingMode(OptoHeadStatus.OptoHeadC7);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadC7, status);
|
||||
//Open serial connection to Optohead
|
||||
OptoHeadService.Con con = new OptoHeadService.Con();
|
||||
con.com = "COM6";
|
||||
OptoHeadService optoHeadService = new OptoHeadService(con);
|
||||
Assert.IsTrue(optoHeadService.CreateSerialConnection());
|
||||
//start loop to receive data
|
||||
optoHeadService.RunLoop();
|
||||
WaterMetrologyData lastData = null;
|
||||
int iCycles = 0, iCyclesMax = 10;
|
||||
for (int i = 0; i < iCyclesMax; i++)
|
||||
{
|
||||
|
||||
bool finished = false;
|
||||
while (!finished)
|
||||
{
|
||||
//optoHeadService.Run();
|
||||
if (optoHeadService.WaterMetrologyData != null
|
||||
&& lastData != optoHeadService.WaterMetrologyData
|
||||
&& optoHeadService.WaterMetrologyData.OptoHeadStatus != OptoHeadStatus.Unknown)
|
||||
{
|
||||
lastData = optoHeadService.WaterMetrologyData;
|
||||
finished = true;
|
||||
iCycles++;
|
||||
if (lastData.OptoHeadStatus.HasFlag(OptoHeadStatus.OptoHeadC7))
|
||||
{
|
||||
Assert.IsNotNull(lastData.C7Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsNotNull(lastData.C2Data);
|
||||
}
|
||||
System.Console.WriteLine("Cycle: {0} lastData: {1}", iCycles, lastData);
|
||||
}
|
||||
}
|
||||
}
|
||||
optoHeadService.CloseSerialConnection();
|
||||
|
||||
Assert.IsTrue(iCycles > 0);
|
||||
Assert.IsTrue(iCycles == iCyclesMax);
|
||||
|
||||
//Close Optohead
|
||||
status = service.SetTestingMode(OptoHeadStatus.OptoHeadDisabled);
|
||||
Assert.AreEqual(OptoHeadStatus.OptoHeadDisabled, status);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using NfcC7_DLL.NfcHandler.Utils;
|
||||
|
||||
namespace NfcC7_DLL.Tests.NfcHanler.Utils;
|
||||
|
||||
//[TestClass]
|
||||
[TestSubject(typeof(SERIAL_Driver))]
|
||||
public class SERIAL_DriverTest
|
||||
{
|
||||
private 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 readonly byte[] Open =
|
||||
{ 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 =
|
||||
{ 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 =
|
||||
{ 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",
|
||||
baudrate = 38400,
|
||||
dataBits = 8,
|
||||
parity = Parity.None,
|
||||
stopbits = StopBits.Two,
|
||||
readTimeout = 5000,
|
||||
writeTimeout = 1000
|
||||
};
|
||||
static Con con6 = new Con()
|
||||
{
|
||||
com = "COM6",
|
||||
baudrate = 38400,
|
||||
dataBits = 8,
|
||||
parity = Parity.None,
|
||||
stopbits = StopBits.Two,
|
||||
readTimeout = 5000,
|
||||
writeTimeout = 1000
|
||||
};
|
||||
|
||||
|
||||
|
||||
//[TestMethod]
|
||||
public void SendMessage_Test()
|
||||
{
|
||||
Con con = con5;
|
||||
|
||||
byte[] message = Open;
|
||||
byte[] bytesReceived;
|
||||
|
||||
SERIAL_Driver driver = new SERIAL_Driver();
|
||||
bool isopen = driver.OpenConnection(
|
||||
con.com,
|
||||
con.baudrate,
|
||||
con.dataBits,
|
||||
con.parity,
|
||||
con.stopbits,
|
||||
con.readTimeout,
|
||||
con.writeTimeout);
|
||||
Assert.IsTrue(isopen);
|
||||
driver.SendMessage(message, message.Length);
|
||||
//Assert.IsTrue(driver.GetRawData().Length == 0);
|
||||
bytesReceived = driver.GetRawData();
|
||||
//Assert.IsTrue(bytesReceived.Length > 0);
|
||||
Console.WriteLine("IsOpened: {0}", driver.isOpen());
|
||||
// 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);
|
||||
}
|
||||
|
||||
// --- 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);
|
||||
|
||||
driver.Close();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//[TestMethod]
|
||||
public void SendMessage_TestLoop()
|
||||
{
|
||||
Con con = con6;
|
||||
|
||||
byte[] message = {0x00};
|
||||
byte[] bytesReceived;
|
||||
|
||||
SERIAL_Driver driver = new SERIAL_Driver();
|
||||
bool isopen = driver.OpenConnection(
|
||||
con.com,
|
||||
con.baudrate,
|
||||
con.dataBits,
|
||||
con.parity,
|
||||
con.stopbits,
|
||||
con.readTimeout,
|
||||
con.writeTimeout);
|
||||
Assert.IsTrue(isopen);
|
||||
|
||||
for (int iStep = 0; iStep < 100; iStep++)
|
||||
{
|
||||
driver.SendMessage(message, message.Length);
|
||||
//Assert.IsTrue(driver.GetRawData().Length == 0);
|
||||
bytesReceived = driver.GetRawData();
|
||||
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);
|
||||
}
|
||||
|
||||
//message = CommDeviceSessionEnd;
|
||||
//driver.SendMessage(message, message.Length);
|
||||
|
||||
driver.CloseConnection();
|
||||
|
||||
}
|
||||
|
||||
|
||||
//[TestMethod]
|
||||
public void SendMessage_TestGetSerialNo()
|
||||
{
|
||||
Con con = con6;
|
||||
byte[] message = Open;
|
||||
byte[] bytesReceived;
|
||||
|
||||
SERIAL_Driver driver = new SERIAL_Driver();
|
||||
bool isopen = driver.OpenConnection(
|
||||
con.com,
|
||||
con.baudrate,
|
||||
con.dataBits,
|
||||
con.parity,
|
||||
con.stopbits,
|
||||
con.readTimeout,
|
||||
con.writeTimeout);
|
||||
Assert.IsTrue(isopen);
|
||||
|
||||
driver.SendMessage(message, message.Length,con.readTimeout);
|
||||
//Assert.IsTrue(driver.GetRawData().Length == 0);
|
||||
bytesReceived = driver.GetRawData();
|
||||
Assert.IsTrue(bytesReceived.Length > 0);
|
||||
if (bytesReceived[0] == 0xFF)
|
||||
Console.WriteLine("Error message: {0}", driver.ErrorMessage);
|
||||
// Display raw bytes (as hex or byte count)
|
||||
Console.WriteLine("IsOpened: {0}", driver.isOpen());
|
||||
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;
|
||||
driver.SendMessage(message, message.Length,con.readTimeout);
|
||||
bytesReceived = driver.GetRawData();
|
||||
Assert.IsTrue(bytesReceived.Length > 0);
|
||||
if (bytesReceived[0] == 0xFF)
|
||||
Console.WriteLine("Error message: {0}", driver.ErrorMessage);
|
||||
// Display raw bytes (as hex or byte count)
|
||||
Console.WriteLine("IsOpened: {0}", driver.isOpen());
|
||||
Console.WriteLine(string.Format("Bytes received: {0}", bytesReceived.Length));
|
||||
Console.WriteLine(string.Format("Bytes (hex): {0}", BitConverter.ToString(bytesReceived)));
|
||||
response = System.Text.Encoding.UTF8.GetString(bytesReceived);
|
||||
Console.WriteLine("Bytes string: {0}",response);
|
||||
|
||||
// --- Get Serial No ---
|
||||
message = ProductDetails2;
|
||||
driver.SendMessage(message, message.Length,con.readTimeout);
|
||||
bytesReceived = driver.GetRawData();
|
||||
Assert.IsTrue(bytesReceived.Length > 0);
|
||||
if (bytesReceived[0] == 0xFF)
|
||||
Console.WriteLine("Error message: {0}", driver.ErrorMessage);
|
||||
// Display raw bytes (as hex or byte count)
|
||||
Console.WriteLine("IsOpened: {0}", driver.isOpen());
|
||||
Console.WriteLine(string.Format("Bytes received: {0}", bytesReceived.Length));
|
||||
Console.WriteLine(string.Format("Bytes (hex): {0}", BitConverter.ToString(bytesReceived)));
|
||||
response = System.Text.Encoding.UTF8.GetString(bytesReceived);
|
||||
Console.WriteLine("Bytes string: {0}",response);
|
||||
|
||||
|
||||
message = CommDeviceSessionEnd;
|
||||
driver.SendMessage(message, message.Length);
|
||||
|
||||
driver.Close();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,57 @@
|
||||
<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;</DefineConstants>
|
||||
<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>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||
<PackageReference Include="System.IO.Ports" Version="10.0.0-rc.1.25451.107" />
|
||||
<PackageReference Include="System.Security.Cryptography.Cng" Version="5.0.0" />
|
||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Build.Utilities.v4.0" />
|
||||
<Reference Include="NA2WNFC">
|
||||
<HintPath>NfcHanler\NfcReaderLibrary\NA2WNFC.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OBIDISC4NET">
|
||||
<HintPath>NfcHanler\NfcReaderLibrary\OBIDISC4NET.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OBIDISC4NETnative">
|
||||
<HintPath>NfcHanler\NfcReaderLibrary\OBIDISC4NETnative.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="OBIDISC4NET_API">
|
||||
<HintPath>NfcHanler\NfcReaderLibrary\OBIDISC4NET_API.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PresentationCore">
|
||||
<HintPath>..\..\..\..\..\Windows\Microsoft.NET\assembly\GAC_32\PresentationCore\v4.0_4.0.0.0__31bf3856ad364e35\PresentationCore.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="PresentationFramework">
|
||||
<HintPath>..\..\..\..\..\Windows\Microsoft.NET\assembly\GAC_MSIL\PresentationFramework\v4.0_4.0.0.0__31bf3856ad364e35\PresentationFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Sensus">
|
||||
<HintPath>NfcHanler\FieldLogicLibrary\Sensus.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
using NfcC7_DLL.NfcHandler.Protocols;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler
|
||||
{
|
||||
public class HeadInfo
|
||||
{
|
||||
string SerialNr { get; set; }
|
||||
OptoHeadStatus OptoHeadStatus { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler
|
||||
{
|
||||
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,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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler.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 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 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}";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler.Protocols
|
||||
{
|
||||
public class WaterMetrologyDataC7 : 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 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 = 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 @@
|
||||
# Protocol Description
|
||||
@@ -0,0 +1,341 @@
|
||||
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;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler.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);
|
||||
return task;
|
||||
}
|
||||
|
||||
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,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
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.NfcHandler.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)
|
||||
{
|
||||
if (!_serialPort.IsOpen) return;
|
||||
lock (this)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
if (!_serialPort.IsOpen) return;
|
||||
SerialPortReadBuffer = new Collection<byte>();
|
||||
while (_serialPort.BytesToRead > 0)
|
||||
{
|
||||
SerialPortReadBuffer.Add((byte)_serialPort.ReadByte());
|
||||
}
|
||||
|
||||
_binMessages.Add(SerialPortReadBuffer.ToArray());
|
||||
_isReading = false;
|
||||
}
|
||||
}
|
||||
|
||||
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,88 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace NfcC7_DLL.NfcHandler.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
//*****************************************************************************
|
||||
@@ -9,7 +7,7 @@ using System.Text;
|
||||
// Author: Venkat, Rajeshwar
|
||||
//*****************************************************************************
|
||||
|
||||
namespace Sensus.Poseidon.NfcHandler
|
||||
namespace NfcC7_DLL.NfcHandler.Utils
|
||||
{
|
||||
public static class Tools
|
||||
{
|
||||
@@ -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>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.IO.MemoryMappedFiles;
|
||||
using System.Text;
|
||||
|
||||
namespace SharedComponents
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
|
||||
@@ -0,0 +1,23 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("SharedComponents")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+498fc21412f36768d9ff9d2abd4fd377ea0bf3ae")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("SharedComponents")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("SharedComponents")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
|
||||
@@ -0,0 +1,23 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("SharedComponents")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+498fc21412f36768d9ff9d2abd4fd377ea0bf3ae")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("SharedComponents")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("SharedComponents")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
@@ -0,0 +1,4 @@
|
||||
// <autogenerated />
|
||||
using System;
|
||||
using System.Reflection;
|
||||
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
|
||||
@@ -0,0 +1,23 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
[assembly: System.Reflection.AssemblyCompanyAttribute("SharedComponents")]
|
||||
[assembly: System.Reflection.AssemblyConfigurationAttribute("Release")]
|
||||
[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")]
|
||||
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+498fc21412f36768d9ff9d2abd4fd377ea0bf3ae")]
|
||||
[assembly: System.Reflection.AssemblyProductAttribute("SharedComponents")]
|
||||
[assembly: System.Reflection.AssemblyTitleAttribute("SharedComponents")]
|
||||
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]
|
||||
|
||||
// Generated by the MSBuild WriteCodeFragment class.
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// <auto-generated/>
|
||||
global using global::System;
|
||||
global using global::System.Collections.Generic;
|
||||
global using global::System.IO;
|
||||
global using global::System.Linq;
|
||||
global using global::System.Net.Http;
|
||||
global using global::System.Threading;
|
||||
global using global::System.Threading.Tasks;
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
|
||||
@@ -7,7 +7,7 @@
|
||||
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
|
||||
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\micha\.nuget\packages\</NuGetPackageFolders>
|
||||
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">PackageReference</NuGetProjectStyle>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">6.14.0</NuGetToolVersion>
|
||||
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">7.0.0</NuGetToolVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<SourceRoot Include="C:\Users\micha\.nuget\packages\" />
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -121,6 +121,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NfcS5_DLL", "..\NfcS5_DLL\N
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NfcC7_DLL", "NfcC7_DLL\NfcC7_DLL.csproj", "{53E75979-B530-4805-8FC9-B314F14A62BE}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NfcC7_DLL.Tests", "NfcC7_DLL.Tests\NfcC7_DLL.Tests.csproj", "{715605C5-568B-48D6-9C09-2DC5F2E81F66}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -553,6 +555,18 @@ Global
|
||||
{53E75979-B530-4805-8FC9-B314F14A62BE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{53E75979-B530-4805-8FC9-B314F14A62BE}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{53E75979-B530-4805-8FC9-B314F14A62BE}.Release|x86.Build.0 = Release|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{715605C5-568B-48D6-9C09-2DC5F2E81F66}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -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")]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
## Version History
|
||||
|
||||
| Version | Target Environment | Title | Description |
|
||||
|------------|--------------------------------------------------------------|-----------------------------------------------------|------------------------------------|
|
||||
| 3.9.2149.0 | HeatMeters, Heat meter sensors, Procedure Dilog, Tab Process | Excanged columns value 'Sensor' and 'Heat meter sensor' | Fix in code ProcedureDlg, row 1851 |
|
||||
| Version | Source of change | Target Environment | Title | Description |
|
||||
|------------|----------------------|--------------------------------------------------------------|-----------------------------------------------------|------------------------------------|
|
||||
| 3.9.2149.0 | Michal databse error | HeatMeters, Heat meter sensors, Procedure Dilog, Tab Process | Excanged columns value 'Sensor' and 'Heat meter sensor' | Fix in code ProcedureDlg, row 1851 |
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
|
||||
namespace TBF.Rig.Generic
|
||||
{
|
||||
public interface ITestParams
|
||||
public interface ITestParams : IParamsProvider
|
||||
{
|
||||
|
||||
public string Activity { get; set; } /// Communication activity
|
||||
public bool SimultWithPrevious { get; set; }
|
||||
public bool SimultWithNext { get; set; }
|
||||
|
||||
void UpdateFromDbEntity(ComponentTest dbEntity);
|
||||
void FromDbEntity(string componentName, Test test);
|
||||
ComponentTest ToDbEntity(string componentName, Test test);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
///
|
||||
/// Copyright (c) 2018 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
/// <summary>
|
||||
/// Factory component 'DatabaseWriter' implements more storing modules
|
||||
/// Mosules:
|
||||
/// * store whole results in database
|
||||
/// * store to specific mexico database structure - not implemented yet
|
||||
/// * store configurable data SQL template to a specific database - not implemented yet
|
||||
/// </summary>
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return GetType().Namespace.Substring(8); } } /// For backward compatibility
|
||||
public override string ToString() { return ClassName; }
|
||||
|
||||
public IComponent DummyComponent() { return new WritingToDb(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new WritingToDb(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new WriterCfg("DatabaseWriter", this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(WriterCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
///
|
||||
/// Copyright (c) 2018-2019 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using Common;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
public partial class WriteDbCfgCtrl : Configs.ConfigCtrlUtils, IComponentCfgCtrl
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
WriterCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as WriterCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public WriteDbCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void WriterCfgCtrl_Load(object sender, EventArgs e)
|
||||
{
|
||||
if (config == null) return;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
public void Closing()
|
||||
{
|
||||
}
|
||||
|
||||
void Redraw()
|
||||
{
|
||||
if (config == null) return; /// Control was not loaded, settings were not changed
|
||||
|
||||
classNameLabel.Text = config.Factory.ClassName;
|
||||
nameTextBox.Text = config.Name;
|
||||
connStrTextBox.Text = config.ConnStr;
|
||||
connStr2TextBox.Text = config.ConnStr2;
|
||||
checkPreviousRecordsCheckBox.Checked = config.CheckPreviousRecords;
|
||||
saveTracingRecordsCheckBox.Checked = config.SaveTracingRecords;
|
||||
|
||||
Network.AdapterInfo.RefreshNetAdaptersInfo();
|
||||
IList<Network.AdapterInfo> adapters = Network.AdapterInfo.NetAdapters;
|
||||
|
||||
string cfgAdapter = string.Empty;
|
||||
foreach (Network.AdapterInfo ai in adapters)
|
||||
{
|
||||
string record;
|
||||
|
||||
if (ai.IPAddress == null)
|
||||
{
|
||||
/// This happens with network adapters that currently have no IP address,
|
||||
/// for instance not connected wireless or dial-up adapters
|
||||
record = "???.???.???.???";
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Do not consider IPv6 adapters as well as "Any", "Broadcast", "Loopback" or "None" addresses
|
||||
if ((ai.IPAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) ||
|
||||
ai.IPAddress.Equals(IPAddress.Any) ||
|
||||
ai.IPAddress.Equals(IPAddress.Broadcast) ||
|
||||
ai.IPAddress.Equals(IPAddress.IPv6Any) ||
|
||||
ai.IPAddress.Equals(IPAddress.IPv6Loopback) ||
|
||||
ai.IPAddress.Equals(IPAddress.IPv6None) ||
|
||||
ai.IPAddress.Equals(IPAddress.Loopback) ||
|
||||
ai.IPAddress.Equals(IPAddress.None))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
record = ai.IPAddress.ToString();
|
||||
}
|
||||
|
||||
record += " - " + ai.Description;
|
||||
int i = netAdapterComboBox.Items.Add(record);
|
||||
if (ai.Description == config.NetAdapter)
|
||||
{
|
||||
/// Select the adapter currently in the configuration
|
||||
netAdapterComboBox.SelectedIndex = i;
|
||||
}
|
||||
}
|
||||
|
||||
/// Select the first one if the adapter from the configuration does not exist on the system
|
||||
if (netAdapterComboBox.SelectedIndex < 0 && netAdapterComboBox.Items.Count > 0)
|
||||
{
|
||||
netAdapterComboBox.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
{
|
||||
nameTextBox.Enabled = true;
|
||||
connStrTextBox.Enabled = true;
|
||||
connStr2TextBox.Enabled = true;
|
||||
netAdapterComboBox.Enabled = true;
|
||||
checkPreviousRecordsCheckBox.Enabled = true;
|
||||
saveTracingRecordsCheckBox.Enabled = true;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
return CfgUpdateFlags.None;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateCfg()
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
|
||||
|
||||
if (config.Name != nameTextBox.Text)
|
||||
{
|
||||
config.Name = nameTextBox.Text;
|
||||
flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
}
|
||||
|
||||
flags |= UpdateDifferent(ref config.ConnStr, connStrTextBox.Text, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
flags |= UpdateDifferent(ref config.ConnStr2, connStr2TextBox.Text, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
flags |= UpdateDifferent(ref config.CheckPreviousRecords, checkPreviousRecordsCheckBox.Checked, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
flags |= UpdateDifferent(ref config.SaveTracingRecords, saveTracingRecordsCheckBox.Checked, CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
|
||||
/// Network adapter
|
||||
string strAdapter = netAdapterComboBox.Text;
|
||||
int iDash = strAdapter.IndexOf(" - ");
|
||||
string netAdapter = (iDash < 0) ? "" : strAdapter.Substring(iDash + 3);
|
||||
if (config.NetAdapter != netAdapter)
|
||||
{
|
||||
config.NetAdapter = netAdapter;
|
||||
flags |= (CfgUpdateFlags.AnyChange | CfgUpdateFlags.RestartRqrd);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
///
|
||||
/// Copyright (c) 2018 Sensus Slovensko a.s.
|
||||
///
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
partial class WriteDbCfgCtrl
|
||||
{
|
||||
/// <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.nameTextBox = new System.Windows.Forms.TextBox();
|
||||
this.nameLabel = new System.Windows.Forms.Label();
|
||||
this.classNameLabel = new System.Windows.Forms.Label();
|
||||
this.connStrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.connStrLabel = new System.Windows.Forms.Label();
|
||||
this.saveTracingRecordsCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.checkPreviousRecordsCheckBox = new System.Windows.Forms.CheckBox();
|
||||
this.netAdapterLabel = new System.Windows.Forms.Label();
|
||||
this.netAdapterComboBox = new System.Windows.Forms.ComboBox();
|
||||
this.connStr2TextBox = new System.Windows.Forms.TextBox();
|
||||
this.connStr2Label = new System.Windows.Forms.Label();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(117, 32);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(326, 20);
|
||||
this.nameTextBox.TabIndex = 2;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(5, 35);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(38, 13);
|
||||
this.nameLabel.TabIndex = 1;
|
||||
this.nameLabel.Text = "Name:";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(114, 10);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
|
||||
this.classNameLabel.TabIndex = 0;
|
||||
this.classNameLabel.Text = "ComonentName";
|
||||
//
|
||||
// connStrTextBox
|
||||
//
|
||||
this.connStrTextBox.Enabled = false;
|
||||
this.connStrTextBox.Location = new System.Drawing.Point(8, 74);
|
||||
this.connStrTextBox.Name = "connStrTextBox";
|
||||
this.connStrTextBox.Size = new System.Drawing.Size(435, 20);
|
||||
this.connStrTextBox.TabIndex = 4;
|
||||
//
|
||||
// connStrLabel
|
||||
//
|
||||
this.connStrLabel.AutoSize = true;
|
||||
this.connStrLabel.Location = new System.Drawing.Point(5, 58);
|
||||
this.connStrLabel.Name = "connStrLabel";
|
||||
this.connStrLabel.Size = new System.Drawing.Size(92, 13);
|
||||
this.connStrLabel.TabIndex = 3;
|
||||
this.connStrLabel.Text = "Connection string:";
|
||||
//
|
||||
// saveTracingRecordsCheckBox
|
||||
//
|
||||
this.saveTracingRecordsCheckBox.AutoSize = true;
|
||||
this.saveTracingRecordsCheckBox.Enabled = false;
|
||||
this.saveTracingRecordsCheckBox.Location = new System.Drawing.Point(117, 221);
|
||||
this.saveTracingRecordsCheckBox.Name = "saveTracingRecordsCheckBox";
|
||||
this.saveTracingRecordsCheckBox.Size = new System.Drawing.Size(177, 17);
|
||||
this.saveTracingRecordsCheckBox.TabIndex = 10;
|
||||
this.saveTracingRecordsCheckBox.Text = "Save production tracing records";
|
||||
this.saveTracingRecordsCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// checkPreviousRecordsCheckBox
|
||||
//
|
||||
this.checkPreviousRecordsCheckBox.AutoSize = true;
|
||||
this.checkPreviousRecordsCheckBox.Enabled = false;
|
||||
this.checkPreviousRecordsCheckBox.Location = new System.Drawing.Point(117, 199);
|
||||
this.checkPreviousRecordsCheckBox.Name = "checkPreviousRecordsCheckBox";
|
||||
this.checkPreviousRecordsCheckBox.Size = new System.Drawing.Size(138, 17);
|
||||
this.checkPreviousRecordsCheckBox.TabIndex = 9;
|
||||
this.checkPreviousRecordsCheckBox.Text = "Check previous records";
|
||||
this.checkPreviousRecordsCheckBox.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// netAdapterLabel
|
||||
//
|
||||
this.netAdapterLabel.AutoSize = true;
|
||||
this.netAdapterLabel.Location = new System.Drawing.Point(5, 147);
|
||||
this.netAdapterLabel.Name = "netAdapterLabel";
|
||||
this.netAdapterLabel.Size = new System.Drawing.Size(89, 13);
|
||||
this.netAdapterLabel.TabIndex = 7;
|
||||
this.netAdapterLabel.Text = "Network adapter:";
|
||||
//
|
||||
// netAdapterComboBox
|
||||
//
|
||||
this.netAdapterComboBox.Enabled = false;
|
||||
this.netAdapterComboBox.FormattingEnabled = true;
|
||||
this.netAdapterComboBox.Location = new System.Drawing.Point(8, 163);
|
||||
this.netAdapterComboBox.Name = "netAdapterComboBox";
|
||||
this.netAdapterComboBox.Size = new System.Drawing.Size(435, 21);
|
||||
this.netAdapterComboBox.TabIndex = 8;
|
||||
//
|
||||
// connStr2TextBox
|
||||
//
|
||||
this.connStr2TextBox.Enabled = false;
|
||||
this.connStr2TextBox.Location = new System.Drawing.Point(8, 118);
|
||||
this.connStr2TextBox.Name = "connStr2TextBox";
|
||||
this.connStr2TextBox.Size = new System.Drawing.Size(434, 20);
|
||||
this.connStr2TextBox.TabIndex = 6;
|
||||
//
|
||||
// connStr2Label
|
||||
//
|
||||
this.connStr2Label.AutoSize = true;
|
||||
this.connStr2Label.Location = new System.Drawing.Point(5, 102);
|
||||
this.connStr2Label.Name = "connStr2Label";
|
||||
this.connStr2Label.Size = new System.Drawing.Size(101, 13);
|
||||
this.connStr2Label.TabIndex = 5;
|
||||
this.connStr2Label.Text = "Connection string 2:";
|
||||
//
|
||||
// TracingCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.connStr2TextBox);
|
||||
this.Controls.Add(this.connStr2Label);
|
||||
this.Controls.Add(this.netAdapterComboBox);
|
||||
this.Controls.Add(this.netAdapterLabel);
|
||||
this.Controls.Add(this.saveTracingRecordsCheckBox);
|
||||
this.Controls.Add(this.checkPreviousRecordsCheckBox);
|
||||
this.Controls.Add(this.connStrTextBox);
|
||||
this.Controls.Add(this.connStrLabel);
|
||||
this.Controls.Add(this.nameTextBox);
|
||||
this.Controls.Add(this.nameLabel);
|
||||
this.Controls.Add(this.classNameLabel);
|
||||
this.Name = "WriteDbCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(450, 250);
|
||||
this.Load += new System.EventHandler(this.WriterCfgCtrl_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox nameTextBox;
|
||||
private System.Windows.Forms.Label nameLabel;
|
||||
private System.Windows.Forms.Label classNameLabel;
|
||||
private System.Windows.Forms.TextBox connStrTextBox;
|
||||
private System.Windows.Forms.Label connStrLabel;
|
||||
private System.Windows.Forms.CheckBox saveTracingRecordsCheckBox;
|
||||
private System.Windows.Forms.CheckBox checkPreviousRecordsCheckBox;
|
||||
private System.Windows.Forms.Label netAdapterLabel;
|
||||
private System.Windows.Forms.ComboBox netAdapterComboBox;
|
||||
private System.Windows.Forms.TextBox connStr2TextBox;
|
||||
private System.Windows.Forms.Label connStr2Label;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
///
|
||||
/// Copyright (c) 2018 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Serialization;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
///
|
||||
/// Class and file name is preserved for backward compatibility
|
||||
///
|
||||
public class WriterCfg : ComponentCfgBase, Generic.IComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(WriterCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new WriteDbCfgCtrl(); }
|
||||
|
||||
|
||||
public string ConnStr;
|
||||
public string ConnStr2;
|
||||
public string NetAdapter;
|
||||
public bool CheckPreviousRecords;
|
||||
public bool SaveTracingRecords;
|
||||
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
WriterCfg()
|
||||
{
|
||||
ParentName = string.Empty;
|
||||
NetAdapter = string.Empty;
|
||||
ConnStr = "server=10.42.128.24; database=sledovanie2020; uid=vyroba2020; pwd=qwerty; charset=utf8;";
|
||||
ConnStr2 = "server=10.42.128.24; database=sledovanie2019; uid=vyroba2019; pwd=qwerty; charset=utf8;";
|
||||
CheckPreviousRecords = true;
|
||||
SaveTracingRecords = true;
|
||||
}
|
||||
|
||||
public WriterCfg(string name, IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Name = name;
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return string.Format("Name={0}, CheckPrev.={1}, SaveRecords={2}, ConnStr={3}, , ConnStr2={4}",
|
||||
Name,
|
||||
CheckPreviousRecords,
|
||||
SaveTracingRecords,
|
||||
ConnStr,
|
||||
ConnStr2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,577 @@
|
||||
///
|
||||
/// Copyright (c) 2018-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using Common;
|
||||
using log4net;
|
||||
using NHibernate;
|
||||
using SharedDatabase;
|
||||
using SharedDatabase.Entities;
|
||||
using TBF.Rig.Sequences;
|
||||
|
||||
namespace TBF.Rig.Output.DB.DatabaseWriter
|
||||
{
|
||||
public enum Retv
|
||||
{
|
||||
OK,
|
||||
Error,
|
||||
}
|
||||
|
||||
class DateTimeComparer : IComparer<DateTime>
|
||||
{
|
||||
public int Compare(DateTime x, DateTime y)
|
||||
{
|
||||
return DateTime.Compare(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
public class WritingToDb : ComponentBase, IOperation, GenericDevices.IResultsWriter, GenericDevices.IStartInfoReader, Generic.IDevice
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(WritingToDb));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
||||
|
||||
public const string WorkstepName = "Test_bench";
|
||||
|
||||
public OrderInfo DefaultOrder;
|
||||
|
||||
WriterCfg tracingCfg;
|
||||
string workplace
|
||||
{
|
||||
get
|
||||
{
|
||||
TBF.Rig.GenericDevices.IBenchInfo benchInfo = TBF.Rig.Sequences.ProcessData.BenchInfo;
|
||||
return (benchInfo != null) ? benchInfo.TestBenchName : "TestBench";
|
||||
}
|
||||
}
|
||||
|
||||
IPAddress ipAddress;
|
||||
IPAddress netMask;
|
||||
public IPAddress IPAddress { get { return ipAddress; } }
|
||||
public IPAddress NetMask { get { return netMask; } }
|
||||
|
||||
enum OpState
|
||||
{
|
||||
None,
|
||||
CheckPreviousRecordsScheduled,
|
||||
CheckPreviousRecordsRunning,
|
||||
SaveTracingRecordsScheduled,
|
||||
SaveTracingRecordsRunning,
|
||||
}
|
||||
///
|
||||
OpState currentOpState;
|
||||
bool opCompleted;
|
||||
bool anyError;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Watermeters to check at the beginning of the cycle
|
||||
/// </summary>
|
||||
IList<Results.Entities.WaterMeter> waterMeters;
|
||||
|
||||
/// <summary>
|
||||
/// Data (tracing records) to write at the end of cycle
|
||||
/// </summary>
|
||||
Results.Entities.Batch batch;
|
||||
|
||||
public ISessionFactory SessionFactory; /// Factory to create database sessions that is initialized in the constructor
|
||||
|
||||
|
||||
public WritingToDb() {}
|
||||
|
||||
public WritingToDb(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
tracingCfg = cfg as WriterCfg;
|
||||
if (tracingCfg == null) throw new ArgumentException("tracingCfg");
|
||||
|
||||
Network.AdapterInfo.RefreshNetAdaptersInfo();
|
||||
Network.AdapterInfo netadapter = Network.AdapterInfo.GetNetAdapter(tracingCfg.NetAdapter);
|
||||
ipAddress = netadapter.IPAddress;
|
||||
|
||||
netMask = netadapter.NetMask;
|
||||
currentOpState = OpState.None;
|
||||
log.Warn(this.ToString());
|
||||
|
||||
DefaultOrder = null;
|
||||
}
|
||||
|
||||
///
|
||||
/// IDevice interface implementation
|
||||
///
|
||||
public override void Initialize()
|
||||
{
|
||||
if (tracingCfg.DebugLevel == DebugMode.Simulate) return;
|
||||
|
||||
string ipAddress = GetIPAddress();
|
||||
|
||||
///
|
||||
/// Session factory is used to create database sessions
|
||||
///
|
||||
SharedDatabase.TracingDB.SessionFactory = this.SessionFactory =
|
||||
FluentNHibernate.Cfg.Fluently.Configure()
|
||||
.Database(FluentNHibernate.Cfg.Db.MySQLConfiguration.Standard.ConnectionString(tracingCfg.ConnStr))
|
||||
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Process>())
|
||||
.ExposeConfiguration(SharedDatabase.TracingDB.BuildSchema)
|
||||
.BuildSessionFactory();
|
||||
|
||||
try
|
||||
{
|
||||
using (var session = SessionFactory.OpenSession())
|
||||
{
|
||||
///
|
||||
/// Initialize DefaultOrder
|
||||
///
|
||||
var dfltOrders = session.QueryOver<OrderInfo>()
|
||||
.Where(x => x.POName == "0000001")
|
||||
.And(x => (x.POState == (sbyte)OrderState.New || x.POState == (sbyte)OrderState.Active))
|
||||
.List();
|
||||
if (dfltOrders.Count > 0) DefaultOrder = dfltOrders[0];
|
||||
|
||||
#if !DEBUG
|
||||
///
|
||||
/// Register this test bench in the tracing DB for approx. 2 weeks (RELEASE version only)
|
||||
///
|
||||
SharedDatabase.TracingDB.RegisterWorkplaceObsolete(session,
|
||||
workplace,
|
||||
CurrentUser.UserName(),
|
||||
GetIPAddress(),
|
||||
"<multiple>",
|
||||
WorkstepName,
|
||||
DateTime.Now + new TimeSpan(15, 0, 0, 0));
|
||||
session.Flush();
|
||||
#endif
|
||||
session.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.ErrorFormat("Cannot load a default order from a database or regster this workplace: {0}", ex);
|
||||
DefaultOrder = null;
|
||||
}
|
||||
}
|
||||
///
|
||||
string GetIPAddress()
|
||||
{
|
||||
return (ipAddress != null) ? ipAddress.ToString() : "1.2.3.4";
|
||||
}
|
||||
///
|
||||
public void RunDeviceBefore() { }
|
||||
public void RunDeviceAfter() { }
|
||||
///
|
||||
public void StopDevice()
|
||||
{
|
||||
if (tracingCfg.DebugLevel != DebugMode.Normal) return;
|
||||
|
||||
using (ISession session = SessionFactory.OpenSession())
|
||||
{
|
||||
SharedDatabase.TracingDB.UnregisterWorkplaceObsolete(session, workplace);
|
||||
session.Flush();
|
||||
}
|
||||
}
|
||||
public void StopDevice2() {}
|
||||
|
||||
public IList<OrderInfo> ReadOrders()
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var session = SessionFactory.OpenSession())
|
||||
{
|
||||
var result = session.QueryOver<OrderInfo>()
|
||||
.Where(x => (x.POState == (sbyte)OrderState.New || x.POState == (sbyte)OrderState.Active))
|
||||
.List();
|
||||
session.Close();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.ErrorFormat("ReadOrders() failed: {0}", ex.Message);
|
||||
return new List<OrderInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read reference records belonging to a specified order.
|
||||
/// Used when retrieving housing S/N-s belonging to obtained eRegister numbers.
|
||||
/// </summary>
|
||||
/// <param name="session">DB sesson</param>
|
||||
/// <param name="order">Order</param>
|
||||
/// <returns>List of reference records-s</returns>
|
||||
public IList<ReferenceRecord> ReadRefRecords(ISession session, OrderInfo order, OrderInfo dfltOrder = null, Process dfltWFlow = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var refRecords = session.QueryOver<ReferenceRecord>()
|
||||
.Where(x => (x.POName == order.POName))
|
||||
.List();
|
||||
refRecords.Reverse();
|
||||
|
||||
if (dfltOrder != null && dfltWFlow != null)
|
||||
{
|
||||
var moreRecords = session.QueryOver<ReferenceRecord>()
|
||||
.Where(x => (x.POName == dfltOrder.POName))
|
||||
.And(x => (x.Workflow == dfltWFlow.Name))
|
||||
.List();
|
||||
for (int i = moreRecords.Count - 1; i >= 0; i--) refRecords.Add(moreRecords[i]);
|
||||
}
|
||||
|
||||
return refRecords;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Cannot read ref.records from the tracing DB: {0}", exc.Message);
|
||||
return new List<ReferenceRecord>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Read records belonging to a specified order
|
||||
/// </summary>
|
||||
/// <param name="session">DB sesson</param>
|
||||
/// <param name="order">Order</param>
|
||||
/// <returns>List of records</returns>
|
||||
public IList<Record> ReadRecords(ISession session, OrderInfo order, OrderInfo dfltOrder = null, Process dfltWFlow = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var records = session.QueryOver<Record>()
|
||||
.JoinQueryOver<ReferenceRecord>(rec => rec.ReferenceRecord)
|
||||
.Where(rr => rr.POName == order.POName)
|
||||
.List();
|
||||
records.Reverse();
|
||||
|
||||
if (dfltOrder != null && dfltWFlow != null)
|
||||
{
|
||||
var moreRecords = session.QueryOver<Record>()
|
||||
.JoinQueryOver<ReferenceRecord>(rec => rec.ReferenceRecord)
|
||||
.Where(rr => (rr.POName == dfltOrder.POName))
|
||||
.And(rr => (rr.Workflow == dfltWFlow.Name))
|
||||
.List();
|
||||
for (int i = moreRecords.Count - 1; i >= 0; i--) records.Add(moreRecords[i]);
|
||||
}
|
||||
|
||||
return records;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Cannot read records from the tracing DB: {0}", exc.Message);
|
||||
return new List<Record>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads information on start of a cycle, Events: Event.InfoRead
|
||||
/// </summary>
|
||||
/// <param name="waterMeters">Results of water meters</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ReadStartInfoOp(IList<Results.Entities.WaterMeter> waterMeters)
|
||||
{
|
||||
if (!tracingCfg.CheckPreviousRecords)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if ((currentOpState == OpState.CheckPreviousRecordsRunning) || (currentOpState == OpState.SaveTracingRecordsRunning))
|
||||
{
|
||||
throw new Exception("Sequence error");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.waterMeters = waterMeters;
|
||||
currentOpState = OpState.CheckPreviousRecordsScheduled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the test cycle results into a file, Events: Event.ResultsWritten
|
||||
/// </summary>
|
||||
/// <param name="procedure">Procedure to print the results of</param>
|
||||
/// <param name="unsortedResults">Results to write into the file</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ProcessResultsOp(Results.Entities.Batch batch)
|
||||
{
|
||||
if (!tracingCfg.SaveTracingRecords)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if ((currentOpState == OpState.CheckPreviousRecordsRunning) || (currentOpState == OpState.SaveTracingRecordsRunning))
|
||||
{
|
||||
throw new Exception("Sequence error");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.batch = batch;
|
||||
currentOpState = OpState.SaveTracingRecordsScheduled;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
if (currentOpState == OpState.CheckPreviousRecordsScheduled)
|
||||
{
|
||||
currentOpState = OpState.CheckPreviousRecordsRunning;
|
||||
}
|
||||
else if (currentOpState == OpState.SaveTracingRecordsScheduled)
|
||||
{
|
||||
currentOpState = OpState.SaveTracingRecordsRunning;
|
||||
}
|
||||
|
||||
opCompleted = false;
|
||||
anyError = false;
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>Event.ResultsWritten or Event.Error</returns>
|
||||
public Event Run()
|
||||
{
|
||||
log.WarnFormat("{0} : Run() : currentOp = {1}", Name, currentOpState);
|
||||
|
||||
if (currentOpState == OpState.CheckPreviousRecordsRunning)
|
||||
{
|
||||
if (tracingCfg.DebugLevel == DebugMode.Simulate) return Event.InfoRead;
|
||||
if (opCompleted) return anyError ? Event.InfoNotRead : Event.InfoRead;
|
||||
|
||||
/// Run once
|
||||
opCompleted = true;
|
||||
if (CheckPreviousRecords(waterMeters) != Retv.OK) anyError = true;
|
||||
return anyError ? Event.InfoNotRead : Event.InfoRead;
|
||||
}
|
||||
|
||||
if (currentOpState == OpState.SaveTracingRecordsRunning)
|
||||
{
|
||||
if (tracingCfg.DebugLevel == DebugMode.Simulate || batch.WaterMeters.Count == 0) return Event.ResultsWritten;
|
||||
if (opCompleted) return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
|
||||
|
||||
/// Run once
|
||||
opCompleted = true;
|
||||
if (SaveTracingRecords(batch) != Retv.OK) anyError = true;
|
||||
|
||||
if (anyError && !string.IsNullOrEmpty(SharedDatabase.EventsDB.ConnectionString))
|
||||
{
|
||||
try
|
||||
{
|
||||
NHibernate.ISession session = SharedDatabase.EventsDB.CreateSession();
|
||||
SharedDatabase.EventsDB.LoadSubscribers(session);
|
||||
|
||||
TBF.UiBridge.Bridge.TriggerEvent(session, Name, EventClass.ComputerResources, Severity.Error,
|
||||
string.Format("Nepodarilo sa uložiť výsledky do sledovacej DB: Číslo dávky={0}", batch.BatchNr),
|
||||
string.Format("Nepodarilo sa uložiť výsledky do sledovacej DB\r\nČíslo dávky = {0}", batch.BatchNr),
|
||||
SubscriberGroup.Metrology | SubscriberGroup.Maintenance | SubscriberGroup.Production);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Triggering event(s) failed: {0}", exc.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return anyError ? Event.ErrorProcessingResults : Event.ResultsWritten;
|
||||
}
|
||||
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
currentOpState = OpState.None;
|
||||
}
|
||||
|
||||
|
||||
Retv CheckPreviousRecords(IList<Results.Entities.WaterMeter> waterMeters)
|
||||
{
|
||||
Retv retVal = Retv.Error;
|
||||
|
||||
var sampleWM = waterMeters.FirstOrDefault<Results.Entities.WaterMeter>(x => x != null && x.Disabled == false);
|
||||
if (sampleWM != null)
|
||||
{
|
||||
using (ISession session = SessionFactory.OpenSession())
|
||||
{
|
||||
for (int i = 0; i < waterMeters.Count; i++)
|
||||
{
|
||||
Results.Entities.WaterMeter wm = waterMeters[i];
|
||||
|
||||
if ((wm != null) && !wm.Disabled)
|
||||
{
|
||||
CheckPreviousRecordOfSingleWM(session, wm);
|
||||
}
|
||||
}
|
||||
|
||||
retVal = Retv.OK; /// Successfully completed (regardless of wm.LastRecordIsNok)
|
||||
}
|
||||
}
|
||||
|
||||
return retVal; /// Returns Retv.Error if checking not completed successfully
|
||||
}
|
||||
|
||||
|
||||
Retv CheckPreviousRecordOfSingleWM(ISession session, Results.Entities.WaterMeter wm)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(wm.SerialNr) && ProcessData.WorkflowSummary != null)
|
||||
{
|
||||
/// Get all reference records with Code == SerialNr from all worksteps different from 'Test_bench'
|
||||
var refRecords = session.QueryOver<ReferenceRecord>()
|
||||
.Where(rr => (rr.Code1 == wm.SerialNr))
|
||||
.List();
|
||||
|
||||
if (refRecords.Count == 1)
|
||||
{
|
||||
ReferenceRecord refRecord = refRecords[0];
|
||||
StepRecord previousStep = string.IsNullOrEmpty(ProcessData.WorkflowSummary.PreviousWorkstepName) ? null
|
||||
: refRecord.StepRecords.FirstOrDefault(x => x.Workstep == ProcessData.WorkflowSummary.PreviousWorkstepName);
|
||||
|
||||
if (refRecord.Name1 == ProcessData.WorkflowSummary.Part1Name &&
|
||||
refRecord.Name2 == ProcessData.WorkflowSummary.Part2Name &&
|
||||
(ProcessData.WorkflowSummary.PreviousWorkstepName == null ||
|
||||
(previousStep != null && previousStep.Workstep == ProcessData.WorkflowSummary.PreviousWorkstepName)))
|
||||
{
|
||||
wm.Workflow = ProcessData.WorkflowSummary.Workflow.Name;
|
||||
wm.LastRecordIsNok = false; /// OK
|
||||
return Retv.OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// S/N is missing OR no records found OR workflows do not match OR previous StepRecord is missing
|
||||
wm.Workflow = string.Empty;
|
||||
wm.LastRecordIsNok = true; /// NOK
|
||||
return Retv.OK;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Write results of a batch of water meters to the DB
|
||||
/// </summary>
|
||||
/// <param name="session">DB session</param>
|
||||
/// <param name="batch">Batch entity</param>
|
||||
Retv SaveTracingRecords(Results.Entities.Batch batch)
|
||||
{
|
||||
ITransaction transaction = null;
|
||||
ISession session = null;
|
||||
|
||||
var order = ProcessData.OrderInfo as SharedDatabase.Entities.OrderInfo;
|
||||
if (order != null && ProcessData.WorkflowSummary != null && !string.IsNullOrEmpty(ProcessData.WorkflowSummary.WorkstepName))
|
||||
{
|
||||
///
|
||||
/// Save to regular tracing DB
|
||||
///
|
||||
try
|
||||
{
|
||||
session = SessionFactory.OpenSession();
|
||||
transaction = session.BeginTransaction();
|
||||
|
||||
string workplace = (ProcessData.BenchInfo != null) ? ProcessData.BenchInfo.TestBenchName : "TestBench";
|
||||
int writtenRecordsCount = 0;
|
||||
foreach (var wm in batch.WaterMeters)
|
||||
{
|
||||
if (!wm.Disabled && !string.IsNullOrEmpty(wm.SerialNr))
|
||||
{
|
||||
writtenRecordsCount += SaveSingleWM2DB(session, wm, order.POName, ProcessData.WorkflowSummary, workplace);
|
||||
}
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
session.Flush();
|
||||
|
||||
log.WarnFormat("Batch {0}: {1} of {2} watermeters written to the regular production tracing DB",
|
||||
batch.BatchNr, writtenRecordsCount, batch.WaterMeters.Count);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
if (transaction != null && !transaction.WasCommitted) transaction.Rollback();
|
||||
|
||||
log.ErrorFormat("Failed to write results of batch {0} to production tracing DB: {1}",
|
||||
batch.BatchNr, exc.Message);
|
||||
|
||||
return Retv.Error;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (session != null)
|
||||
{
|
||||
session.Close();
|
||||
session.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Retv.OK;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write one meter results to the DB
|
||||
/// </summary>
|
||||
/// <param name="session">DB session</param>
|
||||
/// <param name="wm">Watermeter entity</param>
|
||||
int SaveSingleWM2DB(ISession session, Results.Entities.WaterMeter wm, string poName, WorkflowSummary wflowSummary, string worplace)
|
||||
{
|
||||
if (string.IsNullOrEmpty(wflowSummary.WorkstepName)) return 0;
|
||||
|
||||
IList<ReferenceRecord> existingRecords = session.QueryOver<ReferenceRecord>()
|
||||
.Where(x => (x.Code1 == wm.SerialNr))
|
||||
.List();
|
||||
if (existingRecords.Count > 1)
|
||||
{
|
||||
/// Unexpected error
|
||||
log.ErrorFormat("Multiple reference records exist: Code1 = {0}", wm.SerialNr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
///
|
||||
/// Reference record
|
||||
///
|
||||
ReferenceRecord refRecord = null;
|
||||
if (existingRecords.Count == 1)
|
||||
{
|
||||
/// TODO: Check if the selected worflow is the same as in the found record
|
||||
refRecord = existingRecords[0];
|
||||
|
||||
refRecord.POName = poName;
|
||||
refRecord.Workflow = wflowSummary.Workflow.Name;
|
||||
refRecord.Code2 = wm.SerialNrAux;
|
||||
refRecord.Code3 = wm.CompleteSerialNr;
|
||||
refRecord.Code4 = wm.RadioAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
refRecord = new ReferenceRecord(poName,
|
||||
wflowSummary.Workflow.Name,
|
||||
wflowSummary.Part1Name, /// PCB (iPERL) or housing (620/640) SAP number
|
||||
wm.SerialNr, /// PcbNumber (iPERL) or housing S/N (620/640)
|
||||
wflowSummary.Part2Name, /// Flowtube SAP nummber (iPERL) or "eRegister#" (640) or empty
|
||||
wm.SerialNrAux, /// Flowtube S/N (iPERL) or eRegister number (640) or empty
|
||||
wm.CompleteSerialNr, /// Complete assigned S/N
|
||||
wm.RadioAddress); /// Radio address (iPERL and 640)
|
||||
}
|
||||
|
||||
///
|
||||
/// Step record
|
||||
///
|
||||
StepRecord stepRecord = new StepRecord(refRecord,
|
||||
wflowSummary.WorkstepName,
|
||||
workplace,
|
||||
Common.CurrentUser.UserName(),
|
||||
wm.PassedFromTests() ? 0 : 1);
|
||||
if (refRecord.StepRecords == null)
|
||||
{
|
||||
refRecord.StepRecords = new List<StepRecord> { stepRecord };
|
||||
}
|
||||
else
|
||||
{
|
||||
refRecord.StepRecords.Add(stepRecord);
|
||||
}
|
||||
|
||||
session.SaveOrUpdate(refRecord);
|
||||
session.SaveOrUpdate(stepRecord);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-7
@@ -1,12 +1,10 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2021 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR
|
||||
{
|
||||
public enum MessageID
|
||||
{
|
||||
@@ -107,7 +105,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
|
||||
public enum CommunicationInterface
|
||||
{
|
||||
RFID,
|
||||
NFC
|
||||
[Description("RFID")] RFID,
|
||||
[Description("NFC")] NFC
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR
|
||||
{
|
||||
public interface IArg
|
||||
{
|
||||
int Value { get; }
|
||||
string Name { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl
|
||||
{
|
||||
public interface ICombiHeadParams
|
||||
{
|
||||
///
|
||||
/// NFC S4.5 Combihead params
|
||||
///
|
||||
public int MciTimeoutMs { get; set; }
|
||||
public int BaudRate { get; set; }
|
||||
public int DataBits { get; set; }
|
||||
public Parity ParityBit { get; set; }
|
||||
public StopBits StopBits { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl
|
||||
{
|
||||
public interface ICommunicationTimeOuts
|
||||
{
|
||||
/// Communication timeout in ms (500 .. 5000)
|
||||
public int DelayBetweenRetries { get; set; } /// Delay between communication retries in ms (0 .. 5000)
|
||||
public int MaxCommRetries { get; set; } /// Max. number of retries (1 .. 10)
|
||||
public int WaitTimeAfterFailure { get; set; } /// Wait time after communication failure in ms
|
||||
public int PassThroughWaitTime { get; set; } /// Pass Through wait time for radio parameters in ms
|
||||
public int NrThreads { get; set; } /// Numbwr of parallel threads (1, 2 or 4)
|
||||
public int CommTimeout { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl
|
||||
{
|
||||
public interface ISerialPortData
|
||||
{
|
||||
|
||||
public Boolean? CliExists { get;}
|
||||
public string CmdClientName { get; set; }
|
||||
public string PortName { get; set; }
|
||||
public int MeterType { get; set; }
|
||||
public string SerialPortCmdClientPath { get; }
|
||||
public IArg MeterArg { get; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using Config.Entities;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl
|
||||
{
|
||||
public interface ITestMethodCfg : IComponentCfg, ICommunicationTimeOuts, ICombiHeadParams, IWebService
|
||||
{
|
||||
|
||||
public abstract IComponentCfgCtrl GetControl(IList<Component> cmpntEntities);
|
||||
public abstract string ToString(int i);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl
|
||||
{
|
||||
public interface IWebService
|
||||
{
|
||||
public bool UseWebService { get; set; }
|
||||
public string BaseUrl { get; set; }
|
||||
public string RelativeUrl { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.IO.Ports;
|
||||
using System.Xml.Serialization;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl
|
||||
{
|
||||
public interface IiPerlTestMethodCfg : ITestMethodCfg
|
||||
{
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
|
||||
|
||||
|
||||
public int IperlCheckErrorsToStop { get; set; }
|
||||
|
||||
|
||||
|
||||
public int DfltQ2c_15_rl { get; set; }
|
||||
public int DfltQ2c_15_lr { get; set; }
|
||||
public int DfltQ2c_20_rl { get; set; }
|
||||
public int DfltQ2c_20_lr { get; set; }
|
||||
public int DfltQ2c_25_63_rl { get; set; }
|
||||
public int DfltQ2c_25_63_lr { get; set; }
|
||||
public int DfltQ2c_25_10_rl { get; set; }
|
||||
public int DfltQ2c_25_10_lr { get; set; }
|
||||
public int DfltQ2c_32_rl { get; set; }
|
||||
public int DfltQ2c_32_lr { get; set; }
|
||||
public int DfltQ2c_40_rl { get; set; }
|
||||
public int DfltQ2c_40_lr { get; set; }
|
||||
|
||||
public bool UseWebService { get; set; }
|
||||
public string BaseUrl { get; set; }
|
||||
public string RelativeUrl { get; set; }
|
||||
|
||||
/// <summary> Test parameters </summary>
|
||||
/// Remember to Ignore in XmlSerializer !!
|
||||
[XmlIgnore]
|
||||
public ITestParams TestParams { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Sensus.iPerl.RfidCom.Structures;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl;
|
||||
|
||||
namespace NfcC7_DLL.NfcHanler.Utils
|
||||
{
|
||||
public class SerialPortData : ISerialPortData
|
||||
{
|
||||
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 class EMeterArg : IArg{
|
||||
public int Value { get; }
|
||||
public string Name { get; }
|
||||
|
||||
private EMeterArg(int value, string name)
|
||||
{
|
||||
Value = value;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public static readonly EMeterArg Calibration = new EMeterArg(0, "Calibration");
|
||||
public static readonly EMeterArg AllParams = new EMeterArg(2, "AllParams");
|
||||
public static readonly EMeterArg DeviceId = new EMeterArg(3, "DeviceId");
|
||||
public static readonly EMeterArg OptoHead = new EMeterArg(4, "OptoHead");
|
||||
|
||||
}
|
||||
|
||||
public IArg MeterArg { get{return _eMeterArg;} }
|
||||
|
||||
EMeterArg _eMeterArg = EMeterArg.AllParams;
|
||||
|
||||
private static readonly Dictionary<EMeterArg, string> _commandsRead = new Dictionary<EMeterArg, string>
|
||||
{
|
||||
{ EMeterArg.AllParams, "-p {0} -m {1} --operation readall" },
|
||||
{ EMeterArg.DeviceId, "-p {0} -m {1} --operation read --parameter DeviceId" },
|
||||
{ EMeterArg.OptoHead, "-p {0} -m {1} --operation read --parameter \"OpticalDataMode\"" }
|
||||
};
|
||||
|
||||
public string DefaultArgSettingsRead(IArg eMeterArg)
|
||||
{
|
||||
EMeterArg meterArg = eMeterArg as EMeterArg;
|
||||
if (meterArg != null && _commandsRead.TryGetValue(meterArg, out var cmd))
|
||||
return string.Format(cmd, PortName, MeterType);
|
||||
|
||||
throw new Exception("Not implemented correct command!");
|
||||
}
|
||||
|
||||
private static readonly Dictionary<EMeterArg, string> _commandsWrite = new Dictionary<EMeterArg, string>
|
||||
{
|
||||
{ EMeterArg.Calibration, "-p {0} -m {1} --operation write --parameter Calibration --value {2}" },
|
||||
{ EMeterArg.OptoHead, "-p {0} -m {1} --operation write --parameter \"OpticalDataMode\" --value {arg}" },
|
||||
|
||||
};
|
||||
|
||||
public string DefaultArgSettingsWrite(IArg eMeterArg, string arg)
|
||||
{
|
||||
EMeterArg meterArg = eMeterArg as EMeterArg;
|
||||
if (meterArg != null && _commandsRead.TryGetValue(meterArg, out var cmd))
|
||||
return string.Format(cmd, PortName, MeterType);
|
||||
|
||||
throw new Exception("Not implemented correct command!");
|
||||
}
|
||||
|
||||
public SerialPortData(
|
||||
string portName,
|
||||
string cmdClientName,
|
||||
int meterType)
|
||||
{
|
||||
PortName = portName;
|
||||
CmdClientName = cmdClientName;
|
||||
MeterType = meterType;
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2020 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
public class CalibrationStruct
|
||||
{
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
///
|
||||
/// Copyright (c) 2018-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
public class CalibrationStructV4
|
||||
{
|
||||
@@ -0,0 +1,43 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2019 Sensus Metering Systems
|
||||
/// Author: Milan Hanajík
|
||||
///
|
||||
|
||||
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
|
||||
{
|
||||
public class CommCompletedEventArgs : EventArgs
|
||||
{
|
||||
public int ThreadId;
|
||||
public int WMNr0; /// 0-based water meter position
|
||||
public ISmartReader Ihead;
|
||||
public Results.Entities.WaterMeter Wm;
|
||||
public string CommMessage;
|
||||
public CommErr CommErr;
|
||||
|
||||
public CommCompletedEventArgs(int threadId, int wmNr0, ISmartReader ihead, Results.Entities.WaterMeter wm, string commMessage, CommErr commErr)
|
||||
{
|
||||
this.ThreadId = threadId;
|
||||
this.WMNr0 = wmNr0;
|
||||
this.Ihead = ihead;
|
||||
this.Wm = wm;
|
||||
this.CommMessage = commMessage;
|
||||
this.CommErr = commErr;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Thread={0} WMNr0={1} IHead={2} WM={3} CommMsg={4} CommErr={5}",
|
||||
ThreadId,
|
||||
WMNr0,
|
||||
(Ihead != null) ? Ihead.Name : "null",
|
||||
Wm.WMPosition,
|
||||
(CommMessage != null) ? CommMessage : "null",
|
||||
CommErr);
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -1,10 +1,11 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2020 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
public class ConfigStruct
|
||||
{
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
public class IPerlCommunicationsTimeOut : ICommunicationTimeOuts
|
||||
{
|
||||
public int DelayBetweenRetries { get; set; }
|
||||
public int MaxCommRetries { get; set; }
|
||||
public int WaitTimeAfterFailure { get; set; }
|
||||
public int PassThroughWaitTime { get; set; }
|
||||
public int NrThreads { get; set; }
|
||||
public int CommTimeout { get; set; }
|
||||
}
|
||||
}
|
||||
+10
-9
@@ -1,19 +1,20 @@
|
||||
using log4net;
|
||||
using Sensus.iPerl.NfcHandler;
|
||||
using Sensus.iPerl.RfidCom.Exceptions;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using Sensus.iPerl.NfcHandler;
|
||||
using Sensus.iPerl.RfidCom.Exceptions;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
using static Sensus.iPerl.NfcHandler.MCI_Protocol;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.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)
|
||||
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++)
|
||||
{
|
||||
@@ -58,7 +59,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
return 3;
|
||||
}
|
||||
|
||||
internal static int WriteRequest(TestMethodCfg cfg, IPerlReader 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);
|
||||
@@ -84,7 +85,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
}
|
||||
}
|
||||
|
||||
private static void OpenConnection(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, IPerlReader iperlHead)
|
||||
private static void OpenConnection(NfcDataHandler nfcDataHandler, ITestMethodCfg cfg, ISmartReader iperlHead)
|
||||
{
|
||||
string comPort = $"COM{iperlHead.RfidComPortNr}";
|
||||
int retryCount = 0 ;
|
||||
@@ -128,7 +129,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
nfcDataHandler.Close();
|
||||
}
|
||||
|
||||
private static byte[] MciRead(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, StructName structName, ushort offset, int length)
|
||||
private static byte[] MciRead(NfcDataHandler nfcDataHandler, ITestMethodCfg cfg, StructName structName, ushort offset, int length)
|
||||
{
|
||||
bool isReadValues = false;
|
||||
int retryCount = 0;
|
||||
@@ -175,7 +176,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
return new byte[length];
|
||||
}
|
||||
|
||||
private static void MciWrite(NfcDataHandler nfcDataHandler, TestMethodCfg cfg, MCI_Protocol.StructName structName, ushort offset, int length, byte[] payload)
|
||||
private static void MciWrite(NfcDataHandler nfcDataHandler, ITestMethodCfg cfg, MCI_Protocol.StructName structName, ushort offset, int length, byte[] payload)
|
||||
{
|
||||
int retryCount = 0;
|
||||
Write:
|
||||
@@ -0,0 +1,44 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
-10
@@ -1,22 +1,22 @@
|
||||
using Sensus.iPerl.RfidCom.Exceptions;
|
||||
using Sensus.iPerl.RfidCom.Helper;
|
||||
using Sensus.iPerl.RfidCom;
|
||||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using log4net;
|
||||
using TBF.Rig.Uni.SharedDialogs.iPerlCommunication;
|
||||
using static TBF.Rig.Uni.SharedDialogs.iPerlCommunication.iPerlCommunicationForm;
|
||||
using Sensus.iPerl.RfidCom;
|
||||
using Sensus.iPerl.RfidCom.Exceptions;
|
||||
using Sensus.iPerl.RfidCom.Helper;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
internal class RfidServices
|
||||
{
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm));
|
||||
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)
|
||||
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.iPerlReaderUNI.comminication
|
||||
return 3;
|
||||
}
|
||||
|
||||
internal static int WriteRequest(TestMethodCfg cfg, IPerlReader 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);
|
||||
+8
-5
@@ -1,13 +1,16 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
namespace TBF.Rig.RegisterReaders.CommonRR.IPerl.communication
|
||||
{
|
||||
internal class SimulationServices
|
||||
{
|
||||
const int Q2CorrFactorsAddr = Uni.SharedDialogs.iPerlCommunication.iPerlCommunicationConstants.Q2CorrFactorsAddr;
|
||||
const int Q2CorrFactorsAddr = iPerlCommunicationConstants.Q2CorrFactorsAddr;
|
||||
|
||||
internal static int ReadRequest(IPerlReader 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 };
|
||||
@@ -34,13 +37,13 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.comminication
|
||||
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,
|
||||
internal static int WriteRequest(ITestMethodCfg cfg, ISmartReader iperlHead, MessageID messageID, int offset,
|
||||
int length, byte[] buffer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static Array GetPCB(IPerlReader 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
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.iPerlReaderUNI;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
{
|
||||
public class IPerlCfg : ComponentCfgBase, Generic.IComponentCfg
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(IPerlCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
public IComponentCfgCtrl GetControl(IList<Component> cmpntEntities)
|
||||
{
|
||||
return new IPerlUniCfgCtrl();
|
||||
}
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public bool UseTcpIP;
|
||||
public string OptoIPAddress;
|
||||
public ushort OptoTcpipPortNr;
|
||||
public int HeadCommunicationComPortNr;
|
||||
public int OptoComPortNr;
|
||||
public int RfidComPortNr; /// 0 = use MuxBoardNr
|
||||
public int MuxBoardNr; /// 0 = use RfidComPort(Nr), otherwise mux. board nr. 1 .. 4
|
||||
public int Group; /// Number written to QuidoRS to connct the watermeter to RfidComPort, 1 .. 10
|
||||
public CommunicationInterface CommunicationInterface; /// Communication Interface: RFID or NFC
|
||||
|
||||
/// <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
|
||||
IPerlCfg()
|
||||
{
|
||||
Name = "iPerl";
|
||||
ParentName = string.Empty;
|
||||
OptoComPortNr = 10;
|
||||
RfidComPortNr = 0; /// = use mux. board
|
||||
MuxBoardNr = 1;
|
||||
ProcParams = CreateProcParamsProvider() as ProcParams;
|
||||
CommunicationInterface = CommunicationInterface.RFID;
|
||||
HeadCommunicationComPortNr = 0;
|
||||
}
|
||||
|
||||
public IPerlCfg(IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
this.Factory = factory;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
return $"{Name} Group1 (mux#)={MuxBoardNr}, Group2={Group}, Opto=Com{OptoComPortNr}, {CommunicationInterface}=Com{RfidComPortNr}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
{
|
||||
public partial class IPerlUniCfgCtrl : UserControl, IComponentCfgCtrl
|
||||
{
|
||||
public bool ShowMore { get { return false; } }
|
||||
|
||||
iPerlReaderUNI.IPerlCfg config;
|
||||
public IComponentCfg Config
|
||||
{
|
||||
get { return config as IComponentCfg; }
|
||||
set
|
||||
{
|
||||
config = value as iPerlReaderUNI.IPerlCfg;
|
||||
Redraw();
|
||||
}
|
||||
}
|
||||
|
||||
public IPerlUniCfgCtrl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
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();
|
||||
comboBoxCommunicationInterface.SelectedItem = config.CommunicationInterface.ToString();
|
||||
tabPage2.Controls.Add(new IperlUniHeadTestCtrl(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;
|
||||
}
|
||||
|
||||
public CfgUpdateFlags VerifyCfg(ref string message)
|
||||
{
|
||||
CfgUpdateFlags flags = CfgUpdateFlags.None;
|
||||
|
||||
int dummy;
|
||||
if (radioButton1.Checked)
|
||||
{
|
||||
IPAddress dummyIPAddress;
|
||||
if (!IPAddress.TryParse(ipAddressTextBox.Text, out dummyIPAddress))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'IP address' is not valid";
|
||||
}
|
||||
|
||||
ushort sdummy;
|
||||
if (!ushort.TryParse(tcpipPortTextBox.Text, out sdummy))
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + "'TCP/IP port nr.' is not valid";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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 (!int.TryParse(muxBoardNrTextBox.Text, out dummy) || dummy < 1 || dummy > 4)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, muxBoardNrLabel.Text);
|
||||
}
|
||||
|
||||
if (!int.TryParse(groupTextBox.Text, out dummy) || dummy < 1 || dummy > 10)
|
||||
{
|
||||
flags |= CfgUpdateFlags.Error;
|
||||
message += Environment.NewLine + string.Format(Strings.Invalid_0, groupLabel.Text);
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (radioButton1.Checked)
|
||||
{
|
||||
config.UseTcpIP = true;
|
||||
config.OptoIPAddress = ipAddressTextBox.Text;
|
||||
config.OptoTcpipPortNr = ushort.Parse(tcpipPortTextBox.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
config.UseTcpIP = false;
|
||||
config.OptoComPortNr = int.Parse(optoSerialPortTextBox.Text);
|
||||
}
|
||||
|
||||
config.RfidComPortNr = int.Parse(rfidPortNrTextBox.Text);
|
||||
config.MuxBoardNr = int.Parse(muxBoardNrTextBox.Text);
|
||||
config.Group = int.Parse(groupTextBox.Text);
|
||||
config.CommunicationInterface = (CommunicationInterface)comboBoxCommunicationInterface.SelectedIndex;
|
||||
config.HeadCommunicationComPortNr = int.Parse(headPortNrTextBox.Text);
|
||||
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,441 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
{
|
||||
partial class IPerlUniCfgCtrl
|
||||
{
|
||||
/// <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.label4 = new System.Windows.Forms.Label();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
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.tcpipPortLabel = new System.Windows.Forms.Label();
|
||||
this.tcpipPortTextBox = new System.Windows.Forms.TextBox();
|
||||
this.ipAddressLabel = new System.Windows.Forms.Label();
|
||||
this.ipAddressTextBox = new System.Windows.Forms.TextBox();
|
||||
this.radioButton1 = new System.Windows.Forms.RadioButton();
|
||||
this.radioButton2 = new System.Windows.Forms.RadioButton();
|
||||
this.optoSerialPortLabel = new System.Windows.Forms.Label();
|
||||
this.optoSerialPortTextBox = new System.Windows.Forms.TextBox();
|
||||
this.groupTextBox = new System.Windows.Forms.TextBox();
|
||||
this.groupLabel = new System.Windows.Forms.Label();
|
||||
this.muxBoardNrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.muxBoardNrLabel = new System.Windows.Forms.Label();
|
||||
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.groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.headPortNrTextBox = new System.Windows.Forms.TextBox();
|
||||
this.tabControl1.SuspendLayout();
|
||||
this.tabPage1.SuspendLayout();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.optoDataGroupBox.SuspendLayout();
|
||||
this.groupBox2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tabControl1
|
||||
//
|
||||
this.tabControl1.Controls.Add(this.tabPage1);
|
||||
this.tabControl1.Controls.Add(this.tabPage2);
|
||||
this.tabControl1.Location = new System.Drawing.Point(3, 3);
|
||||
this.tabControl1.Name = "tabControl1";
|
||||
this.tabControl1.SelectedIndex = 0;
|
||||
this.tabControl1.Size = new System.Drawing.Size(611, 432);
|
||||
this.tabControl1.TabIndex = 0;
|
||||
//
|
||||
// tabPage1
|
||||
//
|
||||
this.tabPage1.Controls.Add(this.groupBox2);
|
||||
this.tabPage1.Controls.Add(this.label4);
|
||||
this.tabPage1.Controls.Add(this.label3);
|
||||
this.tabPage1.Controls.Add(this.groupBox1);
|
||||
this.tabPage1.Controls.Add(this.optoDataGroupBox);
|
||||
this.tabPage1.Controls.Add(this.groupTextBox);
|
||||
this.tabPage1.Controls.Add(this.groupLabel);
|
||||
this.tabPage1.Controls.Add(this.muxBoardNrTextBox);
|
||||
this.tabPage1.Controls.Add(this.muxBoardNrLabel);
|
||||
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, 25);
|
||||
this.tabPage1.Name = "tabPage1";
|
||||
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage1.Size = new System.Drawing.Size(603, 403);
|
||||
this.tabPage1.TabIndex = 0;
|
||||
this.tabPage1.Text = "Config";
|
||||
this.tabPage1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(208, 101);
|
||||
this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(40, 16);
|
||||
this.label4.TabIndex = 25;
|
||||
this.label4.Text = "1 .. 10";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(208, 72);
|
||||
this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(33, 16);
|
||||
this.label3.TabIndex = 24;
|
||||
this.label3.Text = "1 .. 4";
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
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(10, 259);
|
||||
this.groupBox1.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.groupBox1.Name = "groupBox1";
|
||||
this.groupBox1.Padding = new System.Windows.Forms.Padding(4);
|
||||
this.groupBox1.Size = new System.Drawing.Size(552, 68);
|
||||
this.groupBox1.TabIndex = 23;
|
||||
this.groupBox1.TabStop = false;
|
||||
this.groupBox1.Text = "RFID / NFC communication (in case mux. board is not used)";
|
||||
//
|
||||
// comboBoxCommunicationInterface
|
||||
//
|
||||
this.comboBoxCommunicationInterface.Enabled = false;
|
||||
this.comboBoxCommunicationInterface.FormattingEnabled = true;
|
||||
this.comboBoxCommunicationInterface.Items.AddRange(new object[] {
|
||||
"RFID",
|
||||
"NFC"});
|
||||
this.comboBoxCommunicationInterface.Location = new System.Drawing.Point(201, 27);
|
||||
this.comboBoxCommunicationInterface.Name = "comboBoxCommunicationInterface";
|
||||
this.comboBoxCommunicationInterface.Size = new System.Drawing.Size(71, 24);
|
||||
this.comboBoxCommunicationInterface.TabIndex = 9;
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(41, 30);
|
||||
this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(153, 16);
|
||||
this.label1.TabIndex = 8;
|
||||
this.label1.Text = "Communication Interface";
|
||||
//
|
||||
// rfidPortNrTextBox
|
||||
//
|
||||
this.rfidPortNrTextBox.Enabled = false;
|
||||
this.rfidPortNrTextBox.Location = new System.Drawing.Point(439, 26);
|
||||
this.rfidPortNrTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.rfidPortNrTextBox.Name = "rfidPortNrTextBox";
|
||||
this.rfidPortNrTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.rfidPortNrTextBox.TabIndex = 7;
|
||||
//
|
||||
// rfidSerialPortNrLabel
|
||||
//
|
||||
this.rfidSerialPortNrLabel.AutoSize = true;
|
||||
this.rfidSerialPortNrLabel.Location = new System.Drawing.Point(321, 30);
|
||||
this.rfidSerialPortNrLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.rfidSerialPortNrLabel.Name = "rfidSerialPortNrLabel";
|
||||
this.rfidSerialPortNrLabel.Size = new System.Drawing.Size(88, 16);
|
||||
this.rfidSerialPortNrLabel.TabIndex = 6;
|
||||
this.rfidSerialPortNrLabel.Text = "Serial port nr.:";
|
||||
//
|
||||
// optoDataGroupBox
|
||||
//
|
||||
this.optoDataGroupBox.Controls.Add(this.tcpipPortLabel);
|
||||
this.optoDataGroupBox.Controls.Add(this.tcpipPortTextBox);
|
||||
this.optoDataGroupBox.Controls.Add(this.ipAddressLabel);
|
||||
this.optoDataGroupBox.Controls.Add(this.ipAddressTextBox);
|
||||
this.optoDataGroupBox.Controls.Add(this.radioButton1);
|
||||
this.optoDataGroupBox.Controls.Add(this.radioButton2);
|
||||
this.optoDataGroupBox.Controls.Add(this.optoSerialPortLabel);
|
||||
this.optoDataGroupBox.Controls.Add(this.optoSerialPortTextBox);
|
||||
this.optoDataGroupBox.Location = new System.Drawing.Point(10, 131);
|
||||
this.optoDataGroupBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.optoDataGroupBox.Name = "optoDataGroupBox";
|
||||
this.optoDataGroupBox.Padding = new System.Windows.Forms.Padding(4);
|
||||
this.optoDataGroupBox.Size = new System.Drawing.Size(552, 119);
|
||||
this.optoDataGroupBox.TabIndex = 18;
|
||||
this.optoDataGroupBox.TabStop = false;
|
||||
this.optoDataGroupBox.Text = "Opto-data";
|
||||
//
|
||||
// tcpipPortLabel
|
||||
//
|
||||
this.tcpipPortLabel.AutoSize = true;
|
||||
this.tcpipPortLabel.Location = new System.Drawing.Point(41, 87);
|
||||
this.tcpipPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.tcpipPortLabel.Name = "tcpipPortLabel";
|
||||
this.tcpipPortLabel.Size = new System.Drawing.Size(54, 16);
|
||||
this.tcpipPortLabel.TabIndex = 4;
|
||||
this.tcpipPortLabel.Text = "Port nr..:";
|
||||
//
|
||||
// tcpipPortTextBox
|
||||
//
|
||||
this.tcpipPortTextBox.Enabled = false;
|
||||
this.tcpipPortTextBox.Location = new System.Drawing.Point(143, 84);
|
||||
this.tcpipPortTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.tcpipPortTextBox.Name = "tcpipPortTextBox";
|
||||
this.tcpipPortTextBox.Size = new System.Drawing.Size(51, 22);
|
||||
this.tcpipPortTextBox.TabIndex = 5;
|
||||
//
|
||||
// ipAddressLabel
|
||||
//
|
||||
this.ipAddressLabel.AutoSize = true;
|
||||
this.ipAddressLabel.Location = new System.Drawing.Point(41, 59);
|
||||
this.ipAddressLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.ipAddressLabel.Name = "ipAddressLabel";
|
||||
this.ipAddressLabel.Size = new System.Drawing.Size(78, 16);
|
||||
this.ipAddressLabel.TabIndex = 2;
|
||||
this.ipAddressLabel.Text = "IP address.:";
|
||||
//
|
||||
// ipAddressTextBox
|
||||
//
|
||||
this.ipAddressTextBox.Enabled = false;
|
||||
this.ipAddressTextBox.Location = new System.Drawing.Point(143, 55);
|
||||
this.ipAddressTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.ipAddressTextBox.Name = "ipAddressTextBox";
|
||||
this.ipAddressTextBox.Size = new System.Drawing.Size(129, 22);
|
||||
this.ipAddressTextBox.TabIndex = 3;
|
||||
//
|
||||
// radioButton1
|
||||
//
|
||||
this.radioButton1.AutoSize = true;
|
||||
this.radioButton1.Checked = true;
|
||||
this.radioButton1.Enabled = false;
|
||||
this.radioButton1.Location = new System.Drawing.Point(29, 23);
|
||||
this.radioButton1.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.radioButton1.Name = "radioButton1";
|
||||
this.radioButton1.Size = new System.Drawing.Size(99, 20);
|
||||
this.radioButton1.TabIndex = 0;
|
||||
this.radioButton1.TabStop = true;
|
||||
this.radioButton1.Text = "Use TCP/IP";
|
||||
this.radioButton1.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// radioButton2
|
||||
//
|
||||
this.radioButton2.AutoSize = true;
|
||||
this.radioButton2.Enabled = false;
|
||||
this.radioButton2.Location = new System.Drawing.Point(312, 23);
|
||||
this.radioButton2.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.radioButton2.Name = "radioButton2";
|
||||
this.radioButton2.Size = new System.Drawing.Size(115, 20);
|
||||
this.radioButton2.TabIndex = 1;
|
||||
this.radioButton2.Text = "Use serial port";
|
||||
this.radioButton2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// optoSerialPortLabel
|
||||
//
|
||||
this.optoSerialPortLabel.AutoSize = true;
|
||||
this.optoSerialPortLabel.Location = new System.Drawing.Point(321, 55);
|
||||
this.optoSerialPortLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.optoSerialPortLabel.Name = "optoSerialPortLabel";
|
||||
this.optoSerialPortLabel.Size = new System.Drawing.Size(88, 16);
|
||||
this.optoSerialPortLabel.TabIndex = 6;
|
||||
this.optoSerialPortLabel.Text = "Serial port nr.:";
|
||||
//
|
||||
// optoSerialPortTextBox
|
||||
//
|
||||
this.optoSerialPortTextBox.Enabled = false;
|
||||
this.optoSerialPortTextBox.Location = new System.Drawing.Point(439, 52);
|
||||
this.optoSerialPortTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.optoSerialPortTextBox.Name = "optoSerialPortTextBox";
|
||||
this.optoSerialPortTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.optoSerialPortTextBox.TabIndex = 7;
|
||||
//
|
||||
// groupTextBox
|
||||
//
|
||||
this.groupTextBox.Enabled = false;
|
||||
this.groupTextBox.Location = new System.Drawing.Point(153, 97);
|
||||
this.groupTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.groupTextBox.Name = "groupTextBox";
|
||||
this.groupTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.groupTextBox.TabIndex = 22;
|
||||
//
|
||||
// groupLabel
|
||||
//
|
||||
this.groupLabel.AutoSize = true;
|
||||
this.groupLabel.Location = new System.Drawing.Point(6, 101);
|
||||
this.groupLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.groupLabel.Name = "groupLabel";
|
||||
this.groupLabel.Size = new System.Drawing.Size(54, 16);
|
||||
this.groupLabel.TabIndex = 21;
|
||||
this.groupLabel.Text = "Group 2";
|
||||
//
|
||||
// muxBoardNrTextBox
|
||||
//
|
||||
this.muxBoardNrTextBox.Enabled = false;
|
||||
this.muxBoardNrTextBox.Location = new System.Drawing.Point(153, 69);
|
||||
this.muxBoardNrTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.muxBoardNrTextBox.Name = "muxBoardNrTextBox";
|
||||
this.muxBoardNrTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.muxBoardNrTextBox.TabIndex = 20;
|
||||
//
|
||||
// muxBoardNrLabel
|
||||
//
|
||||
this.muxBoardNrLabel.AutoSize = true;
|
||||
this.muxBoardNrLabel.Location = new System.Drawing.Point(6, 72);
|
||||
this.muxBoardNrLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.muxBoardNrLabel.Name = "muxBoardNrLabel";
|
||||
this.muxBoardNrLabel.Size = new System.Drawing.Size(131, 16);
|
||||
this.muxBoardNrLabel.TabIndex = 19;
|
||||
this.muxBoardNrLabel.Text = "Group 1 (mux. board)";
|
||||
//
|
||||
// nameTextBox
|
||||
//
|
||||
this.nameTextBox.Enabled = false;
|
||||
this.nameTextBox.Location = new System.Drawing.Point(153, 40);
|
||||
this.nameTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.nameTextBox.Name = "nameTextBox";
|
||||
this.nameTextBox.Size = new System.Drawing.Size(160, 22);
|
||||
this.nameTextBox.TabIndex = 17;
|
||||
//
|
||||
// nameLabel
|
||||
//
|
||||
this.nameLabel.AutoSize = true;
|
||||
this.nameLabel.Location = new System.Drawing.Point(6, 44);
|
||||
this.nameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.nameLabel.Name = "nameLabel";
|
||||
this.nameLabel.Size = new System.Drawing.Size(44, 16);
|
||||
this.nameLabel.TabIndex = 16;
|
||||
this.nameLabel.Text = "Name";
|
||||
//
|
||||
// classNameLabel
|
||||
//
|
||||
this.classNameLabel.AutoSize = true;
|
||||
this.classNameLabel.Location = new System.Drawing.Point(149, 11);
|
||||
this.classNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.classNameLabel.Name = "classNameLabel";
|
||||
this.classNameLabel.Size = new System.Drawing.Size(78, 16);
|
||||
this.classNameLabel.TabIndex = 15;
|
||||
this.classNameLabel.Text = "ClassName";
|
||||
//
|
||||
// tabPage2
|
||||
//
|
||||
this.tabPage2.Location = new System.Drawing.Point(4, 25);
|
||||
this.tabPage2.Name = "tabPage2";
|
||||
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
|
||||
this.tabPage2.Size = new System.Drawing.Size(603, 403);
|
||||
this.tabPage2.TabIndex = 1;
|
||||
this.tabPage2.Text = "Test";
|
||||
this.tabPage2.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
this.groupBox2.Controls.Add(this.headPortNrTextBox);
|
||||
this.groupBox2.Controls.Add(this.label2);
|
||||
this.groupBox2.Location = new System.Drawing.Point(10, 335);
|
||||
this.groupBox2.Name = "groupBox2";
|
||||
this.groupBox2.Size = new System.Drawing.Size(552, 50);
|
||||
this.groupBox2.TabIndex = 26;
|
||||
this.groupBox2.TabStop = false;
|
||||
this.groupBox2.Text = "Head Communication";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(321, 18);
|
||||
this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(88, 16);
|
||||
this.label2.TabIndex = 7;
|
||||
this.label2.Text = "Serial port nr.:";
|
||||
//
|
||||
// headPortNrTextBox
|
||||
//
|
||||
this.headPortNrTextBox.Enabled = false;
|
||||
this.headPortNrTextBox.Location = new System.Drawing.Point(439, 15);
|
||||
this.headPortNrTextBox.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.headPortNrTextBox.Name = "headPortNrTextBox";
|
||||
this.headPortNrTextBox.Size = new System.Drawing.Size(44, 22);
|
||||
this.headPortNrTextBox.TabIndex = 8;
|
||||
//
|
||||
// IperlHeadCfgCtrl
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.tabControl1);
|
||||
this.Margin = new System.Windows.Forms.Padding(4);
|
||||
this.Name = "IPerlUniCfgCtrl";
|
||||
this.Size = new System.Drawing.Size(617, 438);
|
||||
this.Load += new System.EventHandler(this.WaterMeterCfgCtrl_Load);
|
||||
this.tabControl1.ResumeLayout(false);
|
||||
this.tabPage1.ResumeLayout(false);
|
||||
this.tabPage1.PerformLayout();
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.groupBox1.PerformLayout();
|
||||
this.optoDataGroupBox.ResumeLayout(false);
|
||||
this.optoDataGroupBox.PerformLayout();
|
||||
this.groupBox2.ResumeLayout(false);
|
||||
this.groupBox2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TabControl tabControl1;
|
||||
private System.Windows.Forms.TabPage tabPage1;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private System.Windows.Forms.Label label3;
|
||||
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 tcpipPortLabel;
|
||||
private System.Windows.Forms.TextBox tcpipPortTextBox;
|
||||
private System.Windows.Forms.Label ipAddressLabel;
|
||||
private System.Windows.Forms.TextBox ipAddressTextBox;
|
||||
private System.Windows.Forms.RadioButton radioButton1;
|
||||
private System.Windows.Forms.RadioButton radioButton2;
|
||||
private System.Windows.Forms.Label optoSerialPortLabel;
|
||||
private System.Windows.Forms.TextBox optoSerialPortTextBox;
|
||||
private System.Windows.Forms.TextBox groupTextBox;
|
||||
private System.Windows.Forms.Label groupLabel;
|
||||
private System.Windows.Forms.TextBox muxBoardNrTextBox;
|
||||
private System.Windows.Forms.Label muxBoardNrLabel;
|
||||
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.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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,16 +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
|
||||
{
|
||||
@@ -20,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); }
|
||||
@@ -42,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;
|
||||
@@ -53,15 +56,23 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
|
||||
if (isCliLogging)
|
||||
{
|
||||
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
|
||||
);
|
||||
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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +95,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
}
|
||||
|
||||
|
||||
public async Task<string> SendAsync(string fileName, string args)
|
||||
public async Task<string> SendAsync(string fileName, string args, CancellationToken ct = default)
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
@@ -96,26 +107,33 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var process = new Process { StartInfo = psi };
|
||||
var sb = new StringBuilder();
|
||||
|
||||
process.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
if (e.Data != null)
|
||||
sb.AppendLine(e.Data);
|
||||
};
|
||||
|
||||
using var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
|
||||
process.WaitForExit();
|
||||
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();
|
||||
}
|
||||
|
||||
// Now all outputs are available
|
||||
string allOutput = sb.ToString();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
public void AddRunAndCaptureJsonAsync<T>(SerialPortData data, SerialPortData.EMeterArg eMeterArg) where T : new()
|
||||
{
|
||||
@@ -123,7 +141,7 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
taskPool.Add(task);
|
||||
}
|
||||
|
||||
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args) where T : new()
|
||||
public async Task<T> RunAndCaptureJsonAsync<T>(string fileName, string args, CancellationToken ct = default) where T : new()
|
||||
{
|
||||
var psi = new ProcessStartInfo
|
||||
{
|
||||
@@ -135,29 +153,19 @@ namespace TBF.Rig.RegisterReaders.PoseidonCmdStartStop
|
||||
CreateNoWindow = true
|
||||
};
|
||||
|
||||
var process = new Process { StartInfo = psi };
|
||||
var sb = new StringBuilder();
|
||||
|
||||
process.OutputDataReceived += (sender, e) =>
|
||||
{
|
||||
if (e.Data != null)
|
||||
sb.AppendLine(e.Data);
|
||||
};
|
||||
|
||||
using var process = new Process { StartInfo = psi, EnableRaisingEvents = true };
|
||||
process.Start();
|
||||
process.BeginOutputReadLine();
|
||||
|
||||
process.WaitForExit();
|
||||
var stdoutTask = process.StandardOutput.ReadToEndAsync();
|
||||
var stderrTask = process.StandardError.ReadToEndAsync();
|
||||
|
||||
// Now sb contains all output text
|
||||
string allOutput = sb.ToString();
|
||||
await Task.WhenAll(stdoutTask, stderrTask, process.WaitForExitAsync(ct));
|
||||
|
||||
string allOutput = (stdoutTask.Result ?? "") + (stderrTask.Result ?? "");
|
||||
log?.Debug(allOutput);
|
||||
|
||||
// Extract JSON part
|
||||
string json = ExtractJson(allOutput);
|
||||
|
||||
if (TryJsonStringDeserialize(json, out T runAndCaptureJsonAsync)) return runAndCaptureJsonAsync;
|
||||
|
||||
if (TryJsonStringDeserialize(json, out T result)) return result;
|
||||
return default;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user