/// /// Copyright (c) 2021-2023 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using log4net; using Common; using SchematicDrawing; using TBF.Resources; using TBF.Rig.Sequences; using TBF.Rig.Various.Drawing.Junction; using TBF.UiBridge; using Dirichlet.Numerics; using TBF.Rig.Modbus.Meret.AdjustableScale; using Factory = TBF.Rig.Various.Drawing.Junction.Factory; 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, PulsesPerLtr, SerialNr, Count } int qfromIx; int qtoIx; int testtimeIx; int startMassIx; int massIx; int volumeIx; int refErrorIx; MetersKind metersKind; public ProcessTabPageCtrl() { InitializeComponent(); InitializeTestDataTable(testDataListView, null); InitializeTableOfMeters(metersListView, MetersKind.Single, TBF.Data.WMsCount); InitializeDrawing(MetersKind.Single); Bridge.ProcedureSelectedHandler += delegate(object sender, ProcedureSelectedEventArgs args) { try { if (InvokeRequired) Invoke(new EventHandler(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(OnTestSelected), sender, args); else OnTestSelected(sender, args); } catch (Exception e) { log.ErrorFormat("ProcessTabPageCtrl.OnTestSelected() failed: {0}", e.Message); } }; Bridge.FlowDetectedHandler += delegate (object sender, FlowDetectedEventArgs args) { try { if (InvokeRequired) Invoke(new EventHandler(OnFlowDetected), sender, args); else OnFlowDetected(sender, args); } catch (Exception e) { log.ErrorFormat("ProcessTabPageCtrl.OnFlowDetected() failed: {0}", e.Message); } }; Bridge.StateMachineTickHandler += delegate(object sndr, UiBridge.StateMachineTickEventArgs args) { if (InvokeRequired) { Invoke(new EventHandler(OnStateMachineTick), sndr, args); } else OnStateMachineTick(sndr, args); }; Bridge.TestCompletedHandler += delegate(object sender, TestCompletedEventArgs args) { try { if (InvokeRequired) Invoke(new EventHandler(OnTestCompleted), sender, args); else OnTestCompleted(sender, args); } catch (Exception e) { log.ErrorFormat("ProcessTabPageCtrl.OnTestCompleted() failed: {0}", e.Message); } }; Bridge.CompoundDetectionHandler += delegate(object sender, CompoundDetectionEventArgs args) { try { if (InvokeRequired) Invoke(new EventHandler(OnCompoundDetection), sender, args); else OnCompoundDetection(sender, args); } catch (Exception e) { log.ErrorFormat("ProcessTabPageCtrl.OnCompoundDetection() failed: {0}", e.Message); } }; } public void Settings2UI() { TBF.LocalSettings ls = Program.LocalSettings; /// Splitter distances splitContainer1.SplitterDistance = Math.Max(150, Math.Min(ls.ProcessSplitDist1, 500)); /// metersListViewEx columns var cols = ls.ProcMetersColWidths; metersListView.Columns.Add(Strings.Nr, (cols != null && cols.Length > 0) ? cols[0] : 40 * MainWnd.Dpi / Constants.Dpi100pct); metersListView.Columns.Add(Strings.Error, (cols != null && cols.Length > 1) ? cols[1] : 50 * MainWnd.Dpi / Constants.Dpi100pct); metersListView.Columns.Add(Strings.Volume, (cols != null && cols.Length > 2) ? cols[2] : 50 * MainWnd.Dpi / Constants.Dpi100pct); metersListView.Columns.Add(Strings.Pulses, (cols != null && cols.Length > 3) ? cols[3] : 60 * MainWnd.Dpi / Constants.Dpi100pct); metersListView.Columns.Add(Strings.Ref_pulses, (cols != null && cols.Length > 4) ? cols[4] : 75 * MainWnd.Dpi / Constants.Dpi100pct); metersListView.Columns.Add(Strings.PulsesPerLtr, (cols != null && cols.Length > 5) ? cols[5] : 90 * MainWnd.Dpi / Constants.Dpi100pct); metersListView.Columns.Add(Strings.SerialNr, (cols != null && cols.Length > 6) ? cols[6] : 100 * MainWnd.Dpi / Constants.Dpi100pct); /// testDataListViewEx columns cols = ls.ProcTestDataColWidths; testDataListView.Columns.Add(Strings.Name, (cols != null && cols.Length > 0) ? cols[0] : 225 * MainWnd.Dpi / Constants.Dpi100pct); testDataListView.Columns.Add(Strings.Value, (cols != null && cols.Length > 1) ? cols[1] : 80 * MainWnd.Dpi / Constants.Dpi100pct); testDataListView.Columns.Add(Strings.Unit, (cols != null && cols.Length > 2) ? cols[2] : 60 * MainWnd.Dpi / Constants.Dpi100pct); } /// /// Save UI settings to Program.LocalSettings and save them to a file. /// UI settings are: /// MainWnd size and location and splitter distances. /// public void UI2Settings() { LocalSettings ls = Program.LocalSettings; bool anyChange = splitContainer1.SplitterDistance != ls.ProcessSplitDist1; if (anyChange) { ls.ProcessSplitDist1 = splitContainer1.SplitterDistance; } /// Compare list view column widths with the saved ones if (ls.ProcMetersColWidths == null || ls.ProcMetersColWidths.Length != metersListView.Columns.Count) { ls.ProcMetersColWidths = new int[metersListView.Columns.Count]; for (int i = 0; i < metersListView.Columns.Count; i++) { ls.ProcMetersColWidths[i] = metersListView.Columns[i].Width; } anyChange = true; } else { for (int i = 0; i < metersListView.Columns.Count; i++) { if (metersListView.Columns[i].Width != ls.ProcMetersColWidths[i]) { ls.ProcMetersColWidths[i] = metersListView.Columns[i].Width; anyChange = true; } } } /// Compare list view column widths with the saved ones if (ls.ProcTestDataColWidths == null || ls.ProcTestDataColWidths.Length != testDataListView.Columns.Count) { ls.ProcTestDataColWidths = new int[testDataListView.Columns.Count]; for (int i = 0; i < testDataListView.Columns.Count; i++) { ls.ProcTestDataColWidths[i] = testDataListView.Columns[i].Width; } anyChange = true; } else { for (int i = 0; i < testDataListView.Columns.Count; i++) { if (testDataListView.Columns[i].Width != ls.ProcTestDataColWidths[i]) { ls.ProcTestDataColWidths[i] = testDataListView.Columns[i].Width; anyChange = true; } } } if (anyChange) ls.Save(); } /// /// Initializes test data table - ListView control. /// Table is filled with dots "." /// /// ListView control void InitializeTestDataTable(ListView lv, TestSelectedEventArgs args) { lv.Items.Clear(); lv.Items.Add(new ListViewItem(new string[] { Strings.Test, args != null ? args.Test.Name : "---", string.Empty })); lv.Items.Add(new ListViewItem(new string[] { Strings.Repetition, args != null ? string.Format("{0} / {1}", args.RepetitionNr, args.Test.Repeats) : "---", string.Empty, })); double qfrom = (args != null) ? args.Test.QfromM3ph() : 0; qfromIx = lv.Items.Count; lv.Items.Add(new ListViewItem(new string[] { Strings.Q_from, (qfrom > 0) ? Units.ConvertTo(ProcessData.FlowUnit, qfrom).ToString() : "---", (ProcessData.FlowUnit == Unit.None ? Unit.m3ph : ProcessData.FlowUnit).ToDescription(), })); double qto = (args != null) ? args.Test.QtoM3ph() : 0; qtoIx = lv.Items.Count; lv.Items.Add(new ListViewItem(new string[] { Strings.Q_to, (qto > 0) ? Units.ConvertTo(ProcessData.FlowUnit, qto).ToString() : "---", (ProcessData.FlowUnit == Unit.None ? Unit.m3ph : ProcessData.FlowUnit).ToDescription(), })); lv.Items.Add(new ListViewItem(new string[] { Strings.Target_volume, args != null ? Units.ConvertTo(ProcessData.VolumeUnit, args.Test.Volume).ToString() : "---", (ProcessData.VolumeUnit == Unit.None ? Unit.l : ProcessData.VolumeUnit).ToDescription(), })); testtimeIx = lv.Items.Count; lv.Items.Add(new ListViewItem(new string[] { Strings.Test_time, args != null ? args.Test.TestTime.ToString() : "---", Unit.s.ToDescription(), })); startMassIx = lv.Items.Count; lv.Items.Add(new ListViewItem(new string[] { Strings.Start_mass, "---", (ProcessData.MassUnit == Unit.None ? Unit.kg : ProcessData.MassUnit).ToDescription(), })); massIx = lv.Items.Count; lv.Items.Add(new ListViewItem(new string[] { Strings.Mass, "---", (ProcessData.MassUnit == Unit.None ? Unit.kg : ProcessData.MassUnit).ToDescription(), })); volumeIx = lv.Items.Count; lv.Items.Add(new ListViewItem(new string[] { Strings.Volume, "---", (ProcessData.VolumeUnit == Unit.None ? Unit.l : ProcessData.VolumeUnit).ToDescription(), })); refErrorIx = lv.Items.Count; lv.Items.Add(new ListViewItem(new string[] { Strings.Ref_flowmeter_error, "---", Unit.Pct.ToDescription() })); splitContainer2.SplitterDistance = 45 + 17 * lv.Items.Count; } /// /// Initializes water meters table - ListView control. /// Table is filled with dots "." /// /// ListView control /// Water meters count /// Optional water meters to be used as list view item tags void InitializeTableOfMeters(ListView listView, MetersKind metersKind, int wmsCount, IList waterMeters = null) { int rowsCount = (metersKind == MetersKind.Combined) ? (3 * wmsCount) : wmsCount; splitContainer3.SplitterDistance = 45 + 17 * rowsCount; if (listView.Items.Count != rowsCount) { /// Nr. of water meters has changed => All table rows are re-initialized listView.Items.Clear(); for (int i = 0; i < wmsCount; i++) { if (metersKind == MetersKind.Combined) { listView.Items.Add(new ListViewItem(string.Format("{0}", i + 1))); /// Compound listView.Items.Add(new ListViewItem(string.Format("{0} main", i + 1))); /// Compound - Main listView.Items.Add(new ListViewItem(string.Format("{0} aux", i + 1))); /// Compound - Aux } else { listView.Items.Add(new ListViewItem(string.Format("{0}", i + 1))); /// Single } } } /// Add or Update subitems 1 .. (int)Column.Count for (int i = 0; i < rowsCount; i++) { if (listView.Items[i].SubItems.Count == (int)Column.Count) { for (int j = 1; j < (int)Column.Count; j++) listView.Items[i].SubItems[j].Text = "."; } else { for (int j = 1; j < (int)Column.Count; j++) listView.Items[i].SubItems.Add("."); } } /// Update Tag-s of ListView items with references to water meters, display serial numbers for (int i = 0; i < wmsCount; i++) { if (waterMeters != null && waterMeters[i] != null) { if (metersKind == MetersKind.Combined) { /// Compound listView.Items[3 * i].Tag = waterMeters[i]; /// Compound - Main listView.Items[3 * i + 1].Tag = waterMeters[i]; if (!string.IsNullOrEmpty(waterMeters[i].SerialNr)) { listView.Items[3 * i + 1].SubItems[(int)Column.SerialNr].Text = waterMeters[i].SerialNr; } /// Compound - Aux listView.Items[3 * i + 2].Tag = waterMeters[i]; if (!string.IsNullOrEmpty(waterMeters[i].SerialNrAux)) { listView.Items[3 * i + 2].SubItems[(int)Column.SerialNr].Text = waterMeters[i].SerialNrAux; } } else { /// Single listView.Items[i].Tag = waterMeters[i]; if (!string.IsNullOrEmpty(waterMeters[i].SerialNr)) { listView.Items[i].SubItems[(int)Column.SerialNr].Text = waterMeters[i].SerialNr; } } } } } /// /// Schematic drawing components /// water Rig.Various.Drawing.Tank.Configuration tankCfg; /// | Rig.Modbus.PumpFM.DanfossVLT.PumpCfg pumpCfg; /// | setpoint, route based (initially bit nr. = 124) //Rig.Modbus.PumpFM.Grundfoss.PumpCfg pump2Cfg; /// | setpoint, route based (initially bit nr. = 124)// Rig.Modbus.TempMeter.Groch.TempMeterCfg tempInCfg; /// | measured value Rig.Modbus.PressureMeter.Meret.PressureMeterCfg pressUpCfg; /// | measured value Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg electricUpCfg; /// | measured value Rig.WaterMeters.WaterMeter.WaterMeterCfg wm1Cfg; /// | Rig.WaterMeters.WaterMeter.WaterMeterCfg wm2Cfg; /// | Rig.WaterMeters.WaterMeter.WaterMeterCfg wmLastCfg; /// | Rig.Modbus.TempMeter.Groch.TempMeterCfg tempOutCfg; /// | measured value Rig.Modbus.PressureMeter.Meret.PressureMeterCfg pressDnCfg; /// | measured value Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg electricDownCfg; /// | measured value Rig.BuiltIn.Valve.ValveCfg startValveCfg; /// | route based (initially bit nr. = 125) Rig.Uni.FlowMeter.FlowMeterCfg flowMeterCfg; /// | measured value Rig.Uni.RegValve.RegValveCfg regValveCfg; /// | setpoint Rig.Modbus.TempMeter.Groch.TempMeterCfg tempDivCfg; /// | measured value Rig.Uni.Diverter.DiverterCfg diverterCfg; /// | route based (initially bit nr. = 126) Rig.Scales.MettlerToledo.ScaleCfg scaleCfg; /// | measured value 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, electricUpId, electricDownId; int wm1Id, wm2Id, wmLastId, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11; /// int scaleMsrdIx, flowMeterMsrdIx, tempMtrUpMsrdIx, tempMtrDownMsrdIx, tempMtrDivMsrdIx; int pressMtrUpMsrdIx, pressMtrDownMsrdIx; int electricMtrUpMsrdIx, electricMtrDownMsrdIx; /// int regValveSetpIx, pumpSetpIx; /// IDrawingItCmpntWithMeasuredVal[] cmpntWithMeasuredVal; IDrawingItCmpntWithSetpoint[] cmpntWithSetpoint; IDrawingItCmpntWithCustomBmp[] cmpntWithCustomBmp; /// /// Initialize hydraulical schematic drawing. /// This should be called before initialization of handlers. /// void InitializeDrawing(MetersKind mtrKind) { processDrawingCtrl.SupressRedraws = true; processDrawingCtrl.ClearItems(); int id = 1; int msrdIx = 0; int setpIx = 0; int bmpIx = 0; /// Tank processDrawingCtrl.AddItem( tankCfg = new Rig.Various.Drawing.Tank.Configuration("Tank", new 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, }); /// Pump pumpSetpIx = setpIx++; processDrawingCtrl.AddItem( pumpCfg = new Rig.Modbus.PumpFM.DanfossVLT.PumpCfg(new 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 = Unit.Pct, BitNr = DfltPumpBitNr, Inverted = false, }); /*/// Pump pumpSetpIx = setpIx++; processDrawingCtrl.AddItem( pump2Cfg = new Rig.Modbus.PumpFM.Grundfoss.PumpCfg(new Rig.Modbus.PumpFM.Grundfoss.Factory()) { Id = pumpId = id++, Name = "P Grundfoss", 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 = Unit.Pct, BitNr = DfltPumpBitNr, 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, }); /// T up tempMtrUpMsrdIx = msrdIx++; processDrawingCtrl.AddItem( tempInCfg = new Rig.Modbus.TempMeter.Groch.TempMeterCfg(new 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 = Unit.C, MsrdValLimLo = 5, MsrdValLimHi = 95, }); /// Pr up pressMtrUpMsrdIx = msrdIx++; processDrawingCtrl.AddItem( pressUpCfg = new Rig.Modbus.PressureMeter.Meret.PressureMeterCfg(new 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 = Unit.bar, MsrdValLimLo = -0.1, MsrdValLimHi = 25, }); /// Electric up electricMtrUpMsrdIx = msrdIx++; processDrawingCtrl.AddItem( electricUpCfg = new Rig.Modbus.Meret.AdjustableScale.AdjustableMeterCfg(new Rig.Modbus.Meret.AdjustableScale.Factory()) { Id = electricUpId = id++, Name = "El up", X = 50, Y = 270, Shape = Shape.ElectricM, 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} A", MsrdUnit = Unit.A, MsrdValLimLo = -0.1, MsrdValLimHi = 25, }); if (mtrKind == MetersKind.Combined) { /// WM 1 main processDrawingCtrl.AddItem( wm1Cfg = new Rig.WaterMeters.WaterMeter.WaterMeterCfg(new Rig.WaterMeters.WaterMeter.WaterMeterFactory()) { Id = wm1Id = id++, Name = "WM1 main", X = 230, Y = 360, Shape = Shape.WaterM, Sz = Sz.L, Orient = Orient.R, Flip = false, LblX = 0, LblY = -24, LblOrient = Orient.R, }); /// WM 1 aux processDrawingCtrl.AddItem( wm2Cfg = new Rig.WaterMeters.WaterMeter.WaterMeterCfg(new Rig.WaterMeters.WaterMeter.WaterMeterFactory()) { Id = wm2Id = id++, Name = "WM1 aux", X = 230, Y = 240, Shape = Shape.WaterM, Sz = Sz.L, Orient = Orient.R, Flip = false, LblX = 0, LblY = -24, LblOrient = Orient.R, }); /// Junctions to connect Aux meter processDrawingCtrl.AddItem(new Configuration("J3", new Factory()) { Id = j3 = id++, Shape = Shape.Junction, X = 170, Y = 370, Sz = Sz.L, }); processDrawingCtrl.AddItem(new Configuration("J4", new Factory()) { Id = j4 = id++, Shape = Shape.Junction, X = 170, Y = 250, Sz = Sz.L, }); processDrawingCtrl.AddItem(new Configuration("J5", new Factory()) { Id = j5 = id++, Shape = Shape.Junction, X = 310, Y = 250, Sz = Sz.L, }); processDrawingCtrl.AddItem(new Configuration("J6", new Factory()) { Id = j6 = id++, Shape = Shape.Junction, X = 310, Y = 370, Sz = Sz.L, }); } else { /// WM 1 processDrawingCtrl.AddItem( wm1Cfg = new Rig.WaterMeters.WaterMeter.WaterMeterCfg(new 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, }); /// WM 2 processDrawingCtrl.AddItem( wm2Cfg = new Rig.WaterMeters.WaterMeter.WaterMeterCfg(new 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, }); /// WM last processDrawingCtrl.AddItem( wmLastCfg = new Rig.WaterMeters.WaterMeter.WaterMeterCfg(new Rig.WaterMeters.WaterMeter.WaterMeterFactory()) { Id = wmLastId = id++, Name = "WMn", X = 310, Y = 360, Shape = Shape.WaterM, Sz = Sz.L, Orient = Orient.R, Flip = false, LblX = 0, LblY = -24, LblOrient = Orient.R, }); } /// T down tempMtrDownMsrdIx = msrdIx++; processDrawingCtrl.AddItem( tempOutCfg = new Rig.Modbus.TempMeter.Groch.TempMeterCfg(new 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, }); /// Pr down pressMtrDownMsrdIx = msrdIx++; processDrawingCtrl.AddItem( pressDnCfg = new Rig.Modbus.PressureMeter.Meret.PressureMeterCfg(new 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, }); /// El down electricMtrDownMsrdIx = msrdIx++; processDrawingCtrl.AddItem( electricDownCfg = new AdjustableMeterCfg(new Rig.Modbus.Meret.AdjustableScale.Factory()) { Id = electricDownId = id++, Name = "El 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} A", MsrdUnit = Common.Unit.A, MsrdValLimLo = -0.1, MsrdValLimHi = 25, }); /// Junction processDrawingCtrl.AddItem(new Configuration("J7", new Factory()) { Id=(j7=id++), Shape=Shape.Junction, X=460, Y=370, Sz=Sz.L, }); /// Start valve processDrawingCtrl.AddItem( startValveCfg = new Rig.BuiltIn.Valve.ValveCfg(new 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, }); /// Flow meter flowMeterMsrdIx = msrdIx++; processDrawingCtrl.AddItem( flowMeterCfg = new Rig.Uni.FlowMeter.FlowMeterCfg(new 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, }); /// Regulation valve regValveSetpIx = setpIx++; processDrawingCtrl.AddItem( regValveCfg = new Rig.Uni.RegValve.RegValveCfg("VR", new 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, }); /// Junctions processDrawingCtrl.AddItem(new Configuration("J8", new Factory()) { Id=(j8=id++), Shape=Shape.Junction, X=460, Y=80, Sz=Sz.L, }); processDrawingCtrl.AddItem(new Configuration("J9", new Factory()) { Id=(j9=id++), Shape=Shape.Junction, X=630, Y=40, Sz=Sz.L, }); /// T div tempMtrDivMsrdIx = msrdIx++; processDrawingCtrl.AddItem( tempDivCfg = new Rig.Modbus.TempMeter.Groch.TempMeterCfg(new 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, }); /// Diverter processDrawingCtrl.AddItem( diverterCfg = new Rig.Uni.Diverter.DiverterCfg(new 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, }); /// Scale scaleMsrdIx = msrdIx++; processDrawingCtrl.AddItem( scaleCfg = new Rig.Scales.MettlerToledo.ScaleCfg("WT", new 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, }); /// Drain valve processDrawingCtrl.AddItem( drainValveCfg = new Rig.BuiltIn.Valve.ValveCfg(new 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("J10", new Factory()) { Id=j10=id++, Shape=Shape.Junction, X=680, Y=390, Sz=Sz.None, }); processDrawingCtrl.AddItem(new Configuration("J11", new Factory()) { Id=j11=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]; processDrawingCtrl.CustomBitmaps = new DrawingShape[bmpIx]; /// cmpntWithMeasuredVal = new IDrawingItCmpntWithMeasuredVal[msrdIx]; cmpntWithSetpoint = new IDrawingItCmpntWithSetpoint[setpIx]; cmpntWithCustomBmp = new IDrawingItCmpntWithCustomBmp[bmpIx]; processDrawingCtrl.PipesS = new string[0]; processDrawingCtrl.PipesM = new string[0]; if (mtrKind == MetersKind.Combined) { 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, j3), string.Format("{0}~0~{1}~0", j3, j4), string.Format("{0}~0~{1}~0", j3, wm1Id), string.Format("{0}~0~{1}~0", j4, wm2Id), string.Format("{0}~1~{1}~0", wm2Id, j5), string.Format("{0}~1~{1}~0", wm1Id, j6), string.Format("{0}~0~{1}~0", j5, j6), string.Format("{0}~0~{1}~0", j6, j7), string.Format("{0}~0~{1}~0", j7, startValveId), string.Format("{0}~1~{1}~0", startValveId, flowMeterId), string.Format("{0}~1~{1}~0", flowMeterId, regValveId), string.Format("{0}~1~{1}~0", regValveId, j8), string.Format("{0}~0~{1}~0", j8, j9), string.Format("{0}~0~{1}~0", j9, diverterId), string.Format("{0}~0~{1}~0", scaleId, drainValveId), string.Format("{0}~1~{1}~0", drainValveId, j10), string.Format("{0}~1~{1}~0", diverterId, j11) }; } else { 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, j7), string.Format("{0}~0~{1}~0", j7, startValveId), string.Format("{0}~1~{1}~0", startValveId, flowMeterId), string.Format("{0}~1~{1}~0", flowMeterId, regValveId), string.Format("{0}~1~{1}~0", regValveId, j8), string.Format("{0}~0~{1}~0", j8, j9), string.Format("{0}~0~{1}~0", j9, diverterId), string.Format("{0}~0~{1}~0", scaleId, drainValveId), string.Format("{0}~1~{1}~0", drainValveId, j10), string.Format("{0}~1~{1}~0", diverterId, j11) }; } processDrawingCtrl.PipesXL = new string[0]; processDrawingCtrl.Route = 0; processDrawingCtrl.SupressRedraws = false; /// Invokes Dijkstra algoritm } void OnProcedureSelected(object sender, ProcedureSelectedEventArgs args) { metersKind = args.Procedure.MetersKind; InitializeDrawing(metersKind); InitializeTestDataTable(testDataListView, null); InitializeTableOfMeters(metersListView, metersKind, (metersKind == MetersKind.Combined) ? TBF.Data.CompoundWMsCount : TBF.Data.WMsCount); } void OnTestSelected(object sender, TestSelectedEventArgs args) { InitializeTestDataTable(testDataListView, args); InitializeTableOfMeters(metersListView, metersKind, (metersKind == MetersKind.Combined) ? TBF.Data.CompoundWMsCount : TBF.Data.WMsCount, ProcessData.BatchRslts.Batch.WaterMeters); compoundDetectionTextBox.Visible = (metersKind == MetersKind.Combined); compoundDetectionTextBox.Text = string.Empty; 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"; tempInCfg.MsrdFormat = (args.BenchPath != null && args.BenchPath.TempMtrUp != null) ? args.BenchPath.TempMtrUp.MsrdFormat : "{0:F1} °C"; tempInCfg.MsrdUnit = (args.BenchPath != null && args.BenchPath.TempMtrUp != null) ? args.BenchPath.TempMtrUp.MsrdUnit : Unit.C; tempInCfg.MsrdValLimLo = (args.BenchPath != null && args.BenchPath.TempMtrUp != null) ? args.BenchPath.TempMtrUp.MsrdValLimLo : 5; tempInCfg.MsrdValLimHi = (args.BenchPath != null && args.BenchPath.TempMtrUp != null) ? args.BenchPath.TempMtrUp.MsrdValLimHi : 95; pressUpCfg.Name = (args.BenchPath != null && args.BenchPath.PressMtrUp != null) ? args.BenchPath.PressMtrUp.Name : "n/a"; pressUpCfg.MsrdFormat = (args.BenchPath != null && args.BenchPath.PressMtrUp != null) ? args.BenchPath.PressMtrUp.MsrdFormat : "{0:F2} bar"; pressUpCfg.MsrdUnit = (args.BenchPath != null && args.BenchPath.PressMtrUp != null) ? args.BenchPath.PressMtrUp.MsrdUnit : Unit.bar; pressUpCfg.MsrdValLimLo = (args.BenchPath != null && args.BenchPath.PressMtrUp != null) ? args.BenchPath.PressMtrUp.MsrdValLimLo : 0; pressUpCfg.MsrdValLimHi = (args.BenchPath != null && args.BenchPath.PressMtrUp != null) ? args.BenchPath.PressMtrUp.MsrdValLimHi : 15; //Electric electricUpCfg.Name = (args.BenchPath != null && args.BenchPath.ElectricMtrUp != null) ? args.BenchPath.ElectricMtrUp.Name : "n/a"; electricUpCfg.MsrdFormat = (args.BenchPath != null && args.BenchPath.ElectricMtrUp != null) ? args.BenchPath.ElectricMtrUp.MsrdFormat : "{0:F2} A"; electricUpCfg.MsrdUnit = (args.BenchPath != null && args.BenchPath.ElectricMtrUp != null) ? args.BenchPath.ElectricMtrUp.MsrdUnit : Unit.A; electricUpCfg.MsrdValLimLo = (args.BenchPath != null && args.BenchPath.ElectricMtrUp != null) ? args.BenchPath.ElectricMtrUp.MsrdValLimLo : 0; electricUpCfg.MsrdValLimHi = (args.BenchPath != null && args.BenchPath.ElectricMtrUp != null) ? args.BenchPath.ElectricMtrUp.MsrdValLimHi : 15; tempOutCfg.Name = (args.BenchPath != null && args.BenchPath.TempMtrDown != null) ? args.BenchPath.TempMtrDown.Name : "n/a"; tempOutCfg.MsrdFormat = (args.BenchPath != null && args.BenchPath.TempMtrDown != null) ? args.BenchPath.TempMtrDown.MsrdFormat : "{0:F1} °C"; tempOutCfg.MsrdUnit = (args.BenchPath != null && args.BenchPath.TempMtrDown != null) ? args.BenchPath.TempMtrDown.MsrdUnit : Unit.C; tempOutCfg.MsrdValLimLo = (args.BenchPath != null && args.BenchPath.TempMtrDown != null) ? args.BenchPath.TempMtrDown.MsrdValLimLo : 5; tempOutCfg.MsrdValLimHi = (args.BenchPath != null && args.BenchPath.TempMtrDown != null) ? args.BenchPath.TempMtrDown.MsrdValLimHi : 95; pressDnCfg.Name = (args.BenchPath != null && args.BenchPath.PressMtrDown != null) ? args.BenchPath.PressMtrDown.Name : "n/a"; pressDnCfg.MsrdFormat = (args.BenchPath != null && args.BenchPath.PressMtrDown != null) ? args.BenchPath.PressMtrDown.MsrdFormat : "{0:F2} bar"; pressDnCfg.MsrdUnit = (args.BenchPath != null && args.BenchPath.PressMtrDown != null) ? args.BenchPath.PressMtrDown.MsrdUnit : Unit.bar; pressDnCfg.MsrdValLimLo = (args.BenchPath != null && args.BenchPath.PressMtrDown != null) ? args.BenchPath.PressMtrDown.MsrdValLimLo : 0; pressDnCfg.MsrdValLimHi = (args.BenchPath != null && args.BenchPath.PressMtrDown != null) ? args.BenchPath.PressMtrDown.MsrdValLimHi : 15; //Electric electricDownCfg.Name = (args.BenchPath != null && args.BenchPath.ElectricMtrDown != null) ? args.BenchPath.ElectricMtrDown.Name : "n/a"; electricDownCfg.MsrdFormat = (args.BenchPath != null && args.BenchPath.ElectricMtrDown != null) ? args.BenchPath.ElectricMtrDown.MsrdFormat : "{0:F2} A"; electricDownCfg.MsrdUnit = (args.BenchPath != null && args.BenchPath.ElectricMtrDown != null) ? args.BenchPath.ElectricMtrDown.MsrdUnit : Unit.A; electricDownCfg.MsrdValLimLo = (args.BenchPath != null && args.BenchPath.ElectricMtrDown != null) ? args.BenchPath.ElectricMtrDown.MsrdValLimLo : 0; electricDownCfg.MsrdValLimHi = (args.BenchPath != null && args.BenchPath.ElectricMtrDown != null) ? args.BenchPath.ElectricMtrDown.MsrdValLimHi : 15; /// Output path startValveCfg.Name = (args.OutputPath != null && args.OutputPath.StartValve1 != null) ? args.OutputPath.StartValve1.Name : "n/a"; flowMeterCfg.Name = (args.OutputPath != null && args.OutputPath.FlowMeter != null) ? args.OutputPath.FlowMeter.Name : "n/a"; flowMeterCfg.MsrdFormat = (args.OutputPath != null && args.OutputPath.FlowMeter != null) ? args.OutputPath.FlowMeter.MsrdFormat : "{0:F3} m3/h"; flowMeterCfg.MsrdUnit = (args.OutputPath != null && args.OutputPath.FlowMeter != null) ? args.OutputPath.FlowMeter.MsrdUnit : Unit.m3ph; flowMeterCfg.MsrdValLimLo = (args.OutputPath != null && args.OutputPath.FlowMeter != null) ? args.OutputPath.FlowMeter.MsrdValLimLo : 0; flowMeterCfg.MsrdValLimHi = (args.OutputPath != null && args.OutputPath.FlowMeter != null) ? args.OutputPath.FlowMeter.MsrdValLimHi : 1600; regValveCfg.Name = (args.OutputPath != null && args.OutputPath.RegValve != null) ? args.OutputPath.RegValve.Name : "n/a"; tempDivCfg.Name = (args.OutputPath != null && args.OutputPath.TempMtrDiv != null) ? args.OutputPath.TempMtrDiv.Name : "n/a"; tempDivCfg.MsrdFormat = (args.OutputPath != null && args.OutputPath.TempMtrDiv != null) ? args.OutputPath.TempMtrDiv.MsrdFormat : "{0:F1} °C"; tempDivCfg.MsrdUnit = (args.OutputPath != null && args.OutputPath.TempMtrDiv != null) ? args.OutputPath.TempMtrDiv.MsrdUnit : Unit.C; tempDivCfg.MsrdValLimLo = (args.OutputPath != null && args.OutputPath.TempMtrDiv != null) ? args.OutputPath.TempMtrDiv.MsrdValLimLo : 5; tempDivCfg.MsrdValLimHi = (args.OutputPath != null && args.OutputPath.TempMtrDiv != null) ? args.OutputPath.TempMtrDiv.MsrdValLimHi : 95; diverterCfg.Name = (args.OutputPath != null && args.OutputPath.Diverter != null) ? args.OutputPath.Diverter.Name : "n/a"; scaleCfg.Name = (args.OutputPath != null && args.OutputPath.Scale != null) ? args.OutputPath.Scale.Name : "n/a"; scaleCfg.Capacity = (args.OutputPath != null && args.OutputPath.Scale != null) ? args.OutputPath.Scale.Capacity : 100.0; drainValveCfg.Name = (args.OutputPath != null && args.OutputPath.Scale != null && args.OutputPath.Scale.DrainValve != null) ? args.OutputPath.Scale.DrainValve.Name : "n/a"; /// Meters path if (metersKind == MetersKind.Combined) { wm1Cfg.Name = "WM1 main"; wm2Cfg.Name = "WM1 aux"; } else if (args.MetersPath != null && args.MetersPath.RegisterReaders != null) { var rrs = args.MetersPath.RegisterReaders; int first = 0; int last = ProcessData.WMsCount; for (int i = 0; i < rrs.Length; i++) { if (first == 0 && rrs[i] != null) first = i + 1; if (first != 0 && rrs[i] == null) { last = i; break; } } wm1Cfg.Name = string.Format("WM{0}", first); wm2Cfg.Name = string.Format("WM{0}", first + 1); wmLastCfg.Name = string.Format("WM{0}", last); } else { wm1Cfg.Name = "WM1"; wm2Cfg.Name = "WM2"; wmLastCfg.Name = "WMn"; } /// Route based - pump if (args.FeedingPath != null && args.FeedingPath.Pump != null && args.FeedingPath.Pump.Cfg is Rig.BuiltIn.Pump.PumpCfg) { pumpCfg.BitNr = (args.FeedingPath.Pump.Cfg as Rig.BuiltIn.Pump.PumpCfg).BitNr; pumpCfg.Inverted = (args.FeedingPath.Pump.Cfg as Rig.BuiltIn.Pump.PumpCfg).Inverted; } else if (args.FeedingPath != null && args.FeedingPath.Pump != null && args.FeedingPath.Pump.Cfg is Rig.Modbus.PumpFM.DanfossVLT.PumpCfg) { pumpCfg.BitNr = (args.FeedingPath.Pump.Cfg as Rig.Modbus.PumpFM.DanfossVLT.PumpCfg).BitNr; pumpCfg.Inverted = (args.FeedingPath.Pump.Cfg as Rig.Modbus.PumpFM.DanfossVLT.PumpCfg).Inverted; } else if (args.FeedingPath != null && args.FeedingPath.Pump != null && args.FeedingPath.Pump.Cfg is Rig.Modbus.PumpFM.Grundfoss.PumpCfg) { pumpCfg.BitNr = (args.FeedingPath.Pump.Cfg as Rig.Modbus.PumpFM.Grundfoss.PumpCfg).BitNr; pumpCfg.Inverted = (args.FeedingPath.Pump.Cfg as Rig.Modbus.PumpFM.Grundfoss.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 Rig.BuiltIn.Valve.ValveCfg) { startValveCfg.BitNr = (args.OutputPath.StartValve1.Cfg as Rig.BuiltIn.Valve.ValveCfg).BitNr; startValveCfg.Inverted = (args.OutputPath.StartValve1.Cfg as Rig.BuiltIn.Valve.ValveCfg).Inverted; } else if (args.OutputPath != null && args.OutputPath.StartValve1 != null && args.OutputPath.StartValve1.Cfg is Rig.BuiltIn.ValveEx.ValveCfg) { startValveCfg.BitNr = (args.OutputPath.StartValve1.Cfg as 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 Rig.Uni.Diverter.DiverterCfg) { diverterCfg.BitNr = (args.OutputPath.Diverter.Cfg as Rig.Uni.Diverter.DiverterCfg).BitNr; diverterCfg.Inverted = (args.OutputPath.Diverter.Cfg as 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 Rig.BuiltIn.Valve.ValveCfg) { drainValveCfg.BitNr = (args.OutputPath.Scale.DrainValve.Cfg as Rig.BuiltIn.Valve.ValveCfg).BitNr; drainValveCfg.Inverted = (args.OutputPath.Scale.DrainValve.Cfg as 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; cmpntWithMeasuredVal[electricMtrUpMsrdIx] = args.BenchPath.ElectricMtrUp as IDrawingItCmpntWithMeasuredVal; cmpntWithMeasuredVal[electricMtrDownMsrdIx] = args.BenchPath.ElectricMtrDown as IDrawingItCmpntWithMeasuredVal; cmpntWithSetpoint[regValveSetpIx] = args.OutputPath.RegValve as IDrawingItCmpntWithSetpoint; cmpntWithSetpoint[pumpSetpIx] = args.FeedingPath.Pump as IDrawingItCmpntWithSetpoint; UpdateRouteMsrdValuesAndSetpoints(Rig.StateMachine.ControlBoardMain != null ? Rig.StateMachine.ControlBoardMain.Route : 0); processDrawingCtrl.SupressRedraws = false; } /// /// This function copies route and process values to the schematic drawing control. /// Schematic drawing is then redrawn accordingly in the next OnPaint(). /// /// /// void OnStateMachineTick(object sender, StateMachineTickEventArgs args) { log.DebugFormat("OnStateMachineTick: startMassIx={0} massIx={1} volumeIx={2} refErrorIx={3} itemsCount={4}", startMassIx, massIx, volumeIx, refErrorIx, testDataListView.Items.Count); try { /// /// Update test data /// if (refErrorIx != 0 && testDataListView.Items.Count > refErrorIx) { if (ProcessData.StartMass.Valid) { double converted = Units.ConvertTo(ProcessData.MassUnit, ProcessData.StartMass.Val); testDataListView.Items[startMassIx].SubItems[1].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 6)); converted = Units.ConvertTo(ProcessData.MassUnit, ProcessData.Mass - ProcessData.StartMass.Val); testDataListView.Items[massIx].SubItems[1].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 6)); } else { testDataListView.Items[startMassIx].SubItems[1].Text = "---"; testDataListView.Items[massIx].SubItems[1].Text = "---"; } if (Rig.StateMachine.ControlBoardMain.Activity == Rig.ControlBoard.Activity.FlyingStartStopTestWithDiverter) { double density = Formulas.WaterDensityFromTempPress((ProcessData.TempUp.Val + ProcessData.TempDown.Val) / 2, (ProcessData.PressUp.Val + ProcessData.PressDown.Val) / 2); double volumeCtv = 1000 * Formulas.Buoyancy() * (ProcessData.Mass - ProcessData.StartMass.Val) / density; //double refVolume = cBrd.RefPulses * cBrd.Devices.FlowMeter.LtrPerPulse; double refVolume = (ProcessData.Devices != null && ProcessData.Devices.FlowMeter != null) ? ProcessData.Devices.FlowMeter.LtrPerPulse * ProcessData.RefPulses : 0; double refError = Formulas.ErrorFromVolumes(refVolume, volumeCtv); double converted = Units.ConvertTo(ProcessData.VolumeUnit, volumeCtv); testDataListView.Items[volumeIx].SubItems[1].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 5)); testDataListView.Items[refErrorIx].SubItems[1].Text = refError.ToString(Common.Utils.SignificantDigitsToFmt(refError, 3)); } else if (Rig.StateMachine.ControlBoardMain.Activity == Rig.ControlBoard.Activity.FlyingStartStopTest) { double refVolume = (ProcessData.Devices != null && ProcessData.Devices.FlowMeter != null) ? ProcessData.Devices.FlowMeter.LtrPerPulse * ProcessData.RefPulses : 0; double converted = Units.ConvertTo(ProcessData.VolumeUnit, refVolume); testDataListView.Items[volumeIx].SubItems[1].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 5)); testDataListView.Items[refErrorIx].SubItems[1].Text = "---"; } else if (Rig.StateMachine.ControlBoardMain.Activity == Rig.ControlBoard.Activity.StandingStartStopTest) { /// TODO: ??? //var converted = Units.ConvertTo(ProcessData.VolumeUnit, volumeCtv); //testDataListView.Items[volumeIx].SubItems[1].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 5)); //testDataListView.Items[refErrorIx].SubItems[1].Text = "---"; } else { testDataListView.Items[volumeIx].SubItems[1].Text = "---"; testDataListView.Items[refErrorIx].SubItems[1].Text = "---"; } } /// /// Update water meter states /// var rrs = ProcessData.RegisterReaders; if (ProcessData.Devices != null && ProcessData.Devices.FlowMeter != null && rrs != null && (Rig.StateMachine.ControlBoardMain.Activity == Rig.ControlBoard.Activity.FlyingStartStopTest || Rig.StateMachine.ControlBoardMain.Activity == Rig.ControlBoard.Activity.FlyingStartStopTestWithDiverter || Rig.StateMachine.ControlBoardMain.Activity == Rig.ControlBoard.Activity.StandingStartStopTest)) { if (metersKind == MetersKind.Single) { for (int i = 0; i < TBF.Data.WMsCount; i++) { if (i < metersListView.Items.Count && i < rrs.Length) { /// Update a list view item belonging to the (single) water meter var lvi = metersListView.Items[i]; var rr = rrs[i]; if (rr != null && rr.WMPulses != 0) { /// Single meter double wmVolume = rr.WMPulses * rr.LtrsPerPulse; double wmRefVolume = rr.WMRefPulses * ProcessData.Devices.FlowMeter.LtrPerPulse; double error = Formulas.ErrorFromVolumes(wmVolume, wmRefVolume); double convertedVol = Units.ConvertTo(ProcessData.VolumeUnit, wmVolume); lvi.SubItems[(int)Column.Error].Text = error.ToString(Common.Utils.SignificantDigitsToFmt(error, 2)); lvi.SubItems[(int)Column.Volume].Text = convertedVol.ToString(Common.Utils.SignificantDigitsToFmt(convertedVol, 5)); lvi.SubItems[(int)Column.Pulses].Text = rr.WMPulses.ToString(); lvi.SubItems[(int)Column.RefPulses].Text = rr.WMRefPulses.ToString(); lvi.SubItems[(int)Column.PulsesPerLtr].Text = rr.PulsesPerLtr.ToString(); if (rr is Rig.RegisterReaders.S640Stream.S640Stream) { lvi.SubItems[(int)Column.SerialNr].Text = (rr as Rig.RegisterReaders.S640Stream.S640Stream).PcbNumber.ToString(); } } } } } else if (metersKind == MetersKind.Combined) { for (int i = 0; i < TBF.Data.CompoundWMsCount; i++) { if (3 * i + 2 < metersListView.Items.Count && 2 * i + 1 < rrs.Length) { var rrMain = rrs[2 * i]; var rrAux = rrs[2 * i + 1]; if (rrMain != null && rrAux != null) { /// Total result (sum of main and aux meter) of a compound meter double volMain = rrMain.WMPulses * rrMain.LtrsPerPulse; double volAux = rrAux.WMPulses * rrAux.LtrsPerPulse; double wmVolume = volMain + volAux; double wmRefVolume = Math.Max(rrMain.WMRefPulses, rrAux.WMRefPulses) * ProcessData.Devices.FlowMeter.LtrPerPulse; double error = Formulas.ErrorFromVolumes(wmVolume, wmRefVolume); double convMain = Units.ConvertTo(ProcessData.VolumeUnit, volMain); double convAux = Units.ConvertTo(ProcessData.VolumeUnit, volAux); double convVol = Units.ConvertTo(ProcessData.VolumeUnit, wmVolume); var lviTot = metersListView.Items[3 * i]; lviTot.SubItems[(int)Column.Error].Text = error.ToString(Common.Utils.SignificantDigitsToFmt(error, 2)); lviTot.SubItems[(int)Column.Volume].Text = convVol.ToString(Common.Utils.SignificantDigitsToFmt(convVol, 5)); if (rrMain.WMRefPulses != 0) lviTot.SubItems[(int)Column.RefPulses].Text = rrMain.WMRefPulses.ToString(); /// Main meter var lviMain = metersListView.Items[3 * i + 1]; if (rrMain.WMPulses != 0) { lviMain.SubItems[(int)Column.Volume].Text = convMain.ToString(Common.Utils.SignificantDigitsToFmt(convMain, 5)); lviMain.SubItems[(int)Column.Pulses].Text = rrMain.WMPulses.ToString(); lviMain.SubItems[(int)Column.RefPulses].Text = rrMain.WMRefPulses.ToString(); } lviMain.SubItems[(int)Column.PulsesPerLtr].Text = rrMain.PulsesPerLtr.ToString(); /// Aux meter var lviAux = metersListView.Items[3 * i + 2]; if (rrAux.WMPulses != 0) { lviAux.SubItems[(int)Column.Volume].Text = convAux.ToString(Common.Utils.SignificantDigitsToFmt(convAux, 5)); lviAux.SubItems[(int)Column.Pulses].Text = rrAux.WMPulses.ToString(); lviAux.SubItems[(int)Column.RefPulses].Text = rrAux.WMRefPulses.ToString(); } lviAux.SubItems[(int)Column.PulsesPerLtr].Text = rrAux.PulsesPerLtr.ToString(); } } } } else if (metersKind == MetersKind.HeatMeter) { /// TODO } else { foreach (var lvi in metersListView.Items) { (lvi as ListViewItem).SubItems[(int)Column.Error].Text = string.Empty; (lvi as ListViewItem).SubItems[(int)Column.Volume].Text = string.Empty; (lvi as ListViewItem).SubItems[(int)Column.Pulses].Text = string.Empty; (lvi as ListViewItem).SubItems[(int)Column.RefPulses].Text = string.Empty; (lvi as ListViewItem).SubItems[(int)Column.PulsesPerLtr].Text = string.Empty; } } } /// /// Redraw schematic drawing /// UpdateRouteMsrdValuesAndSetpoints(args.Route); } 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[i] = (cmpntWithSetpoint[i] != null) ? cmpntWithSetpoint[i].SetpointVal : 0; } } void OnCompoundDetection(object sender, CompoundDetectionEventArgs args) { compoundDetectionTextBox.AppendText(args.Message + Environment.NewLine); } void OnFlowDetected(object sender, FlowDetectedEventArgs args) { if (args != null && testDataListView.Items.Count > testtimeIx) { double qfrom = Units.ConvertTo(ProcessData.FlowUnit, args.Qfrom); testDataListView.Items[qfromIx].SubItems[1].Text = qfrom.ToString(Common.Utils.SignificantDigitsToFmt(qfrom, 3)); double qto = Units.ConvertTo(ProcessData.FlowUnit, args.Qto); testDataListView.Items[qtoIx].SubItems[1].Text = qto.ToString(Common.Utils.SignificantDigitsToFmt(qto, 3)); testDataListView.Items[testtimeIx].SubItems[1].Text = args.TestTime.ToString("F1"); } } void OnTestCompleted(object sender, TestCompletedEventArgs args) { if (args.TestRslt == null || ProcessData.RegisterReaders == null || ProcessData.BatchRslts == null || ProcessData.BatchRslts.Batch == null || ProcessData.BatchRslts.Batch.WaterMeters == null) { return; } /// TODO: ??? update mass //double converted = Units.ConvertTo(ProcessData.VolumeUnit, args.TestRslt.MassEnd - args.TestRslt.MassStart); //testDataListView.Items[volumeIx].SubItems[1].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 5)); double converted = Units.ConvertTo(ProcessData.VolumeUnit, args.TestRslt.VolumeCTV); testDataListView.Items[volumeIx].SubItems[1].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 5)); testDataListView.Items[refErrorIx].SubItems[1].Text = args.TestRslt.ErrorMaster.ToString(Common.Utils.SignificantDigitsToFmt(args.TestRslt.ErrorMaster, 3)); int wmsCount = (metersKind == MetersKind.Combined) ? TBF.Data.CompoundWMsCount : TBF.Data.WMsCount; int rowsCount = (metersKind == MetersKind.Combined) ? 2 * TBF.Data.CompoundWMsCount : TBF.Data.WMsCount; if (metersListView.Items.Count != rowsCount) { InitializeTableOfMeters(metersListView, metersKind, wmsCount); } if (args.TestRslt != null) { if (ProcessData.BatchRslts.Batch.WaterMeters.Count < wmsCount) { throw new Exception("Water Meter components cout is smaller as Bench Info water meter count!"); } for (int i = 0; i < wmsCount; i++) { var wm = ProcessData.BatchRslts.Batch.WaterMeters[i]; if (wm != null && !wm.Disabled) { /// Update list view items if (metersKind == MetersKind.Single) { var mtr = wm.MeterTestRslts.FirstOrDefault(x => x.TestRslt == args.TestRslt && x.CompoundMeterId == (byte)Common.CompoundMeterId.Single); if (mtr != null && i < metersListView.Items.Count) { var lvi = metersListView.Items[i]; lvi.SubItems[(int)Column.Error].Text = mtr.Error.ToString(Common.Utils.SignificantDigitsToFmt(mtr.Error, 3)); converted = Units.ConvertTo(ProcessData.VolumeUnit, mtr.VolumeMeter); lvi.SubItems[(int)Column.Volume].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 5)); lvi.SubItems[(int)Column.Pulses].Text = mtr.PulsesMeter.ToString(); lvi.SubItems[(int)Column.RefPulses].Text = mtr.PulsesMaster.ToString(); if (!string.IsNullOrEmpty(mtr.SerialNr())) lvi.SubItems[(int)Column.SerialNr].Text = mtr.SerialNr(); } } else if (metersKind == MetersKind.Combined) { var mtr = wm.MeterTestRslts.FirstOrDefault(x => x.TestRslt == args.TestRslt && x.CompoundMeterId == (byte)Common.CompoundMeterId.Compound); var mtrMain = wm.MeterTestRslts.FirstOrDefault(x => x.TestRslt == args.TestRslt && x.CompoundMeterId == (byte)Common.CompoundMeterId.CompoundMain); var mtrAux = wm.MeterTestRslts.FirstOrDefault(x => x.TestRslt == args.TestRslt && x.CompoundMeterId == (byte)Common.CompoundMeterId.CompoundAux); if (mtr != null && 3 * i < metersListView.Items.Count) { /// Compound meter (sum) var lvi = metersListView.Items[3 * i]; lvi.SubItems[(int)Column.Error].Text = mtr.Error.ToString(Common.Utils.SignificantDigitsToFmt(mtr.Error, 3)); converted = Units.ConvertTo(ProcessData.VolumeUnit, mtr.VolumeMeter); lvi.SubItems[(int)Column.Volume].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 5)); lvi.SubItems[(int)Column.Pulses].Text = "---"; lvi.SubItems[(int)Column.RefPulses].Text = mtr.PulsesMaster.ToString(); } if (mtrMain != null && 3 * i + 1 < metersListView.Items.Count) { /// Compound meter - main var lvi = metersListView.Items[3 * i + 1]; lvi.SubItems[(int)Column.Error].Text = "---"; converted = Units.ConvertTo(ProcessData.VolumeUnit, mtrMain.VolumeMeter); lvi.SubItems[(int)Column.Volume].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 5)); lvi.SubItems[(int)Column.Pulses].Text = mtrMain.PulsesMeter.ToString(); lvi.SubItems[(int)Column.RefPulses].Text = "---"; if (!string.IsNullOrEmpty(mtrMain.SerialNr())) lvi.SubItems[(int)Column.SerialNr].Text = mtrMain.SerialNr(); } if (mtrAux != null && 3 * i + 2 < metersListView.Items.Count) { /// Compound meter - aux var lvi = metersListView.Items[3 * i + 2]; lvi.SubItems[(int)Column.Error].Text = "---"; converted = Units.ConvertTo(ProcessData.VolumeUnit, mtrAux.VolumeMeter); lvi.SubItems[(int)Column.Volume].Text = converted.ToString(Common.Utils.SignificantDigitsToFmt(converted, 5)); lvi.SubItems[(int)Column.Pulses].Text = mtrAux.PulsesMeter.ToString(); lvi.SubItems[(int)Column.RefPulses].Text = "---"; if (!string.IsNullOrEmpty(mtrAux.SerialNr())) lvi.SubItems[(int)Column.SerialNr].Text = mtrAux.SerialNr(); } } } } } } private void ProcessTabPageCtrl_Paint(object sender, PaintEventArgs e) { CreateGraphics(); } } }