Compare commits

..
216 changed files with 232501 additions and 737 deletions
+1
View File
@@ -67,5 +67,6 @@ WorkflowConfigurator/obj/
Workplace/bin/
Workplace/obj/
.vs/
.idea/
*.suo
*.bak
+4 -4
View File
@@ -17,7 +17,7 @@
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;LANG_PL</DefineConstants>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
@@ -25,13 +25,13 @@
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;LANG_PL</DefineConstants>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="System" />
<Reference Include="System.Core" />
+43 -1
View File
@@ -105,6 +105,14 @@ namespace Common
///
[Description("pulse/kWh")] ppkWh, /// * 1 pulse/kWh
[Description("kWh/pulse")] kWhpp, /// 1 kWh/pulse
///
[Description("A")] A, /// *1 A
[Description("mA")] mA, /// 1 mA = 0.001 A
///
[Description("V")] V, /// *1 V
[Description("mV")] mV, /// 1 mV = 0.001 V
Count
}
@@ -135,6 +143,8 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Datum und Uhrzeit")] DateTime,
[Description("Aufgezählt")] Enumerated,
[Description("Strom")] Current,
[Description("Spannung")] Voltage,
#elif LANG_PL
[Description("Objętość")] Volume,
[Description("Przepływ")] Flow,
@@ -158,6 +168,8 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Data i czas")] DateTime,
[Description("Wyliczone")] Enumerated,
[Description("Prąd")] Current,
[Description("Napięcie")] Voltage,
#elif LANG_CS
[Description("Objem")] Volume,
[Description("Průtok")] Flow,
@@ -181,6 +193,8 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Datum a čas")] DateTime,
[Description("Vyjmenované")] Enumerated,
[Description("Proud")] Current,
[Description("Napětí")] Voltage,
#elif LANG_IT
[Description("Volume")] Volume,
[Description("Flusso")] Flow,
@@ -204,6 +218,8 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Data e ora")] DateTime,
[Description("Enumerato")] Enumerated,
[Description("Corrente")] Current,
[Description("Voltaggio")] Voltage,
#else
[Description("Volume")] Volume,
[Description("Flow")] Flow,
@@ -227,6 +243,8 @@ namespace Common
[Description("Boolean")] Boolean,
[Description("Date and time")] DateTime,
[Description("Enumerated")] Enumerated,
[Description("Current")] Current,
[Description("Voltage")] Voltage,
#endif
Count,
}
@@ -242,7 +260,8 @@ namespace Common
{
return unit == Unit.l || unit == Unit.m3ph || unit == Unit.kg || unit == Unit.s || unit == Unit.C ||
unit == Unit.bar || unit == Unit.RPct || unit == Unit.Pct || unit == Unit.mm || unit == Unit.kgpm3 ||
unit == Unit.J || unit == Unit.uSpcm || unit == Unit.ppl || unit == Unit.ppkWh;
unit == Unit.J || unit == Unit.uSpcm || unit == Unit.ppl || unit == Unit.ppkWh || unit == Unit.A ||
unit == Unit.V;
}
public static bool IsQuantity(Unit unit, Quantity quantity)
@@ -351,6 +370,14 @@ namespace Common
case Unit.ppkWh:
case Unit.kWhpp:
return Quantity.PulsePerKWh;
case Unit.A:
case Unit.mA:
return Quantity.Current;
case Unit.V:
case Unit.mV:
return Quantity.Voltage;
default:
return Quantity.Number;
@@ -372,6 +399,8 @@ namespace Common
public static bool IsPulsePerLtr(Unit unit) { return IsQuantity(unit, Quantity.PulsePerLtr); }
public static bool IsPulsePerKWh(Unit unit) { return IsQuantity(unit, Quantity.PulsePerKWh); }
public static bool IsConductivity(Unit unit) { return IsQuantity(unit, Quantity.Conductivity); }
public static bool IsCurrent(Unit unit) { return IsQuantity(unit, Quantity.Current); }
public static bool IsVoltage(Unit unit) { return IsQuantity(unit, Quantity.Voltage); }
@@ -455,6 +484,13 @@ namespace Common
case Unit.dm3pp:
case Unit.lpdeg:
case Unit.dm3pdeg: return (v <= float.Epsilon) ? 0 : 1/v;
/// Current: internal representation in A
case Unit.mA: return 1000 * v; /// 1000 mA = 1 A
/// Voltage: internal representation in V
case Unit.mV: return 1000 * v; /// 1000 mV = 1 V
default: return v; /// Do not convert
}
@@ -534,6 +570,12 @@ namespace Common
/// Electrical conductivity
case Unit.mSpm: return 10 * v;
/// Current: internal representation in A
case Unit.mA: return 0.001 * v; /// 1 mA = 0.001 A
/// Voltage: internal representation in V
case Unit.mV: return 0.001 * v; /// 1 mV = 0.001 V
/// Invert
case Unit.kWhpp:
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+1 -1
View File
@@ -43,7 +43,7 @@
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
+6
View File
@@ -22,6 +22,9 @@ namespace Config.Entities
public virtual string PressMtrUp { get; set; }
public virtual string PressMtrDown { get; set; }
public virtual string PressMtrDelta { get; set; }
public virtual string ElectricMtrUp { get; set; }
public virtual string ElectricMtrDown { get; set; }
public virtual string ElectricMtrDelta { get; set; }
public virtual string StopBFValve { get; set; }
/// Valves
@@ -59,6 +62,9 @@ namespace Config.Entities
result.PressMtrUp = PressMtrUp;
result.PressMtrDown = PressMtrDown;
result.PressMtrDelta = PressMtrDelta;
result.ElectricMtrUp = ElectricMtrUp;
result.ElectricMtrDown = ElectricMtrDown;
result.ElectricMtrDelta = ElectricMtrDelta;
result.StopBFValve = StopBFValve;
result.ValvesOpen = ValvesOpen;
result.ValvesClose = ValvesClose;
+2
View File
@@ -78,6 +78,7 @@ namespace Config.Entities
public virtual Unit TempUnit { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
public virtual Unit PressUnit { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
public virtual Unit LengthUnit { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
public virtual Unit ElectricUnit { get; set; } /// Not mapped to database, used in ProcedureDlg / Metrology1Tab
/// Wrappers
public virtual double QfromM3ph()
@@ -209,6 +210,7 @@ namespace Config.Entities
result.TempUnit = TempUnit;
result.PressUnit = PressUnit;
result.LengthUnit = LengthUnit;
result.ElectricUnit = ElectricUnit;
foreach (var prms in MoreParams) { result.MoreParams.Add(prms.Clone()); }
return result;
+3
View File
@@ -21,6 +21,9 @@ namespace Config.Mappings
Map(x => x.PressMtrUp);
Map(x => x.PressMtrDown);
Map(x => x.PressMtrDelta);
//Map(x => x.ElectricMtrUp);
//Map(x => x.ElectricMtrDown);
//Map(x => x.ElectricMtrDelta);
Map(x => x.StopBFValve);
Map(x => x.ValvesOpen)
.CustomType("StringClob")
@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
@@ -1 +0,0 @@
22fa51b09dbd9afa4c5d73fd5d4267426f09bc510527f701d437b89d74765cc0
@@ -1,18 +0,0 @@
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\bin\Debug\Doc\Software interface for datastream water meters.docx
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\bin\Debug\DataStreamInterfaceTest.exe.config
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\bin\Debug\DataStreamInterfaceTest.exe
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\bin\Debug\DataStreamInterfaceTest.pdb
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\bin\Debug\DataStreamInterface.dll
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\bin\Debug\DataStreamInterface.pdb
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.csproj.AssemblyReference.cache
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.DemoMainWnd.resources
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.GetDblValueDlg.resources
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.GetFrameBoundariesDlg.resources
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.GetIntegerNumberDlg.resources
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.GetStateDlg.resources
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.Properties.Resources.resources
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.csproj.GenerateResource.cache
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.csproj.CoreCompileInputs.cache
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStre.F4216CC0.Up2Date
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.exe
C:\VSProjects\proj9\tbf\DataStreamInterfaceTest\obj\Debug\DataStreamInterfaceTest.pdb
+2 -3
View File
@@ -40,9 +40,8 @@
<StartupObject>DeviceTest.Program</StartupObject>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="System" />
<Reference Include="System.Core" />
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+1 -1
View File
@@ -49,7 +49,7 @@
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<HintPath>..\packages\log4net.2.0.15\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
+2 -2
View File
@@ -46,8 +46,8 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+3 -2
View File
@@ -38,8 +38,8 @@
<Reference Include="Iesi.Collections">
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
@@ -62,6 +62,7 @@
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Config\Config.csproj">
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+2 -2
View File
@@ -48,8 +48,8 @@
<Reference Include="Iesi.Collections">
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+2 -2
View File
@@ -49,8 +49,8 @@
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="MySql.Data, Version=6.6.5.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
+1
View File
@@ -3,4 +3,5 @@
<package id="FluentNHibernate" version="2.0.3.0" targetFramework="net40" />
<package id="Iesi.Collections" version="4.0.0.4000" targetFramework="net40" />
<package id="NHibernate" version="4.0.4.4000" targetFramework="net40" />
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+2 -2
View File
@@ -34,8 +34,8 @@
<Reference Include="Gma.QrCodeNet.Encoding">
<HintPath>..\packages\QrCode.Net.0.4.0.0\net40\Gma.QrCodeNet.Encoding.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="NHibernate">
<HintPath>..\packages\NHibernate.4.0.4.4000\lib\net40\NHibernate.dll</HintPath>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+15 -17
View File
@@ -44,8 +44,8 @@
<Reference Include="Iesi.Collections">
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
@@ -75,6 +75,12 @@
<Compile Include="Entities\WaterMeterData.cs" />
<Compile Include="Entities\WaterMeter.cs" />
<Compile Include="DB.cs" />
<Compile Include="Forms\BatchResultsDlg.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\BatchResultsDlg.Designer.cs">
<DependentUpon>BatchResultsDlg.cs</DependentUpon>
</Compile>
<Compile Include="Forms\IOneWMResultsCtrl.cs" />
<Compile Include="Forms\ManualEntryConfigCtrl.cs">
<SubType>UserControl</SubType>
@@ -118,10 +124,6 @@
<Compile Include="Forms\ResultsConfigDlg.designer.cs">
<DependentUpon>ResultsConfigDlg.cs</DependentUpon>
</Compile>
<Compile Include="Forms\TracingResultsDlg.cs" />
<Compile Include="Forms\TracingResultsDlg.Designer.cs">
<DependentUpon>TracingResultsDlg.cs</DependentUpon>
</Compile>
<Compile Include="Forms\WaterMeterEventArgs.cs" />
<Compile Include="ItemID.cs" />
<Compile Include="ManualEntryItemSpec.cs" />
@@ -132,6 +134,7 @@
<Compile Include="Mappings\TestRsltMap.cs" />
<Compile Include="Mappings\WaterMeterDataMap.cs" />
<Compile Include="Mappings\WaterMeterMap.cs" />
<Compile Include="Output\Cell.cs" />
<Compile Include="Output\Printers\Enhanced\EnhancedPrintDocument.cs">
<SubType>Component</SubType>
</Compile>
@@ -149,7 +152,6 @@
<SubType>Component</SubType>
</Compile>
<Compile Include="Output\Printers\OnePerBatch\OnePerBatchPrinterCfg.cs" />
<Compile Include="Output\Printers\Munich\MunichPrintDocument.cs" />
<Compile Include="Output\Printers\OnePerMeter\OnePerMeterPrintDocument.cs">
<SubType>Component</SubType>
</Compile>
@@ -188,13 +190,9 @@
<Project>{32817bf9-e380-4467-9c7f-936f4b122bc7}</Project>
<Name>GenCode128</Name>
</ProjectReference>
<ProjectReference Include="..\TracingDB\TracingDB.csproj">
<Project>{EFEC8A31-3022-4DA7-A8F6-16D30A94C3FF}</Project>
<Name>TracingDB</Name>
</ProjectReference>
<ProjectReference Include="..\Users\Users.csproj">
<Project>{6E5CB0E9-E1B6-4E5D-AC6E-B1049E180F2B}</Project>
<Name>Users</Name>
<ProjectReference Include="..\SharedDatabase\SharedDatabase.csproj">
<Project>{211b5e3f-9996-48a7-abde-c878dd2d71c2}</Project>
<Name>SharedDatabase</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
@@ -203,6 +201,9 @@
<Folder Include="Output\FileWriters\OneFilePerMeter\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Forms\BatchResultsDlg.resx">
<DependentUpon>BatchResultsDlg.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\ManualEntryConfigCtrl.resx">
<DependentUpon>ManualEntryConfigCtrl.cs</DependentUpon>
</EmbeddedResource>
@@ -224,9 +225,6 @@
<EmbeddedResource Include="Forms\ResultsConfigDlg.resx">
<DependentUpon>ResultsConfigDlg.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\TracingResultsDlg.resx">
<DependentUpon>TracingResultsDlg.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+4 -2
View File
@@ -47,8 +47,8 @@
<Reference Include="Iesi.Collections">
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
@@ -65,7 +65,9 @@
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms.DataVisualization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
+1
View File
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Oracle.ManagedDataAccess" version="19.11.0" targetFramework="net472" />
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+6
View File
@@ -332,6 +332,12 @@ namespace SchematicDrawing
Shapes[DrShIx(Shape.PressM, Sz.M)] = new DrawingShape(Shape.PressM, Sz.M, 0, 0);
Shapes[DrShIx(Shape.PressM, Sz.L)] = new DrawingShape(Shape.PressM, Sz.L, 0, 0);
Shapes[DrShIx(Shape.PressM, Sz.XL)] = new DrawingShape(Shape.PressM, Sz.XL, 0, 0);
/// Electric meter
Shapes[DrShIx(Shape.ElectricM, Sz.S)] = new DrawingShape(Shape.ElectricM, Sz.S, 0, 0);
Shapes[DrShIx(Shape.ElectricM, Sz.M)] = new DrawingShape(Shape.ElectricM, Sz.M, 0, 0);
Shapes[DrShIx(Shape.ElectricM, Sz.L)] = new DrawingShape(Shape.ElectricM, Sz.L, 0, 0);
Shapes[DrShIx(Shape.ElectricM, Sz.XL)] = new DrawingShape(Shape.ElectricM, Sz.XL, 0, 0);
/// Parallel flow meters
Shapes[DrShIx(Shape.ParallelFlowM, Sz.S)] = new DrawingShape(Shape.ParallelFlowM, Sz.S, 0, 0);
+1
View File
@@ -51,6 +51,7 @@ namespace SchematicDrawing
Vacuum,
Valve,
WaterM,
ElectricM,
Count,
Custom,
+2 -2
View File
@@ -36,8 +36,8 @@
<Reference Include="Iesi.Collections">
<HintPath>..\packages\Iesi.Collections.4.0.0.4000\lib\net40\Iesi.Collections.dll</HintPath>
</Reference>
<Reference Include="log4net">
<HintPath>..\packages\log4net.2.0.2\lib\net40-full\log4net.dll</HintPath>
<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="MySql.Data">
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
+4
View File
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.15" targetFramework="net472" />
</packages>
+17 -1
View File
@@ -1,6 +1,8 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
# Visual Studio Version 17
VisualStudioVersion = 17.8.34330.188
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TBF", "TBF\TBF.csproj", "{8648FD92-CDA1-4C3A-B5F9-FE547CE1FA48}"
ProjectSection(ProjectDependencies) = postProject
{7EBEEA14-91C4-48D7-AF0A-7A4BC3FF9A28} = {7EBEEA14-91C4-48D7-AF0A-7A4BC3FF9A28}
@@ -100,6 +102,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S640TestApp", "S640TestApp\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabelPrinting", "LabelPrinting\LabelPrinting.csproj", "{E4531D13-317C-4D9F-809F-5533B5C3C8BF}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TBFTests", "TBFTests\TBFTests.csproj", "{77EB589F-C670-4489-AAD6-2A3C02061FD1}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -446,6 +450,18 @@ Global
{E4531D13-317C-4D9F-809F-5533B5C3C8BF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E4531D13-317C-4D9F-809F-5533B5C3C8BF}.Release|x86.ActiveCfg = Release|Any CPU
{E4531D13-317C-4D9F-809F-5533B5C3C8BF}.Release|x86.Build.0 = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Debug|x86.ActiveCfg = Debug|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Debug|x86.Build.0 = Debug|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Release|Any CPU.Build.0 = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Release|x86.ActiveCfg = Release|Any CPU
{77EB589F-C670-4489-AAD6-2A3C02061FD1}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+2 -2
View File
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("3.9.2139.0")]
[assembly: AssemblyFileVersion("3.9.2139.0")]
[assembly: AssemblyVersion("3.9.2141.1")]
[assembly: AssemblyFileVersion("3.9.2141.1")]
+20 -3
View File
@@ -1,7 +1,6 @@
//------------------------------------------------------------------------------
// <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.
@@ -1257,12 +1256,21 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Current.
/// </summary>
internal static string Current {
get {
return ResourceManager.GetString("Current", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to current.
/// </summary>
internal static string current {
internal static string current_ {
get {
return ResourceManager.GetString("current", resourceCulture);
return ResourceManager.GetString("current_", resourceCulture);
}
}
@@ -6813,6 +6821,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Voltage.
/// </summary>
internal static string Voltage {
get {
return ResourceManager.GetString("Voltage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Volume.
/// </summary>
+6
View File
@@ -1746,4 +1746,10 @@
<data name="Print" xml:space="preserve">
<value>Tisknout</value>
</data>
<data name="Current" xml:space="preserve">
<value>Proud</value>
</data>
<data name="Voltage" xml:space="preserve">
<value>Napětí</value>
</data>
</root>
+6
View File
@@ -2211,4 +2211,10 @@
<data name="Calibration_certificate_validity_expired" xml:space="preserve">
<value>Kalibrierschein gültigkeit abgelaufen</value>
</data>
<data name="Current" xml:space="preserve">
<value>Strom</value>
</data>
<data name="Voltage" xml:space="preserve">
<value>Spannung</value>
</data>
</root>
+6
View File
@@ -2010,4 +2010,10 @@
<data name="Fill" xml:space="preserve">
<value>Inonder</value>
</data>
<data name="Current" xml:space="preserve">
<value>Curren</value>
</data>
<data name="Voltage" xml:space="preserve">
<value>Tension</value>
</data>
</root>
+6
View File
@@ -1779,4 +1779,10 @@
<data name="Start_cycle" xml:space="preserve">
<value>Avviare il ciclo</value>
</data>
<data name="Current" xml:space="preserve">
<value>Corrente</value>
</data>
<data name="Voltage" xml:space="preserve">
<value>Voltaggio</value>
</data>
</root>
+6
View File
@@ -1686,4 +1686,10 @@
<data name="Uncertainty" xml:space="preserve">
<value>Nepevność</value>
</data>
<data name="Current" xml:space="preserve">
<value>Prąd</value>
</data>
<data name="Voltage" xml:space="preserve">
<value>Napięcie</value>
</data>
</root>
+7 -1
View File
@@ -1813,7 +1813,7 @@
<data name="Refresh" xml:space="preserve">
<value>Refresh</value>
</data>
<data name="current" xml:space="preserve">
<data name="current_" xml:space="preserve">
<value>current</value>
</data>
<data name="Flow" xml:space="preserve">
@@ -2449,4 +2449,10 @@
<data name="Test_Bench_Framework" xml:space="preserve">
<value>Test Bench Framework</value>
</data>
<data name="Current" xml:space="preserve">
<value>Current</value>
</data>
<data name="Voltage" xml:space="preserve">
<value>Voltage</value>
</data>
</root>
+6
View File
@@ -831,4 +831,10 @@
<data name="Evaporation" xml:space="preserve">
<value>Evaporare</value>
</data>
<data name="Current" xml:space="preserve">
<value>Current</value>
</data>
<data name="Voltage" xml:space="preserve">
<value>Voltage</value>
</data>
</root>
+6
View File
@@ -1599,4 +1599,10 @@
<data name="Evaporation" xml:space="preserve">
<value>испарение</value>
</data>
<data name="Current" xml:space="preserve">
<value>Current</value>
</data>
<data name="Voltage" xml:space="preserve">
<value>Voltage</value>
</data>
</root>
File diff suppressed because it is too large Load Diff
+6
View File
@@ -1191,4 +1191,10 @@
<data name="Evaporation" xml:space="preserve">
<value>蒸发</value>
</data>
<data name="Current" xml:space="preserve">
<value>Current</value>
</data>
<data name="Voltage" xml:space="preserve">
<value>Voltage</value>
</data>
</root>
+6
View File
@@ -18,6 +18,9 @@ namespace TBF.Rig
public IPressureMeter PressMtrUp;
public IPressureMeter PressMtrDown;
public IPressureMeter PressMtrDelta;
public IAdjustableMeter ElectricMtrUp;
public IAdjustableMeter ElectricMtrDown;
public IAdjustableMeter ElectricMtrDelta;
public IValve StopBFValve;
public IList<IValve> ValvesOpen;
public IList<IValve> ValvesClose;
@@ -43,6 +46,9 @@ namespace TBF.Rig
PressMtrUp = TbfComponents.FindComponent(entity.PressMtrUp, components) as IPressureMeter;
PressMtrDown = TbfComponents.FindComponent(entity.PressMtrDown, components) as IPressureMeter;
PressMtrDelta = TbfComponents.FindComponent(entity.PressMtrDelta, components) as IPressureMeter;
ElectricMtrUp = TbfComponents.FindComponent(entity.ElectricMtrUp, components) as IAdjustableMeter;
ElectricMtrDown = TbfComponents.FindComponent(entity.ElectricMtrDown, components) as IAdjustableMeter;
ElectricMtrDelta = TbfComponents.FindComponent(entity.ElectricMtrDelta, components) as IAdjustableMeter;
StopBFValve = TbfComponents.FindComponent(entity.StopBFValve, components) as IValve;
string[] vOpen = entity.ValvesOpen.Split(new char[] { ';' });
+7 -9
View File
@@ -29,14 +29,12 @@ namespace TBF.Rig.BuiltIn
/// Relative time in [s] from the start of the operation
int timeShift; /// Set in SetValvesOp(cb, bool open, OutputPath outPath, DateTimeBox timeStamp)
int waitOnCBDelay = 2; // additional wait for the correct ControlBoard response in [s]
/// <summary>
/// Processes coupled valves and creates switch points.
/// </summary>
/// <param name="valvesOpen">A list of opening master valves</param>
/// <param name="valvesClose">A list of closing master valves</param>
/// <returns></returns>
/// <summary>
/// Processes coupled valves and creates switch points.
/// </summary>
/// <param name="valvesOpen">A list of opening master valves</param>
/// <param name="valvesClose">A list of closing master valves</param>
/// <returns></returns>
IList<SwitchPoint> AddSwitchPoints(IList<SwitchPoint> swPoints, IList<IValve> valvesOpen, IList<IValve> valvesClose, int time)
{
int ix0 = swPoints.Count;
@@ -279,7 +277,7 @@ namespace TBF.Rig.BuiltIn
{
if (nextIx >= switchPoints.Count)
{
return (StateMachine.Time >= swStartTime + maxDelayTime + waitOnCBDelay) ? Event.ValvesSet : Event.ValvesBusy;
return (StateMachine.Time >= swStartTime + maxDelayTime) ? Event.ValvesSet : Event.ValvesBusy;
}
if (StateMachine.Time >= swStartTime + switchPoints[nextIx].TimeSec)
+2 -2
View File
@@ -125,7 +125,7 @@ namespace TBF.Rig.Danfoss.VLT2800
int bitNr; /// 0 .. 127
public UInt128 Mask; /// derived from bitPosition in the constructor
public bool State { get { return (TBF.Rig.StateMachine.ControlBoard.Route & Mask) != 0; } }
public bool State { get { return (TBF.Rig.StateMachine.ControlBoardMain.Route & Mask) != 0; } }
/// Private fields
SerialPort serialPort;
@@ -148,7 +148,7 @@ namespace TBF.Rig.Danfoss.VLT2800
public override void Initialize()
{
if (TBF.Rig.StateMachine.ControlBoard == null) throw new Exception("Control board is missing");
if (TBF.Rig.StateMachine.ControlBoardMain == null) throw new Exception("Control board is missing");
bitNr = pumpCfg.BitNr;
Mask = (((UInt128)1) << bitNr);
@@ -35,6 +35,7 @@ namespace TBF.Rig.DataContainer.BenchInfo
public Unit TempUnit { get { return myCfg.TempUnit; } }
public Unit PressUnit { get { return myCfg.PressUnit; } }
public Unit LengthUnit { get { return myCfg.LenghtUnit; } }
public Unit ElectricUnit { get { return myCfg.ElectricUnit; } }
public ICollection<ProcedureSelection> Sources
{
@@ -47,6 +47,7 @@ namespace TBF.Rig.DataContainer.BenchInfo
public ProcedureSelection Source2; /// 21
public ProcedureSelection Source3; /// 22
public ProcedureSelection Source4; /// 23
public Unit ElectricUnit; /// 24
/// Private parameterless constructor invoked by all other (public) constructors
ComponentCfg() {}
@@ -36,6 +36,7 @@ namespace TBF.Rig.DataContainer.iPerlBenchInfo
public Unit TempUnit { get { return myCfg.TempUnit; } }
public Unit PressUnit { get { return myCfg.PressUnit; } }
public Unit LengthUnit { get { return myCfg.LenghtUnit; } }
public Unit ElectricUnit { get { return myCfg.ElectricUnit; } }
public Side Side { get { return myCfg.Side; } }
public int MaxTestIndex { get { return myCfg.MaxTestIndex; } } /// (MaxPruefindex % 100) value when to reject water meters completely if they are NOK
@@ -49,6 +49,7 @@ namespace TBF.Rig.DataContainer.iPerlBenchInfo
public ProcedureSelection Source2; /// 23
public ProcedureSelection Source3; /// 24
public ProcedureSelection Source4; /// 25
public Unit ElectricUnit; /// 26
/// Calibration info serialized parameters displayed in Metrology tab page
public string CalibCertificateNr { get; set; }
@@ -99,6 +100,7 @@ namespace TBF.Rig.DataContainer.iPerlBenchInfo
Source2 = ProcedureSelection.FromLocalDB;
Source3 = ProcedureSelection.None;
Source4 = ProcedureSelection.None;
ElectricUnit = Unit.A;
CalibCertificateNr = string.Empty;
CalibDate = TBF.UI.Constants.MinDate;
@@ -133,6 +135,7 @@ namespace TBF.Rig.DataContainer.iPerlBenchInfo
"Procedure selection source 2", /// 23
"Procedure selection source 3", /// 24
"Procedure selection source 4", /// 25
"Preffered electric unit", /// 26
};
public string ParamName(int i) { return paramNames[i]; }
public int ParamsCount() { return paramNames.Length; }
@@ -193,6 +196,13 @@ namespace TBF.Rig.DataContainer.iPerlBenchInfo
for (ProcedureSelection src = 0; src < ProcedureSelection.Count; src++)
list.Add(src.ToDescription());
return list;
case 26:
for (Unit unit = 0; unit < Unit.Count; unit++)
if (Units.IsQuantity(unit, Quantity.Current) ||
Units.IsQuantity(unit, Quantity.Voltage))
list.Add(unit.ToDescription());
return list;
default:
return null;
@@ -229,6 +239,7 @@ namespace TBF.Rig.DataContainer.iPerlBenchInfo
case 23: return Source2.ToDescription();
case 24: return Source3.ToDescription();
case 25: return Source4.ToDescription();
case 26: return ElectricUnit.ToDescription();
default:
return string.Format("{0}: Bench={1}, ID={2}, Mtrs={3}, Lines={4}, Compund mtrs={5}, S1={6}, S2={7}, S3={8}, S4={9}",
Name, TestBenchName, TestBenchId, WaterMetersCount, LinesCount, CompoundMetersCount, Source1, Source2, Source3, Source4);
@@ -329,6 +340,10 @@ namespace TBF.Rig.DataContainer.iPerlBenchInfo
}
break;
case 26:
ElectricUnit = Units.FromDescription(str);
return CfgUpdateFlags.RestartRqrd;
default: return CfgUpdateFlags.None;
}
return CfgUpdateFlags.Error;
@@ -388,6 +403,10 @@ namespace TBF.Rig.DataContainer.iPerlBenchInfo
if (str == source.ToDescription()) return true;
}
break;
case 26:
if (ParamValues(i).Contains(str)) return true;
break;
default:
message = "Invalid index";
return false;
@@ -425,6 +444,7 @@ namespace TBF.Rig.DataContainer.iPerlBenchInfo
prms.Source2 = Source2;
prms.Source3 = Source3;
prms.Source4 = Source4;
prms.ElectricUnit = ElectricUnit;
prms.CalibCertificateNr = this.CalibCertificateNr;
prms.CertPath = this.CertPath;
+16 -2
View File
@@ -80,10 +80,22 @@ namespace TBF.Rig.DataEntry.StandardCamera
public string WMCycleEndState(int wmNr) { return (wmNr >= 0 && wmNr < wmCycleEndState.Length) ? wmCycleEndState[wmNr] : string.Empty; }
double[] wmStartState;
public double WMStartState(int wmNr) { return (wmNr >= 0 && wmNr < wmStartState.Length) ? wmStartState[wmNr] : 0; }
public double WMStartState(int wmNr)
{
bool real = (wmNr >= 0 && wmNr < wmStartState.Length);
log.DebugFormat("WMEndState, wmNr:{0}, wmEndState real: {1}, wmEndState[wmNr]: {2} ",wmNr,real, real ? wmStartState[wmNr] : 0);
return real ? wmStartState[wmNr] : 0;
}
double[] wmEndState;
public double WMEndState(int wmNr) { return (wmNr >= 0 && wmNr < wmEndState.Length) ? wmEndState[wmNr] : 0; }
public double WMEndState(int wmNr)
{
bool real = (wmNr >= 0 && wmNr < wmEndState.Length);
log.DebugFormat("WMEndState, wmNr:{0}, wmEndState real: {1}, wmEndState[wmNr]: {2} ",wmNr,real, real ? wmEndState[wmNr] : 0);
return real ? wmEndState[wmNr] : 0;
}
string[] wmStartStateStr;
@@ -215,6 +227,7 @@ namespace TBF.Rig.DataEntry.StandardCamera
///
void OpenTestStartStatesDlg(EntryForm myRef)
{
log.Debug("-- OpenTestStartStatesDlg --");
string ocrMessage;
var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage);
myRef.modelessDlg = new TestStartEndForm(TBF.Data.WMsCount, myRef.regReaders, ocr, ocrMessage, myRef.OcrStream,
@@ -224,6 +237,7 @@ namespace TBF.Rig.DataEntry.StandardCamera
///
void OpenTestEndStatesDlg(EntryForm myRef)
{
log.Debug("-- OpenTestEndStatesDlg --");
string ocrMessage;
var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage);
myRef.modelessDlg = new TestStartEndForm(TBF.Data.WMsCount, myRef.regReaders, ocr, ocrMessage, myRef.OcrStream,
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using log4net;
@@ -547,6 +548,7 @@ namespace TBF.Rig.DataEntry.StandardCamera
{
try
{
log.DebugFormat("okButton_Click - TextBoxesCount: [{0}], phys2wm:[{1}]", TextBoxesCount, phys2wm.ToArray().ToString());
for (int i = 0; i < TextBoxesCount; i++)
{
int wmPos = phys2wm[i];
@@ -560,6 +562,7 @@ namespace TBF.Rig.DataEntry.StandardCamera
{
WMStartState[wmPos - 1] = Units.ConvertFrom(unit, val); /// Convert to liters
WMStartStateStr[wmPos - 1] = startTextBoxes[i].Text;
log.DebugFormat("startTextBoxes[{0}]= {1} - wmPos= {2} - WMStartState[{3}]= {4} ", i,startTextBoxes[i].Text, wmPos, wmPos - 1,WMStartState[wmPos - 1] );
}
}
@@ -569,6 +572,7 @@ namespace TBF.Rig.DataEntry.StandardCamera
if (Utils.TryParseUDouble(endTextBoxes[i].Text, out val))
{
WMEndState[wmPos - 1] = Units.ConvertFrom(unit, val); /// Convert to liters
log.DebugFormat("endTextBoxes[{0}]= {1} - wmPos= {2} - WMEndState[{3}]= {4} ", i,endTextBoxes[i].Text, wmPos, wmPos - 1,WMEndState[wmPos - 1] );
}
}
}
@@ -688,10 +692,14 @@ namespace TBF.Rig.DataEntry.StandardCamera
double err = 100.0 * (endVolumeL - startVolumeL - refVolume) / refVolume;
exclamations[uiCtrlPos].Visible = (err < warningLimLo) || (warningLimHi < err);
log.Debug(string.Format("DataEntry - Update unit:[{0}], startV: {1} -> {2}, endV: {3} -> {4} ",
unit, startV, startVolumeL, endV, endVolumeL));
}
catch
{
exclamations[uiCtrlPos].Visible = false;
log.Debug("DataEntry - Update unit - Error uiCtrlPos: " + uiCtrlPos);
}
}
}
@@ -0,0 +1,31 @@
using TBF.Boxes;
using TBF.Rig.Generic;
namespace TBF.Rig.GenericDevices
{
public interface IAdjustableMeter : IPressureMeter
{
/// <summary>
/// Events: PressureDone, Error
/// </summary>
/// <param name="pressure">Reference to a variable for the measured pressure in bar</param>
/// <returns>ReadPressureOp instance reference casted to IOperaton</returns>
IOperation ReadAdjustableOp(ref DoubleBox value);
/// <summary>
/// Events: pressureDone, Error
/// </summary>
/// <param name="pressure">Reference to a variable for the measured pressure in bar</param>
/// <param name="pressureDone">Event returned when measurement done</param>
/// <returns>ReadPressureOp instance reference casted to IOperaton</returns>
IOperation ReadAdjustableOp(ref DoubleBox value, Event valueDone);
bool MsrmntAvailable { get; }
double MeasuredVal { get; }
double MsrdValLimLo { get; }
double MsrdValLimHi { get; }
string MsrdFormat { get; }
Common.Unit MsrdUnit { get; }
string AltString { get; }
}
}
+2 -1
View File
@@ -29,5 +29,6 @@ namespace TBF.Rig.GenericDevices
Unit TempUnit { get; }
Unit PressUnit { get; }
Unit LengthUnit { get; }
}
Unit ElectricUnit { get; }
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace TBF.Rig.GenericDevices
{
public interface IFTPAdapter : TBF.Rig.Generic.IComponent
{
string Path { get; }
}
}
@@ -22,5 +22,8 @@ namespace TBF.Rig.GenericDevices
bool blackAndWhite,
bool lowResolution,
Common.ImageRotation imageRotation);
//if has valve return it
IValve GetValve();
}
}
+2 -2
View File
@@ -79,8 +79,8 @@ namespace TBF.Rig.MettlerToledo
if (drainValve == null) throw new Exception(string.Format("{0} is missing a drain valve", Name));
openTheDrainValveOp = new BuiltIn.SetValvesOp(StateMachine.ControlBoard, drainValve, null);
closeTheDrainValveOp = new BuiltIn.SetValvesOp(StateMachine.ControlBoard, null, drainValve);
openTheDrainValveOp = new BuiltIn.SetValvesOp(StateMachine.ControlBoardMain, drainValve, null);
closeTheDrainValveOp = new BuiltIn.SetValvesOp(StateMachine.ControlBoardMain, null, drainValve);
waitTankIsEmptyOp = new WaitTankEmptyOp(this);
Various.TankWithLevelMsrmnt.TankCfg tankCfg = tankDrainingCfg as Various.TankWithLevelMsrmnt.TankCfg;
@@ -0,0 +1,290 @@
///
/// Copyright (c) 2016-2020 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using log4net;
using Common;
using Config.Entities;
using SchematicDrawing;
using TBF.Rig.Generic;
using TBF.Boxes;
using TBF.Resources;
using TBF.Rig.GenericDevices;
namespace TBF.Rig.Modbus.Meret.AdjustableScale
{
public class AdjustableMeter : ComponentBase, IAdjustableMeter, IDevice, ISequenceCondition, IDrawingItCmpntWithMeasuredVal
{
private static readonly ILog log = LogManager.GetLogger(typeof(AdjustableMeter));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
readonly AdjustableMeterCfg _adjustableMtrCfg;
public IDrawingItem DrawingItem { get { return _adjustableMtrCfg as IDrawingItem; } }
Common.Modbus modbus;
double receivedValue;
double receivedAmpers;
public IOperation ReadPressureOp(ref DoubleBox pressure) { return this.ReadAdjustableOp(ref pressure); }
public IOperation ReadPressureOp(ref DoubleBox pressure, Event pressureDone) { return this.ReadAdjustableOp(ref pressure, pressureDone); }
public bool MsrmntAvailable { get { return true; } }
public double MeasuredVal { get { return receivedValue; } }
public double MsrdValLimLo { get { return Units.ConvertFrom(MsrdUnit, _adjustableMtrCfg.MsrdValLimLo); } }
public double MsrdValLimHi { get { return Units.ConvertFrom(MsrdUnit, _adjustableMtrCfg.MsrdValLimHi); } }
public Unit MsrdUnit { get { return _adjustableMtrCfg.MsrdUnit; } }
public string MsrdFormat { get { return _adjustableMtrCfg.MsrdFormat; } }
public string AltString { get { return string.Empty; } }
int ticketNumber; /// 0 .. number of devices registered for regular polling - 1
public double CorrectionValLo { get { return Units.ConvertFrom(MsrdUnit, _adjustableMtrCfg.CorrectionValLo); } }
public double CorrectionValHi { get { return Units.ConvertFrom(MsrdUnit, _adjustableMtrCfg.CorrectionValHi); } }
IList<MeasurementCorrection> CorrectionsLocal;
public AdjustableMeter() { }
public AdjustableMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
_adjustableMtrCfg = cfg as AdjustableMeterCfg;
CreateConditions();
}
///
/// IDevice interface
///
public override void Initialize()
{
if (DebugLevel == DebugMode.Normal)
{
InitModbus();
if (CorrectionValLo != 0 || CorrectionValHi != 0 ) {
CorrectionsLocal = new List<MeasurementCorrection>();
MeasurementCorrection Lo, Hi;
Lo = new MeasurementCorrection(1);
Lo.Measurement = CorrectionValLo;
Lo.Correction = MsrdValLimLo;
CorrectionsLocal.Add(Lo);
Hi = new MeasurementCorrection(2);
Hi.Measurement = CorrectionValHi;
Hi.Correction = MsrdValLimHi;
CorrectionsLocal.Add(Hi);
log.FatalFormat("{0} Correction initialised - CorrectionValLo: {1} CorrectionValHi: {2}", Name, CorrectionValLo, CorrectionValHi);
}
}
else
{
log.FatalFormat("{0} simulated: {1}", Name, this);
}
}
private void InitModbus()
{
modbus = TbfComponents.FindComponent(_adjustableMtrCfg.ParentName) as Common.Modbus;
if (modbus == null) throw new Exception("Cannot find " + Name + " parent");
modbus.ComponentNames[_adjustableMtrCfg.ModbusAddress] = Name;
ticketNumber = modbus.RegisterForPolling();
log.FatalFormat("{0} initialized: {1}", Name, this);
}
public void RunDeviceBefore()
{
if (DebugLevel == DebugMode.Normal && modbus.ReceivedTelegrams[_adjustableMtrCfg.ModbusAddress].Count > 0)
{
byte[] telegram = modbus.ReceivedTelegrams[_adjustableMtrCfg.ModbusAddress].Dequeue();
if (telegram.Length == 9 && telegram[1] == 4 && telegram[2] == 4)
{
/// Swap byte order
byte t1 = telegram[3];
byte t2 = telegram[4];
byte t3 = telegram[5];
byte t4 = telegram[6];
telegram[3] = t4;
telegram[4] = t3;
telegram[5] = t2;
telegram[6] = t1;
receivedAmpers = Units.ConvertFrom(Unit.A, System.BitConverter.ToSingle(telegram, 3));
if (CorrectionsLocal != null)
{
receivedValue = GetCorrectionLimitLessHi(receivedAmpers, CorrectionsLocal);
}
else
{
receivedValue = receivedAmpers;
}
log.WarnFormat("Adjustable meter: {0}={1} Unit interpolated from Ampers: {2}", Name, receivedValue.ToString("F3"), receivedAmpers.ToString("F3"));
}
}
}
/// <summary>
/// Get a correction from a list of corrections by interpolation.
/// It is assumed that values in the list 'corrections' are sorted.
/// </summary>
/// <param name="rawMeasurement">Raw uncorrected value</param>
/// <param name="corrections">Sorted (value, correction) pairs</param>
/// <returns>Corrected value</returns>
public static double GetCorrectionLimitLessHi(double rawValue, IList<MeasurementCorrection> corrections)
{
if ((corrections == null) || (corrections.Count == 0)) return 0; /// No correction
if (rawValue < corrections[0].Measurement)
{
/// rawValue is below the lowest value in the correction table
return corrections[0].Correction;
}
for (int i = 1; i < corrections.Count; i++)
{
if (rawValue < corrections[i].Measurement)
{
double d1 = rawValue - corrections[i - 1].Measurement;
double d2 = corrections[i].Measurement - rawValue;
if (d1 + d2 <= float.Epsilon)
{
/// Neigboring values in the corection table are close to each other -> calculate the average
return (corrections[i - 1].Correction + corrections[i].Correction) / 2.0;
}
else
{
/// Interpolate the correction from neigboring values in the corection table
return (corrections[i - 1].Correction * d2 + corrections[i].Correction * d1) / (d1 + d2);
}
}
}
int lastCorrection = corrections.Count - 1;
if (lastCorrection > 0)
{
double d1 = rawValue - corrections[lastCorrection - 1].Measurement;
double d2 = corrections[lastCorrection].Measurement - rawValue;
return (corrections[lastCorrection - 1].Correction * d2 + corrections[lastCorrection].Correction * d1) /
(d1 + d2);
}
/// rawValue is above the highest value in the correction table
return corrections[corrections.Count - 1].Correction;
}
public void RunDeviceAfter()
{
if (DebugLevel == DebugMode.Normal && modbus.IsMyTurn(ticketNumber))
{
const byte Function = 4; /// Read input registers
const ushort Address = 0; /// Pressure
modbus.SendMessage((byte)_adjustableMtrCfg.ModbusAddress, Function, Address, 2, Name);
}
}
public void StopDevice() { }
public void StopDevice2() { }
/// <summary>
/// Returns the water pressure
/// </summary>
/// <returns>Pressure in mBar</returns>
public double ReadPressure()
{
if (DebugLevel == DebugMode.Normal)
{
return MeasurementCorrection.CorrectedValue(receivedValue, Corrections);
}
else if (DebugLevel == DebugMode.Simulate)
{
return 1.0;
}
else
{
return 0;
}
}
/// <summary>
/// Events: PressureDone, Error
/// </summary>
/// <param name="pressureBox">Reference to a variable for the pressure in Bar</param>
/// <returns>ReadPressureOp instance reference casted to IOperaton</returns>
public IOperation ReadAdjustableOp(ref DoubleBox value)
{
return new ReadValueOp(this, ref value);
}
/// <summary>
/// Events: valueDone, Error
/// </summary>
/// <param name="pressureBox">Reference to a variable for the pressure in Bar</param>
/// <param name="pressureDone">Event returned when measurement done</param>
/// <returns>ReadPressureOp instance reference casted to IOperaton</returns>
public IOperation ReadAdjustableOp(ref DoubleBox value, Event valueDone)
{
return new ReadValueOp(this, ref value, valueDone);
}
///
/// ISequenceCondition interface implementation (conditions in transition sequences)
///
IList<string> sequenceConditionNames;
IList<IOperation> sequenceConditions;
public int ConditionsCount { get { return sequenceConditions != null ? sequenceConditions.Count : 0; } }
/// Strings are added to the combo-box for transition sequence condition selection
public string ConditionName(int i)
{
if (sequenceConditionNames != null && i < sequenceConditionNames.Count && i >= 0)
return sequenceConditionNames[i];
else
return string.Empty;
}
/// Operations are executed as a part of a transition sequence
public IOperation ConditionOp(int i)
{
if (sequenceConditions != null && i < sequenceConditions.Count && i >= 0)
return sequenceConditions[i];
else
return null;
}
void ClearConditions()
{
sequenceConditionNames = new List<string>();
sequenceConditions = new List<IOperation>();
}
void AddCondition(string conditionName, IOperation conditionOperation)
{
sequenceConditionNames.Add(conditionName);
sequenceConditions.Add(conditionOperation);
}
/// <summary>
/// Create a list of conditions
/// </summary>
void CreateConditions()
{
ClearConditions();
foreach (var pressLimit in new double[] { 2.18, 2.2, 2.22, 2.24, 2.26, 2.27 })
{
AddCondition(string.Format("{0} {1} > {2} bar", Strings.Wait_until, Name, pressLimit), new WaitUntilValueIsOp(this, Pr.IsGT, pressLimit));
AddCondition(string.Format("{0} {1} < {2} bar", Strings.Wait_until, Name, pressLimit), new WaitUntilValueIsOp(this, Pr.IsLT, pressLimit));
}
}
}
}
@@ -0,0 +1,240 @@
///
/// Copyright (c) 2021-2023 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using Common;
using Config.Entities;
using SchematicDrawing;
using TBF.Rig.Generic;
namespace TBF.Rig.Modbus.Meret.AdjustableScale
{
public class AdjustableMeterCfg : ComponentCfgBase, IChildComponentCfg, GenericDevices.ICalibInfoCfg, IParamsProvider,
IDrawingItemWithMeasuredVal
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(AdjustableMeterCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities)
{
var parents = cmpntEntities.Where(x => x.ClassName == "Modbus.Common");
return new Configs.ParamsProvider.ComponentCfgCtrl(this, parents);
}
///
/// Serialized parameters
///
public int ModbusAddress; /// 0 (1..254)
public double DefaultPressure; /// 1
public string MsrdFormat { get; set; } /// 2
public Unit MsrdUnit { get; set; } /// 3
public double MsrdValLimLo { get; set; } /// 4
public double MsrdValLimHi { get; set; } /// 5
public double CorrectionValLo { get ; set; } /// 6
public double CorrectionValHi { get ; set; } /// 7
/// Calibration info serialized parameters displayed in Metrology tab page
public string CalibCertificateNr { get; set; }
public string CertPath { get; set; }
public DateTime CalibDate { get; set; }
public DateTime CalibValidDate { get; set; }
/// Schematic drawing info
public Shape Shape { get; set; }
public int X { get; set; }
public int Y { get; set; }
public Sz Sz { get; set; }
public Orient Orient { get; set; }
public bool Flip { get; set; }
public int LblX { get; set; }
public int LblY { get; set; }
public Orient LblOrient { get; set; }
public int MsrdX { get; set; }
public int MsrdY { get; set; }
public Orient MsrdOrient { get; set; }
[XmlIgnore]
public IList<GNode> GNodes { get; set; }
/// Private parameterless constructor invoked by all other (public) constructors
AdjustableMeterCfg()
{
GNodes = new List<GNode>();
}
public AdjustableMeterCfg(IComponentFactory factory)
: this()
{
Shape = Shape.ElectricM;
Sz = Sz.M;
Factory = factory;
Name = "Ad";
ParentName = "Modbus";
InitializeAll();
}
public string ComponentName { get { return Name; } }
public void InitializeAll()
{
ModbusAddress = 49;
DefaultPressure = 2.34;
MsrdFormat = "{0:F2} A";
MsrdUnit = Unit.A;
MsrdValLimLo = -0.1;
MsrdValLimHi = 25.0;
CorrectionValLo = 0.0;
CorrectionValHi = 0.0;
MsrdY = 22;
}
string[] paramNames = new string[]
{
"Modbus address", /// 0
"Default value", /// 1
"Display format", /// 2
"Unit", /// 3
"Limit Lo", /// 4
"Limit Hi", /// 5
"Correction limit Lo", /// 6
"Correction limit Hi", /// 7
};
public string ParamName(int i) { return paramNames[i]; }
public int ParamsCount() { return paramNames.Length; }
public ICollection<string> ParamValues(int i)
{
switch (i)
{
case 3:
return new string[] { "A", "mA", "V", "mV", "Pa", "hPa", "mbar", "kPa", "inHg", "psi", "bar", "MPa" };
default:
return null;
}
}
public string ToString(int i)
{
switch (i)
{
case 0: return ModbusAddress.ToString();
case 1: return DefaultPressure.ToString();
case 2: return MsrdFormat;
case 3: return MsrdUnit.ToDescription();
case 4: return MsrdValLimLo.ToString();
case 5: return MsrdValLimHi.ToString();
case 6: return CorrectionValLo.ToString();
case 7: return CorrectionValHi.ToString();
default:
return string.Format("{0}({1}) address={2}", Name, string.IsNullOrEmpty(ParentName) ? "-" : ParentName, ModbusAddress);
}
}
public CfgUpdateFlags UpdateParam(int i, string str)
{
switch (i)
{
case 0: ModbusAddress = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
case 1: DefaultPressure = Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd;
case 2: MsrdFormat = str; return CfgUpdateFlags.RestartRqrd;
case 3:
foreach (var u in new Unit[] { Unit.A, Unit.mA, Unit.V, Unit.mV, Unit.Pa, Unit.hPa, Unit.mbar, Unit.kPa, Unit.inHg, Unit.psi, Unit.bar, Unit.MPa })
{
if (str == u.ToDescription())
{
MsrdUnit = u;
return CfgUpdateFlags.RestartRqrd;
}
}
return CfgUpdateFlags.None;
case 4: MsrdValLimLo = Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd;
case 5: MsrdValLimHi = Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd;
case 6: CorrectionValLo = Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd;
case 7: CorrectionValHi = Utils.ParseSDouble(str); return CfgUpdateFlags.RestartRqrd;
default: return CfgUpdateFlags.None;
}
}
public bool ValidateParam(int i, string str, out string message)
{
message = string.Empty;
int idummy;
double dummy;
switch (i)
{
case 0:
if (int.TryParse(str, out idummy) && idummy >= 1 && idummy <= 254) return true;
break;
case 1:
case 4:
case 5:
case 6:
case 7:
if (TBF.Utils.TryParseSDouble(str, out dummy)) return true;
break;
case 2:
return true;
case 3:
if (ParamValues(i).Contains(str)) return true;
break;
default:
message = "Invalid index";
return false;
}
message = ParamName(i) + " is invalid";
return false;
}
void CopyContentTo(AdjustableMeterCfg prms)
{
prms.ParentName = this.ParentName;
prms.CalibCertificateNr = this.CalibCertificateNr;
prms.CertPath = this.CertPath;
prms.CalibDate = this.CalibDate;
prms.CalibValidDate = this.CalibValidDate;
prms.Shape = this.Shape;
prms.Sz = this.Sz;
prms.Orient = this.Orient;
prms.Flip = this.Flip;
prms.LblX = this.LblX;
prms.LblY = this.LblY;
prms.LblOrient = this.LblOrient;
prms.MsrdX = this.MsrdX;
prms.MsrdY = this.MsrdY;
prms.MsrdOrient = this.MsrdOrient;
prms.ModbusAddress = this.ModbusAddress;
prms.DefaultPressure = this.DefaultPressure;
prms.MsrdFormat = this.MsrdFormat;
prms.MsrdUnit = this.MsrdUnit;
prms.MsrdValLimLo = this.MsrdValLimLo;
prms.MsrdValLimHi = this.MsrdValLimHi;
prms.CorrectionValLo = this.CorrectionValLo;
prms.CorrectionValHi = this.CorrectionValHi;
}
public IParamsProvider Clone()
{
AdjustableMeterCfg pars = new AdjustableMeterCfg();
CopyContentTo(pars);
return pars;
}
public bool UpdateEmbeddedDbEntity()
{
return true; /// =OK, do nothing
}
}
}
@@ -0,0 +1,25 @@
///
/// Copyright (c) 2016-2020 Sensus Slovensko a.s.
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.Modbus.Meret.AdjustableScale
{
public class Factory : IComponentFactory
{
public string ClassName { get { return GetType().Namespace.Substring(8); } }
public override string ToString() { return ClassName; }
public IComponent DummyComponent() { return new AdjustableMeter(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new AdjustableMeter(cfg, components); }
public IComponentCfg DefaultConfig() { return new AdjustableMeterCfg(this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(AdjustableMeterCfg.Serializer, component, this);
}
}
}
@@ -0,0 +1,60 @@
///
/// Copyright (c) 2016-2021 Sensus Slovensko a.s.
///
using System;
using log4net;
using TBF.Boxes;
namespace TBF.Rig.Modbus.Meret.AdjustableScale
{
public class ReadValueOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadValueOp));
public override string ToString() { return string.Format("ReadPressureOp(.,{0},.)", eventDone); }
/// Set by the constructor
readonly AdjustableMeter _adjustableMeter;
readonly DoubleBox value; /// Box for the measured value
readonly Event eventDone;
/// <summary>
/// Events: PressureDone or Error
/// </summary>
/// <param name="adjustableMeter">Pressure meter reference</param>
/// <param name="value">Reference to the measured pressure variable, value is in bar</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public ReadValueOp(AdjustableMeter adjustableMeter, ref DoubleBox value, Event eventDone)
{
if (adjustableMeter == null) throw new ArgumentNullException("adjustableMeter");
this._adjustableMeter = adjustableMeter;
this.value = value;
this.eventDone = eventDone;
log.Debug(this.ToString());
}
public ReadValueOp(AdjustableMeter adjustableMeter, ref DoubleBox value)
: this(adjustableMeter, ref value, Event.PressureDone)
{
}
/// <summary>Start this operation</summary>
public void Start()
{
if (value != null) value.Val = _adjustableMeter.ReadPressure();
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.PressureInDone or Event.PressureOutDone
/// </returns>
public Event Run()
{
if (value != null) value.Val = _adjustableMeter.ReadPressure();
return eventDone;
}
/// <summary>Stop this operation</summary>
public void Stop() { }
}
}
@@ -0,0 +1,61 @@
///
/// Copyright (c) 2022 Sensus Slovensko a.s.
///
using System;
using log4net;
namespace TBF.Rig.Modbus.Meret.AdjustableScale
{
public enum Pr
{
IsGT,
IsLT,
}
public class WaitUntilValueIsOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(WaitUntilValueIsOp));
public override string ToString() { return string.Format("WaitUntilPressureIsOp({0}, {1}, {2:F1}bar)", meter.Name, condition, valueLimit); }
/// Set by the constructor
readonly AdjustableMeter meter;
readonly double valueLimit;
readonly Pr condition;
/// <summary>
/// Events: PressureInDone, PressureOutDone or Error
/// </summary>
/// <param name="meter">Temp. controller reference</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public WaitUntilValueIsOp(AdjustableMeter meter, Pr condition, double valueLimit)
{
if (meter == null) throw new ArgumentNullException("tempControl");
this.meter = meter;
this.valueLimit = valueLimit;
this.condition = condition;
log.Debug(this.ToString());
}
/// <summary>Start this operation</summary>
public void Start() { }
/// <summary>Run this operation</summary>
public Event Run()
{
if (condition == Pr.IsGT && meter.ReadPressure() > valueLimit)
{
return Event.ConditionMet;
}
else if (condition == Pr.IsLT && meter.ReadPressure() < valueLimit)
{
return Event.ConditionMet;
}
return Event.ConditionNotMet;
}
/// <summary>Stop this operation</summary>
public void Stop() { }
}
}
+2 -2
View File
@@ -191,7 +191,7 @@ namespace TBF.Rig.Modbus.TankSelector
/// </summary>
void RecoverState()
{
latchedDigitalInputs = StateMachine.ControlBoard.DigitalInputs;
latchedDigitalInputs = StateMachine.ControlBoardMain.DigitalInputs;
if ((latchedDigitalInputs & (ulong)DigitalInputs.ColdTankSelected) != 0)
{
if ((latchedDigitalInputs & (ulong)DigitalInputs.Pumping_WaitingLevel) == 0)
@@ -228,7 +228,7 @@ namespace TBF.Rig.Modbus.TankSelector
/// </summary>
void DetectNoTankSelected()
{
ulong digiIn = StateMachine.ControlBoard.DigitalInputs;
ulong digiIn = StateMachine.ControlBoardMain.DigitalInputs;
if (digiIn == latchedDigitalInputs)
{
+25
View File
@@ -0,0 +1,25 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.Network.AdapterFTP
{
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 NetFtpAdapter(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new NetFtpAdapter(cfg); }
public IComponentCfg DefaultConfig() { return new NetFtpadapterCfg(this.GetType().Namespace.Substring(8), this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(NetFtpadapterCfg.Serializer, component, this);
}
}
}
@@ -0,0 +1,35 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System.Net;
using log4net;
using TBF.Rig.GenericDevices;
namespace TBF.Rig.Network.AdapterFTP
{
public class NetFtpAdapter : ComponentBase, GenericDevices.IFTPAdapter
{
private static readonly ILog log = LogManager.GetLogger(typeof(NetFtpAdapter));
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
readonly NetFtpadapterCfg netFtpadapterCfg;
private string path;
public string Path { get => path; }
public NetFtpAdapter() { }
public NetFtpAdapter(Generic.IComponentCfg cfg)
: base(cfg)
{
netFtpadapterCfg = cfg as NetFtpadapterCfg;
log.Warn(this.ToString());
}
public override void Initialize()
{
path = netFtpadapterCfg.Path;
}
}
}
@@ -0,0 +1,44 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.Xml.Serialization;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Rig.GenericDevices;
namespace TBF.Rig.Network.AdapterFTP
{
public class NetFtpadapterCfg : ComponentCfgBase, Generic.IComponentCfg
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(NetFtpadapterCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new NetadapterCfgCtrl(); }
public string Description; /// Description string of the selected network adapter
public string Path; // path to Ftp
public string Trigger;
/// Private parameterless constructor invoked by all other (public) constructors NetFtpadapterCfg() {}
public NetFtpadapterCfg(string name, IComponentFactory factory)
: this()
{
Name = name;
Factory = factory;
ParentName = string.Empty;
}
protected NetFtpadapterCfg()
{
}
public string ToString(int i)
{
return string.Format("Name={0}, Description={1}", Name, Description);
}
}
}
@@ -0,0 +1,126 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Windows.Forms;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
namespace TBF.Rig.Network.AdapterFTP
{
public partial class NetadapterCfgCtrl : UserControl, IComponentCfgCtrl
{
public bool ShowMore { get { return false; } }
NetFtpadapterCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as NetFtpadapterCfg;
Redraw();
}
}
public NetadapterCfgCtrl()
{
InitializeComponent();
nameTextBox.Enabled = false;
textBoxFtpDir.Enabled = false;
btnDirSelect.Enabled = false;
button1.Enabled = false;
}
private void EntryFormCfgCtrl_Load(object sender, EventArgs e)
{
if (ParentForm == null) return; /// Return is executed when tab page is open in Designer
if (config == null) return; /// Control was not loaded, settings were not changed
Localize();
Redraw();
}
void Redraw()
{
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
textBoxFtpDir.Text = config.Path;
}
void Localize()
{
}
public void Closing()
{
}
public void Unlock()
{
nameTextBox.Enabled = true;
textBoxFtpDir.Enabled = true;
btnDirSelect.Enabled = true;
button1.Enabled = true;
}
public CfgUpdateFlags VerifyCfg(ref string message)
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
if (!Directory.Exists(textBoxFtpDir.Text))
{
flags = CfgUpdateFlags.Error;
message += Environment.NewLine + "Invalid 'Dir path'";
}
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;
/// Network adapter
string strAdapter = textBoxFtpDir.Text;
int iDash = strAdapter.IndexOf(" - ");
config.Description = iDash < 0 ? "" : strAdapter.Substring(iDash + 3);
config.Path = textBoxFtpDir.Text;
return flags;
}
private void btnDirSelect_Click(object sender, EventArgs e)
{
// Create FolderBrowserDialog
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
// Set initial directory
folderBrowserDialog.SelectedPath = textBoxFtpDir.Text; // Set your predefined path here
// Show the dialog and capture the result
DialogResult result = folderBrowserDialog.ShowDialog();
// Process the result
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(folderBrowserDialog.SelectedPath))
{
textBoxFtpDir.Text = folderBrowserDialog.SelectedPath;
}
}
private void button1_Click(object sender, EventArgs e)
{
textBoxFtpDir.Text = @"C:\TBF\camera";
}
}
}
+162
View File
@@ -0,0 +1,162 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
namespace TBF.Rig.Network.AdapterFTP
{
partial class NetadapterCfgCtrl
{
/// <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.components = new System.ComponentModel.Container();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.adapterLabel = new System.Windows.Forms.Label();
this.errorProvider1 = new System.Windows.Forms.ErrorProvider(this.components);
this.textBoxFtpDir = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.btnDirSelect = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.errorProvider1)).BeginInit();
this.SuspendLayout();
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(152, 77);
this.nameTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(169, 26);
this.nameTextBox.TabIndex = 5;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(14, 82);
this.nameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(51, 20);
this.nameLabel.TabIndex = 4;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(147, 37);
this.classNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(125, 20);
this.classNameLabel.TabIndex = 3;
this.classNameLabel.Text = "ComonentName";
//
// adapterLabel
//
this.adapterLabel.AutoSize = true;
this.adapterLabel.Location = new System.Drawing.Point(14, 123);
this.adapterLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.adapterLabel.Name = "adapterLabel";
this.adapterLabel.Size = new System.Drawing.Size(66, 20);
this.adapterLabel.TabIndex = 6;
this.adapterLabel.Text = "Adapter";
//
// errorProvider1
//
this.errorProvider1.ContainerControl = this;
//
// textBoxFtpDir
//
this.textBoxFtpDir.Location = new System.Drawing.Point(151, 120);
this.textBoxFtpDir.Name = "textBoxFtpDir";
this.textBoxFtpDir.Size = new System.Drawing.Size(373, 26);
this.textBoxFtpDir.TabIndex = 7;
//
// label1
//
this.label1.Location = new System.Drawing.Point(151, 161);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(267, 36);
this.label1.TabIndex = 8;
this.label1.Text = "Standart FTP dir: C:\\TBF\\camera";
//
// btnDirSelect
//
this.btnDirSelect.Location = new System.Drawing.Point(546, 116);
this.btnDirSelect.Name = "btnDirSelect";
this.btnDirSelect.Size = new System.Drawing.Size(37, 34);
this.btnDirSelect.TabIndex = 9;
this.btnDirSelect.Text = "...";
this.btnDirSelect.UseVisualStyleBackColor = true;
this.btnDirSelect.Click += new System.EventHandler(this.btnDirSelect_Click);
//
// button1
//
this.button1.Location = new System.Drawing.Point(465, 152);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(118, 39);
this.button1.TabIndex = 10;
this.button1.Text = "Set Default";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// NetadapterCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.button1);
this.Controls.Add(this.btnDirSelect);
this.Controls.Add(this.label1);
this.Controls.Add(this.textBoxFtpDir);
this.Controls.Add(this.adapterLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.Name = "NetadapterCfgCtrl";
this.Size = new System.Drawing.Size(675, 462);
this.Load += new System.EventHandler(this.EntryFormCfgCtrl_Load);
((System.ComponentModel.ISupportInitialize)(this.errorProvider1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button btnDirSelect;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ErrorProvider errorProvider1;
private System.Windows.Forms.TextBox textBoxFtpDir;
#endregion
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.Label adapterLabel;
}
}
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="errorProvider1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
-4
View File
@@ -2,9 +2,7 @@
/// Copyright (c) 2017-2022 Sensus Slovensko a.s.
///
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
@@ -12,11 +10,9 @@ using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Timers;
using log4net;
using Renci.SshNet;
using Common;
using Config.Entities;
using TBF.Rig.Network.Telnet;
using TBF.Resources;
@@ -0,0 +1,318 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Text.RegularExpressions;
using System.Threading;
using Common;
using log4net;
using TBF.Resources;
namespace TBF.Rig.Network.Camera.KeyenceIV3G120
{
public class Camera : ComponentBase, GenericDevices.ICamera, Generic.IDevice, IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(KeyenceIV3G120.Camera));
private static readonly string ftpCameraSource = "C:\\TBF\\camera\\";
private static readonly string prefixCameraFolder = "camera";
private static readonly string prefixCameraName = "cam";
private static readonly string imageExtension = "bmp";
public static string FtpCameraSource => ftpCameraSource;
public static string PrefixCameraFolder => prefixCameraFolder;
public static string PrefixCameraName => prefixCameraName;
public static string ImageExtension => imageExtension;
public override string ToString()
{
return string.Format("{0}: Name={1}, Addr={2}",
this.GetType().Namespace.Substring(8),
CameraCfg.Name,
CameraCfg.HardwareAddress);
}
///
/// Properties
///
public readonly CameraCfg CameraCfg;
public readonly GenericDevices.IFTPAdapter NetAdapter;
//internal parameters
Thread rtpListenerThread;
static bool stopRtpListenerFlag = false;
private string lastImageRtpListener = "";
private static bool newImagePuls = false;
public Camera()
{
}
public Camera(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
: base(cfg)
{
CameraCfg = cfg as KeyenceIV3G120.CameraCfg;
NetAdapter = TbfComponents.FindComponent(cfg.ParentName, components) as GenericDevices.IFTPAdapter;
if (NetAdapter == null) throw new ArgumentNullException("no network adapter");
}
public int CameraIdx
{
get { return cameraIdx; }
}
int cameraIdx;
///
static int nextCameraIdx = 0;
static int GetCameraIdx()
{
return nextCameraIdx++;
}
/// Used in Initialize()
#region Configuration Change Handling
public static void OnCfgChange(object sender, CfgChangeArgs args)
{
if (CfgChangeHandler == null) return;
try
{
CfgChangeHandler(sender, args);
}
catch (Exception e)
{
log.Error("CfgChangeHandler(...) failed", e);
}
}
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
public override void StartChangeHandler()
{
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
{
CameraCfg tmpcfg = args.Cfg as CameraCfg;
if (tmpcfg != null && tmpcfg.Name.Equals(Name))
{
if (args.Command == CfgChangeCmd.CfgChange)
{
}
}
};
}
#endregion Configuration Change Handling
public override void Initialize()
{
cameraIdx = GetCameraIdx();
roisAndResults = new RoisAndResults();
if (CameraCfg.DebugLevel == DebugMode.Simulate)
{
UiBridge.Bridge.OnCameraInfo(cameraIdx,
string.Format("{0} s/n {1} si simulated", Name, CameraCfg.HardwareAddress));
return;
}
/// Detect a camera
bool cameraDetected = true;
if (CameraCfg.DebugLevel == DebugMode.AutoDetect)
{
//TODO BUMI detect camera via send impuls must appere new pictures in FTP server - that must be implemented to FTP loading logic
CameraCfg.DebugLevel = cameraDetected ? DebugMode.DetectedOn : DebugMode.DetectedOff;
}
else if (!cameraDetected)
{
throw new Exception(string.Format("{0}={1}", Strings.Address, CameraCfg.HardwareAddress));
}
if (cameraDetected)
{
UiBridge.Bridge.OnCameraInfo(cameraIdx,
string.Format("{0} s/n {1}", Name, CameraCfg.HardwareAddress));
StartRtpListener();
}
}
///
/// ROI related parameters
///
RoisAndResults roisAndResults;
///
public void ClearRoiParams() { roisAndResults.ClearRoiParams(); }
public int RegisterRoi(string roiParams) { return roisAndResults.RegisterRoi(roiParams); }
public int GetResult(int roiHandle, out long timeMs) { return roisAndResults.GetResult(roiHandle, out timeMs); }
public bool Running { get { return running; } }
bool running;
public bool ShowOverlayRect { set { showOverlayRect = value; } }
bool showOverlayRect = false;
public Rectangle OverlayRect { set { overlayRect = value; } }
Rectangle overlayRect;
public int OverlayThickness { set { overlayThickness = value; } }
int overlayThickness;
public IOperation LiveStreamOp(bool hiRes)
{
throw new System.NotImplementedException();
}
public IOperation MeasurementOp()
{
return this;
}
public IOperation GrabImagesOp(string[] imgFileNames, bool blackAndWhite, bool lowResolution,
ImageRotation imageRotation)
{
return new GrabImagesOp(this, imgFileNames, null, new DateTime());
}
public void RunDeviceBefore()
{
if ((CameraCfg.DebugLevel != DebugMode.Simulate) && (CameraCfg.DebugLevel != DebugMode.DetectedOff))
{
}
}
public void RunDeviceAfter() { }
public void StopDevice()
{
if ((CameraCfg.DebugLevel != DebugMode.Simulate) && (CameraCfg.DebugLevel != DebugMode.DetectedOff))
{
running = false;
stopRtpListenerFlag = true;
}
}
public void StopDevice2()
{
if ((CameraCfg.DebugLevel != DebugMode.Simulate) && (CameraCfg.DebugLevel != DebugMode.DetectedOff))
{
if (rtpListenerThread != null) rtpListenerThread.Join(50);
}
}
public void Start()
{
throw new System.NotImplementedException();
}
public Event Run()
{
throw new System.NotImplementedException();
}
public void Stop()
{
if ((CameraCfg.DebugLevel != DebugMode.Simulate) && (CameraCfg.DebugLevel != DebugMode.DetectedOff))
{
running = false;
stopRtpListenerFlag = true;
}
}
private void StartRtpListener()
{
rtpListenerThread = new Thread(new ThreadStart(RtpListener));
rtpListenerThread.Start();
}
public void RtpListener()
{
log.Debug($"RtpListener - started, stopRtpListenerFlag: {stopRtpListenerFlag}");
int penWidth = 1;
Pen pen = new Pen(Color.Green, penWidth);
string pathDir = $"{ftpCameraSource}{prefixCameraFolder}{cameraIdx}\\";
string searchPattern = $"^.*{prefixCameraName}{cameraIdx}_[\\w]{{0,5}}[\\d]{{6}}_[\\d]{{6}}\\.(?i)bmp$";
while (!stopRtpListenerFlag)
{
try
{
//Try to find picture candidate, shout be on FTP
Image image = null;
string[] picCandidates = Directory.GetFiles(pathDir, "*.bmp", SearchOption.TopDirectoryOnly);
if (picCandidates.Length == 1 && picCandidates.Any(pic => pic == lastImageRtpListener))
{
continue;
}
picCandidates = picCandidates.Where(pic => Regex.IsMatch(pic, searchPattern)).ToArray();
if (picCandidates != null && picCandidates.Length > 0)
{
string newCandidate = CameraUtils.GetLastCreationTimeCandidate(picCandidates);
if (newCandidate == lastImageRtpListener)
{
continue;
}
log.Debug($"RtpListener - in Cycle, newCandidate: {newCandidate}");
try
{
CameraUtils.WaitForImageCompleteOnDisk(newCandidate);
using (Image originalImage = Image.FromFile(newCandidate))
{
// Create a new bitmap from the loaded image
using (Bitmap bitmapCopy = new Bitmap(originalImage))
{
// Create an Image object from the Bitmap object (bitmapCopy)
image = bitmapCopy.Clone() as Image;
}
}
}
catch (Exception ex)
{
log.Error("Error loading image: " + ex.Message);
}
if (showOverlayRect && overlayRect != null && overlayThickness > 0)
{
using (var grph = Graphics.FromImage(image))
{
if (penWidth != overlayThickness)
{
penWidth = overlayThickness;
pen = new Pen(Color.Green, penWidth);
}
grph.DrawRectangle(pen, overlayRect);
}
}
log.Debug($"Image success!, size: {image.Size.ToString()}");
UiBridge.Bridge.OnImage(this.cameraIdx, image);
lastImageRtpListener = newCandidate;
}
}
catch (Exception exc)
{
string msg = string.Format("Exception in MJpeg RTP listener thread: {0}", exc.Message);
log.Error(msg);
}
}
log.Debug($"RtpListener - finished, stopRtpListenerFlag: {stopRtpListenerFlag}");
return;
}
}
}
@@ -0,0 +1,48 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Xml.Serialization;
using Common;
using TBF.Rig.Generic;
using TBF.Resources;
namespace TBF.Rig.Network.Camera.KeyenceIV3G120
{
public class CameraCfg : ComponentCfgBase, IChildComponentCfg
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(CameraCfg) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public IComponentCfgCtrl GetControl(IList<Config.Entities.Component> cmpntEntities) { return new CameraCfgCtrl(); }
///
/// Serialized parameters
///
public int HardwareAddress;
/// Private parameterless constructor invoked by all other (public) constructors
CameraCfg() { }
public CameraCfg(string name, IComponentFactory factory)
: this()
{
Name = name;
Factory = factory;
ParentName = "Network.AdapterFTP";
HardwareAddress = 1;
DebugLevel = DebugMode.AutoDetect;
}
public string ToString(int i)
{
return string.Format("Name={0}, s/n={1}, Parent={2}",
Name,
HardwareAddress,
ParentName);
}
}
}
@@ -0,0 +1,145 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using System.Windows.Forms;
using Common;
using Config.Entities;
using TBF.Rig.Generic;
using TBF.Resources;
using TBF.UI.Bench.Components;
namespace TBF.Rig.Network.Camera.KeyenceIV3G120
{
public partial class CameraCfgCtrl : UserControl, IComponentCfgCtrl
{
ComponentParametersDlg parent;
public bool ShowMore { get { return false; } }
CameraCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as CameraCfg;
Redraw();
}
}
public CameraCfgCtrl()
{
InitializeComponent();
}
private void PumpCfgCtrl_Load(object sender, EventArgs e)
{
Localize();
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.CmpntEntities != null)
{
foreach (var cmpnt in parent.CmpntEntities)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is TBF.Rig.Network.AdapterFTP.Factory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
void Localize()
{
nameLabel.Text = Strings.Name;
parentNameLabel.Text = Strings.Parent_name;
hwAddressLabel.Text = Strings.Serial_number;
}
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;
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
hwAddressTextBox.Text = config.HardwareAddress.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
hwAddressTextBox.Enabled = true;
}
public CfgUpdateFlags VerifyCfg(ref string message)
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
int dummy;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format(Strings.Invalid_0, parentNameLabel.Text);
}
if (!int.TryParse(hwAddressTextBox.Text, out dummy) || dummy % 100 > 63)
{
flags |= CfgUpdateFlags.Error;
message += Environment.NewLine + string.Format(Strings.Invalid_0, hwAddressLabel.Text);
}
return flags;
}
public CfgUpdateFlags UpdateCfg()
{
CfgUpdateFlags flags = CfgUpdateFlags.None;
if (config == null) return CfgUpdateFlags.Error; /// Control was not loaded, settings were not changed
string newParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
int newHWAddress = int.Parse(hwAddressTextBox.Text);
if (config.Name != nameTextBox.Text ||
config.ParentName != newParentName ||
config.HardwareAddress != newHWAddress )
{
config.Name = nameTextBox.Text;
config.ParentName = newParentName;
config.HardwareAddress = newHWAddress;
flags |= (CfgUpdateFlags.RestartRqrd | CfgUpdateFlags.AnyChange);
}
// if (config.TestImagesMode != newTestImagesMode ||
// config.TestImagesCount != newTestImagesCount)
// {
// config.TestImagesMode = newTestImagesMode;
// config.TestImagesCount = newTestImagesCount;
//
// flags |= (CfgUpdateFlags.InvokeCfgChange | CfgUpdateFlags.VolatileChange);
// }
if ((flags & CfgUpdateFlags.InvokeCfgChange) != 0)
{
Camera.OnCfgChange(this, new CfgChangeArgs(CfgChangeCmd.CfgChange, config));
}
return flags;
}
}
}
@@ -0,0 +1,140 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
namespace TBF.Rig.Network.Camera.KeyenceIV3G120
{
partial class CameraCfgCtrl
{
/// <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.hwAddressTextBox = new System.Windows.Forms.TextBox();
this.hwAddressLabel = new System.Windows.Forms.Label();
this.parentNameLabel = 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.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// hwAddressTextBox
//
this.hwAddressTextBox.Enabled = false;
this.hwAddressTextBox.Location = new System.Drawing.Point(198, 142);
this.hwAddressTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.hwAddressTextBox.Name = "hwAddressTextBox";
this.hwAddressTextBox.Size = new System.Drawing.Size(193, 26);
this.hwAddressTextBox.TabIndex = 6;
//
// hwAddressLabel
//
this.hwAddressLabel.AutoSize = true;
this.hwAddressLabel.Location = new System.Drawing.Point(42, 146);
this.hwAddressLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.hwAddressLabel.Name = "hwAddressLabel";
this.hwAddressLabel.Size = new System.Drawing.Size(107, 20);
this.hwAddressLabel.TabIndex = 5;
this.hwAddressLabel.Text = "Serial number";
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(42, 106);
this.parentNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.parentNameLabel.Name = "parentNameLabel";
this.parentNameLabel.Size = new System.Drawing.Size(100, 20);
this.parentNameLabel.TabIndex = 3;
this.parentNameLabel.Text = "Parent name";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(198, 63);
this.nameTextBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(193, 26);
this.nameTextBox.TabIndex = 2;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(42, 68);
this.nameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(51, 20);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(194, 26);
this.classNameLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(125, 20);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(198, 102);
this.parentNameComboBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(193, 28);
this.parentNameComboBox.TabIndex = 4;
//
// CameraCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.hwAddressTextBox);
this.Controls.Add(this.hwAddressLabel);
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.Name = "CameraCfgCtrl";
this.Size = new System.Drawing.Size(603, 391);
this.Load += new System.EventHandler(this.PumpCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox hwAddressTextBox;
private System.Windows.Forms.Label hwAddressLabel;
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.ComboBox parentNameComboBox;
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,97 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using log4net;
namespace TBF.Rig.Network.Camera.KeyenceIV3G120
{
public class CameraUtils
{
private static readonly ILog log = LogManager.GetLogger(typeof(KeyenceIV3G120.CameraUtils));
public static string GetLastCreationTimeCandidate(string[] picCandidates)
{
var creationTimes = picCandidates.Select(path => new FileInfo(path).CreationTime).ToArray();
// Find the index of the latest creation time
var latestIndex = Array.IndexOf(creationTimes, creationTimes.Max());
// Get the path of the file with the latest creation time
return picCandidates[latestIndex];
}
public static void WaitForImageCompleteOnDisk(string picturePath)
{
//TODO finish
//we start this part in moment we found some file in disk
//wait for finish write image on disk - FTP is slow
if (File.Exists(picturePath))
{
try
{
for (int iIteration = 0;iIteration < 10;iIteration++) // wait max 2 sec - otherwise there may be a problem
{
Thread.Sleep(200);
try
{
using (FileStream fs = File.Open(picturePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
break;
}
}
catch (IOException ex)
{
// Handle the case when the file is not ready or cannot be accessed
log.Debug("No accessing rihts! We will wait next iteration!");
}
}
}
catch (Exception e)
{
log.Error("Error to wait for writing file to disk. Detail: " + e.StackTrace);
}
}
}
public void CallTrigger()
{
//TODO call initialisation signal - valve open
}
public static void ClearDir(string path)
{
log.Debug($"ClearDir({path}) called!");
string[] filesToDelete = Directory.GetFiles(path, "*.*", SearchOption.TopDirectoryOnly);
ClearDir(filesToDelete);
}
public static void ClearDir(string[] files)
{
foreach (string file in files)
{
if (File.Exists(file))
{
try
{
// Check if user has write permission for the file
if ((File.GetAttributes(file) & FileAttributes.ReadOnly) == 0)
{
File.Delete(file);
log.Debug($"Deleted: {file}");
}
else
{
log.Debug($"Insufficient permissions to delete: {file}");
}
}
catch (Exception ex)
{
log.Debug($"Error deleting {file}: {ex.Message}");
}
}
}
}
}
}
@@ -0,0 +1,25 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System.Collections.Generic;
using TBF.Rig.Generic;
namespace TBF.Rig.Network.Camera.KeyenceIV3G120
{
public class Factory : IComponentFactory
{
public string ClassName { get { return GetType().Namespace.Substring(8); } }
public override string ToString() { return ClassName; }
public IComponent DummyComponent() { return new Camera(); }
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Camera(cfg, components); }
public IComponentCfg DefaultConfig() { return new CameraCfg(this.GetType().Namespace.Substring(8), this); }
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
{
return ComponentCfgBase.CreateFromDbEntity(CameraCfg.Serializer, component, this);
}
}
}
@@ -0,0 +1,115 @@
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Common;
using log4net;
namespace TBF.Rig.Network.Camera.KeyenceIV3G120
{
public class GrabImagesOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(GrabImagesOp));
public override string ToString() { return string.Format("GrabImageOp()"); }
private readonly Camera camera;
readonly string[] imgFileNames;
private readonly string path;
private readonly DateTime time;
bool grabImageDone;
bool grabPassed;
bool grabFailed;
public GrabImagesOp(Camera camera, string[] imgFileNames, string path, DateTime time)
{
this.camera = camera;
this.imgFileNames = imgFileNames;
this.path = path;
this.time = time;
}
public void Start()
{
grabImageDone = false;
if ((imgFileNames != null) && (imgFileNames.Length > 0) && File.Exists(imgFileNames[0]))
{
///
/// An image specified, (1) delete previous image, (2) check if this is a simulation
///
File.Delete(imgFileNames[0]);
if (camera.CameraCfg.DebugLevel == DebugMode.Simulate || camera.CameraCfg.DebugLevel == DebugMode.DetectedOff)
{
///
/// Camera is in simulation mode => create a simulated image
///
File.Copy(string.Format("{0}\\Pictures\\sample.jpg", Program.ExecutableDir), imgFileNames[0]);
}
}
}
public Event Run()
{
if ((imgFileNames == null) || (imgFileNames.Length < 1) || (imgFileNames[0] == null))
{
///
/// No images to be grabbed => Done
///
return Event.GrabPassed;
}
else if (camera.CameraCfg.DebugLevel == DebugMode.Simulate ||
camera.CameraCfg.DebugLevel == DebugMode.DetectedOff)
{
///
/// Camera is in simulation mode => create a simulated image and complete
///
return Event.GrabPassed;
}
else if (!grabImageDone)
{
string pathDir = $"{Camera.FtpCameraSource}{Camera.PrefixCameraFolder}{camera.CameraIdx}\\";
string searchPattern = $"^.*{Camera.PrefixCameraName}{camera.CameraIdx}_[\\w]{{0,5}}[\\d]{{6}}_[\\d]{{6}}\\.(?i)bmp$";
string[] picCandidates = Directory.GetFiles(pathDir, "*.bmp", SearchOption.TopDirectoryOnly);
picCandidates = picCandidates.Where(pic => Regex.IsMatch(pic, searchPattern)).ToArray();
if (picCandidates != null && picCandidates.Length > 0)
{
string newCandidate = CameraUtils.GetLastCreationTimeCandidate(picCandidates);
log.Debug($"GrabImageOP.Run() - in Cycle, newCandidate: {newCandidate}");
try
{
CameraUtils.WaitForImageCompleteOnDisk(newCandidate);
File.Move(newCandidate, imgFileNames[0]);
grabImageDone = true;
grabPassed = true;
CameraUtils.ClearDir(pathDir);
return Event.GrabPassed;
}
catch (Exception ex)
{
log.Error("Error loading image: " + ex.Message);
grabFailed = true;
return Event.Error;
}
}
return Event.CameraBusy;
}
return Event.CameraBusy;
}
public void Stop()
{
if (camera.CameraCfg.DebugLevel == DebugMode.Simulate) return;
if (grabImageDone)
{
string pathDir = $"{Camera.FtpCameraSource}{Camera.PrefixCameraFolder}{camera.CameraIdx}\\";
CameraUtils.ClearDir(pathDir);
}
}
}
}
@@ -0,0 +1,91 @@
///
/// Copyright (c) 2017 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
namespace TBF.Rig.Network.Camera.KeyenceIV3G120
{
public class RoisAndResults
{
public const int MaxRegisteredRois = 4; /// Max. count of registered (and measured) ROI-s
public long CameraTimeMs;
public int[] Angles;
private IList<string> roiParams;
public int RegisteredRoisCount { get { return roiParams.Count; } }
public RoisAndResults()
{
Angles = new int[MaxRegisteredRois];
roiParams = new List<string>();
}
public void ClearRoiParams()
{
lock (this)
{
roiParams.Clear();
}
}
public int RegisterRoi(string roiParam)
{
lock (this)
{
if (this.roiParams.Count >= MaxRegisteredRois) return 0;
this.roiParams.Add(roiParam);
return this.roiParams.Count; /// return a handle 1 .. MaxRegisteredRois
}
}
public string GetRoiParams(int roiHandle)
{
lock (this)
{
if (roiHandle > 0 && roiHandle <= roiParams.Count)
{
return roiParams[roiHandle - 1];
}
else
{
return string.Empty;
}
}
}
public void SetResults(long timeMs, int[] angles)
{
lock (this)
{
CameraTimeMs = timeMs;
for (int i = 0; i < Math.Min(angles.Length, Angles.Length); i++)
{
Angles[i] = angles[i];
}
}
}
public int GetResult(int roiHandle, out long timeMs)
{
lock (this)
{
if (roiHandle > 0 && roiHandle <= roiParams.Count)
{
timeMs = CameraTimeMs;
return Angles[roiHandle - 1];
}
else
{
timeMs = 0;
return 0;
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More