417 lines
16 KiB
C#
417 lines
16 KiB
C#
using CordonelPreadjustmentUi.Const;
|
|
using CordonelPreadjustmentUi.Helper;
|
|
using Logic.ProductionToProductMapper.Cordonel;
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using Logic.ProductionToProductMapper.Cordonel;
|
|
using Xylem.Common.CommonCore.Consts;
|
|
using Xylem.Common.Hardware.Interfaces.Ports.PortCore;
|
|
using Xylem.Common.Hardware.Interfaces.Protocols.ProtocolCore.EventArguments;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.EventArguments;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisConfig;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.GenesisCore;
|
|
using Xylem.Common.Ui.CordonelPreadjustmentUi.Helper.Extensions;
|
|
|
|
namespace CordonelPreadjustmentUi
|
|
{
|
|
public class ZeroFlowGenesisMeter : GenesisMeter
|
|
{
|
|
|
|
|
|
#region Data logging
|
|
|
|
private bool logZeroFlow = false;
|
|
public bool logAmpTest = false;
|
|
|
|
#endregion
|
|
private CultureInfo GlobalCulture { get; set; }
|
|
public Byte Gp30LastByte { get; set; }
|
|
private Byte[] GP30LastRegister { get; set; }
|
|
public void SetGP30LastRegister(Byte[] data)
|
|
{
|
|
GP30LastRegister = data;
|
|
}
|
|
private Byte GP30LastPayloadLsb { get; set; }
|
|
public Byte GP30LastCommand { get; set; }
|
|
private Byte GP30RXPayload { get; set; }
|
|
private Boolean GP30RequestStarted { get; set; }
|
|
private Boolean GP30RequestFailed { get; set; }
|
|
private Boolean GP30RequestGotAnswer { get; set; }
|
|
private Byte Privilege { get; set; }
|
|
private Byte FirstHitLevelUpPath0 { get; set; }
|
|
private Byte FirstHitLevelUpPath1 { get; set; }
|
|
private Byte FirstHitLevelUpPath2 { get; set; }
|
|
private Byte FirstHitLevelDownPath0 { get; set; }
|
|
private Byte FirstHitLevelDownPath1 { get; set; }
|
|
private Byte FirstHitLevelDownPath2 { get; set; }
|
|
private Byte PercentPath0 { get; set; }
|
|
private Byte PercentPath1 { get; set; }
|
|
private Byte PercentPath2 { get; set; }
|
|
public Byte Subreason { get; set; }
|
|
private Byte Starthit { get; set; }
|
|
private Byte StoreCalibration { get; set; }
|
|
private Byte Amplitude { get; set; }
|
|
private Byte Samplerate { get; set; }
|
|
private UInt16 CalibrationFactorPath0 { get; set; }
|
|
private UInt16 CalibrationFactorPath1 { get; set; }
|
|
private UInt16 CalibrationFactorPath2 { get; set; }
|
|
private Int32 ZeroOffsetPath0 { get; set; }
|
|
private Int32 ZeroOffsetPath1 { get; set; }
|
|
private Int32 ZeroOffsetPath2 { get; set; }
|
|
private Byte LedMode { get; set; }
|
|
private Byte UpdatePeriode { get; set; }
|
|
private Byte FirstHitShift { get; set; }
|
|
private UInt32 ToFTempCalibrate { get; set; }
|
|
|
|
|
|
|
|
private Int32 ToFTempOffsetPath0 { get; set; }
|
|
private Int32 ToFTempOffsetPath1 { get; set; }
|
|
private Int32 ToFTempOffsetPath2 { get; set; }
|
|
public Int32 MeterNumber { get; set; }
|
|
private Byte MeterSize { get; set; }
|
|
public bool CalculationIndicatorZeroFlowTest { get; private set; }
|
|
public bool LoggingIndicatorZeroFlowTest { get; private set; }
|
|
public long ZeroflowOffsetTestNumberOfLines { get; private set; }
|
|
|
|
public Boolean LogOnEnable;
|
|
public Boolean AmplitudeEnable;
|
|
public Boolean ZeroFlowOffsetEnable;
|
|
public Boolean TempCalEnable;
|
|
public Boolean CompletionEnable;
|
|
public Boolean LoginFailed;
|
|
public Boolean PreparationFailed;
|
|
public Boolean AmplitudeFailed;
|
|
public Boolean ZeroFlowOffsetFailed;
|
|
public Boolean TempCalFailed;
|
|
public Boolean CompletionFailed;
|
|
public Boolean Ok;
|
|
public Boolean EmptyPipeCheckEnable;
|
|
public Boolean EmptyPipeCheckFailed;
|
|
public Boolean MeterSelected;
|
|
|
|
|
|
public CalibrationResult calibrationResult = new CalibrationResult();
|
|
public ConcurrentQueue<CalibrationRecord> CurrentRecords = new ConcurrentQueue<CalibrationRecord>();
|
|
public ZeroFlowGenesisMeter(int Slot, int PathsCount = 3, bool ignorCurruptdata = true) : base()
|
|
{
|
|
|
|
base.SetupFromConfigFile(Slot, ignorCurruptdata);
|
|
|
|
|
|
//base.EnableAutoLogon();
|
|
Setup(PathsCount);
|
|
|
|
//on zeroflow every param has to be stored
|
|
Configuration.UseRegisterWatchService = true;
|
|
Configuration.RegisterWatchServiceUrl = Xylem.Common.CommonCore.Configuration.ServiceUrls.RegisterWatchServiceUrl();
|
|
|
|
}
|
|
public ZeroFlowGenesisMeter(int Slot, int PathsCount, PortConfig request, PortConfig streaming, bool ignoreCurrptData) : base()
|
|
{
|
|
base.SetupGenesisMeter(Slot, request, streaming, ignoreCurrptData);
|
|
// base.EnableAutoLogon();
|
|
Setup(PathsCount);
|
|
|
|
//overide register watch service
|
|
//on zeroflow every param has to be stored
|
|
Configuration.UseRegisterWatchService = true;
|
|
|
|
}
|
|
private void Setup(int PathsCount)
|
|
{
|
|
base.LogRawData(true);
|
|
this.GP30LastRegister = new Byte[2] { 0, 0 };
|
|
this.GP30LastPayloadLsb = 0;
|
|
this.GP30LastCommand = 0;
|
|
this.GP30RXPayload = 0;
|
|
this.GP30RequestStarted = false;
|
|
this.GP30RequestFailed = false;
|
|
this.GP30RequestGotAnswer = false;
|
|
this.FirstHitLevelUpPath0 = 0;
|
|
this.FirstHitLevelUpPath1 = 0;
|
|
this.FirstHitLevelUpPath2 = 0;
|
|
this.FirstHitLevelDownPath0 = 0;
|
|
this.FirstHitLevelDownPath1 = 0;
|
|
this.FirstHitLevelDownPath2 = 0;
|
|
this.Starthit = 0;
|
|
this.Amplitude = 0;
|
|
this.Samplerate = 0;
|
|
this.CalibrationFactorPath0 = 0;
|
|
this.CalibrationFactorPath1 = 0;
|
|
this.CalibrationFactorPath2 = 0;
|
|
this.ZeroOffsetPath0 = 0;
|
|
this.ZeroOffsetPath1 = 0;
|
|
this.ZeroOffsetPath2 = 0;
|
|
this.LedMode = 0;
|
|
this.MeterNumber = Slot;
|
|
this.GlobalCulture = CultureInfo.CreateSpecificCulture("en-US");
|
|
this.Gp30LastByte = 0;
|
|
|
|
linesRecived = new MultiPathDataLogContainer<Int64>(PathsCount);
|
|
listOfTotalTimeOfFlightSPerPath = new ActivityCheckMultiPathDataLogContainer<List<Double>>(PathsCount);
|
|
listOfTotalTimeOfFlightSPerPath.Update(null, new List<Double>());
|
|
|
|
BadDataCounterZeroFlowTest = new MultiPathDataLogContainer<Int64>(PathsCount);
|
|
LineCounterZeroFlowTest = new MultiPathDataLogContainer<Int64>(PathsCount);
|
|
AmplitudeValuesUp = new MultiPathDataLogContainer<List<double>>(PathsCount);
|
|
AmplitudeValuesDown = new MultiPathDataLogContainer<List<double>>(PathsCount);
|
|
DeltaTimeOfFlightAverage = new MultiPathDataLogContainer<List<double>>(PathsCount);
|
|
Decoded = new MultiPathDataLogContainer<CalibrationRecord>(PathsCount);
|
|
}
|
|
|
|
public Boolean CheckStreamingPort()
|
|
{
|
|
if (!StreamingPort.IsOpen())
|
|
{
|
|
base.StreamingPort.Open();
|
|
}
|
|
return StreamingPort.IsOpen();
|
|
}
|
|
public Boolean CheckRequestPort()
|
|
{
|
|
if (!RequestPort.IsOpen())
|
|
{
|
|
base.RequestPort.Open();
|
|
}
|
|
return RequestPort.IsOpen();
|
|
}
|
|
public void StartRecordData(int zeroflowOffsetTestNumberOfLines = 0)
|
|
{
|
|
CurrentRecords.Clear();
|
|
StreamingProtocol.OnRecordIsDecoded += StreamingProtocol_OnRecordIsDecoded; ;
|
|
SyncStreamingBuffer(SyncMarkRecord.DecodeEveryPackage);
|
|
ZeroflowOffsetTestNumberOfLines = zeroflowOffsetTestNumberOfLines;
|
|
}
|
|
private List<string> logContent = new List<String>();
|
|
|
|
public ActivityCheckMultiPathDataLogContainer<List<double>> listOfTotalTimeOfFlightSPerPath;
|
|
private MultiPathDataLogContainer<Int64> linesRecived;
|
|
|
|
private MultiPathDataLogContainer<Int64> BadDataCounterZeroFlowTest;
|
|
private MultiPathDataLogContainer<Int64> LineCounterZeroFlowTest;
|
|
private MultiPathDataLogContainer<List<double>> AmplitudeValuesUp;
|
|
private MultiPathDataLogContainer<List<double>> AmplitudeValuesDown;
|
|
private MultiPathDataLogContainer<List<double>> DeltaTimeOfFlightAverage;
|
|
|
|
private MultiPathDataLogContainer<CalibrationRecord> Decoded;
|
|
internal void DataLog(string text)
|
|
{
|
|
logContent.Add(text);
|
|
//todo nlog!
|
|
}
|
|
private void StreamingProtocol_OnRecordIsDecoded(object sender, BaseDataEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (e is CalibDataEventArgs)
|
|
{
|
|
|
|
var decodedDate = (CalibDataEventArgs)e;
|
|
var data = decodedDate.CalibChl;
|
|
if (Slot == 10 && data.Channel == 2)
|
|
{
|
|
String time = DateTime.Now.ToString(Formats.RawDataDateTimeLogString);
|
|
DataLog($"{time} {decodedDate.RawData}\n");
|
|
}
|
|
CurrentRecords.Enqueue(data);
|
|
//todo make new imesturementrecord according to units need by zeroflow app
|
|
var TotalTimeOfFlightS = data.TotalTimeOfFlightS * 1000000;
|
|
Double temp = data.DeltaTimeOfFlightS;
|
|
//data.DeltaTimeOfFlightS = data.DeltaTimeOfFlightS * (1.0 / 0x4000000000); // 2^38;
|
|
data.AmplitudeUpV = data.AmplitudeUpV * 1000.0;
|
|
data.AmplitudeDownV = data.AmplitudeDownV * 1000.0;
|
|
|
|
#region Logging (Zero flow test)
|
|
if (logZeroFlow || logAmpTest)
|
|
{
|
|
String time = DateTime.Now.ToString(Formats.RawDataDateTimeLogString);
|
|
DataLog($"{time} {decodedDate.RawData}\n");
|
|
|
|
}
|
|
#endregion
|
|
#region Add to list h-protocol
|
|
UInt16 Path = (UInt16)(decodedDate.CalibChl.Channel - 1);
|
|
//todo check if isValid == crc Ok
|
|
if (decodedDate.CalibChl.IsValid)
|
|
{
|
|
#region Activity check for empty pipe test
|
|
linesRecived.Update(Path, linesRecived.Get(Path) + 1);
|
|
#endregion
|
|
|
|
#region Data for amplitude test
|
|
|
|
if (logAmpTest)
|
|
{
|
|
DataLog($"Add {TotalTimeOfFlightS} for chnl {Path}\n");
|
|
var tmp = listOfTotalTimeOfFlightSPerPath.Get(Path).ToList();
|
|
tmp.Add(TotalTimeOfFlightS);
|
|
listOfTotalTimeOfFlightSPerPath.Update(Path, tmp);
|
|
}
|
|
#endregion
|
|
#region Data for zero flow test
|
|
|
|
var meterDone = true;
|
|
|
|
for (int i = 0; i < LineCounterZeroFlowTest.GetPathCount(); i++)
|
|
{
|
|
if (LineCounterZeroFlowTest.Get(i) < ZeroflowOffsetTestNumberOfLines)
|
|
{
|
|
meterDone = false;
|
|
}
|
|
}
|
|
|
|
if (meterDone)
|
|
{
|
|
CalculationIndicatorZeroFlowTest = false;
|
|
LoggingIndicatorZeroFlowTest = false;
|
|
}
|
|
if (CalculationIndicatorZeroFlowTest)
|
|
{
|
|
#region Bad data check
|
|
if (decodedDate.CalibChl.Validation == DataErrorCodes.NoError)
|
|
{
|
|
AmplitudeValuesUp.Get(Path).Add(decodedDate.CalibChl.AmplitudeUpV);
|
|
AmplitudeValuesDown.Get(Path).Add(decodedDate.CalibChl.AmplitudeDownV);
|
|
DeltaTimeOfFlightAverage.Get(Path).Add(decodedDate.CalibChl.DeltaTimeOfFlightS);
|
|
|
|
LineCounterZeroFlowTest.Update(Path, LineCounterZeroFlowTest.Get(Path) + 1);
|
|
}
|
|
else
|
|
{
|
|
BadDataCounterZeroFlowTest.Update(Path, BadDataCounterZeroFlowTest.Get(Path) + 1);
|
|
}
|
|
#endregion
|
|
}
|
|
#endregion
|
|
}
|
|
#endregion
|
|
#region Copy to global object
|
|
Decoded.Update(Path, data);
|
|
#endregion
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
DataLog($"Exception occur {e}\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
public void StopRecordData()
|
|
{
|
|
StreamingProtocol.OnRecordIsDecoded -= StreamingProtocol_OnRecordIsDecoded;
|
|
SyncStreamingBuffer(SyncMarkRecord.SkipDecoding);
|
|
}
|
|
|
|
internal void Flush()
|
|
{
|
|
if (StreamingPort == null)
|
|
{
|
|
throw new ApplicationException("Synchronization not possible due to undefined streaming port");
|
|
}
|
|
SyncStreamingBuffer(SyncMarkRecord.FlushBuffer);
|
|
}
|
|
|
|
|
|
|
|
public new Boolean WriteRegisterUnsafe<T>(string reg, T value)
|
|
{
|
|
var RetrysLeft = 8;
|
|
|
|
|
|
while (RetrysLeft >= 0)
|
|
{
|
|
try
|
|
{
|
|
|
|
var result = base.WriteRegister(reg, value, true, false);
|
|
if (result)
|
|
{
|
|
return result;
|
|
}
|
|
Thread.Sleep(1500);
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
base.WriteLog($"Can not WriteRegisterUnsafe retry left: {RetrysLeft}, message: {e.Message}");
|
|
}
|
|
RetrysLeft = RetrysLeft - 1;
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
public new Boolean WriteRegisterSafe<T>(string reg, T value)
|
|
{
|
|
var RetrysLeft = 8;
|
|
|
|
|
|
while (RetrysLeft >= 0)
|
|
{
|
|
try
|
|
{
|
|
var result = base.WriteRegister(reg, value, true, true);
|
|
if (result)
|
|
{
|
|
return result;
|
|
}
|
|
Thread.Sleep(1500);
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
base.WriteLog($"Can not WriteRegisterUnsafe retry left: {RetrysLeft}, message: {e.Message}");
|
|
}
|
|
RetrysLeft = RetrysLeft - 1;
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
public new Byte[] ReadRegister(string reg)
|
|
{
|
|
|
|
|
|
var RetrysLeft = 8;
|
|
|
|
Exception lastEx = null;
|
|
while (RetrysLeft >= 0)
|
|
{
|
|
|
|
try
|
|
{
|
|
return base.ReadRegister(reg);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
lastEx = e;
|
|
base.WriteLog($"Can not WriteRegisterUnsafe retry left: {RetrysLeft}, message: {e.Message}");
|
|
}
|
|
Thread.Sleep(1500);
|
|
RetrysLeft = RetrysLeft - 1;
|
|
}
|
|
|
|
if (lastEx == null)
|
|
{
|
|
throw new ApplicationException("something went totally wrong on ReadRegister. no Exception found");
|
|
}
|
|
throw new ApplicationException($"something went wrong on ReadRegister.Message{lastEx.Message}");
|
|
|
|
}
|
|
|
|
|
|
}
|
|
}
|