536 lines
20 KiB
C#
536 lines
20 KiB
C#
///
|
|
/// Copyright (c) 2015-2017 Sensus Metering Systems
|
|
///
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using Config.Entities;
|
|
using Results.Resources;
|
|
|
|
namespace Results.Entities
|
|
{
|
|
|
|
public enum ResultCode
|
|
{
|
|
None = 0,
|
|
|
|
Bit16 = (1 << 16),
|
|
Bit17 = (1 << 17),
|
|
Bit18 = (1 << 18),
|
|
Bit19 = (1 << 19),
|
|
RfidErrorCodeMask = (Bit16 | Bit17 | Bit18 | Bit19), /// RFID comm. err. (the first encounetered error is stored)
|
|
|
|
Bit20 = (1 << 20),
|
|
Bit21 = (1 << 21),
|
|
Bit22 = (1 << 22),
|
|
Bit23 = (1 << 23),
|
|
RfidErrorTestIdMask = (Bit20 | Bit21 | Bit22 | Bit23), /// RFID comm. err. (the first encounetered error is stored)
|
|
|
|
MissingOptoData = (1 << 24),
|
|
OptoDataWithZeroFlow = (1 << 25),
|
|
OptoErrorCodeMask = (MissingOptoData | OptoDataWithZeroFlow), /// Opto comm. err. (the first encounetered error is stored)
|
|
|
|
Bit26 = (1 << 26),
|
|
Bit27 = (1 << 27),
|
|
Bit28 = (1 << 28),
|
|
Bit29 = (1 << 29),
|
|
Bit30 = (1 << 30),
|
|
Bit31 = (1 << 31),
|
|
}
|
|
|
|
|
|
public class WaterMeter
|
|
{
|
|
public virtual int Id { get; protected set; }
|
|
public virtual string SerialNr { get; set; } /// S/N _or_ S/N of the main meter of a compound meter _or_ PCB Number of an iPerl water meter
|
|
public virtual string SerialNrAux { get; set; } /// S/N of the aux. meter of a compound meter _or_ a complete assigned S/N of an iPerl water meter
|
|
public virtual string PurchaseOrder { get; set; }
|
|
public virtual int YearOfProduction { get; set; }
|
|
public virtual int WMPosition { get; set; }
|
|
public virtual string EndState { get; set; } /// End state (of the main water meter)
|
|
public virtual string EndStateAux { get; set; } /// End state of the auxiliary water meter
|
|
public virtual double QRise { get; set; } /// [m3/h] detected Q_rise of a composed meter or 'sensitivity' of a single meter
|
|
public virtual double QFall { get; set; } /// [m3/h] detected Q_fall of a composed meter
|
|
public virtual long ErrorFlags { get; set; } /// bitfield : bit14=E15, bit15=E16
|
|
public virtual long InfoFlags { get; set; } /// bitfield : bit14=E15, bit15=E16
|
|
public virtual bool Passed { get; set; }
|
|
public virtual int ResultCode { get; set; }
|
|
public virtual string ArchivePath { get; set; }
|
|
public virtual string Remark { get; set; }
|
|
|
|
#if IPERL
|
|
public virtual double OrigCalibFactor { get; set; } /// Original iPerl calibration factor used during the test
|
|
public virtual double CalibFactor { get; set; } /// iPerl calibration factor used during the test
|
|
public virtual double OrigCalibFactorLNA{ get; set; } /// Original iPerl LNA calibration factor used during the test
|
|
public virtual double CalibFactorLNA { get; set; } /// iPerl LNA calibration factor used during the test
|
|
public virtual double Q2ErrWOCorrection { get; set; }
|
|
public virtual int Q2CorrRL { get; set; } /// iPerl Q2 correction for the R-flow written to iPerl
|
|
public virtual int Q2CorrLR { get; set; } /// iPerl Q2 correction for the L-flow written to iPerl
|
|
public virtual int Q2CorrFlowRight { get; set; } /// 1 = right to left
|
|
public virtual double Diff2Hz8Hz { get; set; }
|
|
public virtual bool Hz2CorrectionDone { get; set; } /// true = iPerl Q2 correction was done
|
|
public virtual int Hz2Correction { get; set; } /// iPerl Q2 correction used during the test
|
|
public virtual string FWVersion { get; set; }
|
|
#endif
|
|
#if TURA_SPECIAL
|
|
/// <summary>
|
|
/// Data from a production test bench (in case of tests on iPerl special)
|
|
/// </summary>
|
|
public virtual int AssignedSerialNr { get; set; }
|
|
public virtual string CompleteSerialNr { get; set; }
|
|
public virtual string RadioAddress { get; set; }
|
|
public virtual int PaletteNr { get; set; }
|
|
public virtual int UmkartonNr { get; set; }
|
|
public virtual string ProdTestBench { get; set; }
|
|
public virtual int ProdWMPosition { get; set; }
|
|
public virtual string ProdUserName { get; set; }
|
|
public virtual string ProdPurchaseOrder { get; set; }
|
|
public virtual bool ProdPassed { get; set; }
|
|
public virtual int ProdResultCode { get; set; }
|
|
public virtual int ProdQ2CorrRL { get; set; } /// iPerl Q2 correction for the R-flow written to iPerl
|
|
public virtual int ProdQ2CorrLR { get; set; } /// iPerl Q2 correction for the L-flow written to iPerl
|
|
#endif
|
|
#if ORACLE_DB
|
|
public virtual int Pruefindex { get; set; } /// >= 1 ... pruefindex
|
|
public virtual int HydrPruefung { get; set; }
|
|
public virtual int WMTypeRevision { get; set; } /// Not mapped to DB !!!
|
|
public virtual object RawTestInfos { get; set; } /// IList<SensusTestInfo> fetched from Oracle at the beginning of the cycle, not mapped to DB !!!
|
|
public virtual object CompleteTestInfos { get; set; } /// SensusTestInfo[] obtained as a best match at the beginning of the cycle, not mapped to DB !!!
|
|
#endif
|
|
public virtual int ProcessId { get; set; } /// Not mapped to DB !!! Tracing DB Process ID
|
|
public virtual bool LastRecordIsNok { get; set; } /// Not mapped to DB !!! Previous record verification result
|
|
|
|
public virtual WaterMeterData WaterMeterData { get; set; }
|
|
public virtual Batch Batch { get; set; }
|
|
public virtual IList<MeterTestRslt> MeterTestRslts { get; set; }
|
|
|
|
///
|
|
/// Wrappers
|
|
///
|
|
public virtual string ProductName() { return WaterMeterData.ProductName; }
|
|
public virtual string Producer() { return WaterMeterData.Producer; }
|
|
public virtual string MetrologicalClass() { return WaterMeterData.MetrologicalClass; }
|
|
public virtual string ApprovalInfo() { return WaterMeterData.ApprovalInfo; }
|
|
public virtual bool NewQnames() { return WaterMeterData.NewQnames; }
|
|
public virtual double Q4_Qmax() { return WaterMeterData.Q4_Qmax; }
|
|
public virtual double Q3_Qn() { return WaterMeterData.Q3_Qn; }
|
|
public virtual double Q2_Qt() { return WaterMeterData.Q2_Qt; }
|
|
public virtual double Q1_Qmin() { return WaterMeterData.Q1_Qmin; }
|
|
|
|
public virtual bool Compound() { return WaterMeterData.Compound; }
|
|
public virtual bool HeatMeter() { return WaterMeterData.HeatMeter; }
|
|
|
|
public virtual string ProducerAux() { return WaterMeterData.ProducerAux; }
|
|
public virtual double Q3_Qn_Aux() { return WaterMeterData.Q3_Qn_Aux; }
|
|
public virtual string MetrologicalClassAux() { return WaterMeterData.MetrologicalClassAux; }
|
|
public virtual string ApprovalInfoAux() { return WaterMeterData.ApprovalInfoAux; }
|
|
|
|
public virtual int BatchNr() { return Batch.BatchNr; }
|
|
public virtual int BenchId() { return Batch.TestBenchId; }
|
|
public virtual string ProcedureName() { return Batch.ProcedureName; }
|
|
public virtual int ProcedureRevision() { return Batch.ProcedureRevision; }
|
|
public virtual DateTime StartTime() { return Batch.StartTime; }
|
|
public virtual DateTime EndTime() { return Batch.EndTime; }
|
|
|
|
protected MeterTestRslt lastMeterTestRslts;
|
|
public virtual MeterTestRslt LastMeterTestRslts() { return lastMeterTestRslts; }
|
|
|
|
|
|
public virtual long ErrorFlagsFromTests()
|
|
{
|
|
long errorFlags = 0;
|
|
foreach (var mtr in MeterTestRslts)
|
|
{
|
|
if (mtr.Evaluate() && mtr.TestDone) errorFlags |= mtr.TestRslt.ErrorFlags;
|
|
}
|
|
return errorFlags;
|
|
}
|
|
|
|
public virtual long ErrorFlagsFromTestsAndWM()
|
|
{
|
|
return ErrorFlagsFromTests() | ErrorFlags;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert combined errorFlags of all tests to string
|
|
/// </summary>
|
|
/// <returns>ErrorFlags string</returns>
|
|
public virtual string ErrorFlagsStr()
|
|
{
|
|
string eFlags = Utils.ErrorFlagsStr(ErrorFlagsFromTestsAndWM());
|
|
#if LANG_PL
|
|
return string.IsNullOrEmpty(eFlags) ? "brak" : eFlags;
|
|
#else
|
|
return eFlags;
|
|
#endif
|
|
}
|
|
|
|
public virtual string PassedOrErrorFlagsStr()
|
|
{
|
|
string eFlags = Utils.ErrorFlagsStr(ErrorFlagsFromTestsAndWM());
|
|
return string.IsNullOrEmpty(eFlags) ? (WaterMeterData.Text4 + PassedColorStr(null)) : eFlags;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Convert failed tests and combined errorFlags of all tests to string
|
|
/// </summary>
|
|
/// <returns>ErrorFlagsEx string</returns>
|
|
public virtual string ErrorFlagsStrEx()
|
|
{
|
|
StringBuilder errFlgsStr = new StringBuilder();
|
|
foreach (var mtr in MeterTestRslts)
|
|
{
|
|
if (mtr.Evaluate() && mtr.TestDone && !mtr.Passed)
|
|
{
|
|
errFlgsStr.Append(mtr.Name());
|
|
errFlgsStr.Append(" ");
|
|
}
|
|
}
|
|
|
|
errFlgsStr.Append(Utils.ErrorFlagsStr(ErrorFlagsFromTestsAndWM()));
|
|
|
|
return errFlgsStr.ToString();
|
|
}
|
|
|
|
public virtual bool PassedFromTests()
|
|
{
|
|
bool passed = (ErrorFlagsFromTestsAndWM() == 0);
|
|
|
|
foreach (var mtr in MeterTestRslts)
|
|
{
|
|
if (mtr.Evaluate() && (!mtr.Passed || !mtr.TestDone))
|
|
{
|
|
passed = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return passed;
|
|
}
|
|
|
|
public virtual bool CompletedFromTests()
|
|
{
|
|
bool completed = true;
|
|
foreach (var mtr in MeterTestRslts)
|
|
{
|
|
if (mtr.Evaluate() && !mtr.TestDone)
|
|
{
|
|
completed = false;
|
|
break;
|
|
}
|
|
}
|
|
return completed;
|
|
}
|
|
|
|
|
|
public virtual string PassedColorStr(string yesNoFormatOrEmpty)
|
|
{
|
|
if (string.IsNullOrEmpty(yesNoFormatOrEmpty))
|
|
{
|
|
return Utils.PassedColorStr(Passed, true);
|
|
}
|
|
else
|
|
{
|
|
string[] yesNo = yesNoFormatOrEmpty.Split(new char[] { '~' });
|
|
return Passed ? yesNo[0] : ((yesNo.Length >= 2) ? yesNo[1] : Results.Resources.Strings.No);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
///
|
|
/// Not mapped to the database
|
|
///
|
|
public virtual bool Disabled { get; set; } /// true = Disabled water meters (not saved into DB)
|
|
|
|
|
|
public virtual MeterTestRslt GetMeterTestRslt(string testName)
|
|
{
|
|
return GetMeterTestRslt(testName, CompoundMeterId.SingleOrCompound);
|
|
}
|
|
|
|
public virtual MeterTestRslt GetMeterTestRslt(string testName, Config.Entities.CompoundMeterId meterId)
|
|
{
|
|
if (string.IsNullOrEmpty(testName)) return null;
|
|
if (Disabled) return null;
|
|
|
|
string testNameL = testName.ToLower();
|
|
foreach (var mtr in MeterTestRslts)
|
|
{
|
|
if (mtr.Name().ToLower().Equals(testNameL))
|
|
{
|
|
if (mtr.CompoundMeterId == (byte)meterId)
|
|
{
|
|
return mtr;
|
|
}
|
|
else if (meterId == Config.Entities.CompoundMeterId.SingleOrCompound &&
|
|
mtr.CompoundMeterId == (byte)Config.Entities.CompoundMeterId.Single)
|
|
{
|
|
return mtr;
|
|
}
|
|
else if (meterId == Config.Entities.CompoundMeterId.SingleOrCompound &&
|
|
mtr.CompoundMeterId == (byte)Config.Entities.CompoundMeterId.Compound)
|
|
{
|
|
return mtr;
|
|
}
|
|
else if (meterId == Config.Entities.CompoundMeterId.SingleOrCompound &&
|
|
mtr.CompoundMeterId == (byte)Config.Entities.CompoundMeterId.HeatMeterEnergy)
|
|
{
|
|
return mtr;
|
|
}
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public virtual TestRslt GetTestRslt(string testName)
|
|
{
|
|
MeterTestRslt mtr = GetMeterTestRslt(testName);
|
|
if (mtr != null) return mtr.TestRslt;
|
|
return null;
|
|
}
|
|
|
|
public virtual bool TryGetTestRslt(string testName, out TestRslt testRslt)
|
|
{
|
|
MeterTestRslt mtr = GetMeterTestRslt(testName);
|
|
if (mtr != null)
|
|
{
|
|
testRslt = mtr.TestRslt;
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
testRslt = null;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public virtual TestData GetTestData(string testName)
|
|
{
|
|
foreach (var mtr in MeterTestRslts)
|
|
{
|
|
if (mtr.TestRslt.TestData.Name == testName)
|
|
{
|
|
return mtr.TestRslt.TestData;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public virtual bool TryGetTestData(string testName, out TestData testData)
|
|
{
|
|
foreach (var mtr in MeterTestRslts)
|
|
{
|
|
if (mtr.TestRslt.TestData.Name == testName)
|
|
{
|
|
testData = mtr.TestRslt.TestData;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
testData = null;
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Constructor, initializes a list, used as a base for other constructors
|
|
/// </summary>
|
|
public WaterMeter()
|
|
{
|
|
MeterTestRslts = new List<MeterTestRslt>();
|
|
#if ORACLE_DB
|
|
Pruefindex = 1;
|
|
HydrPruefung = 0;
|
|
WMTypeRevision = 0;
|
|
RawTestInfos = null;
|
|
CompleteTestInfos = null;
|
|
#endif
|
|
ProcessId = 0;
|
|
ErrorFlags = 0;
|
|
LastRecordIsNok = false;
|
|
}
|
|
|
|
|
|
public virtual void CopyContentFrom(WaterMeter src)
|
|
{
|
|
if (src == null) return;
|
|
|
|
SerialNr = src.SerialNr;
|
|
SerialNrAux = src.SerialNrAux;
|
|
PurchaseOrder = src.PurchaseOrder;
|
|
YearOfProduction = src.YearOfProduction;
|
|
// WMPosition skipped
|
|
EndState = src.EndState;
|
|
EndStateAux = src.EndStateAux;
|
|
QRise = src.QRise;
|
|
QFall = src.QFall;
|
|
ErrorFlags = src.ErrorFlags;
|
|
Passed = src.Passed;
|
|
ResultCode = src.ResultCode;
|
|
ArchivePath = src.ArchivePath;
|
|
Remark = src.Remark;
|
|
#if IPERL
|
|
OrigCalibFactor = src.OrigCalibFactor;
|
|
CalibFactor = src.CalibFactor;
|
|
OrigCalibFactorLNA = src.OrigCalibFactorLNA;
|
|
CalibFactorLNA = src.CalibFactorLNA;
|
|
Q2ErrWOCorrection = src.Q2ErrWOCorrection;
|
|
Q2CorrRL = src.Q2CorrRL;
|
|
Q2CorrLR = src.Q2CorrLR;
|
|
Q2CorrFlowRight = src.Q2CorrFlowRight;
|
|
Diff2Hz8Hz = src.Diff2Hz8Hz;
|
|
Hz2CorrectionDone = src.Hz2CorrectionDone;
|
|
Hz2Correction = src.Hz2Correction;
|
|
FWVersion = src.FWVersion;
|
|
#endif
|
|
#if TURA_SPECIAL
|
|
AssignedSerialNr = src.AssignedSerialNr;
|
|
CompleteSerialNr = src.CompleteSerialNr;
|
|
RadioAddress = src.RadioAddress;
|
|
PaletteNr = src.PaletteNr;
|
|
UmkartonNr = src.UmkartonNr;
|
|
ProdTestBench = src.ProdTestBench;
|
|
ProdWMPosition = src.ProdWMPosition;
|
|
ProdUserName = src.ProdUserName;
|
|
ProdPurchaseOrder = src.ProdPurchaseOrder;
|
|
ProdPassed = src.ProdPassed;
|
|
ProdResultCode = src.ProdResultCode;
|
|
ProdQ2CorrRL = src.ProdQ2CorrRL;
|
|
ProdQ2CorrLR = src.ProdQ2CorrLR;
|
|
#endif
|
|
#if ORACLE_DB
|
|
Pruefindex = src.Pruefindex;
|
|
HydrPruefung = src.HydrPruefung;
|
|
WMTypeRevision = src.WMTypeRevision;
|
|
RawTestInfos = src.RawTestInfos;
|
|
CompleteTestInfos = src.CompleteTestInfos;
|
|
#endif
|
|
ProcessId = src.ProcessId;
|
|
LastRecordIsNok = src.LastRecordIsNok;
|
|
|
|
foreach (var mtr in MeterTestRslts)
|
|
{
|
|
MeterTestRslt srcMtr = src.GetMeterTestRslt(mtr.Name(), (Config.Entities.CompoundMeterId)mtr.CompoundMeterId);
|
|
if (srcMtr != null)
|
|
{
|
|
mtr.CopyContentFrom(srcMtr);
|
|
mtr.TestRslt.CopyContentFrom(srcMtr.TestRslt);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
StringBuilder sb = new StringBuilder(80);
|
|
#if IPERL
|
|
sb.AppendFormat("PCB:{0} S/N:{1} ", SerialNr, SerialNrAux);
|
|
#else
|
|
sb.AppendFormat("S/N:{0} ", SerialNr);
|
|
#endif
|
|
|
|
foreach (var tr in MeterTestRslts) sb.AppendFormat(" {0}:{1}%", tr.Name(), tr.Error.ToString("F2"));
|
|
sb.AppendFormat(" test start: {0} {1} batch={2}", StartTime().ToShortDateString(), StartTime().ToShortTimeString(), BatchNr());
|
|
return sb.ToString();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Get decorated test names for a specified watermeter
|
|
/// </summary>
|
|
/// <param name="wMtr">Watermeter results entity</param>
|
|
/// <returns>A list of strings</returns>
|
|
public virtual IList<string> GetAllDecoratedTestNames()
|
|
{
|
|
IList<string> testNames = new List<string>();
|
|
|
|
if (MeterTestRslts != null)
|
|
{
|
|
foreach (var mtr in MeterTestRslts)
|
|
{
|
|
if ((mtr.CompoundMeterId == (byte)CompoundMeterId.Single || mtr.CompoundMeterId == (byte)CompoundMeterId.Compound || mtr.CompoundMeterId == (byte)CompoundMeterId.HeatMeterEnergy)
|
|
&& mtr.TestDone
|
|
&& (mtr.Publish() != Config.Entities.Publish.Never)
|
|
&& (mtr.Publish() != Config.Entities.Publish.Internal))
|
|
{
|
|
testNames.Add(mtr.Name());
|
|
}
|
|
}
|
|
}
|
|
|
|
return testNames;
|
|
}
|
|
|
|
|
|
static readonly System.Drawing.Color NotCompletedColor = System.Drawing.Color.White;
|
|
static readonly System.Drawing.Color OkColor = System.Drawing.Color.LightGreen;
|
|
static readonly System.Drawing.Color NokColor = System.Drawing.Color.LightPink;
|
|
static readonly System.Drawing.Color RejectColor = System.Drawing.Color.Magenta;
|
|
static readonly System.Drawing.Color ProductionErrorColor = System.Drawing.Color.RoyalBlue;
|
|
static readonly System.Drawing.Color WrongDirectionColor = System.Drawing.Color.Gold;
|
|
static readonly System.Drawing.Color WrongQ2FactorsColor = System.Drawing.Color.Red;
|
|
|
|
/// <summary>
|
|
/// Get color for highlighting results and an apporpriate text message.
|
|
/// </summary>
|
|
/// <param name="wMtr">Water meter results entity</param>
|
|
/// <param name="message">Appropriate message</param>
|
|
/// <returns>Color for results</returns>
|
|
public virtual System.Drawing.Color GetColorOfResults(bool maxRepeatsExceeded, out string message)
|
|
{
|
|
bool wmtrCompleted = CompletedFromTests();
|
|
bool wmtrPassed = PassedFromTests();
|
|
|
|
if ((ErrorFlags & (int)ErrorFlagMask.E28) != 0)
|
|
{
|
|
message = Strings.Previous_step_is_missing_or_NOK;
|
|
return ProductionErrorColor;
|
|
}
|
|
else if ((ErrorFlags & (int)ErrorFlagMask.E27) != 0)
|
|
{
|
|
message = Strings.Wrong_iPerl_counting_direction;
|
|
return WrongDirectionColor;
|
|
}
|
|
else if ((ErrorFlags & (int)ErrorFlagMask.E26) != 0)
|
|
{
|
|
message = Strings.Invalid_Q2_correction_factors;
|
|
return WrongQ2FactorsColor;
|
|
}
|
|
else if (wmtrPassed)
|
|
{
|
|
/// Water meter passed (therefore is was also completed)
|
|
message = Strings.Passed;
|
|
return OkColor;
|
|
}
|
|
else if (wmtrCompleted)
|
|
{
|
|
/// Water meter was completed but did not pass => Failed
|
|
if (maxRepeatsExceeded)
|
|
{
|
|
message = Strings.Test_repetition_count_exceeded_upper_limit;
|
|
return RejectColor;
|
|
}
|
|
else
|
|
{
|
|
message = Strings.Failed;
|
|
return NokColor;
|
|
}
|
|
}
|
|
else if (Disabled)
|
|
{
|
|
/// Water meter was not completed yet => did not pass, did not fail
|
|
message = Strings.This_position_is_disabled;
|
|
return NotCompletedColor;
|
|
}
|
|
else
|
|
{
|
|
/// Water meter was not completed yet => did not pass, did not fail
|
|
message = Strings.Test_in_progress;
|
|
return NotCompletedColor;
|
|
}
|
|
}
|
|
}
|
|
}
|