Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1bb1ff079 | ||
|
|
db4ac6a838 | ||
|
|
a0201427ca | ||
|
|
202eef0d46 | ||
|
|
daad73ff81 |
@@ -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.
|
||||
|
||||
@@ -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,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 |
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
public IComponentCfgCtrl GetControl(IList<Component> cmpntEntities)
|
||||
{
|
||||
return new iPerlASICReader.IPerlUniCfgCtrl();
|
||||
return new IPerlUniCfgCtrl();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
muxBoardNrTextBox.Text = config.MuxBoardNr.ToString();
|
||||
groupTextBox.Text = config.Group.ToString();
|
||||
comboBoxCommunicationInterface.SelectedItem = config.CommunicationInterface.ToString();
|
||||
tabPage2.Controls.Add(new iPerlASICReader.IperlASICUniHeadTestCtrl(config));
|
||||
tabPage2.Controls.Add(new IperlUniHeadTestCtrl(config));
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl.communication;
|
||||
using TBF.Rig.RegisterReaders.IPerlReader.implementations;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.implementations;
|
||||
@@ -21,7 +20,7 @@ namespace TBF.Rig.RegisterReaders.IPerlReader
|
||||
|
||||
public IperlUniHeadTestCtrl(iPerlReaderUNI.IPerlCfg config)
|
||||
{
|
||||
this._ctrl = new IPerlImplHeadTestCtrl();
|
||||
this._ctrl = new PoseidonImplHeadTestCtrl();
|
||||
Ctrl.config = config;
|
||||
InitializeComponent();
|
||||
if (config == null) return;
|
||||
|
||||
@@ -4,7 +4,6 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl.communication;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
@@ -38,51 +37,35 @@ namespace TBF.Rig.RegisterReaders.IPerlReader.implementations
|
||||
optoThread.Abort();
|
||||
}
|
||||
}
|
||||
|
||||
private const string StrReadPcbCmd = "ReadPCB";
|
||||
private const string StrSetTestModeCmd = "SetTestMode";
|
||||
private const string StrSetActiveModeCmd = "SetActiveMode";
|
||||
private const string StrReadOptoDataCmd = "ReadOptoData";
|
||||
private const string StrStopReadOptoDataCmd = "StopReadOptoData";
|
||||
private const string StrResetNfcHeadCmd = "ResetNfcHead";
|
||||
private const string StrSetNfcHeadCmd = "SetNfcHead";
|
||||
private const string StrSetRfidHeadCmd = "SetRfidHead";
|
||||
private const string StrEmptyCmd = "";
|
||||
|
||||
public enum Operations
|
||||
{
|
||||
[Description(StrReadPcbCmd)]ReadPcbCmd,
|
||||
[Description(StrSetTestModeCmd)]SetTestModeCmd,
|
||||
[Description(StrSetActiveModeCmd)]SetActiveModeCmd,
|
||||
[Description(StrReadOptoDataCmd)]ReadOptoDataCmd,
|
||||
[Description(StrStopReadOptoDataCmd)]StopReadOptoDataCmd,
|
||||
[Description(StrResetNfcHeadCmd)]ResetNfcHeadCmd,
|
||||
[Description(StrSetNfcHeadCmd)]SetNfcHeadCmd,
|
||||
[Description(StrSetRfidHeadCmd)]SetRfidHeadCmd,
|
||||
[Description(StrEmptyCmd)]EmptyCmd
|
||||
}
|
||||
|
||||
|
||||
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, Operations> ItemsForIperlOperations = new Dictionary<string, Operations>
|
||||
private static readonly Dictionary<string, string> ItemsForIperlOperations = new Dictionary<string, string>
|
||||
{
|
||||
{"Read PCB", Operations.ReadPcbCmd},
|
||||
{"Set Test Mode", Operations.SetTestModeCmd},
|
||||
{"Set Active Mode", Operations.SetActiveModeCmd},
|
||||
{"Read PCB", ReadPCBCmd},
|
||||
{"Set Test Mode", SetTestModeCmd},
|
||||
{"Set Active Mode", SetActiveModeCmd},
|
||||
#if DEBUG
|
||||
{"Start Read Opto Data", Operations.ReadOptoDataCmd},
|
||||
{"Stop Read Opto Data", Operations.StopReadOptoDataCmd},
|
||||
{"Start Read Opto Data", ReadOptoDataCmd},
|
||||
{"Stop Read Opto Data", StopReadOptoDataCmd},
|
||||
#endif
|
||||
{" ", Operations.EmptyCmd},
|
||||
{"Reset NFC Head", Operations.ResetNfcHeadCmd},
|
||||
{"Set NFC Head Interface", Operations.SetNfcHeadCmd},
|
||||
{"Set RFID Head interface", Operations.SetRfidHeadCmd}
|
||||
{" ", 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();
|
||||
return ItemsForIperlOperations.Select(kvp => (kvp.Key, kvp.Value.ToDescription())).ToArray();
|
||||
return ItemsForIperlOperations.Select(kvp => (kvp.Key, kvp.Value)).ToArray();
|
||||
}
|
||||
|
||||
public void CommandTestButtonClick(object sender, MouseEventArgs e, Arguments a)
|
||||
@@ -93,15 +76,12 @@ namespace TBF.Rig.RegisterReaders.IPerlReader.implementations
|
||||
{
|
||||
ListItem rfidListItem = new ListItem();
|
||||
rfidListItem.Attributes.Add("style", "font-weight:bold");
|
||||
Operations selectedOperation;
|
||||
if(!ItemsForIperlOperations.TryGetValue((string)a.RfidCommandComboBox.SelectedValue, out selectedOperation))
|
||||
selectedOperation = Operations.EmptyCmd;
|
||||
switch (selectedOperation)
|
||||
switch (a.RfidCommandComboBox.SelectedValue)
|
||||
{
|
||||
case Operations.ReadPcbCmd:
|
||||
case ReadPCBCmd:
|
||||
rfidListItem.Text = $"PCB: {OpticalHeadTest.ReadRequest_PCB(a.ISmartReader)}";
|
||||
break;
|
||||
case Operations.SetTestModeCmd:
|
||||
case SetTestModeCmd:
|
||||
rfidListItem.Text = OpticalHeadTest.SetTestMode(a.ISmartReader);
|
||||
a.OptoListBox.Items.Clear();
|
||||
stopWorkerThread = false;
|
||||
@@ -111,23 +91,22 @@ namespace TBF.Rig.RegisterReaders.IPerlReader.implementations
|
||||
a.ISmartReader.StartDataStreamProcessing(); // open opto port
|
||||
optoThread.Start();
|
||||
}
|
||||
|
||||
break;
|
||||
case Operations.SetActiveModeCmd:
|
||||
case SetActiveModeCmd:
|
||||
rfidListItem.Text = OpticalHeadTest.SetActiveMode(a.ISmartReader);
|
||||
stopWorkerThread = true;
|
||||
a.ISmartReader.StopDataStreamProcessing(); // close opto port
|
||||
break;
|
||||
case Operations.ResetNfcHeadCmd:
|
||||
case ResetNfcHeadCmd:
|
||||
a.ISmartReader.ResetNfcInterface();
|
||||
break;
|
||||
case Operations.SetNfcHeadCmd:
|
||||
case SetNfcHeadCmd:
|
||||
a.ISmartReader.SetNfcInterface();
|
||||
break;
|
||||
case Operations.SetRfidHeadCmd:
|
||||
case SetRfidHeadCmd:
|
||||
a.ISmartReader.SetRfidInterface();
|
||||
break;
|
||||
case Operations.ReadOptoDataCmd:
|
||||
case ReadOptoDataCmd:
|
||||
a.OptoListBox.Items.Clear();
|
||||
stopWorkerThread = false;
|
||||
optoThread = new Thread(OptoWorker);
|
||||
@@ -136,20 +115,17 @@ namespace TBF.Rig.RegisterReaders.IPerlReader.implementations
|
||||
stopWorkerThread = true;
|
||||
a.ISmartReader.StopDataStreamProcessing(); // close opto port
|
||||
}
|
||||
|
||||
if (!optoThread.IsAlive)
|
||||
{
|
||||
a.ISmartReader.StartDataStreamProcessing(); // open opto port
|
||||
optoThread.Start();
|
||||
}
|
||||
|
||||
break;
|
||||
case Operations.StopReadOptoDataCmd:
|
||||
case StopReadOptoDataCmd:
|
||||
stopWorkerThread = true;
|
||||
a.ISmartReader.StopDataStreamProcessing(); // close opto port
|
||||
break;
|
||||
}
|
||||
|
||||
a.RfidOutputListBox.Items.Add(rfidListItem);
|
||||
a.RfidOutputListBox.Items.AddRange(logChecker.Messages.ToArray());
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using log4net;
|
||||
using TBF.Rig.Output.Printers.Label;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils;
|
||||
using CliRunner = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.CliRunnerOld;
|
||||
using OptoHeadStatus = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols.OptoHeadStatus;
|
||||
using SerialPortData = TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils.SerialPortData;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
using System;
|
||||
|
||||
using NfcC7_DLL.NfcHandler.Protocols;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Protocols
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using NfcC7_DLL.NfcHandler.Utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.PoseidonReader.communication.C7.Utils
|
||||
{
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.implementations;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader
|
||||
{
|
||||
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); } // TODO ????
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(iPerlReaderUNI.IPerlCfg.Serializer, component, this); // TODO ????
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
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.iPerlASICReader
|
||||
{
|
||||
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}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
///
|
||||
/// 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;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader
|
||||
{
|
||||
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 IperlASICUniHeadTestCtrl(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,441 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
-137
@@ -1,137 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader
|
||||
{
|
||||
partial class IperlASICUniHeadTestCtrl
|
||||
{
|
||||
/// <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 = "IperlASICUniHeadTestCtrl";
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl.communication;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.implementations;
|
||||
using TBF.Rig.RegisterReaders.IPerlReader.implementations;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader
|
||||
{
|
||||
public partial class IperlASICUniHeadTestCtrl : UserControl
|
||||
{
|
||||
private IUniHeadTestCtrl _ctrl;
|
||||
private IUniHeadTestCtrl Ctrl { get => _ctrl; }
|
||||
|
||||
|
||||
|
||||
|
||||
public IperlASICUniHeadTestCtrl(iPerlReaderUNI.IPerlCfg config)
|
||||
{
|
||||
this._ctrl = new IPerlASICImplHeadTestCtrl();
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProtocol
|
||||
{
|
||||
public static class Constants
|
||||
{
|
||||
public const byte Start = 0x53; //'S'
|
||||
public const byte Write = 0x57; // 'W'
|
||||
public const byte Read = 0x52; // 'R'
|
||||
public const byte End = 0x0D; //'.'
|
||||
public const byte Question = (byte)0x3F; // '?'
|
||||
public static readonly byte[] Version = {0x76, 0x65, 0x72, 0x73 }; // 'v' 'e' 'r' 's'
|
||||
|
||||
public const byte StatusOk = 0x01;
|
||||
public const byte StatusNok = 0x00;
|
||||
}
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProtocol
|
||||
{
|
||||
public sealed class IperlHatFrame
|
||||
{
|
||||
public byte Start { get; }
|
||||
public byte Direction { get; }
|
||||
public byte End { get; }
|
||||
public byte Length { get; }
|
||||
|
||||
public byte[] CommandInformation { get; }
|
||||
public byte[] Payload { get; }
|
||||
|
||||
public IperlHatFrame(byte start, byte direction, byte length, byte[] commandBytes, byte[] payload, byte end)
|
||||
{
|
||||
Start = start;
|
||||
Direction = direction;
|
||||
Length = length;
|
||||
CommandInformation = commandBytes ?? Array.Empty<byte>();
|
||||
Payload = payload ?? Array.Empty<byte>();
|
||||
End = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
-158
@@ -1,158 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.protocolCommons;
|
||||
using TBF.Rig.RegisterReaders.PoseidonReader.communication.C7;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProtocol
|
||||
{
|
||||
public sealed class IperlHatFrameBuilder
|
||||
{
|
||||
|
||||
private byte _direction;
|
||||
private readonly List<byte> _commandBytes = new List<byte>();
|
||||
private readonly List<byte> _payload = new List<byte>();
|
||||
|
||||
public IperlHatFrameBuilder RequestResponse(bool enabled)
|
||||
{
|
||||
_direction = enabled ? Constants.Write : Constants.Read;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder AddCommand(ProtocolCommand command)
|
||||
{
|
||||
_commandBytes.Add((byte)command);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder AddSubCommand(ProtocolCommand subCommand)
|
||||
{
|
||||
if (_commandBytes.Count == 0 ||
|
||||
_commandBytes[0] != (byte)ProtocolCommand.DeviceSpecific)
|
||||
throw new InvalidOperationException(
|
||||
"Sub-command is only valid for DeviceSpecific (0xFD) commands.");
|
||||
|
||||
_commandBytes.Add((byte)subCommand);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder AddSubCommand(ProtocolStatuses subCommand)
|
||||
{
|
||||
if (_commandBytes.Count == 0 ||
|
||||
_commandBytes[0] != (byte)ProtocolCommand.SetState)
|
||||
throw new InvalidOperationException(
|
||||
"Sub-command is only valid for SetState (0xA1) commands.");
|
||||
|
||||
_commandBytes.Add((byte)subCommand);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder AddDeviceCommand(
|
||||
ProtocolDeviceSubCommand subCommand)
|
||||
{
|
||||
_commandBytes.Add((byte)ProtocolCommand.DeviceSpecific);
|
||||
_commandBytes.Add((byte)subCommand);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder SetVersionCommand()
|
||||
{
|
||||
_commandBytes.Add((byte)ProtocolCommand.Question);
|
||||
_payload.AddRange(Constants.Version);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder AddPayload(byte[] payload)
|
||||
{
|
||||
if (payload != null)
|
||||
_payload.AddRange(payload);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder AddPayload(DiagnosticLedState state)
|
||||
{
|
||||
_payload.Add((byte)state);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder AddPayload(byte payload)
|
||||
{
|
||||
_payload.Add(payload);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder AddDiagnosticLedState(DiagnosticLedState state)
|
||||
{
|
||||
RequestResponse(true);
|
||||
AddDeviceCommand(ProtocolDeviceSubCommand.SetDiagnosticLEDState);
|
||||
AddPayload((byte)state);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrameBuilder AddNullTerminatedAscii(string text)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
_commandBytes.AddRange(
|
||||
System.Text.Encoding.ASCII.GetBytes(text));
|
||||
|
||||
_commandBytes.Add(0x00);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IperlHatFrame BuildFrame()
|
||||
{
|
||||
if (_commandBytes.Count == 0)
|
||||
throw new InvalidOperationException("No command specified.");
|
||||
|
||||
byte length = (byte)(4 + _commandBytes.Count + _payload.Count); // 4 = START + dirrection + LEN + END
|
||||
|
||||
|
||||
return new IperlHatFrame(
|
||||
Constants.Start,
|
||||
_direction,
|
||||
length,
|
||||
_commandBytes.ToArray(),
|
||||
_payload.ToArray(),
|
||||
Constants.End);
|
||||
}
|
||||
|
||||
public byte[] BuildBytes()
|
||||
{
|
||||
IperlHatFrame frame = BuildFrame();
|
||||
|
||||
if (frame.CommandInformation.Length > 0 && frame.CommandInformation[0] == Constants.Question)
|
||||
{
|
||||
var bytes = new List<byte>
|
||||
{
|
||||
frame.Start,
|
||||
frame.Direction,
|
||||
};
|
||||
|
||||
bytes.AddRange(frame.CommandInformation);
|
||||
bytes.AddRange(frame.Payload);
|
||||
bytes.Add(frame.End);
|
||||
|
||||
return bytes.ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
var bytes = new List<byte>
|
||||
{
|
||||
frame.Start,
|
||||
frame.Direction,
|
||||
frame.Length,
|
||||
};
|
||||
|
||||
bytes.AddRange(frame.CommandInformation);
|
||||
bytes.AddRange(frame.Payload);
|
||||
bytes.Add(frame.End);
|
||||
|
||||
return bytes.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-133
@@ -1,133 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProtocol
|
||||
{
|
||||
public sealed class IperlHatFrameParser
|
||||
{
|
||||
|
||||
public IperlHatResponse Parse(byte[] data)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
|
||||
if (data.Length < 5)
|
||||
throw new FormatException("Frame too short.");
|
||||
|
||||
|
||||
|
||||
if (data[0] != Constants.Start)
|
||||
{
|
||||
//if version parse version
|
||||
if (data[0] == Constants.Question)
|
||||
{
|
||||
//Define Question answer
|
||||
var prefix = new List<byte>{ Constants.Question };
|
||||
var end = new List<byte>{ Constants.End };
|
||||
|
||||
if (IsPrefixValid(data, prefix, end))
|
||||
{
|
||||
//whole payload may be like "vers: Harry T:B800, V:06.06.01, FW:190215, 7ECE, B1.6.01, HW:4, Serial:0"
|
||||
prefix = new List<byte>{ Constants.Question };
|
||||
byte[] payloadVersion = ExtractPayloadUsePrefix(data, prefix, end);
|
||||
return new IperlHatResponse(Constants.Question, payloadVersion.Length > 0 ? Constants.StatusOk : Constants.StatusNok, payloadVersion);
|
||||
}
|
||||
}
|
||||
|
||||
throw new FormatException("Invalid START byte.");
|
||||
}
|
||||
|
||||
if (data[1] != Constants.Read)
|
||||
throw new FormatException("Frame is no Response.");
|
||||
|
||||
byte length = data[2];
|
||||
if (length != data.Length)
|
||||
throw new FormatException("Length mismatch.");
|
||||
|
||||
byte direction = data[1];
|
||||
byte status = data[3];
|
||||
|
||||
var prefixCommand = new List<byte>{ Constants.Start,direction,length,status };
|
||||
var endCommand = new List<byte>{ Constants.End };
|
||||
|
||||
byte[] payload = ExtractPayloadUsePrefix(data,prefixCommand,endCommand);
|
||||
|
||||
return new IperlHatResponse(0x00, status, payload);
|
||||
}
|
||||
|
||||
|
||||
private static byte[] ExtractPayloadUsePrefix(byte[] data, List<byte> prefix, List<byte> end)
|
||||
{
|
||||
// payload exists only if frame longer than:
|
||||
// START + DIRECTION + LEN + CTRL + END = 5 bytes
|
||||
// OR VERSION_START + VERSION = 5 bytes
|
||||
if (data.Length <= 5)
|
||||
return Array.Empty<byte>();
|
||||
|
||||
//check prefix is equal
|
||||
int prefixLength = prefix.Count;
|
||||
byte[] commandPrefix = new byte[prefixLength];
|
||||
Buffer.BlockCopy(data, 0, commandPrefix, 0, prefixLength);
|
||||
|
||||
if (StartsWithPrefix(end, commandPrefix))
|
||||
{
|
||||
return Array.Empty<byte>();
|
||||
}
|
||||
|
||||
int payloadLength = data.Length - (prefix.Count + end.Count);
|
||||
byte[] payload = new byte[payloadLength];
|
||||
Buffer.BlockCopy(data, prefix.Count, payload, 0, payloadLength);
|
||||
return payload;
|
||||
}
|
||||
|
||||
private static bool IsPrefixValid(byte[] data, List<byte> prefix, List<byte> end)
|
||||
{
|
||||
int prefixLength = prefix.Count;
|
||||
// payload exists only if frame longer than:
|
||||
// OR VERSION_START + VERSION = 5 bytes - "?VERS" version implemented
|
||||
if (data.Length <= prefixLength) // need be and on END
|
||||
return false;
|
||||
|
||||
//check prefix is equal
|
||||
byte[] commandPrefix = new byte[prefixLength];
|
||||
Buffer.BlockCopy(data, 0, commandPrefix, 0, prefixLength);
|
||||
|
||||
if (StartsWithPrefix(end, commandPrefix))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool StartsWithPrefix(List<byte> data, byte[] prefix)
|
||||
{
|
||||
if (data.Count < prefix.Length)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < prefix.Length; i++)
|
||||
{
|
||||
if (data[i] != prefix[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static byte[] ExtractVersionPayload(byte[] data)
|
||||
{
|
||||
// payload exists only if frame longer than:
|
||||
// START + LEN + CTRL + STATUS + CHK_HI + CHK_LO = 6 bytes
|
||||
if (data.Length <= 5)
|
||||
return Array.Empty<byte>();
|
||||
|
||||
int payloadLength = data.Length - 4;
|
||||
byte[] payload = new byte[payloadLength];
|
||||
Buffer.BlockCopy(data, 5, payload, 0, payloadLength);
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProtocol
|
||||
{
|
||||
public static class IperlHatProtocol
|
||||
{
|
||||
public const byte START = 0x0D;
|
||||
|
||||
// Control bits (CNTRL1)
|
||||
public const byte RESPONSE_FLAG = 0x08; // RF
|
||||
}
|
||||
}
|
||||
-35
@@ -1,35 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProtocol
|
||||
{
|
||||
public sealed class IperlHatResponse
|
||||
{
|
||||
public byte Control { get; } //classic control byte - valid for question now
|
||||
private byte Status { get; }
|
||||
public byte[] Payload { get; }
|
||||
|
||||
public bool IsOk => Status == Constants.StatusOk;
|
||||
|
||||
public IperlHatResponse(byte control, byte status, byte[] payload)
|
||||
{
|
||||
Control = control;
|
||||
Status = status;
|
||||
Payload = payload ?? Array.Empty<byte>();
|
||||
}
|
||||
|
||||
|
||||
public string GetAsciiPayload()
|
||||
{
|
||||
if (Payload.Length == 0)
|
||||
return null;
|
||||
|
||||
int length = Array.IndexOf(Payload, (byte)0x00);
|
||||
if (length < 0)
|
||||
length = Payload.Length;
|
||||
|
||||
return System.Text.Encoding.ASCII.GetString(Payload, 0, length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed
|
||||
{
|
||||
public sealed class DiagnosticLedParser
|
||||
{
|
||||
private readonly DiagnosticLedState _state;
|
||||
|
||||
public DiagnosticLedParser(DiagnosticLedState state)
|
||||
{
|
||||
_state = state;
|
||||
}
|
||||
|
||||
public DiagnosticLedData ParseLine(string line, bool checkLineTermination = true)
|
||||
{
|
||||
if (string.IsNullOrEmpty(line))
|
||||
throw new ArgumentNullException(nameof(line));
|
||||
|
||||
if (checkLineTermination && !line.EndsWith("\r\n"))
|
||||
throw new FormatException("Invalid diagnostic LED line termination");
|
||||
|
||||
string trimmed = line.TrimEnd('\r', '\n');
|
||||
string[] parts = trimmed.Split('\t');
|
||||
|
||||
if (parts.Length < 2)
|
||||
throw new FormatException("Too few diagnostic LED fields");
|
||||
|
||||
// ---- Checksum ----
|
||||
string checksumHex = parts[parts.Length - 1];
|
||||
|
||||
int lastTab = trimmed.LastIndexOf('\t');
|
||||
if (lastTab < 0)
|
||||
throw new FormatException("Checksum separator not found");
|
||||
|
||||
string beforeChecksum = trimmed.Substring(0, lastTab + 1);
|
||||
|
||||
byte expected = DiagnosticChecksum.Compute(beforeChecksum);
|
||||
byte actual = DiagnosticHex.ParseByte(checksumHex);
|
||||
|
||||
if (expected != actual)
|
||||
throw new FormatException("Diagnostic LED checksum mismatch");
|
||||
|
||||
// ---- Dispatch ----
|
||||
switch (_state)
|
||||
{
|
||||
case DiagnosticLedState.State1:
|
||||
return new DiagnosticLedState1Data(line, parts);
|
||||
|
||||
case DiagnosticLedState.State2:
|
||||
return new DiagnosticLedState2Data(line, parts);
|
||||
|
||||
case DiagnosticLedState.State3:
|
||||
return new DiagnosticLedState3Data(line, parts);
|
||||
|
||||
case DiagnosticLedState.State4:
|
||||
return new DiagnosticLedState4Data(line, parts);
|
||||
|
||||
case DiagnosticLedState.State5:
|
||||
return new DiagnosticLedState5Data(line, parts);
|
||||
|
||||
case DiagnosticLedState.State6:
|
||||
return new DiagnosticLedState6Data(line, parts);
|
||||
|
||||
case DiagnosticLedState.State7:
|
||||
return new DiagnosticLedState7Data(line, parts);
|
||||
|
||||
default:
|
||||
throw new NotSupportedException("Unknown diagnostic LED state");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-96
@@ -1,96 +0,0 @@
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.protocolCommons;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed
|
||||
{
|
||||
/// <summary>
|
||||
/// Diagnostic LED output mode.
|
||||
/// <para>
|
||||
/// Determines the format and content of high-speed serial diagnostic data
|
||||
/// emitted by the meter when the diagnostic LED is enabled.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Each state corresponds to a specific TAB-separated ASCII HEX frame layout
|
||||
/// as defined in the iPERL TouchRead protocol documentation.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// See <see cref="ProtocolDeviceSubCommand.SetDiagnosticLEDState"/>
|
||||
/// diagnostic LED States.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public enum DiagnosticLedState : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Diagnostic LED OFF - State #0.
|
||||
/// <para>
|
||||
/// Basic diagnostic output containing raw ADC, field strength,
|
||||
/// flow rate, volume accumulator, and capacitor voltage.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
StateOFF = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #1.
|
||||
/// <para>
|
||||
/// Basic diagnostic output containing raw ADC, field strength,
|
||||
/// flow rate, volume accumulator, and capacitor voltage.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
State1 = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #2.
|
||||
/// <para>
|
||||
/// Extends State #1 with LCD volume, meter state,
|
||||
/// and low-flow cutoff indication.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
State2 = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #3.
|
||||
/// <para>
|
||||
/// Extends State #1 with field calibration value,
|
||||
/// ASIC timestamp, and field drive time.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
State3 = 0x03,
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #4.
|
||||
/// <para>
|
||||
/// Extended diagnostic output including mean flow rate,
|
||||
/// field measurements, integrator calibration values,
|
||||
/// and ASIC state.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
State4 = 0x04,
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #5.
|
||||
/// <para>
|
||||
/// Extends State #4 with water impedance measurement.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
State5 = 0x05,
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #6.
|
||||
/// <para>
|
||||
/// Extends State #5 with electrode delta, spike detection data,
|
||||
/// pipe status, LCD volume, and additional ASIC state.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
State6 = 0x06,
|
||||
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #7.
|
||||
/// <para>
|
||||
/// Extends State #6 with raw ADC before offset correction,
|
||||
/// detrended ADC value, imaginary water impedance,
|
||||
/// electrode voltage noise, and ADC offset learning status.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
State7 = 0x07
|
||||
}
|
||||
}
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class for all Diagnostic LED data frames.
|
||||
///
|
||||
/// <para>
|
||||
/// The iPERL meter emits diagnostic LED frames when the
|
||||
/// Diagnostic LED is enabled using the
|
||||
/// <c>Set Diagnostic LED State (0xFD 0x60)</c> command.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// All diagnostic LED states (State #1 – State #7) share a common
|
||||
/// set of leading fields, followed by state-specific extensions.
|
||||
/// This class represents those common fields.
|
||||
/// </para>
|
||||
///
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Pos</term>
|
||||
/// <description>Common field description</description>
|
||||
/// </listheader>
|
||||
/// <item><term>0 – xxxxxx</term><description>Signed 24-bit ADC value (two’s complement)</description></item>
|
||||
/// <item><term>1 – aaaa</term><description>Unsigned 16-bit field strength (internal units)</description></item>
|
||||
/// <item><term>2 – yyyy</term><description>Signed 16-bit raw flow rate (¼ ml per bit)</description></item>
|
||||
/// <item><term>3 – vvvvvv</term><description>Unsigned 24-bit raw volume accumulation (¼ ml per bit)</description></item>
|
||||
/// <item><term>4 – cccc</term><description>Unsigned 16-bit millivolt delta on the field drive capacitor</description></item>
|
||||
/// </list>
|
||||
///
|
||||
/// <para>
|
||||
/// Each derived state class parses additional fields starting at
|
||||
/// position 5, according to the selected diagnostic LED state.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// The raw ASCII line (including checksum and CRLF) is preserved
|
||||
/// for logging, debugging, and offline analysis.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public abstract class DiagnosticLedData
|
||||
{
|
||||
|
||||
public abstract int GetByteCount();
|
||||
|
||||
/// <summary>
|
||||
/// Raw diagnostic LED line exactly as received from the meter,
|
||||
/// including checksum and CRLF.
|
||||
/// </summary>
|
||||
public string RawLine { get; }
|
||||
|
||||
// ----- Common fields (present in all LED states) -----
|
||||
|
||||
/// <summary>
|
||||
/// Signed 24-bit ADC value (two’s complement).
|
||||
/// </summary>
|
||||
public int Adc24 { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unsigned 16-bit field strength in internal (non-legacy) units.
|
||||
/// </summary>
|
||||
public ushort FieldStrength { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Signed 16-bit raw flow rate in units of ¼ milliliter per bit.
|
||||
/// </summary>
|
||||
public short RawFlow { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unsigned 24-bit raw volume accumulation in units of ¼ milliliter per bit.
|
||||
/// </summary>
|
||||
public uint RawVolume { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Unsigned 16-bit millivolt delta measured on the field drive capacitor.
|
||||
/// </summary>
|
||||
public ushort CapacitorMv { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the base diagnostic LED data with the raw input line.
|
||||
/// </summary>
|
||||
/// <param name="raw">
|
||||
/// Raw ASCII line received from the diagnostic LED output.
|
||||
/// </param>
|
||||
protected DiagnosticLedData(string raw)
|
||||
{
|
||||
RawLine = raw;
|
||||
}
|
||||
}
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
public static class DiagnosticLedFrameSpec
|
||||
{
|
||||
public static int GetExpectedAsciiLength(DiagnosticLedState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case DiagnosticLedState.State1: return 33;
|
||||
case DiagnosticLedState.State2: return 48;
|
||||
case DiagnosticLedState.State3: return 50;
|
||||
case DiagnosticLedState.State4: return 84;
|
||||
case DiagnosticLedState.State5: return 89;
|
||||
case DiagnosticLedState.State6: return 112;
|
||||
case DiagnosticLedState.State7: return 139;
|
||||
default: throw new ArgumentOutOfRangeException(nameof(state));
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetExpectedFieldCount(DiagnosticLedState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case DiagnosticLedState.State1: return 6;
|
||||
case DiagnosticLedState.State2: return 9;
|
||||
case DiagnosticLedState.State3: return 9;
|
||||
case DiagnosticLedState.State4: return 15;
|
||||
case DiagnosticLedState.State5: return 16;
|
||||
case DiagnosticLedState.State6: return 21;
|
||||
case DiagnosticLedState.State7: return 26;
|
||||
default: throw new ArgumentOutOfRangeException(nameof(state));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #1 data frame.
|
||||
///
|
||||
/// <para>
|
||||
/// Frame format: TAB-separated ASCII hexadecimal fields, terminated by CRLF.
|
||||
/// The checksum is an 8-bit sum of all previous ASCII bytes including
|
||||
/// the TAB character before the checksum field.
|
||||
/// </para>
|
||||
///
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Pos</term>
|
||||
/// <description>Field description</description>
|
||||
/// </listheader>
|
||||
/// <item><term>0 – xxxxxx</term><description>Signed 24-bit ADC value (two’s complement)</description></item>
|
||||
/// <item><term>1 – aaaa</term><description>Unsigned 16-bit field strength (internal units)</description></item>
|
||||
/// <item><term>2 – yyyy</term><description>Signed 16-bit raw flow rate (¼ ml per bit)</description></item>
|
||||
/// <item><term>3 – vvvvvv</term><description>Unsigned 24-bit raw volume accumulation (¼ ml per bit)</description></item>
|
||||
/// <item><term>4 – cccc</term><description>Unsigned 16-bit millivolt delta on the field drive capacitor</description></item>
|
||||
/// <item><term>5 – ss</term><description>Unsigned 8-bit checksum (sum of all previous ASCII bytes
|
||||
/// including the TAB before the checksum field)</description></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public class DiagnosticLedState1Data : DiagnosticLedData
|
||||
{
|
||||
public DiagnosticLedState1Data(string raw, string[] f)
|
||||
: base(raw)
|
||||
{
|
||||
Adc24 = DiagnosticHex.ParseInt24(f[0]);
|
||||
FieldStrength = DiagnosticHex.ParseUInt16(f[1]);
|
||||
RawFlow = DiagnosticHex.ParseInt16(f[2]);
|
||||
RawVolume = DiagnosticHex.ParseUInt24(f[3]);
|
||||
CapacitorMv = DiagnosticHex.ParseUInt16(f[4]);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"DiagnosticLedState1Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format: xxxxxx aaaa yyyy vvvvvv cccc ss
|
||||
/// Chars total = 26
|
||||
/// Tabs = 5
|
||||
/// CRLF = 2
|
||||
/// Total bytes = 33
|
||||
/// </summary>
|
||||
/// <returns> Total bytes</returns>
|
||||
public override int GetByteCount()
|
||||
{
|
||||
return 33;
|
||||
}
|
||||
}
|
||||
}
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #2 data frame.
|
||||
///
|
||||
/// <para>
|
||||
/// State #2 extends the common diagnostic LED fields with information
|
||||
/// about the LCD-displayed volume, the current meter operating state,
|
||||
/// and whether the meter is in low-flow cutoff mode.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// Frame format: TAB-separated ASCII hexadecimal fields, terminated by CRLF.
|
||||
/// The checksum is an 8-bit sum of all previous ASCII bytes including
|
||||
/// the TAB character before the checksum field.
|
||||
/// </para>
|
||||
///
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Pos</term>
|
||||
/// <description>Field description</description>
|
||||
/// </listheader>
|
||||
/// <item><term>0 – xxxxxx</term><description>Signed 24-bit ADC value (two’s complement)</description></item>
|
||||
/// <item><term>1 – aaaa</term><description>Unsigned 16-bit field strength (internal units)</description></item>
|
||||
/// <item><term>2 – yyyy</term><description>Signed 16-bit raw flow rate (¼ ml per bit)</description></item>
|
||||
/// <item><term>3 – vvvvvv</term><description>Unsigned 24-bit raw volume accumulation (¼ ml per bit)</description></item>
|
||||
/// <item><term>4 – cccc</term><description>Unsigned 16-bit millivolt delta on the field drive capacitor</description></item>
|
||||
/// <item><term>5 – gggggggg</term><description>Unsigned 32-bit volume displayed on the LCD</description></item>
|
||||
/// <item><term>6 – mm</term><description>Unsigned 8-bit meter state (see Table 17-23 in protocol documentation)</description></item>
|
||||
/// <item><term>7 – ff</term><description>Unsigned 8-bit boolean flag indicating low-flow cutoff
|
||||
/// state (0 = false, 1 = true)</description></item>
|
||||
/// <item><term>8 – ss</term><description>Unsigned 8-bit checksum (sum of all previous ASCII bytes including
|
||||
/// the TAB before the checksum field)</description></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class DiagnosticLedState2Data : DiagnosticLedData
|
||||
{
|
||||
/// <summary>
|
||||
/// Volume displayed on LCD (raw units).
|
||||
/// </summary>
|
||||
public uint LcdVolume { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Meter state (see Table 17-23).
|
||||
/// </summary>
|
||||
public byte MeterState { get; }
|
||||
|
||||
/// <summary>
|
||||
/// True if meter is in low-flow cutoff.
|
||||
/// </summary>
|
||||
public bool IsLowFlowCutoff { get; }
|
||||
|
||||
public DiagnosticLedState2Data(string rawLine, string[] fields)
|
||||
: base(rawLine)
|
||||
{
|
||||
// ---- Common fields (0–4) ----
|
||||
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
|
||||
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
|
||||
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
|
||||
RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
|
||||
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
|
||||
|
||||
// ---- State #2 specific ----
|
||||
LcdVolume = DiagnosticHex.ParseUInt32(fields[5]);
|
||||
MeterState = DiagnosticHex.ParseByte(fields[6]);
|
||||
IsLowFlowCutoff = DiagnosticHex.ParseByte(fields[7]) != 0;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"DiagnosticLedState2Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, LcdVolume={LcdVolume}, MeterState={MeterState}, IsLowFlowCutoff={IsLowFlowCutoff}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format: xxxxxx aaaa yyyy vvvvvv cccc gggggggg mm ff ss
|
||||
/// Chars total = 38
|
||||
/// Tabs = 8
|
||||
/// CRLF = 2
|
||||
/// Total bytes = 48
|
||||
/// </summary>
|
||||
/// <returns> Total bytes</returns>
|
||||
public override int GetByteCount()
|
||||
{
|
||||
return 48;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-89
@@ -1,89 +0,0 @@
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #3 data frame.
|
||||
///
|
||||
/// <para>
|
||||
/// State #3 extends the common diagnostic LED fields with calibration
|
||||
/// and timing information related to the field drive and ASIC operation.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>
|
||||
/// Frame format: TAB-separated ASCII hexadecimal fields, terminated by CRLF.
|
||||
/// The checksum is an 8-bit sum of all previous ASCII bytes including
|
||||
/// the TAB character before the checksum field.
|
||||
/// </para>
|
||||
///
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Pos</term>
|
||||
/// <description>Field description</description>
|
||||
/// </listheader>
|
||||
/// <item><term>0 – xxxxxx</term><description>Signed 24-bit ADC value (two’s complement)</description></item>
|
||||
/// <item><term>1 – aaaa</term><description>Unsigned 16-bit field strength (internal units)</description></item>
|
||||
/// <item><term>2 – yyyy</term><description>Signed 16-bit raw flow rate (¼ ml per bit)</description></item>
|
||||
/// <item><term>3 – vvvvvv</term><description>Unsigned 24-bit raw volume accumulation (¼ ml per bit)</description></item>
|
||||
/// <item><term>4 – cccc</term><description>Unsigned 16-bit millivolt delta on the field drive capacitor</description></item>
|
||||
/// <item><term>5 – tttt</term><description>Unsigned 16-bit field calibration value</description></item>
|
||||
/// <item><term>6 – bbbbbbbb</term><description>Unsigned 32-bit ASIC timestamp (8192 ticks per second,
|
||||
/// rolls over at 2^32)</description></item>
|
||||
/// <item><term>7 – ff</term><description>Unsigned 8-bit field drive time in microseconds</description></item>
|
||||
/// <item><term>8 – ss</term><description>Unsigned 8-bit checksum (sum of all previous ASCII bytes including
|
||||
/// the TAB before the checksum field)</description></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class DiagnosticLedState3Data : DiagnosticLedData
|
||||
{
|
||||
/// <summary>
|
||||
/// Unsigned 16-bit field calibration value.
|
||||
/// </summary>
|
||||
public ushort FieldCalibration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ASIC timestamp in units of 1 / 8192 seconds.
|
||||
/// Rolls over at 2^32.
|
||||
/// </summary>
|
||||
public uint AsicTimestamp { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Field drive time in microseconds.
|
||||
/// </summary>
|
||||
public byte FieldDriveTimeUs { get; }
|
||||
|
||||
public DiagnosticLedState3Data(string rawLine, string[] fields)
|
||||
: base(rawLine)
|
||||
{
|
||||
// ---- Common fields (0–4) ----
|
||||
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
|
||||
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
|
||||
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
|
||||
RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
|
||||
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
|
||||
|
||||
// ---- State #3 specific fields ----
|
||||
FieldCalibration = DiagnosticHex.ParseUInt16(fields[5]);
|
||||
AsicTimestamp = DiagnosticHex.ParseUInt32(fields[6]);
|
||||
FieldDriveTimeUs = DiagnosticHex.ParseByte(fields[7]);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"DiagnosticLedState3Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format: xxxxxx aaaa yyyy vvvvvv cccc tttt bbbbbbbb ff ss
|
||||
/// Chars total = 40
|
||||
/// Tabs = 8
|
||||
/// CRLF = 2
|
||||
/// Total bytes = 50
|
||||
/// </summary>
|
||||
/// <returns> Total bytes</returns>
|
||||
public override int GetByteCount()
|
||||
{
|
||||
return 50;
|
||||
}
|
||||
}
|
||||
}
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #4 data frame.
|
||||
/// <para>Frame format (TAB-separated ASCII HEX fields, CRLF terminated).</para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term># / Field</term>
|
||||
/// <description>Description</description>
|
||||
/// </listheader>
|
||||
/// <item><term>0 – xxxxxx</term><description>signed 24-bit ADC value</description></item>
|
||||
/// <item><term>1 – aaaa</term><description>unsigned 16-bit Field strength</description></item>
|
||||
/// <item><term>2 – yyyy</term><description>signed 16-bit Raw flow rate (1/4 ml per bit)</description></item>
|
||||
/// <item><term>3 – vvvvvv</term><description>unsigned 24-bit Raw volume accumulation</description></item>
|
||||
/// <item><term>4 – cccc</term><description>unsigned 16-bit Capacitor mV delta</description></item>
|
||||
/// <item><term>5 – tttt</term><description>unsigned 16-bit Field calibration</description></item>
|
||||
/// <item><term>6 – bbbbbbbb</term><description>unsigned 32-bit ASIC timestamp</description></item>
|
||||
/// <item><term>7 – ff</term><description>unsigned 8-bit Field drive time (µs)</description></item>
|
||||
/// <item><term>8 – mmmmmmmm</term><description>signed 32-bit Mean flow rate</description></item>
|
||||
/// <item><term>9 – gggg</term><description>unsigned 16-bit Field 1 measurement</description></item>
|
||||
/// <item><term>10 – hhhh</term><description>unsigned 16-bit Field 2 measurement</description></item>
|
||||
/// <item><term>11 – cccc</term><description>unsigned 16-bit Integrator calibration positive</description></item>
|
||||
/// <item><term>12 – nnnn</term><description>unsigned 16-bit Integrator calibration negative</description></item>
|
||||
/// <item><term>13 – qq</term><description>unsigned 8-bit ASIC state</description></item>
|
||||
/// <item><term>14 – ss</term><description>unsigned 8-bit Checksum</description></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class DiagnosticLedState4Data : DiagnosticLedData
|
||||
{
|
||||
public ushort FieldCalibration { get; }
|
||||
public uint AsicTimestamp { get; }
|
||||
public byte FieldDriveTimeUs { get; }
|
||||
|
||||
public int MeanFlowRate { get; }
|
||||
|
||||
public ushort Field1Measurement { get; }
|
||||
public ushort Field2Measurement { get; }
|
||||
|
||||
public ushort IntegratorCalibrationPositive { get; }
|
||||
public ushort IntegratorCalibrationNegative { get; }
|
||||
|
||||
public byte AsicState { get; }
|
||||
|
||||
public DiagnosticLedState4Data(string rawLine, string[] fields)
|
||||
: base(rawLine)
|
||||
{
|
||||
// ---- Common fields (0–4) ----
|
||||
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
|
||||
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
|
||||
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
|
||||
RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
|
||||
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
|
||||
|
||||
// ---- State #4 specific ----
|
||||
FieldCalibration = DiagnosticHex.ParseUInt16(fields[5]);
|
||||
AsicTimestamp = DiagnosticHex.ParseUInt32(fields[6]);
|
||||
FieldDriveTimeUs = DiagnosticHex.ParseByte(fields[7]);
|
||||
|
||||
MeanFlowRate = unchecked((int)DiagnosticHex.ParseUInt32(fields[8]));
|
||||
|
||||
Field1Measurement = DiagnosticHex.ParseUInt16(fields[9]);
|
||||
Field2Measurement = DiagnosticHex.ParseUInt16(fields[10]);
|
||||
|
||||
IntegratorCalibrationPositive = DiagnosticHex.ParseUInt16(fields[11]);
|
||||
IntegratorCalibrationNegative = DiagnosticHex.ParseUInt16(fields[12]);
|
||||
|
||||
AsicState = DiagnosticHex.ParseByte(fields[13]);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"DiagnosticLedState4Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState={AsicState}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format: xxxxxx aaaa yyyy vvvvvv cccc tttt bbbbbbbb mmmmmmmm ff gggg hhhh cccc nnnn qq ss
|
||||
/// Chars total = 68
|
||||
/// Tabs = 14
|
||||
/// CRLF = 2
|
||||
/// Total bytes = 84
|
||||
/// </summary>
|
||||
/// <returns> Total bytes</returns>
|
||||
public override int GetByteCount()
|
||||
{
|
||||
return 84;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-111
@@ -1,111 +0,0 @@
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #5 data frame.
|
||||
/// <para>
|
||||
/// Frame format: TAB-separated ASCII HEX fields, CRLF terminated.
|
||||
/// </para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term># / Field</term>
|
||||
/// <description>Description</description>
|
||||
/// </listheader>
|
||||
/// <item><term>0 – xxxxxx</term><description>signed 24-bit ADC value</description></item>
|
||||
/// <item><term>1 – aaaa</term><description>unsigned 16-bit Field strength (internal units)</description></item>
|
||||
/// <item><term>2 – yyyy</term><description>signed 16-bit Raw flow rate (1/4 ml per bit)</description></item>
|
||||
/// <item><term>3 – vvvvvv</term><description>unsigned 24-bit Raw volume accumulation (1/4 ml per bit)</description></item>
|
||||
/// <item><term>4 – cccc</term><description>unsigned 16-bit Millivolts delta on field drive capacitor</description></item>
|
||||
/// <item><term>5 – tttt</term><description>unsigned 16-bit Field calibration value</description></item>
|
||||
/// <item><term>6 – bbbbbbbb</term><description>unsigned 32-bit ASIC timestamp (8192 ticks/sec, rolls over at 2^32)</description></item>
|
||||
/// <item><term>7 – ff</term><description>unsigned 8-bit Field drive time in microseconds</description></item>
|
||||
/// <item><term>8 – mmmmmmmm</term><description>signed 32-bit Mean flow rate (rolls over at 2^32)</description></item>
|
||||
/// <item><term>9 – gggg</term><description>unsigned 16-bit Field 1 measurement</description></item>
|
||||
/// <item><term>10 – hhhh</term><description>unsigned 16-bit Field 2 measurement</description></item>
|
||||
/// <item><term>11 – cccc</term><description>unsigned 16-bit Integrator calibration positive</description></item>
|
||||
/// <item><term>12 – nnnn</term><description>unsigned 16-bit Integrator calibration negative</description></item>
|
||||
/// <item><term>13 – qq</term><description>unsigned 8-bit ASIC state</description></item>
|
||||
/// <item><term>14 – iiii</term><description>signed 16-bit Water impedance measurement</description></item>
|
||||
/// <item><term>15 – ss</term><description>unsigned 8-bit Checksum</description></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class DiagnosticLedState5Data : DiagnosticLedData
|
||||
{
|
||||
/// <summary>Field calibration value (tttt).</summary>
|
||||
public ushort FieldCalibration { get; }
|
||||
|
||||
/// <summary>ASIC timestamp (bbbbbbbb), 8192 ticks per second.</summary>
|
||||
public uint AsicTimestamp { get; }
|
||||
|
||||
/// <summary>Field drive time in microseconds (ff).</summary>
|
||||
public byte FieldDriveTimeUs { get; }
|
||||
|
||||
/// <summary>Mean flow rate (mmmmmmmm), signed 32-bit.</summary>
|
||||
public int MeanFlowRate { get; }
|
||||
|
||||
/// <summary>Field 1 measurement (gggg).</summary>
|
||||
public ushort Field1Measurement { get; }
|
||||
|
||||
/// <summary>Field 2 measurement (hhhh).</summary>
|
||||
public ushort Field2Measurement { get; }
|
||||
|
||||
/// <summary>Integrator calibration positive (cccc).</summary>
|
||||
public ushort IntegratorCalibrationPositive { get; }
|
||||
|
||||
/// <summary>Integrator calibration negative (nnnn).</summary>
|
||||
public ushort IntegratorCalibrationNegative { get; }
|
||||
|
||||
/// <summary>ASIC state (qq).</summary>
|
||||
public byte AsicState { get; }
|
||||
|
||||
/// <summary>Water impedance measurement (iiii), signed 16-bit.</summary>
|
||||
public short WaterImpedance { get; }
|
||||
|
||||
public DiagnosticLedState5Data(string rawLine, string[] fields)
|
||||
: base(rawLine)
|
||||
{
|
||||
// ---- Common fields ----
|
||||
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
|
||||
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
|
||||
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
|
||||
RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
|
||||
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
|
||||
|
||||
// ---- State #5 specific ----
|
||||
FieldCalibration = DiagnosticHex.ParseUInt16(fields[5]);
|
||||
AsicTimestamp = DiagnosticHex.ParseUInt32(fields[6]);
|
||||
FieldDriveTimeUs = DiagnosticHex.ParseByte(fields[7]);
|
||||
|
||||
MeanFlowRate = unchecked((int)DiagnosticHex.ParseUInt32(fields[8]));
|
||||
|
||||
Field1Measurement = DiagnosticHex.ParseUInt16(fields[9]);
|
||||
Field2Measurement = DiagnosticHex.ParseUInt16(fields[10]);
|
||||
|
||||
IntegratorCalibrationPositive = DiagnosticHex.ParseUInt16(fields[11]);
|
||||
IntegratorCalibrationNegative = DiagnosticHex.ParseUInt16(fields[12]);
|
||||
|
||||
AsicState = DiagnosticHex.ParseByte(fields[13]);
|
||||
WaterImpedance = DiagnosticHex.ParseInt16(fields[14]);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"DiagnosticLedState5Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState={AsicState}, WaterImpedance={WaterImpedance}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format: xxxxxx aaaa yyyy vvvvvv cccc tttt bbbbbbbb mmmmmmmm ff iiii ss
|
||||
/// Chars total = 72
|
||||
/// Tabs = 15
|
||||
/// CRLF = 2
|
||||
/// Total bytes = 89
|
||||
/// </summary>
|
||||
/// <returns> Total bytes</returns>
|
||||
public override int GetByteCount()
|
||||
{
|
||||
return 89;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-152
@@ -1,152 +0,0 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #6 data frame.
|
||||
/// <para>
|
||||
/// Frame format: TAB-separated ASCII HEX fields, CRLF terminated.
|
||||
/// </para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term># / Field</term>
|
||||
/// <description>Description</description>
|
||||
/// </listheader>
|
||||
/// <item><term>0 – xxxxxx</term><description>signed 24-bit ADC value</description></item>
|
||||
/// <item><term>1 – aaaa</term><description>unsigned 16-bit Field strength (internal units)</description></item>
|
||||
/// <item><term>2 – yyyy</term><description>signed 16-bit Raw flow rate (1/4 ml per bit)</description></item>
|
||||
/// <item><term>3 – vvvvvv</term><description>unsigned 24-bit Raw volume accumulation (1/4 ml per bit)</description></item>
|
||||
/// <item><term>4 – cccc</term><description>unsigned 16-bit Millivolts delta on field drive capacitor</description></item>
|
||||
/// <item><term>5 – tttt</term><description>unsigned 16-bit Field calibration value</description></item>
|
||||
/// <item><term>6 – bbbbbbbb</term><description>unsigned 32-bit ASIC timestamp (8192 ticks/sec, rolls over at 2^32)</description></item>
|
||||
/// <item><term>7 – ff</term><description>unsigned 8-bit Field drive time in microseconds</description></item>
|
||||
/// <item><term>8 – mmmmmmmm</term><description>signed 32-bit Mean flow rate (rolls over at 2^32)</description></item>
|
||||
/// <item><term>9 – gggg</term><description>unsigned 16-bit Field 1 measurement</description></item>
|
||||
/// <item><term>10 – hhhh</term><description>unsigned 16-bit Field 2 measurement</description></item>
|
||||
/// <item><term>11 – cccc</term><description>unsigned 16-bit Integrator calibration positive</description></item>
|
||||
/// <item><term>12 – nnnn</term><description>unsigned 16-bit Integrator calibration negative</description></item>
|
||||
/// <item><term>13 – qq</term><description>unsigned 8-bit ASIC state 0</description></item>
|
||||
/// <item><term>14 – iiii</term><description>signed 16-bit Water impedance measurement</description></item>
|
||||
/// <item><term>15 – rrrr</term><description>signed 16-bit Electrode delta (mV)</description></item>
|
||||
/// <item><term>16 – pp</term><description>unsigned 8-bit Spike detection diagnostic</description></item>
|
||||
/// <item><term>17 – ll</term><description>unsigned 8-bit Pipe status</description></item>
|
||||
/// <item><term>18 – dddddddd</term><description>unsigned 32-bit LCD volume</description></item>
|
||||
/// <item><term>19 – oo</term><description>unsigned 8-bit ASIC state 1</description></item>
|
||||
/// <item><term>20 – ss</term><description>unsigned 8-bit Checksum</description></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class DiagnosticLedState6Data : DiagnosticLedData
|
||||
{
|
||||
public ushort FieldCalibration { get; }
|
||||
public uint AsicTimestamp { get; }
|
||||
public byte FieldDriveTimeUs { get; }
|
||||
|
||||
public int MeanFlowRate { get; }
|
||||
|
||||
public ushort Field1Measurement { get; }
|
||||
public ushort Field2Measurement { get; }
|
||||
|
||||
public ushort IntegratorCalibrationPositive { get; }
|
||||
public ushort IntegratorCalibrationNegative { get; }
|
||||
|
||||
public byte AsicState0 { get; }
|
||||
|
||||
public short WaterImpedance { get; }
|
||||
public short ElectrodeDeltaMv { get; }
|
||||
|
||||
public byte SpikeDetection { get; }
|
||||
public byte PipeStatus { get; }
|
||||
|
||||
public uint LcdVolume { get; }
|
||||
|
||||
public byte AsicState1 { get; }
|
||||
|
||||
public DiagnosticLedState6Data(string rawLine, string[] fields)
|
||||
: base(rawLine)
|
||||
{
|
||||
// ---- Common fields (0–4) ----
|
||||
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
|
||||
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
|
||||
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
|
||||
RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
|
||||
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
|
||||
|
||||
// ---- State #6 specific ----
|
||||
FieldCalibration = DiagnosticHex.ParseUInt16(fields[5]);
|
||||
AsicTimestamp = DiagnosticHex.ParseUInt32(fields[6]);
|
||||
FieldDriveTimeUs = DiagnosticHex.ParseByte(fields[7]);
|
||||
|
||||
MeanFlowRate = unchecked((int)DiagnosticHex.ParseUInt32(fields[8]));
|
||||
|
||||
Field1Measurement = DiagnosticHex.ParseUInt16(fields[9]);
|
||||
Field2Measurement = DiagnosticHex.ParseUInt16(fields[10]);
|
||||
|
||||
IntegratorCalibrationPositive = DiagnosticHex.ParseUInt16(fields[11]);
|
||||
IntegratorCalibrationNegative = DiagnosticHex.ParseUInt16(fields[12]);
|
||||
|
||||
AsicState0 = DiagnosticHex.ParseByte(fields[13]);
|
||||
|
||||
WaterImpedance = DiagnosticHex.ParseInt16(fields[14]);
|
||||
ElectrodeDeltaMv = DiagnosticHex.ParseInt16(fields[15]);
|
||||
|
||||
SpikeDetection = DiagnosticHex.ParseByte(fields[16]);
|
||||
PipeStatus = DiagnosticHex.ParseByte(fields[17]);
|
||||
|
||||
LcdVolume = DiagnosticHex.ParseUInt32(fields[18]);
|
||||
AsicState1 = DiagnosticHex.ParseByte(fields[19]);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Pipe status interpreted as <see cref="PipeStatus"/>.
|
||||
/// If the value is outside the defined range, returns null.
|
||||
/// </summary>
|
||||
public PipeStatus PipeStatusEnumValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(PipeStatus), PipeStatus))
|
||||
throw new InvalidOperationException(
|
||||
"Unknown pipe status value: 0x" + PipeStatus.ToString("X2"));
|
||||
|
||||
return (PipeStatus)PipeStatus;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Spike Detection interpreted as <see cref="SpikeDetectionStatus"/>.
|
||||
/// If the value is outside the defined range, returns null.
|
||||
/// </summary>
|
||||
public SpikeDetectionStatus SpikeDetectionEnumValue
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(SpikeDetectionStatus), SpikeDetection))
|
||||
throw new InvalidOperationException(
|
||||
"Unknown Spike Detection value: 0x" + SpikeDetection.ToString("X2"));
|
||||
|
||||
return (SpikeDetectionStatus)SpikeDetection;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"DiagnosticLedState6Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState0={AsicState0}, WaterImpedance={WaterImpedance}, SpikeDetection={SpikeDetection}, PipeStatus={PipeStatus}, LcdVolume={LcdVolume}, AsicState1={AsicState1}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format: xxxxxx aaaa yyyy vvvvvv cccc tttt bbbbbbbb mmmmmmmm ff iiii rrrr pp ll dddddddd oo ss
|
||||
/// Chars total = 90
|
||||
/// Tabs = 20
|
||||
/// CRLF = 2
|
||||
/// Total bytes = 112
|
||||
/// </summary>
|
||||
/// <returns> Total bytes</returns>
|
||||
public override int GetByteCount()
|
||||
{
|
||||
return 112;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-155
@@ -1,155 +0,0 @@
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
/// <summary>
|
||||
/// Diagnostic LED State #7 data frame.
|
||||
/// <para>
|
||||
/// Frame format: TAB-separated ASCII HEX fields, CRLF terminated.
|
||||
/// This state extends State #6 with additional ADC and learning diagnostics.
|
||||
/// </para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term># / Field</term>
|
||||
/// <description>Description</description>
|
||||
/// </listheader>
|
||||
/// <item><term>0 – xxxxxx</term><description>signed 24-bit ADC value</description></item>
|
||||
/// <item><term>1 – aaaa</term><description>unsigned 16-bit Field strength (internal units)</description></item>
|
||||
/// <item><term>2 – yyyy</term><description>signed 16-bit Raw flow rate (1/4 ml per bit)</description></item>
|
||||
/// <item><term>3 – vvvvvv</term><description>unsigned 24-bit Raw volume accumulation (1/4 ml per bit)</description></item>
|
||||
/// <item><term>4 – cccc</term><description>unsigned 16-bit Millivolts delta on field drive capacitor</description></item>
|
||||
/// <item><term>5 – tttt</term><description>unsigned 16-bit Field calibration value</description></item>
|
||||
/// <item><term>6 – bbbbbbbb</term><description>unsigned 32-bit ASIC timestamp (8192 ticks/sec)</description></item>
|
||||
/// <item><term>7 – ff</term><description>unsigned 8-bit Field drive time (µs)</description></item>
|
||||
/// <item><term>8 – mmmmmmmm</term><description>signed 32-bit Mean flow rate</description></item>
|
||||
/// <item><term>9 – gggg</term><description>unsigned 16-bit Field 1 measurement</description></item>
|
||||
/// <item><term>10 – hhhh</term><description>unsigned 16-bit Field 2 measurement</description></item>
|
||||
/// <item><term>11 – cccc</term><description>unsigned 16-bit Integrator calibration positive</description></item>
|
||||
/// <item><term>12 – nnnn</term><description>unsigned 16-bit Integrator calibration negative</description></item>
|
||||
/// <item><term>13 – qq</term><description>unsigned 8-bit ASIC state 0</description></item>
|
||||
/// <item><term>14 – iiii</term><description>signed 16-bit Water impedance measurement</description></item>
|
||||
/// <item><term>15 – rrrr</term><description>signed 16-bit Electrode delta (mV)</description></item>
|
||||
/// <item><term>16 – pp</term><description>unsigned 8-bit Spike detection diagnostic</description></item>
|
||||
/// <item><term>17 – ll</term><description>unsigned 8-bit Pipe status</description></item>
|
||||
/// <item><term>18 – dddddddd</term><description>unsigned 32-bit LCD volume</description></item>
|
||||
/// <item><term>19 – oo</term><description>unsigned 8-bit ASIC state 1</description></item>
|
||||
/// <item><term>20 – xxxxxx</term><description>signed 24-bit Raw ADC value (before offset correction)</description></item>
|
||||
/// <item><term>21 – yyyyyy</term><description>signed 24-bit Detrended ADC value</description></item>
|
||||
/// <item><term>22 – iiii</term><description>signed 16-bit Imaginary water impedance</description></item>
|
||||
/// <item><term>23 – nnnn</term><description>unsigned 16-bit Electrode voltage noise level</description></item>
|
||||
/// <item><term>24 – aa</term><description>unsigned 8-bit ADC offset learning status</description></item>
|
||||
/// <item><term>25 – ss</term><description>unsigned 8-bit Checksum</description></item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public sealed class DiagnosticLedState7Data : DiagnosticLedData
|
||||
{
|
||||
// ----- State #6 fields -----
|
||||
|
||||
public ushort FieldCalibration { get; }
|
||||
public uint AsicTimestamp { get; }
|
||||
public byte FieldDriveTimeUs { get; }
|
||||
|
||||
public int MeanFlowRate { get; }
|
||||
|
||||
public ushort Field1Measurement { get; }
|
||||
public ushort Field2Measurement { get; }
|
||||
|
||||
public ushort IntegratorCalibrationPositive { get; }
|
||||
public ushort IntegratorCalibrationNegative { get; }
|
||||
|
||||
public byte AsicState0 { get; }
|
||||
|
||||
public short WaterImpedance { get; }
|
||||
public short ElectrodeDeltaMv { get; }
|
||||
|
||||
public byte SpikeDetection { get; }
|
||||
public byte PipeStatus { get; }
|
||||
|
||||
public uint LcdVolume { get; }
|
||||
|
||||
public byte AsicState1 { get; }
|
||||
|
||||
// ----- State #7 extensions -----
|
||||
|
||||
/// <summary>Raw ADC value before offset correction (signed 24-bit).</summary>
|
||||
public int RawAdcBeforeOffset { get; }
|
||||
|
||||
/// <summary>Detrended ADC value (signed 24-bit).</summary>
|
||||
public int DetrendedAdc { get; }
|
||||
|
||||
/// <summary>Imaginary water impedance (signed 16-bit).</summary>
|
||||
public short ImaginaryWaterImpedance { get; }
|
||||
|
||||
/// <summary>Electrode voltage noise level (unsigned 16-bit).</summary>
|
||||
public ushort ElectrodeVoltageNoise { get; }
|
||||
|
||||
/// <summary>
|
||||
/// ADC offset learning status bitfield.
|
||||
/// Bit 0: currently learning
|
||||
/// Bit 1: completed first learning cycle
|
||||
/// Other bits reserved.
|
||||
/// </summary>
|
||||
public byte AdcOffsetLearningStatus { get; }
|
||||
|
||||
public DiagnosticLedState7Data(string rawLine, string[] fields)
|
||||
: base(rawLine)
|
||||
{
|
||||
// ---- Common fields (0–4) ----
|
||||
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
|
||||
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
|
||||
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
|
||||
RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
|
||||
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
|
||||
|
||||
// ---- State #6 fields ----
|
||||
FieldCalibration = DiagnosticHex.ParseUInt16(fields[5]);
|
||||
AsicTimestamp = DiagnosticHex.ParseUInt32(fields[6]);
|
||||
FieldDriveTimeUs = DiagnosticHex.ParseByte(fields[7]);
|
||||
|
||||
MeanFlowRate = unchecked((int)DiagnosticHex.ParseUInt32(fields[8]));
|
||||
|
||||
Field1Measurement = DiagnosticHex.ParseUInt16(fields[9]);
|
||||
Field2Measurement = DiagnosticHex.ParseUInt16(fields[10]);
|
||||
|
||||
IntegratorCalibrationPositive = DiagnosticHex.ParseUInt16(fields[11]);
|
||||
IntegratorCalibrationNegative = DiagnosticHex.ParseUInt16(fields[12]);
|
||||
|
||||
AsicState0 = DiagnosticHex.ParseByte(fields[13]);
|
||||
|
||||
WaterImpedance = DiagnosticHex.ParseInt16(fields[14]);
|
||||
ElectrodeDeltaMv = DiagnosticHex.ParseInt16(fields[15]);
|
||||
|
||||
SpikeDetection = DiagnosticHex.ParseByte(fields[16]);
|
||||
PipeStatus = DiagnosticHex.ParseByte(fields[17]);
|
||||
|
||||
LcdVolume = DiagnosticHex.ParseUInt32(fields[18]);
|
||||
AsicState1 = DiagnosticHex.ParseByte(fields[19]);
|
||||
|
||||
// ---- State #7 extensions ----
|
||||
RawAdcBeforeOffset = DiagnosticHex.ParseInt24(fields[20]);
|
||||
DetrendedAdc = DiagnosticHex.ParseInt24(fields[21]);
|
||||
ImaginaryWaterImpedance = DiagnosticHex.ParseInt16(fields[22]);
|
||||
ElectrodeVoltageNoise = DiagnosticHex.ParseUInt16(fields[23]);
|
||||
AdcOffsetLearningStatus = DiagnosticHex.ParseByte(fields[24]);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"DiagnosticLedState7Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState0={AsicState0}, WaterImpedance={WaterImpedance}, ElectrodeDeltaMv={ElectrodeDeltaMv}, SpikeDetection={SpikeDetection}, PipeStatus={PipeStatus}, LcdVolume={LcdVolume}, AsicState1={AsicState1}, RawAdcBeforeOffset={RawAdcBeforeOffset}, DetrendedAdc={DetrendedAdc}, ImaginaryWaterImpedance={ImaginaryWaterImpedance}, ElectrodeVoltageNoise={ElectrodeVoltageNoise}, AdcOffsetLearningStatus={AdcOffsetLearningStatus}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Format:
|
||||
/// Chars total = 112
|
||||
/// Tabs = 25
|
||||
/// CRLF = 2
|
||||
/// Total bytes = 139
|
||||
/// </summary>
|
||||
/// <returns> Total bytes</returns>
|
||||
public override int GetByteCount()
|
||||
{
|
||||
return 139;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
public enum PipeStatus : byte
|
||||
{
|
||||
MetroLowFlowCut = 0,
|
||||
MetroFlowReverse = 1,
|
||||
MetroFlowForward = 2,
|
||||
MetroEmptyPipe = 3
|
||||
}
|
||||
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer
|
||||
{
|
||||
public enum SpikeDetectionStatus : byte
|
||||
{
|
||||
NoSpike = 0,
|
||||
AdcSpike = 1,
|
||||
SpikeHoldOff = 2,
|
||||
SpikeHighFlow = 5
|
||||
}
|
||||
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils
|
||||
{
|
||||
internal static class DiagnosticChecksum
|
||||
{
|
||||
public static byte Compute(string lineWithoutChecksum)
|
||||
{
|
||||
byte sum = 0;
|
||||
foreach (char c in lineWithoutChecksum)
|
||||
sum += (byte)c;
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.utils
|
||||
{
|
||||
internal static class DiagnosticHex
|
||||
{
|
||||
public static int ParseInt24(string hex)
|
||||
{
|
||||
int value = Convert.ToInt32(hex, 16);
|
||||
if ((value & 0x800000) != 0)
|
||||
value |= unchecked((int)0xFF000000); // sign extend
|
||||
return value;
|
||||
}
|
||||
|
||||
public static uint ParseUInt24(string hex)
|
||||
{
|
||||
return Convert.ToUInt32(hex, 16);
|
||||
}
|
||||
|
||||
public static short ParseInt16(string hex)
|
||||
{
|
||||
return unchecked((short)Convert.ToUInt16(hex, 16));
|
||||
}
|
||||
|
||||
public static ushort ParseUInt16(string hex)
|
||||
{
|
||||
return Convert.ToUInt16(hex, 16);
|
||||
}
|
||||
|
||||
public static uint ParseUInt32(string hex)
|
||||
{
|
||||
return Convert.ToUInt32(hex, 16);
|
||||
}
|
||||
|
||||
public static byte ParseByte(string hex)
|
||||
{
|
||||
return Convert.ToByte(hex, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger
|
||||
{
|
||||
public static class HexFormatter
|
||||
{
|
||||
/// <summary>
|
||||
/// Formats a single byte as 0xNN.
|
||||
/// Example: 0x0D
|
||||
/// </summary>
|
||||
public static string ToHex(byte value)
|
||||
{
|
||||
return "0x" + value.ToString("X2");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// int to byte securely
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||
public static byte ToHexByte(int value)
|
||||
{
|
||||
if (value < 0 || value > 255)
|
||||
throw new ArgumentOutOfRangeException(nameof(value),
|
||||
"Value must be between 0 and 255.");
|
||||
|
||||
return (byte)value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats a byte array as 0xNN 0xNN ...
|
||||
/// </summary>
|
||||
public static string ToHex(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
return "<empty>";
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
sb.Append(' ');
|
||||
|
||||
sb.Append("0x");
|
||||
sb.Append(data[i].ToString("X2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formats a byte array exactly as shown in serial terminals.
|
||||
/// Example: "0D 04 08 01 00 1A"
|
||||
/// </summary>
|
||||
public static string ToSerialHex(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
return string.Empty;
|
||||
|
||||
var sb = new System.Text.StringBuilder();
|
||||
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
sb.Append(' ');
|
||||
|
||||
sb.Append(data[i].ToString("X2"));
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
public static string ToHexWithAscii(byte value)
|
||||
{
|
||||
char c = (value >= 32 && value <= 126) ? (char)value : '.';
|
||||
return $"0x{value:X2} ('{c}')";
|
||||
}
|
||||
|
||||
public static string ToSerialHexWithAscii(byte[] data)
|
||||
{
|
||||
if (data == null || data.Length == 0)
|
||||
return string.Empty;
|
||||
|
||||
var hex = new StringBuilder(data.Length * 3);
|
||||
var ascii = new StringBuilder(data.Length);
|
||||
|
||||
foreach (byte b in data)
|
||||
{
|
||||
hex.Append(b.ToString("X2")).Append(' ');
|
||||
|
||||
// Printable ASCII range
|
||||
if (b >= 32 && b <= 126)
|
||||
{
|
||||
ascii.Append((char)b);
|
||||
}
|
||||
// Binary numbers 0–9 -> show digit
|
||||
else if (b <= 9)
|
||||
{
|
||||
ascii.Append((char)('0' + b));
|
||||
}
|
||||
else
|
||||
{
|
||||
ascii.Append('.');
|
||||
}
|
||||
}
|
||||
|
||||
// remove last trailing space in hex
|
||||
if (hex.Length > 0)
|
||||
hex.Length--;
|
||||
|
||||
return $"{hex} | {ascii}";
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static string ToHex(int value)
|
||||
{
|
||||
return $"0x{(byte)value:X2}";
|
||||
}
|
||||
|
||||
public static byte[] IntToBytesBE(int value, int byteCount)
|
||||
{
|
||||
var result = new byte[byteCount];
|
||||
|
||||
for (int i = 0; i < byteCount; i++)
|
||||
result[byteCount - 1 - i] = (byte)(value >> (8 * i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] IntToBytesLE(int value, int byteCount)
|
||||
{
|
||||
var result = new byte[byteCount];
|
||||
|
||||
for (int i = 0; i < byteCount; i++)
|
||||
result[i] = (byte)(value >> (8 * i));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] AsciiToBytes(string text)
|
||||
{
|
||||
return string.IsNullOrEmpty(text)
|
||||
? Array.Empty<byte>()
|
||||
: System.Text.Encoding.ASCII.GetBytes(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a hex string to a byte array.
|
||||
/// Like: string hex = "3F 76 65 72 73 3A 20 48 61 72 72 79 20 54 3A 42 38 30 30 2C 20";
|
||||
/// </summary>
|
||||
/// <param name="hex"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public static byte[] HexStringToByteArray(string hex)
|
||||
{
|
||||
if (hex == null)
|
||||
throw new ArgumentNullException(nameof(hex));
|
||||
|
||||
return hex
|
||||
.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(b => byte.Parse(b, NumberStyles.HexNumber, CultureInfo.InvariantCulture))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger
|
||||
{
|
||||
public class IpelHatCommandDecoder
|
||||
{
|
||||
public static string DescribeCommand(byte command)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string DescribeDirection(byte direction)
|
||||
{
|
||||
if (direction == IperlHatProtocol.Constants.Write)
|
||||
return "(WRITE - OUTGOING)";
|
||||
|
||||
if (direction == IperlHatProtocol.Constants.Read)
|
||||
return "(READ - INCOMING)";
|
||||
|
||||
return "INVALID CONTROL BITS (unsupported pattern)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger
|
||||
{
|
||||
public static class IperlHatLogger
|
||||
{
|
||||
public static string DescribeTx(byte[] frame)
|
||||
{
|
||||
if (frame == null || frame.Length < 5)
|
||||
return "Invalid frame";
|
||||
|
||||
if (frame[2] == IperlHatProtocol.Constants.Question)
|
||||
{
|
||||
return
|
||||
"TX Frame\n" +
|
||||
$" START : {HexFormatter.ToHex(frame[0])}\n" +
|
||||
$" DIRECTION : {HexFormatter.ToHex(frame[1])} ({IpelHatCommandDecoder.DescribeDirection(frame[1])})\n" +
|
||||
$" COMMAND : {HexFormatter.ToHexWithAscii(frame[2])}\n" +
|
||||
$" INFO : {HexFormatter.ToSerialHexWithAscii(GetInformatioQuestion(frame))}\n" +
|
||||
$" END : {HexFormatter.ToHex(frame[frame.Length - 1])}\n" +
|
||||
$" RAW : {HexFormatter.ToHex(frame)}";
|
||||
}
|
||||
else
|
||||
{
|
||||
return
|
||||
"TX Frame\n" +
|
||||
$" START : {HexFormatter.ToHex(frame[0])}\n" +
|
||||
$" DIRECTION : {HexFormatter.ToHex(frame[1])} ({HexFormatter.ToHexWithAscii(frame[1])}) {IpelHatCommandDecoder.DescribeDirection(frame[1])}\n" +
|
||||
$" LEN : {HexFormatter.ToHex(frame[2])} - {(int)frame[2]}\n" +
|
||||
$" COMMAND : {HexFormatter.ToHexWithAscii(frame[3])}\n" +
|
||||
$" INFO : {HexFormatter.ToSerialHexWithAscii(GetInformation(frame))}\n" +
|
||||
$" END : {HexFormatter.ToHex(frame[frame.Length - 1])}\n" +
|
||||
$" RAW : {HexFormatter.ToHex(frame)}";
|
||||
}
|
||||
}
|
||||
|
||||
//payload
|
||||
private static byte[] GetInformation(byte[] frame)
|
||||
{
|
||||
int infoLength = frame.Length - 5; // START + DIRECTION + LEN + COMMAND + END
|
||||
if (infoLength <= 0)
|
||||
return Array.Empty<byte>();
|
||||
|
||||
var info = new byte[infoLength];
|
||||
Buffer.BlockCopy(frame, 4, info, 0, infoLength);
|
||||
return info;
|
||||
}
|
||||
|
||||
//payload for question
|
||||
private static byte[] GetInformatioQuestion(byte[] frame)
|
||||
{
|
||||
int infoLength = frame.Length - 4; // START + DIRECTION + COMMAND + END
|
||||
if (infoLength <= 0)
|
||||
return Array.Empty<byte>();
|
||||
|
||||
var info = new byte[infoLength];
|
||||
Buffer.BlockCopy(frame, 3, info, 0, infoLength);
|
||||
return info;
|
||||
}
|
||||
|
||||
public static string DescribeRx(byte[] frame, TouchReadResponse response)
|
||||
{
|
||||
return
|
||||
"RX Frame\n" +
|
||||
$" START : {HexFormatter.ToHex(frame[0])}\n" +
|
||||
$" LEN : {HexFormatter.ToHex(frame[1])} ({frame[1]})\n" +
|
||||
$" CONTROL : {HexFormatter.ToHex(response.Control)}\n" +
|
||||
$" STATUS : {HexFormatter.ToHex(response.Status)} ({DescribeStatus(response.Status)})\n" +
|
||||
$" PAYLOAD : {HexFormatter.ToHex(response.Payload)}\n" +
|
||||
$" RAW : {HexFormatter.ToHex(frame)}";
|
||||
}
|
||||
|
||||
private static string DescribeStatus(byte status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case 0x01: return "Command complete, no errors";
|
||||
case 0x02: return "Unable to execute";
|
||||
case 0x04: return "Unsupported control bits";
|
||||
default: return "Unknown status";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger
|
||||
{
|
||||
public static class TouchReadControlDecoder
|
||||
{
|
||||
public static string Describe(byte control)
|
||||
{
|
||||
if (control == 0x00)
|
||||
return "RF=0 (No response expected)";
|
||||
|
||||
if (control == 0x08)
|
||||
return "RF=1 (Response expected)";
|
||||
|
||||
return "INVALID CONTROL BITS (unsupported pattern)";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger
|
||||
{
|
||||
public static class TouchReadLogger
|
||||
{
|
||||
public static string DescribeTx(byte[] frame)
|
||||
{
|
||||
if (frame == null || frame.Length < 6)
|
||||
return "Invalid frame";
|
||||
|
||||
return
|
||||
"TX Frame\n" +
|
||||
$" START : {HexFormatter.ToHex(frame[0])}\n" +
|
||||
$" LEN : {HexFormatter.ToHex(frame[1])} ({frame[1]})\n" +
|
||||
$" CONTROL : {HexFormatter.ToHex(frame[2])} - {TouchReadControlDecoder.Describe(frame[2])}\n" +
|
||||
$" INFO : {HexFormatter.ToHex(GetInformation(frame))}\n" +
|
||||
$" CHECKSUM: {HexFormatter.ToHex(frame[frame.Length - 2])} {HexFormatter.ToHex(frame[frame.Length - 1])}\n" +
|
||||
$" RAW : {HexFormatter.ToHex(frame)}";
|
||||
}
|
||||
|
||||
private static byte[] GetInformation(byte[] frame)
|
||||
{
|
||||
int infoLength = frame.Length - 5; // CTRL + INFO + CHK(2)
|
||||
if (infoLength <= 0)
|
||||
return Array.Empty<byte>();
|
||||
|
||||
var info = new byte[infoLength];
|
||||
Buffer.BlockCopy(frame, 3, info, 0, infoLength);
|
||||
return info;
|
||||
}
|
||||
|
||||
public static string DescribeRx(byte[] frame, TouchReadResponse response)
|
||||
{
|
||||
return
|
||||
"RX Frame\n" +
|
||||
$" START : {HexFormatter.ToHex(frame[0])}\n" +
|
||||
$" LEN : {HexFormatter.ToHex(frame[1])} ({frame[1]})\n" +
|
||||
$" CONTROL : {HexFormatter.ToHex(response.Control)}\n" +
|
||||
$" STATUS : {HexFormatter.ToHex(response.Status)} ({DescribeStatus(response.Status)})\n" +
|
||||
$" PAYLOAD : {HexFormatter.ToHex(response.Payload)}\n" +
|
||||
$" RAW : {HexFormatter.ToHex(frame)}";
|
||||
}
|
||||
|
||||
private static string DescribeStatus(byte status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case 0x01: return "Command complete, no errors";
|
||||
case 0x02: return "Unable to execute";
|
||||
case 0x04: return "Unsupported control bits";
|
||||
default: return "Unknown status";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.led
|
||||
{
|
||||
public interface ITouchReadLedParser
|
||||
{
|
||||
TouchReadLedData Parse(TouchReadLedMessage message);
|
||||
}
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
using System.Globalization;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.led
|
||||
{
|
||||
public class ShortVariableLedParser : ITouchReadLedParser
|
||||
{
|
||||
public TouchReadLedData Parse(TouchReadLedMessage msg)
|
||||
{
|
||||
return new TouchReadLedData(msg.Raw)
|
||||
{
|
||||
MeterId = msg.Fields[0],
|
||||
Reading = decimal.Parse(msg.Fields[1],
|
||||
CultureInfo.InvariantCulture)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.led
|
||||
{
|
||||
/// <summary>
|
||||
/// Parsed data from a unidirectional TouchRead LED message.
|
||||
/// The exact populated fields depend on the configured reading mode.
|
||||
/// </summary>
|
||||
public sealed class TouchReadLedData
|
||||
{
|
||||
/// <summary>
|
||||
/// Raw LED message including delimiters.
|
||||
/// Example: ";12345678,00012345.67,m3;"
|
||||
/// </summary>
|
||||
public string Raw { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Meter factory ID or serial number (if present).
|
||||
/// </summary>
|
||||
public string MeterId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Customer programmable ID (if present).
|
||||
/// </summary>
|
||||
public string CustomerId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Parsed meter reading value.
|
||||
/// </summary>
|
||||
public decimal? Reading { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Engineering units (e.g. "m3", "ft3", "gal").
|
||||
/// </summary>
|
||||
public string Units { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional alarm/status field (bitfield or text).
|
||||
/// </summary>
|
||||
public string AlarmStatus { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Timestamp when the LED data was received.
|
||||
/// </summary>
|
||||
public DateTime Timestamp { get; }
|
||||
|
||||
public TouchReadLedData(string raw)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(raw))
|
||||
throw new ArgumentException("Raw LED data must not be null or empty.", nameof(raw));
|
||||
|
||||
Raw = raw;
|
||||
Timestamp = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper to safely parse a decimal value using invariant culture.
|
||||
/// </summary>
|
||||
public static decimal? ParseDecimal(string value)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
return null;
|
||||
|
||||
if (decimal.TryParse(
|
||||
value,
|
||||
NumberStyles.Number,
|
||||
CultureInfo.InvariantCulture,
|
||||
out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.led
|
||||
{
|
||||
public class TouchReadLedMessage
|
||||
{
|
||||
public string Raw { get; }
|
||||
public string[] Fields { get; }
|
||||
|
||||
public TouchReadLedMessage(string raw)
|
||||
{
|
||||
Raw = raw ?? throw new ArgumentNullException(nameof(raw));
|
||||
|
||||
if (!raw.StartsWith(";") || !raw.EndsWith(";"))
|
||||
throw new FormatException("Invalid LED message framing");
|
||||
|
||||
string content = raw.Substring(1, raw.Length - 2);
|
||||
Fields = content.Split(',');
|
||||
}
|
||||
}
|
||||
}
|
||||
-140
@@ -1,140 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.protocolCommons
|
||||
{
|
||||
/// <summary>
|
||||
/// Common iPERL TouchRead bidirectional commands.
|
||||
/// These commands consist of a single-byte command code
|
||||
/// placed in the Information field.
|
||||
/// </summary>
|
||||
public enum ProtocolCommand : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple (legacy) commands (e.g. View Factory ID = 0x01)
|
||||
/// </summary>
|
||||
Simple = 0x00,
|
||||
|
||||
/// <summary>
|
||||
/// View Factory ID (ex-works serial number).
|
||||
/// Returns a 0–12 byte ASCII string terminated by NULL.
|
||||
/// Response only if RF flag is set.
|
||||
/// </summary>
|
||||
ViewFactoryId = 0x01,
|
||||
|
||||
/// <summary>
|
||||
/// Set Factory ID (0–12 ASCII characters, NULL terminated).
|
||||
/// Protected by meter seal.
|
||||
/// </summary>
|
||||
SetFactoryId = 0x02,
|
||||
|
||||
/// <summary>
|
||||
/// View Customer Programmable ID (1–12 ASCII characters).
|
||||
/// </summary>
|
||||
ViewProgrammableId = 0x03,
|
||||
|
||||
/// <summary>
|
||||
/// Set Customer Programmable ID (1–12 ASCII characters, NULL terminated).
|
||||
/// </summary>
|
||||
SetProgrammableId = 0x04,
|
||||
|
||||
/// <summary>
|
||||
/// View Version and Type string.
|
||||
/// Example: B1.22,SMW002,B0.02
|
||||
/// </summary>
|
||||
ViewVersionAndType = 0x05,
|
||||
|
||||
/// <summary>
|
||||
/// View Customer Programmable Text (0–20 ASCII characters).
|
||||
/// </summary>
|
||||
ViewProgrammableText = 0x07,
|
||||
|
||||
/// <summary>
|
||||
/// Set Customer Programmable Text (0–20 ASCII characters, NULL terminated).
|
||||
/// </summary>
|
||||
SetProgrammableText = 0x08,
|
||||
|
||||
/// <summary>
|
||||
/// View number of reading digits and decimal shift.
|
||||
/// Payload: uint8 digits, int8 decimal shift.
|
||||
/// </summary>
|
||||
ViewNumberOfReadingDigits = 0x09,
|
||||
|
||||
/// <summary>
|
||||
/// Set number of reading digits and decimal shift.
|
||||
/// Digits range: 4–8, Decimal shift: -5..0.
|
||||
/// </summary>
|
||||
SetNumberOfReadingDigits = 0x0A,
|
||||
|
||||
/// <summary>
|
||||
/// View reading units.
|
||||
/// Returns numeric unit code (m3, ft3, gallons).
|
||||
/// </summary>
|
||||
ViewReadingUnits = 0x0B,
|
||||
|
||||
/// <summary>
|
||||
/// Set reading units.
|
||||
/// Valid values: 0x00=m3, 0x01=ft3, 0x04=US gallons, 0xFF=off.
|
||||
/// </summary>
|
||||
SetReadingUnits = 0x0C,
|
||||
|
||||
/// <summary>
|
||||
/// View reading multiplier (resolution).
|
||||
/// Range: -7..+5 or 0x80 (disabled).
|
||||
/// </summary>
|
||||
ViewReadingMultiplier = 0x0F,
|
||||
|
||||
/// <summary>
|
||||
/// Set reading multiplier (resolution).
|
||||
/// </summary>
|
||||
SetReadingMultiplier = 0x10,
|
||||
|
||||
/// <summary>
|
||||
/// View preset total (volume accumulator).
|
||||
/// Returns 8 ASCII digits + NULL.
|
||||
/// </summary>
|
||||
ViewPresetTotal = 0x13,
|
||||
|
||||
/// <summary>
|
||||
/// Set preset total (0–8 ASCII digits, NULL terminated).
|
||||
/// Protected by meter seal.
|
||||
/// </summary>
|
||||
SetPresetTotal = 0x14,
|
||||
|
||||
/// <summary>
|
||||
/// View reading mode (unidirectional TouchRead format).
|
||||
/// </summary>
|
||||
ViewReadingMode = 0x15,
|
||||
|
||||
/// <summary>
|
||||
/// Set reading mode.
|
||||
/// Values: Short Variable, Extended, Fixed, Smart Meter.
|
||||
/// </summary>
|
||||
SetReadingMode = 0x16,
|
||||
|
||||
/// <summary>
|
||||
/// View build information (firmware details).
|
||||
/// </summary>
|
||||
ViewBuildInformation = 0x17,
|
||||
|
||||
/// <summary>
|
||||
/// View meter state.
|
||||
/// </summary>
|
||||
ViewState = 0x19,
|
||||
|
||||
/// <summary>
|
||||
/// Set meter state (operating mode).
|
||||
/// Protected by meter seal.
|
||||
/// </summary>
|
||||
SetState = 0x1A,
|
||||
|
||||
/// <summary>
|
||||
/// Device-specific command prefix.
|
||||
/// Must be followed by a device sub-command byte.
|
||||
/// </summary>
|
||||
DeviceSpecific = 0xFD,
|
||||
|
||||
/// <summary>
|
||||
/// Question - specific switch to add additional payload request like "vers"
|
||||
/// Mandatory add payload
|
||||
/// </summary>
|
||||
Question = 0x3F,
|
||||
}
|
||||
}
|
||||
-201
@@ -1,201 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.protocolCommons
|
||||
{
|
||||
/// <summary>
|
||||
/// Device-specific TouchRead sub-commands.
|
||||
/// These sub-commands are used together with the
|
||||
/// <see cref="TouchReadCommand.DeviceSpecific"/> (0xFD) command.
|
||||
/// </summary>
|
||||
public enum ProtocolDeviceSubCommand : byte
|
||||
{
|
||||
// ==========================================================
|
||||
// System / Time
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>
|
||||
/// View system time.
|
||||
/// Returns uint32 seconds since 2000-01-01 00:00:00.
|
||||
/// </summary>
|
||||
ViewSystemTime = 0x10,
|
||||
|
||||
/// <summary>
|
||||
/// Set system time.
|
||||
/// Payload: uint32 seconds since 2000-01-01.
|
||||
/// If set to zero, the meter resets and erases data.
|
||||
/// Protected by meter seal.
|
||||
/// </summary>
|
||||
SetSystemTime = 0x11,
|
||||
|
||||
// ==========================================================
|
||||
// Alarm Mask / Alarm Configuration
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>View alarm mask (lower 16 bits).</summary>
|
||||
ViewAlarmMask = 0x31,
|
||||
|
||||
/// <summary>Set alarm mask (lower 16 bits).</summary>
|
||||
SetAlarmMask = 0x32,
|
||||
|
||||
/// <summary>View alarm persistence period (days).</summary>
|
||||
ViewPersistence = 0x33,
|
||||
|
||||
/// <summary>Set alarm persistence period (days).</summary>
|
||||
SetPersistence = 0x34,
|
||||
|
||||
/// <summary>View leak duration (hours).</summary>
|
||||
ViewLeakDuration = 0x35,
|
||||
|
||||
/// <summary>Set leak duration (hours).</summary>
|
||||
SetLeakDuration = 0x36,
|
||||
|
||||
/// <summary>View current alarm states.</summary>
|
||||
ViewAlarms = 0x37,
|
||||
|
||||
/// <summary>Set alarm states (protected by meter seal).</summary>
|
||||
SetAlarms = 0x38,
|
||||
|
||||
// ==========================================================
|
||||
// Manufacture / Counters
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>View manufacture date.</summary>
|
||||
ViewManufactureDate = 0x39,
|
||||
|
||||
/// <summary>Set manufacture date (protected by meter seal).</summary>
|
||||
SetManufactureDate = 0x3A,
|
||||
|
||||
/// <summary>View seconds idle.</summary>
|
||||
ViewSecondsIdle = 0x3B,
|
||||
|
||||
/// <summary>View seconds active.</summary>
|
||||
ViewSecondsActive = 0x3D,
|
||||
|
||||
/// <summary>View seconds used.</summary>
|
||||
ViewSecondsUsed = 0x3F,
|
||||
|
||||
// ==========================================================
|
||||
// Snapshot / Datalog
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>View snapshot data.</summary>
|
||||
ViewSnapshotData = 0x41,
|
||||
|
||||
/// <summary>View datalog duration.</summary>
|
||||
ViewDatalogDuration = 0x43,
|
||||
|
||||
/// <summary>Set datalog duration.</summary>
|
||||
SetDatalogDuration = 0x44,
|
||||
|
||||
/// <summary>Read datalog.</summary>
|
||||
ReadDatalog = 0x45,
|
||||
|
||||
/// <summary>Clear datalog.</summary>
|
||||
ClearDatalog = 0x46,
|
||||
|
||||
// ==========================================================
|
||||
// History
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>View history mask.</summary>
|
||||
ViewHistoryMask = 0x47,
|
||||
|
||||
/// <summary>Set history mask.</summary>
|
||||
SetHistoryMask = 0x48,
|
||||
|
||||
/// <summary>Read history.</summary>
|
||||
ReadHistory = 0x49,
|
||||
|
||||
/// <summary>Clear history.</summary>
|
||||
ClearHistory = 0x4A,
|
||||
|
||||
// ==========================================================
|
||||
// Diagnostics / Status
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>View diagnostics.</summary>
|
||||
ViewDiagnostics = 0x4B,
|
||||
|
||||
/// <summary>Reset diagnostics.</summary>
|
||||
ResetDiagnostics = 0x4C,
|
||||
|
||||
/// <summary>View status file.</summary>
|
||||
ViewStatusFile = 0x4F,
|
||||
|
||||
/// <summary>Set status file (protected by meter seal).</summary>
|
||||
SetStatusFile = 0x50,
|
||||
|
||||
// ==========================================================
|
||||
// Calibration / Configuration
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>View calibration structure.</summary>
|
||||
ViewCalibrationStructure = 0x51,
|
||||
|
||||
/// <summary>Set calibration structure (protected by meter seal).</summary>
|
||||
SetCalibrationStructure = 0x52,
|
||||
|
||||
/// <summary>View calibration.</summary>
|
||||
ViewCalibration = 0x53,
|
||||
|
||||
/// <summary>Set calibration (protected by meter seal).</summary>
|
||||
SetCalibration = 0x54,
|
||||
|
||||
/// <summary>View reboot count.</summary>
|
||||
ViewRebootCount = 0x55,
|
||||
|
||||
/// <summary>Set reboot count (protected by meter seal).</summary>
|
||||
SetRebootCount = 0x56,
|
||||
|
||||
/// <summary>View temperature.</summary>
|
||||
ViewTemperature = 0x57,
|
||||
|
||||
/// <summary>Set temperature (protected by meter seal).</summary>
|
||||
SetTemperature = 0x58,
|
||||
|
||||
// ==========================================================
|
||||
// Diagnostic LED / Hardware
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>
|
||||
/// Set diagnostic LED state.
|
||||
/// Enables or disables high-speed LED serial output.
|
||||
/// <para>
|
||||
/// See <see cref="TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.DiagnosticLedState"/>
|
||||
/// diagnostic LED output modes.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
SetDiagnosticLEDState = 0x60,
|
||||
|
||||
|
||||
// ==========================================================
|
||||
// Build / Firmware Info
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>View iPERL build information.</summary>
|
||||
ViewIPerlBuild = 0x65,
|
||||
|
||||
/// <summary>Set iPERL build (protected by meter seal).</summary>
|
||||
SetIPerlBuild = 0x66,
|
||||
|
||||
// ==========================================================
|
||||
// Bootloader (DANGEROUS – use with care)
|
||||
// ==========================================================
|
||||
|
||||
/// <summary>Enter bootloader mode.</summary>
|
||||
EnterBootloader = 0x81,
|
||||
|
||||
/// <summary>Read FLASH memory.</summary>
|
||||
ReadFlash = 0x82,
|
||||
|
||||
/// <summary>Erase all FLASH memory.</summary>
|
||||
EraseAll = 0x83,
|
||||
|
||||
/// <summary>Erase FLASH segment.</summary>
|
||||
EraseSegment = 0x84,
|
||||
|
||||
/// <summary>Update firmware code.</summary>
|
||||
UpdateCode = 0x85,
|
||||
|
||||
/// <summary>Exit bootloader mode.</summary>
|
||||
ExitBootloader = 0x86
|
||||
}
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.protocolCommons
|
||||
{
|
||||
public enum ProtocolStatuses : byte
|
||||
{
|
||||
Idle = 0x01,
|
||||
Active = 0x02,
|
||||
Inactive = 0x03,
|
||||
|
||||
}
|
||||
}
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol
|
||||
{
|
||||
public sealed class TouchReadFrame
|
||||
{
|
||||
public byte Start { get; }
|
||||
public byte Length { get; }
|
||||
public byte Control { get; }
|
||||
public byte[] Information { get; }
|
||||
public ushort Checksum { get; }
|
||||
|
||||
public TouchReadFrame(
|
||||
byte start,
|
||||
byte length,
|
||||
byte control,
|
||||
byte[] information,
|
||||
ushort checksum)
|
||||
{
|
||||
Start = start;
|
||||
Length = length;
|
||||
Control = control;
|
||||
Information = information ?? Array.Empty<byte>();
|
||||
Checksum = checksum;
|
||||
}
|
||||
}
|
||||
}
|
||||
-125
@@ -1,125 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.protocolCommons;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol
|
||||
{
|
||||
public sealed class TouchReadFrameBuilder
|
||||
{
|
||||
private const byte START = 0x0D;
|
||||
private byte _control;
|
||||
private readonly List<byte> _information = new List<byte>();
|
||||
|
||||
public TouchReadFrameBuilder RequestResponse(bool enabled)
|
||||
{
|
||||
_control = enabled ? (byte)0x08 : (byte)0x00;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TouchReadFrameBuilder AddCommand(ProtocolCommand command)
|
||||
{
|
||||
_information.Add((byte)command);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TouchReadFrameBuilder AddSubCommand(ProtocolDeviceSubCommand subCommand)
|
||||
{
|
||||
if (_information.Count == 0 ||
|
||||
_information[0] != (byte)ProtocolCommand.DeviceSpecific)
|
||||
throw new InvalidOperationException(
|
||||
"Sub-command is only valid for DeviceSpecific (0xFD) commands.");
|
||||
|
||||
_information.Add((byte)subCommand);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TouchReadFrameBuilder AddDeviceCommand(
|
||||
ProtocolDeviceSubCommand subCommand)
|
||||
{
|
||||
_information.Add((byte)ProtocolCommand.DeviceSpecific);
|
||||
_information.Add((byte)subCommand);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TouchReadFrameBuilder AddPayload(byte[] payload)
|
||||
{
|
||||
if (payload != null)
|
||||
_information.AddRange(payload);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public TouchReadFrameBuilder AddDiagnosticLedState(DiagnosticLedState state)
|
||||
{
|
||||
_information.Add((byte)ProtocolCommand.DeviceSpecific);
|
||||
_information.Add((byte)ProtocolDeviceSubCommand.SetDiagnosticLEDState);
|
||||
_information.Add((byte)state);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TouchReadFrameBuilder AddNullTerminatedAscii(string text)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(text))
|
||||
_information.AddRange(
|
||||
System.Text.Encoding.ASCII.GetBytes(text));
|
||||
|
||||
_information.Add(0x00);
|
||||
return this;
|
||||
}
|
||||
|
||||
public TouchReadFrame BuildFrame()
|
||||
{
|
||||
if (_information.Count == 0)
|
||||
throw new InvalidOperationException("No command specified.");
|
||||
|
||||
byte length = (byte)(1 + _information.Count + 2);
|
||||
|
||||
var raw = new List<byte>
|
||||
{
|
||||
START,
|
||||
length,
|
||||
_control
|
||||
};
|
||||
|
||||
raw.AddRange(_information);
|
||||
|
||||
ushort checksum = CalculateChecksum(raw);
|
||||
raw.Add((byte)(checksum >> 8));
|
||||
raw.Add((byte)(checksum & 0xFF));
|
||||
|
||||
return new TouchReadFrame(
|
||||
START,
|
||||
length,
|
||||
_control,
|
||||
_information.ToArray(),
|
||||
checksum);
|
||||
}
|
||||
|
||||
public byte[] BuildBytes()
|
||||
{
|
||||
TouchReadFrame frame = BuildFrame();
|
||||
|
||||
var bytes = new List<byte>
|
||||
{
|
||||
frame.Start,
|
||||
frame.Length,
|
||||
frame.Control
|
||||
};
|
||||
|
||||
bytes.AddRange(frame.Information);
|
||||
bytes.Add((byte)(frame.Checksum >> 8));
|
||||
bytes.Add((byte)(frame.Checksum & 0xFF));
|
||||
|
||||
return bytes.ToArray();
|
||||
}
|
||||
|
||||
public static ushort CalculateChecksum(IEnumerable<byte> data)
|
||||
{
|
||||
ushort sum = 0;
|
||||
foreach (var b in data)
|
||||
sum += b;
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol
|
||||
{
|
||||
public sealed class TouchReadFrameParser
|
||||
{
|
||||
private const byte START = 0x0D;
|
||||
|
||||
public TouchReadResponse Parse(byte[] data)
|
||||
{
|
||||
if (data == null)
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
|
||||
if (data.Length < 6)
|
||||
throw new FormatException("Frame too short.");
|
||||
|
||||
if (data[0] != START)
|
||||
throw new FormatException("Invalid START byte.");
|
||||
|
||||
byte length = data[1];
|
||||
if (length + 2 != data.Length)
|
||||
throw new FormatException("Length mismatch.");
|
||||
|
||||
ushort receivedChecksum =
|
||||
(ushort)((data[data.Length - 2] << 8) |
|
||||
data[data.Length - 1]);
|
||||
|
||||
ushort calculatedChecksum = CalculateChecksum(data, data.Length - 2);
|
||||
if (receivedChecksum != calculatedChecksum)
|
||||
throw new FormatException("Checksum error.");
|
||||
|
||||
byte control = data[2];
|
||||
byte status = data[3];
|
||||
|
||||
byte[] payload = ExtractPayload(data);
|
||||
|
||||
return new TouchReadResponse(control, status, payload);
|
||||
}
|
||||
|
||||
private static ushort CalculateChecksum(byte[] data, int count)
|
||||
{
|
||||
ushort sum = 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
sum += data[i];
|
||||
return sum;
|
||||
}
|
||||
|
||||
private static byte[] ExtractPayload(byte[] data)
|
||||
{
|
||||
// payload exists only if frame longer than:
|
||||
// START + LEN + CTRL + STATUS + CHK_HI + CHK_LO = 6 bytes
|
||||
if (data.Length <= 6)
|
||||
return Array.Empty<byte>();
|
||||
|
||||
int payloadLength = data.Length - 6;
|
||||
byte[] payload = new byte[payloadLength];
|
||||
Buffer.BlockCopy(data, 4, payload, 0, payloadLength);
|
||||
return payload;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol
|
||||
{
|
||||
public static class TouchReadProtocol
|
||||
{
|
||||
public const byte START = 0x0D;
|
||||
|
||||
// Control bits (CNTRL1)
|
||||
public const byte RESPONSE_FLAG = 0x08; // RF
|
||||
}
|
||||
}
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol
|
||||
{
|
||||
public sealed class TouchReadResponse
|
||||
{
|
||||
public byte Control { get; }
|
||||
public byte Status { get; }
|
||||
public byte[] Payload { get; }
|
||||
|
||||
public bool IsOk => Status == 0x01;
|
||||
|
||||
public TouchReadResponse(byte control, byte status, byte[] payload)
|
||||
{
|
||||
Control = control;
|
||||
Status = status;
|
||||
Payload = payload ?? Array.Empty<byte>();
|
||||
}
|
||||
|
||||
public string GetAsciiPayload()
|
||||
{
|
||||
if (Payload.Length == 0)
|
||||
return null;
|
||||
|
||||
int length = Array.IndexOf(Payload, (byte)0x00);
|
||||
if (length < 0)
|
||||
length = Payload.Length;
|
||||
|
||||
return System.Text.Encoding.ASCII.GetString(Payload, 0, length);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using log4net;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
|
||||
{
|
||||
public class OpthoHeadService
|
||||
{
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
using Common;
|
||||
using log4net;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.Utils;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
|
||||
{
|
||||
public class OptoHeadTest : IDisposable
|
||||
{
|
||||
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
|
||||
|
||||
private static SerialDriver serialDriver;
|
||||
|
||||
public static SerialDriver BuildConnection(ISmartReader iHead)
|
||||
{
|
||||
return new SerialDriverBuilder()
|
||||
.WithPort($"COM{iHead.RfidComPortNr}")
|
||||
.WithBaudRate(2400)
|
||||
.WithDataBits(8)
|
||||
.WithParity(Parity.None)
|
||||
.WithStopBits(StopBits.One)
|
||||
.WithTimeouts(4000, 2000)
|
||||
.BuildAndConnect();
|
||||
|
||||
}
|
||||
|
||||
public void CloseConnection()
|
||||
{
|
||||
if (serialDriver != null)
|
||||
serialDriver.CloseConnection();
|
||||
}
|
||||
|
||||
|
||||
public static string ReadRequest_PCB(ISmartReader iHead)
|
||||
{
|
||||
if (iHead.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return "-OK Simulated response-";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (iHead != null)
|
||||
{
|
||||
if (serialDriver == null)
|
||||
serialDriver = BuildConnection(iHead);
|
||||
|
||||
RadioService headService = new RadioService(serialDriver);
|
||||
string serialNo = headService.ReadRequest_PCB(iHead);
|
||||
return serialNo;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (ex.Message.ToString());
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string SetTestMode(ISmartReader iHead)
|
||||
{
|
||||
if (iHead.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return "-OK Simulated response-";
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
if (iHead != null)
|
||||
{
|
||||
if (serialDriver == null)
|
||||
serialDriver = BuildConnection(iHead);
|
||||
|
||||
RadioService headService = new RadioService(serialDriver);
|
||||
string answer = headService.SetTestMode(iHead);
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (ex.Message.ToString());
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static string SetActiveMode(ISmartReader iHead)
|
||||
{
|
||||
if (iHead.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
return "-OK Simulated response-";
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (iHead != null)
|
||||
{
|
||||
if (serialDriver == null)
|
||||
serialDriver = BuildConnection(iHead);
|
||||
|
||||
RadioService headService = new RadioService(serialDriver);
|
||||
string answer = headService.SetActiveMode(iHead);
|
||||
return answer;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return (ex.Message.ToString());
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
CloseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
using Common;
|
||||
using log4net;
|
||||
using TBF.Rig.Modbus.Meret.AdjustableScale;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.IperlHatProtocol;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.protocolCommons;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.wiredProtocol;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.Utils;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication
|
||||
{
|
||||
public class RadioService
|
||||
{
|
||||
|
||||
static string okResponse = "Command complete, no errors";
|
||||
static string errorResponse = "Unable to execute";
|
||||
|
||||
private SerialDriver serialDriver;
|
||||
public RadioService(SerialDriver serialDriver)
|
||||
{
|
||||
this.serialDriver = serialDriver;
|
||||
}
|
||||
|
||||
public string ReadRequest_PCB(ISmartReader iHead)
|
||||
{
|
||||
if (!serialDriver.IsOpen())
|
||||
{
|
||||
serialDriver.Open();
|
||||
}
|
||||
|
||||
var request = new IperlHatFrameBuilder()
|
||||
.RequestResponse(true)
|
||||
.AddCommand(ProtocolCommand.ViewFactoryId)
|
||||
.BuildBytes();
|
||||
|
||||
|
||||
byte[] rawData = serialDriver.SendAndWait(request, 10000);
|
||||
if (rawData == null)
|
||||
return null;
|
||||
|
||||
// parse rawData
|
||||
var parser = new IperlHatFrameParser();
|
||||
IperlHatResponse decoded = parser.Parse(rawData);
|
||||
if (decoded.IsOk)
|
||||
{
|
||||
return decoded.GetAsciiPayload();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public string SetTestMode(ISmartReader iHead)
|
||||
{
|
||||
if (!serialDriver.IsOpen())
|
||||
{
|
||||
serialDriver.Open();
|
||||
}
|
||||
|
||||
//Set LED to state 4
|
||||
byte[] request = new IperlHatFrameBuilder()
|
||||
.AddDiagnosticLedState(DiagnosticLedState.State4)
|
||||
.BuildBytes();
|
||||
|
||||
byte[] rawData = serialDriver.SendAndWait(request, 1000);
|
||||
if (rawData == null)
|
||||
return null;
|
||||
|
||||
|
||||
// parse rawData
|
||||
var parser = new IperlHatFrameParser();
|
||||
IperlHatResponse decoded = parser.Parse(rawData);
|
||||
if (decoded.IsOk)
|
||||
{
|
||||
|
||||
|
||||
//correct or incorrect response
|
||||
//okResponse, errorResponse
|
||||
|
||||
return "Set Test Mode - OK";
|
||||
}
|
||||
|
||||
return "Set Test Mode - FAILED";
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// stop data streaming by LED
|
||||
/// </summary>
|
||||
/// <param name="iHead"></param>
|
||||
/// <returns></returns>
|
||||
public string SetActiveMode(ISmartReader iHead)
|
||||
{
|
||||
if (!serialDriver.IsOpen())
|
||||
{
|
||||
serialDriver.Open();
|
||||
}
|
||||
|
||||
//Set LED to state 1
|
||||
byte[] request = new IperlHatFrameBuilder()
|
||||
.AddDiagnosticLedState(DiagnosticLedState.StateOFF)
|
||||
.BuildBytes();
|
||||
|
||||
byte[] rawData = serialDriver.SendAndWait(request, 1000);
|
||||
if (rawData == null)
|
||||
return null;
|
||||
|
||||
|
||||
// parse rawData
|
||||
var parser = new IperlHatFrameParser();
|
||||
IperlHatResponse decoded = parser.Parse(rawData);
|
||||
if (decoded.IsOk)
|
||||
{
|
||||
|
||||
return "Set Active Mode - OK";
|
||||
}
|
||||
|
||||
return "Set Active Mode - FAILED";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,290 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using FluentNHibernate.Conventions;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.hexLogger;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.Utils
|
||||
{
|
||||
public class SerialDriver : IDisposable
|
||||
{
|
||||
public string ErrorMessage { get; private set; }
|
||||
private List<byte> SerialPortReadBuffer = new List<byte>();
|
||||
|
||||
private SerialPort _serialPort;
|
||||
private readonly List<byte> _binMessages = new List<byte>();
|
||||
private bool _isReading;
|
||||
|
||||
// Stored configuration (used by Builder)
|
||||
private readonly string _portName;
|
||||
private readonly int _baudRate;
|
||||
private readonly int _dataBits;
|
||||
private readonly Parity _parity;
|
||||
private readonly StopBits _stopBits;
|
||||
private readonly int _readTimeout;
|
||||
private readonly int _writeTimeout;
|
||||
|
||||
private readonly ManualResetEvent _responseReceived = new ManualResetEvent(false);
|
||||
|
||||
#region Constructors
|
||||
|
||||
// Default constructor (legacy support)
|
||||
public SerialDriver()
|
||||
{
|
||||
_serialPort = new SerialPort();
|
||||
}
|
||||
|
||||
// Builder constructor
|
||||
internal SerialDriver(
|
||||
string portName,
|
||||
int baudRate,
|
||||
int dataBits,
|
||||
Parity parity,
|
||||
StopBits stopBits,
|
||||
int readTimeout,
|
||||
int writeTimeout)
|
||||
{
|
||||
_portName = portName;
|
||||
_baudRate = baudRate;
|
||||
_dataBits = dataBits;
|
||||
_parity = parity;
|
||||
_stopBits = stopBits;
|
||||
_readTimeout = readTimeout;
|
||||
_writeTimeout = writeTimeout;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Open / Close
|
||||
|
||||
// Builder-based open
|
||||
public bool Open()
|
||||
{
|
||||
return OpenConnection(
|
||||
_portName,
|
||||
_baudRate,
|
||||
_dataBits,
|
||||
_parity,
|
||||
_stopBits,
|
||||
_readTimeout,
|
||||
_writeTimeout
|
||||
);
|
||||
}
|
||||
|
||||
// Legacy API (unchanged)
|
||||
public bool OpenConnection(
|
||||
string comPort,
|
||||
int baudrate,
|
||||
int dataBits,
|
||||
Parity parity,
|
||||
StopBits stopbits,
|
||||
int readTimeout = 1000,
|
||||
int writeTimeout = 1000)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
CloseConnection();
|
||||
|
||||
try
|
||||
{
|
||||
ErrorMessage = string.Empty;
|
||||
|
||||
_serialPort = new SerialPort(comPort, baudrate, parity, dataBits, stopbits)
|
||||
{
|
||||
ReadTimeout = readTimeout,
|
||||
WriteTimeout = writeTimeout
|
||||
};
|
||||
|
||||
_serialPort.DataReceived += DataReceivedHandler;
|
||||
_serialPort.Open();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorMessage = $"COM error: Open failed {comPort}. {ex.Message}";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_serialPort.IsOpen)
|
||||
{
|
||||
ErrorMessage = $"COM error: Can't open {comPort}.";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void CloseConnection()
|
||||
{
|
||||
if (_serialPort != null)
|
||||
{
|
||||
_serialPort.DataReceived -= DataReceivedHandler;
|
||||
if (_serialPort.IsOpen)
|
||||
_serialPort.Close();
|
||||
|
||||
_serialPort.Dispose();
|
||||
_serialPort = null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsOpen() => _serialPort?.IsOpen == true;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Send / Receive
|
||||
|
||||
public bool SendMessage(byte[] sendDataBytes, int length, int readTimeout = 1000, int writeTimeout = 1000)
|
||||
{
|
||||
if (!IsOpen()) return false;
|
||||
if (sendDataBytes.Length == 0) return true;
|
||||
|
||||
try
|
||||
{
|
||||
PrepareReading();
|
||||
|
||||
_serialPort.WriteTimeout = writeTimeout;
|
||||
_serialPort.ReadTimeout = readTimeout;
|
||||
_serialPort.Write(sendDataBytes, 0, length);
|
||||
|
||||
_isReading = true;
|
||||
|
||||
var stopwatch = Stopwatch.StartNew();
|
||||
while (_isReading)
|
||||
{
|
||||
if (stopwatch.ElapsedMilliseconds > readTimeout)
|
||||
{
|
||||
ErrorMessage = "COM error: Receive timeout";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ErrorMessage = $"COM error: Transmit failed {_serialPort.PortName}. {ex.Message}";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void PrepareReading()
|
||||
{
|
||||
_serialPort.DiscardInBuffer();
|
||||
_binMessages.Clear();
|
||||
_responseReceived.Reset();
|
||||
_isReading = true;
|
||||
}
|
||||
|
||||
public byte[] GetRawData()
|
||||
{
|
||||
return _binMessages.ToArray();
|
||||
}
|
||||
|
||||
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (_serialPort == null || !_serialPort.IsOpen) return;
|
||||
|
||||
try
|
||||
{
|
||||
Thread.Sleep(5);
|
||||
|
||||
if (!SerialPortReadBuffer.IsEmpty())
|
||||
{
|
||||
SerialPortReadBuffer.Clear();
|
||||
}
|
||||
|
||||
int iWordCounter = 0;
|
||||
bool isStart = false;
|
||||
bool isQuestion = false;
|
||||
int iLength = 0;
|
||||
while (true)//_serialPort.BytesToRead > 0
|
||||
{
|
||||
byte readByte = (byte)_serialPort.ReadByte();
|
||||
|
||||
//I have START
|
||||
if (readByte == C4.IperlHatProtocol.Constants.Start)
|
||||
{
|
||||
iWordCounter++;
|
||||
isStart = true;
|
||||
}
|
||||
// I have QUESTION
|
||||
if (readByte == C4.IperlHatProtocol.Constants.Question)
|
||||
{
|
||||
iWordCounter++;
|
||||
isQuestion = true;
|
||||
}
|
||||
//I count length from start
|
||||
if (iWordCounter > 0)
|
||||
iWordCounter++;
|
||||
|
||||
if (iWordCounter > 0)
|
||||
{
|
||||
//Store byte to data
|
||||
SerialPortReadBuffer.Add(readByte);
|
||||
}
|
||||
// we have length
|
||||
if (iLength == 0 && isStart && SerialPortReadBuffer.Count > 2 )
|
||||
{
|
||||
iLength = (int)SerialPortReadBuffer[2];
|
||||
}
|
||||
|
||||
//If we have enough bytes
|
||||
if (isStart && iLength > 0 && SerialPortReadBuffer.Count >= iLength)
|
||||
{
|
||||
break;
|
||||
}
|
||||
//if we read END
|
||||
if (isQuestion && readByte == C4.IperlHatProtocol.Constants.End)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (SerialPortReadBuffer.Count > 0)
|
||||
{
|
||||
_binMessages.AddRange(SerialPortReadBuffer.ToArray());
|
||||
_responseReceived.Set();
|
||||
}
|
||||
}
|
||||
catch (TimeoutException te)
|
||||
{
|
||||
// Ignore shutdown race conditions
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isReading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] SendAndWait(byte[] data, int timeoutMs)
|
||||
{
|
||||
if (!IsOpen())
|
||||
throw new InvalidOperationException("Serial port not open");
|
||||
|
||||
PrepareReading();
|
||||
_serialPort.Write(data, 0, data.Length);
|
||||
|
||||
if (!_responseReceived.WaitOne(timeoutMs))
|
||||
{
|
||||
ErrorMessage = "COM error: response timeout";
|
||||
return null;
|
||||
}
|
||||
|
||||
return GetRawData();
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
CloseConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
using System;
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.Utils
|
||||
{
|
||||
public class SerialDriverBuilder
|
||||
{
|
||||
private string _portName;
|
||||
private int _baudRate = 9600;
|
||||
private int _dataBits = 8;
|
||||
private Parity _parity = Parity.None;
|
||||
private StopBits _stopBits = StopBits.One;
|
||||
private int _readTimeout = 1000;
|
||||
private int _writeTimeout = 1000;
|
||||
|
||||
public SerialDriverBuilder WithPort(string portName)
|
||||
{
|
||||
_portName = portName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SerialDriverBuilder WithBaudRate(int baudRate)
|
||||
{
|
||||
_baudRate = baudRate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SerialDriverBuilder WithDataBits(int dataBits)
|
||||
{
|
||||
_dataBits = dataBits;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SerialDriverBuilder WithParity(Parity parity)
|
||||
{
|
||||
_parity = parity;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SerialDriverBuilder WithStopBits(StopBits stopBits)
|
||||
{
|
||||
_stopBits = stopBits;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SerialDriverBuilder WithTimeouts(int readTimeout, int writeTimeout)
|
||||
{
|
||||
_readTimeout = readTimeout;
|
||||
_writeTimeout = writeTimeout;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build driver WITHOUT opening connection
|
||||
/// </summary>
|
||||
public SerialDriver Build()
|
||||
{
|
||||
return new SerialDriver(
|
||||
_portName,
|
||||
_baudRate,
|
||||
_dataBits,
|
||||
_parity,
|
||||
_stopBits,
|
||||
_readTimeout,
|
||||
_writeTimeout
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Build driver AND open connection
|
||||
/// </summary>
|
||||
public SerialDriver BuildAndConnect()
|
||||
{
|
||||
var driver = Build();
|
||||
if (!driver.Open())
|
||||
{
|
||||
throw new InvalidOperationException(driver.ErrorMessage);
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Windows.Forms;
|
||||
using Common;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl.communication;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.common;
|
||||
using TBF.Rig.RegisterReaders.iPerlReaderUNI.test;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
|
||||
{
|
||||
public class IPerlASICImplHeadTestCtrl : 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 StrReadPcbCmd = "ReadPCB";
|
||||
private const string StrSetTestModeCmd = "SetTestMode";
|
||||
private const string StrSetActiveModeCmd = "SetActiveMode";
|
||||
private const string StrReadOptoDataCmd = "ReadOptoData";
|
||||
private const string StrStopReadOptoDataCmd = "StopReadOptoData";
|
||||
private const string StrResetNfcHeadCmd = "ResetNfcHead";
|
||||
private const string StrSetNfcHeadCmd = "SetNfcHead";
|
||||
private const string StrSetRfidHeadCmd = "SetRfidHead";
|
||||
private const string StrEmptyCmd = "";
|
||||
|
||||
public enum Operations
|
||||
{
|
||||
[Description(StrReadPcbCmd)]ReadPcbCmd,
|
||||
[Description(StrSetTestModeCmd)]SetTestModeCmd,
|
||||
[Description(StrSetActiveModeCmd)]SetActiveModeCmd,
|
||||
[Description(StrReadOptoDataCmd)]ReadOptoDataCmd,
|
||||
[Description(StrStopReadOptoDataCmd)]StopReadOptoDataCmd,
|
||||
[Description(StrResetNfcHeadCmd)]ResetNfcHeadCmd,
|
||||
[Description(StrSetNfcHeadCmd)]SetNfcHeadCmd,
|
||||
[Description(StrSetRfidHeadCmd)]SetRfidHeadCmd,
|
||||
[Description(StrEmptyCmd)]EmptyCmd
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static readonly Dictionary<string, Operations> ItemsForIperlOperations = new Dictionary<string, Operations>
|
||||
{
|
||||
{"Read PCB", Operations.ReadPcbCmd},
|
||||
{"Set Test Mode", Operations.SetTestModeCmd},
|
||||
{"Set Active Mode", Operations.SetActiveModeCmd},
|
||||
#if DEBUG
|
||||
{"Start Read Opto Data", Operations.ReadOptoDataCmd},
|
||||
{"Stop Read Opto Data", Operations.StopReadOptoDataCmd},
|
||||
#endif
|
||||
{" ", Operations.EmptyCmd},
|
||||
{"Reset NFC Head", Operations.ResetNfcHeadCmd},
|
||||
{"Set NFC Head Interface", Operations.SetNfcHeadCmd},
|
||||
{"Set RFID Head interface", Operations.SetRfidHeadCmd}
|
||||
};
|
||||
|
||||
public (string Name, string Value)[] GetComboOperationsPairs()
|
||||
{
|
||||
//return ItemsForIperlOperations.Select(kvp => (kvp.Key, kvp.Value)).ToArray();
|
||||
return ItemsForIperlOperations.Select(kvp => (kvp.Key, kvp.Value.ToDescription())).ToArray();
|
||||
}
|
||||
|
||||
public void CommandTestButtonClick(object sender, MouseEventArgs e, Arguments a)
|
||||
{
|
||||
a.RfidOutputListBox.Items.Clear();
|
||||
|
||||
using (Tools.LogChecker logChecker = new Tools.LogChecker("ASIC_RfidData", log4net.Core.Level.Debug))
|
||||
{
|
||||
ListItem rfidListItem = new ListItem();
|
||||
rfidListItem.Attributes.Add("style", "font-weight:bold");
|
||||
Operations selectedOperation;
|
||||
if(!ItemsForIperlOperations.TryGetValue((string)a.RfidCommandComboBox.SelectedValue, out selectedOperation))
|
||||
selectedOperation = Operations.EmptyCmd;
|
||||
|
||||
switch (selectedOperation)
|
||||
{
|
||||
case Operations.ReadPcbCmd:
|
||||
rfidListItem.Text = $"PCB: {OptoHeadTest.ReadRequest_PCB(a.ISmartReader)}";
|
||||
break;
|
||||
case Operations.SetTestModeCmd:
|
||||
rfidListItem.Text = OptoHeadTest.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 Operations.SetActiveModeCmd:
|
||||
rfidListItem.Text = OptoHeadTest.SetActiveMode(a.ISmartReader);
|
||||
stopWorkerThread = true;
|
||||
a.ISmartReader.StopDataStreamProcessing(); // close opto port
|
||||
break;
|
||||
case Operations.ResetNfcHeadCmd:
|
||||
a.ISmartReader.ResetNfcInterface();
|
||||
break;
|
||||
case Operations.SetNfcHeadCmd:
|
||||
a.ISmartReader.SetNfcInterface();
|
||||
break;
|
||||
case Operations.SetRfidHeadCmd:
|
||||
a.ISmartReader.SetRfidInterface();
|
||||
break;
|
||||
case Operations.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 Operations.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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4.diagnosticLed.parserer;
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlASICReader.implementations
|
||||
{
|
||||
public enum OptoTelegramFlags : byte
|
||||
{
|
||||
OK = 0,
|
||||
OK_TestStart,
|
||||
OK_TestEnd,
|
||||
InvalidTelegram, /// Wrong telegram format of checksum error
|
||||
SyncError,
|
||||
}
|
||||
|
||||
public class OptoTelegramRaw
|
||||
{
|
||||
private DiagnosticLedState4Data data;
|
||||
private static CultureInfo culture;
|
||||
///
|
||||
/// Strobed value
|
||||
///
|
||||
public static decimal TestStartTimestampDec;
|
||||
|
||||
///
|
||||
/// Stored values
|
||||
///
|
||||
public OptoTelegramFlags Flags;
|
||||
|
||||
public DateTime DateTime; /// From PC
|
||||
public float RefFlow; /// [m3/h]
|
||||
public int Counter;
|
||||
|
||||
public Int16 FlowRaw;
|
||||
public UInt32 VolumeRaw;
|
||||
public Int64 VolumeRawExt;
|
||||
public UInt32 Timestamp;
|
||||
public Int64 TimestampExt;
|
||||
|
||||
|
||||
///
|
||||
/// Calculated values
|
||||
///
|
||||
public double Flow(double scalingFactor) { return 0.225 * scalingFactor * (double)FlowRaw; }
|
||||
public double Volume(double scalingFactor) { return 0.0000625 * scalingFactor * (double)VolumeRawExt; }
|
||||
public decimal TimestampDec() { return (decimal)TimestampExt / (decimal)8192; }
|
||||
public double VolumeDelta(double scalingFactor,OptoTelegramRaw previous) { return (previous == null) ? 0 : Volume(scalingFactor) - previous.Volume(scalingFactor); }
|
||||
public decimal TimeDelta() { return TimestampDec() - TestStartTimestampDec; }
|
||||
public string Label()
|
||||
{
|
||||
if (Flags == OptoTelegramFlags.OK_TestStart) return "#### start test ####";
|
||||
else if (Flags == OptoTelegramFlags.OK_TestEnd) return "#### end of test ####";
|
||||
else return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
static OptoTelegramRaw()
|
||||
{
|
||||
culture = CultureInfo.CreateSpecificCulture("DE"); /// This is to use comma as decimal number separator
|
||||
}
|
||||
|
||||
public OptoTelegramRaw()
|
||||
{
|
||||
}
|
||||
|
||||
public void UpdateFromSmart(DiagnosticLedState4Data data,int counter, float refFlow, ref Int64 volumeRawExtLast, ref Int64 timestampExtLast)
|
||||
{
|
||||
|
||||
DateTime = DateTime.Now;
|
||||
Counter = counter;
|
||||
RefFlow = refFlow;
|
||||
|
||||
FlowRaw = data.RawFlow;
|
||||
VolumeRaw = data.RawVolume;
|
||||
Timestamp = data.AsicTimestamp;
|
||||
|
||||
|
||||
///
|
||||
/// Cope with 'VolumeRaw' overflow
|
||||
///
|
||||
Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & 0xFFFFFFFFFF000000UL) | VolumeRaw);
|
||||
if (Math.Abs(uncorrected - volumeRawExtLast) <= 0x800000L)
|
||||
{
|
||||
VolumeRawExt = volumeRawExtLast = uncorrected;
|
||||
}
|
||||
else if (Math.Abs(uncorrected + 0x1000000L - volumeRawExtLast) <= 0x800000L)
|
||||
{
|
||||
VolumeRawExt = volumeRawExtLast = uncorrected + 0x1000000L;
|
||||
}
|
||||
else if (Math.Abs(uncorrected - 0x1000000L - volumeRawExtLast) <= 0x800000L)
|
||||
{
|
||||
VolumeRawExt = volumeRawExtLast = uncorrected - 0x1000000L;
|
||||
}
|
||||
else
|
||||
{
|
||||
VolumeRawExt = volumeRawExtLast = uncorrected;
|
||||
}
|
||||
|
||||
///
|
||||
/// Cope with 'Timestamp' overflow
|
||||
///
|
||||
uncorrected = (Int64)(((UInt64)timestampExtLast & 0xFFFFFFFF00000000UL) | Timestamp);
|
||||
if (Math.Abs(uncorrected - timestampExtLast) <= 0x80000000L)
|
||||
{
|
||||
TimestampExt = timestampExtLast = uncorrected;
|
||||
}
|
||||
else if (Math.Abs(uncorrected + 0x100000000L - timestampExtLast) <= 0x80000000L)
|
||||
{
|
||||
TimestampExt = timestampExtLast = uncorrected + 0x100000000L;
|
||||
}
|
||||
else if (Math.Abs(uncorrected - 0x100000000L - timestampExtLast) <= 0x80000000L)
|
||||
{
|
||||
TimestampExt = timestampExtLast = uncorrected - 0x100000000L;
|
||||
}
|
||||
else
|
||||
{
|
||||
TimestampExt = timestampExtLast = uncorrected;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetFlags(OptoTelegramFlags flags)
|
||||
{
|
||||
this.Flags = flags;
|
||||
}
|
||||
|
||||
|
||||
public string ToString(double scalingFactor, OptoTelegramRaw previous)
|
||||
{
|
||||
if (Flags == OptoTelegramFlags.SyncError)
|
||||
{
|
||||
return "Sychronization error";
|
||||
}
|
||||
else if (Flags == OptoTelegramFlags.InvalidTelegram)
|
||||
{
|
||||
return "Invalid telegram";
|
||||
}
|
||||
else /// if (flags == OptoTelegramFlags.OK / OptoTelegramFlags.OK_TestStart / OptoTelegramFlags.OK_TestEnd)
|
||||
{
|
||||
return string.Format("{0}:{1}:{2}.{3}\t{4} :\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}\t{12}\t{13}\t{14}\t{15}",
|
||||
DateTime.Hour.ToString("D2"),
|
||||
DateTime.Minute.ToString("D2"),
|
||||
DateTime.Second.ToString("D2"),
|
||||
DateTime.Millisecond.ToString("D4"),
|
||||
Counter,
|
||||
FlowRaw.ToString("X4"),
|
||||
VolumeRaw.ToString("X6"),
|
||||
Timestamp.ToString("X8"),
|
||||
Flow(scalingFactor).ToString("F2", culture),
|
||||
Volume(scalingFactor).ToString("F4", culture),
|
||||
TimestampDec().ToString("F4", culture),
|
||||
(RefFlow * 1000).ToString("F2", culture),
|
||||
VolumeDelta(scalingFactor, previous).ToString("F4", culture),
|
||||
TimeDelta().ToString("F3", culture),
|
||||
scalingFactor.ToString("F1", culture),
|
||||
Label());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
public IComponentCfgCtrl GetControl(IList<Component> cmpntEntities)
|
||||
{
|
||||
return new iPerlASICReader.IPerlUniCfgCtrl();
|
||||
return new IPerlReader.IPerlUniCfgCtrl();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
muxBoardNrTextBox.Text = config.MuxBoardNr.ToString();
|
||||
groupTextBox.Text = config.Group.ToString();
|
||||
comboBoxCommunicationInterface.SelectedItem = config.CommunicationInterface.ToString();
|
||||
tabPage2.Controls.Add(new iPerlASICReader.IperlASICUniHeadTestCtrl(config));
|
||||
tabPage2.Controls.Add(new IPerlReader.IperlUniHeadTestCtrl(config));
|
||||
}
|
||||
|
||||
public void Unlock()
|
||||
|
||||
@@ -11,7 +11,6 @@ using TBF.Rig.RegisterReaders.CommonRR.IPerl;
|
||||
using TBF.Rig.TestMethods.SmartTest;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
|
||||
|
||||
namespace TBF.Rig.RegisterReaders.iPerlReaderUNI
|
||||
{
|
||||
public class TestMethodCfg : ComponentCfgBase, ITestMethodCfg
|
||||
|
||||
@@ -3,8 +3,6 @@ using log4net;
|
||||
using Sensus.iPerl.RfidCom.Helper;
|
||||
using System;
|
||||
using TBF.Rig.RegisterReaders.CommonRR;
|
||||
using TBF.Rig.RegisterReaders.CommonRR.IPerl;
|
||||
using TBF.Rig.TestMethods.iPerlCommunication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
|
||||
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.implementations;
|
||||
@@ -27,18 +25,7 @@ namespace TBF.Rig.RegisterReaders.iPerlReaderUNI.test
|
||||
try
|
||||
{
|
||||
byte[] pcb = null;
|
||||
|
||||
ITestMethodCfg iTestMethodCfg = SmartCommunicationForm.TestMethodCfg;
|
||||
if (iTestMethodCfg == null)
|
||||
{
|
||||
//TODO find from components
|
||||
TestMethod testMethod = TbfComponents.FindFirstComponentImpl<TestMethod>() as TestMethod;
|
||||
if (testMethod != null)
|
||||
{
|
||||
iTestMethodCfg = testMethod.TestMethodCfg;
|
||||
}
|
||||
}
|
||||
int readRetVal = IPerlCorrections.ReadRequestPort(iTestMethodCfg, iHead, MessageID.Configuration, Sensus.iPerl.NfcHandler.MCI_Protocol.StructName.Configuration, 16, 5, out pcb);
|
||||
int readRetVal = IPerlCorrections.ReadRequestPort(SmartCommunicationForm.TestMethodCfg, iHead, MessageID.Configuration, Sensus.iPerl.NfcHandler.MCI_Protocol.StructName.Configuration, 16, 5, out pcb);
|
||||
if (readRetVal == 0)
|
||||
{
|
||||
return RfidHelper.HexLiteral2Unsigned(RfidHelper.SwapHexcode(BitConverter.ToString(pcb).Replace("-", string.Empty))).ToString();
|
||||
|
||||
@@ -9,7 +9,6 @@ using log4net;
|
||||
using log4net.Repository.Hierarchy;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.Sequences;
|
||||
using TBF.Rig.TestMethods.SmartTest;
|
||||
|
||||
namespace TBF.Rig
|
||||
{
|
||||
@@ -92,6 +91,7 @@ namespace TBF.Rig
|
||||
new Network.Camera.RoiForFixedStartKeyence.Factory(),
|
||||
new Network.Comet.Ambient.Factory(),
|
||||
new Network.RestAPI.Factory(),
|
||||
new Output.DB.DatabaseWriter.Factory(), // 'DatabaseWriter' module implements more store specific modules
|
||||
new Output.DB.ProductionTracing.Factory(),
|
||||
new Output.DB.SaveDiverterCorrections.Factory(),
|
||||
new Output.DB.SaveFlowmeterCorrections.Factory(),
|
||||
@@ -135,11 +135,11 @@ namespace TBF.Rig
|
||||
new RegisterReaders.FrequencyMeterFromUniCB.Factory(), ///
|
||||
//new RegisterReaders.iPerlReaderUNI.Factory(), /// 'UNI RegisterReader for Smart Meters'
|
||||
new RegisterReaders.PoseidonReader.Factory(),
|
||||
new RegisterReaders.IPerlReader.Factory(), /// the same functionality as TestMethods.iPerlCommunication.iPerlHead.Factory(),
|
||||
new RegisterReaders.iPerlASICReader.Factory(), /// ASIC IPerl, C4 communication
|
||||
new RegisterReaders.IPerlReader.Factory(), /// the same functionality as TestMethods.iPerlCommunication.iPerlHead.Factory(),
|
||||
new RegisterReaders.PulsesFromUniCB.Factory(), /// 'RegisterReader'
|
||||
new RegisterReaders.StandingStartStop.Factory(), /// 'RegisterReader for standing start/stop'
|
||||
new TestMethods.iPerlCommunication.iPerlHead.Factory(), /// 'RegisterReader for iPerl'
|
||||
new TestMethods.GenesisCommunication.GenesisHead.Factory(), /// 'RegisterReader for Cordonel'
|
||||
new RegisterReaders.S640Stream.Factory(), /// 'RegisterReader for S640'
|
||||
new RegisterReaders.SerialStream.Factory(), /// 'RegisterReader for generic serial stream'
|
||||
new RegisterReaders.PoseidonCmdStartStop.Factory(), /// 'RegisterReader for poseidon start/stop'
|
||||
@@ -192,7 +192,6 @@ namespace TBF.Rig
|
||||
new TestMethods.FlyingStartTankCollection.Compound.Factory(),
|
||||
new TestMethods.GrabImage.Factory(),
|
||||
new TestMethods.iPerlCommunication.TestMethodFactory(), /// iPerlCommunication
|
||||
new TestMethods.SmartTest.TestMethodFactory(), /// Smart Meter Tests
|
||||
new TestMethods.LeakTest.Factory(),
|
||||
new TestMethods.LiveStream.Factory(),
|
||||
new TestMethods.ManualEntry.Factory(),
|
||||
|
||||
@@ -6,10 +6,13 @@ using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using log4net;
|
||||
using Common;
|
||||
using Config.Entities;
|
||||
using Results.Entities;
|
||||
using TBF.Rig;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using TBF.Boxes;
|
||||
using TBF.Resources;
|
||||
using TBF.Rig.TestMethods.GenesisCommunication.GenesisHead;
|
||||
using TBF.UiBridge;
|
||||
|
||||
namespace TBF.Rig.TestMethods.FlyingStart
|
||||
@@ -135,6 +138,8 @@ namespace TBF.Rig.TestMethods.FlyingStart
|
||||
Bridge.OnTestSelected(this, new TestSelectedEventArgs(test, repetitionNr, inPath, benchPath, outPath, sensPath, heatMetersPath));
|
||||
string testName = Results.Utils.GetTestName(test.Name, test.Repeats, repetitionNr);
|
||||
TestStartTime = DateTime.Now;
|
||||
// Genesis switch
|
||||
bool atleastOneGenesis = GenesisHeadBatch.Start(sensPath.RegisterReaders, Program.LocalSettings.LastSNTexts);
|
||||
|
||||
///
|
||||
/// Optionally display prompt to emerge temperature meters to appropriate baths for heat meters test
|
||||
@@ -323,6 +328,20 @@ namespace TBF.Rig.TestMethods.FlyingStart
|
||||
|
||||
temperature_set:
|
||||
|
||||
//TODO genesis - check with genesis switch
|
||||
if (atleastOneGenesis)
|
||||
{
|
||||
if (test.Name.ToLower().Contains("calib"))
|
||||
{
|
||||
GenesisHeadBatch.BatchHolder.Value.MetersLogin();
|
||||
GenesisHeadBatch.BatchHolder.Value.MetersInitCalibration();
|
||||
|
||||
} else if (test.Name.ToLower().Contains("Init"))
|
||||
{
|
||||
GenesisHeadBatch.BatchHolder.Value.MetersLogin();
|
||||
GenesisHeadBatch.BatchHolder.Value.MetersInitMeasurement();
|
||||
}
|
||||
}
|
||||
///
|
||||
/// Prepare cameras, ROI-s and measurementOperations
|
||||
///
|
||||
@@ -358,7 +377,12 @@ namespace TBF.Rig.TestMethods.FlyingStart
|
||||
|
||||
foreach (var rr in sensPath.RegisterReaders)
|
||||
{
|
||||
if (rr is IRegReaderDatastream) (rr as IRegReaderDatastream).TestIsGoingToStartSoon(test, repetitionNr);
|
||||
if (rr is IRegReaderDatastream)
|
||||
(rr as IRegReaderDatastream).TestIsGoingToStartSoon(test, repetitionNr);
|
||||
|
||||
if (rr is GenesisHead) // Genesis - CORDONEL head
|
||||
(rr as GenesisHead).StartRead(test.Name, BatchRslts.Batch.BatchNr, repetitionNr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -426,8 +450,21 @@ namespace TBF.Rig.TestMethods.FlyingStart
|
||||
|
||||
/// Measurement loop end
|
||||
StopRecordingStatistics();
|
||||
|
||||
//TODO genesis - check with genesis switch
|
||||
if (atleastOneGenesis)
|
||||
{
|
||||
if (test.Name.ToLower().Contains("calib"))
|
||||
{
|
||||
GenesisHeadBatch.BatchHolder.Value.MetersStopCalibration();
|
||||
}
|
||||
else if (test.Name.ToLower().Contains("Init"))
|
||||
{
|
||||
GenesisHeadBatch.BatchHolder.Value.MetersStopMeasurement();
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
//------------------------------------------------
|
||||
Bridge.OnActivity(this, Strings.Test_completed);
|
||||
//------------------------------------------------
|
||||
|
||||
@@ -589,6 +626,7 @@ namespace TBF.Rig.TestMethods.FlyingStart
|
||||
GenericDevices.IRegReaderDatastream dstrReader = regReader as GenericDevices.IRegReaderDatastream;
|
||||
TestMethods.iPerlCommunication.iPerlHead.IperlHead iPerl = regReader as TestMethods.iPerlCommunication.iPerlHead.IperlHead;
|
||||
GenericDevices.IRegReaderLiveCamera cameraRoi = regReader as GenericDevices.IRegReaderLiveCamera;
|
||||
GenesisHead Genesis = regReader as GenesisHead;
|
||||
|
||||
if (meterRslt != null && regReader != null)
|
||||
{
|
||||
@@ -596,83 +634,147 @@ namespace TBF.Rig.TestMethods.FlyingStart
|
||||
meterRslt.PulsesPerLiter = regReader.PulsesPerLtr;
|
||||
meterRslt.PulsesMeter = Convert.ToDouble(regReader.WMPulses);
|
||||
|
||||
if (dstrReader != null)
|
||||
{
|
||||
meterRslt.TimestampStart = dstrReader.TimestampSecStart;
|
||||
meterRslt.TimestampEnd = dstrReader.NoSamples ? (dstrReader.TimestampSecStart + tstRslt.TestTime) : dstrReader.TimestampSecEnd;
|
||||
meterRslt.TestTime = meterRslt.TimestampEnd - meterRslt.TimestampStart;
|
||||
meterRslt.VolumeStart = dstrReader.VolumeLtrStart; /// liter
|
||||
meterRslt.VolumeEnd = dstrReader.VolumeLtrEnd; /// liter
|
||||
meterRslt.VolumeMeter = Math.Abs(dstrReader.VolumeLtrEnd - dstrReader.VolumeLtrStart);
|
||||
meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
|
||||
meterRslt.PulsesMaster = tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
|
||||
|
||||
if (Genesis != null)
|
||||
{
|
||||
Genesis.Stop(tstRslt.TestTime, tstRslt.VolumeCTV);
|
||||
|
||||
if (iPerl != null)
|
||||
meterRslt.TimestampStart = Genesis.TimestampSecStart;
|
||||
meterRslt.TimestampEnd = Genesis.TimestampSecEnd;
|
||||
meterRslt.TestTime = Genesis.WMTestTime;
|
||||
meterRslt.VolumeStart = Genesis.BeginWMState;
|
||||
meterRslt.VolumeEnd = Genesis.EndWMState; /// liter
|
||||
meterRslt.VolumeMeter = Math.Abs(Genesis.WMVolume);
|
||||
meterRslt.VolumeRef = tstRslt.VolumeCTV;
|
||||
if (GenesisHeadBatch.MeterIdDetailResults == null)
|
||||
{
|
||||
if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode & (int)Results.Entities.ResultCode.OptoErrorCodeMask) == 0)
|
||||
Genesis.Log("MeterIdDetailResults na!");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Genesis.DetailedResults != null)
|
||||
{
|
||||
meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
|
||||
try
|
||||
{
|
||||
GenesisHeadBatch.MeterIdDetailResults.Add(meterRslt.SerialNr(), Genesis.DetailedResults);
|
||||
}
|
||||
catch (Exception ex) { Genesis.Log(ex.Message.ToString()); }
|
||||
}
|
||||
#if IPERL
|
||||
meterRslt.WaterMeter.CalibFactor = iPerl.CalibFactor;
|
||||
meterRslt.ExtraDataPath = iPerl.ExtraDataPath;
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 1) meterRslt.X1 = iPerl.X[0];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 2) meterRslt.X2 = iPerl.X[1];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 3) meterRslt.X3 = iPerl.X[2];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 4) meterRslt.X4 = iPerl.X[3];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 5) meterRslt.X5 = iPerl.X[4];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 6) meterRslt.X6 = iPerl.X[5];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 7) meterRslt.X7 = iPerl.X[6];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 8) meterRslt.X8 = iPerl.X[7];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 9) meterRslt.X9 = iPerl.X[8];
|
||||
#endif
|
||||
iPerl.LastTestResult2 = iPerl.LastTestResult; /// Save shift previous test result
|
||||
iPerl.LastTestResult = meterRslt; /// Save this test result
|
||||
}
|
||||
}
|
||||
else if (cameraRoi != null)
|
||||
{
|
||||
meterRslt.TimestampStart = cameraRoi.TimestampStart; /// second
|
||||
meterRslt.TimestampEnd = cameraRoi.TimestampEnd; /// second
|
||||
|
||||
meterRslt.VolumeStart = cameraRoi.VolumeStart; /// liter
|
||||
meterRslt.VolumeEnd = cameraRoi.VolumeEnd; /// liter
|
||||
meterRslt.VolumeMeter = cameraRoi.VolumeEnd - cameraRoi.VolumeStart; /// liter
|
||||
|
||||
if (meterRslt.VolumeMeter != 0)
|
||||
{
|
||||
/// Normal measurement with camera
|
||||
meterRslt.TestTime = cameraRoi.TimestampEnd - cameraRoi.TimestampStart; /// second
|
||||
meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
|
||||
meterRslt.PulsesMaster = tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// None or one pulse from the water meter using camera
|
||||
meterRslt.TestTime = tstRslt.TestTime;
|
||||
meterRslt.VolumeRef = tstRslt.VolumeCTV;
|
||||
meterRslt.PulsesMaster = tstRslt.PulsesMaster;
|
||||
else
|
||||
{
|
||||
Genesis.Log("DetailedResults na!");
|
||||
}
|
||||
}
|
||||
|
||||
Genesis.Log("VolumeRef=" + meterRslt.VolumeRef);
|
||||
Genesis.Log("TestTime Meter =" + meterRslt.TestTime + "S, test time ref =" + tstRslt.TestTime + "s");
|
||||
Genesis.Log(" results for " + test.Name);
|
||||
Genesis.Log(" Ref Vol = " + meterRslt.VolumeRef + " m³");
|
||||
Genesis.Log(" Ref Time = " + tstRslt.TestTime + " s");
|
||||
Genesis.Log(" Meter Time = " + meterRslt.TestTime + " s");
|
||||
Genesis.Log(" Meter Vol = " + meterRslt.VolumeMeter + " m³");
|
||||
|
||||
var calError = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef);
|
||||
Genesis.Log(" MeterError = " + calError.ToString() + " %");
|
||||
}
|
||||
else
|
||||
{
|
||||
meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
|
||||
meterRslt.VolumeStart = 0;
|
||||
meterRslt.VolumeEnd = 0;
|
||||
meterRslt.VolumeMeter = meterRslt.PulsesMeter * regReader.LtrsPerPulse; /// liter
|
||||
///
|
||||
if (regReader.WMPulses >= 1)
|
||||
{
|
||||
/// Normal measurement
|
||||
meterRslt.TestTime = cBrd.TestTimeWM(regReader.Position);
|
||||
meterRslt.VolumeRef = meterRslt.PulsesMaster * tstRslt.ConstMaster; /// liter
|
||||
}
|
||||
else
|
||||
{
|
||||
/// None or one pulse from the water meter
|
||||
meterRslt.TestTime = tstRslt.TestTime;
|
||||
meterRslt.VolumeRef = tstRslt.VolumeCTV; /// liter
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dstrReader != null)
|
||||
{
|
||||
meterRslt.TimestampStart = dstrReader.TimestampSecStart;
|
||||
meterRslt.TimestampEnd = dstrReader.NoSamples
|
||||
? (dstrReader.TimestampSecStart + tstRslt.TestTime)
|
||||
: dstrReader.TimestampSecEnd;
|
||||
meterRslt.TestTime = meterRslt.TimestampEnd - meterRslt.TimestampStart;
|
||||
meterRslt.VolumeStart = dstrReader.VolumeLtrStart; /// liter
|
||||
meterRslt.VolumeEnd = dstrReader.VolumeLtrEnd; /// liter
|
||||
meterRslt.VolumeMeter =
|
||||
Math.Abs(dstrReader.VolumeLtrEnd - dstrReader.VolumeLtrStart);
|
||||
meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
|
||||
meterRslt.PulsesMaster =
|
||||
tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
|
||||
|
||||
if (iPerl != null)
|
||||
{
|
||||
if (iPerl.ResultCode != 0 && (meterRslt.WaterMeter.ResultCode &
|
||||
(int)Results.Entities.ResultCode
|
||||
.OptoErrorCodeMask) == 0)
|
||||
{
|
||||
meterRslt.WaterMeter.ResultCode |= iPerl.ResultCode;
|
||||
}
|
||||
#if IPERL
|
||||
meterRslt.WaterMeter.CalibFactor = iPerl.CalibFactor;
|
||||
meterRslt.ExtraDataPath = iPerl.ExtraDataPath;
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 1)
|
||||
meterRslt.X1 = iPerl.X[0];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 2)
|
||||
meterRslt.X2 = iPerl.X[1];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 3)
|
||||
meterRslt.X3 = iPerl.X[2];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 4)
|
||||
meterRslt.X4 = iPerl.X[3];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 5)
|
||||
meterRslt.X5 = iPerl.X[4];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 6)
|
||||
meterRslt.X6 = iPerl.X[5];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 7)
|
||||
meterRslt.X7 = iPerl.X[6];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 8)
|
||||
meterRslt.X8 = iPerl.X[7];
|
||||
if (TestMethods.iPerlCommunication.iPerlHead.IperlHead.FeatureVectorSize >= 9)
|
||||
meterRslt.X9 = iPerl.X[8];
|
||||
#endif
|
||||
iPerl.LastTestResult2 =
|
||||
iPerl.LastTestResult; /// Save shift previous test result
|
||||
iPerl.LastTestResult = meterRslt; /// Save this test result
|
||||
}
|
||||
}
|
||||
else if (cameraRoi != null)
|
||||
{
|
||||
meterRslt.TimestampStart = cameraRoi.TimestampStart; /// second
|
||||
meterRslt.TimestampEnd = cameraRoi.TimestampEnd; /// second
|
||||
|
||||
meterRslt.VolumeStart = cameraRoi.VolumeStart; /// liter
|
||||
meterRslt.VolumeEnd = cameraRoi.VolumeEnd; /// liter
|
||||
meterRslt.VolumeMeter = cameraRoi.VolumeEnd - cameraRoi.VolumeStart; /// liter
|
||||
|
||||
if (meterRslt.VolumeMeter != 0)
|
||||
{
|
||||
/// Normal measurement with camera
|
||||
meterRslt.TestTime =
|
||||
cameraRoi.TimestampEnd - cameraRoi.TimestampStart; /// second
|
||||
meterRslt.VolumeRef = tstRslt.VolumeCTV * meterRslt.TestTime / tstRslt.TestTime;
|
||||
meterRslt.PulsesMaster =
|
||||
tstRslt.PulsesMaster * meterRslt.TestTime / tstRslt.TestTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// None or one pulse from the water meter using camera
|
||||
meterRslt.TestTime = tstRslt.TestTime;
|
||||
meterRslt.VolumeRef = tstRslt.VolumeCTV;
|
||||
meterRslt.PulsesMaster = tstRslt.PulsesMaster;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
meterRslt.PulsesMaster = Convert.ToDouble(regReader.WMRefPulses);
|
||||
meterRslt.VolumeStart = 0;
|
||||
meterRslt.VolumeEnd = 0;
|
||||
meterRslt.VolumeMeter = meterRslt.PulsesMeter * regReader.LtrsPerPulse; /// liter
|
||||
///
|
||||
if (regReader.WMPulses >= 1)
|
||||
{
|
||||
/// Normal measurement
|
||||
meterRslt.TestTime = cBrd.TestTimeWM(regReader.Position);
|
||||
meterRslt.VolumeRef = meterRslt.PulsesMaster * tstRslt.ConstMaster; /// liter
|
||||
}
|
||||
else
|
||||
{
|
||||
/// None or one pulse from the water meter
|
||||
meterRslt.TestTime = tstRslt.TestTime;
|
||||
meterRslt.VolumeRef = tstRslt.VolumeCTV; /// liter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
meterRslt.Error = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef);
|
||||
@@ -724,10 +826,14 @@ namespace TBF.Rig.TestMethods.FlyingStart
|
||||
/// Append the results to the CSV-file
|
||||
allResults.Info(TestResult2CsvLine(testName, test.Part));
|
||||
|
||||
//TODO genesis - process result writing
|
||||
//ProcessDatabaseResultsWriting(test, tstRslt);
|
||||
|
||||
if (stopCycle) retVal = Event.ErrorFlagsStop;
|
||||
|
||||
stopTest:
|
||||
|
||||
GenesisHeadBatch.BatchHolder.Value.RemoveAllMeters();
|
||||
StopRecordingStatistics();
|
||||
|
||||
cBrd.StopAll(false);
|
||||
@@ -748,8 +854,36 @@ namespace TBF.Rig.TestMethods.FlyingStart
|
||||
return new List<Event> { retVal };
|
||||
}
|
||||
|
||||
//backup how work genesis - not a clean code!
|
||||
// private void ProcessDatabaseResultsWriting(Test test, TestRslt tstRslt)
|
||||
// {
|
||||
// IList<Event> e;
|
||||
// if (!String.IsNullOrEmpty(test.Procedure.ResultsWriter))
|
||||
// {
|
||||
// string[] writers = StateMachine.Procedure.ResultsWriter.Split(new char[] { '~' });
|
||||
// foreach (var writerName in writers)
|
||||
// {
|
||||
// IResultsWriter writer = TbfComponents.FindComponent(writerName) as IResultsWriter;
|
||||
// if (writer != null && writer is )
|
||||
// {
|
||||
// var SensusLaWriter = ((DB.SensusLa.Database)writer);
|
||||
//
|
||||
// State.Create(string.Format("{0}({1}) : Store results into db.", test.Method, test.Name))
|
||||
// .AddOperation(checkUiOp)
|
||||
// .AddOperation(SensusLaWriter.WriteResultsOp(tstRslt, BatchRslts, GenesisHeadBatch.MeterIdDetailResults))
|
||||
// .EnterState();
|
||||
// do
|
||||
// {
|
||||
// e = StateMachine.WaitRunDevsRunOps();
|
||||
// }
|
||||
// while (!e.Contains(Event.Error) && !e.Contains(Event.ResultsWritten) && !e.Contains(Event.ResultsNotWritten));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
IList<Event> Simulate(Config.Entities.Test test, int repetitionNr, bool isLastRepetition,
|
||||
|
||||
IList<Event> Simulate(Config.Entities.Test test, int repetitionNr, bool isLastRepetition,
|
||||
Compound.TestParams compoundTestParams,
|
||||
HeatMeters.TestParams heatMetersTestParams,
|
||||
Common.DebugMode debugLevel)
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication.GenesisHead
|
||||
{
|
||||
public class CalibrationStruct
|
||||
{
|
||||
public static readonly int Length = 35;
|
||||
|
||||
public Byte Version;
|
||||
public MeterType MeterType;
|
||||
public UInt16 Calibration;
|
||||
public VolumeUnits VolumeUnits;
|
||||
public FlowArrow FlowArrow;
|
||||
public UInt16 FWVersion;
|
||||
public UInt16[] TargetField;
|
||||
public UInt16 RecipMeanCurrent;
|
||||
public UInt16 ThresholdVolume;
|
||||
public UInt16 ThresholdTime;
|
||||
public UInt16 FlowActivationThr;
|
||||
public UInt16 VolumeArrowThr;
|
||||
public UInt32 CalibrationTime;
|
||||
public ulong SerialNumber;
|
||||
public MeterSealed MeterSealed;
|
||||
public byte CheckSum;
|
||||
|
||||
|
||||
public CalibrationStruct()
|
||||
{
|
||||
TargetField = new UInt16[3];
|
||||
}
|
||||
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
byte[] result = new byte[Length];
|
||||
|
||||
result[0] = Version;
|
||||
result[1] = (byte)MeterType;
|
||||
|
||||
result[2] = (byte)(Calibration & 0x00FF);
|
||||
result[3] = (byte)((Calibration >> 8) & 0x00FF);
|
||||
|
||||
result[4] = (byte)VolumeUnits;
|
||||
|
||||
result[5] = (byte)FlowArrow;
|
||||
|
||||
result[6] = (byte)(FWVersion & 0x00FF);
|
||||
result[7] = (byte)((FWVersion >> 8) & 0x00FF);
|
||||
|
||||
result[8] = (byte)( TargetField[0] & 0x00FF);
|
||||
result[9] = (byte)((TargetField[0] >> 8) & 0x00FF);
|
||||
result[10] = (byte)( TargetField[1] & 0x00FF);
|
||||
result[11] = (byte)((TargetField[1] >> 8) & 0x00FF);
|
||||
result[12] = (byte)( TargetField[2] & 0x00FF);
|
||||
result[13] = (byte)((TargetField[2] >> 8) & 0x00FF);
|
||||
|
||||
result[14] = (byte)(RecipMeanCurrent & 0x00FF);
|
||||
result[15] = (byte)((RecipMeanCurrent >> 8) & 0x00FF);
|
||||
|
||||
result[16] = (byte)(ThresholdVolume & 0x00FF);
|
||||
result[17] = (byte)((ThresholdVolume >> 8) & 0x00FF);
|
||||
|
||||
result[18] = (byte)(ThresholdTime & 0x00FF);
|
||||
result[19] = (byte)((ThresholdTime >> 8) & 0x00FF);
|
||||
|
||||
result[20] = (byte)(FlowActivationThr & 0x00FF);
|
||||
result[21] = (byte)((FlowActivationThr >> 8) & 0x00FF);
|
||||
|
||||
result[22] = (byte)(VolumeArrowThr & 0x00FF);
|
||||
result[23] = (byte)((VolumeArrowThr >> 8) & 0x00FF);
|
||||
|
||||
result[24] = (byte)(CalibrationTime & 0x000000FF);
|
||||
result[25] = (byte)((CalibrationTime >> 8) & 0x000000FF);
|
||||
result[26] = (byte)((CalibrationTime >> 16) & 0x000000FF);
|
||||
result[27] = (byte)((CalibrationTime >> 24) & 0x000000FF);
|
||||
|
||||
result[28] = (byte)(SerialNumber & 0x00000000000000FF);
|
||||
result[29] = (byte)((SerialNumber >> 8) & 0x00000000000000FF);
|
||||
result[30] = (byte)((SerialNumber >> 16) & 0x00000000000000FF);
|
||||
result[31] = (byte)((SerialNumber >> 24) & 0x00000000000000FF);
|
||||
result[32] = (byte)((SerialNumber >> 32) & 0x00000000000000FF);
|
||||
|
||||
result[33] = (byte)MeterSealed;
|
||||
result[34] = CheckSum;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a calibration structure from a complete byte array
|
||||
/// </summary>
|
||||
/// <param name="data">A complete byte array data</param>
|
||||
/// <returns>CalibrationStruct or null when byte array was not complete</returns>
|
||||
public static CalibrationStruct FromByteArray(byte[] data)
|
||||
{
|
||||
if (data.Length != Length) return null;
|
||||
|
||||
CalibrationStruct result = new CalibrationStruct();
|
||||
|
||||
result.Version = data[0];
|
||||
result.MeterType = (MeterType)data[1];
|
||||
result.Calibration = (UInt16)(data[2] + 256 * data[3]);
|
||||
result.VolumeUnits = (VolumeUnits)data[4];
|
||||
result.FlowArrow = (FlowArrow)data[5];
|
||||
result.FWVersion = (UInt16)(data[6] + 256 * data[7]);
|
||||
result.TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
|
||||
result.TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
|
||||
result.TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
|
||||
result.RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
|
||||
result.ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
|
||||
result.ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
|
||||
result.FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
|
||||
result.VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
|
||||
result.CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
|
||||
result.SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
|
||||
result.MeterSealed = (MeterSealed)data[33];
|
||||
result.CheckSum = data[34];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the calibration structure from an incomplete byte array
|
||||
/// </summary>
|
||||
/// <param name="data">Byte array data</param>
|
||||
/// <param name="offset">Offset of byte array data in CalibrationStruct</param>
|
||||
/// <returns>true when successful, false when data are not appropriate</returns>
|
||||
public bool Update(byte[] data, int offset)
|
||||
{
|
||||
if (offset == 2 && data.Length == 2)
|
||||
{
|
||||
/// Data containing iPerl calibration factor
|
||||
Calibration = (UInt16)(data[2 - offset] + 256 * data[3 - offset]);
|
||||
return true;
|
||||
}
|
||||
else if (offset == 0 && data.Length == Length)
|
||||
{
|
||||
/// Data containing a complete CalibrationStruct
|
||||
Version = data[0];
|
||||
MeterType = (MeterType)data[1];
|
||||
Calibration = (UInt16)(data[2] + 256 * data[3]);
|
||||
VolumeUnits = (VolumeUnits)data[4];
|
||||
FlowArrow = (FlowArrow)data[5];
|
||||
FWVersion = (UInt16)(data[6] + 256 * data[7]);
|
||||
TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
|
||||
TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
|
||||
TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
|
||||
RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
|
||||
ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
|
||||
ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
|
||||
FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
|
||||
VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
|
||||
CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
|
||||
SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
|
||||
MeterSealed = (MeterSealed)data[33];
|
||||
CheckSum = data[34];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public string FWVersionStr()
|
||||
{
|
||||
int d1 = (FWVersion >> 8) & 0x000F;
|
||||
int d2 = (FWVersion >> 12) & 0x000F;
|
||||
int d3 = (FWVersion >> 4) & 0x000F;
|
||||
int d4 = FWVersion & 0x000F;
|
||||
return string.Format("{0}.{1}{2}{3}", d1, d2, d3, d4);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Calibration: V{0} Type={1} Cal={2} Units={3} FlowArrow.{4} FW={5} Hi={6} Norm={7} Low={8} RMC={9} ThrVol={10} ThrTime={11} FlActThr={12} VolArrThr={13} CalTm={14} SN={15} MeterSealed={16} Chksum={17}",
|
||||
Version,
|
||||
MeterType,
|
||||
Calibration,
|
||||
VolumeUnits,
|
||||
FlowArrow,
|
||||
FWVersion,
|
||||
TargetField[0],
|
||||
TargetField[1],
|
||||
TargetField[2],
|
||||
RecipMeanCurrent,
|
||||
ThresholdVolume,
|
||||
ThresholdTime,
|
||||
FlowActivationThr,
|
||||
VolumeArrowThr,
|
||||
CalibrationTime,
|
||||
SerialNumber,
|
||||
MeterSealed,
|
||||
CheckSum.ToString("X2"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication.GenesisHead
|
||||
{
|
||||
public class ConfigStruct
|
||||
{
|
||||
public const int Length = 32;
|
||||
|
||||
public Byte Version; /// 0: 1 byte
|
||||
public MeterState MeterState; /// 1: 1 byte
|
||||
public UInt32 TargetTimeVeryLowBatt; /// 2: 4 bytes in seconds
|
||||
public UInt32 TargetTimeLowBatt; /// 6: 4 bytes, in seconds
|
||||
public UInt32 TestModeTime; /// 10: 4 bytes, Max. test mode time in seconds
|
||||
public UInt16 EmptyPipeThreshold; /// 14: 2 bytes
|
||||
public byte[] PCBNumber; /// 16: 5 bytes
|
||||
public byte TestModeConfig; /// 21: 1 byte
|
||||
public UInt32 RadioAddress; /// 22: 4 bytes
|
||||
public UInt16 TempCalibration; /// 26: 2 bytes
|
||||
public UInt16 AlarmMask; /// 28: 2 bytes, Default 0xA3F7
|
||||
public UInt16 ConfigCheckSum; /// 30: 2 bytes
|
||||
|
||||
public ConfigStruct()
|
||||
{
|
||||
PCBNumber = new byte[5];
|
||||
}
|
||||
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
byte[] result = new byte[Length];
|
||||
|
||||
result[0] = Version;
|
||||
result[1] = (byte)MeterState;
|
||||
|
||||
result[2] = (byte)(TargetTimeVeryLowBatt & 0x000000FF);
|
||||
result[3] = (byte)((TargetTimeVeryLowBatt >> 8) & 0x000000FF);
|
||||
result[4] = (byte)((TargetTimeVeryLowBatt >> 16) & 0x000000FF);
|
||||
result[5] = (byte)((TargetTimeVeryLowBatt >> 24) & 0x000000FF);
|
||||
|
||||
result[6] = (byte)(TargetTimeLowBatt & 0x000000FF);
|
||||
result[7] = (byte)((TargetTimeLowBatt >> 8) & 0x000000FF);
|
||||
result[8] = (byte)((TargetTimeLowBatt >> 16) & 0x000000FF);
|
||||
result[9] = (byte)((TargetTimeLowBatt >> 24) & 0x000000FF);
|
||||
|
||||
result[10] = (byte)(TestModeTime & 0x000000FF);
|
||||
result[11] = (byte)((TestModeTime >> 8) & 0x000000FF);
|
||||
result[12] = (byte)((TestModeTime >> 16) & 0x000000FF);
|
||||
result[13] = (byte)((TestModeTime >> 24) & 0x000000FF);
|
||||
|
||||
result[14] = (byte)(EmptyPipeThreshold & 0x00FF);
|
||||
result[15] = (byte)((EmptyPipeThreshold >> 8) & 0x00FF);
|
||||
|
||||
result[16] = PCBNumber[0];
|
||||
result[17] = PCBNumber[1];
|
||||
result[18] = PCBNumber[2];
|
||||
result[19] = PCBNumber[3];
|
||||
result[20] = PCBNumber[4];
|
||||
|
||||
result[21] = TestModeConfig;
|
||||
|
||||
result[22] = (byte)(RadioAddress & 0x000000FF);
|
||||
result[23] = (byte)((RadioAddress >> 8) & 0x000000FF);
|
||||
result[24] = (byte)((RadioAddress >> 16) & 0x000000FF);
|
||||
result[25] = (byte)((RadioAddress >> 24) & 0x000000FF);
|
||||
|
||||
result[26] = (byte)(TempCalibration & 0x00FF);
|
||||
result[27] = (byte)((TempCalibration >> 8) & 0x00FF);
|
||||
|
||||
result[28] = (byte)(AlarmMask & 0x00FF);
|
||||
result[29] = (byte)((AlarmMask >> 8) & 0x00FF);
|
||||
|
||||
result[30] = (byte)(ConfigCheckSum & 0x00FF);
|
||||
result[31] = (byte)((ConfigCheckSum >> 8) & 0x00FF);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a configuration structure from a complete byte array
|
||||
/// </summary>
|
||||
/// <param name="data">A complete byte array data</param>
|
||||
/// <returns>ConfigStruct or null when byte array was not complete</returns>
|
||||
public static ConfigStruct FromByteArray(byte[] data)
|
||||
{
|
||||
if (data.Length != Length) return null;
|
||||
|
||||
ConfigStruct result = new ConfigStruct();
|
||||
|
||||
result.Version = data[0];
|
||||
result.MeterState = (MeterState)data[1];
|
||||
result.TargetTimeVeryLowBatt = (((UInt32)data[5] * 256 + data[4]) * 256 + data[3]) * 256 + data[2];
|
||||
result.TargetTimeLowBatt = (((UInt32)data[9] * 256 + data[8]) * 256 + data[7]) * 256 + data[6];
|
||||
result.TestModeTime = (((UInt32)data[13] * 256 + data[12]) * 256 + data[11]) * 256 + data[10];
|
||||
result.EmptyPipeThreshold = (UInt16)(data[15] * 256 + data[14]);
|
||||
result.PCBNumber[0] = data[16];
|
||||
result.PCBNumber[1] = data[17];
|
||||
result.PCBNumber[2] = data[18];
|
||||
result.PCBNumber[3] = data[19];
|
||||
result.PCBNumber[4] = data[20];
|
||||
result.TestModeConfig = data[21];
|
||||
result.RadioAddress = (((UInt32)data[25] * 256 + data[24]) * 256 + data[23]) * 256 + data[22];
|
||||
result.TempCalibration = (UInt16)(data[27] * 256 + data[26]);
|
||||
result.AlarmMask = (UInt16)(data[29] * 256 + data[28]);
|
||||
result.ConfigCheckSum = (UInt16)(data[31] * 256 + data[30]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update the configuration structure from an incomplete byte array
|
||||
/// </summary>
|
||||
/// <param name="offset">Offset of byte array data in ConfigStruct</param>
|
||||
/// <param name="data">Byte array data</param>
|
||||
/// <returns>true when successful, false when data are not appropriate</returns>
|
||||
public bool Update(int offset, byte[] data)
|
||||
{
|
||||
if (offset == 0 && data.Length == 2)
|
||||
{
|
||||
/// iPerl mode of function
|
||||
Version = data[0];
|
||||
MeterState = (MeterState)data[1];
|
||||
return true;
|
||||
}
|
||||
else if (offset == 0 && data.Length == 4)
|
||||
{
|
||||
/// iPerl mode of function and extra 2 bytes
|
||||
Version = data[0];
|
||||
MeterState = (MeterState)data[1];
|
||||
return true;
|
||||
}
|
||||
else if (offset == 21 && data.Length == 1)
|
||||
{
|
||||
/// TestModeConfig value
|
||||
TestModeConfig = data[21 - offset];
|
||||
return true;
|
||||
}
|
||||
else if (offset == 0 && data.Length == Length)
|
||||
{
|
||||
/// Complete ConfigStruct
|
||||
Version = data[0];
|
||||
MeterState = (MeterState)data[1];
|
||||
TargetTimeVeryLowBatt = (((UInt32)data[5] * 256 + data[4]) * 256 + data[3]) * 256 + data[2];
|
||||
TargetTimeLowBatt = (((UInt32)data[9] * 256 + data[8]) * 256 + data[7]) * 256 + data[6];
|
||||
TestModeTime = (((UInt32)data[13] * 256 + data[12]) * 256 + data[11]) * 256 + data[10];
|
||||
EmptyPipeThreshold = (UInt16)(data[15] * 256 + data[14]);
|
||||
PCBNumber[0] = data[16];
|
||||
PCBNumber[1] = data[17];
|
||||
PCBNumber[2] = data[18];
|
||||
PCBNumber[3] = data[19];
|
||||
PCBNumber[4] = data[20];
|
||||
TestModeConfig = data[21];
|
||||
RadioAddress = (((UInt32)data[25] * 256 + data[24]) * 256 + data[23]) * 256 + data[22];
|
||||
TempCalibration = (UInt16)(data[27] * 256 + data[26]);
|
||||
AlarmMask = (UInt16)(data[29] * 256 + data[28]);
|
||||
ConfigCheckSum = (UInt16)(data[31] * 256 + data[30]);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns PCB number string (12 characters, 12 decimal digits)
|
||||
/// </summary>
|
||||
/// <returns>PCB number STRING</returns>
|
||||
public string GetPcbNrString()
|
||||
{
|
||||
return PCBNumber2String(this.PCBNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts PCBNumber to string (12 characters, 12 decimal digits)
|
||||
/// </summary>
|
||||
/// <param name="pcbNumber"></param>
|
||||
/// <returns>PCB number string</returns>
|
||||
public static string PCBNumber2String(byte[] pcbNumber)
|
||||
{
|
||||
if (pcbNumber.Length != 5) return string.Empty;
|
||||
|
||||
Int64 number = 0;
|
||||
for (int i = 4; i >= 0; i--)
|
||||
{
|
||||
number = 256 * number + (Int64)pcbNumber[i];
|
||||
}
|
||||
|
||||
return number.ToString();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("Config: V{0} State={1} VLoBattT={2}s LoBattT={3}s TestModeT={4}s EPThld={5} PCB#={6} TMCfg={7} RadioAddr={8} TempCalib={9} AlarmMask={10} CfgCheckSum={11}",
|
||||
Version,
|
||||
MeterState,
|
||||
TargetTimeVeryLowBatt,
|
||||
TargetTimeLowBatt,
|
||||
TestModeTime,
|
||||
EmptyPipeThreshold,
|
||||
GetPcbNrString(),
|
||||
TestModeConfig.ToString("X2"),
|
||||
RadioAddress,
|
||||
TempCalibration,
|
||||
AlarmMask.ToString("X4"),
|
||||
ConfigCheckSum.ToString("X4"));
|
||||
}
|
||||
|
||||
public string ToString(int sel)
|
||||
{
|
||||
return string.Format("{1} PCB#={6} TMCfg={7}",
|
||||
Version,
|
||||
MeterState,
|
||||
TargetTimeVeryLowBatt,
|
||||
TargetTimeLowBatt,
|
||||
TestModeTime,
|
||||
EmptyPipeThreshold,
|
||||
GetPcbNrString(),
|
||||
TestModeConfig.ToString("X2"),
|
||||
RadioAddress,
|
||||
TempCalibration,
|
||||
AlarmMask.ToString("X4"),
|
||||
ConfigCheckSum.ToString("X4"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication.GenesisHead
|
||||
{
|
||||
public enum MessageID
|
||||
{
|
||||
Calibration = 0x00, /// Access to stCalibration
|
||||
Configuration = 0x01, /// Access to stConfig
|
||||
Status = 0x02, /// Access to stStaus, read only
|
||||
Power = 0x03, /// Access to stPower, containing power info from both processors
|
||||
LCD = 0x04, /// Access to stLCD
|
||||
EventData = 0x05, /// NOT USED
|
||||
IntervalData = 0x06, /// NOT USED
|
||||
Diagnostics = 0x07, /// Access tostMetroDiagArray, read onl
|
||||
MetrologyMemory = 0x08, /// Memory block access, read only
|
||||
Error_LongAck = 0x09, /// Error message
|
||||
Command = 0x0A, /// Command to execute, with no arguments
|
||||
Parameterizing = 0x0B, /// Parameterizing message is used in MCI-SPI interface only
|
||||
Error_ShortAck = 0x0C, /// Short acknowledge message is used in MCI-SPI interface only
|
||||
ChanelAlive = 0x0D, /// Channel alive message is used in MCI-SPI interface only
|
||||
RadioPassthrough = 0x0E, /// RFID <-> Metrology <-> Radio passthrough message
|
||||
ASICRegisterReadTest = 0x0F, /// ASIC Register read test
|
||||
IMIDebugMessagesAccess = 0x10, /// IMI debug messages read test
|
||||
ProductionChecksumsRead = 0x11, /// Production checksum read: Calibration (1 byte), Configuration (2 bytes), spare (4 bytes)
|
||||
HardwareParametersTest = 0x12, /// Hardware Parameters Testing: User configurable fixed field drive time (1 byte)
|
||||
/// <summary>
|
||||
/// Notes:
|
||||
/// 1. Short Ack message contains 1-byte error code and all the fields (Offset, Payload length, payload and password) will not be present.
|
||||
/// 2. Channel Alive message does not contain the fields (Offset, Payload length, payload and password).
|
||||
/// 3. Except the above two special messages, rest all the messages in the above table will follow the message format mentioned in sections 3.1 and 3.2.
|
||||
/// </summary>
|
||||
Count /// Number of MessageID-s
|
||||
}
|
||||
|
||||
public enum MeterType : byte
|
||||
{
|
||||
DN15 = 0,
|
||||
CoaxManifold = 1,
|
||||
DN20 = 2,
|
||||
DN25 = 3,
|
||||
DN26 = 4, /// DN25*
|
||||
DN32 = 5,
|
||||
DN40 = 6,
|
||||
AutoDetect,
|
||||
Count /// Number of meter types
|
||||
}
|
||||
|
||||
public enum VolumeUnits : byte
|
||||
{
|
||||
m3 = 0,
|
||||
UK_gallon = 1,
|
||||
US_gallon = 2,
|
||||
Count /// Number of volume units
|
||||
}
|
||||
|
||||
public enum FlowArrow : byte
|
||||
{
|
||||
No = 0,
|
||||
Right = 1,
|
||||
Left = 2,
|
||||
Count /// Number of flow arrows
|
||||
}
|
||||
|
||||
public enum MeterSealed : byte
|
||||
{
|
||||
InProduction = 0x00,
|
||||
OutOfProduction = 0xA5,
|
||||
Sealed = 0x5A,
|
||||
}
|
||||
|
||||
public enum MeterState : byte
|
||||
{
|
||||
None = 0,
|
||||
Idle = 1,
|
||||
Active = 2,
|
||||
Test = 3,
|
||||
EndOfLife = 4,
|
||||
Count /// Number of meter states
|
||||
}
|
||||
|
||||
public enum FlowState : byte
|
||||
{
|
||||
No = 0,
|
||||
Reverse = 1,
|
||||
Forward = 2,
|
||||
EmptyPipe = 3,
|
||||
Count /// Number of flow states
|
||||
}
|
||||
|
||||
public enum OptoTelegramFlags : byte
|
||||
{
|
||||
OK = 0,
|
||||
OK_TestStart,
|
||||
OK_TestEnd,
|
||||
InvalidTelegram, /// Wrong telegram format of checksum error
|
||||
SyncError,
|
||||
}
|
||||
|
||||
public enum OptoState
|
||||
{
|
||||
Read,
|
||||
Flush,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
///
|
||||
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
||||
///
|
||||
using System.Collections.Generic;
|
||||
using TBF.Rig.Generic;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication.GenesisHead
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return "RegisterReader for Genesis"; } }
|
||||
|
||||
public void ResetStaticProperties() { GenesisHead.ResetStaticProperties(); }
|
||||
|
||||
public IComponent DummyComponent() { return new GenesisHead(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new GenesisHead(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new GenesisHeadCfg(this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(GenesisHeadCfg.Serializer, component, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,636 @@
|
||||
using Config.Entities;
|
||||
using log4net;
|
||||
///
|
||||
/// Copyright (c) 2015-2018 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using TBF.Rig.Generic;
|
||||
using TBF.Rig.GenericDevices;
|
||||
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
||||
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
||||
using Xylem.Common.Metrology.Measurements;
|
||||
using Xylem.Common.Metrology.Measurements.Consts;
|
||||
using Common;
|
||||
using System.IO.Ports;
|
||||
|
||||
namespace TBF.Rig.TestMethods.GenesisCommunication.GenesisHead
|
||||
{
|
||||
public static class GenesisHeadBatch
|
||||
{
|
||||
public static Dictionary<string, List<MeasurementResults>> MeterIdDetailResults = new Dictionary<string, List<MeasurementResults>>();
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(GenesisHeadBatch));
|
||||
public static readonly Lazy<MeterBatch> BatchHolder = new Lazy<MeterBatch>(() =>
|
||||
{
|
||||
return new MeterBatch();
|
||||
});
|
||||
|
||||
internal static bool Start(IRegReader[] registerReaders, string[] lastSNTexts)
|
||||
{
|
||||
try
|
||||
{
|
||||
MeterIdDetailResults = new Dictionary<string, List<MeasurementResults>>();
|
||||
int index = 0;
|
||||
var ret = false;
|
||||
foreach (var rr in registerReaders)
|
||||
{
|
||||
if (rr is TestMethods.GenesisCommunication.GenesisHead.GenesisHead)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(lastSNTexts[index]))
|
||||
{
|
||||
var myGenesis = ((TestMethods.GenesisCommunication.GenesisHead.GenesisHead)rr).SetUp();
|
||||
myGenesis.SerialNumber = lastSNTexts[index];
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
index = index + 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log.Fatal(ex.Message, ex);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// This component = instance of this class is a placeholder for a combined main watermeter
|
||||
/// </summary>
|
||||
public class GenesisHead : ComponentBase, IDevice, GenericDevices./*IRegisterReader*/IRegReader, IOperation
|
||||
{
|
||||
public List<MeasurementResults> DetailedResults { get; set; }
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(GenesisHead));
|
||||
public override string ToString() { return string.Format("Genesis({0})", Cfg.ToString(1)); }
|
||||
|
||||
public RegisterReaderType RegisterReaderType { get { return RegisterReaderType.DataStream; } }
|
||||
|
||||
private readonly GenesisHeadCfg genesisHeadCfg;
|
||||
public int SlotNr { get { return genesisHeadCfg.SlotNr; } }
|
||||
public double PulsesPerLtr { get { return 1000.0; } }
|
||||
public double LtrsPerPulse { get { return 1 / PulsesPerLtr; } }
|
||||
public int Position { get; }//...MF
|
||||
|
||||
// Adding the missing static method to resolve the error. ...MF
|
||||
public static void ResetStaticProperties()
|
||||
{
|
||||
// Add logic to reset static properties here, if applicable.
|
||||
// If no static properties exist, this method can remain empty.
|
||||
}
|
||||
|
||||
#if ORACLE_DB
|
||||
public int WMType_ID { get { return iperlHeadCfg.ProcParams.WMType_ID; } } /// Required by Oracle DB
|
||||
public int WMType_Rev { get { return iperlHeadCfg.ProcParams.WMType_Rev; } } /// Required by Oracle DB
|
||||
#endif
|
||||
public float CalibTarget { get { return (ushort)genesisHeadCfg.ProcParams.CalibTarget; } }
|
||||
public ushort FactorLimitLo { get { return (ushort)genesisHeadCfg.ProcParams.FactorLimitLo; } }
|
||||
public ushort FactorLimitHi { get { return (ushort)genesisHeadCfg.ProcParams.FactorLimitHi; } }
|
||||
|
||||
/// Properties set by the Begin and the End form
|
||||
//todo rd implement
|
||||
public string SerialNr;
|
||||
|
||||
|
||||
public string EndState
|
||||
{
|
||||
get { return endState; }
|
||||
set { endState = value; }
|
||||
}
|
||||
|
||||
private string endState;
|
||||
|
||||
public string BeginState
|
||||
{
|
||||
get { return beginState; }
|
||||
set { beginState = value; }
|
||||
}
|
||||
|
||||
private string beginState;
|
||||
|
||||
public bool Disabled
|
||||
{
|
||||
get { return disabled; }
|
||||
set { disabled = value; }
|
||||
}
|
||||
|
||||
private bool disabled;
|
||||
|
||||
public bool CommFailed
|
||||
{
|
||||
get { return commFailed; }
|
||||
set { commFailed = value; }
|
||||
}
|
||||
|
||||
private bool commFailed;
|
||||
|
||||
public int ResultCode
|
||||
{
|
||||
get { return resultCode; }
|
||||
}
|
||||
|
||||
private int resultCode;
|
||||
|
||||
|
||||
/// <summary> ConfigStruct of the water meter obtained or updated by iPerlCommunication </summary>
|
||||
public ConfigStruct ConfigStruct
|
||||
{
|
||||
get { return configStruct; }
|
||||
set { configStruct = value; }
|
||||
}
|
||||
|
||||
private ConfigStruct configStruct;
|
||||
|
||||
/// <summary> CalibrationStruct of the water meter obtained or updated by iPerlCommunication </summary>
|
||||
public CalibrationStruct CalibrationStruct
|
||||
{
|
||||
get { return calibrationStruct; }
|
||||
set { calibrationStruct = value; }
|
||||
}
|
||||
|
||||
private CalibrationStruct calibrationStruct;
|
||||
|
||||
public ushort OrigCalibFactor;
|
||||
public ushort CalibFactor { get { return (CalibrationStruct != null) ? CalibrationStruct.Calibration : (ushort)0; } }
|
||||
|
||||
public double Q2ErrWOCorrection;
|
||||
public bool Q2CorrectionDone;
|
||||
public double Q2Correction;
|
||||
public int Q2CorrRFlow;
|
||||
public int Q2CorrLFlow;
|
||||
|
||||
public double Diff2Hz8Hz;
|
||||
public bool Hz2CorrectionDone;
|
||||
public int Hz2Correction;
|
||||
|
||||
public string FWVersion { get { return (CalibrationStruct != null) ? CalibrationStruct.FWVersionStr() : string.Empty; } }
|
||||
|
||||
|
||||
/// <summary> Result of the last test used to calculate Q2 correction factors, etc </summary>
|
||||
public Results.Entities.MeterTestRslt LastTestResult2;
|
||||
public Results.Entities.MeterTestRslt LastTestResult;
|
||||
public double NominalTestFlowLph; /// in liter per hour
|
||||
|
||||
|
||||
///
|
||||
/// Required for IRegisterReader interface
|
||||
///
|
||||
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 WMTestTime { get { return wmTestTime; } }
|
||||
|
||||
private double beginWMState;
|
||||
private double endWMState;
|
||||
private double wmVolume;
|
||||
private int wmPulses;
|
||||
private int wmRefPulses;
|
||||
private double wmTestTime;
|
||||
|
||||
|
||||
/// <summary> Name set by the test, to be used as a part of the opto-data log file name </summary>
|
||||
public string TestName;
|
||||
|
||||
/// <summary> Name set by the test, to be used as a part of the opto-data log file name </summary>
|
||||
public string BenchName;
|
||||
|
||||
///
|
||||
/// Volume of water from the opto telegram
|
||||
///
|
||||
private Int64 lastVolumeRaw; /// Last read raw volume
|
||||
private double volumeLtr; ///
|
||||
private double volumeLtr0;
|
||||
|
||||
|
||||
///
|
||||
/// Timestamp from the opto telegram
|
||||
///
|
||||
private double timestampSec;
|
||||
private double timestampSec0;
|
||||
|
||||
public bool NoSamples { get { return (timestampSecEnd - timestampSecStart) < float.Epsilon; } }
|
||||
public double TimestampSecStart { get { return timestampSecStart; } }
|
||||
public double TimestampSecEnd { get { return timestampSecEnd; } }
|
||||
|
||||
private double timestampSecStart;
|
||||
private double timestampSecEnd;
|
||||
|
||||
public GenesisHead()
|
||||
{
|
||||
}
|
||||
|
||||
public GenesisHead(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
ClearData();
|
||||
|
||||
genesisHeadCfg = cfg as GenesisHeadCfg;
|
||||
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
private GenesisMeter myGenesis = null;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public GenesisMeter SetUp()
|
||||
{
|
||||
try
|
||||
{
|
||||
Log("Call SetUp()");
|
||||
if (myGenesis != null)
|
||||
{
|
||||
myGenesis.DisposeMeter();
|
||||
}
|
||||
//add for gen
|
||||
|
||||
myGenesis = new GenesisMeter();
|
||||
myGenesis.SetupFromConfigFile(SlotNr);
|
||||
Log("Add Meter to batch");
|
||||
GenesisHeadBatch.BatchHolder.Value.AddMeter(myGenesis);
|
||||
Log("Log Raw Data");
|
||||
myGenesis.LogRawData(true);
|
||||
return myGenesis;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (myGenesis != null)
|
||||
{
|
||||
Log(e.Message);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear data related to a specific water meter
|
||||
/// </summary>
|
||||
public void ClearData()
|
||||
{
|
||||
DetailedResults = new List<MeasurementResults>();
|
||||
resultCode = 0;
|
||||
|
||||
disabled = false;
|
||||
commFailed = false;
|
||||
endState = string.Empty;
|
||||
beginState = string.Empty;
|
||||
|
||||
configStruct = null;
|
||||
calibrationStruct = null;
|
||||
|
||||
LastTestResult = null;
|
||||
NominalTestFlowLph = 0;
|
||||
|
||||
OrigCalibFactor = 0;
|
||||
Q2ErrWOCorrection = 0;
|
||||
Q2CorrectionDone = false;
|
||||
Q2CorrRFlow = 0;
|
||||
}
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
ClearData();
|
||||
|
||||
if (DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
|
||||
|
||||
////todo: RD- Login??
|
||||
//if (DebugLevel == DebugMode.Normal)
|
||||
//{
|
||||
|
||||
|
||||
// if (myGenesis != null)
|
||||
// {
|
||||
// Log("TBF RunDeviceBefore");
|
||||
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// //throw new Exception("No meter was bound!");
|
||||
// }
|
||||
//}
|
||||
//else if (DebugLevel == DebugMode.FailureDuringOperation)
|
||||
//{
|
||||
//}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter() { }
|
||||
|
||||
public void StopDevice()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (DebugLevel == DebugMode.Normal && myGenesis != null)
|
||||
{
|
||||
myGenesis.DisposeMeter();
|
||||
|
||||
GenesisHeadBatch.BatchHolder.Value.RemoveMeter(myGenesis);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public void StopDevice2() { }
|
||||
|
||||
/// <summary>
|
||||
/// Events: Event.ReadRegisterDone, Event.Error
|
||||
/// </summary>
|
||||
/// <returns>ReadWaterMeter instance reference casted to IOperaton</returns>
|
||||
public IOperation ReadRegisterOp()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear data/counters related to a specific tests
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
resultCode = 0;
|
||||
|
||||
sampleNr = 0;
|
||||
|
||||
volumeLtr = 0;
|
||||
volumeLtr0 = 0;
|
||||
timestampSec = 0;
|
||||
timestampSec0 = 0;
|
||||
|
||||
ReadPulses();
|
||||
}
|
||||
|
||||
public void TestCompleted()
|
||||
{
|
||||
/// TODO: Implement
|
||||
}
|
||||
|
||||
private int sampleNr; /// This is to determine when the test start sample should be taken
|
||||
|
||||
|
||||
private bool StoreStartPackage = false;
|
||||
private bool StoreEndPackage = false;
|
||||
private bool Enable = false;
|
||||
public bool IsCalibration = false;
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
public void StartRead(string TestName, int batchNr, int repetitionNr)
|
||||
{
|
||||
StoreStartPackage = false;
|
||||
StoreEndPackage = false;
|
||||
//Start mesurement
|
||||
if (DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
if (myGenesis != null)
|
||||
{
|
||||
IsCalibration = false;
|
||||
Log($"TBF Start Measurement {TestName}");
|
||||
myGenesis.CurrentActionText = $"Batch{batchNr}_Rep{repetitionNr}";
|
||||
|
||||
|
||||
if (TestName.ToLower().Contains("calib"))
|
||||
{
|
||||
IsCalibration = true;
|
||||
//myGenesis.Login();
|
||||
myGenesis.StartCalibration();
|
||||
}
|
||||
else if (TestName.ToLower().Contains("login"))
|
||||
{
|
||||
//myGenesis.Login();
|
||||
|
||||
myGenesis.InitMeasurement();
|
||||
}
|
||||
else
|
||||
{
|
||||
DetailedResults = new List<MeasurementResults>();
|
||||
|
||||
myGenesis.StartMeasurement();
|
||||
}
|
||||
|
||||
StoreStartPackage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Log(string text)
|
||||
{
|
||||
if (DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
if (myGenesis != null)
|
||||
{
|
||||
myGenesis.WriteLog(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>eventDone</returns>
|
||||
public Event Run()
|
||||
{
|
||||
if (DebugLevel == DebugMode.Normal)
|
||||
{
|
||||
if (myGenesis != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
//var results = myGenesis.GetIntermediateMeasurementResult();
|
||||
//readOutResults(results);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return Event.ReadRegisterDone;
|
||||
}
|
||||
public double RefVolume = 0.0;
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
//Stop(null);
|
||||
if (DebugLevel == DebugMode.Normal && myGenesis != null)
|
||||
{
|
||||
if (IsCalibration)
|
||||
{
|
||||
myGenesis.StopCalibration();
|
||||
}
|
||||
else
|
||||
{
|
||||
myGenesis.StopMeasurement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop(Double? testTimeS = null, double? refVol = null)
|
||||
{
|
||||
|
||||
if (DebugLevel == DebugMode.Normal && myGenesis != null)
|
||||
{
|
||||
Log($"TBF Stop Measurement {IsCalibration} {testTimeS} {refVol }");
|
||||
if (IsCalibration)
|
||||
{
|
||||
//myGenesis.StopCalibration();
|
||||
int retryCounter = 400;
|
||||
while (myGenesis.GetCalibrationState() != MeasurementStates.IsCompleted)
|
||||
{
|
||||
if (retryCounter < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Thread.Sleep(10);
|
||||
retryCounter = retryCounter - 1;
|
||||
}
|
||||
try
|
||||
{
|
||||
var results = myGenesis.GetMainMeasurementResult(refVol, testTimeS, false);
|
||||
|
||||
readOutResults(results, testTimeS);
|
||||
if (refVol.HasValue && refVol.Value != 0.0)
|
||||
{
|
||||
|
||||
|
||||
myGenesis.BuildAndCheckCalibFactorsAllChannels(refVol.Value / 1000, testTimeS, Q2ErrWOCorrection);
|
||||
myGenesis.SetCalibFactorsAllChannels(false);
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MarkAsError();
|
||||
Log("Error while Stop Calib " + ex.Message);
|
||||
if (ex.InnerException != null)
|
||||
{
|
||||
Log("Inner Error:" + ex.InnerException.Message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int retryCounter = 4000;
|
||||
//myGenesis.StopMeasurement();
|
||||
try
|
||||
{
|
||||
while (myGenesis.GetMeasurementState() != MeasurementStates.IsCompleted)
|
||||
{
|
||||
if (retryCounter < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Thread.Sleep(10);
|
||||
retryCounter = retryCounter - 1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (refVol.HasValue && testTimeS.HasValue)
|
||||
{
|
||||
Log("GetMainMeasurementResult V" + refVol.ToString() + " and S" + testTimeS.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log("GetMainMeasurementResult empty");
|
||||
}
|
||||
|
||||
DetailedResults = myGenesis.GetAllMeasurementResults(refVol, testTimeS);
|
||||
foreach (var item in DetailedResults)
|
||||
{
|
||||
Log("Detail Measurement Channel =" + item.Channel + "; CorrectedDutVolumeCm= " + item.CorrectedDutVolumeCm + "; DeviationDutToRefPer= " + item.DeviationDutToRefPer);
|
||||
}
|
||||
|
||||
|
||||
readOutResults(DetailedResults.First(), testTimeS);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MarkAsError();
|
||||
Log("Error while Stop Measurement " + ex.Message);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MarkAsError();
|
||||
Log("Error while GetMeasurementState " + ex.Message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
StoreEndPackage = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void readOutResults(MeasurementResults results, double? testTimeS)
|
||||
{
|
||||
volumeLtr = results.CorrectedDutVolumeCm * 1000;
|
||||
timestampSec = results.DutStopRecord.GetTimeS();
|
||||
if (testTimeS.HasValue)
|
||||
{
|
||||
wmTestTime = testTimeS.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
wmTestTime = results.DutTimeS;
|
||||
}
|
||||
|
||||
wmVolume = results.CorrectedDutVolumeCm * 1000;
|
||||
Log("DutFlowRateCmPh" + results.DutFlowRateCmPh.ToString());
|
||||
Log("CorrectedDutVolumeCm=" + results.CorrectedDutVolumeCm.ToString());
|
||||
Log("DutVolumeCm=" + results.DutVolumeCm.ToString());
|
||||
ReadPulses();
|
||||
}
|
||||
|
||||
private void MarkAsError()
|
||||
{
|
||||
volumeLtr = 0;
|
||||
timestampSec = 0;
|
||||
wmTestTime = 0;
|
||||
wmVolume = 0;
|
||||
ReadPulses();
|
||||
}
|
||||
|
||||
private void ReadPulses()
|
||||
{
|
||||
beginWMState = volumeLtr0;
|
||||
endWMState = volumeLtr;
|
||||
wmPulses = (int)(wmVolume * (double)PulsesPerLtr + 0.5);
|
||||
wmRefPulses = StateMachine.ControlBoardMain.RefPulses;//EtPulses(0);//...MF
|
||||
}
|
||||
|
||||
private bool optoSerialPortParsingEnabled;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user