Performance of reading opto-data improved, deferred logging, nr.threads in iPerlComm = 4version 1.5.89.

This commit is contained in:
Milan Hanajik 2015-08-21 16:06:38 +02:00
parent db8598579d
commit 5d00bcf456
6 changed files with 105 additions and 51 deletions

View File

@ -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)

View File

@ -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));

View File

@ -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,
}
}

View File

@ -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 "???";
}
}
/// <summary>
@ -54,35 +76,46 @@ namespace TBF.BenchControl.WaterMeters.iPerl
/// </description>
/// <param name="data">A complete byte array data</param>
/// <returns>ConfigStruct or null when byte array was not complete</returns>
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;
}
}
}

View File

@ -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
/// <summary>Start this operation</summary>
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
/// <summary>Stop this operation</summary>
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"));
}

View File

@ -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")]