550 lines
16 KiB
C#
550 lines
16 KiB
C#
///
|
|
/// 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<MeterBatch> BatchHolder = new Lazy<MeterBatch>(() =>
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// This component = instance of this class is a placeholder for a combined main watermeter
|
|
/// </summary>
|
|
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;
|
|
|
|
|
|
/// <summary> ConfigStruct of the water meter obtained or updated by iPerlCommunication </summary>
|
|
public ConfigStruct ConfigStruct
|
|
{
|
|
get { return configStruct; }
|
|
set { configStruct = value; }
|
|
}
|
|
ConfigStruct configStruct;
|
|
|
|
/// <summary> CalibrationStruct of the water meter obtained or updated by iPerlCommunication </summary>
|
|
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; } }
|
|
|
|
|
|
/// <summary> Result of the last test used to calculate Q2 correction factors, etc </summary>
|
|
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;
|
|
|
|
|
|
/// <summary> Name set by the test, to be used as a part of the opto-data log file name </summary>
|
|
public string TestName;
|
|
|
|
/// <summary> Name set by the test, to be used as a part of the opto-data log file name </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clear data related to a specific water meter
|
|
/// </summary>
|
|
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() { }
|
|
|
|
/// <summary>
|
|
/// Events: Event.ReadRegisterDone, Event.Error
|
|
/// </summary>
|
|
/// <returns>ReadWaterMeter instance reference casted to IOperaton</returns>
|
|
public IOperation ReadRegisterOp()
|
|
{
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clear data/counters related to a specific tests
|
|
/// </summary>
|
|
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;
|
|
/// <summary>Start this operation</summary>
|
|
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();
|
|
//}
|
|
|
|
|
|
}
|
|
|
|
/// <summary>Run this operation</summary>
|
|
/// <returns>eventDone</returns>
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Stop this operation</summary>
|
|
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;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|