tbf/TBF/UI/Process/ProcessTabPageCtrl.cs

711 lines
35 KiB
C#

///
/// Copyright (c) 2021-2022 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using log4net;
using Common;
using Config.Entities;
using SchematicDrawing;
using TBF.Resources;
using TBF.Rig.Sequences;
using TBF.Rig.Various.Drawing.Junction;
using TBF.UiBridge;
using Dirichlet.Numerics;
namespace TBF.UI.Process
{
public partial class ProcessTabPageCtrl : UserControl
{
static readonly ILog log = LogManager.GetLogger(typeof(ProcessTabPageCtrl));
const int DfltPumpBitNr = 124;
const int DfltStartValveBitNr = 125;
const int DfltDiverterBitNr = 126;
const int DfltDrainValveBitNr = 127;
enum Column
{
Nr,
Error,
Volume,
Pulses,
RefPulses,
SerialNr,
Count
}
MetersKind currentMetersKind;
public ProcessTabPageCtrl()
{
InitializeComponent();
InitializeTableOfWatermeters(processListViewEx, ProcessData.WMsCount);
InitializeDrawing();
Bridge.ProcedureSelectedHandler += delegate(object sender, ProcedureSelectedEventArgs args)
{
try {
if (InvokeRequired) Invoke(new EventHandler<ProcedureSelectedEventArgs>(OnProcedureSelected), sender, args);
else OnProcedureSelected(sender, args);
}
catch (Exception e) { log.ErrorFormat("ProcessTabPageCtrl.OnProcedureSelected() failed: {0}", e.Message); }
};
Bridge.TestSelectedHandler += delegate(object sender, TestSelectedEventArgs args)
{
try {
if (InvokeRequired) Invoke(new EventHandler<TestSelectedEventArgs>(OnTestSelected), sender, args);
else OnTestSelected(sender, args);
}
catch (Exception e) { log.ErrorFormat("ProcessTabPageCtrl.OnTestSelected() failed: {0}", e.Message); }
};
Bridge.StateMachineTickHandler += delegate(object sndr, UiBridge.StateMachineTickEventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<UiBridge.StateMachineTickEventArgs>(OnStateMachineTick), sndr, args); }
else OnStateMachineTick(sndr, args);
};
Bridge.TestCompletedHandler += delegate(object sender, TestCompletedEventArgs args)
{
try {
if (InvokeRequired) Invoke(new EventHandler<TestCompletedEventArgs>(OnTestCompleted), sender, args);
else OnTestCompleted(sender, args);
}
catch (Exception e) { log.ErrorFormat("ProcessTabPageCtrl.OnTestCompleted() failed: {0}", e.Message); }
};
Bridge.ProcedureCompletedHandler += delegate(object sender, ProcedureCompletedEventArgs args)
{
try {
if (InvokeRequired) Invoke(new EventHandler<ProcedureCompletedEventArgs>(OnProcedureCompleted), sender, args);
else OnProcedureCompleted(sender, args);
}
catch (Exception e) { log.ErrorFormat("ProcessTabPageCtrl.OnProcedureCompleted() failed: {0}", e.Message); }
};
}
public void Settings2UI()
{
TBF.LocalSettings ls = Program.LocalSettings;
/// Splitter distances
splitContainer1.SplitterDistance = ls.ProcessSplitDist1;
splitContainer2.SplitterDistance = ls.ProcessSplitDist2;
/// ListViewEx columns
processListViewEx.Columns.Add(Strings.Nr, (ls.ProcessColumnCount > 0) ? ls.ProcessColumnWidths[0] : 30 * MainWnd.Dpi / Constants.Dpi100pct);
processListViewEx.Columns.Add(Strings.Error, (ls.ProcessColumnCount > 1) ? ls.ProcessColumnWidths[1] : 50 * MainWnd.Dpi / Constants.Dpi100pct);
processListViewEx.Columns.Add(Strings.Volume, (ls.ProcessColumnCount > 2) ? ls.ProcessColumnWidths[2] : 50 * MainWnd.Dpi / Constants.Dpi100pct);
processListViewEx.Columns.Add(Strings.Pulses, (ls.ProcessColumnCount > 3) ? ls.ProcessColumnWidths[3] : 60 * MainWnd.Dpi / Constants.Dpi100pct);
processListViewEx.Columns.Add(Strings.Ref_pulses, (ls.ProcessColumnCount > 4) ? ls.ProcessColumnWidths[4] : 75 * MainWnd.Dpi / Constants.Dpi100pct);
processListViewEx.Columns.Add(Strings.SerialNr, (ls.ProcessColumnCount > 5) ? ls.ProcessColumnWidths[5] : 100 * MainWnd.Dpi / Constants.Dpi100pct);
}
/// <summary>
/// Save UI settings to Program.LocalSettings and save them to a file.
/// UI settings are:
/// MainWnd size and location and splitter distances.
/// </summary>
public void UI2Settings()
{
LocalSettings ls = Program.LocalSettings;
bool anyChange = splitContainer1.SplitterDistance != ls.ProcessSplitDist1
|| splitContainer2.SplitterDistance != ls.ProcessSplitDist2;
if (anyChange)
{
ls.ProcessSplitDist1 = splitContainer1.SplitterDistance;
ls.ProcessSplitDist2 = splitContainer2.SplitterDistance;
}
/// Compare list view column widths with the saved ones
if (processListViewEx.Columns.Count != ls.ProcessColumnCount)
{
ls.ProcessColumnWidths = new int[processListViewEx.Columns.Count];
for (int i = 0; i < ls.ProcessColumnCount; i++)
{
ls.ProcessColumnWidths[i] = processListViewEx.Columns[i].Width;
}
anyChange = true;
}
else
{
for (int i = 0; i < ls.ProcessColumnCount; i++)
{
if (processListViewEx.Columns[i].Width != ls.ProcessColumnWidths[i])
{
ls.ProcessColumnWidths[i] = processListViewEx.Columns[i].Width;
anyChange = true;
}
}
}
if (anyChange) ls.Save();
}
/// <summary>
/// Initializes water meters table - ListView control.
/// Table is filled with dots "."
/// </summary>
/// <param name="listView">ListView control</param>
/// <param name="wmsCount">Water meters count</param>
/// <param name="waterMeters">Optional water meters to be used as list view item tags</param>
void InitializeTableOfWatermeters(ListView listView, int wmsCount, IList<Results.Entities.WaterMeter> waterMeters = null)
{
if (listView.Items.Count != wmsCount)
{
/// Executed when the number of water meters or register readers changes
listView.Items.Clear();
for (int i = 0; i < wmsCount; i++)
{
listView.Items.Add(new ListViewItem((i + 1).ToString()));
}
}
for (int i = 0; i < wmsCount; i++)
{
if (listView.Items[i].SubItems.Count == (int)Column.Count)
{
for (int j = 1; j < (int)Column.Count; j++) /// Column 1 .. Column.Count-1
{
listView.Items[i].SubItems[j].Text = ".";
}
}
else
{
for (int j = 1; j < (int)Column.Count; j++) /// Column 1 .. Column.Count-1
{
listView.Items[i].SubItems.Add(".");
}
}
if (waterMeters != null && i < waterMeters.Count)
{
listView.Items[i].Tag = waterMeters[i];
}
}
}
///
/// Schematic drawing components
/// water
TBF.Rig.Various.Drawing.Tank.Configuration tankCfg; /// |
TBF.Rig.Modbus.PumpFM.DanfossVLT.PumpCfg pumpCfg; /// | setpoint, route based (initially bit nr. = 124)
TBF.Rig.Modbus.TempMeter.Groch.TempMeterCfg tempInCfg; /// | measured value
TBF.Rig.Modbus.PressureMeter.Meret.PressureMeterCfg pressUpCfg; /// | measured value
TBF.Rig.WaterMeters.WaterMeter.WaterMeterCfg wm1Cfg; /// |
TBF.Rig.WaterMeters.WaterMeter.WaterMeterCfg wm2Cfg; /// |
TBF.Rig.WaterMeters.WaterMeter.WaterMeterCfg wmLastCfg; /// |
TBF.Rig.Modbus.TempMeter.Groch.TempMeterCfg tempOutCfg; /// | measured value
TBF.Rig.Modbus.PressureMeter.Meret.PressureMeterCfg pressDnCfg; /// | measured value
TBF.Rig.BuiltIn.Valve.ValveCfg startValveCfg; /// | route based (initially bit nr. = 125)
TBF.Rig.Uni.FlowMeter.FlowMeterCfg flowMeterCfg; /// | measured value
TBF.Rig.Uni.RegValve.RegValveCfg regValveCfg; /// | setpoint
TBF.Rig.Modbus.TempMeter.Groch.TempMeterCfg tempDivCfg; /// | measured value
TBF.Rig.Uni.Diverter.DiverterCfg diverterCfg; /// | route based (initially bit nr. = 126)
TBF.Rig.Scales.MettlerToledo.ScaleCfg scaleCfg; /// | measured value
TBF.Rig.BuiltIn.Valve.ValveCfg drainValveCfg; /// v route based (initially bit nr. = 127)
///
int scaleId, tankId, drainValveId, diverterId, regValveId, flowMeterId, startValveId;
int pumpId, tempInId, tempOutId, tempDivId, pressUpId, pressDownId;
int wm1Id, wm2Id, wmLastId, j1, j2, j3, j4, j5, j6, j7;
///
int scaleMsrdIx, flowMeterMsrdIx, tempMtrUpMsrdIx, tempMtrDownMsrdIx, tempMtrDivMsrdIx;
int pressMtrUpMsrdIx, pressMtrDownMsrdIx;
///
int regValveSetpIx, pumpSetpIx;
IDrawingItCmpntWithMeasuredVal[] cmpntWithMeasuredVal;
IDrawingItCmpntWithSetpoint[] cmpntWithSetpoint;
/// <summary>
/// Initialize hydraulical schematic drawing.
/// This should be called before initialization of handlers.
/// </summary>
void InitializeDrawing()
{
processDrawingCtrl.SupressRedraws = true;
int id = 1;
int msrdIx = 0;
int setpIx = 0;
processDrawingCtrl.AddItem(
tankCfg = new TBF.Rig.Various.Drawing.Tank.Configuration("Tank", new TBF.Rig.Various.Drawing.Tank.Factory())
{
Id = (tankId = id++),
X = 570, Y = 410, Shape = Shape.Tank, Sz = Sz.L, Orient = Orient.R, Flip = false,
LblX = 33, LblY = 22, LblOrient = Orient.R,
});
pumpSetpIx = setpIx++;
processDrawingCtrl.AddItem(
pumpCfg = new TBF.Rig.Modbus.PumpFM.DanfossVLT.PumpCfg(new TBF.Rig.Modbus.PumpFM.DanfossVLT.Factory())
{
Id = (pumpId = id++), Name = "P",
X = 450, Y = 480, Shape = Shape.PumpFM, Sz = Sz.L, Orient = Orient.L, Flip = false,
LblX = 0, LblY = -46, LblOrient = Orient.R,
SetpX = 0, SetpY = -24, SetpOrient = Orient.R, SetpFormat = "{0:F0} %", SetpUnit = Common.Unit.Pct,
BitNr = DfltPumpBitNr,
Inverted = false,
});
tempMtrUpMsrdIx = msrdIx++;
processDrawingCtrl.AddItem(
tempInCfg = new TBF.Rig.Modbus.TempMeter.Groch.TempMeterCfg(new TBF.Rig.Modbus.TempMeter.Groch.Factory())
{
Id = (tempInId = id++), Name = "T in",
X = 50, Y = 320, Shape = Shape.TempM, Sz = Sz.M, Orient = Orient.R, Flip = false,
LblX = 0, LblY = 2, LblOrient = Orient.R,
MsrdX = 0, MsrdY = 24, MsrdOrient = Orient.R, MsrdFormat = "{0:F1} °C", MsrdUnit = Common.Unit.C,
MsrdValLimLo = 5, MsrdValLimHi = 95,
});
pressMtrUpMsrdIx = msrdIx++;
processDrawingCtrl.AddItem(
pressUpCfg = new TBF.Rig.Modbus.PressureMeter.Meret.PressureMeterCfg(new TBF.Rig.Modbus.PressureMeter.Meret.Factory())
{
Id = (pressUpId = id++), Name = "Pr up",
X = 50, Y = 270, Shape = Shape.PressM, Sz = Sz.M, Orient = Orient.R, Flip = false,
LblX = 0, LblY = 0, LblOrient = Orient.R,
MsrdX = 0, MsrdY = 22, MsrdOrient = Orient.R, MsrdFormat = "{0:F2} bar", MsrdUnit = Common.Unit.bar,
MsrdValLimLo = -0.1, MsrdValLimHi = 25,
});
processDrawingCtrl.AddItem(
wm1Cfg = new TBF.Rig.WaterMeters.WaterMeter.WaterMeterCfg(new TBF.Rig.WaterMeters.WaterMeter.WaterMeterFactory())
{
Id = (wm1Id = id++), Name = "WM1",
X = 120, Y = 360, Shape = Shape.WaterM, Sz = Sz.L, Orient = Orient.R, Flip = false,
LblX = 0, LblY = -24, LblOrient = Orient.R,
});
processDrawingCtrl.AddItem(
wm2Cfg = new TBF.Rig.WaterMeters.WaterMeter.WaterMeterCfg(new TBF.Rig.WaterMeters.WaterMeter.WaterMeterFactory())
{
Id = (wm2Id = id++), Name = "WM2",
X = 180, Y = 360, Shape = Shape.WaterM, Sz = Sz.L, Orient = Orient.R, Flip = false,
LblX = 0, LblY = -24, LblOrient = Orient.R,
});
processDrawingCtrl.AddItem(
wmLastCfg = new TBF.Rig.WaterMeters.WaterMeter.WaterMeterCfg(new TBF.Rig.WaterMeters.WaterMeter.WaterMeterFactory())
{
Id = (wmLastId = id++), Name = "WM3",
X = 310, Y = 360, Shape = Shape.WaterM, Sz = Sz.L, Orient = Orient.R, Flip = false,
LblX = 0, LblY = -24, LblOrient = Orient.R,
});
tempMtrDownMsrdIx = msrdIx++;
processDrawingCtrl.AddItem(
tempOutCfg = new TBF.Rig.Modbus.TempMeter.Groch.TempMeterCfg(new TBF.Rig.Modbus.TempMeter.Groch.Factory())
{
Id = (tempOutId = id++), Name = "T out",
X = 370, Y = 320, Shape = Shape.TempM, Sz = Sz.M, Orient = Orient.R, Flip = false,
LblX = 0, LblY = 2, LblOrient = Orient.R,
MsrdX = 0, MsrdY = 24, MsrdOrient = Orient.R, MsrdFormat = "{0:F1} °C", MsrdUnit = Common.Unit.C,
MsrdValLimLo = 5, MsrdValLimHi = 95,
});
pressMtrDownMsrdIx = msrdIx++;
processDrawingCtrl.AddItem(
pressDnCfg = new TBF.Rig.Modbus.PressureMeter.Meret.PressureMeterCfg(new TBF.Rig.Modbus.PressureMeter.Meret.Factory())
{
Id = (pressDownId = id++), Name = "Pr dn",
X = 370, Y = 270, Shape = Shape.PressM, Sz = Sz.M, Orient = Orient.R, Flip = false,
LblX = 0, LblY = 0, LblOrient = Orient.R,
MsrdX = 0, MsrdY = 22, MsrdOrient = Orient.R, MsrdFormat = "{0:F2} bar", MsrdUnit = Common.Unit.bar,
MsrdValLimLo = -0.1, MsrdValLimHi = 25,
});
processDrawingCtrl.AddItem(
startValveCfg = new TBF.Rig.BuiltIn.Valve.ValveCfg(new TBF.Rig.BuiltIn.Valve.ValveFactory())
{
Id = (startValveId = id++), Name = "VI",
X = 450, Y = 280, Shape = Shape.Valve, Sz = Sz.L, Orient = Orient.Up, Flip = false,
LblX = 48, LblY = 9, LblOrient = Orient.R,
BitNr = DfltStartValveBitNr,
Inverted = false,
});
flowMeterMsrdIx = msrdIx++;
processDrawingCtrl.AddItem(
flowMeterCfg = new TBF.Rig.Uni.FlowMeter.FlowMeterCfg(new TBF.Rig.Uni.FlowMeter.Factory(), "I")
{
Id = (flowMeterId = id++),
X = 450, Y = 210, Shape = Shape.FlowM, Sz = Sz.L, Orient = Orient.Up, Flip = true,
LblX = 46, LblY = 0, LblOrient = Orient.R,
MsrdX = 46, MsrdY = 22, MsrdOrient = Orient.R, MsrdFormat = "{0:F3} m2/h", MsrdUnit = Common.Unit.m3ph,
});
regValveSetpIx = setpIx++;
processDrawingCtrl.AddItem(
regValveCfg = new TBF.Rig.Uni.RegValve.RegValveCfg("VR", new TBF.Rig.Uni.RegValve.Factory())
{
Id = (regValveId = id++),
X = 450, Y = 140, Shape = Shape.RegV, Sz = Sz.L, Orient = Orient.Up, Flip = true,
LblX = 46, LblY = 0, LblOrient = Orient.R,
SetpX = 46, SetpY = 22, SetpOrient = Orient.R,
});
tempMtrDivMsrdIx = msrdIx++;
processDrawingCtrl.AddItem(
tempDivCfg = new TBF.Rig.Modbus.TempMeter.Groch.TempMeterCfg(new TBF.Rig.Modbus.TempMeter.Groch.Factory())
{
Id = (tempDivId = id++), Name = "T div",
X = 660, Y = 30, Shape = Shape.TempM, Sz = Sz.M, Orient = Orient.R, Flip = false,
LblX = 0, LblY = 0, LblOrient = Orient.R,
MsrdX = 0, MsrdY = 22, MsrdOrient = Orient.R, MsrdFormat = "{0:F1} °C", MsrdUnit = Common.Unit.C,
MsrdValLimLo = 5, MsrdValLimHi = 95,
});
processDrawingCtrl.AddItem(
diverterCfg = new TBF.Rig.Uni.Diverter.DiverterCfg(new TBF.Rig.Uni.Diverter.Factory())
{
Id = (diverterId = id++), Name = "Div",
X = 610, Y = 90, Shape = Shape.Div, Sz = Sz.L, Orient = Orient.R, Flip = false,
LblX = 50, LblY = -8, LblOrient = Orient.R,
DivNr1 = 1,
BitNr = DfltDiverterBitNr,
Inverted = false,
});
scaleMsrdIx = msrdIx++;
processDrawingCtrl.AddItem(
scaleCfg = new TBF.Rig.Scales.MettlerToledo.ScaleCfg("WT", new TBF.Rig.Scales.MettlerToledo.Factory())
{
Id = (scaleId = id++),
X = 640, Y = 150, Shape = Shape.Scale, Sz = Sz.M, Orient = Orient.R, Flip = false,
LblX = 16, LblY = 40, LblOrient = Orient.R,
MsrdX = 16, MsrdY = 64, MsrdOrient = Orient.R, MsrdFormat = "{0:F3}", MsrdUnit = Common.Unit.kg,
});
processDrawingCtrl.AddItem(
drainValveCfg = new TBF.Rig.BuiltIn.Valve.ValveCfg(new TBF.Rig.BuiltIn.Valve.ValveFactory())
{
Id = (drainValveId = id++), Name = "VB",
X = 660, Y = 270, Shape = Shape.Valve, Sz = Sz.M, Orient = Orient.Dn, Flip = false,
LblX = 40, LblY = 5, LblOrient = Orient.R,
BitNr = DfltDrainValveBitNr,
Inverted = false,
});
/// Junctions
processDrawingCtrl.AddItem(new Configuration("J1", new Factory()) { Id = (j1 = id++), Shape = Shape.Junction, X = 50, Y = 490, Sz = Sz.L, });
processDrawingCtrl.AddItem(new Configuration("J2", new Factory()) { Id = (j2 = id++), Shape = Shape.Junction, X = 50, Y = 370, Sz = Sz.L, });
processDrawingCtrl.AddItem(new Configuration("J3", new Factory()) { Id = (j3 = id++), Shape = Shape.Junction, X = 460, Y = 370, Sz = Sz.L, });
processDrawingCtrl.AddItem(new Configuration("J4", new Factory()) { Id = (j4 = id++), Shape = Shape.Junction, X = 460, Y = 80, Sz = Sz.L, });
processDrawingCtrl.AddItem(new Configuration("J5", new Factory()) { Id = (j5 = id++), Shape = Shape.Junction, X = 630, Y = 40, Sz = Sz.L, });
processDrawingCtrl.AddItem(new Configuration("J6", new Factory()) { Id = (j6 = id++), Shape = Shape.Junction, X = 680, Y = 390, Sz = Sz.None, });
processDrawingCtrl.AddItem(new Configuration("J7", new Factory()) { Id = (j7 = id++), Shape = Shape.Junction, X = 620, Y = 390, Sz = Sz.None, });
processDrawingCtrl.MsrmntAvailableFlags = new bool[msrdIx];
processDrawingCtrl.MeasuredValues = new double[msrdIx];
processDrawingCtrl.AltStrings = new string[msrdIx];
processDrawingCtrl.Setpoints = new double[setpIx];
///
cmpntWithMeasuredVal = new IDrawingItCmpntWithMeasuredVal[msrdIx];
cmpntWithSetpoint = new IDrawingItCmpntWithSetpoint[setpIx];
processDrawingCtrl.PipesS = new string[0];
processDrawingCtrl.PipesM = new string[0];
processDrawingCtrl.PipesL = new string[]
{
string.Format("{0}~0~{1}~0", tankId, pumpId),
string.Format("{0}~1~{1}~0", pumpId, j1),
string.Format("{0}~0~{1}~0", j1, j2),
string.Format("{0}~0~{1}~0", j2, wm1Id),
string.Format("{0}~1~{1}~0", wm1Id, wm2Id),
string.Format("{0}~1~{1}~0", wm2Id, wmLastId),
string.Format("{0}~1~{1}~0", wmLastId, j3),
string.Format("{0}~0~{1}~0", j3, startValveId),
string.Format("{0}~1~{1}~0", startValveId, flowMeterId),
string.Format("{0}~1~{1}~0", flowMeterId, regValveId),
string.Format("{0}~1~{1}~0", regValveId, j4),
string.Format("{0}~0~{1}~0", j4, j5),
string.Format("{0}~0~{1}~0", j5, diverterId),
string.Format("{0}~0~{1}~0", scaleId, drainValveId),
string.Format("{0}~1~{1}~0", drainValveId, j6),
string.Format("{0}~1~{1}~0", diverterId, j7)
};
processDrawingCtrl.PipesXL = new string[0];
processDrawingCtrl.Route = 0;
processDrawingCtrl.SupressRedraws = false; /// Invokes Dijkstra algoritm
}
void OnProcedureSelected(object sender, ProcedureSelectedEventArgs args)
{
currentMetersKind = args.Procedure.MetersKind;
Invalidate();
}
void OnTestSelected(object sender, TestSelectedEventArgs args)
{
InitializeTableOfWatermeters(processListViewEx, ProcessData.WMsCount, ProcessData.BatchRslts.Batch.WaterMeters);
processDrawingCtrl.SupressRedraws = true;
/// Feeding path
pumpCfg.Name = (args.FeedingPath != null && args.FeedingPath.Pump != null) ? args.FeedingPath.Pump.Name : "n/a";
/// Bench path
tempInCfg.Name = (args.BenchPath != null && args.BenchPath.TempMtrUp != null) ? args.BenchPath.TempMtrUp.Name : "n/a";
tempOutCfg.Name = (args.BenchPath != null && args.BenchPath.TempMtrDown != null) ? args.BenchPath.TempMtrDown.Name : "n/a";
pressUpCfg.Name = (args.BenchPath != null && args.BenchPath.PressMtrUp != null) ? args.BenchPath.PressMtrUp.Name : "n/a";
pressDnCfg.Name = (args.BenchPath != null && args.BenchPath.PressMtrDown != null) ? args.BenchPath.PressMtrDown.Name : "n/a";
/// Output path
scaleCfg.Name = (args.OutputPath != null && args.OutputPath.Scale != null) ? args.OutputPath.Scale.Name : "n/a";
drainValveCfg.Name = (args.OutputPath != null && args.OutputPath.Scale != null && args.OutputPath.Scale.DrainValve != null) ? args.OutputPath.Scale.DrainValve.Name : "n/a";
diverterCfg.Name = (args.OutputPath != null && args.OutputPath.Diverter != null) ? args.OutputPath.Diverter.Name : "n/a";
regValveCfg.Name = (args.OutputPath != null && args.OutputPath.RegValve != null) ? args.OutputPath.RegValve.Name : "n/a";
flowMeterCfg.Name = (args.OutputPath != null && args.OutputPath.FlowMeter != null) ? args.OutputPath.FlowMeter.Name : "n/a";
startValveCfg.Name = (args.OutputPath != null && args.OutputPath.StartValve1 != null) ? args.OutputPath.StartValve1.Name : "n/a";
tempDivCfg.Name = (args.OutputPath != null && args.OutputPath.TempMtrDiv != null) ? args.OutputPath.TempMtrDiv.Name : "n/a";
/// Meters path
//wm1.Name = args.BenchPath;
//wm2.Name = args.BenchPath;
//wmLast.Name = args.BenchPath;
/// Route based - pump
if (args.FeedingPath != null && args.FeedingPath.Pump != null &&
args.FeedingPath.Pump.Cfg is TBF.Rig.BuiltIn.Pump.PumpCfg)
{
pumpCfg.BitNr = (args.FeedingPath.Pump.Cfg as TBF.Rig.BuiltIn.Pump.PumpCfg).BitNr;
pumpCfg.Inverted = (args.FeedingPath.Pump.Cfg as TBF.Rig.BuiltIn.Pump.PumpCfg).Inverted;
}
else if (args.FeedingPath != null && args.FeedingPath.Pump != null &&
args.FeedingPath.Pump.Cfg is TBF.Rig.Modbus.PumpFM.DanfossVLT.PumpCfg)
{
pumpCfg.BitNr = (args.FeedingPath.Pump.Cfg as TBF.Rig.Modbus.PumpFM.DanfossVLT.PumpCfg).BitNr;
pumpCfg.Inverted = (args.FeedingPath.Pump.Cfg as TBF.Rig.Modbus.PumpFM.DanfossVLT.PumpCfg).Inverted;
}
else
{
pumpCfg.BitNr = DfltPumpBitNr;
pumpCfg.Inverted = false;
}
/// Route based - start valve
if (args.OutputPath != null && args.OutputPath.StartValve1 != null &&
args.OutputPath.StartValve1.Cfg is TBF.Rig.BuiltIn.Valve.ValveCfg)
{
startValveCfg.BitNr = (args.OutputPath.StartValve1.Cfg as TBF.Rig.BuiltIn.Valve.ValveCfg).BitNr;
startValveCfg.Inverted = (args.OutputPath.StartValve1.Cfg as TBF.Rig.BuiltIn.Valve.ValveCfg).Inverted;
}
else if (args.OutputPath != null && args.OutputPath.StartValve1 != null &&
args.OutputPath.StartValve1.Cfg is TBF.Rig.BuiltIn.ValveEx.ValveCfg)
{
startValveCfg.BitNr = (args.OutputPath.StartValve1.Cfg as TBF.Rig.BuiltIn.ValveEx.ValveCfg).BitPosition;
startValveCfg.Inverted = false;
}
else
{
startValveCfg.BitNr = DfltStartValveBitNr;
startValveCfg.Inverted = false;
}
/// Route based - diverter
if (args.OutputPath != null && args.OutputPath.Diverter != null &&
args.OutputPath.Diverter.Cfg is TBF.Rig.Uni.Diverter.DiverterCfg)
{
diverterCfg.BitNr = (args.OutputPath.Diverter.Cfg as TBF.Rig.Uni.Diverter.DiverterCfg).BitNr;
diverterCfg.Inverted = (args.OutputPath.Diverter.Cfg as TBF.Rig.Uni.Diverter.DiverterCfg).Inverted;
}
else
{
diverterCfg.BitNr = DfltDiverterBitNr;
diverterCfg.Inverted = false;
}
/// Route based - drain valve
if (args.OutputPath != null && args.OutputPath.Scale != null && args.OutputPath.Scale.DrainValve != null &&
args.OutputPath.Scale.DrainValve.Cfg is TBF.Rig.BuiltIn.Valve.ValveCfg)
{
drainValveCfg.BitNr = (args.OutputPath.Scale.DrainValve.Cfg as TBF.Rig.BuiltIn.Valve.ValveCfg).BitNr;
drainValveCfg.Inverted = (args.OutputPath.Scale.DrainValve.Cfg as TBF.Rig.BuiltIn.Valve.ValveCfg).Inverted;
}
else
{
drainValveCfg.BitNr = DfltDrainValveBitNr;
drainValveCfg.Inverted = false;
}
cmpntWithMeasuredVal[scaleMsrdIx] = args.OutputPath.Scale as IDrawingItCmpntWithMeasuredVal;
cmpntWithMeasuredVal[flowMeterMsrdIx] = args.OutputPath.FlowMeter as IDrawingItCmpntWithMeasuredVal;
cmpntWithMeasuredVal[tempMtrUpMsrdIx] = args.BenchPath.TempMtrUp as IDrawingItCmpntWithMeasuredVal;
cmpntWithMeasuredVal[tempMtrDownMsrdIx] = args.BenchPath.TempMtrDown as IDrawingItCmpntWithMeasuredVal;
cmpntWithMeasuredVal[tempMtrDivMsrdIx] = args.OutputPath.TempMtrDiv as IDrawingItCmpntWithMeasuredVal;
cmpntWithMeasuredVal[pressMtrUpMsrdIx] = args.BenchPath.PressMtrUp as IDrawingItCmpntWithMeasuredVal;
cmpntWithMeasuredVal[pressMtrDownMsrdIx] = args.BenchPath.PressMtrDown as IDrawingItCmpntWithMeasuredVal;
cmpntWithSetpoint[regValveSetpIx] = args.OutputPath.RegValve as IDrawingItCmpntWithSetpoint;
cmpntWithSetpoint[pumpSetpIx] = args.FeedingPath.Pump as IDrawingItCmpntWithSetpoint;
UpdateRouteMsrdValuesAndSetpoints(TBF.Rig.StateMachine.ControlBoard != null ? TBF.Rig.StateMachine.ControlBoard.Route : 0);
processDrawingCtrl.SupressRedraws = false;
}
/// <summary>
/// This function copies route and process values to the schematic drawing control.
/// Schematic drawing is then redrawn accordingly in the next OnPaint().
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
void OnStateMachineTick(object sender, StateMachineTickEventArgs args)
{
try
{
/// Redraw schematic drawing
UpdateRouteMsrdValuesAndSetpoints(args.Route);
//if (ProcessData.RegisterReaders == null || ProcessData.BatchRslts == null ||
// ProcessData.BatchRslts.Batch == null || ProcessData.BatchRslts.Batch.WaterMeters == null)
//{
// return;
//}
///
/// Update water meter states
///
TBF.Rig.ControlBoard.IControlBoard cBrd = TBF.Rig.StateMachine.ControlBoard;
if (cBrd != null && cBrd.Devices != null && cBrd.Devices.FlowMeter != null && ProcessData.RegisterReaders != null)
{
double refVolume = cBrd.RefPulses * cBrd.Devices.FlowMeter.LtrPerPulse;
for (int i = 0; i < Math.Min(processListViewEx.Items.Count, ProcessData.RegisterReaders.Length); i++)
{
var lvi = processListViewEx.Items[i];
var rr = ProcessData.RegisterReaders[i];
if (rr != null && Math.Abs(rr.WMVolume) > float.Epsilon && refVolume > float.Epsilon)
{
/// Update a list view item
lvi.SubItems[(int)Column.Error].Text = Formulas.ErrorFromVolumes(rr.WMVolume, refVolume).ToString("F1");
lvi.SubItems[(int)Column.Volume].Text = rr.WMVolume.ToString("F1");
lvi.SubItems[(int)Column.Pulses].Text = rr.WMPulses.ToString();
lvi.SubItems[(int)Column.RefPulses].Text = rr.WMRefPulses.ToString();
}
else
{
lvi.SubItems[(int)Column.Error].Text = string.Empty;
lvi.SubItems[(int)Column.Volume].Text = string.Empty;
lvi.SubItems[(int)Column.Pulses].Text = string.Empty;
lvi.SubItems[(int)Column.RefPulses].Text = string.Empty;
}
if (rr is TBF.Rig.RegisterReaders.S640Stream.S640Stream)
{
lvi.SubItems[(int)Column.SerialNr].Text = (rr as TBF.Rig.RegisterReaders.S640Stream.S640Stream).PcbNumber.ToString();
}
}
}
}
catch (Exception e)
{
log.ErrorFormat("ProcessTabPageCtrl.OnStateMachineTick() failed: {0}", e.Message);
if (e.InnerException != null) log.FatalFormat("InnerMessage : {0}", e.InnerException.Message);
log.FatalFormat("StackTrace : {0}{1}", Environment.NewLine, e.StackTrace);
}
}
void UpdateRouteMsrdValuesAndSetpoints(UInt128 route)
{
processDrawingCtrl.Route = route;
for (int i = 0; i < cmpntWithMeasuredVal.Length; i++)
{
if (cmpntWithMeasuredVal[i] != null)
{
processDrawingCtrl.MsrmntAvailableFlags[i] = cmpntWithMeasuredVal[i].MsrmntAvailable;
processDrawingCtrl.MeasuredValues[i] = cmpntWithMeasuredVal[i].MeasuredVal;
processDrawingCtrl.AltStrings[i] = cmpntWithMeasuredVal[i].AltString;
}
else
{
processDrawingCtrl.MsrmntAvailableFlags[i] = false;
processDrawingCtrl.MeasuredValues[i] = 0;
processDrawingCtrl.AltStrings[i] = string.Empty;
}
}
for (int i = 0; i < cmpntWithSetpoint.Length; i++)
{
processDrawingCtrl.Setpoints[0] = (cmpntWithSetpoint[i] != null) ? cmpntWithSetpoint[i].SetpointVal : 0;
}
}
void OnTestCompleted(object sender, TestCompletedEventArgs args)
{
if (ProcessData.RegisterReaders == null || ProcessData.BatchRslts == null ||
ProcessData.BatchRslts.Batch == null || ProcessData.BatchRslts.Batch.WaterMeters == null)
{
return;
}
int wmsCount = Math.Min(ProcessData.RegisterReaders.Length, ProcessData.BatchRslts.Batch.WaterMeters.Count);
if (processListViewEx.Items.Count != wmsCount)
{
/// Invoked only when the number of water meters or register readers changes
processListViewEx.Items.Clear();
for (int i = 0; i < wmsCount; i++)
{
var lvi = new ListViewItem((i + 1).ToString()); /// Column 0
for (Column c = (Column)1; c < Column.Count; c++) /// Column 1 .. Column.Count-1
{
lvi.SubItems.Add(".");
}
lvi.Tag = ProcessData.BatchRslts.Batch.WaterMeters[i];
processListViewEx.Items.Add(lvi);
}
}
if (args.TestRslt != null)
{
for (int i = 0; i < wmsCount; i++)
{
var wm = processListViewEx.Items[i].Tag as Results.Entities.WaterMeter;
if (wm != null && !wm.Disabled)
{
Results.Entities.MeterTestRslt mtr = wm.MeterTestRslts.FirstOrDefault(x => x.TestRslt == args.TestRslt);
if (mtr != null)
{
var lvi = processListViewEx.Items[i];
/// Update a list view item
lvi.SubItems[(int)Column.Error].Text = mtr.Error.ToString("F1");
lvi.SubItems[(int)Column.Volume].Text = mtr.VolumeMeter.ToString("F1");
lvi.SubItems[(int)Column.Pulses].Text = mtr.PulsesMeter.ToString();
lvi.SubItems[(int)Column.RefPulses].Text = mtr.PulsesMaster.ToString();
lvi.SubItems[(int)Column.SerialNr].Text = mtr.SerialNr();
}
}
}
}
}
void OnProcedureCompleted(object sender, ProcedureCompletedEventArgs args)
{
}
private void ProcessTabPageCtrl_Paint(object sender, PaintEventArgs e)
{
System.Drawing.Graphics formGraphics = this.CreateGraphics();
}
}
}