diff --git a/Results/Entities/Batch.cs b/Results/Entities/Batch.cs index 1f5651e5e..02afc2904 100644 --- a/Results/Entities/Batch.cs +++ b/Results/Entities/Batch.cs @@ -39,6 +39,7 @@ namespace Results.Entities public virtual int Counter10 { get; set; } public virtual DateTime StartTime { get; set; } public virtual DateTime EndTime { get; set; } + public virtual DateTime SaveTime { get; set; } public virtual bool Dirty { get; set; } public virtual bool RsltsSent { get; set; } public virtual bool RsltsPrinted { get; set; } @@ -157,6 +158,7 @@ namespace Results.Entities Counter10 = oriBatch.Counter10; StartTime = oriBatch.StartTime; EndTime = oriBatch.EndTime; + SaveTime = oriBatch.SaveTime; Dirty = oriBatch.Dirty; RsltsSent = oriBatch.RsltsSent; RsltsPrinted = oriBatch.RsltsPrinted; @@ -321,16 +323,19 @@ namespace Results.Entities public override string ToString() { - return string.Format("Batch #{0}, Start:{1}, End:{2}, Procedure:{3}", BatchNr, StartTime, EndTime, ProcedureName); + return string.Format("Batch {0} ({1}s) Start {2}, End {3}, Proc={4}", + BatchNr, (EndTime - StartTime).TotalSeconds, StartTime, EndTime, ProcedureName); } public virtual string ToString(int i) { - return string.Format("Batch: BatchNr={0} ProgramVersion={1} TestBenchId={2} UserName={3} UserNumber={4} ProcedureName={5}{6} ProcRev={7} ProtocolTitle={8} Remark={9} RealDensity={10} AtTemperature={11} Buoyancy={12} StartTime={13} EndTime={14} Dirty={15} RsltsSent={16} RsltsPrinted={17}", - BatchNr, ProgramVersion, TestBenchId, UserName, UserNumber, + return string.Format("Batch {0} ({1}s) ver={2} TestBenchId={3} User={4}/{5} Proc={6}{7} Rev={8} Remark={9} RealDensity={10} AtTemperature={11} Buoyancy={12} StartTime={13} EndTime={14} SaveTime={15} RsltsSent={16} RsltsPrinted={17}", + BatchNr, + (EndTime - StartTime).TotalSeconds, + ProgramVersion, TestBenchId, UserName, UserNumber, ProcedureName, (IsRemoteProcedure ? "(R)" : ""), ProcedureRevision, - ProtocolTitle, Remark, RealDensity, AtTemperature, Buoyancy, - StartTime, EndTime, Dirty, RsltsSent, RsltsPrinted); + Remark, RealDensity, AtTemperature, Buoyancy, + StartTime, EndTime, SaveTime, RsltsSent, RsltsPrinted); } public virtual void WriteBinary(BinaryWriter writer) @@ -364,6 +369,7 @@ namespace Results.Entities writer.Write(Counter10); writer.Write(StartTime.ToString()); writer.Write(EndTime.ToString()); + writer.Write(SaveTime.ToString()); writer.Write(Dirty); writer.Write(RsltsSent); writer.Write(RsltsPrinted); @@ -431,6 +437,7 @@ namespace Results.Entities Counter10 = reader.ReadInt32(); StartTime = DateTime.Parse(reader.ReadString()); EndTime = DateTime.Parse(reader.ReadString()); + SaveTime = DateTime.Parse(reader.ReadString()); Dirty = reader.ReadBoolean(); RsltsSent = reader.ReadBoolean(); RsltsPrinted = reader.ReadBoolean(); diff --git a/Results/Entities/TestRslt.cs b/Results/Entities/TestRslt.cs index d561f4980..9380b0db7 100644 --- a/Results/Entities/TestRslt.cs +++ b/Results/Entities/TestRslt.cs @@ -148,6 +148,7 @@ namespace Results.Entities /// Wrappers public virtual string Name() { return Common.Utils.GetTestName(TestData.Name, TestData.Repeats, RepetitionNr); } + public virtual string Key() { return string.Format("{0}~{1}~{2}~{3}", TestData.Name, Part, TestData.Repeats, RepetitionNr); } /// Unique key public virtual int Repeats() { return TestData.Repeats; } public virtual double Qfrom() { return TestData.Qfrom; } public virtual double Qto() { return TestData.Qto; } diff --git a/Results/Mappings/BatchMap.cs b/Results/Mappings/BatchMap.cs index 385861e16..7556785bd 100644 --- a/Results/Mappings/BatchMap.cs +++ b/Results/Mappings/BatchMap.cs @@ -35,6 +35,7 @@ namespace Results.Mappings Map(x => x.StartTime); Map(x => x.EndTime); + Map(x => x.SaveTime); Map(x => x.Dirty); Map(x => x.RsltsSent); Map(x => x.RsltsPrinted); diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index c2bccd3bf..404375524 100644 --- a/TBF/Properties/AssemblyInfo.cs +++ b/TBF/Properties/AssemblyInfo.cs @@ -29,5 +29,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("2.31.2018.0")] -[assembly: AssemblyFileVersion("2.31.2018.0")] +[assembly: AssemblyVersion("2.32.2022.0")] +[assembly: AssemblyFileVersion("2.32.2022.0")] diff --git a/TBF/Resources/Strings.cs.resx b/TBF/Resources/Strings.cs.resx index 44208df1e..c29a998bd 100644 --- a/TBF/Resources/Strings.cs.resx +++ b/TBF/Resources/Strings.cs.resx @@ -673,10 +673,10 @@ Tiskárna - Postup + Prodedura - Postupy + Procedury Výrobce @@ -688,7 +688,7 @@ Restart programu vyžaduje použít některá nastavení - V činnosti + Postup Vlastnosti diff --git a/TBF/Rig/Sequences/MainSeq.cs b/TBF/Rig/Sequences/MainSeq.cs index 8a67cf60c..b6e8ef83a 100644 --- a/TBF/Rig/Sequences/MainSeq.cs +++ b/TBF/Rig/Sequences/MainSeq.cs @@ -440,6 +440,7 @@ namespace TBF.Rig.Sequences { /// Clear session data in case this is not an interrupted/restored session ClearSessionData(); + SampleRemainingTimeSec.Clear(); } @@ -504,6 +505,60 @@ namespace TBF.Rig.Sequences { /// This is a regular session => initialize BatchRslts BatchRslts = CreateNewBatchResults(newBatchNr, StateMachine.Procedure); + Batch b = BatchRslts.Batch; + b.EndTime = DateTime.MinValue; /// Disable the batch end time estimate + + Batch sampleBatch = null; + using (ISession rsltsDB = Results.DB.CreateSession()) + { + var bts = rsltsDB.QueryOver() + .OrderBy(x => x.BatchNr).Desc + .Where(x => x.ProcedureName == StateMachine.Procedure.Name) + //.And(x => x.ProcedureRevision == StateMachine.Procedure.Revision) + .List(); + /// + /// Take the median batch of the last 7, 5, 3 or 1 batches + /// + if (bts.Count >= 7) + { + var batches7 = new List() { bts[0], bts[1], bts[2], bts[3], bts[4], bts[5], bts[6] }; + sampleBatch = batches7.OrderBy(x => (x.EndTime - x.StartTime)).Skip(3).Take(1).Single(); + } + else if (bts.Count >= 5) + { + var batches5 = new List() { bts[0], bts[1], bts[2], bts[3], bts[4] }; + sampleBatch = batches5.OrderBy(x => (x.EndTime - x.StartTime)).Skip(2).Take(1).Single(); + } + else if (bts.Count >= 3) + { + var batches3 = new List() { bts[0], bts[1], bts[2] }; + sampleBatch = batches3.OrderBy(x => (x.EndTime - x.StartTime)).Skip(1).Take(1).Single(); + } + else if (bts.Count >= 1) + { + sampleBatch = bts[0]; + } + + if (sampleBatch != null) + { + /// Update the batch end time estimate according to a sample batch + b.EndTime = b.StartTime + (sampleBatch.EndTime - sampleBatch.StartTime); + + /// Prepare the dictionary of remaining times for each completed test according to the sample batch + SampleRemainingTimeSec.Clear(); + foreach (TestRslt tr in sampleBatch.TestRslts) + { + if (TBF.Utils.IsHydroTest(tr.TestData.Method)) + { + string key = tr.Key(); + if (!SampleRemainingTimeSec.ContainsKey(key)) + { + SampleRemainingTimeSec.Add(key, sampleBatch.EndTime - tr.EndTime); + } + } + } + } + } } @@ -895,14 +950,10 @@ namespace TBF.Rig.Sequences for (int i = currentTestIx + 1; i < StateMachine.TestInstances.Length - simultWithEvacuationCount; i++) { Test tst = StateMachine.TestInstances[i].Test; - if (tst != null) + if (tst != null && TBF.Utils.IsHydroTest(tst.Method)) { - ITestMethod tm = TbfComponents.FindComponent(tst.Method) as ITestMethod; - if (tm != null && tm.DoTransitions()) - { nextHydroTest = tst; break; - } } } @@ -991,7 +1042,6 @@ namespace TBF.Rig.Sequences Bridge.OnTestProgress(this, new TestProgressEventArgs(testInst.Test, testInst.Repetition, Progress.JustStarted)); bool currentTestFinished = true; - bool doOneMoreRepetition = false; bool doExecuteTransitionBefore = (currentTestIx == simultWithPurgingCount) || (testInst.Test != StateMachine.TestInstances[currentTestIx - 1].Test) || veryFirstTestInTheRestOfCycle; bool isLastRepetition = (currentTestIx == StateMachine.TestInstances.Length - simultWithEvacuationCount - 1) || (testInst.Test != StateMachine.TestInstances[currentTestIx + 1].Test); @@ -1261,7 +1311,18 @@ namespace TBF.Rig.Sequences /// /// Update batch results, determine whether watermeters passed all required tests /// - BatchRslts.Batch.EndTime = DateTime.Now; /// Set cycle end time + + /// Determine the end of the last test and save it as the batch end time + DateTime lastTestEndTime = DateTime.MinValue; + if (BatchRslts.Batch.TestRslts != null) + { + foreach (var tr in BatchRslts.Batch.TestRslts) + { + if (tr.EndTime > lastTestEndTime) lastTestEndTime = tr.EndTime; + } + } + BatchRslts.Batch.EndTime = lastTestEndTime; + Results.Utils.GetCounterStates(BatchRslts.Batch, Program.LocalSettings.Counters); /// Update counters /// Remove results of internal tests for (int i = BatchRslts.Batch.TestRslts.Count - 1; i >= 0; i--) diff --git a/TBF/Rig/Sequences/ProcessData.cs b/TBF/Rig/Sequences/ProcessData.cs index e807931ec..991b6d058 100644 --- a/TBF/Rig/Sequences/ProcessData.cs +++ b/TBF/Rig/Sequences/ProcessData.cs @@ -47,6 +47,7 @@ namespace TBF.Rig.Sequences // public static TBF.UI.ProcedureInfo SelectedProcedure; public static Common.IOrderInfo OrderInfo; // public static SharedDatabase.WorkflowSummary WorkflowSummary; /// Selected production tracing workflow + public static IDictionary SampleRemainingTimeSec = new Dictionary(); /// /// State variables to be saved after each completed test diff --git a/TBF/UI/MainWnd.cs b/TBF/UI/MainWnd.cs index 65b1016db..f56100464 100644 --- a/TBF/UI/MainWnd.cs +++ b/TBF/UI/MainWnd.cs @@ -401,12 +401,38 @@ namespace TBF.UI void OnTestProgress(object sender, UiBridge.TestProgressEventArgs args) { - mainProgressBar.Value = (int)(100.499f * args.OveralProgress); + if (TBF.Rig.Sequences.ProcessData.BatchRslts != null) + { + var b = TBF.Rig.Sequences.ProcessData.BatchRslts.Batch; + if (b != null && b.EndTime > b.StartTime) + { + progressGroupBox.Text = string.Format("{0} @ {1}", Strings.End, b.EndTime.ToShortTimeString()); + } + else + { + progressGroupBox.Text = Strings.Progress; + } + } + else + { + progressGroupBox.Text = Strings.Progress; + } + + mainProgressBar.Value = (int)(100.499f * args.OveralProgress); } void OnProcedureSelected(object sender, UiBridge.ProcedureSelectedEventArgs args) { mainProgressBar.Value = 0; + + if (TBF.Rig.Sequences.ProcessData.BatchRslts != null) + { + var b = TBF.Rig.Sequences.ProcessData.BatchRslts.Batch; + if (b != null && b.EndTime > b.StartTime) + { + progressGroupBox.Text = string.Format("{0} @ {1}", Strings.End, b.EndTime.ToShortTimeString()); + } + } } /// @@ -445,6 +471,8 @@ namespace TBF.UI procedureComboBox.Enabled = ((args.Flags & ButtonsEtc.ProcedureCmbBoxEn) != 0); optoHeadsToolStripMenuItem.Enabled = ((args.Flags & ButtonsEtc.ProcedureCmbBoxEn) != 0); + if (procedureComboBox.Enabled) progressGroupBox.Text = Strings.Progress; + if (procedureComboBox.Enabled && ProceduresUpdated) { ReloadProcedureComboBoxItems(); diff --git a/TBF/UiBridge/Bridge.cs b/TBF/UiBridge/Bridge.cs index db5e82c2f..b84869ca2 100644 --- a/TBF/UiBridge/Bridge.cs +++ b/TBF/UiBridge/Bridge.cs @@ -135,6 +135,13 @@ namespace TBF.UiBridge { TBF.Rig.Sequences.ProcessData.SaveProcessData(); + /// Update the estimated batch end time + TimeSpan remainingTime; + if (data.TestRslt != null && TBF.Rig.Sequences.ProcessData.SampleRemainingTimeSec.TryGetValue(data.TestRslt.Key(), out remainingTime)) + { + TBF.Rig.Sequences.ProcessData.BatchRslts.Batch.EndTime = DateTime.Now + remainingTime; + } + if (TestCompletedHandler == null) return; try { TestCompletedHandler(sender, data); } catch (Exception e) { log.Error("TestCompletedHandler(...) failed", e); } diff --git a/TBF/UiBridge/TestCompletedEventArgs.cs b/TBF/UiBridge/TestCompletedEventArgs.cs index 2dc74b914..46040aadb 100644 --- a/TBF/UiBridge/TestCompletedEventArgs.cs +++ b/TBF/UiBridge/TestCompletedEventArgs.cs @@ -1,20 +1,20 @@ /// -/// Copyright (c) 2013-2016 Sensus Metering Systems +/// Copyright (c) 2013-2023 Sensus Slovensko a.s. /// using System; -using Config.Entities; +using Results.Entities; namespace TBF.UiBridge { public class TestCompletedEventArgs : EventArgs { public string TestName; - public Results.Entities.TestRslt TestRslt; /// If null => just redraw results + public TestRslt TestRslt; /// If null => just redraw results - public TestCompletedEventArgs(string testName, Results.Entities.TestRslt testRslt) + public TestCompletedEventArgs(string testName, TestRslt testRslt) { - this.TestName = testName; - this.TestRslt = testRslt; + TestName = testName; + TestRslt = testRslt; } } }