diff --git a/Config/Config.csproj b/Config/Config.csproj
index cca307760..afa47fddb 100644
--- a/Config/Config.csproj
+++ b/Config/Config.csproj
@@ -78,6 +78,7 @@
+
diff --git a/Config/Entities/Enums.cs b/Config/Entities/Enums.cs
index 0558d7dcd..8048dc7e1 100644
--- a/Config/Entities/Enums.cs
+++ b/Config/Entities/Enums.cs
@@ -1,5 +1,5 @@
///
-/// Copyright (c) 2013-2017 Sensus Metering Systems
+/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@@ -58,7 +58,7 @@ namespace Config.Entities
[Description("Remote DB only")] RemoteDBOnly,
[Description("Both DB-s, local 1st")] BothDBsLocalFirst,
[Description("Both DB-s, remote 1st")] BothDBsRemoteFirst,
- Count,
+ Count
}
///
diff --git a/Config/Entities/IperlEnums.cs b/Config/Entities/IperlEnums.cs
new file mode 100644
index 000000000..ce32d3848
--- /dev/null
+++ b/Config/Entities/IperlEnums.cs
@@ -0,0 +1,36 @@
+///
+/// Copyright (c) 2018 Sensus Slovensko a.s.
+///
+using System;
+
+namespace Config.Entities
+{
+
+ public enum Side
+ {
+#if LANG_CS
+ [Description("Levá")] Left,
+ [Description("Pravá")] Right,
+#else
+ [Description("Left")] Left,
+ [Description("Right")] Right,
+#endif
+ Count
+ }
+
+ public enum FlowDir
+ {
+ R_L,
+ L_R,
+ Count
+ }
+
+ public enum OptoHeadState
+ {
+ Disabled,
+ OptoAndDirOK,
+ OptoNok,
+ DirNok,
+ Count
+ }
+}
diff --git a/Config/Properties/AssemblyInfo.cs b/Config/Properties/AssemblyInfo.cs
index 288d2bd35..22b945181 100644
--- a/Config/Properties/AssemblyInfo.cs
+++ b/Config/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.18.982.0")]
-[assembly: AssemblyFileVersion("2.18.982.0")]
+[assembly: AssemblyVersion("2.18.1082.0")]
+[assembly: AssemblyFileVersion("2.18.1082.0")]
diff --git a/TBF/BenchControl/BenchInfo/Extended/Component.cs b/TBF/BenchControl/BenchInfo/Extended/Component.cs
index 8dddba2c4..2c95e465f 100644
--- a/TBF/BenchControl/BenchInfo/Extended/Component.cs
+++ b/TBF/BenchControl/BenchInfo/Extended/Component.cs
@@ -30,10 +30,6 @@ namespace TBF.BenchControl.BenchInfo.Extended
public string Address5 { get { return myCfg.Address5; } }
public RemoteDBUse RemoteDBUse { get { return myCfg.RemoteDBUse; } }
-#if ORACLE_DB
- public int MaxTestIndex { get { return myCfg.MaxTestIndex; } } /// (MaxPruefindex % 100) value when to reject water meters completely if they are NOK
-#endif
-
public Component()
{
}
diff --git a/TBF/BenchControl/BenchInfo/Extended/ComponentCfg.cs b/TBF/BenchControl/BenchInfo/Extended/ComponentCfg.cs
index dbf7efb5c..75d5796b0 100644
--- a/TBF/BenchControl/BenchInfo/Extended/ComponentCfg.cs
+++ b/TBF/BenchControl/BenchInfo/Extended/ComponentCfg.cs
@@ -33,9 +33,6 @@ namespace TBF.BenchControl.BenchInfo.Extended
public string ApprovalDate;
public string ApprovedBy;
public RemoteDBUse RemoteDBUse;
-#if ORACLE_DB
- public int MaxTestIndex; /// (MaxPruefindex % 100) value when to reject water meters completely if they are NOK
-#endif
/// Private parameterless constructor invoked by all other (public) constructors
ComponentCfg() {}
@@ -67,9 +64,6 @@ namespace TBF.BenchControl.BenchInfo.Extended
ApprovedBy = string.Empty;
RemoteDBUse = RemoteDBUse.LocalDBOnly;
-#if ORACLE_DB
- MaxTestIndex = 4;
-#endif
}
string[] paramNames = new string[]
@@ -85,9 +79,6 @@ namespace TBF.BenchControl.BenchInfo.Extended
"Approval date",
"Approved by",
"Remote DB use",
-#if ORACLE_DB
- "Max.test index",
-#endif
};
public string ParamName(int i) { return paramNames[i]; }
public int ParamsCount() { return paramNames.Length; }
@@ -126,9 +117,6 @@ namespace TBF.BenchControl.BenchInfo.Extended
case 8: return ApprovalDate;
case 9: return ApprovedBy;
case 10: return RemoteDBUse.ToDescription();
-#if ORACLE_DB
- case 11: return MaxTestIndex.ToString();
-#endif
default: return string.Empty;
}
}
@@ -165,9 +153,7 @@ namespace TBF.BenchControl.BenchInfo.Extended
}
}
return CfgUpdateFlags.Error;
-#if ORACLE_DB
- case 11: MaxTestIndex = int.Parse(strValue); return CfgUpdateFlags.RestartRqrd;
-#endif
+
default: return CfgUpdateFlags.None;
}
}
@@ -190,7 +176,6 @@ namespace TBF.BenchControl.BenchInfo.Extended
case 9:
return true;
case 1:
- case 11:
if (int.TryParse(strValue, out idummy) && (idummy >= 0)) return true;
break;
case 10:
@@ -221,9 +206,6 @@ namespace TBF.BenchControl.BenchInfo.Extended
prms.ApprovalDate = this.ApprovalDate;
prms.ApprovedBy = this.ApprovedBy;
prms.RemoteDBUse = this.RemoteDBUse;
-#if ORACLE_DB
- prms.MaxTestIndex = this.MaxTestIndex;
-#endif
}
public Config.Entities.IParamsProvider Clone()
diff --git a/TBF/BenchControl/BenchInfo/iPerl/Component.cs b/TBF/BenchControl/BenchInfo/iPerl/Component.cs
new file mode 100644
index 000000000..c5de0fad6
--- /dev/null
+++ b/TBF/BenchControl/BenchInfo/iPerl/Component.cs
@@ -0,0 +1,46 @@
+///
+/// Copyright (c) 2018 Sensus Slovensko a.s.
+///
+using System;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using log4net;
+using Config.Entities;
+using TBF.BenchControl;
+using TBF.BenchControl.Generic;
+
+namespace TBF.BenchControl.BenchInfo.iPerl
+{
+ ///
+ /// Holds information identifying the test bench.
+ ///
+ public class Component : ComponentBase, GenericDevices.IBenchInfo
+ {
+ private static readonly ILog log = LogManager.GetLogger(typeof(Component));
+ public override string ToString() { return string.Format("BenchInfo.iPerl({0})", Cfg.ToString(1)); }
+
+ readonly ComponentCfg myCfg;
+
+ public string TestBenchName { get { return myCfg.TestBenchName; } }
+ public int TestBenchId { get { return myCfg.TestBenchId; } }
+ public string Address1 { get { return myCfg.Address1; } }
+ public string Address2 { get { return myCfg.Address2; } }
+ public string Address3 { get { return myCfg.Address3; } }
+ public string Address4 { get { return myCfg.Address4; } }
+ public string Address5 { get { return myCfg.Address5; } }
+ public RemoteDBUse RemoteDBUse { get { return myCfg.RemoteDBUse; } }
+ public Side Side { get { return myCfg.Side; } }
+ public int MaxTestIndex { get { return myCfg.MaxTestIndex; } } /// (MaxPruefindex % 100) value when to reject water meters completely if they are NOK
+
+ public Component()
+ {
+ }
+
+ public Component(Generic.IComponentCfg cfg)
+ : base(cfg)
+ {
+ myCfg = cfg as ComponentCfg;
+ log.Debug(this.ToString());
+ }
+ }
+}
diff --git a/TBF/BenchControl/BenchInfo/iPerl/ComponentCfg.cs b/TBF/BenchControl/BenchInfo/iPerl/ComponentCfg.cs
new file mode 100644
index 000000000..4db637b7c
--- /dev/null
+++ b/TBF/BenchControl/BenchInfo/iPerl/ComponentCfg.cs
@@ -0,0 +1,266 @@
+///
+/// Copyright (c) 2018 Sensus Slovensko a.s.
+///
+using System;
+using System.Collections.Generic;
+using System.Xml.Serialization;
+using Config.Entities;
+using TBF.BenchControl.Generic;
+using TBF.Resources;
+
+namespace TBF.BenchControl.BenchInfo.iPerl
+{
+ ///
+ /// Holds information identifying the test bench - serializable configuration.
+ ///
+ public class ComponentCfg : ComponentCfgBase, Generic.IComponentCfg, Config.Entities.IParamsProvider
+ {
+ public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(ComponentCfg) })[0];
+ public override XmlSerializer GetSerializer() { return Serializer; }
+
+ public IComponentCfgCtrl GetControl() { return new Configs.ParamsProvider.ComponentCfgCtrl(this, null); }
+
+ ///
+ /// Serialized parameters
+ ///
+ public string TestBenchName;
+ public int TestBenchId;
+ public string Address1;
+ public string Address2;
+ public string Address3;
+ public string Address4;
+ public string Address5;
+ public string ApprovalId;
+ public string ApprovalDate;
+ public string ApprovedBy;
+ public RemoteDBUse RemoteDBUse;
+ public Side Side;
+ public int MaxTestIndex; /// (MaxPruefindex % 100) value when to reject water meters completely if they are NOK
+
+ /// Private parameterless constructor invoked by all other (public) constructors
+ ComponentCfg() {}
+
+ public ComponentCfg(string name, IComponentFactory factory)
+ : this()
+ {
+ Factory = factory;
+ Name = name;
+ ParentName = string.Empty;
+ InitializeAll();
+ }
+
+ public string ComponentName { get { return Name; } }
+
+ public void InitializeAll()
+ {
+ TestBenchName = "1";
+ TestBenchId = 1;
+
+ Address1 = string.Empty;
+ Address2 = string.Empty;
+ Address3 = string.Empty;
+ Address4 = string.Empty;
+ Address5 = string.Empty;
+
+ ApprovalId = string.Empty;
+ ApprovalDate = string.Empty;
+ ApprovedBy = string.Empty;
+
+ RemoteDBUse = RemoteDBUse.LocalDBOnly;
+ Side = Side.Left;
+ MaxTestIndex = 4;
+ }
+
+ string[] paramNames = new string[]
+ {
+ "Test bench name",
+ "Test bench ID",
+ "Address 1",
+ "Address 2",
+ "Address 3",
+ "Address 4",
+ "Address 5",
+ "Approval",
+ "Approval date",
+ "Approved by",
+ "Remote DB use",
+ Strings.Side,
+ "Max.test index",
+ };
+ public string ParamName(int i) { return paramNames[i]; }
+ public int ParamsCount() { return paramNames.Length; }
+
+ public IList ParamValues(int i)
+ {
+ if (i == 10)
+ {
+ IList list = new List();
+ for (RemoteDBUse rdbu = 0; rdbu < RemoteDBUse.Count; rdbu++) list.Add(rdbu.ToDescription());
+ return list;
+ }
+ else if (i == 11)
+ {
+ IList list = new List();
+ for (Side side = 0; side < Side.Count; side++) list.Add(side.ToDescription());
+ return list;
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ public string ToString(int i)
+ {
+ if (i == -1)
+ {
+ return string.Format("{0}: Bench name={1}, Bench Id={2}, Procedures={3}", Name, TestBenchName, TestBenchId, RemoteDBUse.ToDescription());
+ }
+
+ switch (i)
+ {
+ case 0: return TestBenchName;
+ case 1: return TestBenchId.ToString();
+ case 2: return Address1;
+ case 3: return Address2;
+ case 4: return Address3;
+ case 5: return Address4;
+ case 6: return Address5;
+ case 7: return ApprovalId;
+ case 8: return ApprovalDate;
+ case 9: return ApprovedBy;
+ case 10: return RemoteDBUse.ToDescription();
+ case 11: return Side.ToDescription();
+ case 12: return MaxTestIndex.ToString();
+ default: return string.Empty;
+ }
+ }
+
+ public CfgUpdateFlags UpdateParam(int i, string strValue)
+ {
+ switch (i)
+ {
+ case 0: TestBenchName = strValue; return CfgUpdateFlags.RestartRqrd;
+ case 1: TestBenchId = int.Parse(strValue); return CfgUpdateFlags.RestartRqrd;
+ case 2: Address1 = strValue; return CfgUpdateFlags.RestartRqrd;
+ case 3: Address2 = strValue; return CfgUpdateFlags.RestartRqrd;
+ case 4: Address3 = strValue; return CfgUpdateFlags.RestartRqrd;
+ case 5: Address4 = strValue; return CfgUpdateFlags.RestartRqrd;
+ case 6: Address5 = strValue; return CfgUpdateFlags.RestartRqrd;
+ case 7: ApprovalId = strValue; return CfgUpdateFlags.RestartRqrd;
+ case 8: ApprovalDate = strValue; return CfgUpdateFlags.RestartRqrd;
+ case 9: ApprovedBy = strValue; return CfgUpdateFlags.RestartRqrd;
+
+ case 10:
+ for (RemoteDBUse rdbu = 0; rdbu < RemoteDBUse.Count; rdbu++)
+ {
+ if (strValue == rdbu.ToDescription())
+ {
+ if (RemoteDBUse != rdbu)
+ {
+ RemoteDBUse = rdbu;
+ return CfgUpdateFlags.RestartRqrd;
+ }
+ else
+ {
+ return CfgUpdateFlags.None;
+ }
+ }
+ }
+ return CfgUpdateFlags.Error;
+
+ case 11:
+ for (Side side = 0; side < Side.Count; side++)
+ {
+ if (strValue == side.ToDescription())
+ {
+ if (Side != side)
+ {
+ Side = side;
+ return CfgUpdateFlags.RestartRqrd;
+ }
+ else
+ {
+ return CfgUpdateFlags.None;
+ }
+ }
+ }
+ return CfgUpdateFlags.Error;
+
+ case 12: MaxTestIndex = int.Parse(strValue); return CfgUpdateFlags.RestartRqrd;
+ default: return CfgUpdateFlags.None;
+ }
+ }
+
+ public bool ValidateParam(int i, string strValue, out string message)
+ {
+ message = string.Empty;
+ int idummy;
+
+ switch (i)
+ {
+ case 0:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ return true;
+ case 1:
+ case 12:
+ if (int.TryParse(strValue, out idummy) && (idummy >= 0)) return true;
+ break;
+ case 10:
+ for (RemoteDBUse rdbu = 0; rdbu < RemoteDBUse.Count; rdbu++)
+ {
+ if (strValue == rdbu.ToDescription()) return true;
+ }
+ return false;
+ case 11:
+ for (Side side = 0; side < Side.Count; side++)
+ {
+ if (strValue == side.ToDescription()) return true;
+ }
+ return false;
+ default:
+ message = "Invalid index";
+ return false;
+ }
+
+ message = ParamName(i) + " is invalid";
+ return false;
+ }
+
+ void CopyContentTo(ComponentCfg prms)
+ {
+ prms.TestBenchName = this.TestBenchName;
+ prms.TestBenchId = this.TestBenchId;
+ prms.Address1 = this.Address1;
+ prms.Address2 = this.Address2;
+ prms.Address3 = this.Address3;
+ prms.Address4 = this.Address4;
+ prms.Address5 = this.Address5;
+ prms.ApprovalId = this.ApprovalId;
+ prms.ApprovalDate = this.ApprovalDate;
+ prms.ApprovedBy = this.ApprovedBy;
+ prms.RemoteDBUse = this.RemoteDBUse;
+ prms.Side = this.Side;
+ prms.MaxTestIndex = this.MaxTestIndex;
+ }
+
+ public Config.Entities.IParamsProvider Clone()
+ {
+ ComponentCfg pars = new ComponentCfg();
+ CopyContentTo(pars);
+ return pars;
+ }
+
+ public void UpdateEmbeddedDbEntity()
+ {
+ /// Do nothing
+ }
+ }
+}
diff --git a/TBF/BenchControl/BenchInfo/iPerl/ComponentFactory.cs b/TBF/BenchControl/BenchInfo/iPerl/ComponentFactory.cs
new file mode 100644
index 000000000..13498dd05
--- /dev/null
+++ b/TBF/BenchControl/BenchInfo/iPerl/ComponentFactory.cs
@@ -0,0 +1,26 @@
+///
+/// Copyright (c) 2018 Sensus Slovensko a.s.
+///
+using System.Collections.Generic;
+using TBF.BenchControl.Generic;
+
+namespace TBF.BenchControl.BenchInfo.iPerl
+{
+ public class ComponentFactory : IComponentFactory
+ {
+ public string ClassName { get { return "BenchInfo.iPerl"; } }
+
+ public void ResetStaticProperties() { Component.ResetStaticProperties(); }
+
+ public IComponent DummyComponent() { return new Component(); }
+
+ public IComponent GetComponent(IComponentCfg cfg, IList components) { return new Component(cfg); }
+
+ public IComponentCfg DefaultConfig() { return new ComponentCfg("BenchInfo.iPerl", this); }
+
+ public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
+ {
+ return ComponentCfgBase.CreateFromDbEntity(ComponentCfg.Serializer, component, this);
+ }
+ }
+}
diff --git a/TBF/BenchControl/DataEntry/iPerl/CycleBeginningForm.cs b/TBF/BenchControl/DataEntry/iPerl/CycleBeginningForm.cs
index d2de1ad12..d0a272108 100644
--- a/TBF/BenchControl/DataEntry/iPerl/CycleBeginningForm.cs
+++ b/TBF/BenchControl/DataEntry/iPerl/CycleBeginningForm.cs
@@ -59,13 +59,32 @@ namespace TBF.BenchControl.DataEntry.iPerl
orderGroupBox.Text = Strings.Purchase_order;
okButton.Text = Strings.OkBtnText;
PrepareOrderCombo(orderComboBox);
- if (reversedDirection)
+
+ ///
+ /// Draw an appropriate test bench picture
+ ///
+ Config.Entities.Side side = (TBF.BenchControl.Sequences.ProcessData.BenchInfo is BenchInfo.iPerl.Component)
+ ? (TBF.BenchControl.Sequences.ProcessData.BenchInfo as BenchInfo.iPerl.Component).Side
+ : Config.Entities.Side.Left;
+ if (reversedDirection && (side == Config.Entities.Side.Left))
{
- pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\reversed_dir.jpg", Program.ExecutableDir, true));
+ /// direction L->R (reversed), left side
+ pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\reversed_dir_left.jpg", Program.ExecutableDir, true));
+ }
+ else if (reversedDirection && (side == Config.Entities.Side.Right))
+ {
+ /// direction L->R (reversed), right side
+ pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\reversed_dir_right.jpg", Program.ExecutableDir, true));
+ }
+ else if (side == Config.Entities.Side.Right)
+ {
+ /// direction R->L (forward), right side
+ pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\forward_dir_right.jpg", Program.ExecutableDir, true));
}
else
{
- pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\forward_dir.jpg", Program.ExecutableDir, true));
+ /// direction R->L (forward), left side
+ pictureBox.Image = Image.FromFile(string.Format("{0}\\Pictures\\forward_dir_left.jpg", Program.ExecutableDir, true));
}
}
diff --git a/TBF/BenchControl/GenericDevices/IBenchInfo.cs b/TBF/BenchControl/GenericDevices/IBenchInfo.cs
index 3619793ec..182e13113 100644
--- a/TBF/BenchControl/GenericDevices/IBenchInfo.cs
+++ b/TBF/BenchControl/GenericDevices/IBenchInfo.cs
@@ -19,8 +19,5 @@ namespace TBF.BenchControl.GenericDevices
string Address4 { get; }
string Address5 { get; }
RemoteDBUse RemoteDBUse { get; }
-#if ORACLE_DB
- int MaxTestIndex { get; } /// (MaxPruefindex % 100) value when to reject water meters completely if they are NOK
-#endif
}
}
diff --git a/TBF/BenchControl/TbfComponents.cs b/TBF/BenchControl/TbfComponents.cs
index 0766d8a40..a30cefddc 100644
--- a/TBF/BenchControl/TbfComponents.cs
+++ b/TBF/BenchControl/TbfComponents.cs
@@ -17,7 +17,8 @@ namespace TBF.BenchControl
Factories.Add(new BenchInfo.Munich.ComponentFactory());
Factories.Add(new BenchInfo.Extended.ComponentFactory());
- Factories.Add(new Elde.ControlBoardFactory());
+ Factories.Add(new BenchInfo.iPerl.ComponentFactory());
+ Factories.Add(new Elde.ControlBoardFactory());
Factories.Add(new Elde.CoverTest.Factory());
Factories.Add(new DataEntry.Combined.EntryFormFactory());
Factories.Add(new DataEntry.HeatMeters6.Factory());
diff --git a/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs b/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs
index 74fc4c7b0..8801a3efb 100644
--- a/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs
+++ b/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs
@@ -52,6 +52,11 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
const int Q2CorrFactorsAddrRL = 0x1879;
const int Q2CorrFactorsAddrLR = 0x1878;
+ public static Color DisabledColor = Color.DarkGray;
+ public static Color OptoAndDirOKColor = Color.Green;
+ public static Color OptoNokColor = Color.Orange;
+ public static Color DirNokColor = Color.Red;
+
private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm));
protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
@@ -597,7 +602,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
if (!checkBoxesEditMode && (iperlHeads[i] == null || iperlHeads[i].Disabled))
{
checkBoxes[i].Enabled = checkBoxes[i].Checked = ckbState[i] = false;
- counters[i].BackColor = Color.DarkGray;
+ counters[i].BackColor = DisabledColor;
messages[i].Text = Strings.Head_was_disabled_by_the_user;
}
else
@@ -618,7 +623,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
for (int i = 0; i < iperlHeads.Count; i++)
{
iperlHeads[i].FlushedDataCount = 0;
- counters[i].BackColor = Color.Red;
+ counters[i].BackColor = OptoNokColor;
}
///
@@ -2163,11 +2168,25 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
{
if (iperlHeads[i] == null || iperlHeads[i].Disabled)
{
- counters[i].BackColor = Color.DarkGray;
+ counters[i].BackColor = DisabledColor;
}
else
{
- counters[i].BackColor = (iperlHeads[i].FlushedDataDelta == 0) ? Color.Red : Color.Green;
+ switch (iperlHeads[i].CheckFlowDirection())
+ {
+ case OptoHeadState.OptoAndDirOK:
+ counters[i].BackColor = OptoAndDirOKColor;
+ break;
+
+ case OptoHeadState.DirNok:
+ counters[i].BackColor = DirNokColor;
+ break;
+
+ default:
+ case OptoHeadState.OptoNok:
+ counters[i].BackColor = OptoNokColor;
+ break;
+ }
}
}
diff --git a/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/FlowDirectionDetection.cs b/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/FlowDirectionDetection.cs
new file mode 100644
index 000000000..409c041bb
--- /dev/null
+++ b/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/FlowDirectionDetection.cs
@@ -0,0 +1,102 @@
+///
+/// Copyright (c) 2018 Sensus Slovensko a.s.
+///
+using System;
+using Config.Entities;
+
+namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
+{
+ public class FlowDirectionDetection
+ {
+ readonly int fifoSize = 32;
+
+ Int64[] volumeRawFifo; /// Volume FIFO buffer
+ Int64[] timestampFifo; /// Timestamp FIFO buffer
+ ///
+ int fifoCount; /// Number of valid FIFO items
+ int fifoIx; /// Index of the next FIFO item
+ DateTime lastFifoWriteTime; /// Time of the last write to FIFO
+
+
+ public FlowDirectionDetection(int fifoSize)
+ {
+ this.fifoSize = fifoSize;
+ volumeRawFifo = new Int64[fifoSize];
+ timestampFifo = new Int64[fifoSize];
+ ClearFifo();
+ }
+
+
+ ///
+ /// Clear FIFO data
+ ///
+ public void ClearFifo()
+ {
+ fifoCount = 0;
+ fifoIx = 0;
+ lastFifoWriteTime = DateTime.MinValue;
+ }
+
+
+ ///
+ /// Write data to FIFO
+ ///
+ /// Volume
+ /// Time stamp
+ public void WriteToFifo(Int64 volumeRaw, Int64 timestamp)
+ {
+ volumeRawFifo[fifoIx] = volumeRaw;
+ timestampFifo[fifoIx] = timestamp;
+ fifoIx = (fifoIx + 1) % fifoSize;
+ fifoCount = Math.Min(fifoCount + 1, fifoSize);
+ lastFifoWriteTime = DateTime.Now;
+ }
+
+
+ ///
+ /// Determine whether there are enough recent FIFO data
+ ///
+ /// true when data valid
+ public bool AreFifoDataValid()
+ {
+ return (DateTime.Now.Subtract(lastFifoWriteTime).TotalSeconds <= 2.5) && (fifoCount == fifoSize);
+ }
+
+
+ ///
+ /// Verify whether the flow direction is correct
+ ///
+ /// OptoHeadState.OptoAndDirOK, OptoHeadState.OptoNok or OptoHeadState.DirNok
+ public OptoHeadState CheckFlowDirection(FlowDir flowDir)
+ {
+ if (!AreFifoDataValid()) return OptoHeadState.OptoNok;
+
+ int positiveCount = 0;
+ int negativeCount = 0;
+ for (int i = fifoIx; i < fifoIx + fifoSize - 1; i++)
+ {
+ if (volumeRawFifo[(i + 1) % fifoSize] - volumeRawFifo[i % fifoSize] > 0)
+ {
+ positiveCount++;
+ }
+ else if (volumeRawFifo[(i + 1) % fifoSize] - volumeRawFifo[i % fifoSize] < 0)
+ {
+ negativeCount++;
+ }
+ }
+
+ if ((positiveCount > negativeCount) && flowDir == FlowDir.R_L)
+ {
+ return OptoHeadState.OptoAndDirOK;
+ }
+ else if ((positiveCount < negativeCount) && flowDir == FlowDir.L_R)
+ {
+ return OptoHeadState.OptoAndDirOK;
+ }
+ else
+ {
+ return OptoHeadState.DirNok;
+ }
+ }
+ }
+}
diff --git a/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs b/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs
index eabf4a988..e3ad8acb1 100644
--- a/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs
+++ b/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs
@@ -1,5 +1,5 @@
///
-/// Copyright (c) 2015-2017 Sensus Metering Systems
+/// Copyright (c) 2015-2018 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
@@ -35,14 +35,15 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
public double PulsesPerLtr { get { return 1000.0; } }
public double LtrsPerPulse { get { return 1 / PulsesPerLtr; } }
+ public float CalibTarget { get { return iperlHeadCfg.ProcParams.CalibTarget; } }
+ public ushort FactorLimitLo { get { return (ushort)iperlHeadCfg.ProcParams.FactorLimitLo; } }
+ public ushort FactorLimitHi { get { return (ushort)iperlHeadCfg.ProcParams.FactorLimitHi; } }
+ public FlowDir FlowDir { get { return iperlHeadCfg.ProcParams.FlowDir; } }
+ public LogType LogType { get { return iperlHeadCfg.ProcParams.LogType; } }
#if ORACLE_DB
public int WMType_ID { get { return iperlHeadCfg.ProcParams.WMType_ID; } } /// Required by Oracle DB
public int WMType_Rev { get { return iperlHeadCfg.ProcParams.WMType_Rev; } } /// Required by Oracle DB
#endif
- public float CalibTarget { get { return iperlHeadCfg.ProcParams.CalibTarget; } }
- public ushort FactorLimitLo { get { return (ushort)iperlHeadCfg.ProcParams.FactorLimitLo; } }
- public ushort FactorLimitHi { get { return (ushort)iperlHeadCfg.ProcParams.FactorLimitHi; } }
- public LogType LogType { get { return iperlHeadCfg.ProcParams.LogType; } }
/// Properties set by the Begin and the End form
public string SerialNr
@@ -89,15 +90,18 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
}
int resultCode;
+
///
/// Passed to OptoTelegramRaw.UpdateFromString(...)
///
Int64 volumeRawExtLast;
Int64 timestampExtLast;
+ FlowDirectionDetection flowDirectionDetection;
public bool PositiveCounting;
+
/// ConfigStruct of the water meter obtained or updated by iPerlCommunication
public ConfigStruct ConfigStruct
{
@@ -335,7 +339,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
/// Volume of water from the opto telegram
///
private Int64 lastVolumeRaw; /// Last read raw volume
- private double volumeLtr; ///
+ private double volumeLtr;
private double volumeLtr0;
public double VolumeLtrStart { get { return volumeLtrStart; } } /// Test start volume for metrology
@@ -384,18 +388,13 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
int lastFlushedDataCount_1;
int lastFlushedDataCount;
- public int FlushedDataDelta
- {
- get
- {
- int retval = Math.Max(flushedDataCount - lastFlushedDataCount, lastFlushedDataCount - lastFlushedDataCount_1);
- lastFlushedDataCount_1 = lastFlushedDataCount;
- lastFlushedDataCount = flushedDataCount;
- return retval;
- }
- }
+ public OptoHeadState CheckFlowDirection()
+ {
+ return flowDirectionDetection.CheckFlowDirection(FlowDir);
+ }
+
///
/// Opto serial port and worker thread related private variables
@@ -409,8 +408,10 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
public IperlHead(Generic.IComponentCfg cfg)
: base(cfg)
- {
- ClearData();
+ {
+ flowDirectionDetection = new FlowDirectionDetection(32); /// FIFO size = 32, cca 4 sec.
+
+ ClearData();
iperlHeadCfg = cfg as IperlHeadCfg;
@@ -443,7 +444,9 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
Q2CorrRL = 0;
optoDataCount = 0;
- }
+
+ flowDirectionDetection.ClearFifo(); /// Clear FIFO for flow direction detection
+ }
public void Initialize()
{
@@ -757,16 +760,18 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
}
synchronized = true;
}
- // CR+LF found and (pos >= OptoTelegramRaw.Length - 2)
else if (optoData[optoDataCount].UpdateFromString(allRcvd.Substring(pos - OptoTelegramRaw.Length + 2), optoDataCount, ref volumeRawExtLast, ref timestampExtLast))
{
- OptoTelegramRreceived(optoDataCount++, synchronized2);
+ /// CR+LF was found && (pos >= OptoTelegramRaw.Length - 2) && the telegram is OK
+ flowDirectionDetection.WriteToFifo(volumeRawExtLast, timestampExtLast);
+ OptoTelegramRreceived(optoDataCount++, synchronized2, volumeRawExtLast, timestampExtLast);
synchronized2 = synchronized;
allRcvd = allRcvd.Substring(pos + 2);
}
else
{
- optoData[optoDataCount].Counter = optoDataCount;
+ /// CR+LF was found && (pos >= OptoTelegramRaw.Length - 2) but the telgram was not OK
+ optoData[optoDataCount].Counter = optoDataCount;
optoDataCount++;
allRcvd = allRcvd.Substring(pos + 2);
}
@@ -780,9 +785,10 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
synchronized = true;
}
// CR+LF found and (pos >= OptoTelegram.Length - 2)
- else if (toBeFlushed.UpdateFromStringDummy(allRcvd.Substring(pos - OptoTelegramRaw.Length + 2)))
+ else if (toBeFlushed.UpdateFromString(allRcvd.Substring(pos - OptoTelegramRaw.Length + 2), flushedDataCount, ref volumeRawExtLast, ref timestampExtLast))
{
- flushedDataCount++;
+ flowDirectionDetection.WriteToFifo(volumeRawExtLast, timestampExtLast);
+ flushedDataCount++;
synchronized2 = synchronized;
allRcvd = allRcvd.Substring(pos + 2);
}
@@ -803,13 +809,12 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
}
- void OptoTelegramRreceived(int currentIx, bool async)
+ void OptoTelegramRreceived(int currentIx, bool async, Int64 volumeRawExt, Int64 timestampRawExt)
{
- OptoTelegramRaw optoTelegram = optoData[currentIx];
telegramIx = currentIx;
- lastVolumeRaw = volumeRawExtLast;
- lastTimestamp = timestampExtLast;
+ lastVolumeRaw = volumeRawExt;
+ lastTimestamp = timestampRawExt;
if (volumeLtr == 0 && volumeLtr0 == 0)
{
@@ -830,8 +835,6 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
{
timestampSec = (double)lastTimestamp / 8192.0;
}
-
- //optoDataLogger.InfoFormat("{0} {1} {2} ltr {3} {4}", optoTelegram, lastTimestamp, lastVolumeRaw.ToString("X8"), timestampSec.ToString("F1"), volumeLtr.ToString("F3"));
}
diff --git a/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/ProcParams.cs b/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/ProcParams.cs
index 4e91817df..259312a49 100644
--- a/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/ProcParams.cs
+++ b/TBF/BenchControl/TestMethods/iPerlCommunication/iPerlHead/ProcParams.cs
@@ -22,6 +22,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
public float CalibTarget; /// Target error after calibration in [%]
public int FactorLimitLo; /// Lower limit for the calibration factor
public int FactorLimitHi; /// Upper limit for the calibration factor
+ public FlowDir FlowDir; /// Initial iPerl flow direction (R_L or L_R)
public LogType LogType;
#if ORACLE_DB
public int WMType_ID; /// Required for Oracle DB: ID_WZTyp in table VT_PRUEFPUNKT_SOLL_SD
@@ -35,6 +36,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
CalibTarget = 0;
FactorLimitLo = 1000;
FactorLimitHi = 8000;
+ FlowDir = FlowDir.R_L;
LogType = LogType.Just_Q1Q2Q3;
#if ORACLE_DB
WMType_ID = 2; /// Value for iPerl DN15
@@ -48,6 +50,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
"Calib. target [%]",
"Calib. factor Lo",
"Calib. factor Hi",
+ "Flow direction",
"Log type",
#if ORACLE_DB
"WMType ID",
@@ -66,6 +69,12 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
return retVal;
}
else if (i == 4)
+ {
+ IList retVal = new List();
+ for (FlowDir fd = 0; fd < FlowDir.Count; fd++) retVal.Add(fd.ToString());
+ return retVal;
+ }
+ else if (i == 5)
{
IList retVal = new List();
for (LogType lt = 0; lt < LogType.Count; lt++) retVal.Add(lt.ToString());
@@ -82,10 +91,11 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
case 1: return CalibTarget.ToString();
case 2: return FactorLimitLo.ToString();
case 3: return FactorLimitHi.ToString();
- case 4: return LogType.ToString();
+ case 4: return FlowDir.ToString();
+ case 5: return LogType.ToString();
#if ORACLE_DB
- case 5: return WMType_ID.ToString();
- case 6: return WMType_Rev.ToString();
+ case 6: return WMType_ID.ToString();
+ case 7: return WMType_Rev.ToString();
#endif
default: return string.Empty;
}
@@ -105,14 +115,20 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
case 2: FactorLimitLo = int.Parse(strValue); return CfgUpdateFlags.None;
case 3: FactorLimitHi = int.Parse(strValue); return CfgUpdateFlags.None;
case 4:
+ for (FlowDir fd = 0; fd < FlowDir.Count; fd++)
+ {
+ if (fd.ToString().Equals(strValue)) { FlowDir = fd; return CfgUpdateFlags.None; }
+ }
+ break;
+ case 5:
for (LogType lt = 0; lt < LogType.Count; lt++)
{
if (lt.ToString().Equals(strValue)) { LogType = lt; return CfgUpdateFlags.None; }
}
break;
#if ORACLE_DB
- case 5: WMType_ID = int.Parse(strValue); return CfgUpdateFlags.None;
- case 6: WMType_Rev = int.Parse(strValue); return CfgUpdateFlags.None;
+ case 6: WMType_ID = int.Parse(strValue); return CfgUpdateFlags.None;
+ case 7: WMType_Rev = int.Parse(strValue); return CfgUpdateFlags.None;
#endif
default: return CfgUpdateFlags.None;
}
@@ -140,12 +156,14 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
if (int.TryParse(strValue, out iDummy) && iDummy >= 1000 && iDummy <= 8000) return true;
break;
case 4:
+ for (FlowDir fd = 0; fd < FlowDir.Count; fd++) if (fd.ToString().Equals(strValue)) return true;
+ break;
+ case 5:
for (LogType lt = 0; lt < LogType.Count; lt++) if (lt.ToString().Equals(strValue)) return true;
break;
-
#if ORACLE_DB
- case 5: /// WMType_ID
- case 6: /// WMType_Rev
+ case 6: /// WMType_ID
+ case 7: /// WMType_Rev
if (int.TryParse(strValue, out iDummy)) return true;
break;
#endif
@@ -164,6 +182,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication.iPerlHead
prms.CalibTarget = this.CalibTarget;
prms.FactorLimitLo = this.FactorLimitLo;
prms.FactorLimitHi = this.FactorLimitHi;
+ prms.FlowDir = this.FlowDir;
prms.LogType = this.LogType;
#if ORACLE_DB
prms.WMType_ID = this.WMType_ID;
diff --git a/TBF/Pictures/forward_dir.jpg b/TBF/Pictures/forward_dir.jpg
deleted file mode 100644
index 720d648d7..000000000
Binary files a/TBF/Pictures/forward_dir.jpg and /dev/null differ
diff --git a/TBF/Pictures/forward_dir_left.jpg b/TBF/Pictures/forward_dir_left.jpg
new file mode 100644
index 000000000..a3f763896
Binary files /dev/null and b/TBF/Pictures/forward_dir_left.jpg differ
diff --git a/TBF/Pictures/forward_dir_right.jpg b/TBF/Pictures/forward_dir_right.jpg
new file mode 100644
index 000000000..5b964ded6
Binary files /dev/null and b/TBF/Pictures/forward_dir_right.jpg differ
diff --git a/TBF/Pictures/reversed_dir.jpg b/TBF/Pictures/reversed_dir.jpg
deleted file mode 100644
index ef82a2436..000000000
Binary files a/TBF/Pictures/reversed_dir.jpg and /dev/null differ
diff --git a/TBF/Pictures/reversed_dir_left.jpg b/TBF/Pictures/reversed_dir_left.jpg
new file mode 100644
index 000000000..70d7a515d
Binary files /dev/null and b/TBF/Pictures/reversed_dir_left.jpg differ
diff --git a/TBF/Pictures/reversed_dir_right.jpg b/TBF/Pictures/reversed_dir_right.jpg
new file mode 100644
index 000000000..1f5d14e60
Binary files /dev/null and b/TBF/Pictures/reversed_dir_right.jpg differ
diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs
index b50528ff5..86668ab4b 100644
--- a/TBF/Properties/AssemblyInfo.cs
+++ b/TBF/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
-[assembly: AssemblyVersion("2.18.1081.0")]
-[assembly: AssemblyFileVersion("2.18.1081.0")]
+[assembly: AssemblyVersion("2.18.1082.0")]
+[assembly: AssemblyFileVersion("2.18.1082.0")]
diff --git a/TBF/Resources/Strings.Designer.cs b/TBF/Resources/Strings.Designer.cs
index abbfd0681..c25317ff6 100644
--- a/TBF/Resources/Strings.Designer.cs
+++ b/TBF/Resources/Strings.Designer.cs
@@ -2058,6 +2058,15 @@ namespace TBF.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Left.
+ ///
+ internal static string Left {
+ get {
+ return ResourceManager.GetString("Left", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Legalizator.
///
@@ -3813,6 +3822,15 @@ namespace TBF.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Right.
+ ///
+ internal static string Right {
+ get {
+ return ResourceManager.GetString("Right", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to ROI Data.
///
@@ -4155,6 +4173,15 @@ namespace TBF.Resources {
}
}
+ ///
+ /// Looks up a localized string similar to Side.
+ ///
+ internal static string Side {
+ get {
+ return ResourceManager.GetString("Side", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Simultaneous with next step.
///
diff --git a/TBF/Resources/Strings.cs.resx b/TBF/Resources/Strings.cs.resx
index 8ab3861e4..58cd4448a 100644
--- a/TBF/Resources/Strings.cs.resx
+++ b/TBF/Resources/Strings.cs.resx
@@ -1344,4 +1344,13 @@
Mezi opak. - přechod
+
+ Levá
+
+
+ Pravá
+
+
+ Strana
+
\ No newline at end of file
diff --git a/TBF/Resources/Strings.resx b/TBF/Resources/Strings.resx
index 4508958cd..8b14bf556 100644
--- a/TBF/Resources/Strings.resx
+++ b/TBF/Resources/Strings.resx
@@ -1897,4 +1897,13 @@
Reference mass measurement error
+
+ Left
+
+
+ Right
+
+
+ Side
+
\ No newline at end of file
diff --git a/TBF/Resources/Strings.sk.resx b/TBF/Resources/Strings.sk.resx
index 31721e1d0..daf15a29c 100644
--- a/TBF/Resources/Strings.sk.resx
+++ b/TBF/Resources/Strings.sk.resx
@@ -147,4 +147,13 @@
Hladina
+
+ Ľavá
+
+
+ Pravá
+
+
+ Strana
+
\ No newline at end of file
diff --git a/TBF/Screens/ResultsTabPageCtrl.cs b/TBF/Screens/ResultsTabPageCtrl.cs
index 9c988cacc..c5fa023cb 100644
--- a/TBF/Screens/ResultsTabPageCtrl.cs
+++ b/TBF/Screens/ResultsTabPageCtrl.cs
@@ -327,9 +327,9 @@ namespace TBF.Screens
Color commonBackColor = wmtrPassed ? Color.LightGreen : (wmtrCompleted ? Color.LightPink : Color.White);
#if ORACLE_DB
- if (TBF.BenchControl.Sequences.ProcessData.BenchInfo != null)
+ if (TBF.BenchControl.Sequences.ProcessData.BenchInfo is TBF.BenchControl.BenchInfo.iPerl.Component)
{
- int maxTrials = TBF.BenchControl.Sequences.ProcessData.BenchInfo.MaxTestIndex;
+ int maxTrials = (TBF.BenchControl.Sequences.ProcessData.BenchInfo as TBF.BenchControl.BenchInfo.iPerl.Component).MaxTestIndex;
if (wmtrCompleted && !wmtrPassed && ((wMtr.Pruefindex % 100) >= maxTrials)) commonBackColor = Color.DarkOrange;
}
#endif
diff --git a/TBF/TBF.csproj b/TBF/TBF.csproj
index 956b3943a..d4e6d068d 100644
--- a/TBF/TBF.csproj
+++ b/TBF/TBF.csproj
@@ -160,6 +160,9 @@
+
+
+
@@ -1230,6 +1233,7 @@
IperlHeadCfgCtrl.cs
+
@@ -3081,10 +3085,16 @@
-
+
Always
-
+
+ Always
+
+
+ Always
+
+
Always