/// /// Copyright (c) 2015-2018 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.IO; using System.IO.Ports; using System.Threading; using System.Windows.Forms; using log4net; using Config.Entities; using TBF.BenchControl; using TBF.BenchControl.Generic; using TBF.Resources; using Xylem.Common.Hardware.WaterMeter; using Xylem.Common.Hardware.WaterMeter.Genesis; using TBF.BenchControl.GenericDevices; namespace TBF.BenchControl.TestMethods.GenesisCommunication.GenesisHead { public static class GenesisHeadBatch { public static readonly Lazy BatchHolder = new Lazy(() => { return new MeterBatch(); }); internal static bool Start(IRegisterReader[] registerReaders, string[] lastSNTexts) { int index = 0; var ret = false; foreach (var rr in registerReaders) { if (rr is TestMethods.GenesisCommunication.GenesisHead.GenesisHead) { if (!string.IsNullOrEmpty(lastSNTexts[index])) { var myGenesis = ((TestMethods.GenesisCommunication.GenesisHead.GenesisHead)rr).SetUp(); ret = true; } } index = index + 1; } return ret; } } /// /// This component = instance of this class is a placeholder for a combined main watermeter /// public class GenesisHead : ComponentBase, IDevice, GenericDevices.IRegisterReader, IOperation { private static readonly ILog log = LogManager.GetLogger(typeof(GenesisHead)); public override string ToString() { return string.Format("Genesis({0})", Cfg.ToString(1)); } public Config.Entities.RegisterReaderType RegisterReaderType { get { return Config.Entities.RegisterReaderType.DataStream; } } readonly GenesisHeadCfg genesisHeadCfg; public int SlotNr { get { return genesisHeadCfg.SlotNr; } } public double PulsesPerLtr { get { return 1000.0; } } public double LtrsPerPulse { get { return 1 / PulsesPerLtr; } } #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 (ushort)genesisHeadCfg.ProcParams.CalibTarget; } } public ushort FactorLimitLo { get { return (ushort)genesisHeadCfg.ProcParams.FactorLimitLo; } } public ushort FactorLimitHi { get { return (ushort)genesisHeadCfg.ProcParams.FactorLimitHi; } } /// Properties set by the Begin and the End form //todo rd implement public string SerialNr; public string EndState { get { return endState; } set { endState = value; } } string endState; public string BeginState { get { return beginState; } set { beginState = value; } } string beginState; public bool Disabled { get { return disabled; } set { disabled = value; } } bool disabled; public bool CommFailed { get { return commFailed; } set { commFailed = value; } } bool commFailed; public int ResultCode { get { return resultCode; } } int resultCode; /// ConfigStruct of the water meter obtained or updated by iPerlCommunication public ConfigStruct ConfigStruct { get { return configStruct; } set { configStruct = value; } } ConfigStruct configStruct; /// CalibrationStruct of the water meter obtained or updated by iPerlCommunication public CalibrationStruct CalibrationStruct { get { return calibrationStruct; } set { calibrationStruct = value; } } CalibrationStruct calibrationStruct; public ushort OrigCalibFactor; public ushort CalibFactor { get { return (CalibrationStruct != null) ? CalibrationStruct.Calibration : (ushort)0; } } public double Q2ErrWOCorrection; public bool Q2CorrectionDone; public double Q2Correction; public int Q2CorrRFlow; public int Q2CorrLFlow; public double Diff2Hz8Hz; public bool Hz2CorrectionDone; public int Hz2Correction; public string FWVersion { get { return (CalibrationStruct != null) ? CalibrationStruct.FWVersionStr() : string.Empty; } } /// Result of the last test used to calculate Q2 correction factors, etc public Results.Entities.MeterTestRslt LastTestResult2; public Results.Entities.MeterTestRslt LastTestResult; public double NominalTestFlowLph; /// in liter per hour /// /// Required for IRegisterReader interface /// public int WMPulses { get { return wmPulses; } } public int WMRefPulses { get { return wmRefPulses; } } public double WMVolume { get { return wmVolume; } } public double BeginWMState { get { return beginWMState; } } public double EndWMState { get { return endWMState; } } public double WMTestTime { get { return wmTestTime; } } double beginWMState; double endWMState; double wmVolume; int wmPulses; int wmRefPulses; double wmTestTime; /// Name set by the test, to be used as a part of the opto-data log file name public string TestName; /// Name set by the test, to be used as a part of the opto-data log file name public string BenchName; /// /// Volume of water from the opto telegram /// private Int64 lastVolumeRaw; /// Last read raw volume private double volumeLtr; /// private double volumeLtr0; /// /// Timestamp from the opto telegram /// private double timestampSec; private double timestampSec0; public bool NoSamples { get { return (timestampSecEnd - timestampSecStart) < float.Epsilon; } } public double TimestampSecStart { get { return timestampSecStart; } } public double TimestampSecEnd { get { return timestampSecEnd; } } double timestampSecStart; double timestampSecEnd; public GenesisHead() { } public GenesisHead(Generic.IComponentCfg cfg) : base(cfg) { ClearData(); genesisHeadCfg = cfg as GenesisHeadCfg; log.Debug(this.ToString()); } GenesisMeter myGenesis = null; public GenesisMeter SetUp() { if (myGenesis != null) { myGenesis.DisposeMeter(); } //add for gen myGenesis = new GenesisMeter(); myGenesis.SetupFromConfigFile(SlotNr); GenesisHeadBatch.BatchHolder.Value.AddMeter(myGenesis); myGenesis.LogRawData(true); return myGenesis; } /// /// Clear data related to a specific water meter /// public void ClearData() { resultCode = 0; disabled = false; commFailed = false; endState = string.Empty; beginState = string.Empty; configStruct = null; calibrationStruct = null; LastTestResult = null; NominalTestFlowLph = 0; OrigCalibFactor = 0; Q2ErrWOCorrection = 0; Q2CorrectionDone = false; Q2CorrRFlow = 0; } public void Initialize() { ClearData(); if (DebugLevel == DebugMode.Normal) { } } public void RunDeviceBefore() { ////todo: RD- Login?? //if (DebugLevel == DebugMode.Normal) //{ // if (myGenesis != null) // { // Log("TBF RunDeviceBefore"); // //myGenesis.Login(); // //myGenesis.InitMeasurement(); // } // else // { // throw new Exception("No meter was bound!"); // } //} //else if (DebugLevel == DebugMode.FailureDuringOperation) //{ //} } public void RunDeviceAfter() { } public void StopDevice() { try { if (DebugLevel == DebugMode.Normal && myGenesis != null) { myGenesis.DisposeMeter(); GenesisHeadBatch.BatchHolder.Value.RemoveMeter(myGenesis); } } catch { } } public void StopDevice2() { } /// /// Events: Event.ReadRegisterDone, Event.Error /// /// ReadWaterMeter instance reference casted to IOperaton public IOperation ReadRegisterOp() { return this; } /// /// Clear data/counters related to a specific tests /// public void Clear() { resultCode = 0; sampleNr = 0; volumeLtr = 0; volumeLtr0 = 0; timestampSec = 0; timestampSec0 = 0; ReadPulses(); } public void TestCompleted() { /// TODO: Implement } int sampleNr; /// This is to determine when the test start sample should be taken bool StoreStartPackage = false; bool StoreEndPackage = false; bool Enable = false; public bool IsCalibration = false; /// Start this operation public void Start() { } public void StartRead(string TestName) { StoreStartPackage = false; StoreEndPackage = false; //Start mesurement if (DebugLevel == DebugMode.Normal) { if (myGenesis != null) { IsCalibration = false; Log("TBF Start Measurement"); if (TestName.ToLower().Contains("calib")) { IsCalibration = true; myGenesis.StartCalibration(); } else { myGenesis.StartMeasurement(); } StoreStartPackage = true; } } } public void Log(string text) { if (DebugLevel == DebugMode.Normal) { if (myGenesis != null) { myGenesis.WriteLog(text); } } } void readOutResults(Xylem.Common.Hardware.WaterMeter.CommonMeterDefinitions.MeasurementResults results) { //if (StoreStartPackage) //{ // volumeLtr0 = results.StartData.GetVolumeQm() * 1000; // timestampSec0 = results.StartData.GetTimeS(); // StoreStartPackage = false; //} //else if (!StoreEndPackage) //{ volumeLtr = results.EndData.GetVolumeQm() * 1000; timestampSec = results.EndData.GetTimeS(); wmTestTime = results.TotalTimeS; wmVolume = results.TotalVolumeQm * 1000; ReadPulses(); //} } /// Run this operation /// eventDone public Event Run() { if (DebugLevel == DebugMode.Normal) { if (myGenesis != null) { try { //var results = myGenesis.GetIntermediateMeasurementResult(); //readOutResults(results); } catch (Exception) { } } } return Event.ReadRegisterDone; } public double RefVolume = 0.0; public void Stop() { //Stop(null); if (DebugLevel == DebugMode.Normal && myGenesis != null) { if (IsCalibration) { myGenesis.StopCalibration(); } else { myGenesis.StopMeasurement(); } } } /// Stop this operation public void Stop(Double? testTimeS = null) { if (DebugLevel == DebugMode.Normal && myGenesis != null) { Log("TBF Stop Measurement"); if (IsCalibration) { //myGenesis.StopCalibration(); int retryCounter = 400; while (myGenesis.GetCalibrationState() != Xylem.Common.Hardware.WaterMeter.CommonMeterDefinitions.ActionStates.IsCompleted) { if (retryCounter < 0) { break; } Thread.Sleep(10); retryCounter = retryCounter - 1; } try { var results = myGenesis.GetCalibrationResult(); readOutResults(results[0]); if (RefVolume != 0.0) { myGenesis.CalculateCalibrationWithVol(RefVolume,0); myGenesis.SaveCalculatedCalibration(false); } } catch (Exception ex) { MarkAsError(); Log("Error while Stop Calib " + ex.Message); } } else { int retryCounter = 400; //myGenesis.StopMeasurement(); while (myGenesis.GetMeasurementState() != Xylem.Common.Hardware.WaterMeter.CommonMeterDefinitions.ActionStates.IsCompleted) { if (retryCounter < 0) { break; } Thread.Sleep(10); retryCounter = retryCounter - 1; } try { var results = myGenesis.GetMeasurementResult(testTimeS); readOutResults(results); } catch (Exception ex) { MarkAsError(); Log("Error while Stop Measurement " + ex.Message); } } StoreEndPackage = true; } } void MarkAsError() { volumeLtr = 100; timestampSec = 1; wmTestTime = 1; wmVolume = 100; ReadPulses(); } void ReadPulses() { beginWMState = volumeLtr0; endWMState = volumeLtr; wmPulses = (int)(wmVolume * (double)PulsesPerLtr + 0.5); wmRefPulses = StateMachine.ControlBoard.EtPulses(0); } bool optoSerialPortParsingEnabled; } }