From 5d00bcf4568296f1c5ce91e48c91f4d4ac8b3df6 Mon Sep 17 00:00:00 2001 From: Milan Hanajik Date: Fri, 21 Aug 2015 16:06:38 +0200 Subject: [PATCH] Performance of reading opto-data improved, deferred logging, nr.threads in iPerlComm = 4version 1.5.89. --- .../BenchControl/DB/SensusOracle/Database.cs | 5 -- .../iPerlCommunicationForm.cs | 2 +- .../BenchControl/WaterMeters/iPerl/Enums.cs | 7 ++ .../WaterMeters/iPerl/OptoTelegramRaw.cs | 83 +++++++++++++------ .../WaterMeters/iPerl/WaterMeter.cs | 55 ++++++++---- TestBenchFramework/Properties/AssemblyInfo.cs | 4 +- 6 files changed, 105 insertions(+), 51 deletions(-) diff --git a/TestBenchFramework/BenchControl/DB/SensusOracle/Database.cs b/TestBenchFramework/BenchControl/DB/SensusOracle/Database.cs index 54d7ad774..e9bee4369 100644 --- a/TestBenchFramework/BenchControl/DB/SensusOracle/Database.cs +++ b/TestBenchFramework/BenchControl/DB/SensusOracle/Database.cs @@ -262,11 +262,6 @@ namespace TBF.BenchControl.DB.SensusOracle /// Open the Oracle database conn.Open(); - //string oradb = "Data Source=STARA_TEST.WORLD;User Id=deltachef;Password=deltachef;"; - //conn = new OracleConnection(oradb); // C# - - //conn.Open(); - for (int wmNr = 0; wmNr < Program.WMsCount; wmNr++) /// wmNr is 0-based { if (!unsortedResults[0].Meters[wmNr].Disabled) diff --git a/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs b/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs index 7e6915f4b..4a8736583 100644 --- a/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs +++ b/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs @@ -32,7 +32,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication { const int CommTimeout = 1500; const int MaxCommRetries = 3; - const int NrThreads = 2; /// 1, 2 or 4 threads + const int NrThreads = 4; /// 1, 2 or 4 threads private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm)); diff --git a/TestBenchFramework/BenchControl/WaterMeters/iPerl/Enums.cs b/TestBenchFramework/BenchControl/WaterMeters/iPerl/Enums.cs index 4d7ae0232..a8a51b80a 100644 --- a/TestBenchFramework/BenchControl/WaterMeters/iPerl/Enums.cs +++ b/TestBenchFramework/BenchControl/WaterMeters/iPerl/Enums.cs @@ -93,4 +93,11 @@ namespace TBF.BenchControl.WaterMeters.iPerl EmptyPipe = 3, Count /// Number of flow states } + + public enum OptoTelegramFlags : byte + { + OK = 0, + InvalidTelegram, /// Wrong telegram format of checksum error + SyncError, + } } diff --git a/TestBenchFramework/BenchControl/WaterMeters/iPerl/OptoTelegramRaw.cs b/TestBenchFramework/BenchControl/WaterMeters/iPerl/OptoTelegramRaw.cs index 4f38b07b8..c4b9ee389 100644 --- a/TestBenchFramework/BenchControl/WaterMeters/iPerl/OptoTelegramRaw.cs +++ b/TestBenchFramework/BenchControl/WaterMeters/iPerl/OptoTelegramRaw.cs @@ -7,15 +7,15 @@ namespace TBF.BenchControl.WaterMeters.iPerl { public static readonly int Length = 42; + public OptoTelegramFlags flags; + public UInt32 EmfRaw; public Int16 MagneticField; public Int16 FlowRaw; public Int32 VolumeRaw; public Int16 Impedance; public Int64 Timestamp; - public byte GG; - - string sourceStr; + public byte CheckSum; public OptoTelegramRaw() { @@ -23,7 +23,29 @@ namespace TBF.BenchControl.WaterMeters.iPerl public override string ToString() { - return sourceStr; + if (flags == OptoTelegramFlags.OK) + { + return string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}", + EmfRaw.ToString("X6"), + MagneticField.ToString("X4"), + FlowRaw.ToString("X4"), + VolumeRaw.ToString("X6"), + Impedance.ToString("X4"), + Timestamp.ToString("X8"), + CheckSum.ToString("X2")); + } + else if (flags == OptoTelegramFlags.SyncError) + { + return "Sychronization error"; + } + else if (flags == OptoTelegramFlags.InvalidTelegram) + { + return "Invalid telegram"; + } + else + { + return "???"; + } } /// @@ -54,35 +76,46 @@ namespace TBF.BenchControl.WaterMeters.iPerl /// /// A complete byte array data /// ConfigStruct or null when byte array was not complete - public static OptoTelegramRaw FromString(string telegram) + public bool UpdateFromString(string telegram) { if ((telegram == null) || (telegram.Length < Length) || (telegram[6] != '\t') || (telegram[11] != '\t') || (telegram[16] != '\t') || - (telegram[23] != '\t') || (telegram[28] != '\t') || (telegram[37] != '\t') || - (telegram[40] != '\r') || (telegram[41] != '\n')) + (telegram[23] != '\t') || (telegram[28] != '\t') || (telegram[37] != '\t') || + (telegram[40] != '\r') || (telegram[41] != '\n')) + { + return false; + } + + bool f1 = UInt32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out EmfRaw); + bool f2 = Int16.TryParse(telegram.Substring(7, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out MagneticField); + bool f3 = Int16.TryParse(telegram.Substring(12, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out FlowRaw); + bool f4 = Int32.TryParse(telegram.Substring(17, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw); + bool f5 = Int16.TryParse(telegram.Substring(24, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Impedance); + bool f6 = Int64.TryParse(telegram.Substring(29, 8), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Timestamp); + bool f7 = byte.TryParse(telegram.Substring(38, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum); + + return f1 && f2 && f3 && f4 && f5 && f6 && f7; + } + + + public static OptoTelegramRaw FromString(string telegram) + { + OptoTelegramRaw opto = new OptoTelegramRaw(); + + if (opto.UpdateFromString(telegram)) + { + return opto; + } + else { return null; } + } - OptoTelegramRaw opto = new OptoTelegramRaw(); - bool f1 = UInt32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out opto.EmfRaw); - bool f2 = Int16.TryParse(telegram.Substring(7, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out opto.MagneticField); - bool f3 = Int16.TryParse(telegram.Substring(12, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out opto.FlowRaw); - bool f4 = Int32.TryParse(telegram.Substring(17, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out opto.VolumeRaw); - bool f5 = Int16.TryParse(telegram.Substring(24, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out opto.Impedance); - bool f6 = Int64.TryParse(telegram.Substring(29, 8), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out opto.Timestamp); - bool f7 = byte.TryParse(telegram.Substring(38, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out opto.GG); - - if (f1 && f2 && f3 && f4 && f5 && f6 && f7) - { - opto.sourceStr = telegram.Substring(0, Length - 2); - return opto; - } - else - { - return null; - } + public void SetFlags(OptoTelegramFlags flags) + { + this.flags = flags; } } } diff --git a/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs b/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs index a195aafd4..a50c6485d 100644 --- a/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs +++ b/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs @@ -4,6 +4,7 @@ /// using System; using System.Collections.Generic; +using System.IO; using System.IO.Ports; using System.Threading; using log4net; @@ -18,7 +19,6 @@ namespace TBF.BenchControl.WaterMeters.iPerl public class WaterMeter : ComponentBase, IDevice, GenericDevices.IWaterMeter, GenericDevices.IRegisterReader, IOperation { private static readonly ILog log = LogManager.GetLogger(typeof(WaterMeter)); - protected ILog optoDataLogger; /// Instance logger for opto-port data public override string ToString() { return string.Format("iPerl({0})", Cfg.ToString(1)); } @@ -148,6 +148,11 @@ namespace TBF.BenchControl.WaterMeters.iPerl private Boxes.DoubleBox timeSec; + OptoTelegramRaw[] optoData; + const int MaxOptoDataCount = 40000; + int optoDataCount; + string optoDataLogFileName; + /// /// Opto serial port and worker thread related private variables /// @@ -184,10 +189,12 @@ namespace TBF.BenchControl.WaterMeters.iPerl { if (DebugLevel == Entities.DebugMode.Normal) { - int nr = NrFormName(Name); - optoDataLogger = LogManager.GetLogger("OptoData_" + nr.ToString()); - optoDataLogger.Fatal("------------------------------------------------------------------------"); - optoDataLogger.Fatal("Program restarted"); + //int nr = NrFormName(Name); + //optoDataLogger = LogManager.GetLogger("OptoData_" + nr.ToString()); + //optoDataLogger.Fatal("------------------------------------------------------------------------"); + //optoDataLogger.Fatal("Program restarted"); + + optoData = new OptoTelegramRaw[MaxOptoDataCount]; /// Prepare serial port optoSerialPort = new SerialPort(string.Format("COM{0}", iPerlCfg.OptoComPortNr), @@ -284,7 +291,12 @@ namespace TBF.BenchControl.WaterMeters.iPerl /// Start this operation public void Start() { - sampleNr = 0; + /// Reset opto data + optoDataCount = 0; + optoDataLogFileName = (ConfigStruct != null) ? ConfigStruct.PCBNumber2String() : "Unknown PCBNumber"; + optoDataLogFileName += "_" + Name + "_" + DateTime.Now.ToShortTimeString(); + + sampleNr = 0; volumeLtr = 0; volumeLtr0 = 0; @@ -323,9 +335,17 @@ namespace TBF.BenchControl.WaterMeters.iPerl /// Stop this operation public void Stop() { + SaveOptoData(); } + void SaveOptoData() + { + TextWriter optoLogFile = new StreamWriter("C:\\TBF\\ProcessData\\" + optoDataLogFileName + ".txt"); + for (int i = 0; i < optoDataCount; i++) optoLogFile.WriteLine(optoData[i].ToString()); + optoLogFile.Close(); + } + void ReadPulses() { pulses.Val = (int)((volumeLtr - volumeLtr0) * (double)PulsesPerLtr + 0.5); @@ -401,7 +421,6 @@ namespace TBF.BenchControl.WaterMeters.iPerl string allRcvd = partOfTelegram + received; - OptoTelegramRaw opto; while (true) { int pos = allRcvd.IndexOf("\r\n"); @@ -419,20 +438,20 @@ namespace TBF.BenchControl.WaterMeters.iPerl allRcvd = allRcvd.Substring(pos + 2); if (synchronized) { - optoDataLogger.ErrorFormat("{0}: Opto data syncronisation error", Name); + optoData[optoDataCount++].SetFlags(OptoTelegramFlags.SyncError); } synchronized = true; } // CR+LF found and (pos >= OptoTelegram.Length - 2) - else if (null != (opto = OptoTelegramRaw.FromString(allRcvd.Substring(pos - OptoTelegramRaw.Length + 2)))) + else if (optoData[optoDataCount].UpdateFromString(allRcvd.Substring(pos - OptoTelegramRaw.Length + 2))) { - OptoTelegramRreceived(opto, synchronized2); + OptoTelegramRreceived(optoData[optoDataCount++], synchronized2); synchronized2 = synchronized; allRcvd = allRcvd.Substring(pos + 2); } else { - optoDataLogger.ErrorFormat("{0}: Wrong format of opto data", Name); + optoData[optoDataCount++].SetFlags(OptoTelegramFlags.InvalidTelegram); allRcvd = allRcvd.Substring(pos + 2); } } @@ -476,11 +495,11 @@ namespace TBF.BenchControl.WaterMeters.iPerl { lastVolumeRaw = uncorrectedRawVolume - 0x01000000; } - else - { - optoDataLogger.Info("Fatal error"); - } - } + else + { + lastVolumeRaw = uncorrectedRawVolume; /// This should never happen + } + } Int64 uncorrectedTimestamp = 0; @@ -506,7 +525,7 @@ namespace TBF.BenchControl.WaterMeters.iPerl } else { - optoDataLogger.Info("Fatal error2"); + lastTimestamp = uncorrectedTimestamp; /// This should never happen } } @@ -530,7 +549,7 @@ namespace TBF.BenchControl.WaterMeters.iPerl timestampSec = (double)lastTimestamp / 8192.0; } - optoDataLogger.InfoFormat("{0} {1} {2} ltr {3} {4}", optoTelegram, lastTimestamp, lastVolumeRaw.ToString("X8"), timestampSec.ToString("F1"), volumeLtr.ToString("F3")); + //optoDataLogger.InfoFormat("{0} {1} {2} ltr {3} {4}", optoTelegram, lastTimestamp, lastVolumeRaw.ToString("X8"), timestampSec.ToString("F1"), volumeLtr.ToString("F3")); } diff --git a/TestBenchFramework/Properties/AssemblyInfo.cs b/TestBenchFramework/Properties/AssemblyInfo.cs index a05e41755..5635c2ec8 100644 --- a/TestBenchFramework/Properties/AssemblyInfo.cs +++ b/TestBenchFramework/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("1.5.88.1")] -[assembly: AssemblyFileVersion("1.5.88.1")] +[assembly: AssemblyVersion("1.5.89.1")] +[assembly: AssemblyFileVersion("1.5.89.1")]