Merge branch 'develop/SLM-PT50-7-2026-merged-smart-cam-slm-mex' into develop/Mexico-6-2026

This commit is contained in:
Marek Frniak 2026-07-20 15:54:01 +02:00
commit 4cd191fcb2
64 changed files with 17594 additions and 1654 deletions

View File

@ -2,6 +2,7 @@
/// Copyright (c) 2016-2021 Sensus Slovensko a.s.
///
using System;
using System.Linq;
namespace Common
{
@ -286,97 +287,97 @@ namespace Common
public static bool IsQuantity(Unit unit, Quantity quantity)
{
return (quantity == GetQuantity(unit));
return GetQuantity(unit).Contains(quantity);
}
public static Quantity GetQuantity(Unit unit)
public static Quantity[] GetQuantity(Unit unit)
{
switch (unit)
{
case Unit.pulse:
case Unit.degree:
return Quantity.Pulses;
return new[] { Quantity.Pulses };
case Unit.ml:
return Quantity.Volume;
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.l:
return Quantity.Volume;
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.dm3:
return Quantity.Volume;
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.USgal:
return Quantity.Volume;
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.UKgal:
return Quantity.Volume;
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.cf:
return Quantity.Volume;
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.m3:
return Quantity.Volume;
return new[] { Quantity.Volume, Quantity.MultiFunctionalVariables };
case Unit.lph:
return Quantity.Flow;
return new[] { Quantity.Flow };
case Unit.cfph:
return Quantity.Flow;
return new[] { Quantity.Flow };
case Unit.lpm:
return Quantity.Flow;
return new[] { Quantity.Flow };
case Unit.USgalpm:
return Quantity.Flow;
return new[] { Quantity.Flow };
case Unit.m3ph:
return Quantity.Flow;
return new[] { Quantity.Flow };
case Unit.lps:
return Quantity.Flow;
return new[] { Quantity.Flow };
case Unit.USgalps:
return Quantity.Flow;
return new[] { Quantity.Flow };
case Unit.m3pm:
return Quantity.Flow;
return new[] { Quantity.Flow };
case Unit.cfs:
return Quantity.Flow;
return new[] { Quantity.Flow };
case Unit.gps:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.gpm:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.gph:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.kgps:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.kgpm:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.kgph:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.tps:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.tpm:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.tph:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.lbps:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.lbpm:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.lbph:
return Quantity.MassFlow;
return new[] { Quantity.MassFlow};
case Unit.g:
return Quantity.Mass;
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
case Unit.oz:
return Quantity.Mass;
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
case Unit.lb:
return Quantity.Mass;
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
case Unit.kg:
return Quantity.Mass;
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
case Unit.t:
return Quantity.Mass;
return new[] { Quantity.Mass, Quantity.MultiFunctionalVariables };
case Unit.ms:
case Unit.s:
case Unit.min:
case Unit.hour:
return Quantity.Time;
return new[] { Quantity.Time };
case Unit.C:
case Unit.F:
case Unit.K:
return Quantity.Temperature;
return new[] { Quantity.Temperature };
case Unit.Pa:
case Unit.hPa:
@ -386,14 +387,14 @@ namespace Common
case Unit.psi:
case Unit.bar:
case Unit.MPa:
return Quantity.Pressure;
return new[] { Quantity.Pressure };
case Unit.RPct:
return Quantity.Humidity;
return new[] { Quantity.Humidity };
case Unit.Promile:
case Unit.Pct:
return Quantity.Error;
return new[] { Quantity.Error };
case Unit.mm:
case Unit.cm:
@ -402,23 +403,23 @@ namespace Common
case Unit.foot:
case Unit.yard:
case Unit.m:
return Quantity.Length;
return new[] { Quantity.Length };
case Unit.kgpm3:
case Unit.kgpm3:
case Unit.kgpl:
return Quantity.Density;
return new[] { Quantity.Density };
case Unit.J:
case Unit.J:
case Unit.kJ:
case Unit.MJ:
case Unit.Wh:
case Unit.kWh:
case Unit.MWh:
return Quantity.Energy;
return new[] { Quantity.Energy };
case Unit.uSpcm:
case Unit.mSpm:
return Quantity.Conductivity;
return new[] { Quantity.Conductivity };
case Unit.ppl:
case Unit.ppdm3:
@ -428,22 +429,22 @@ namespace Common
case Unit.dm3pp:
case Unit.lpdeg:
case Unit.dm3pdeg:
return Quantity.PulsePerLtr;
return new[] { Quantity.PulsePerLtr };
case Unit.ppkWh:
case Unit.kWhpp:
return Quantity.PulsePerKWh;
return new[] { Quantity.PulsePerKWh };
case Unit.A:
case Unit.mA:
return Quantity.Current;
return new[] { Quantity.Current };
case Unit.V:
case Unit.mV:
return Quantity.Voltage;
return new[] { Quantity.Voltage };
default:
return Quantity.Number;
return new[] { Quantity.Number };
}
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
@ -35,6 +35,12 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Common">
<HintPath>..\packages\Common\Common.dll</HintPath>
</Reference>
<Reference Include="Logic.ProductionToProductMapper">
<HintPath>..\packages\Common\Logic.ProductionToProductMapper.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
@ -54,6 +60,60 @@
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Xylem.Common.CommonCore">
<HintPath>..\packages\Common\Xylem.Common.CommonCore.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.CommonCore.Configuration">
<HintPath>..\packages\Common\Xylem.Common.CommonCore.Configuration.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.CommonCore.ThreadWatcher">
<HintPath>..\packages\Common\Xylem.Common.CommonCore.ThreadWatcher.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Hardware.Interfaces.Ports.PortCore">
<HintPath>..\packages\Common\Xylem.Common.Hardware.Interfaces.Ports.PortCore.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Hardware.Interfaces.Ports.SerialPorts">
<HintPath>..\packages\Common\Xylem.Common.Hardware.Interfaces.Ports.SerialPorts.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.Applications">
<HintPath>..\packages\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Applications.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig">
<HintPath>..\packages\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore">
<HintPath>..\packages\Common\Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Hardware.WaterMeter.Genesis.Registers">
<HintPath>..\packages\Common\Xylem.Common.Hardware.WaterMeter.Genesis.Registers.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Hardware.WaterMeter.MagFlux.Protocols.RequestProtocol">
<HintPath>..\packages\Common\Xylem.Common.Hardware.WaterMeter.MagFlux.Protocols.RequestProtocol.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Hardware.WaterMeter.WaterMeterCore">
<HintPath>..\packages\Common\Xylem.Common.Hardware.WaterMeter.WaterMeterCore.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters">
<HintPath>..\packages\Common\Xylem.Common.Hardware.WaterMeter.WaterMeterRegisters.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Logic.ProductionOrderCore">
<HintPath>..\packages\Common\Xylem.Common.Logic.ProductionOrderCore.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Logic.SoftwareAccessHelper">
<HintPath>..\packages\Common\Xylem.Common.Logic.SoftwareAccessHelper.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Utils.ByteArrayStyle">
<HintPath>..\packages\Common\Xylem.Common.Utils.ByteArrayStyle.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Utils.Crc16Ccitt">
<HintPath>..\packages\Common\Xylem.Common.Utils.Crc16Ccitt.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Utils.Logging">
<HintPath>..\packages\Common\Xylem.Common.Utils.Logging.dll</HintPath>
</Reference>
<Reference Include="Xylem.Common.Utils.ProcessExec">
<HintPath>..\packages\Common\Xylem.Common.Utils.ProcessExec.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="API\ModelsMapping.cs" />
@ -257,74 +317,14 @@
<WCFMetadata Include="Connected Services\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj">
<Project>{c8939821-ba5c-4988-a3d0-bf53b74865c7}</Project>
<Name>Common</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\CommonCore.Configuration\CommonCore.Configuration.csproj">
<Project>{9eb1f659-6f73-4f65-bcab-4114fd94f5fc}</Project>
<Name>CommonCore.Configuration</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\CommonCore\CommonCore.csproj">
<Project>{1b02c79e-0b19-43e2-8f6b-71ef0c786c97}</Project>
<Name>CommonCore</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\CordonelPreadjustmentUi\CordonelPreadjustmentUi.csproj">
<Project>{d0c8d887-ed52-40ab-a069-90bce0e801e2}</Project>
<Project>{D0C8D887-ED52-40AB-A069-90BCE0E801E2}</Project>
<Name>CordonelPreadjustmentUi</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\Interfaces\Ports\PortCore\PortCore.csproj">
<Project>{2e139f63-b6fe-4ea9-a098-85364fe9b26c}</Project>
<Name>PortCore</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\Interfaces\Ports\SerialPorts\SerialPorts.csproj">
<Project>{72037e89-4f63-4b3f-beff-4138e578ce99}</Project>
<Name>SerialPorts</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\Genesis\Applications\Applications.csproj">
<Project>{315e94b8-b82f-4b25-b5bd-297df3bc1d54}</Project>
<Name>Applications</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\Genesis\GenesisConfig\GenesisConfig.csproj">
<Project>{f013a56b-7be6-4852-9cd8-b971cd1add0c}</Project>
<Name>GenesisConfig</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\Genesis\GenesisCore\GenesisCore.csproj">
<Project>{04201e95-90a0-4b73-a72f-379739b2a3ae}</Project>
<Name>GenesisCore</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\Genesis\Registers\Registers.csproj">
<Project>{f4aaf7e6-7333-4284-b735-e32deb076c64}</Project>
<Name>Registers</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\WaterMeterCore\WaterMeterCore.csproj">
<Project>{8203abb8-38e5-472e-a742-33f38b7a74a6}</Project>
<Name>WaterMeterCore</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Hardware\WaterMeter\WaterMeterCore\WaterMeterRegisters\WaterMeterRegisters.csproj">
<Project>{26afcf1e-1287-48b8-a506-32b1e8a0dd0e}</Project>
<Name>WaterMeterRegisters</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Logic.PrdoctionToProductMapper\Logic.ProductionToProductMapper.csproj">
<Project>{d0c859d9-d55e-4e85-ac50-0ff31b1ce50d}</Project>
<Name>Logic.ProductionToProductMapper</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Logic\ProductionOrderCore\ProductionOrderCore.csproj">
<Project>{6d2777bb-7a88-466d-a49b-3266f9bf0160}</Project>
<Name>ProductionOrderCore</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\SoftwareAccessHelper\SoftwareAccessHelper.csproj">
<Project>{a33e3c6d-eaae-4a20-a0ee-f9e6922fd029}</Project>
<Name>SoftwareAccessHelper</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Ui\GenesisToolBox\GenesisToolBox.csproj">
<Project>{95a50087-99ee-4349-9a17-c547290db42f}</Project>
<Project>{95A50087-99EE-4349-9A17-C547290DB42F}</Project>
<Name>GenesisToolBox</Name>
</ProjectReference>
<ProjectReference Include="..\ExternalProjects\Laatzen\Genesis\Common\Utils\Logging\Logging.csproj">
<Project>{4b88b0d3-e791-4774-9521-eabeacdc420e}</Project>
<Name>Logging</Name>
</ProjectReference>
</ItemGroup>
<!-- Import custom GCI runtime packaging logic -->
<Import Project="RuntimePackage\Build\Copy.targets.xml" />

5364
TBF.sln

File diff suppressed because it is too large Load Diff

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
[assembly: AssemblyVersion("3.9.3069.1")]
[assembly: AssemblyFileVersion("3.9.3069.1")]
[assembly: AssemblyVersion("3.9.3134.106")]
[assembly: AssemblyFileVersion("3.9.3134.106")]

View File

@ -1,6 +1,7 @@
//------------------------------------------------------------------------------
// <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.
@ -18,7 +19,7 @@ namespace TBF.Resources {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "18.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Strings {
@ -1427,6 +1428,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Delay between pictures.
/// </summary>
internal static string DelaySendImage {
get {
return ResourceManager.GetString("DelaySendImage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Density.
/// </summary>
@ -2723,15 +2733,6 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to iPerl Communication in progress.
/// </summary>
internal static string iPerl_Communication_in_progress {
get {
return ResourceManager.GetString("iPerl_Communication_in_progress", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to ITS-27 calibration coefficients.
/// </summary>
@ -3101,6 +3102,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Meter Communication in progress.
/// </summary>
internal static string Meter_Communication_in_progress {
get {
return ResourceManager.GetString("Meter_Communication_in_progress", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Sensors.
/// </summary>
@ -3839,6 +3849,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Pictures Count.
/// </summary>
internal static string PictureCouts {
get {
return ResourceManager.GetString("PictureCouts", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to PID.
/// </summary>
@ -4434,7 +4453,7 @@ namespace TBF.Resources {
}
/// <summary>
/// Looks up a localized string similar to Pulses per liter.
/// Looks up a localized string similar to Pulses per unit.
/// </summary>
internal static string PulsesPerLtr {
get {
@ -4640,6 +4659,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Radio Communication failed.
/// </summary>
internal static string Radio_Communication_failed {
get {
return ResourceManager.GetString("Radio_Communication_failed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Rate of change [%].
/// </summary>

View File

@ -1931,15 +1931,6 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to iPERL Komunikace probíhá.
/// </summary>
internal static string iPerl_Communication_in_progress {
get {
return ResourceManager.GetString("iPerl_Communication_in_progress", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Jazyk.
/// </summary>
@ -2147,6 +2138,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Komunikace s vodemerem probíhá.
/// </summary>
internal static string Meter_Communication_in_progress {
get {
return ResourceManager.GetString("Meter_Communication_in_progress", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Testované typy měřičů.
/// </summary>

View File

@ -529,7 +529,7 @@
<value>Rychlost změny [%]</value>
</data>
<data name="PulsesPerLtr" xml:space="preserve">
<value>Impulsy na litr</value>
<value>Impulsy na jednotky</value>
</data>
<data name="Component" xml:space="preserve">
<value>Komponent</value>
@ -1020,8 +1020,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Současně s předchozím krokem</value>
</data>
<data name="iPerl_Communication_in_progress" xml:space="preserve">
<value>iPERL Komunikace probíhá</value>
<data name="Meter_Communication_in_progress" xml:space="preserve">
<value>Komunikace s vodemerem probíhá</value>
</data>
<data name="Language" xml:space="preserve">
<value>Jazyk</value>
@ -1734,6 +1734,18 @@
<data name="ShowDialog" xml:space="preserve">
<value>Zobraz Okno</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
<data name="Test_in_calculation" xml:space="preserve">
<value>Probíhá výpočet</value>
</data>
<data name="Arrangement_of_test" xml:space="preserve">
<value>Uspořádání testu</value>
</data>
@ -1755,16 +1767,4 @@
<data name="Reload" xml:space="preserve">
<value>Znovu otevřít</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
<data name="Test_in_calculation" xml:space="preserve">
<value>Probíhá výpočet</value>
</data>
</root>

File diff suppressed because it is too large Load Diff

View File

@ -532,7 +532,7 @@
<value>Durchflussänderung [%]</value>
</data>
<data name="PulsesPerLtr" xml:space="preserve">
<value>Impulse pro Liter</value>
<value>Impulse pro Einheit</value>
</data>
<data name="Component" xml:space="preserve">
<value>Komponente</value>
@ -1023,8 +1023,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Prallel mit vorherigem Schritt</value>
</data>
<data name="iPerl_Communication_in_progress" xml:space="preserve">
<value>iPerl Kommunikation läuft</value>
<data name="Meter_Communication_in_progress" xml:space="preserve">
<value>Meter Kommunikation läuft</value>
</data>
<data name="Language" xml:space="preserve">
<value>Sprache</value>
@ -2187,6 +2187,15 @@
<data name="ShowDialog" xml:space="preserve">
<value>Dialog anzeigen</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
<data name="Meter_types_tested" xml:space="preserve">
<value>Wasserzähler geprüft</value>
</data>
@ -2220,13 +2229,4 @@
<data name="Opto_head_was_disabled_by_the_user" xml:space="preserve">
<value>Abtastkopf wurde deaktiviert vom Benutzer!</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
</root>

View File

@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="PulsesPerLtr" xml:space="preserve">
<value>pulsos por unidad</value>
</data>
<data name="Activity" xml:space="preserve">
<value>Activity in Spanish</value>
</data>

View File

@ -529,7 +529,7 @@
<value>Taux de changement [%]</value>
</data>
<data name="PulsesPerLtr" xml:space="preserve">
<value>Impulsions par litre</value>
<value>impulsions par unité</value>
</data>
<data name="Component" xml:space="preserve">
<value>Composant</value>
@ -1020,7 +1020,7 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Simultanée étape précédente</value>
</data>
<data name="iPerl_Communication_in_progress" xml:space="preserve">
<data name="Meter_Communication_in_progress" xml:space="preserve">
<value>iPerl Communication en cours</value>
</data>
<data name="Language" xml:space="preserve">
@ -2004,6 +2004,15 @@
<data name="ShowDialog" xml:space="preserve">
<value>Afficher la boîte de dialogue</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
<data name="Meter_types_tested" xml:space="preserve">
<value>Types compteurs testés</value>
</data>
@ -2019,13 +2028,4 @@
<data name="Test_time_s_chdr" xml:space="preserve">
<value>Temps test [s]</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
</root>

View File

@ -529,7 +529,7 @@
<value>tasso di cambio [%]</value>
</data>
<data name="PulsesPerLtr" xml:space="preserve">
<value>impulsi per litro</value>
<value>impulsi per unità</value>
</data>
<data name="Component" xml:space="preserve">
<value>componente</value>
@ -1017,8 +1017,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>simultaneo con il passo precedente</value>
</data>
<data name="iPerl_Communication_in_progress" xml:space="preserve">
<value>iPerl comunicazioni in corso</value>
<data name="Meter_Communication_in_progress" xml:space="preserve">
<value>Meter comunicazioni in corso</value>
</data>
<data name="Language" xml:space="preserve">
<value>lingua</value>
@ -1761,6 +1761,15 @@
<data name="ShowDialog" xml:space="preserve">
<value>Mostra dialogo</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
<data name="Meter_types_tested" xml:space="preserve">
<value>tipi di contatori testati</value>
</data>
@ -1791,13 +1800,4 @@
<data name="Drain" xml:space="preserve">
<value>Drenare</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
</root>

View File

@ -520,7 +520,7 @@
<value>Szybkość zmian [%]</value>
</data>
<data name="PulsesPerLtr" xml:space="preserve">
<value>Impulsy na litr</value>
<value>impulsów na jednostkę</value>
</data>
<data name="Component" xml:space="preserve">
<value>Element</value>
@ -1011,8 +1011,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Jednocześnie z poprzednim krokiem</value>
</data>
<data name="iPerl_Communication_in_progress" xml:space="preserve">
<value>Komunikacja z iPERL w toku</value>
<data name="Meter_Communication_in_progress" xml:space="preserve">
<value>Komunikacja z vodomera w toku</value>
</data>
<data name="Language" xml:space="preserve">
<value>Język</value>
@ -1644,6 +1644,15 @@
<data name="Voltage" xml:space="preserve">
<value>Napięcie</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
<data name="Arrangement_of_test" xml:space="preserve">
<value>Układ testu</value>
</data>
@ -1695,13 +1704,4 @@
<data name="Again" xml:space="preserve">
<value>Jeszcze raz</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
</root>

View File

@ -541,7 +541,13 @@
<value>Rate of change [%]</value>
</data>
<data name="PulsesPerLtr" xml:space="preserve">
<value>Pulses per liter</value>
<value>Pulses per unit</value>
</data>
<data name="DelaySendImage" xml:space="preserve">
<value>Delay between pictures</value>
</data>
<data name="PictureCouts" xml:space="preserve">
<value>Pictures Count</value>
</data>
<data name="Component" xml:space="preserve">
<value>Component</value>
@ -1042,8 +1048,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Simultaneous with previous step</value>
</data>
<data name="iPerl_Communication_in_progress" xml:space="preserve">
<value>iPerl Communication in progress</value>
<data name="Meter_Communication_in_progress" xml:space="preserve">
<value>Meter Communication in progress</value>
</data>
<data name="Language" xml:space="preserve">
<value>Language</value>
@ -1732,6 +1738,9 @@
<data name="RFID_communication_failed" xml:space="preserve">
<value>RFID communication failed</value>
</data>
<data name="Radio_Communication_failed" xml:space="preserve">
<value>Radio Communication failed</value>
</data>
<data name="Head_was_disabled_by_the_user" xml:space="preserve">
<value>Disabled by user</value>
</data>

View File

@ -433,7 +433,7 @@
<value>Variatie debit [%]</value>
</data>
<data name="PulsesPerLtr" xml:space="preserve">
<value>impuls pe litru</value>
<value>impulsuri pe unitate</value>
</data>
<data name="Component" xml:space="preserve">
<value>Componenta</value>
@ -819,6 +819,15 @@
<data name="SaveCommunication" xml:space="preserve">
<value>Save Communication</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
<data name="cold" xml:space="preserve">
<value>rece</value>
</data>
@ -843,13 +852,4 @@
<data name="WMSN" xml:space="preserve">
<value>seria</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
</root>

View File

@ -520,7 +520,7 @@
<value>Скорость изменения [%]</value>
</data>
<data name="PulsesPerLtr" xml:space="preserve">
<value>Импульсов на литр</value>
<value>импульсов на единицу</value>
</data>
<data name="Component" xml:space="preserve">
<value>Компонент</value>
@ -1011,8 +1011,8 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>Одновременно с предыдущим шагом</value>
</data>
<data name="iPerl_Communication_in_progress" xml:space="preserve">
<value>Осуществляется связь с iPerl </value>
<data name="Meter_Communication_in_progress" xml:space="preserve">
<value>Осуществляется связь с водомером </value>
</data>
<data name="Language" xml:space="preserve">
<value>Язык</value>
@ -1554,6 +1554,15 @@
<data name="Voltage" xml:space="preserve">
<value>Voltage</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
<data name="cold" xml:space="preserve">
<value>холодный</value>
</data>
@ -1608,13 +1617,4 @@
<data name="Again" xml:space="preserve">
<value>Снова</value>
</data>
<data name="PulsesPerUnit" xml:space="preserve">
<value />
</data>
<data name="PulsesPerKilogram" xml:space="preserve">
<value />
</data>
<data name="Units" xml:space="preserve">
<value />
</data>
</root>

View File

@ -135,6 +135,9 @@
<data name="Compound_meters" xml:space="preserve">
<value>Združené vodomery</value>
</data>
<data name="PulsesPerLtr" xml:space="preserve">
<value>Pulzy na jednotky</value>
</data>
<data name="Activity" xml:space="preserve">
<value>Činnosť</value>
</data>

View File

@ -1202,15 +1202,6 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to 正在进行Iperl通信.
/// </summary>
internal static string iPerl_Communication_in_progress {
get {
return ResourceManager.GetString("iPerl_Communication_in_progress", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 语言.
/// </summary>
@ -1373,6 +1364,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to 正在进行Iperl通信.
/// </summary>
internal static string Meter_Communication_in_progress {
get {
return ResourceManager.GetString("Meter_Communication_in_progress", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 测试仪表型号.
/// </summary>
@ -2057,6 +2057,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
internal static string PulsesPerKilogram {
get {
return ResourceManager.GetString("PulsesPerKilogram", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 每升脉冲.
/// </summary>
@ -2066,6 +2075,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
internal static string PulsesPerUnit {
get {
return ResourceManager.GetString("PulsesPerUnit", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 水泵.
/// </summary>
@ -2492,9 +2510,9 @@ namespace TBF.Resources {
/// <summary>
/// Looks up a localized string similar to 序列号.
/// </summary>
internal static string Serial_Number {
internal static string Serial_number {
get {
return ResourceManager.GetString("Serial_Number", resourceCulture);
return ResourceManager.GetString("Serial_number", resourceCulture);
}
}
@ -3074,6 +3092,15 @@ namespace TBF.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to .
/// </summary>
internal static string Units {
get {
return ResourceManager.GetString("Units", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 解锁 Unlock.
/// </summary>

View File

@ -1005,7 +1005,7 @@
<data name="Simultaneous_with_previous_step" xml:space="preserve">
<value>同时进行之前步骤</value>
</data>
<data name="iPerl_Communication_in_progress" xml:space="preserve">
<data name="Meter_Communication_in_progress" xml:space="preserve">
<value>正在进行Iperl通信</value>
</data>
<data name="Language" xml:space="preserve">

View File

@ -1389,12 +1389,14 @@ namespace TBF.Rig.DataEntry.Standard24
// unitComboBox
//
this.unitComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.unitComboBox.Enabled = false;
this.unitComboBox.Font = new System.Drawing.Font("Verdana", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
this.unitComboBox.FormattingEnabled = true;
this.unitComboBox.Location = new System.Drawing.Point(999, 131);
this.unitComboBox.Name = "unitComboBox";
this.unitComboBox.Size = new System.Drawing.Size(123, 31);
this.unitComboBox.TabIndex = 103;
this.unitComboBox.Visible = false;
this.unitComboBox.SelectedIndexChanged += new System.EventHandler(this.unitComboBox_SelectedIndexChanged);
this.unitComboBox.TextChanged += new System.EventHandler(this.unitComboBox_TextChanged);
//

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using log4net;
@ -70,6 +71,9 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
int lastWmNr1;
Bitmap lastImage; /// non-zoomed image
Bitmap zoomedImage;
private readonly List<string> currentImageGroup = new List<string>();//multiple pictures
private int currentImageGroupIndex;
private bool mouseOverPictureBox;
Thread imageProcessingThread; /// Thread to process images
public delegate void OcrTextObtainedDelegate(int ix, bool isEnd, string text);
@ -96,6 +100,12 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
public TestStartEndForm()
{
InitializeComponent();
KeyPreview = true;
pictureBox1.MouseWheel += pictureBox1_MouseWheel;
pictureBox1.MouseEnter += pictureBox1_MouseEnter;
pictureBox1.MouseLeave += pictureBox1_MouseLeave;
this.Icon = Properties.Resources.TBF_icon;
@ -483,15 +493,46 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
startTextBoxes[i].TextChanged += new System.EventHandler(this.startTextBoxX_TextChanged);
startTextBoxes[i].KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.startTextBoxX_KeyPress);
startTextBoxes[i].MouseDown += new System.Windows.Forms.MouseEventHandler(this.startTextBoxX_MouseDown);
startTextBoxes[i].Enter += startTextBoxX_Enter;
}
private void startTextBoxX_Enter(object sender, EventArgs e)
{
var textBox = sender as TextBox;
if (textBox == null) { return; }
int physPos = PhysPos(textBox, startTextBoxes);
if (physPos >= 0)
{
LoadImage(sender, Tst.Start, physPos);
}
}
private void EndTextBox_EnableHanders(int i)
{
endTextBoxes[i].AcceptsTabChanged += new System.EventHandler(this.endTextBoxX_AcceptsTabChanged);
endTextBoxes[i].TextChanged += new System.EventHandler(this.endTextBoxX_TextChanged);
endTextBoxes[i].KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.endTextBoxX_KeyPress);
endTextBoxes[i].MouseDown += new System.Windows.Forms.MouseEventHandler(this.endTextBoxX_AcceptsTabChanged);
endTextBoxes[i].Enter += endTextBoxX_Enter;
}
private void endTextBoxX_Enter(object sender, EventArgs e)
{
var textBox = sender as TextBox;
if (textBox == null) { return; }
int physPos = PhysPos(textBox, endTextBoxes);
if (physPos >= 0)
{
LoadImage(sender, Tst.End, physPos);
}
}
private void TestStartEndForm_FormClosed(object sender, FormClosedEventArgs e)
{
@ -763,7 +804,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
TextBox clickedTextBox = sender as TextBox;
if (clickedTextBox != null)
{
var physPos = PhysPos(clickedTextBox, startTextBoxes);
var physPos = PhysPos(clickedTextBox, endTextBoxes);//startTextBoxes);
if (physPos < 0)
{
@ -1069,7 +1110,7 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
TextBox clickedTextBox = sender as TextBox;
if (clickedTextBox != null)
{
var physPos = PhysPos(clickedTextBox, startTextBoxes);
var physPos = PhysPos(clickedTextBox, endTextBoxes);//startTextBoxes);
if (physPos < 0)
{
@ -1134,65 +1175,479 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
/// </summary>
/// <param name="startOrEnd">Tst.Start or Tst.End</param>
/// <param name="physPos">0..23</param>
void LoadImage(object sender, Tst startOrEnd, int physPos)
{
int wmNr1b = phys2wm[physPos]; /// 0 means no WM
if (wmNr1b <= 0) return;
void LoadImage( object sender, Tst startOrEnd, int physPos)
{
if (physPos < 0 || physPos >= phys2wm.Length)
{
return;
}
wmNr0b = wmNr1b - 1;
int wmNr1b = phys2wm[physPos];
string imageFileName;
if (startOrEnd == Tst.Start && startImages[wmNr0b] != null)
imageFileName = startImages[wmNr0b];
else if (startOrEnd == Tst.End && endImages[wmNr0b] != null)
imageFileName = endImages[wmNr0b];
else
imageFileName = string.Empty;
// Hodnota 0 znamená, že na tejto fyzickej pozícii nie je vodomer.
if (wmNr1b <= 0)
{
return;
}
if (imageFileName == lastImageName)
{
return;
}
wmNr0b = wmNr1b - 1;
lastImageName = imageFileName;
lastWmNr1 = wmNr1b;
string imageFileName = GetBaseImageFileName(
startOrEnd,
wmNr0b);
if (string.IsNullOrEmpty(imageFileName) || !File.Exists(imageFileName))
{
lastImage = null;
}
else
{
using (Bitmap tempBmp = Image.FromFile(imageFileName) as Bitmap)
lastWmNr1 = wmNr1b;
if (string.IsNullOrWhiteSpace(imageFileName))
{
ClearImageGroup();
LoadImageFile(null);
return;
}
/*
* Ak používateľ zvolil iný vodomer alebo Start/End obrázok,
* vytvoríme novú skupinu:
*
* TestAdvance-1-start.bmp
* TestAdvance-1-start_img01_....bmp
* TestAdvance-1-start_img02_....bmp
*/
if (!string.Equals(
imageFileName,
lastImageName,
StringComparison.OrdinalIgnoreCase))
{
lastImageName = imageFileName;
LoadImageGroup(imageFileName);
// Pôvodný kompatibilný obrázok bude zobrazený ako prvý.
currentImageGroupIndex = 0;
}
else
{
/*
* Súbory mohli vzniknúť po prvom otvorení dialógu,
* preto skupinu pri opätovnom výbere obnovíme.
*/
RefreshCurrentImageGroup();
}
if (currentImageGroup.Count == 0)
{
LoadImageFile(null);
return;
}
currentImageGroupIndex = Math.Max(
0,
Math.Min(
currentImageGroupIndex,
currentImageGroup.Count - 1));
LoadImageFile(
currentImageGroup[currentImageGroupIndex]);
}
/// <summary>
/// base name of image file
/// </summary>
/// <param name="startOrEnd"></param>
/// <param name="waterMeterIndex"></param>
/// <returns></returns>
private string GetBaseImageFileName(
Tst startOrEnd,
int waterMeterIndex)
{
if (waterMeterIndex < 0 ||
waterMeterIndex >= WaterMetersCount)
{
return null;
}
if (startOrEnd == Tst.Start)
{
if (startImages == null ||
waterMeterIndex >= startImages.Length)
{
Rectangle rect;
if (tempBmp.Height < tempBmp.Width)
return null;
}
return startImages[waterMeterIndex];
}
if (startOrEnd == Tst.End)
{
if (endImages == null ||
waterMeterIndex >= endImages.Length)
{
return null;
}
return endImages[waterMeterIndex];
}
return null;
}
/// <summary>
/// load group of images
/// </summary>
/// <param name="baseImageFileName"></param>
private void LoadImageGroup(
string baseImageFileName)
{
currentImageGroup.Clear();
currentImageGroupIndex = 0;
if (string.IsNullOrWhiteSpace(baseImageFileName))
{
return;
}
string fullBaseFileName;
try
{
fullBaseFileName =
Path.GetFullPath(baseImageFileName);
}
catch (Exception exc)
{
log.Warn(
$"Cannot create image group from invalid path: " +
$"file='{baseImageFileName}', " +
$"error={exc.Message}");
return;
}
string directory =
Path.GetDirectoryName(fullBaseFileName);
string baseName =
Path.GetFileNameWithoutExtension(fullBaseFileName);
string extension =
Path.GetExtension(fullBaseFileName);
if (string.IsNullOrWhiteSpace(directory) ||
string.IsNullOrWhiteSpace(baseName))
{
return;
}
/*
* Pôvodný obrázok pridáme ako prvý.
*/
if (File.Exists(fullBaseFileName))
{
currentImageGroup.Add(fullBaseFileName);
}
if (!Directory.Exists(directory))
{
return;
}
string searchPattern =
$"{baseName}_img*{extension}";
try
{
List<string> timedImages =
Directory
.GetFiles(
directory,
searchPattern,
SearchOption.TopDirectoryOnly)
.OrderBy(GetTimedImageIndex)
.ThenBy(
fileName => fileName,
StringComparer.OrdinalIgnoreCase)
.ToList();
foreach (string timedImage in timedImages)
{
if (!currentImageGroup.Contains(
timedImage,
StringComparer.OrdinalIgnoreCase))
{
int hght = tempBmp.Height;
int leftMargin = (tempBmp.Width - hght) / 2;
rect = new Rectangle(leftMargin, 0, hght, hght);
}
else
{
int hght = tempBmp.Height;
int wdth = tempBmp.Width;
int margin = (hght - wdth) / 2;
rect = new Rectangle(0, margin, wdth, wdth);
}
//int hght = tempBmp.Height;
//int leftMargin = (tempBmp.Width - hght) / 2;
//lastImage = new Bitmap(tempBmp.Clone(new Rectangle(leftMargin, 0, hght, hght), tempBmp.PixelFormat));
lastImage = new Bitmap(tempBmp.Clone(rect, tempBmp.PixelFormat));
if (isZoomed[wmNr0b])
{
zoomedImage = MakeZoomedImage(lastImage, zoomCenterLoc[wmNr0b]);
currentImageGroup.Add(timedImage);
}
}
}
ShowImage();
}
log.Debug(
$"Image group loaded: " +
$"baseFile='{fullBaseFileName}', " +
$"searchPattern='{searchPattern}', " +
$"imagesCount={currentImageGroup.Count}");
}
catch (Exception exc)
{
log.Warn(
$"Cannot load image group: " +
$"baseFile='{fullBaseFileName}', " +
$"pattern='{searchPattern}', " +
$"error={exc.Message}");
}
}
/// <summary>
/// grouping by time
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private static int GetTimedImageIndex(
string fileName)
{
if (string.IsNullOrWhiteSpace(fileName))
{
return int.MaxValue;
}
string nameWithoutExtension =
Path.GetFileNameWithoutExtension(fileName);
Match match = Regex.Match(
nameWithoutExtension,
@"_img(?<index>\d+)_",
RegexOptions.IgnoreCase);
if (!match.Success)
{
return int.MaxValue;
}
int imageIndex;
return int.TryParse(
match.Groups["index"].Value,
out imageIndex)
? imageIndex
: int.MaxValue;
}
/// <summary>
/// refreshing current image group
/// </summary>
private void RefreshCurrentImageGroup()
{
if (string.IsNullOrWhiteSpace(lastImageName))
{
return;
}
string currentlySelectedFile =
currentImageGroupIndex >= 0 &&
currentImageGroupIndex < currentImageGroup.Count
? currentImageGroup[currentImageGroupIndex]
: null;
LoadImageGroup(lastImageName);
if (string.IsNullOrWhiteSpace(currentlySelectedFile))
{
return;
}
int restoredIndex =
currentImageGroup.FindIndex(
fileName =>
string.Equals(
fileName,
currentlySelectedFile,
StringComparison.OrdinalIgnoreCase));
if (restoredIndex >= 0)
{
currentImageGroupIndex = restoredIndex;
}
}
/// --- picture load ---
private void LoadImageFile(
string imageFileName)
{
DisposeLoadedImages();
if (string.IsNullOrWhiteSpace(imageFileName) ||
!File.Exists(imageFileName))
{
log.Debug(
$"Image cannot be displayed because the file does not exist: " +
$"file='{imageFileName}'");
ShowImage();
return;
}
try
{
using (var tempBmp =
new Bitmap(imageFileName))
{
Rectangle rect =
CreateSquareCropRectangle(tempBmp);
using (Bitmap croppedImage =
tempBmp.Clone(
rect,
tempBmp.PixelFormat))
{
lastImage =
new Bitmap(croppedImage);
}
}
if (isZoomed[wmNr0b])
{
zoomedImage =
MakeZoomedImage(
lastImage,
zoomCenterLoc[wmNr0b]);
}
log.Debug(
$"Image displayed from group: " +
$"waterMeter={lastWmNr1}, " +
$"groupIndex={currentImageGroupIndex + 1}/" +
$"{currentImageGroup.Count}, " +
$"file='{imageFileName}'");
}
catch (Exception exc)
{
log.Error(
$"Cannot load image: " +
$"file='{imageFileName}', " +
$"error={exc.Message}",
exc);
DisposeLoadedImages();
}
ShowImage();
}
/// --- block picture Crop help method ---
private static Rectangle CreateSquareCropRectangle( Bitmap bitmap)
{
int size = Math.Min( bitmap.Width, bitmap.Height);
int x = (bitmap.Width - size) / 2;
int y = (bitmap.Height - size) / 2;
return new Rectangle( x, y, size, size);
}
// --- block release old pictures ---
private void DisposeLoadedImages()
{
if (lastImage != null)
{
lastImage.Dispose();
lastImage = null;
}
if (zoomedImage != null)
{
zoomedImage.Dispose();
zoomedImage = null;
}
}
private void ClearImageGroup()
{
currentImageGroup.Clear();
currentImageGroupIndex = 0;
lastImageName = null;
}
// --- block picture exchange ---
private void ShowPreviousImageFromGroup()
{
ShowImageFromGroup(-1);
}
private void ShowNextImageFromGroup()
{
ShowImageFromGroup(1);
}
private void ShowImageFromGroup(
int direction)
{
if (direction == 0 ||
currentImageGroup.Count <= 1)
{
return;
}
int newIndex =
currentImageGroupIndex + direction;
/*
* Cyklické prepínanie:
*
* posledný -> prvý
* prvý -> posledný
*/
if (newIndex < 0)
{
newIndex =
currentImageGroup.Count - 1;
}
else if (newIndex >= currentImageGroup.Count)
{
newIndex = 0;
}
currentImageGroupIndex = newIndex;
LoadImageFile(
currentImageGroup[currentImageGroupIndex]);
}
// --- mouse events ---
private void pictureBox1_MouseEnter(
object sender,
EventArgs e)
{
mouseOverPictureBox = true;
/*
* PictureBox štandardne nemusí mať focus.
* Focus pomôže zachytiť klávesy aj koliesko.
*/
pictureBox1.Focus();
}
private void pictureBox1_MouseLeave(
object sender,
EventArgs e)
{
mouseOverPictureBox = false;
}
private void pictureBox1_MouseWheel(
object sender,
MouseEventArgs e)
{
if (!mouseOverPictureBox ||
currentImageGroup.Count <= 1)
{
return;
}
if (e.Delta > 0)
{
ShowPreviousImageFromGroup();
}
else if (e.Delta < 0)
{
ShowNextImageFromGroup();
}
}
/// <summary>
/// Left click = Zoom, Right click = Unzoom
@ -1276,7 +1731,9 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
{
if (lastImage == null)
{
Image previousImage = pictureBox1.Image;
pictureBox1.Image = new Bitmap(TBF.Properties.Resources.Empty);
previousImage?.Dispose();
return;
}
@ -1312,10 +1769,108 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
Brush brush = (brightness > 160) ? darkBrush : lightBrush;
grph.DrawString(lastWmNr1.ToString(), font, brush, margin, margin);
DrawImageInfo(grph, tempBmp);
}
Image oldPictureBoxImage = pictureBox1.Image;
pictureBox1.Image = tempBmp;
oldPictureBoxImage?.Dispose();
}
private void DrawImageInfo( Graphics graphics, Bitmap bitmap)
{
if (graphics == null)
{
throw new ArgumentNullException(nameof(graphics));
}
if (bitmap == null)
{
throw new ArgumentNullException(nameof(bitmap));
}
string currentImageFileName = GetCurrentImageFileName();
if (string.IsNullOrWhiteSpace(currentImageFileName))
{
return;
}
string fileName = Path.GetFileName(currentImageFileName);
string displayText = fileName;
Match match = Regex.Match( fileName, @"_img(?<index>\d+)_(?<date>\d{8})_(?<time>\d{6})_(?<ms>\d{3})", RegexOptions.IgnoreCase);
if (match.Success)
{
string imageIndex = match.Groups["index"].Value;
string date = match.Groups["date"].Value;
string time = match.Groups["time"].Value;
string milliseconds = match.Groups["ms"].Value;
string formattedDate =
$"{date.Substring(6, 2)}." +
$"{date.Substring(4, 2)}." +
$"{date.Substring(0, 4)}";
string formattedTime =
$"{time.Substring(0, 2)}:" +
$"{time.Substring(2, 2)}:" +
$"{time.Substring(4, 2)}." +
milliseconds;
string baseFileName =
Regex.Replace(
fileName,
@"_img\d+_\d{8}_\d{6}_\d{3}",
string.Empty,
RegexOptions.IgnoreCase);
displayText =
$"{baseFileName} [img{imageIndex}]" +
Environment.NewLine +
$"{formattedDate} {formattedTime}";
}
using (Font font = new Font( "Arial", isZoomed[wmNr0b] ? 8 : 10, FontStyle.Bold))
{
SizeF textSize =
graphics.MeasureString(
displayText,
font);
float margin = 5;
float x = bitmap.Width - textSize.Width - margin;
float y = bitmap.Height - textSize.Height - margin;
graphics.DrawString( displayText, font, Brushes.Black, x + 1, y + 1);
graphics.DrawString( displayText, font, Brushes.White, x, y);
}
}
private string GetCurrentImageFileName()
{
if (currentImageGroup == null ||
currentImageGroup.Count == 0)
{
return lastImageName;
}
if (currentImageGroupIndex < 0 ||
currentImageGroupIndex >= currentImageGroup.Count)
{
return lastImageName;
}
return currentImageGroup[currentImageGroupIndex];
}
private void checkBoxEnableStartBox_CheckStateChanged(object sender, EventArgs e)
@ -1345,5 +1900,35 @@ namespace TBF.Rig.DataEntry.StandartCameraPurchaseOrder
}
}
}
//Page Down/Up evenst
protected override bool ProcessCmdKey(
ref Message msg,
Keys keyData)
{
if (mouseOverPictureBox &&
currentImageGroup.Count > 1)
{
if (keyData == Keys.PageUp)
{
ShowPreviousImageFromGroup();
return true;
}
if (keyData == Keys.PageDown)
{
ShowNextImageFromGroup();
return true;
}
}
return base.ProcessCmdKey(
ref msg,
keyData);
}
}
}

View File

@ -10,7 +10,8 @@ namespace TBF.Rig
{
Valid,
Overload,
Failed,
Underload,
Failed,
Busy,
Busy1, ///
Busy2, /// Used by Mettler-Toledo Multi to distinguish which scale was queried
@ -86,6 +87,7 @@ namespace TBF.Rig
AmbientDone,
ScaleDone,
ScaleUnderload,
ScaleOverload,
ScaleTimeout,
PressureDone,

View File

@ -4,7 +4,7 @@
/// * mark test method from smart family devices
/// * (this Test method is used for devices that support smart reader)
/// </summary>
public interface ITestMethodSmart
public interface ITestMethodSmart : ITestMethod
{
}

View File

@ -34,12 +34,14 @@ namespace TBF.Rig.MettlerToledo.Standard
bool measurementCompleted;
int timeout;
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="scale">Balance device instance</param>
/// <param name="result">Reference to the measured mass in kg</param>
/// <param name="readingsCount">Required mass readings count (>= 4)</param>
bool zeroingAfterUnderload;
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
/// <param name="scale">Balance device instance</param>
/// <param name="result">Reference to the measured mass in kg</param>
/// <param name="readingsCount">Required mass readings count (>= 4)</param>
/// <param name="maxSpread">Maximum spread of measurements in kg (otherwise the measurement continues)</param>
/// <param name="method">Method: false = slow (precise), true = fast (immediate)</param>
public ReadStableMassOp(GenericDevices.IScale scale, ref DoubleBox result, int delayBefore, MassMethod method,
@ -89,6 +91,7 @@ namespace TBF.Rig.MettlerToledo.Standard
startTime = StateMachine.Time;
currentReadingsCount = 0;
measurementCompleted = false;
zeroingAfterUnderload = false;
if (delayBefore == 0 && scale.Activity == Activity.Idle)
{
@ -136,7 +139,34 @@ namespace TBF.Rig.MettlerToledo.Standard
return Event.None; /// Wait for a mass measurement
}
if (scale.MsrmntState == MsrmntState.Valid)
if (scale.MsrmntState == MsrmntState.Underload)
{
log.WarnFormat(
"ReadStableMassOp.Run() ... scale underload detected, zeroing scale");
currentReadingsCount = 0;
Array.Clear(massReadings, 0, massReadings.Length);
Array.Clear(sortedMassReadings, 0, sortedMassReadings.Length);
zeroingAfterUnderload = true;
scale.SendZeroWhenStableCmd();
scale.Activity = Activity.RunningOperation;
return Event.None;
}
if (zeroingAfterUnderload && scale.MsrmntState == MsrmntState.Valid)
{
log.InfoFormat(
"ReadStableMassOp.Run() ... scale zeroing after underload completed, restarting measurement");
zeroingAfterUnderload = false;
StartMeasurement();
return Event.None;
}
if (scale.MsrmntState == MsrmntState.Valid)
{
/// Save the measurement
if (currentReadingsCount < totalReadingsCount)

View File

@ -78,6 +78,13 @@ namespace TBF.Rig.MettlerToledo.Standard
return Event.ScaleOverload;
}
if (scale.MsrmntState == MsrmntState.Underload)
{
tara.Val = scale.Capacity;
done = true;
return Event.ScaleUnderload;
}
if (scale.MsrmntState == MsrmntState.Valid)
{
tara.Val = scale.Mass;

View File

@ -68,6 +68,12 @@ namespace TBF.Rig.MettlerToledo.Standard
if (scale.MsrmntState == MsrmntState.Busy) return Event.Busy;
if (scale.MsrmntState == MsrmntState.Underload)
{
done = true;
return Event.ScaleUnderload;
}
if (scale.MsrmntState == MsrmntState.Overload)
{
done = true;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,154 @@
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TBF.Rig.Network.Camera.CJMS11
{
internal sealed class CameraLineReader
{
private readonly Stream stream;
private readonly byte[] receiveBuffer;
private int bufferStart;
private int bufferEnd;
public CameraLineReader(
Stream stream,
int bufferSize = 64 * 1024)
{
if (stream == null)
throw new ArgumentNullException(nameof(stream));
if (!stream.CanRead)
throw new ArgumentException(
"Stream must be readable.",
nameof(stream));
if (bufferSize <= 0)
throw new ArgumentOutOfRangeException(
nameof(bufferSize));
this.stream = stream;
receiveBuffer = new byte[bufferSize];
}
public async Task<string> ReadLineAsync(
int timeoutMs,
CancellationToken cancellationToken)
{
if (timeoutMs <= 0)
throw new ArgumentOutOfRangeException(
nameof(timeoutMs));
using (var lineBuffer = new MemoryStream())
{
while (true)
{
int newLineIndex = FindNewLine();
if (newLineIndex >= 0)
{
int count = newLineIndex - bufferStart;
if (count > 0)
{
lineBuffer.Write(
receiveBuffer,
bufferStart,
count);
}
bufferStart = newLineIndex + 1;
return ConvertLineToString(lineBuffer);
}
if (bufferStart < bufferEnd)
{
lineBuffer.Write(
receiveBuffer,
bufferStart,
bufferEnd - bufferStart);
}
bufferStart = 0;
bufferEnd = 0;
int read = await ReadChunkAsync(
timeoutMs,
cancellationToken)
.ConfigureAwait(false);
if (read == 0)
{
throw new IOException(
"Camera connection was closed.");
}
bufferStart = 0;
bufferEnd = read;
}
}
}
private int FindNewLine()
{
for (int i = bufferStart; i < bufferEnd; i++)
{
if (receiveBuffer[i] == (byte)'\n')
return i;
}
return -1;
}
private async Task<int> ReadChunkAsync(
int timeoutMs,
CancellationToken cancellationToken)
{
using (var timeoutCts =
CancellationTokenSource.CreateLinkedTokenSource(
cancellationToken))
{
timeoutCts.CancelAfter(timeoutMs);
try
{
return await stream.ReadAsync(
receiveBuffer,
0,
receiveBuffer.Length,
timeoutCts.Token)
.ConfigureAwait(false);
}
catch (OperationCanceledException)
when (!cancellationToken.IsCancellationRequested)
{
throw new TimeoutException(
$"Camera read timeout after {timeoutMs} ms.");
}
}
}
private static string ConvertLineToString(
MemoryStream lineBuffer)
{
int length = checked((int)lineBuffer.Length);
if (length == 0)
return string.Empty;
byte[] data = lineBuffer.GetBuffer();
if (data[length - 1] == (byte)'\r')
length--;
return Encoding.ASCII.GetString(
data,
0,
length);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
using System;
using TBF.Rig.Network.Camera.CJMS11.POJO;
namespace TBF.Rig.Network.Camera.CJMS11
@ -11,6 +12,7 @@ namespace TBF.Rig.Network.Camera.CJMS11
private string orig_status;
private string orig_command;
private string orig_payload;
private DateTime timeStamp;
public POJO.MessageStatus Status
{
@ -35,6 +37,12 @@ namespace TBF.Rig.Network.Camera.CJMS11
public string OrigCommand => orig_command;
public string OrigPayload => orig_payload;
public DateTime TimeStamp
{
get => timeStamp;
set => timeStamp = value;
}
public JmsMessage(string status, string command, string payload)
{

View File

@ -1,6 +1,7 @@
using System;
using System.Text.RegularExpressions;
using log4net;
using Newtonsoft.Json;
using TBF.Rig.Network.Camera.CJMS11.POJO;
namespace TBF.Rig.Network.Camera.CJMS11
@ -44,6 +45,16 @@ namespace TBF.Rig.Network.Camera.CJMS11
if (message.Length < 1) return false;
this.jmsMessage = JmsMessageFromString(message);
try
{
CameraResponse response =
JsonConvert.DeserializeObject<CameraResponse>(jmsMessage.Payload);
jmsMessage.TimeStamp = response.timeStamp;
}catch(Exception e)
{
log.Debug("Error parsing message timestamp: " + e.Message);
}
return true;
}
@ -70,23 +81,39 @@ namespace TBF.Rig.Network.Camera.CJMS11
return null;
}
public static ParsedImage ImageParser(string payloadImage)
public static ParsedImage ImageParser(
string payloadImage)
{
// Equivalent regex pattern
var imagePattern = new Regex(@"IMAGE:([A-Z0-9_]+):\s*(.*?)\s*~IMAGE_END", RegexOptions.Singleline);
const string prefix = "IMAGE:";
const string endMarker = "~IMAGE_END";
var match = imagePattern.Match(payloadImage);
if (match.Success)
{
string encoding = match.Groups[1].Value;
string imageData = match.Groups[2].Value;
int prefixIndex = payloadImage.IndexOf( prefix, StringComparison.Ordinal);
if (prefixIndex < 0)
throw new ArgumentException( "IMAGE prefix was not found.");
return new ParsedImage(ImageTypeEnum.GetCommandM(encoding), imageData);
}
else
{
throw new ArgumentException($"Payload does not match expected image format: {payloadImage}");
}
int encodingStart =
prefixIndex + prefix.Length;
int encodingEnd =
payloadImage.IndexOf(
':',
encodingStart);
if (encodingEnd < 0)
throw new ArgumentException(
"Image encoding separator was not found.");
int dataStart = encodingEnd + 1;
int dataEnd = payloadImage.IndexOf( endMarker, dataStart, StringComparison.Ordinal);
if (dataEnd < 0)
throw new ArgumentException( "IMAGE_END marker was not found.");
string encoding = payloadImage .Substring( encodingStart, encodingEnd - encodingStart) .Trim();
string imageData = payloadImage.Substring( dataStart,dataEnd - dataStart).Trim();
return new ParsedImage( ImageTypeEnum.GetCommandM(encoding), imageData);
}
public override string ToString()

View File

@ -0,0 +1,12 @@
using System;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class CameraResponse
{
public string message { get; set; }
public DateTime timeStamp { get; set; }
}
}

View File

@ -0,0 +1,37 @@
using Newtonsoft.Json;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class SendImagePayload
{
[JsonProperty("frameGap")]
public int FrameGap { get; set; }
[JsonProperty("frameTime")]
public string FrameTime { get; set; }
[JsonProperty("frameTimeMillis")]
public long FrameTimeMillis { get; set; }
[JsonProperty("pictureBase64")]
public string PictureBase64 { get; set; }
[JsonProperty("picturesComplete")]
public int PicturesComplete { get; set; }
[JsonProperty("status")]
public string Status { get; set; }
[JsonProperty("taskId")]
public string TaskId { get; set; }
[JsonProperty("taskPath")]
public string TaskPath { get; set; }
[JsonProperty("taskTime")]
public string TaskTime { get; set; }
[JsonProperty("workerId")]
public int WorkerId { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using Newtonsoft.Json;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class SendImagesRequest
{
[JsonProperty("count")]
public int Count { get; set; }
[JsonProperty("delay")]
public int Delay { get; set; }
[JsonProperty("taskId")]
public string TaskId { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using Newtonsoft.Json;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class SendSummaryPayload
{
[JsonProperty("delay")]
public int Delay { get; set; }
[JsonProperty("pic_count")]
public int PictureCount { get; set; }
[JsonProperty("timeStamp")]
public string TimeStamp { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Drawing;
namespace TBF.Rig.Network.Camera.CJMS11.POJO
{
public class TimedCameraImage
{
public int Index { get; set; }
public string TaskId { get; set; }
public DateTimeOffset? FrameTime { get; set; }
public long FrameTimeMillis { get; set; }
public int FrameGap { get; set; }
public Image Image { get; set; }
}
}

View File

@ -20,17 +20,36 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ProcedureParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public double PulsesPerLtr; /// [l^-1]
public override void InitializeAll()
{
PulsesPerLtr = 1.0;
}
///PulsePerMeter [l^-1]
public double PulsesPerLtr;
/// <summary>
/// delta time gap for send parameter
/// </summary>
/// <description>delta time for send parameter 500ms is minimum</description>
public int RoiDeltaTimeMs;
/// <summary>
/// count of picture for send > 1 / grabImage == 0|1 parameter - switch method
/// </summary>
/// <description>count of picture for send > 1 / grabImage == 0|1 parameter - switch method</description>
public int RoiPicCount;
string[] paramNames = new string[]
{
Strings.PulsesPerLtr,
Strings.PictureCouts,
Strings.DelaySendImage,
};
public override void InitializeAll()
{
PulsesPerLtr = 1.0;
RoiPicCount = 1; //default value 1 => grab Image
RoiDeltaTimeMs = 500; //delta time for send parameter 500ms is minimum
}
public override string ParamName(int i) { return paramNames[i]; }
public override int ParamsCount() { return paramNames.Length; }
@ -39,6 +58,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
switch (i)
{
case 0: return PulsesPerLtr.ToString();
case 1: return RoiPicCount.ToString();
case 2: return RoiDeltaTimeMs.ToString();
default: return string.Empty;
}
}
@ -49,6 +70,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
switch (i)
{
case 0: PulsesPerLtr = Utils.ParseUDouble(strValue); return CfgUpdateFlags.None;
case 1: RoiPicCount = Int32.Parse(strValue); return CfgUpdateFlags.None;
case 2: RoiDeltaTimeMs = Int32.Parse(strValue); return CfgUpdateFlags.None;
default: return CfgUpdateFlags.None;
}
}
@ -59,11 +82,26 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
message = string.Empty;
double dummy;
int dummyInt;
switch (i)
{
case 0:
if (Utils.TryParseUDouble(strValue, out dummy)) return true;
break;
case 1:
if (!Int32.TryParse(strValue, out dummyInt) || (dummyInt < 0 || dummyInt > 50))
{
message = ParamName(i) + " is invalid. Param must be between 0 and 50!";
return false;
}
return true;
case 2:
if (!Int32.TryParse(strValue, out dummyInt) || (dummyInt < 500 || dummyInt < 5500))
{
message = ParamName(i) + " is invalid. Param must be between 500 and 5500!";
return false;
}
return true;
default:
message = "Invalid index";
return false;
@ -76,6 +114,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
void CopyContentTo(ProcedureParams prms)
{
prms.PulsesPerLtr = this.PulsesPerLtr;
prms.RoiDeltaTimeMs = this.RoiDeltaTimeMs;
prms.RoiPicCount = this.RoiPicCount;
}
public IParamsProvider Clone()

View File

@ -3,6 +3,7 @@
///
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using log4net;
using Common;
@ -41,6 +42,8 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
get { return roiCfg.ProcParams.PulsesPerLtr; }
set { roiCfg.ProcParams.PulsesPerLtr = value; }
}
public int RoiDeltaTimeMs { get { return roiCfg.ProcParams.RoiDeltaTimeMs; } }
public int RoiPicCount { get { return roiCfg.ProcParams.RoiPicCount; } }
public double LtrsPerPulse { get { return (PulsesPerLtr <= float.Epsilon) ? 1.0 : (1 / PulsesPerLtr); } }
public string QuantityUnits { get; set; }
@ -123,26 +126,65 @@ namespace TBF.Rig.Network.Camera.RoiForFixedStartCJMS11
return GrabImageOp(imageFileName, roiCfg.BlackAndWhite, roiCfg.LowResolution, roiCfg.ImageRotation);
}
public IOperation GrabImageOp(string imageFileName,
bool blackAndWhite, bool lowResolution, ImageRotation imageRotation)
// Roi.cs
public IOperation GrabImageOp(
string imageFileName,
bool blackAndWhite,
bool lowResolution,
ImageRotation imageRotation)
{
if (NetCamera != null)
if (NetCamera == null)
{
///TODO BUMI - implementing grabing multiple images
/// 1. Create a list of image file names
string[] imageNames = new string[roiCfg.ImageOpacity.Count];
for (int i = 0; i < imageNames.Length; i++)
{
imageNames[i] = imageFileName + string.Format("{0}_{1}",imageNames.Length, i);
}
/// 2. implement count of images to grab
/// 3. implement grabing multiple images
/// TODO: Implement support for sharing one camera by multiple ROI-s
return NetCamera.GrabImagesOp(new string[] { imageFileName }, blackAndWhite, lowResolution, imageRotation);
}
else
return null;
}
int imageCount = Math.Max(1, RoiPicCount);
string[] imageNames = CreateImageFileNames(
imageFileName,
imageCount);
return NetCamera.GrabImagesOp(
imageNames,
blackAndWhite,
lowResolution,
imageRotation);
}
private static string[] CreateImageFileNames(
string originalFileName,
int imageCount)
{
if (imageCount <= 1)
{
return new[] { originalFileName };
}
string directory = Path.GetDirectoryName(originalFileName);
string baseName = Path.GetFileNameWithoutExtension(originalFileName);
string extension = Path.GetExtension(originalFileName);
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss_fff");
var result = new string[imageCount];
// Prvý obrázok zostáva kompatibilný s dialógom.
result[0] = originalFileName;
for (int i = 1; i < imageCount; i++)
{
string fileName = string.Format(
"{0}_{1}_{2:D2}{3}",
baseName,
timestamp,
i + 1,
extension);
result[i] = string.IsNullOrEmpty(directory)
? fileName
: Path.Combine(directory, fileName);
}
return result;
}
public IValve GetValve()

View File

@ -94,17 +94,24 @@ namespace TBF.Rig.Network.Telnet
public class PromptReceivedImagesEventArgs : EventArgs
{
public Image image; /// server image.
public int idxCamera; /// camera index.
public int idxImage; /// image index.
public int imageCounts; /// number of images.
public PromptReceivedImagesEventArgs(int idxCamera, Image image, int idxImage, int imageCounts)
public int idxCamera;
public int idxImage;
public int imageCount;
public Image image;
public DateTimeOffset? frameTime;
public PromptReceivedImagesEventArgs(
int idxCamera,
int idxImage,
int imageCount,
Image image,
DateTimeOffset? frameTime)
{
this.image = image;
this.idxCamera = idxCamera;
this.idxImage = idxImage;
this.imageCounts = imageCounts;
this.imageCount = imageCount;
this.image = image;
this.frameTime = frameTime;
}
}

View File

@ -14,7 +14,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
{
//protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
private static readonly ILog log = LogManager.GetLogger(typeof(OptoHeadTest));
private GenesisSmartReader genesisHead;
//private SerialDriver serialDriver;
@ -30,6 +30,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
StreamingPort = new PublicModels.GciPortConfig{ PortName = $"COM{genesidHead.OptoComPortNr}", Type = string.Empty}
};
genesidHead?.CommInterfaceBridge.InitSlotAsync(request);
genesidHead?.CommInterfaceBridge?.UpdateSlotAsync(request);
slotDefined = true;
}
@ -112,8 +113,11 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
if (genesisHead.CommInterfaceBridge == null)
return string.Empty;
if (!IsSlotDefined) { BuildConnection(genesisHead); }
if (!IsSlotDefined)
{
BuildConnection(genesisHead);
}
GciBridge gciBridge = genesisHead.CommInterfaceBridge;
log.Debug("ReadRequest_PCB() - GciBridge created");
@ -144,7 +148,11 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
/// <returns></returns>
public bool SetTestMode()
{
if (!IsSlotDefined) { BuildConnection(genesisHead); }
if (!IsSlotDefined)
{
BuildConnection(genesisHead);
}
log.Debug("SetTestMode called for iHead: " + genesisHead.ToString());
bool activityModeActive = SetActivityMode_Active();
bool optActiveMode = SetOptTestMode();
@ -160,7 +168,11 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
/// <returns></returns>
public bool SetActiveMode()
{
if (!IsSlotDefined) { BuildConnection(genesisHead); }
if (!IsSlotDefined)
{
BuildConnection(genesisHead);
}
log.Debug("SetActiveMode called for iHead: " + genesisHead.ToString());
bool optActiveMode = SetOptActiveMode(genesisHead);
//bool activityModeIdle = SetActivityMode_Idle();
@ -200,7 +212,8 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
bool testMode = SetTestMode();
isTestModeSuccessful = testMode;
return testMode ? "Set Test Mode - OK" : "Set Test Mode - FAILED";
}catch (Exception ex)
}
catch (Exception ex)
{
log.Error("SetTestMode() - Exception:" + ex.StackTrace);
return "Set Test Mode - Exception";
@ -217,7 +230,6 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
/// <exception cref="Exception"></exception>
private bool SetOptTestMode()
{
if (genesisHead.DebugLevel == DebugMode.Simulate)
{
return true;
@ -273,9 +285,10 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
// log.Error("SetActiveMode() - Exception:" + ex.StackTrace);
// return "Set Active Mode - Exception";
// }
return "Set Active Mode - No Implemented Exception";
}
/// <summary>
/// Set Optical -> Active mode
/// </summary>

View File

@ -1,4 +1,5 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using GenesisCordonelInterface.API;
using log4net;
@ -13,19 +14,19 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
public class RadioService
{
private static readonly ILog log = LogManager.GetLogger(typeof(RadioService));
static string okResponse = "Command complete, no errors";
static string errorResponse = "Unable to execute";
private GciBridge _bridge;
public RadioService(GciBridge genesisHeadCommInterfaceBridgeComponent)
{
this._bridge = genesisHeadCommInterfaceBridgeComponent;
log.Debug("RadioService created with GciBridge= " + genesisHeadCommInterfaceBridgeComponent + "");
this._bridge = genesisHeadCommInterfaceBridgeComponent;
log.Debug("RadioService created with GciBridge= " + genesisHeadCommInterfaceBridgeComponent + "");
}
public async Task<string> ReadRequest_PCBAsync(GenesisSmartReader iHead)
public async Task<string> ReadRequest_PCBAsyn1(GenesisSmartReader iHead)
{
if (iHead?.CommInterfaceBridge == null)
return null;
@ -57,8 +58,117 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
return null;
}
public async Task<string> ReadRequest_PCBAsync(GenesisSmartReader iHead)
{
log.Debug("ReadRequest_PCB called for iHead: " + iHead);
if (iHead?.CommInterfaceBridge == null)
return null;
using var cts = new CancellationTokenSource(TimeSpan.FromMinutes(1));
PublicModels.GciConnectResult result;
try
{
log.Debug("ReadRequest_PCB() - calling ConnectAsync");
result = await iHead.CommInterfaceBridge
.ConnectAsync(iHead.GetSlotNr, cts.Token)
.ConfigureAwait(false);
log.Debug("ReadRequest_PCB() - ConnectAsync completed");
}
catch (OperationCanceledException)
{
log.Debug("ReadRequest_PCB() - ConnectAsync timeout/cancelled");
return null;
}
catch (Exception ex)
{
log.Error("ReadRequest_PCB() - ConnectAsync failed", ex);
return null;
}
if (result == null || !result.Success || !result.IsConnected)
{
log.Debug("ReadRequest_PCB() - invalid result: " + result);
return null;
}
string pcbId = result.PcbId;
if (string.IsNullOrEmpty(pcbId))
{
log.Debug("ReadRequest_PCB() - pcbId is empty");
return null;
}
if (iHead.ConfigStruct != null)
{
iHead.ConfigStruct.PCBNumberString = pcbId;
log.Debug("ReadRequest_PCB() - PCBNumberString: " + pcbId);
}
return pcbId;
}
public string ReadRequest_PCB(ref GenesisSmartReader iHead)
{
var head = iHead; // <-- copy to local (no longer ref)
log.Debug("ReadRequest_PCB called for iHead: " + head);
if (head?.CommInterfaceBridge == null)
return null;
try
{
var connectTask = Task.Run(async () =>
await head.CommInterfaceBridge.ConnectAsync(head.GetSlotNr)
);
var completedTask = Task.WhenAny(
connectTask,
Task.Delay(TimeSpan.FromMinutes(1))
).GetAwaiter().GetResult();
if (completedTask != connectTask)
{
log.Debug("ReadRequest_PCB() - Timeout happened");
return null;
}
var result = connectTask.GetAwaiter().GetResult();
log.Debug("ReadRequest_PCB() - Result: " + result);
if (result == null || !result.Success || !result.IsConnected)
return null;
var pcbId = result.PcbId;
log.Debug("Result pcbId: " + pcbId);
if (!string.IsNullOrEmpty(pcbId) && head.ConfigStruct != null)
{
head.ConfigStruct.PCBNumberString = pcbId;
log.Debug("Result set to ConfigStruct.PCBNumberString = " + head.ConfigStruct.PCBNumberString);
}
return pcbId;
}
catch (Exception ex)
{
log.Error("ReadRequest_PCB() failed", ex);
return null;
}
}
public string ReadRequest_PCB2(ref GenesisSmartReader iHead)
{
return ReadRequest_PCBAsync(iHead).GetAwaiter().GetResult();
}
public string ReadRequest_PCB1(ref GenesisSmartReader iHead)
{
log.Debug("ReadRequest_PCB called for iHead: " + iHead.ToString());
if (iHead?.CommInterfaceBridge == null)
@ -72,7 +182,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
connectTask,
Task.Delay(TimeSpan.FromMinutes(1))
).GetAwaiter().GetResult();
log.Debug("ReadRequest_PCB() - CompletedTask: " + completedTask);
// Timeout happened
@ -98,7 +208,8 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
if (iHead.ConfigStruct != null)
{
iHead.ConfigStruct.PCBNumberString = pcbId;
log.Debug("ReadRequest_PCB() - iHead.ConfigStruct.PCBNumberString: " + iHead.ConfigStruct.PCBNumberString);
log.Debug("ReadRequest_PCB() - iHead.ConfigStruct.PCBNumberString: " +
iHead.ConfigStruct.PCBNumberString);
}
return pcbId;
@ -107,7 +218,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
log.Debug("ReadRequest_PCB() - pcbId is empty");
return null;
}
public ProtocolStatuses GetActivityStatusMode(GenesisSmartReader iHead)
{
if (iHead?.CommInterfaceBridge == null)
@ -136,7 +247,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
return ProtocolStatuses.Active;
}
public DiagnosticLedState SetOptoStatusMode(GenesisSmartReader iHead, DiagnosticLedState opthoStatusMode)
{
if (iHead?.CommInterfaceBridge == null)
@ -165,12 +276,11 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
iHead.ConfigStruct.PCBNumberString = pcbResult.PcbId;
}
return DiagnosticLedState.StatusUnknown;
}
private static ushort SafeIntToUShort(int value)
{
if (value < ushort.MinValue || value > ushort.MaxValue)
@ -179,7 +289,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
return (ushort)value;
}
public string GetVersion(GenesisSmartReader iHead)
{
if (iHead?.CommInterfaceBridge == null)
@ -201,11 +311,11 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
// }
// return version;
// }
return string.Empty;
}
public bool SetActivityMode_Active(GenesisSmartReader iHead)
{
if (iHead?.CommInterfaceBridge == null)
@ -218,7 +328,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
if (connectResult == null || !connectResult.Success || !connectResult.IsConnected)
return false;
//Set LED to state 4
// string version = _bridge?.GciExternalInterface?.GetPcbId(iHead.GetSlotNr);
// if (!string.IsNullOrEmpty(version))
@ -229,10 +339,10 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
// }
// return true;
// }
return false;
}
public bool SetActivityMode_Idle(GenesisSmartReader iHead)
{
if (iHead?.CommInterfaceBridge == null)
@ -245,7 +355,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
if (connectResult == null || !connectResult.Success || !connectResult.IsConnected)
return false;
//Set Activity State Idle
// string version = _bridge?.GciExternalInterface?.GetPcbId(iHead.GetSlotNr);
// if (!string.IsNullOrEmpty(version))
@ -256,10 +366,10 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
// }
// return true;
// }
return false;
}
public bool SetOptTestMode(GenesisSmartReader iHead)
{
if (iHead?.CommInterfaceBridge == null)
@ -272,7 +382,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
if (connectResult == null || !connectResult.Success || !connectResult.IsConnected)
return false;
//Set LED to state 4
// string version = _bridge?.GciExternalInterface?.GetPcbId(iHead.GetSlotNr);
// if (!string.IsNullOrEmpty(version))
@ -283,9 +393,8 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
// }
// return true;
// }
return false;
}
/// <summary>
@ -316,7 +425,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
// }
// return true;
// }
return false;
}
@ -342,7 +451,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.communication
// }
// return version;
// }
return string.Empty;
}
}

View File

@ -16,11 +16,15 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
{
private static readonly ILog log = LogManager.GetLogger(typeof(GenesisSmartReader));
private static readonly ILog logStream = LogManager.GetLogger("StreamData");
Thread optoThread;
//GenesisSmartReader _genesiHead;
public GenesisSmartReader Head { get { return ISmartReader as GenesisSmartReader;} }
public GenesisSmartReader Head
{
get { return ISmartReader as GenesisSmartReader; }
}
public ISmartReader ISmartReader { get; set; }
public bool stopWorkerThread { get; set; }
@ -42,7 +46,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
optoThread.Abort();
}
}
private const string StrReadPcbCmd = "ReadPCB";
private const string StrSetTestModeCmd = "SetTestMode";
private const string StrSetActiveModeCmd = "SetActiveMode";
@ -55,33 +59,33 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
public enum Operations
{
[Description(StrReadPcbCmd)]ReadPcbCmd,
[Description(StrSetTestModeCmd)]SetTestModeCmd,
[Description(StrSetActiveModeCmd)]SetActiveModeCmd,
[Description(StrReadOptoDataCmd)]ReadOptoDataCmd,
[Description(StrStopReadOptoDataCmd)]StopReadOptoDataCmd,
[Description(StrResetNfcHeadCmd)]ResetNfcHeadCmd,
[Description(StrSetNfcHeadCmd)]SetNfcHeadCmd,
[Description(StrSetRfidHeadCmd)]SetRfidHeadCmd,
[Description(StrEmptyCmd)]EmptyCmd
[Description(StrReadPcbCmd)] ReadPcbCmd,
[Description(StrSetTestModeCmd)] SetTestModeCmd,
[Description(StrSetActiveModeCmd)] SetActiveModeCmd,
[Description(StrReadOptoDataCmd)] ReadOptoDataCmd,
[Description(StrStopReadOptoDataCmd)] StopReadOptoDataCmd,
[Description(StrResetNfcHeadCmd)] ResetNfcHeadCmd,
[Description(StrSetNfcHeadCmd)] SetNfcHeadCmd,
[Description(StrSetRfidHeadCmd)] SetRfidHeadCmd,
[Description(StrEmptyCmd)] EmptyCmd
}
private static readonly Dictionary<string, Operations> ItemsForIperlOperations = new Dictionary<string, Operations>
{
{"Read PCB", Operations.ReadPcbCmd},
{"Set Test Mode", Operations.SetTestModeCmd},
{"Set Active Mode", Operations.SetActiveModeCmd},
private static readonly Dictionary<string, Operations> ItemsForIperlOperations =
new Dictionary<string, Operations>
{
{ "Read PCB", Operations.ReadPcbCmd },
{ "Set Test Mode", Operations.SetTestModeCmd },
{ "Set Active Mode", Operations.SetActiveModeCmd },
#if TRUE
{"Start Read Opto Data", Operations.ReadOptoDataCmd},
{"Stop Read Opto Data", Operations.StopReadOptoDataCmd},
{ "Start Read Opto Data", Operations.ReadOptoDataCmd },
{ "Stop Read Opto Data", Operations.StopReadOptoDataCmd },
#endif
{" ", Operations.EmptyCmd},
{"Reset NFC Head", Operations.ResetNfcHeadCmd},
{"Set NFC Head Interface", Operations.SetNfcHeadCmd},
{"Set RFID Head interface", Operations.SetRfidHeadCmd}
};
{ " ", Operations.EmptyCmd },
{ "Reset NFC Head", Operations.ResetNfcHeadCmd },
{ "Set NFC Head Interface", Operations.SetNfcHeadCmd },
{ "Set RFID Head interface", Operations.SetRfidHeadCmd }
};
public (string Name, string Value)[] GetComboOperationsPairs()
{
@ -94,16 +98,17 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
a.RfidOutputListBox.Items.Clear();
log.Debug($"CommandTestButtonClick called: {a?.RfidCommandComboBox?.SelectedValue}");
using (Tools.LogChecker logChecker = new Tools.LogChecker("RfidData", log4net.Core.Level.Debug))
{
ListItem rfidListItem = new ListItem();
rfidListItem.Attributes.Add("style", "font-weight:bold");
Operations selectedOperation;
if(!ItemsForIperlOperations.TryGetValue((string)a.RfidCommandComboBox.SelectedValue, out selectedOperation))
if (!ItemsForIperlOperations.TryGetValue((string)a.RfidCommandComboBox.SelectedValue,
out selectedOperation))
selectedOperation = Operations.EmptyCmd;
bool isTestModeSuccessful = false;
switch (selectedOperation)
switch (selectedOperation)
{
case Operations.ReadPcbCmd:
rfidListItem.Text = $"PCB: {Head.OptoHeadTest.ReadRequest_PCB()}";
@ -121,7 +126,7 @@ namespace TBF.Rig.RegisterReaders.GenesisRegReader.implementations
break;
case Operations.SetActiveModeCmd:
rfidListItem.Text = Head.OptoHeadTest.SetActiveMode( ref isTestModeSuccessful);
rfidListItem.Text = Head.OptoHeadTest.SetActiveMode(ref isTestModeSuccessful);
stopWorkerThread = true;
a.ISmartReader.StopDataStreamProcessing(); // close opto port
break;

View File

@ -24,14 +24,14 @@ namespace TBF.Rig.RegisterReaders.PulsesFromUniCB
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(RRProcParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public double PulsesPerLtr; /// [l^-1]
public string Units; /// [kg^-1]...MF
public double PulsesPerLtr;
public string Units;
public int Filter;
public override void InitializeAll()
{
PulsesPerLtr = 1.0;
Units = "---"; //...MF
Units = "---";
Filter = 0;
}
@ -43,7 +43,7 @@ namespace TBF.Rig.RegisterReaders.PulsesFromUniCB
Strings.Filter,
};
//...MF
private void RefreshParamNames(int i) {
if (i == 0)
{
@ -56,12 +56,12 @@ namespace TBF.Rig.RegisterReaders.PulsesFromUniCB
public override string ParamName(int i)
{
//if(i==0) RefreshParamNames(0);//...MF
//if(i==0) RefreshParamNames(0);
return paramNames[i];
}
public override int ParamsCount() { return paramNames.Length; }
public ICollection<string> ParamValues(int ix)
/*public ICollection<string> ParamValues(int ix)
{
var values = new List<string>();
switch (ix)
@ -72,6 +72,33 @@ namespace TBF.Rig.RegisterReaders.PulsesFromUniCB
default:
return null;
}
}*/
public ICollection<string> ParamValues(int ix)
{
switch (ix)
{
case 1:
{
var values = new List<string>
{
Unit.None.ToDescription()
};
for (Unit unit = (Unit)1; unit < Unit.Count; unit++)
{
if (Common.Units.IsQuantity(unit, Quantity.MultiFunctionalVariables))
{
values.Add(unit.ToDescription());
}
}
return values;
}
default:
return null;
}
}
public override string ToString(int i)
@ -127,7 +154,7 @@ namespace TBF.Rig.RegisterReaders.PulsesFromUniCB
void CopyContentTo(RRProcParams prms)
{
prms.PulsesPerLtr = this.PulsesPerLtr;
prms.Units = this.Units; //...MF
prms.Units = this.Units;
prms.Filter = this.Filter;
}

View File

@ -24,23 +24,23 @@ namespace TBF.Rig.RegisterReaders.StandingStartStop
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(RRProcParams) })[0];
public override XmlSerializer GetSerializer() { return Serializer; }
public double PulsesPerLtr; /// Target low limit of the flow increase or decrease
public string Units; /// [kg^-1]...MF
public double PulsesPerLtr;
public string Units;
public override void InitializeAll()
{
PulsesPerLtr = 1.0;
Units = "---"; //...MF
Units = "---";
}
string[] paramNames = new string[]
{
//Strings.PulsesPerLtr,
Strings.PulsesPerUnit,//...MF
Strings.Units,//...MF
Strings.PulsesPerUnit,
Strings.Units,
};
//...MF
private void RefreshParamNames(int i)
{
if (i == 0)
@ -54,7 +54,7 @@ namespace TBF.Rig.RegisterReaders.StandingStartStop
public override string ParamName(int i) { return paramNames[i]; }
public override int ParamsCount() { return paramNames.Length; }
public ICollection<string> ParamValues(int ix)
/*marek mareciinopublic ICollection<string> ParamValues(int ix)
{
var values = new List<string>();
switch (ix)
@ -65,6 +65,33 @@ namespace TBF.Rig.RegisterReaders.StandingStartStop
default:
return null;
}
}*/
public ICollection<string> ParamValues(int ix)
{
switch (ix)
{
case 1:
{
var values = new List<string>
{
Unit.None.ToDescription()
};
for (Unit unit = (Unit)1; unit < Unit.Count; unit++)
{
if (Common.Units.IsQuantity(unit, Quantity.MultiFunctionalVariables))
{
values.Add(unit.ToDescription());
}
}
return values;
}
default:
return null;
}
}
public override string ToString(int i)
@ -72,7 +99,7 @@ namespace TBF.Rig.RegisterReaders.StandingStartStop
switch (i)
{
case 0: return PulsesPerLtr.ToString();
case 1: return Units;//...MF
case 1: return Units;
default: return string.Empty;
}
}
@ -113,7 +140,7 @@ namespace TBF.Rig.RegisterReaders.StandingStartStop
void CopyContentTo(RRProcParams prms)
{
prms.PulsesPerLtr = this.PulsesPerLtr;
prms.Units = this.Units; //...MF
prms.Units = this.Units;
}
public IParamsProvider Clone()

View File

@ -68,6 +68,7 @@ namespace TBF.Rig.Scales.MettlerToledo
{
WaitingBeforeMeasurment,
MassMeasurement,
ZeroingAfterUnderload,
}
OpState opState;
@ -142,14 +143,45 @@ namespace TBF.Rig.Scales.MettlerToledo
return Event.ScaleDone;
}
if (scale.MsrmntState == MsrmntState.Busy)
{
/// Measurement is in progress - resend command if timeout occurs
if (scale.MsrmntTime >= timeout) StartMeasurement();
return Event.None; /// Wait for a mass measurement
}
if (scale.MsrmntState == MsrmntState.Busy)
{
/// The command is still being processed - resend it after timeout.
if (scale.MsrmntTime >= timeout)
{
if (opState == OpState.ZeroingAfterUnderload)
scale.SendZeroWhenStableCmd();
else
StartMeasurement();
}
if (scale.MsrmntState == MsrmntState.Valid)
return Event.None;
}
if (scale.MsrmntState == MsrmntState.Underload)
{
log.Warn("ReadStableMassOp.Run() ... scale underload detected, zeroing scale");
currentReadingsCount = 0;
Array.Clear(massReadings, 0, massReadings.Length);
Array.Clear(sortedMassReadings, 0, sortedMassReadings.Length);
opState = OpState.ZeroingAfterUnderload;
scale.SendZeroWhenStableCmd();
return Event.None;
}
if (opState == OpState.ZeroingAfterUnderload && scale.MsrmntState == MsrmntState.Valid)
{
log.Info("ReadStableMassOp.Run() ... scale zeroing completed, restarting mass measurement");
opState = OpState.MassMeasurement;
StartMeasurement();
return Event.None;
}
if (scale.MsrmntState == MsrmntState.Valid)
{
/// Save the measurement
if (currentReadingsCount < totalReadingsCount)
@ -167,7 +199,7 @@ namespace TBF.Rig.Scales.MettlerToledo
}
}
if (currentReadingsCount >= totalReadingsCount)
if (currentReadingsCount >= totalReadingsCount)
{
Array.Copy(massReadings, sortedMassReadings, totalReadingsCount);
Array.Sort(sortedMassReadings);

View File

@ -401,7 +401,7 @@ namespace TBF.Rig.Scales.MettlerToledo
{
/// Invalid value : Scale is in underload range
mass = 0;
msrmntState = MsrmntState.Failed;
msrmntState = MsrmntState.Underload;
}
else if ((proto == Protocol.ID1 && field.Length == 1 && field[0] == "SI+") ||
(proto == Protocol.SICS && field.Length == 2 && field[0] == "S" && field[1] == "+") ||

View File

@ -71,6 +71,13 @@ namespace TBF.Rig.Scales.MettlerToledo
if (scale.MsrmntState == MsrmntState.Busy) return Event.Busy;
if (scale.MsrmntState == MsrmntState.Underload)
{
tara.Val = scale.Capacity;
done = true;
return Event.ScaleUnderload;
}
if (scale.MsrmntState == MsrmntState.Overload)
{
tara.Val = scale.Capacity;

View File

@ -74,6 +74,12 @@ namespace TBF.Rig.Scales.MettlerToledo
return Event.ScaleOverload;
}
if (scale.MsrmntState == MsrmntState.Underload)
{
done = true;
return Event.ScaleUnderload;
}
if (scale.MsrmntState == MsrmntState.Valid)
{
done = true;

View File

@ -710,8 +710,37 @@ namespace TBF.Rig.Sequences
regVPosOps,
"SequenceBase : Transition : TestStart - Default action");
if (evnt == Event.Error || evnt == Event.UiCmdStop) return evnt;
}
///
/// Bugfix: PerformSteps() may return Error or UiCmdStop before the common
/// transition shutdown code is reached.
///
if (evnt == Event.Error || evnt == Event.UiCmdStop)
{
log.WarnFormat(
"Transition(context={0}): PerformSteps returned {1}, performing safe shutdown (FM pump off, default valves).",
context,
evnt);
if (inPath.Pump is GenericDevices.IPumpFM)
(inPath.Pump as GenericDevices.IPumpFM).TurnOff();
State.Create("SequenceBase : Transition : STOP/ERROR - Setting default valves")
.AddOperation(checkUiOp)
.AddOperation(StateMachine.ControlBoardMain.SetValvesOp(
StateMachine.DefaultValvesOpen,
StateMachine.DefaultValvesClose))
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(e)) return Event.UiCmdStop;
}
while (!e.Contains(Event.ValvesSet));
return evnt;
}
}
else if (context == TransitionContext.AfterTestWithOverlap && nextInPath != null && nextBenchPath != null && nextOutPath != null)
{
log.WarnFormat("Transition(., context={0}), overlapped action (next flow regulation)", context);

View File

@ -366,7 +366,7 @@ namespace TBF.Rig.Sequences
Program.MainWnd.Invoke(new iPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, method, test, testParams });
//------------------------------------------------
Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress);
Bridge.OnActivity(this, Strings.Meter_Communication_in_progress);
//------------------------------------------------
bool stopPressed = false; /// true when STOP button pressed

View File

@ -153,8 +153,16 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
int totalPulses = Convert.ToInt32(test.Volume / outPath.FlowMeter.LtrPerPulse);
log.InfoFormat(
"{0}({1}) : Test starting... (Repetition {2}, LastRepetition={3}, PumpPower={4})",
test.Method,
test.Name,
repetitionNr,
isLastRepetition,
test.PumpPower);
///============================================================================================
/// Read pressure and temperature once before calling Bridge.OnTestSelected(...)
State.Create(string.Format("{0}({1}) : Measuring process data", test.Method, test.Name))
.AddOperation(checkUiOp)
@ -453,7 +461,19 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
}
}
}
///
/// reading pump power for dynamic using as default test.PumpPower for next test instances in cycle
///
if (inPath.Pump is IPump)
{
test.PumpPower = (float)(inPath.Pump as IPump).Power;
log.InfoFormat(
"PumpPower initialized from operator to '{0}'%",
test.PumpPower);
}
// if (atleastOneGenesis)
// {
// log.Info($"Genesis - Starting... Test Name:{test.Name.ToLower()}.");
@ -472,7 +492,7 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
// }
// }
if (drainTheTank)
if (drainTheTank)
{
//------------------------------------------------
Bridge.OnActivity(this, Strings.Closing_the_tank);
@ -1327,13 +1347,13 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
if (stopCycle) retVal = Event.ErrorFlagsStop;
stopTest:
stopTest:
/*GenesisHeadBatch.BatchHolder.Value.RemoveAllMeters();*/
StopRecordingStatistics(); /// Make sure graph files are closed
///
/// Quit this sequence
///
///
/// Quit this sequence
///
if (isLastRepetition || retVal == Event.UiCmdStop
|| retVal == Event.OpArgumentError
|| retVal == Event.RecoverableError
@ -1341,7 +1361,7 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection
|| retVal == Event.Error
|| retVal == Event.ConfigurationError)
{
cBrd.StopAll(false);
cBrd.StopAll(retVal == Event.UiCmdStop ? true : false);
}
return new List<Event> { retVal };

View File

@ -48,6 +48,16 @@ namespace TBF.Rig.TestMethods.FlyingStartMassCollection.Single
}
else
{
if (DebugLevel == DebugMode.Simulate &&
test.Name.ToLower().Contains("q3")
)
{
//Q3 Test - calibration data
return new FlyingStartMassCollectionSeq().Execute(test, repetNr, isLastRepetition,
testMethodCfg.TestParams.DelayedStart, null, null, DebugLevel);
}
/// DebugLevel == DebugMode.Simulate
(new FlyingStartMassCollectionSeq()).MakeSimulatedTrivial(test, repetNr, test.Part);
Bridge.OnTestProgress(this, new TestProgressEventArgs(test, repetNr, Progress.Completed));

View File

@ -376,7 +376,7 @@ namespace TBF.Rig.TestMethods.GenesisCommunication
Program.MainWnd.Invoke(new iPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, method, test, testParams });
//------------------------------------------------
Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress);
Bridge.OnActivity(this, Strings.Meter_Communication_in_progress);
//------------------------------------------------
bool stopPressed = false; /// true when STOP button pressed

View File

@ -59,7 +59,7 @@ namespace TBF.Rig.TestMethods.S640Communication
Program.MainWnd.Invoke(new S640CommFormDlgt(OpenS640CommForm), new object[] { this, activity, config, procParams, test });
//------------------------------------------------
Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress);
Bridge.OnActivity(this, Strings.Meter_Communication_in_progress);
//------------------------------------------------
bool stopPressed = false; /// true when STOP button pressed

View File

@ -376,7 +376,7 @@ namespace TBF.Rig.TestMethods.SmartMeterFlyingStartMassCollection
Program.MainWnd.Invoke(new SmartCommFormDlgt(OpenSmartCommForm), new object[] { this, method, test, testParams });
//------------------------------------------------
Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress);
Bridge.OnActivity(this, Strings.Meter_Communication_in_progress);
//------------------------------------------------
bool stopPressed = false; /// true when STOP button pressed

View File

@ -1,11 +1,12 @@
///
using Common;
using log4net;
///
/// Copyright (c) 2018-2022 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.IO;
using log4net;
using Common;
using System.Windows.Forms;
using TBF.Boxes;
using TBF.Resources;
using TBF.Rig.GenericDevices;
@ -84,6 +85,8 @@ namespace TBF.Rig.TestMethods.StandingStart
checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, heatMetersTestParams != null);
int delay;
if (cBrd is ControlBoard.Uni.UniCB)
{
int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -120,8 +123,16 @@ namespace TBF.Rig.TestMethods.StandingStart
int totalPulses = Convert.ToInt32(test.Volume / outPath.FlowMeter.LtrPerPulse);
log.InfoFormat(
"{0}({1}) : Test starting... (Repetition {2}, LastRepetition={3}, PumpPower={4})",
test.Method,
test.Name,
repetitionNr,
isLastRepetition,
test.PumpPower);
///============================================================================================
/// Read pressure and temperature once before calling Bridge.OnTestSelected(...)
State.Create(string.Format("{0}({1}) : Measuring process data", test.Method, test.Name))
.AddOperation(checkUiOp)
@ -373,6 +384,18 @@ namespace TBF.Rig.TestMethods.StandingStart
/// Temperature is withing required range at this point
///
///
/// reading pump power for dynamic using as default test.PumpPower for next test instances in cycle
///
if (inPath.Pump is IPump)
{
test.PumpPower = (float)(inPath.Pump as IPump).Power;
log.InfoFormat(
"PumpPower initialized from operator to '{0}'%",
test.PumpPower);
}
//-----------------------------------------------------------------
Bridge.OnActivity(this, Strings.Stopping_flow_for_the_fixed_start);
//-----------------------------------------------------------------
@ -421,10 +444,40 @@ namespace TBF.Rig.TestMethods.StandingStart
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
int startPulses = 0;
///
/// Enter watermeter begin states here
///
GenericDevices.IHasWMStatesForm dataEntryCmpnt = TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IHasWMStatesForm;
///...MF
///-----------------
delay = test.TimeFlow2Mass;
if (delay > 0)
{
State.Create(string.Format("{0}({1}) : Delay for meters stabilization <T flow stab. - start = {2}s> ", test.Method, test.Name, delay))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(new Operations.TimerOp(delay)) //...develop: step 5
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
if ((delay = Math.Max(delay, 0)) > 60)
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", "Delay", delay / 60, "min", delay % 60, Strings.sec));
else
Bridge.OnActivity(this, string.Format("{0} ... {1} s", "Delay", delay));
if (delay > 0)
delay--;
}
while (!e.Contains(Event.TimerExpired));
}
///
/// Enter watermeter begin states here
///
GenericDevices.IHasWMStatesForm dataEntryCmpnt = TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IHasWMStatesForm;
if (dataEntryCmpnt != null)
{
@ -668,6 +721,35 @@ namespace TBF.Rig.TestMethods.StandingStart
double volumeCTV = constMasterCorr * Convert.ToDouble(endPulses - startPulses);
double refEnergy = Energy.Sum * volumeCTV / VolumeForEnergy.Sum; /// [J]=[J]*[l]/[l]
///...MF
///-----------------
delay = test.TimeFlow2Mass;
if (delay > 0)
{
State.Create(string.Format("{0}({1}) : Delay for meters stabilization <T flow stab. - start = {2}s> ", test.Method, test.Name, delay))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(new Operations.TimerOp(delay)) //...develop: step 5
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
if ((delay = Math.Max(delay, 0)) > 60)
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", "Delay", delay / 60, "min", delay % 60, Strings.sec));
else
Bridge.OnActivity(this, string.Format("{0} ... {1} s", "Delay", delay));
if (delay > 0)
delay--;
}
while (!e.Contains(Event.TimerExpired));
}
///
/// Enter watermeter end states here

View File

@ -1,20 +1,22 @@
///
using Common;
using Config.Entities;
using log4net;
using NHibernate.Action;
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using log4net;
using Common;
using Config.Entities;
using System.Windows.Forms;
using System.Xml.Serialization;
using TBF.Boxes;
using TBF.Resources;
using TBF.Rig.GenericDevices;
using TBF.Rig.RegisterReaders.PulsesFromUniCB;
using TBF.Rig.Uni.SharedDialogs.SmartMetersCommunication.common;
using TBF.UiBridge;
using System.Xml.Serialization;
using TBF.Rig.RegisterReaders.PulsesFromUniCB;
namespace TBF.Rig.TestMethods.StandingStartMassCollection
{
@ -113,6 +115,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, heatMetersTestParams != null);
int delay;
if (cBrd is ControlBoard.Uni.UniCB)
{
int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -149,6 +153,14 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
int totalPulses = Convert.ToInt32(test.Volume / outPath.FlowMeter.LtrPerPulse);
log.InfoFormat(
"{0}({1}) : Test starting... (Repetition {2}, LastRepetition={3}, PumpPower={4})",
test.Method,
test.Name,
repetitionNr,
isLastRepetition,
test.PumpPower);
///============================================================================================
/// Read pressure and temperature once before calling Bridge.OnTestSelected(...)
@ -330,8 +342,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
State.Create(string.Format("{0}({1}) : Setting the flow", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(cBrd.SetFlowOp(test.QfromM3ph(), test.QtoM3ph(), RefFlow, FlowSettingTimeoutSec))
.AddOperation(heatMetersPromptOp)
.AddOperation(cBrd.SetFlowOp(test.QfromM3ph(), test.QtoM3ph(), RefFlow, FlowSettingTimeoutSec))//...develop: step 1
.AddOperation(heatMetersPromptOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
@ -435,6 +447,19 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
/// Temperature is withing required range at this point
///
///
/// reading pump power for dynamic using as default test.PumpPower for next test instances in cycle
///
if (inPath.Pump is IPump)
{
test.PumpPower = (float)(inPath.Pump as IPump).Power;
log.InfoFormat(
"PumpPower initialized from operator to '{0}'%",
test.PumpPower);
}
//-----------------------------------------------------------------
Bridge.OnActivity(this, Strings.Stopping_flow_for_the_fixed_start);
//-----------------------------------------------------------------
@ -452,8 +477,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
State.Create(string.Format("{0}({1}) : Close the start/stop valve before measuring the start mass", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(cBrd.CloseStartValveOp())
.EnterState();
.AddOperation(cBrd.CloseStartValveOp())//...develop: step 2
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
@ -461,10 +486,33 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
}
while (!e.Contains(Event.ValvesSet));
///...MF
///-----------------
delay = test.TimeFlow2Mass;
if (delay > 0)
{
State.Create(string.Format("{0}({1}) : Delay for meters stabilization <T flow stab. - start = {2}s> ", test.Method, test.Name, delay))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(new Operations.TimerOp(delay)) //...develop: step 5
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
Bridge.OnDelayActivity(this, "Delayed activity: Start the standing start/stop test (diverter switch...)", ref delay);
}
while (!e.Contains(Event.TimerExpired));
}
State.Create(string.Format("{0}({1}) : Start the standing start/stop test", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(testInProgress) //...develop: step 4 --> diverter switch to the mass
.EnterState();
for (int i = 0; i < 3; i++)
{
@ -473,11 +521,12 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
int time = StateMachine.Time;
double currentFlow = RefFlow.Val;
//------------------------------------------------
Bridge.OnActivity(this, Strings.Measuring_the_weight);
//Bridge.OnActivity(this, Strings.Measuring_the_weight);
//------------------------------------------------
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
@ -490,6 +539,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
///
GenericDevices.IHasWMStatesForm dataEntryCmpnt = TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IHasWMStatesForm;
IOperation readStartMassOp = scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread);
IOperation readStopMassOp = scale.ReadStableMassOp(ref StartMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread);
IOperation readEndMassOp = scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread);
if (dataEntryCmpnt != null)
{
@ -504,8 +555,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
State state2 = State.Create(string.Format("{0}({1}) : Grab images", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(readStartMassOp)
.AddOperation(testInProgress)
//.AddOperation(readStartMassOp)//...MF presuvam do nasledujucej serie
.AddOperation(testInProgress)//...nevhodne prepina diverter
.AddOperation(processDataLoggingOp);
for (int i = 0; i < sensPath.RegisterReaders.Length; i++)
@ -555,22 +606,27 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
string.Format("{0}({1}) : Grabbing images - valve close", test.Method, test.Name));
}
///////
delay = test.TimeStop2Mass;
Bridge.OnActivity(this, Strings.Enter_water_meter_data);
long readStartTime = StateMachine.Time;
State.Create(string.Format("{0}({1}) : Enter start states of water meters", test.Method, test.Name))
State.Create(string.Format("{0}({1}) : Enter start states of water meters and Measuring the start mass after residual flow <T stop-mass msrmt time = {2}s>", test.Method, test.Name, test.TimeStop2Mass))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation((dataEntryCmpnt as GenericDevices.IHasWMStatesForm).ShowTestStartFormOp(sensPath.RegisterReaders))
.AddOperation(testInProgress)//...nevhodne prepina diverter
.AddOperation((dataEntryCmpnt as GenericDevices.IHasWMStatesForm).ShowTestStartFormOp(sensPath.RegisterReaders))//...develop: half of step 6
.AddOperation(readStopMassOp) //...develop: half of step 6
.AddOperation(processDataLoggingOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
Bridge.OnDelayActivity(this, "Delayed activity: Measuring the start mass", ref delay);
}
while (!e.Contains(Event.ModelessFormClosed));
while (!e.Contains(Event.ModelessFormClosed) || !e.Contains(Event.ScaleDone));
long readEndTime = StateMachine.Time;
log.Debug("Read poseidon - took:" + (readEndTime - readStartTime));
@ -651,12 +707,11 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
}
}
//dripping on the scale - using of time constant for delay for measuring
State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
.AddOperation(testInProgress)//...nevhodne prepina diverter
.AddOperation(scale.ReadStableMassOp(ref StartMass, 0, test.MassMethod, test.MassRepeats, test.MassSpread))//...develop: step 8
.AddOperation(processDataLoggingOp)
.EnterState();
do
@ -678,7 +733,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(testInProgress)//...nevhodne prepina diverter
//.AddOperation(readStartMassOp)
.AddOperation(scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
.AddOperation(processDataLoggingOp)
@ -693,6 +748,9 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
retVal = Event.RecoverableError;
goto stopTest;
}
/// Show remaining time
Bridge.OnDelayActivity(this, "Delayed activity: Measuring the start mass", ref delay);
}
while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next));
}
@ -712,7 +770,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
/// Measurement loop preparation
TestStartTime = DateTime.Now;
StartTime = (double)StateMachine.Time;
int estimtdEndTime = StateMachine.Time + (int)test.TestTime;
int estimtdEndTime = StateMachine.Time + Convert.ToInt32(test.TestTime);
int remainingTime;
StartNewStatistics(outPath.FlowMeter, BatchRslts.Batch.BatchNr, test, repetitionNr, Math.Max((int)(test.TestTime / 10), 5));
@ -721,10 +779,10 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
State.Create(string.Format("{0}({1}) : Start the test, open the start/stop valve", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(cBrd.OpenStartValveOp(timeStampStart, startSwitchTime))
.AddOperation(cBrd.OpenStartValveOp(timeStampStart, startSwitchTime)) //...develop: step 9
.AddOperation(testInProgress)
.AddOperation(controlFlowOp)
.AddOperation(processDataLoggingOp)
.AddOperation(processDataLoggingOp)//...develop: step 10, step 11
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
@ -732,12 +790,6 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
if ((remainingTime = Math.Max(estimtdEndTime - StateMachine.Time, 0)) > 60)
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Test_in_progress, remainingTime / 60, "min", remainingTime % 60, Strings.sec));
else
Bridge.OnActivity(this, string.Format("{0} ... {1} s", Strings.Test_in_progress, remainingTime));
/// Update statistics
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
@ -782,7 +834,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(cBrd.CloseStartValveOp(timeStampEnd, stopSwitchTime))
.AddOperation(cBrd.CloseStartValveOp(timeStampEnd, stopSwitchTime))//...develop: step 12
.AddOperation(processDataLoggingOp)
.EnterState();
do {
@ -793,20 +845,55 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
log.WarnFormat("Start valve switch time on test end = {0} ms", cBrd.ValveOpenCloseTime);
/*///...MF
///-----------------
delay = test.TimeStop2Mass;
if (delay > 0)
{
State.Create(string.Format("{0}({1}) : Delay before end mass measuring <T stop-mass msrmt time = {2}s>", test.Method, test.Name, delay))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(new Operations.TimerOp(delay)) //...develop: step 13
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
if ((delay = Math.Max(delay, 0)) > 60)
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", "Delay", delay / 60, "min", delay % 60, Strings.sec));
else
Bridge.OnActivity(this, string.Format("{0} ... {1} s", "Delay", delay));
if (delay > 0)
delay--;
}
while (!e.Contains(Event.TimerExpired));
}*/
if (heatMetersPath == null)
LogProcessDataHeader(processDataLogger, "End mass");
else
LogProcessDataHeaderHeatMeters(processDataLogger, "End mass");
//------------------------------------------------
Bridge.OnActivity(this, Strings.Measuring_the_weight);
//Bridge.OnActivity(this, Strings.Measuring_the_weight);
//------------------------------------------------
State.Create(string.Format("{0}({1}) : Measuring the end mass", test.Method, test.Name))
delay = test.TimeStop2Mass;
State.Create(string.Format("{0}({1}) : Measuring the end mass after residual flow <T stop-mass msrmt time = {2}s>", test.Method, test.Name, delay))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
.AddOperation(new Operations.TimerOp(StableMassMsrmntTimeoutSec))
.AddOperation(scale.ReadStableMassOp(ref EndMass, delay, test.MassMethod, test.MassRepeats, test.MassSpread))//...develop: step 13
//.AddOperation(new Operations.TimerOp(StableMassMsrmntTimeoutSec))
.AddOperation(processDataLoggingOp)
.EnterState();
do {
@ -819,26 +906,14 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
retVal = Event.RecoverableError;
goto stopTest;
}
/// Show remaining time
Bridge.OnDelayActivity(this, "Delayed activity: Measuring the end mass", ref delay);
}
while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next));
///
tMass2 = StateMachine.Time;
if (test.DoDrainingAfter)
{
State.Create(string.Format("{0}({1}) : Open the drain valve", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperation(cBrd.SetValvesOp(scale.DrainValve, null))
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
}
while (e.Contains(Event.ValvesBusy));
}
double massStart = MeasurementCorrection.CorrectedValue(StartMass.Val, scale.Corrections);
double massEnd = MeasurementCorrection.CorrectedValue(EndMass.Val, scale.Corrections);
double densityOut = Formulas.WaterDensityFromTempPress((TempUpStat.Average + TempDownStat.Average) / 2,
@ -922,22 +997,24 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
state.AddOperation((dataEntryCmpnt as GenericDevices.IHasHeatMtrStatesForm).
ShowTestEndFormOp(sensPath.RegisterReaders,
volumeCTV, test.ErrLimLo + test.Uncertainty, test.ErrLimHi - test.Uncertainty,
refEnergy, test.ErrLimLo + test.Uncertainty, test.ErrLimHi - test.Uncertainty));
refEnergy, test.ErrLimLo + test.Uncertainty, test.ErrLimHi - test.Uncertainty)); //...develop: half of step 14
}
else
{
state.AddOperation(dataEntryCmpnt.ShowTestEndFormOp(sensPath.RegisterReaders,
volumeCTV, test.ErrLimLo + test.Uncertainty, test.ErrLimHi - test.Uncertainty));
volumeCTV, test.ErrLimLo + test.Uncertainty, test.ErrLimHi - test.Uncertainty)); //...develop: half of step 14
}
state.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
//.AddOperation(readEndMassOp) //...develop: half of step 14 + step 15
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
}
while (!e.Contains(Event.ModelessFormClosed));
while (!e.Contains(Event.ModelessFormClosed)) ;
if (heatMetersTestParams != null)
@ -1016,6 +1093,20 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
}
}
if (test.DoDrainingAfter)
{
State.Create(string.Format("{0}({1}) : Open the drain valve", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperation(cBrd.SetValvesOp(scale.DrainValve, null))
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
}
while (e.Contains(Event.ValvesBusy));
}
//------------------------------------------------
Bridge.OnActivity(this, Strings.Test_completed);
//------------------------------------------------
@ -1072,6 +1163,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
tstRslt.ConstMasterRaw = 1; /// Uncorrected master flowmeter coefficient
tstRslt.ConstMasterCorr = 1; /// Corrected master pulses per liter
tstRslt.ConstMaster = 1;
tstRslt.MassConstMaster = 1;
}
tstRslt.ErrorMaster = Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.VolumeCTV);
tstRslt.MassErrorMaster = Formulas.ErrorFromVolumes(tstRslt.VolumeMaster, tstRslt.MassCTV);
@ -1360,7 +1452,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollection
|| retVal == Event.Error
|| retVal == Event.ConfigurationError)
{
cBrd.StopAll(false);
cBrd.StopAll(retVal == Event.UiCmdStop ? true : false);
}
return new List<Event> { retVal };

View File

@ -1,14 +1,16 @@
///
using Common;
using Config.Entities;
using FluentNHibernate.Conventions;
using log4net;
///
/// Copyright (c) 2013-2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using log4net;
using Common;
using Config.Entities;
using FluentNHibernate.Conventions;
using System.Windows.Forms;
using System.Xml.Serialization;
using TBF.Boxes;
using TBF.Resources;
using TBF.Rig.Generic;
@ -16,6 +18,7 @@ using TBF.Rig.GenericDevices;
using TBF.Rig.Network.RestAPI;
using TBF.Rig.Operations;
using TBF.Rig.Sequences;
using TBF.Rig.Various.ErrorFlags;
using TBF.UiBridge;
namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
@ -115,6 +118,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
checkUiOp = new Operations.CheckUIOp(true); /// Runs in more then one state
processDataLoggingOp = new TBF.Rig.Operations.ProcessDataLoggingOp(processDataLogger, this, heatMetersTestParams != null);
int delay;
if (cBrd is ControlBoard.Uni.UniCB)
{
int[] filters = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -332,8 +337,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
State.Create(string.Format("{0}({1}) : Setting the flow", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(cBrd.SetFlowOp(test.QfromM3ph(), test.QtoM3ph(), RefFlow, FlowSettingTimeoutSec))
.AddOperation(heatMetersPromptOp)
.AddOperation(cBrd.SetFlowOp(test.QfromM3ph(), test.QtoM3ph(), RefFlow, FlowSettingTimeoutSec))//...develop: step 1
.AddOperation(heatMetersPromptOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
@ -454,8 +459,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
State.Create(string.Format("{0}({1}) : Close the start/stop valve before measuring the start mass", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(cBrd.CloseStartValveOp())
.EnterState();
.AddOperation(cBrd.CloseStartValveOp())//...develop: step 2
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
@ -463,10 +468,33 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
}
while (!e.Contains(Event.ValvesSet));
///...MF
///-----------------
delay = test.TimeFlow2Mass;
if (delay > 0)
{
State.Create(string.Format("{0}({1}) : Delay for meters stabilization <T flow stab. - start = {2}s> ", test.Method, test.Name, delay))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(new Operations.TimerOp(delay)) //...develop: step 5
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
Bridge.OnDelayActivity(this, "Delayed activity: Start the standing start/stop test (diverter switch...)", ref delay);
}
while (!e.Contains(Event.TimerExpired));
}
State.Create(string.Format("{0}({1}) : Start the standing start/stop test", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(testInProgress)//...develop: step 4 --> diverter switch to the mass
.EnterState();
for (int i = 0; i < 3; i++)
{
@ -479,7 +507,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
double currentFlow = RefFlow.Val;
//------------------------------------------------
Bridge.OnActivity(this, Strings.Measuring_the_weight);
//Bridge.OnActivity(this, Strings.Measuring_the_weight);
//------------------------------------------------
LogProcessDataTestInfo(processDataLogger, test.Procedure.Name, test.Name);
@ -492,6 +520,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
///
GenericDevices.IHasWMStatesForm dataEntryCmpnt = TbfComponents.FindComponent(StateMachine.Procedure.DataEntry) as GenericDevices.IHasWMStatesForm;
IOperation readStartMassOp = scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread);
IOperation readStopMassOp = scale.ReadStableMassOp(ref StartMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread);
IOperation readEndMassOp = scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread);
if (dataEntryCmpnt != null)
{
@ -510,7 +540,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
State state2 = State.Create(string.Format("{0}({1}) : Grab images", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(readStartMassOp)
//.AddOperation(readStartMassOp)
.AddOperation(testInProgress)
.AddOperation(processDataLoggingOp);
@ -562,20 +592,24 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
string.Format("{0}({1}) : Grabbing images - valve close", test.Method, test.Name));
}
///////
delay = test.TimeStop2Mass;
Bridge.OnActivity(this, Strings.Grabbing_images);//Strings.Enter_water_meter_data);
State.Create(string.Format("{0}({1}) : Enter start states of water meters", test.Method, test.Name))
State.Create(string.Format("{0}({1}) : Enter start states of water meters and Measuring the start mass after residual flow <T stop-mass msrmt time = {2}s>", test.Method, test.Name, test.TimeStop2Mass))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(readStartMassOp)
//.AddOperation(readStartMassOp)
.AddOperation(testInProgress)
//.AddOperation((dataEntryCmpnt as GenericDevices.IHasWMStatesForm).ShowTestStartFormOp(sensPath.RegisterReaders))
//.AddOperation((dataEntryCmpnt as GenericDevices.IHasWMStatesForm).ShowTestStartFormOp(sensPath.RegisterReaders))//...develop: half of step 6
.AddOperation(readStopMassOp) //...develop: half of step 6
.AddOperation(processDataLoggingOp)
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
Bridge.OnDelayActivity(this, "Delayed activity: Measuring the start mass", ref delay);
}
while (!e.Contains(Event.ScaleDone/*Event.ModelessFormClosed*/));
@ -650,10 +684,31 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
}
}
}
State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)//...nevhodne prepina diverter
.AddOperation(scale.ReadStableMassOp(ref StartMass, 0, test.MassMethod, test.MassRepeats, test.MassSpread))//...develop: step 8
.AddOperation(processDataLoggingOp)
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
if (e.Contains(Event.ScaleTimeout))
{
Bridge.OnError(this, Strings.Mass_measurement_timeout);
retVal = Event.RecoverableError;
goto stopTest;
}
}
while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next));
}
else
{
State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name))
/*State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
@ -671,6 +726,30 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
goto stopTest;
}
}
while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next));*/
State.Create(string.Format("{0}({1}) : Measure the start mass", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)//...nevhodne prepina diverter
//.AddOperation(readStartMassOp)
.AddOperation(scale.ReadStableMassOp(ref StartMass, test.TimeFlow2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
.AddOperation(processDataLoggingOp)
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
if (e.Contains(Event.ScaleTimeout))
{
Bridge.OnError(this, Strings.Mass_measurement_timeout);
retVal = Event.RecoverableError;
goto stopTest;
}
/// Show remaining time
Bridge.OnDelayActivity(this, "Delayed activity: Measuring the start mass", ref delay);
}
while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next));
}
///
@ -698,10 +777,10 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
State.Create(string.Format("{0}({1}) : Start the test, open the start/stop valve", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(cBrd.OpenStartValveOp(timeStampStart, startSwitchTime))
.AddOperation(cBrd.OpenStartValveOp(timeStampStart, startSwitchTime)) //...develop: step 9
.AddOperation(testInProgress)
.AddOperation(controlFlowOp)
.AddOperation(processDataLoggingOp)
.AddOperation(processDataLoggingOp)//...develop: step 10, step 11
.EnterState();
do {
e = StateMachine.WaitRunDevsRunOps();
@ -709,12 +788,6 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
if (TestAndLogUiCmdStop(test, e)) { retVal = Event.UiCmdStop; goto stopTest; }
/// Show remaining time
if ((remainingTime = Math.Max(estimtdEndTime - StateMachine.Time, 0)) > 60)
Bridge.OnActivity(this, string.Format("{0} ... {1} {2} {3} {4}", Strings.Test_in_progress, remainingTime / 60, "min", remainingTime % 60, Strings.sec));
else
Bridge.OnActivity(this, string.Format("{0} ... {1} s", Strings.Test_in_progress, remainingTime));
/// Update statistics
RefFrequency.Val = cBrd.RefFrequency;
RefFlow.Val = outPath.FlowMeter.ReadFlow();
@ -759,7 +832,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(cBrd.CloseStartValveOp(timeStampEnd, stopSwitchTime))
.AddOperation(cBrd.CloseStartValveOp(timeStampEnd, stopSwitchTime))//...develop: step 12
.AddOperation(processDataLoggingOp)
.EnterState();
do {
@ -776,14 +849,17 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
LogProcessDataHeaderHeatMeters(processDataLogger, "End mass");
//------------------------------------------------
Bridge.OnActivity(this, Strings.Measuring_the_weight);
//Bridge.OnActivity(this, Strings.Measuring_the_weight);
//------------------------------------------------
State.Create(string.Format("{0}({1}) : Measuring the end mass", test.Method, test.Name))
delay = test.TimeStop2Mass;
State.Create(string.Format("{0}({1}) : Measuring the end mass after residual flow <T stop-mass msrmt time = {2}s>", test.Method, test.Name, delay))
.AddOperation(checkUiOp)
.AddOperations(readTempPressOps)
.AddOperation(testInProgress)
.AddOperation(scale.ReadStableMassOp(ref EndMass, test.TimeStop2Mass, test.MassMethod, test.MassRepeats, test.MassSpread))
.AddOperation(new Operations.TimerOp(StableMassMsrmntTimeoutSec))
//.AddOperation(new Operations.TimerOp(StableMassMsrmntTimeoutSec))
.AddOperation(processDataLoggingOp)
.EnterState();
do {
@ -796,26 +872,14 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
retVal = Event.RecoverableError;
goto stopTest;
}
/// Show remaining time
Bridge.OnDelayActivity(this, "Delayed activity: Measuring the end mass", ref delay);
}
while (!e.Contains(Event.ScaleDone) && !e.Contains(Event.Next));
///
tMass2 = StateMachine.Time;
if (test.DoDrainingAfter)
{
State.Create(string.Format("{0}({1}) : Open the drain valve", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperation(cBrd.SetValvesOp(scale.DrainValve, null))
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
}
while (e.Contains(Event.ValvesBusy));
}
double massStart = MeasurementCorrection.CorrectedValue(StartMass.Val, scale.Corrections);
double massEnd = MeasurementCorrection.CorrectedValue(EndMass.Val, scale.Corrections);
double densityOut = Formulas.WaterDensityFromTempPress((TempUpStat.Average + TempDownStat.Average) / 2,
@ -823,7 +887,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
double buoyancy = Formulas.Buoyancy();
double massOfEvaporatedWater = (double)(tMass2 - tMass1) * outPath.Scale.EvaporationRate(TempDivStat.Average);
double volumeCTV = 1000.0 * buoyancy * (massEnd - massStart + massOfEvaporatedWater) / densityOut;
if (debugLevel == Common.DebugMode.Simulate) volumeCTV = test.Volume;
double massCTV = buoyancy * (massEnd - massStart + massOfEvaporatedWater);
if (debugLevel == Common.DebugMode.Simulate) volumeCTV = test.Volume;
double refEnergy = Energy.Sum * volumeCTV / VolumeForEnergy.Sum; /// [J]=[J]*[l]/[l]
@ -989,6 +1054,20 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
}
}
if (test.DoDrainingAfter)
{
State.Create(string.Format("{0}({1}) : Open the drain valve", test.Method, test.Name))
.AddOperation(checkUiOp)
.AddOperation(cBrd.SetValvesOp(scale.DrainValve, null))
.EnterState();
do
{
e = StateMachine.WaitRunDevsRunOps();
if (e.Contains(Event.Error)) { retVal = Event.Error; goto stopTest; }
}
while (e.Contains(Event.ValvesBusy));
}
//------------------------------------------------
Bridge.OnActivity(this, Strings.Test_completed);
//------------------------------------------------
@ -1026,6 +1105,8 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
/// Main results
tstRslt.VolumeCTV = volumeCTV; /// [l] 1000.0f is because density is in [kg/m3]
tstRslt.Flow = 3.6 * volumeCTV / tstRslt.TestTime; /// [m3/h]
tstRslt.MassCTV = massCTV; /// [kg] 1000.0f is because density is in [kg/m3]
tstRslt.MassFlow = 3.6 * massCTV / tstRslt.TestTime; /// [kg/h]
if (cBrd is ControlBoard.Uni.UniCB)
{
@ -1034,6 +1115,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
tstRslt.ConstMasterCorr = outPath.FlowMeter.LtrPerPulseCorrected(tstRslt.Flow, tstRslt.TempDownMean);
tstRslt.VolumeMaster = tstRslt.ConstMasterRaw * tstRslt.PulsesMaster; /// [l] volume from the master flow meter
tstRslt.ConstMaster = (tstRslt.VolumeMaster != 0) ? (tstRslt.ConstMasterRaw * tstRslt.VolumeCTV / tstRslt.VolumeMaster) : tstRslt.ConstMasterCorr;
tstRslt.MassConstMaster = (tstRslt.PulsesMaster != 0) ? (tstRslt.MassCTV / tstRslt.PulsesMaster) : tstRslt.ConstMasterCorr;
}
else
{
@ -1193,18 +1275,74 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvance
if (meterRslt != null && regReader != null)
{
meterRslt.RegReaderType = (int)regReader.RegisterReaderType;
ComponentProcedure procParamsEntity = test.Procedure.GetProcedureParamsEntity(regReader.Name);
try
{
if (regReader.RegisterReaderType == RegisterReaderType.Pulses)
{
XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TBF.Rig.RegisterReaders.PulsesFromUniCB.RRProcParams) })[0];
TBF.Rig.RegisterReaders.PulsesFromUniCB.RRProcParams tmp = Serializer.Deserialize(new StringReader(procParamsEntity.Parameters.ToString())) as TBF.Rig.RegisterReaders.PulsesFromUniCB.RRProcParams;
regReader.PulsesPerLtr = tmp.PulsesPerLtr;
regReader.QuantityUnits = tmp.Units;
}
else if (regReader.RegisterReaderType == RegisterReaderType.Manual)
{
XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TBF.Rig.RegisterReaders.StandingStartStop.RRProcParams) })[0];
TBF.Rig.RegisterReaders.StandingStartStop.RRProcParams tmp = Serializer.Deserialize(new StringReader(procParamsEntity.Parameters.ToString())) as TBF.Rig.RegisterReaders.StandingStartStop.RRProcParams;
regReader.PulsesPerLtr = tmp.PulsesPerLtr;
regReader.QuantityUnits = tmp.Units;
}
else
{
//MessageBox.Show("Cannot create or initialize a printer", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
}
catch (Exception ex)
{
log.ErrorFormat(string.Format("Error during RegisterReader parameters deserialization. regReader.Name='{0}', regReader.ClassName='{1}', Exception: {2}",
regReader.Name,
regReader.ClassName,
ex));
}
meterRslt.PulsesPerLiter = regReader.PulsesPerLtr;
meterRslt.VolumeStart = 0.0d;//regReader.BeginWMState;
meterRslt.VolumeEnd = 0.0d;//regReader.EndWMState;
meterRslt.VolumeMeter = 0.0d;//Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart);
meterRslt.VolumeStart = regReader.BeginWMState;//0.0d;//regReader.BeginWMState;
meterRslt.VolumeEnd = regReader.EndWMState;//0.0d;//regReader.EndWMState;
meterRslt.VolumeMeter = Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart);//0.0d;//Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart);
meterRslt.MassMeter = Math.Abs(meterRslt.VolumeEnd - meterRslt.VolumeStart);
meterRslt.VolumeRef = tstRslt.VolumeCTV; /// liter
meterRslt.MassRef = tstRslt.MassCTV; /// kg
meterRslt.PulsesMeter = meterRslt.VolumeMeter;
meterRslt.PulsesMaster = tstRslt.PulsesMaster;
meterRslt.TestTime = tstRslt.TestTime;
meterRslt.Error = 100.0d;//Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef);
meterRslt.Passed = (meterRslt.Error >= test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime) + test.Uncertainty)
//meterRslt.Error = 100.0d;//Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef);
double Error = 0;
if (meterRslt.GetQuantityFromUnits() == "Mass")
Error = Formulas.ErrorFromVolumes(meterRslt.MassMeter, meterRslt.MassRef);
else
Error = Formulas.ErrorFromVolumes(meterRslt.VolumeMeter, meterRslt.VolumeRef);
meterRslt.Error = Error;
/*meterRslt.Passed = (meterRslt.Error >= test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime) + test.Uncertainty)
&& (meterRslt.Error <= test.GetErrLimHi(tstRslt.VolumeCTV, tstRslt.TestTime) - test.Uncertainty)
&& (tstRslt.ErrorFlags == 0);
&& (tstRslt.ErrorFlags == 0);*/
var ErrLimLo_Volume = test.GetErrLimLo(tstRslt.VolumeCTV, tstRslt.TestTime);
var ErrLimHi_Volume = test.GetErrLimHi(tstRslt.VolumeCTV, tstRslt.TestTime);
var ErrLimLo_Mass = test.GetErrLimLo(tstRslt.MassCTV, tstRslt.TestTime);
var ErrLimHi_Mass = test.GetErrLimHi(tstRslt.MassCTV, tstRslt.TestTime);
bool Passed;
if (meterRslt.GetQuantityFromUnits() == "Mass")
Passed = (meterRslt.Error >= ErrLimLo_Volume + test.Uncertainty) &&
(meterRslt.Error <= ErrLimHi_Volume - test.Uncertainty) &&
(tstRslt.ErrorFlags == 0);
else
Passed = (meterRslt.Error >= ErrLimLo_Mass + test.Uncertainty) &&
(meterRslt.Error <= ErrLimHi_Mass - test.Uncertainty) &&
(tstRslt.ErrorFlags == 0);
meterRslt.Passed = Passed;
meterRslt.TestDone = false;
tstRslt.TestDone = false;
tstRslt.TestMeasured = true;

View File

@ -150,9 +150,7 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvanceCollect
(rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).EndWMState = dataEntryCmpnt.WMEndState(i);
(rr as Rig.RegisterReaders.StandingStartStop.RegisterReader).BeginWMState = dataEntryCmpnt.WMStartState(i);
}
if (rr is Rig.Network.Camera.RoiForFixedStart.Roi)
{
(rr as Rig.Network.Camera.RoiForFixedStart.Roi).EndWMState = dataEntryCmpnt.WMEndState(i);
@ -167,6 +165,16 @@ namespace TBF.Rig.TestMethods.StandingStartMassCollectionAdvanceCollect
dataEntryCmpnt.WMStartState(i);
log.DebugFormat(" StandingStartMassCollectionAdvanceSeq.cs - BeginWMState [{0}], EndWMState [{1}] -> RoiForFixedStartKeyence.Roi",dataEntryCmpnt.WMStartState(i),dataEntryCmpnt.WMEndState(i));
}
//New camera CJMS11 - supplier Java Microservices, s.r.o
if (rr is Rig.Network.Camera.RoiForFixedStartCJMS11.Roi)
{
(rr as Rig.Network.Camera.RoiForFixedStartCJMS11.Roi).EndWMState =
dataEntryCmpnt.WMEndState(i);
(rr as Rig.Network.Camera.RoiForFixedStartCJMS11.Roi).BeginWMState =
dataEntryCmpnt.WMStartState(i);
log.DebugFormat(" StandingStartMassCollectionAdvanceSeq.cs - BeginWMState [{0}], EndWMState [{1}] -> RoiForFixedStartCJMS11.Roi",dataEntryCmpnt.WMStartState(i),dataEntryCmpnt.WMEndState(i));
}
}
}

View File

@ -372,7 +372,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
Program.MainWnd.Invoke(new iPerlCommFormDlgt(OpenIPerlCommForm), new object[] { this, method, test, testParams });
//------------------------------------------------
Bridge.OnActivity(this, Strings.iPerl_Communication_in_progress);
Bridge.OnActivity(this, Strings.Meter_Communication_in_progress);
//------------------------------------------------
bool stopPressed = false; /// true when STOP button pressed

View File

@ -1152,9 +1152,9 @@ namespace Config.Resources {
/// <summary>
/// Looks up a localized string similar to iPerl Communication in progress.
/// </summary>
internal static string iPerl_Communication_in_progress {
internal static string Meter_Communication_in_progress {
get {
return ResourceManager.GetString("iPerl_Communication_in_progress", resourceCulture);
return ResourceManager.GetString("Meter_Communication_in_progress", resourceCulture);
}
}

View File

@ -1038,11 +1038,13 @@
<Compile Include="Rig\Network\Camera\CJMS11\CameraCfgCtrl.designer.cs">
<DependentUpon>CameraCfgCtrl.cs</DependentUpon>
</Compile>
<Compile Include="Rig\Network\Camera\CJMS11\CameraLineReader.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\Factory.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\GrabImagesOp.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\JmsMessage.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\JmsPacket.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\LiveStreamOp.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\CameraResponse.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\CommandM.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\CommandMEnum.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\ImageType.cs" />
@ -1050,6 +1052,10 @@
<Compile Include="Rig\Network\Camera\CJMS11\POJO\MessageStatus.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\MessageStatusEnum.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\ParsedImage.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\SendImagePayload.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\SendImagesRequest.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\SendSummaryPayload.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\POJO\TimedCameraImage.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\RoisAndResults.cs" />
<Compile Include="Rig\Network\Camera\CJMS11\TerminalDlg.cs">
<SubType>Form</SubType>

View File

@ -3,11 +3,13 @@
///
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using log4net;
using NHibernate;
using Common;
using Config.Entities;
using SharedDatabase.Entities;
using Config.Resources;
namespace TBF.UiBridge
{
@ -229,7 +231,26 @@ namespace TBF.UiBridge
public static void OnCameraUICmd(object sender, CameraUICmdEventArgs data)
{
if (CameraUICmdHandler == null) return;
try { CameraUICmdHandler(sender, data); }
try
{
log.DebugFormat("CameraUICmdHandler: {0}", data.CameraUICmd);
foreach (EventHandler<CameraUICmdEventArgs> handler in CameraUICmdHandler.GetInvocationList())
{
var localHandler = handler;
Task.Run(() =>
{
try
{
localHandler(sender, data);
}
catch (Exception e)
{
log.Error("CameraUICmdHandler(...) failed", e);
}
});
}
}
catch (Exception e) { log.Error("CameraUICmdHandler(...) failed", e); }
}
public static event EventHandler<CameraUICmdEventArgs> CameraUICmdHandler;
@ -314,5 +335,35 @@ namespace TBF.UiBridge
catch (Exception e) { log.Error("SetpointChangeHandler(...) failed", e); }
}
public static event EventHandler<SetpointChangeArgs> SetpointChangeHandler;
public static void OnDelayActivity(object sender, string nextAction, ref int delay)
{
delay = Math.Max(delay, 0);
string activity;
if (delay > 60)
{
activity = string.Format(
"{0} in {1} min {2} {3}",
nextAction,
delay / 60,
delay % 60,
Strings.sec);
}
else
{
activity = string.Format(
"{0} in {1} {2}",
nextAction,
delay,
Strings.sec);
}
OnActivity(sender, activity);
if (delay > 0)
delay--;
}
}
}

View File

@ -2,10 +2,13 @@ using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading.Tasks;
using Common;
using JetBrains.Annotations;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TBF.Rig.Generic;
using TBF.Rig.Network.Camera.CJMS11;
using TBF.Rig.Network.Camera.RoiForFixedStartCJMS11;
using TBF.Rig.Network.Camera.RoiForFixedStartCJMS11.common;
using Factory = TBF.Rig.Network.Camera.CJMS11.Factory;
@ -17,25 +20,41 @@ namespace TBFTests.Rig.Network.Camera.CJMS11
public class CameraTest
{
private static string ipCamera1 = "192.168.0.170";
private static string ipCamera2 = "192.168.0.169";
private static string ipCamera2 = "192.168.0.129";
public string IPCamera1 { get { return ipCamera1; } }
public string IPCamera2 { get { return ipCamera2; } }
private RoiCfg CreateTestRoiCfg()
{
var factory = new TBF.Rig.Network.Camera.RoiForFixedStartCJMS11.Factory();
var roi = new RoiCfg("TestRoi", factory);
roi.BlackAndWhite = false;
roi.LowResolution = true;
roi.ImageRotation = ImageRotation.None;
roi.ImageFrame = Frame.StandardFrame();
return roi;
}
[TestMethod]
public void Initialize()
{
TBF.Rig.Network.Camera.CJMS11.Camera camera = GetCamera( IPCamera1);
TBF.Rig.Network.Camera.CJMS11.Camera camera = GetCamera(IPCamera1);
camera.RoiConfiguration = CreateTestRoiCfg();
camera.Initialize();
TBF.Rig.Network.Camera.CJMS11.Camera camera2 = GetCamera( IPCamera2);
camera2.RoiConfiguration = CreateTestRoiCfg();
camera2.Initialize();
TBF.Rig.Network.Camera.CJMS11.Camera camera11 = GetCamera( IPCamera1);
camera11.Initialize();
TBF.Rig.Network.Camera.CJMS11.Camera camera12 = GetCamera( IPCamera2);
camera12.Initialize();
// TBF.Rig.Network.Camera.CJMS11.Camera camera11 = GetCamera( IPCamera1);
// camera11.Initialize();
//
// TBF.Rig.Network.Camera.CJMS11.Camera camera12 = GetCamera( IPCamera2);
// camera12.Initialize();
}
@ -57,25 +76,25 @@ namespace TBFTests.Rig.Network.Camera.CJMS11
camera.Initialize();
});
var task3 = Task.Run(() =>
{
var camera = GetCamera(IPCamera2);
camera.Initialize();
});
var task4 = Task.Run(() =>
{
var camera = GetCamera(IPCamera1);
camera.Initialize();
});
// var task3 = Task.Run(() =>
// {
// var camera = GetCamera(IPCamera2);
// camera.Initialize();
// });
//
// var task4 = Task.Run(() =>
// {
// var camera = GetCamera(IPCamera1);
// camera.Initialize();
// });
Task.WaitAll(task1, task2, task3, task4); // blocks until both finish
Task.WaitAll(task1, task2/*, task3, task4*/); // blocks until both finish
// Optionally, add assertions or diagnostics
Assert.IsTrue(task1.IsCompleted);
Assert.IsTrue(task2.IsCompleted);
Assert.IsTrue(task3.IsCompleted);
Assert.IsTrue(task4.IsCompleted);
// Assert.IsTrue(task3.IsCompleted);
// Assert.IsTrue(task4.IsCompleted);
}
@ -112,7 +131,7 @@ namespace TBFTests.Rig.Network.Camera.CJMS11
var camera = GetCamera(IPCamera1);
Task<Image> saveImageTask = Task.Run(() => camera.SaveImageListener());
Task<Image> saveImageTask = Task.Run(() => camera.SaveImageListenerAsynch());
var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(3));
var completedAnswerTask = Task.WhenAny(saveImageTask, timeoutAnswerTask).Result;
if (completedAnswerTask == timeoutAnswerTask)
@ -129,35 +148,35 @@ namespace TBFTests.Rig.Network.Camera.CJMS11
camera.Initialize();
});
var task3 = Task.Run(() =>
{
var camera = GetCamera(IPCamera2);
Task<Image> saveImageTask = Task.Run(() => camera.SaveImageListener());
var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(3));
var completedAnswerTask = Task.WhenAny(saveImageTask, timeoutAnswerTask).Result;
if (completedAnswerTask == timeoutAnswerTask)
{
Assert.Fail();
}
// var task3 = Task.Run(() =>
// {
// var camera = GetCamera(IPCamera2);
//
// Task<Image> saveImageTask = Task.Run(() => camera.SaveImageListenerAsynch());
// var timeoutAnswerTask = Task.Delay(TimeSpan.FromSeconds(3));
// var completedAnswerTask = Task.WhenAny(saveImageTask, timeoutAnswerTask).Result;
// if (completedAnswerTask == timeoutAnswerTask)
// {
// Assert.Fail();
// }
//
// //TODO BUMI enable check image
// //Assert.IsTrue(saveImageTask.Result != null);
// });
//
// var task4 = Task.Run(() =>
// {
// var camera = GetCamera(IPCamera1);
// camera.Initialize();
// });
//TODO BUMI enable check image
//Assert.IsTrue(saveImageTask.Result != null);
});
var task4 = Task.Run(() =>
{
var camera = GetCamera(IPCamera1);
camera.Initialize();
});
await Task.WhenAll(task1, task2,task3, task4); // blocks until both finish
await Task.WhenAll(task1, task2/*,task3, task4*/); // blocks until both finish
// Optionally, add assertions or diagnostics
Assert.IsTrue(task1.IsCompleted);
Assert.IsTrue(task2.IsCompleted);
Assert.IsTrue(task3.IsCompleted);
Assert.IsTrue(task4.IsCompleted);
// Assert.IsTrue(task3.IsCompleted);
// Assert.IsTrue(task4.IsCompleted);
}