908 lines
31 KiB
C#
908 lines
31 KiB
C#
using CordonelPreadjustmentUi;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.Data.SqlClient;
|
|
using System.Drawing;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.IO.Pipes;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Timers;
|
|
using System.Windows.Forms;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords;
|
|
using Xylem.Common.Hardware.WaterMeter.Genesis.Registers;
|
|
using Xylem.Common.Hardware.WaterMeter.WaterMeterCore;
|
|
using Xylem.Common.Logic.ServiceCore;
|
|
using Xylem.Common.Logic.SoftwareAccessHelper;
|
|
using Xylem.Common.Ui.GenesisToolBox.Infrastructure;
|
|
using Watcher = System.Timers.Timer;
|
|
|
|
namespace Xylem.Common.Ui.GenesisToolBox
|
|
{
|
|
public partial class FrmTempMeter : Form
|
|
{
|
|
public class CordonelTempLut
|
|
{
|
|
public Int32 Id { get; set; }
|
|
public Int32 PcbId { get; set; }
|
|
public Double RefTempC { get; set; }
|
|
public Double AvgTof { get; set; }
|
|
|
|
public Boolean Active { get; set; }
|
|
|
|
|
|
}
|
|
public class LutTemp
|
|
{
|
|
public Int32 PcbId { get; set; }
|
|
public Int32 FromTempC { get; set; }
|
|
public Int32 ToTempC { get; set; }
|
|
public Double? AvgRefTempC { get; set; }
|
|
public List<Double> ListOfRecordedTofs { get; set; }
|
|
public Double? AvgTofs { get; set; }
|
|
}
|
|
|
|
|
|
|
|
public FrmTempMeter()
|
|
{
|
|
InitializeComponent();
|
|
SetEnabled(ProgrammState.Start);
|
|
}
|
|
|
|
public ZeroFlowGenesisMeter _currentGenesis { get; private set; }
|
|
public MeterBatch _meterBatch { get; private set; }
|
|
|
|
|
|
private void btnConnect_Click(Object sender, EventArgs e)
|
|
{
|
|
Connect();
|
|
}
|
|
|
|
private void Connect()
|
|
{
|
|
try
|
|
{
|
|
Int32 slotNr;
|
|
|
|
if (string.IsNullOrEmpty(cbComSlot.SelectedItem.ToString()) ||
|
|
!int.TryParse(cbComSlot.SelectedItem.ToString(), out slotNr))
|
|
{
|
|
return;
|
|
}
|
|
//var drive = 1;
|
|
_currentGenesis?.DisposeMeter();
|
|
//dispose old meter
|
|
_meterBatch = new MeterBatch();
|
|
_currentGenesis = null;
|
|
Thread.Sleep(200);
|
|
|
|
//assign new meter and assign meter to FW update file if this exists
|
|
_currentGenesis = new ZeroFlowGenesisMeter(slotNr, 3, false);
|
|
|
|
//_currentGenesis.SetupFromConfigFile(slotNr);
|
|
_meterBatch.AddMeter(_currentGenesis);
|
|
|
|
Task.Factory.StartNew(() =>
|
|
{
|
|
_meterBatch.MetersLogin();
|
|
|
|
if (!_currentGenesis.IsLoggedOn)
|
|
{
|
|
Thread.Sleep(2000);
|
|
_meterBatch.MetersLogin();
|
|
}
|
|
|
|
if (!_currentGenesis.IsLoggedOn)
|
|
{
|
|
SetEnabled(ProgrammState.Start);
|
|
return;
|
|
}
|
|
|
|
|
|
var a = GetLutsText(_currentGenesis.PcbId);
|
|
//
|
|
_currentGenesis.InitMeasurement();
|
|
Invoke(new Action(() =>
|
|
{
|
|
|
|
txtLuts.Text = a;
|
|
if (LutsMissing)
|
|
{
|
|
txtLuts.BackColor = Color.IndianRed;
|
|
}
|
|
else
|
|
{
|
|
txtLuts.BackColor = Color.LightGreen;
|
|
}
|
|
lblPcbId.Text = _currentGenesis.PcbId;
|
|
SetEnabled(ProgrammState.Connected);
|
|
|
|
}));
|
|
});//.ContinueWith(delegate { ViewProgressPcb(false); });
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
txtLuts.Text = "-";
|
|
MessageBox.Show(ex.Message);
|
|
SetEnabled(ProgrammState.Start);
|
|
}
|
|
}
|
|
|
|
private void btnRefreshLut_Click(Object sender, EventArgs e)
|
|
{
|
|
if (!string.IsNullOrEmpty(_currentGenesis?.PcbId))
|
|
{
|
|
|
|
Task.Factory.StartNew(() =>
|
|
{
|
|
var a = GetLutsText(_currentGenesis.PcbId);
|
|
|
|
Invoke(new Action(() =>
|
|
{
|
|
txtLuts.Text = a;
|
|
if (LutsMissing)
|
|
{
|
|
txtLuts.BackColor = Color.IndianRed;
|
|
}
|
|
else
|
|
{
|
|
txtLuts.BackColor = Color.LightGreen;
|
|
}
|
|
}));
|
|
});
|
|
}
|
|
else
|
|
{
|
|
txtLuts.Text = "-";
|
|
}
|
|
|
|
}
|
|
public class RefTempRange
|
|
{
|
|
public Double Min { get; set; }
|
|
public Double Max { get; set; }
|
|
}
|
|
private List<RefTempRange> ReftempRangeReq = new List<RefTempRange>()
|
|
{
|
|
new RefTempRange() { Min = 7, Max= 9 },
|
|
new RefTempRange() { Min = 13,Max = 15 },
|
|
new RefTempRange() { Min = 16,Max = 18 },
|
|
new RefTempRange() { Min = 19,Max = 20 },
|
|
new RefTempRange() { Min = 20,Max = 22 },
|
|
new RefTempRange() { Min = 23,Max = 25 },
|
|
new RefTempRange() { Min = 26,Max = 28 },
|
|
new RefTempRange() { Min = 28,Max = 30 },
|
|
new RefTempRange() { Min = 33,Max = 36 },
|
|
};
|
|
private List<CordonelTempLut> cordonelTempLut = null;
|
|
private Boolean LutsMissing = false;
|
|
private String GetLutsText(String PcbId)
|
|
{
|
|
var ret = new StringBuilder();
|
|
var err = 0;
|
|
var resp = LocalWebRequest.GetRequest($"http://10.49.40.25/MeterProcessState/api/TempFlange/GetLut?PcbId={PcbId}");
|
|
|
|
ret.AppendLine($"Ref Temp C°\t|\t AvgTof");
|
|
|
|
var CurrentReqRequierd = new List<RefTempRange>();
|
|
CurrentReqRequierd.AddRange(ReftempRangeReq);
|
|
try
|
|
{
|
|
cordonelTempLut = JsonConvert.DeserializeObject<List<CordonelTempLut>>(resp);
|
|
|
|
foreach (var item in cordonelTempLut.OrderBy(a => a.RefTempC))
|
|
{
|
|
CurrentReqRequierd.RemoveAll(rem => item.RefTempC >= rem.Min && item.RefTempC <= rem.Max);
|
|
ret.AppendLine($"{item.RefTempC.ToString("n8")}\t|\t{item.AvgTof}");
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
|
|
ret.AppendLine($"No entrys");
|
|
}
|
|
|
|
LutsMissing = false;
|
|
foreach (var item in CurrentReqRequierd)
|
|
{
|
|
LutsMissing = true;
|
|
ret.AppendLine($"{item.Min}-{item.Max}\t|\t Missing");
|
|
}
|
|
return ret.ToString();
|
|
}
|
|
|
|
private ProgrammState State = ProgrammState.Start;
|
|
|
|
private enum ProgrammState
|
|
{
|
|
Start,
|
|
Connected,
|
|
RecordRuning,
|
|
RecordStoped,
|
|
RecodCalculated,
|
|
}
|
|
|
|
private void SetEnabled(ProgrammState state)
|
|
{
|
|
this.State = state;
|
|
|
|
switch (State)
|
|
{
|
|
case ProgrammState.Start:
|
|
this.btnStartRecord.Enabled = false;
|
|
this.btnStopRecord.Enabled = false;
|
|
this.btnAddLut.Enabled = false;
|
|
this.nudRef.Visible = false;
|
|
this.btnRefreshLut.Enabled = false;
|
|
this.StartAutomaticalyCalibrationBtn.Enabled = false;
|
|
this.StopAutomaticalCalibrationBtn.Enabled = false;
|
|
this.UpdateGridBtn.Enabled = false;
|
|
break;
|
|
case ProgrammState.Connected:
|
|
this.btnStartRecord.Enabled = true;
|
|
this.btnStopRecord.Enabled = false;
|
|
this.btnAddLut.Enabled = false;
|
|
this.nudRef.Visible = false;
|
|
this.btnRefreshLut.Enabled = true;
|
|
this.StartAutomaticalyCalibrationBtn.Enabled = true;
|
|
this.StopAutomaticalCalibrationBtn.Enabled = false;
|
|
this.UpdateGridBtn.Enabled = true;
|
|
break;
|
|
case ProgrammState.RecordRuning:
|
|
this.btnStartRecord.Enabled = false;
|
|
this.btnStopRecord.Enabled = true;
|
|
this.btnAddLut.Enabled = false;
|
|
this.nudRef.Visible = false;
|
|
this.btnRefreshLut.Enabled = true;
|
|
this.StartAutomaticalyCalibrationBtn.Enabled = false;
|
|
this.StopAutomaticalCalibrationBtn.Enabled = true;
|
|
this.UpdateGridBtn.Enabled = true;
|
|
break;
|
|
case ProgrammState.RecordStoped:
|
|
this.btnStartRecord.Enabled = true;
|
|
this.btnStopRecord.Enabled = false;
|
|
this.btnAddLut.Enabled = true;
|
|
this.nudRef.Visible = true;
|
|
this.btnRefreshLut.Enabled = true;
|
|
this.StartAutomaticalyCalibrationBtn.Enabled = true;
|
|
this.StopAutomaticalCalibrationBtn.Enabled = false;
|
|
this.UpdateGridBtn.Enabled = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
public void tmp()
|
|
{
|
|
|
|
//var cRecords = _currentGenesis.CurrentRecords.ToList();
|
|
//Log($"cRecords.Count={cRecords.Count}");
|
|
//if (cRecords != null && cRecords.Any())
|
|
//{
|
|
// decimal checkTempMeter = 0;
|
|
// if (MeterTempMode == TempMode.CalcTof)
|
|
// {
|
|
// //
|
|
|
|
// var sumTof = 0.0;
|
|
// var countTof = 0;
|
|
// foreach (var tofItem in cRecords.Where(c => c.Channel == 2))
|
|
// {
|
|
|
|
|
|
// if (tofItem.Channel == 2)
|
|
// {
|
|
// Log($"TotalTimeOfFlightS;{(tofItem.TotalTimeOfFlightS * 1000).ToString()}");
|
|
// Log($"RAWTEMP;{interPol(TempFromTofLUT, (tofItem.TotalTimeOfFlightS * 1000))}");
|
|
// sumTof = (tofItem.TotalTimeOfFlightS * 1000) + sumTof;
|
|
// countTof = countTof + 1;
|
|
// }
|
|
|
|
// }
|
|
|
|
// var x = (sumTof / countTof) / 1000;
|
|
|
|
|
|
// Log($"avgTof;{x}({sumTof}/{countTof})");
|
|
|
|
|
|
// checkTempMeter = interPol(TempFromTofLUT, x);
|
|
// Meter.CurrentRecords.Clear();
|
|
// }
|
|
// else
|
|
// {
|
|
// checkTempMeter = (decimal)cRecords.Last().TemperatureDegC;
|
|
// }
|
|
//}
|
|
}
|
|
|
|
private DateTimeOffset start;
|
|
private Task tempTask;
|
|
|
|
private void BtnStartRecord_Click(Object sender, EventArgs e)
|
|
{
|
|
automatic = false;
|
|
start = DateTimeOffset.Now;
|
|
_currentGenesis.StartRecordData();
|
|
_currentGenesis.WriteRegister<Byte>(Register.Genesisflow.SampleRate, 16, checkRegister: true);
|
|
SetEnabled(ProgrammState.RecordRuning);
|
|
timer2.Enabled = true;
|
|
|
|
}
|
|
|
|
private void BtnStopRecord_Click(Object sender, EventArgs e)
|
|
{
|
|
timer2.Enabled = false;
|
|
OutputAvgTof(true);
|
|
_currentGenesis.WriteRegister<Byte>(Register.Genesisflow.SampleRate, 0, checkRegister: true);
|
|
SetEnabled(ProgrammState.RecordStoped);
|
|
|
|
}
|
|
|
|
private void btnAddLut_Click(Object sender, EventArgs e)
|
|
{
|
|
|
|
var req = LocalWebRequest.PostRequestAsync($"http://10.49.40.25/MeterProcessState/api/TempFlange/AddLut?PcbId={_currentGenesis.PcbId}&RefTempC={nudRef.Value.ToString().Replace(",", ".")}&AvgTof={lblAvgDutTof.Text.Replace(",", ".")}");
|
|
|
|
|
|
SetEnabled(ProgrammState.Connected);
|
|
}
|
|
|
|
private void btnCheck_Click(Object sender, EventArgs e)
|
|
{
|
|
if (btnCheck.Text == "Start Check")
|
|
{
|
|
_currentGenesis.StartRecordData();
|
|
timer1.Enabled = true;
|
|
|
|
btnCheck.Text = "Stop Check";
|
|
}
|
|
else
|
|
{
|
|
|
|
_currentGenesis.StopRecordData();
|
|
timer1.Enabled = false;
|
|
btnCheck.Text = "Start Check";
|
|
}
|
|
}
|
|
|
|
private static Decimal interPol(List<CordonelTempLut> points, Double x)
|
|
{
|
|
var x1 = 0.000;
|
|
var y1 = 0.000;
|
|
var x2 = 0.000;
|
|
var y2 = 0.000;
|
|
Decimal checkTempMeter;
|
|
if ((x <= points[0].AvgTof) && (x >= points.Last().AvgTof))
|
|
{
|
|
var i = 0;
|
|
foreach (var val in points)
|
|
{
|
|
if (points[i].AvgTof <= x)
|
|
{
|
|
x1 = points[i - 1].AvgTof;
|
|
y1 = points[i - 1].RefTempC;
|
|
x2 = points[i].AvgTof;
|
|
y2 = points[i].RefTempC;
|
|
break;
|
|
}
|
|
i = i + 1;
|
|
}
|
|
|
|
checkTempMeter = (Decimal)((y2 - y1) / (x2 - x1) * (x - x1) + y1);
|
|
}
|
|
else
|
|
{
|
|
checkTempMeter = 1;
|
|
}
|
|
|
|
return checkTempMeter;
|
|
}
|
|
|
|
private void timer1_Tick(Object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
|
|
var cRecords = _currentGenesis.CurrentRecords.ToList();
|
|
|
|
|
|
if (cRecords != null && cRecords.Any())
|
|
{
|
|
Decimal checkTempMeter = 0;
|
|
|
|
//
|
|
|
|
var sumTof = 0.0;
|
|
var countTof = 0;
|
|
foreach (var tofItem in cRecords.Where(c => c.Channel == 2))
|
|
{
|
|
|
|
|
|
if (tofItem.Channel == 2)
|
|
{
|
|
sumTof = (tofItem.TotalTimeOfFlightS * 1000) + sumTof;
|
|
countTof = countTof + 1;
|
|
}
|
|
|
|
}
|
|
|
|
var x = (sumTof / countTof) / 1000;
|
|
|
|
checkTempMeter = interPol(cordonelTempLut, x);
|
|
|
|
var a = new Hardware.WaterMeter.Genesis.DataPackages.MeasurementRecords.CalibrationRecord();
|
|
while (_currentGenesis.CurrentRecords.TryDequeue(out a))
|
|
{
|
|
// do nothing
|
|
}
|
|
|
|
lblCheck.Text = checkTempMeter.ToString();
|
|
|
|
}
|
|
else
|
|
{
|
|
lblCheck.Text = $"temp NA";
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
lblCheck.Text = $"temp NA - {ex.Message}";
|
|
|
|
}
|
|
}
|
|
|
|
private void timer2_Tick(Object sender, EventArgs e)
|
|
{
|
|
if (State == ProgrammState.RecordRuning)
|
|
{
|
|
if (automatic)
|
|
{
|
|
|
|
}
|
|
else
|
|
{
|
|
OutputAvgTof();
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
private double OutputAvgTof(Boolean stop = false)
|
|
{
|
|
var avgToF = default(double);
|
|
|
|
try
|
|
{
|
|
StringBuilder cTofs = new StringBuilder();
|
|
var listOfRec = _currentGenesis.CurrentRecords.Where(s => s.Channel == 2).ToList();
|
|
|
|
if (stop)
|
|
{
|
|
_currentGenesis.StopRecordData();
|
|
}
|
|
|
|
var list = listOfRec.Select(s => new { ToF = s.TotalTimeOfFlightS * 1000, Channel = s.Channel });
|
|
foreach (var item in list.OrderBy(o => o.Channel))
|
|
{
|
|
cTofs.Append(item.Channel);
|
|
cTofs.Append(":");
|
|
cTofs.AppendLine((item.ToF / 1000).ToString());
|
|
}
|
|
|
|
avgToF = (list.Average(s => s.ToF) / 1000);
|
|
|
|
lblAvgDutTof.Text = avgToF.ToString();
|
|
txtCurrentTofs.Text = cTofs.ToString();
|
|
lblLines.Text = list.Count().ToString(); ;
|
|
lblDuration.Text = $"{(DateTimeOffset.Now - start).TotalSeconds}S";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
txtCurrentTofs.Text = ex.Message;
|
|
|
|
}
|
|
|
|
return avgToF;
|
|
}
|
|
|
|
private class TempTime
|
|
{
|
|
public TempTime(Double temp)
|
|
{
|
|
date = DateTime.UtcNow;
|
|
Temp = temp;
|
|
}
|
|
|
|
public TempTime(String temp)
|
|
{
|
|
Double tmp = double.MinValue;
|
|
if (double.TryParse(temp, out tmp))
|
|
{
|
|
date = DateTime.UtcNow;
|
|
|
|
Temp = tmp;
|
|
}
|
|
}
|
|
|
|
public DateTime date;
|
|
public Double Temp;
|
|
}
|
|
|
|
private class ToFTime
|
|
{
|
|
public ToFTime(Double temp, DateTimeOffset date)
|
|
{
|
|
Date = date.ToUniversalTime().DateTime;
|
|
Tof = temp;
|
|
}
|
|
|
|
public DateTime Date;
|
|
public Double Tof;
|
|
}
|
|
|
|
private ConcurrentQueue<TempTofCalc> listTempTime = new ConcurrentQueue<TempTofCalc>();
|
|
|
|
private void RunTemConnection()
|
|
{
|
|
using (var pipeClient = new NamedPipeClientStream(".", "TempPipe", PipeDirection.In))
|
|
{
|
|
// Connect to the pipe or wait until the pipe is available.
|
|
//Console.Write("Attempting to connect to pipe...");
|
|
pipeClient.Connect();
|
|
|
|
//Console.WriteLine("Connected to pipe.");
|
|
//Console.WriteLine("There are currently {0} pipe server instances open.",
|
|
// pipeClient.NumberOfServerInstances);
|
|
using (var sr = new StreamReader(pipeClient))
|
|
{
|
|
string temp;
|
|
|
|
while ((temp = sr.ReadLine()) != null)
|
|
{
|
|
CalibrationRecord record;
|
|
Double avgTof = 0;
|
|
Double reftemp = 0;
|
|
if (double.TryParse(temp, out reftemp))
|
|
{
|
|
avgTof = 0;
|
|
var i = 0;
|
|
while (_currentGenesis.CurrentRecords.TryDequeue(out record))
|
|
{
|
|
if (record.Channel == 2)
|
|
{
|
|
avgTof = avgTof + record.TotalTimeOfFlightS;
|
|
i = 1 + i;
|
|
}
|
|
|
|
}
|
|
if (i > 0)
|
|
{
|
|
|
|
|
|
avgTof = avgTof / i;
|
|
if (!double.IsNaN(avgTof))
|
|
{
|
|
listTempTime.Enqueue(new TempTofCalc() { RefDate = DateTime.Now, RefTemp = reftemp, Tof = avgTof });
|
|
if (avgTof.ToString().Contains("a"))
|
|
{
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private List<ToFTime> toFTimes = new List<ToFTime>();
|
|
private void MergeToAutoFile()
|
|
{
|
|
List<TempTofCalc> itimestowri = new List<TempTofCalc>();
|
|
TempTofCalc lItem;
|
|
while (listTempTime.TryDequeue(out lItem))
|
|
{
|
|
itimestowri.Add(lItem);
|
|
}
|
|
var fiName = $"{_currentGenesis.PcbId}_{start.ToString("yyyy_MM_dd_HH-mm-ss")}.TempTof";
|
|
String jsonData = JsonConvert.SerializeObject(itimestowri.ToList());
|
|
jsonData = jsonData.TrimStart('[').TrimEnd(']');
|
|
if (File.Exists(fiName))
|
|
{
|
|
jsonData = $",{jsonData}";
|
|
}
|
|
|
|
File.AppendAllText(fiName, jsonData);
|
|
}
|
|
|
|
private Int32 PlateauMinLengt = 15;
|
|
private Double TempConstMarker = 0.01;
|
|
private List<TempTofCalc> toGrid = new List<TempTofCalc>();
|
|
|
|
private void UpdateGridBtn_Clicked(object sender, EventArgs e)
|
|
{
|
|
|
|
}
|
|
|
|
private void timer3_Tick(Object sender, EventArgs e)
|
|
{
|
|
MergeToAutoFile();
|
|
}
|
|
|
|
private Double generateTof(Random r , Double temp)
|
|
{
|
|
var tmp = r.Next(1, 5);
|
|
var retrn = (temp / 9000) - Math.Pow(temp, 1.6) / 100_000;
|
|
|
|
return retrn - (retrn * tmp / 100 + Math.Pow(tmp, 1.6) / 100_000);
|
|
}
|
|
|
|
private void button3_Click(Object sender, EventArgs e)
|
|
{
|
|
List<TempTofCalc> refTempss = new List<TempTofCalc>();
|
|
var sDate = DateTime.UtcNow;
|
|
Double refTemp = 5.0;
|
|
for (Int32 i = 0; i <= 5; i++)
|
|
{
|
|
var needUp = 2.5;
|
|
var rramp = new Random();
|
|
var rtof = new Random();
|
|
|
|
//plateau
|
|
while (needUp >= 0)
|
|
{
|
|
|
|
var temp = rramp.NextDouble() / (needUp * 100);//+0
|
|
needUp = needUp - temp;
|
|
refTemp = refTemp + temp;
|
|
refTempss.Add(new TempTofCalc() { RefDate = sDate.AddSeconds(refTempss.Count), RefTemp = refTemp, Tof = generateTof(rtof, refTemp) });
|
|
}
|
|
|
|
var ra = new Random();
|
|
var tillI = ra.Next(150, 4000);//+0
|
|
var r = new Random(tillI);
|
|
for (Int32 platI = 0; platI < tillI; platI++)
|
|
{
|
|
|
|
|
|
var temp = r.NextDouble() / 5;
|
|
refTempss.Add(new TempTofCalc() { RefDate = sDate.AddSeconds(refTempss.Count), RefTemp = refTemp + temp, Tof = generateTof(rtof, refTemp) });
|
|
}
|
|
}
|
|
|
|
var jsonData = JsonConvert.SerializeObject(refTempss);
|
|
File.AppendAllText($"124563_{start.ToString("yyyy_MM_dd_HH-mm-ss")}.TempTof", jsonData);
|
|
}
|
|
|
|
private Boolean automatic = false;
|
|
private AutomaticTemperaturCalibration automaticCalibration;
|
|
|
|
private void StartAutomaticalyBtn_Clicked(object sender, EventArgs _)
|
|
{
|
|
this.automatic = true;
|
|
this.start = DateTimeOffset.Now;
|
|
|
|
this._currentGenesis?.StartRecordData();
|
|
this._currentGenesis?.WriteRegister<Byte>(Register.Genesisflow.SampleRate, 16, checkRegister: true);
|
|
|
|
this.automaticCalibration = new AutomaticTemperaturCalibration(() => this.OutputAvgTof());
|
|
this.automaticCalibration.TemperatureMesured += this.SaveMessurement;
|
|
|
|
this.automaticCalibration.StartMessuring();
|
|
this.SetEnabled(ProgrammState.RecordRuning);
|
|
}
|
|
|
|
private void StopAutomaticalyBtn_Clicked(Object sender, EventArgs e)
|
|
{
|
|
this.automatic = false;
|
|
this.automaticCalibration.TemperatureMesured -= this.SaveMessurement;
|
|
|
|
this.MergeToAutoFile();
|
|
this.automaticCalibration.StopMessuring();
|
|
this._currentGenesis?.WriteRegister<Byte>(Register.Genesisflow.SampleRate, 0, checkRegister: true);
|
|
this.SetEnabled(ProgrammState.RecordStoped);
|
|
}
|
|
|
|
private void SaveMessurement(double meterTOF, double referenceT, DateTime timestamp)
|
|
{
|
|
var pcbid = this._currentGenesis.PcbId;
|
|
|
|
File.AppendAllLines($"{timestamp:yyyy_MM_dd}.messurements", new[] { $"{pcbid};{referenceT};{meterTOF};{timestamp.ToLongTimeString()}" });
|
|
|
|
var tmp = referenceT.ToString("us-US");
|
|
var tof = meterTOF.ToString("us-US");
|
|
LocalWebRequest.PostRequestAsync($"http://10.49.40.25/MeterProcessState/api/TempFlange/AddLut?PcbId={pcbid}&RefTempC={tmp}&AvgTof={tof}");
|
|
}
|
|
}
|
|
|
|
internal class AutomaticTemperaturCalibration
|
|
{
|
|
private readonly int messurementsCount;
|
|
private readonly Watcher temperatureWatcher;
|
|
private readonly Watcher messurementWatcher;
|
|
private readonly Func<double> meterTCallback;
|
|
private readonly ICollection<KeyValuePair<double, double>> messurements;
|
|
|
|
private double referenceT;
|
|
private int messurmentN;
|
|
private int checksCount;
|
|
private StreamReader streamReader;
|
|
private NamedPipeClientStream pipeStream;
|
|
|
|
public AutomaticTemperaturCalibration(Func<double> meterTCallback)
|
|
{
|
|
if (meterTCallback != null)
|
|
{
|
|
this.meterTCallback = meterTCallback;
|
|
this.messurementsCount = Appsettings.MessurementDauer / Appsettings.MessurementStep;
|
|
|
|
this.temperatureWatcher = new Watcher(Appsettings.TemperatureCheckInMs);
|
|
this.temperatureWatcher.Elapsed += this.CheckTemperature;
|
|
|
|
this.messurementWatcher = new Watcher(Appsettings.MessurementStep);
|
|
this.messurementWatcher.Elapsed += this.Messure;
|
|
|
|
this.messurements = new List<KeyValuePair<double, double>>();
|
|
}
|
|
}
|
|
|
|
public event Action<double, double, DateTime> TemperatureMesured;
|
|
|
|
public void StartMessuring()
|
|
{
|
|
this.pipeStream = new NamedPipeClientStream(".", "TempPipe", PipeDirection.In);
|
|
this.pipeStream.Connect(3000);
|
|
|
|
if (this.pipeStream.IsConnected)
|
|
{
|
|
this.streamReader = new StreamReader(this.pipeStream);
|
|
this.StopMessurementWatcher();
|
|
this.StartTemperatureWatcher();
|
|
}
|
|
}
|
|
|
|
public void StopMessuring()
|
|
{
|
|
this.StopMessurementWatcher();
|
|
this.StopTemperatureWatcher();
|
|
this.streamReader.Dispose();
|
|
this.pipeStream.Close();
|
|
}
|
|
|
|
private void CheckTemperature(object sender, ElapsedEventArgs e)
|
|
{
|
|
// If reading reference temperature succeeds.
|
|
if (this.TryGetReferenceT(out var referenceT))
|
|
{
|
|
// calculating the difference to previouse point.
|
|
var differenceT = Math.Abs(this.referenceT - referenceT);
|
|
|
|
// If difference is greater as configured then reset counter and start counting.
|
|
if (differenceT >= Appsettings.TemperatureStepInC)
|
|
{
|
|
this.checksCount = 1;
|
|
}
|
|
// If smaller as 0.05, the temperature is same also continue counting.
|
|
else if (differenceT <= Appsettings.TemperaturToleranceInC)
|
|
{
|
|
this.checksCount++;
|
|
}
|
|
|
|
this.referenceT = referenceT;
|
|
|
|
// if count of same temperature events reaches 10 then start messurement for configured time.
|
|
if (this.checksCount == 10)
|
|
{
|
|
this.checksCount = 1;
|
|
|
|
// next call breaks current method execution.
|
|
this.StopTemperatureWatcher();
|
|
// next call starts messurements again.
|
|
this.StartMessurementWatcher();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Messure(object sender, ElapsedEventArgs e)
|
|
{
|
|
// If reading reference temperature succeeds and is in the expected range.
|
|
if (this.TryGetReferenceT(out var referenceT))
|
|
{
|
|
if (Math.Abs(this.referenceT - referenceT) <= Appsettings.TemperaturToleranceInC)
|
|
{
|
|
this.referenceT = referenceT;
|
|
var meterTOF = this.meterTCallback();
|
|
|
|
this.messurements.Add(new KeyValuePair<double, double>(this.referenceT, meterTOF));
|
|
}
|
|
else
|
|
{
|
|
this.messurmentN = this.messurementsCount;
|
|
}
|
|
|
|
this.messurmentN++;
|
|
|
|
if (this.messurmentN >= this.messurementsCount)
|
|
{
|
|
var avgT = this.messurements.Average(x => x.Key);
|
|
var avgTOF = this.messurements.Average(x => x.Value);
|
|
|
|
this.messurements.Clear();
|
|
this.TemperatureMesured?.Invoke(avgTOF, avgTOF, e.SignalTime);
|
|
|
|
// next call breaks current method execution.
|
|
this.StopMessurementWatcher();
|
|
// next call starts seeking for new temperature change.
|
|
this.StartTemperatureWatcher();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void StartTemperatureWatcher()
|
|
{
|
|
this.temperatureWatcher.AutoReset = true;
|
|
this.temperatureWatcher.Enabled = true;
|
|
this.temperatureWatcher.Start();
|
|
}
|
|
|
|
private void StopTemperatureWatcher()
|
|
{
|
|
this.temperatureWatcher.Stop();
|
|
this.temperatureWatcher.Enabled = false;
|
|
this.temperatureWatcher.AutoReset = false;
|
|
}
|
|
|
|
private void StartMessurementWatcher()
|
|
{
|
|
this.messurmentN = 0;
|
|
this.messurementWatcher.AutoReset = true;
|
|
this.messurementWatcher.Enabled = true;
|
|
this.messurementWatcher.Start();
|
|
}
|
|
|
|
private void StopMessurementWatcher()
|
|
{
|
|
this.messurmentN = 0;
|
|
this.messurementWatcher.Stop();
|
|
this.messurementWatcher.Enabled = false;
|
|
this.messurementWatcher.AutoReset = false;
|
|
}
|
|
|
|
private bool TryGetReferenceT(out double referenceT)
|
|
{
|
|
referenceT = 0;
|
|
|
|
var succeeded = false;
|
|
var readAttempts = 1000;
|
|
|
|
do
|
|
{
|
|
var referenceTemperatureLine = this.streamReader.ReadLine();
|
|
|
|
if (double.TryParse(referenceTemperatureLine, NumberStyles.Any, new CultureInfo("de"), out referenceT)
|
|
|| double.TryParse(referenceTemperatureLine, NumberStyles.Any, new CultureInfo("us"), out referenceT))
|
|
{
|
|
succeeded = true;
|
|
|
|
break;
|
|
}
|
|
|
|
Thread.Sleep(10);
|
|
|
|
} while (readAttempts-- > 0);
|
|
|
|
return succeeded;
|
|
}
|
|
}
|
|
}
|