505 lines
19 KiB
C#
505 lines
19 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.Protocols.StreamingProtocol;
|
|
|
|
namespace DynamicStremingLogAnalyzer
|
|
{
|
|
internal class PathOffsetBag
|
|
{
|
|
public int Path { get; set; }
|
|
public int CurrentOffsetValue { get; set; }
|
|
public List<double> DeltaTimeOfFlightS { get; set; }
|
|
public int indexOflastChange { get; set; }
|
|
|
|
}
|
|
|
|
internal class MeterBag
|
|
{
|
|
public MeterBag()
|
|
{
|
|
LedFiles = new Dictionary<string, List<string>>();
|
|
LogFiles = new Dictionary<string, List<string>>();
|
|
}
|
|
public string SerialNumber { get; set; }
|
|
public string PcbID { get; set; }
|
|
|
|
public Dictionary<string, List<string>> LedFiles;
|
|
public Dictionary<string, List<string>> LogFiles;
|
|
|
|
public List<OffsetRun> OffsetRuns = new List<OffsetRun>();
|
|
|
|
// public List<AmpRun> AmpRuns = new List<AmpRun>();
|
|
public List<CompRun> CompRuns = new List<CompRun>();
|
|
|
|
//public List<TestRun> TestRuns = new List<TestRun>();
|
|
|
|
//public List<PathOffsetBag> PathOffsets { get; set; }
|
|
|
|
//public bool MeterValid { get; set; } = true;
|
|
}
|
|
|
|
|
|
|
|
public class AmpRun
|
|
{
|
|
public DateTime? Start;
|
|
public DateTime? End;
|
|
|
|
public int? FirstHitPercent1;
|
|
public int? FirstHitPercent2;
|
|
public int? FirstHitPercent3;
|
|
|
|
public List<CalibrationRecord> Chnl1 = new List<CalibrationRecord>();
|
|
public List<CalibrationRecord> Chnl2 = new List<CalibrationRecord>();
|
|
public List<CalibrationRecord> Chnl3 = new List<CalibrationRecord>();
|
|
|
|
public int TotalLineCount { get; internal set; }
|
|
|
|
public void Calc()
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
public enum Stage
|
|
{
|
|
Login,
|
|
FirstFlush,
|
|
Preparation,
|
|
Amp,
|
|
SecondFlush,
|
|
Temp,
|
|
Offset,
|
|
}
|
|
public class CompRun
|
|
{
|
|
public DateTime? Start;// Login sequence Login sequence successful
|
|
public DateTime? Flush;//First Flush procedure started
|
|
public DateTime? Preparation;//Preparation procedure started
|
|
public DateTime? StartAmp;//Amplitude Test procedure started
|
|
public DateTime? FlushSecond;//Amplitude Test sequence successful at all
|
|
public DateTime? StartTemp;//Temperature Calibration procedure started
|
|
public DateTime? StartOffset;//Temperature Calibration sequence successful at all
|
|
public DateTime? End; //Offset Test sequence Offset Test sequence successful at all ;
|
|
|
|
|
|
|
|
|
|
public List<CalibrationRecord> Chnl1 = new List<CalibrationRecord>();
|
|
public List<CalibrationRecord> Chnl2 = new List<CalibrationRecord>();
|
|
public List<CalibrationRecord> Chnl3 = new List<CalibrationRecord>();
|
|
|
|
public int TotalLineCount { get; internal set; }
|
|
|
|
public List<Tuple<DateTimeOffset, Stage, CalibrationRecord>> MatchData()
|
|
{
|
|
var ret = new List<Tuple<DateTimeOffset, Stage, CalibrationRecord>>();
|
|
var matchList = new List<CalibrationRecord>();
|
|
matchList.AddRange(Chnl1);
|
|
matchList.AddRange(Chnl2);
|
|
matchList.AddRange(Chnl3);
|
|
foreach (var item in matchList)
|
|
{
|
|
var matchtime = item.DecodedTime;
|
|
var currentStage = Stage.Login;
|
|
if (matchtime >= Start && matchtime < Flush) { currentStage = Stage.Login; }
|
|
if (matchtime >= Flush && matchtime < Preparation) { currentStage = Stage.FirstFlush; }
|
|
if (matchtime >= Preparation && matchtime < StartAmp) { currentStage = Stage.Preparation; }
|
|
if (matchtime >= StartAmp && matchtime < FlushSecond) { currentStage = Stage.Amp; }
|
|
if (matchtime >= FlushSecond && matchtime < StartTemp) { currentStage = Stage.SecondFlush; }
|
|
if (matchtime >= StartTemp && matchtime < StartOffset) { currentStage = Stage.Temp; }
|
|
if (matchtime >= StartOffset && matchtime < End) { currentStage = Stage.Offset; }
|
|
|
|
|
|
|
|
ret.Add(new Tuple<DateTimeOffset, Stage, CalibrationRecord>(matchtime, currentStage, item));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
}
|
|
|
|
public class OffsetRun
|
|
{
|
|
public DateTime? Start;
|
|
public DateTime? End;
|
|
|
|
public int? Offset1;
|
|
public int? Offset2;
|
|
public int? Offset3;
|
|
|
|
public List<CalibrationRecord> Chnl1 = new List<CalibrationRecord>();
|
|
public List<CalibrationRecord> Chnl2 = new List<CalibrationRecord>();
|
|
public List<CalibrationRecord> Chnl3 = new List<CalibrationRecord>();
|
|
|
|
public List<double> DeltaTimeOfFlightS1 = new List<double>();
|
|
public List<double> DeltaTimeOfFlightS2 = new List<double>();
|
|
public List<double> DeltaTimeOfFlightS3 = new List<double>();
|
|
|
|
public int? CalcOffset1;
|
|
public int? CalcOffset2;
|
|
public int? CalcOffset3;
|
|
|
|
public int TotalLineCount { get; internal set; }
|
|
|
|
public void Calc()
|
|
{
|
|
|
|
var avg = DeltaTimeOfFlightS1.Sum() / DeltaTimeOfFlightS1.Count;
|
|
CalcOffset1 = (Int32)((avg * Math.Pow(2, 40)));
|
|
|
|
avg = DeltaTimeOfFlightS2.Sum() / DeltaTimeOfFlightS2.Count;
|
|
CalcOffset2 = (Int32)((avg * Math.Pow(2, 40)));
|
|
|
|
avg = DeltaTimeOfFlightS3.Sum() / DeltaTimeOfFlightS3.Count;
|
|
CalcOffset3 = (Int32)((avg * Math.Pow(2, 40)));
|
|
}
|
|
|
|
}
|
|
|
|
internal class Program
|
|
{
|
|
private static void Main(string[] args)
|
|
{
|
|
DateTimeOffset timestamp;
|
|
var meters = new List<MeterBag>();
|
|
|
|
foreach (var item in Directory.GetFiles("\\\\sla12file\\Auftrag\\p2016nez\\GenesisLog2\\2025-02-17\\Pruef2000\\", "*_PreAdjustment.log", SearchOption.AllDirectories))
|
|
{
|
|
|
|
|
|
var SerialNumber = item.Substring(item.LastIndexOf("_SN") + 3, item.IndexOf("_PreAdjustment.log") - item.LastIndexOf("_SN") - 3);
|
|
MeterBag meter;
|
|
if (!meters.Any(m => m.SerialNumber == SerialNumber))
|
|
{
|
|
meter = new MeterBag();
|
|
meter.SerialNumber = SerialNumber;
|
|
meters.Add(meter);
|
|
}
|
|
else
|
|
{
|
|
meter = meters.FirstOrDefault(m => m.SerialNumber == SerialNumber);
|
|
}
|
|
|
|
if (item.Contains("LedRawData_"))
|
|
{
|
|
meter.LedFiles.Add(item, File.ReadAllLines(item).ToList());
|
|
}
|
|
else if (item.Contains("Meter_Slot"))
|
|
{
|
|
meter.LogFiles.Add(item, File.ReadAllLines(item).ToList());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var meter in meters)
|
|
{
|
|
foreach (var logfile in meter.LogFiles)
|
|
{
|
|
|
|
var c = new CompRun();
|
|
foreach (var logline in logfile.Value)
|
|
{
|
|
//Start logging at Meter 1 (244230137)
|
|
if (logline.Contains("Login sequence Login sequence successful"))
|
|
{
|
|
if (c.End.HasValue)
|
|
{
|
|
meter.CompRuns.Add(c);
|
|
}
|
|
c = new CompRun();
|
|
DateTime.TryParse(logline.Substring(0, "2023-06-05 17:50:38.3184".Length), out DateTime tmp);
|
|
c.Start = tmp;
|
|
}
|
|
if (c.Start.HasValue && logline.Contains("First Flush procedure started"))
|
|
{
|
|
DateTime.TryParse(logline.Substring(0, "2023-06-05 17:50:38.3184".Length), out DateTime tmp);
|
|
c.Flush = tmp;
|
|
|
|
}
|
|
if (c.Flush.HasValue && logline.Contains("Preparation procedure started"))
|
|
{
|
|
DateTime.TryParse(logline.Substring(0, "2023-06-05 17:50:38.3184".Length), out DateTime tmp);
|
|
c.Preparation = tmp;
|
|
|
|
}
|
|
if (c.Preparation.HasValue && logline.Contains("Amplitude Test procedure started"))
|
|
{
|
|
DateTime.TryParse(logline.Substring(0, "2023-06-05 17:50:38.3184".Length), out DateTime tmp);
|
|
c.StartAmp = tmp;
|
|
|
|
}
|
|
if (c.StartAmp.HasValue && logline.Contains("Amplitude Test sequence successful at all"))
|
|
{
|
|
DateTime.TryParse(logline.Substring(0, "2023-06-05 17:50:38.3184".Length), out DateTime tmp);
|
|
c.FlushSecond = tmp;
|
|
|
|
}
|
|
|
|
if (c.FlushSecond.HasValue && logline.Contains("Temperature Calibration procedure started"))
|
|
{
|
|
DateTime.TryParse(logline.Substring(0, "2023-06-05 17:50:38.3184".Length), out DateTime tmp);
|
|
c.StartTemp = tmp;
|
|
|
|
}
|
|
if (c.StartTemp.HasValue && logline.Contains("Temperature Calibration sequence successful at all"))
|
|
{
|
|
DateTime.TryParse(logline.Substring(0, "2023-06-05 17:50:38.3184".Length), out DateTime tmp);
|
|
c.StartOffset = tmp;
|
|
|
|
}
|
|
if (c.StartOffset.HasValue && logline.Contains("Offset Test sequence Offset Test sequence successful at all"))
|
|
{
|
|
DateTime.TryParse(logline.Substring(0, "2023-06-05 17:50:38.3184".Length), out DateTime tmp);
|
|
c.End = tmp;
|
|
}
|
|
|
|
|
|
}
|
|
if (c.End.HasValue)
|
|
{
|
|
meter.CompRuns.Add(c);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
var StreamingDecode = new StreamingDecoder(false);
|
|
foreach (var ledFile in meter.LedFiles)
|
|
{
|
|
foreach (var line in ledFile.Value)
|
|
{
|
|
|
|
|
|
if (line.Contains('|'))
|
|
{
|
|
if (DateTimeOffset.TryParse(line.Split('|')[0], out timestamp))
|
|
{
|
|
|
|
if (meter.CompRuns.Any(run => run.Start <= timestamp && run.End >= timestamp))
|
|
{
|
|
var currentRun = meter.CompRuns.First(run => run.Start <= timestamp && run.End >= timestamp);
|
|
if (StreamingDecode.DecodeMsg(line.Split('|')[1].Trim()))
|
|
{
|
|
var c = ((CalibrationRecord)StreamingDecode.DataCalib?.Clone());
|
|
if (StreamingDecode.DataCalib != null && c.IsValid)
|
|
{
|
|
c.DecodedTime = timestamp;
|
|
switch (c.Channel)
|
|
{
|
|
case 1:
|
|
currentRun.Chnl1.Add(c);
|
|
break;
|
|
case 2:
|
|
currentRun.Chnl2.Add(c);
|
|
break;
|
|
case 3:
|
|
currentRun.Chnl3.Add(c);
|
|
break;
|
|
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
string sep = ";";
|
|
var sb = new StringBuilder();
|
|
foreach (var meter in meters)
|
|
{
|
|
foreach (var testrun in meter.CompRuns)
|
|
{
|
|
var results = testrun.MatchData();
|
|
sb.AppendLine(meter.SerialNumber);
|
|
|
|
sb.Append("Time").Append(sep);
|
|
sb.Append("Stage").Append(sep);
|
|
sb.Append("Channel").Append(sep);
|
|
sb.Append("Validation").Append(sep);
|
|
sb.Append("TotalTimeOfFlightS").Append(sep);
|
|
sb.Append("DeltaTimeOfFlightS").Append(sep);
|
|
sb.Append("VolumeScaleRawPerMl").Append(sep);
|
|
sb.Append("VolumeFactorRawToQm").Append(sep);
|
|
sb.Append("DeltaVolumeRaw").Append(sep);
|
|
sb.Append("DeltaVolumeQm").Append(sep);
|
|
sb.Append("AccuVolumeRaw").Append(sep);
|
|
sb.Append("VolumeCm").Append(sep);
|
|
sb.Append("OverflowVolumeCm").Append(sep);
|
|
sb.Append("SampleIntervalS").Append(sep);
|
|
sb.Append("AmplitudeUpV").Append(sep);
|
|
sb.Append("AmplitudeDownV").Append(sep);
|
|
sb.Append("PulseWidthRatioUp").Append(sep);
|
|
sb.Append("PulseWidthRatioDown").Append(sep);
|
|
sb.Append("TemperatureRaw").Append(sep);
|
|
sb.Append("TemperaturePowFactor").Append(sep);
|
|
sb.Append("TemperatureDegC").Append(sep);
|
|
sb.Append("TimeS").Append(sep);
|
|
sb.Append("OverflowTimeS").Append(sep);
|
|
sb.Append("Crc").Append(sep);
|
|
sb.Append("IsValid").Append(sep);
|
|
|
|
|
|
foreach (var logI in results)
|
|
{
|
|
var h = logI.Item3;
|
|
sb.Append(logI.Item1).Append(sep);
|
|
sb.Append(logI.Item2).Append(sep);
|
|
sb.Append(h.Channel).Append(sep);
|
|
sb.Append(h.Validation).Append(sep);
|
|
sb.Append(h.TotalTimeOfFlightS).Append(sep);
|
|
sb.Append(h.DeltaTimeOfFlightS).Append(sep);
|
|
sb.Append(h.VolumeScaleRawPerMl).Append(sep);
|
|
sb.Append(h.VolumeFactorRawToQm).Append(sep);
|
|
sb.Append(h.DeltaVolumeRaw).Append(sep);
|
|
sb.Append(h.DeltaVolumeQm).Append(sep);
|
|
sb.Append(h.AccuVolumeRaw).Append(sep);
|
|
sb.Append(h.VolumeCm).Append(sep);
|
|
sb.Append(h.OverflowVolumeCm).Append(sep);
|
|
sb.Append(h.SampleIntervalS).Append(sep);
|
|
sb.Append(h.AmplitudeUpV).Append(sep);
|
|
sb.Append(h.AmplitudeDownV).Append(sep);
|
|
sb.Append(h.PulseWidthRatioUp).Append(sep);
|
|
sb.Append(h.PulseWidthRatioDown).Append(sep);
|
|
sb.Append(h.TemperatureRaw).Append(sep);
|
|
sb.Append(h.TemperaturePowFactor).Append(sep);
|
|
sb.Append(h.TemperatureDegC).Append(sep);
|
|
sb.Append(h.TimeS).Append(sep);
|
|
sb.Append(h.OverflowTimeS).Append(sep);
|
|
sb.Append(h.Crc).Append(sep);
|
|
sb.Append(h.IsValid).Append(sep);
|
|
sb.AppendLine("");
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
File.AppendAllLines($"{meter.SerialNumber}_offset.CSV", new[] { sb.ToString() });
|
|
sb = new StringBuilder();
|
|
}
|
|
|
|
|
|
|
|
Console.ReadLine();
|
|
|
|
|
|
////Meter_SlotSlot_2_SN23706764_PreAdjustment
|
|
//meter.PathOffsets.Add(new PathOffsetBag() { Path = 1, CurrentOffsetValue = 0, indexOflastChange = 0, DeltaTimeOfFlightS = new List<double>() });
|
|
// meter.PathOffsets.Add(new PathOffsetBag() { Path = 2, CurrentOffsetValue = 0, indexOflastChange = 0, DeltaTimeOfFlightS = new List<double>() });
|
|
// meter.PathOffsets.Add(new PathOffsetBag() { Path = 3, CurrentOffsetValue = 0, indexOflastChange = 0, DeltaTimeOfFlightS = new List<double>() });
|
|
|
|
|
|
// var directoryName = Path.GetDirectoryName(item);
|
|
|
|
|
|
// //LedRawData__Slot_10_SN23706763_PreAdjustment.log
|
|
// File.Exists(directoryName + "\\Meter_SlotSlot_2_SN23706764_PreAdjustment.log");
|
|
|
|
|
|
|
|
// DateTimeOffset? Start = null;
|
|
//
|
|
// foreach (var line in File.ReadAllLines(item))
|
|
// {
|
|
|
|
|
|
// meters.Add(meter);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
//foreach (var removeLineMeter in meters)
|
|
//{
|
|
// for (int i = 1; i <= 3; i++)
|
|
// {
|
|
// var cList = removeLineMeter.PathOffsets.Find(f => f.Path == i);
|
|
// if (cList.DeltaTimeOfFlightS.Count > 27000)
|
|
// {
|
|
// cList.DeltaTimeOfFlightS.RemoveRange(0, cList.DeltaTimeOfFlightS.Count - 27000);
|
|
// }
|
|
// else
|
|
// {
|
|
// removeLineMeter.MeterValid = false;
|
|
// }
|
|
// }
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
//foreach (var calcMeter in meters.Where(m => m.MeterValid))
|
|
//{
|
|
// foreach (var pOffset in calcMeter.PathOffsets)
|
|
// {
|
|
// List<double> CalculatedOffsets = new List<double>();
|
|
|
|
// foreach (var currentOffset in pOffset.DeltaTimeOfFlightS)
|
|
// {
|
|
// CalculatedOffsets.Add(currentOffset);
|
|
|
|
// var avg = CalculatedOffsets.Sum() / CalculatedOffsets.Count;
|
|
// var OffsetValue = (Int32)((avg * Math.Pow(2, 40)));
|
|
// if (pOffset.CurrentOffsetValue != OffsetValue)
|
|
// {
|
|
// pOffset.CurrentOffsetValue = OffsetValue;
|
|
// pOffset.indexOflastChange = CalculatedOffsets.Count;
|
|
// }
|
|
// else
|
|
// {
|
|
|
|
// }
|
|
// }
|
|
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//var sb = new StringBuilder();
|
|
|
|
//foreach (var PrintMeter in meters.Where(m => m.MeterValid))
|
|
//{
|
|
|
|
// Console.WriteLine(PrintMeter.SerialNumber);
|
|
// foreach (var pOffset in PrintMeter.PathOffsets)
|
|
// {
|
|
// Console.WriteLine($"{pOffset.Path} = {pOffset.indexOflastChange}");
|
|
// }
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
//\Pruef2000
|
|
}
|
|
}
|
|
}
|