iPerl head failure rate is monitored by Various.StatisticsMonitoring component, ver. 2.26.1458
This commit is contained in:
parent
05f72bc9f7
commit
bc2804d0b9
@ -1,5 +1,5 @@
|
||||
///
|
||||
/// Copyright (c) 2013-2018 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2013-2020 Sensus Slovensko a.s.
|
||||
///
|
||||
namespace TBF.BenchControl
|
||||
{
|
||||
@ -155,6 +155,8 @@ namespace TBF.BenchControl
|
||||
ResultsProcessed, /// Event triggers
|
||||
ErrorProcessingResults,
|
||||
|
||||
StatisticsProcessed, /// Statistics monitoring (Event triggers)
|
||||
|
||||
/// Timer events
|
||||
TimerExpired,
|
||||
|
||||
|
||||
21
TBF/BenchControl/GenericDevices/IStatisticsMonitoring.cs
Normal file
21
TBF/BenchControl/GenericDevices/IStatisticsMonitoring.cs
Normal file
@ -0,0 +1,21 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TBF.BenchControl.Generic;
|
||||
using Results.Entities;
|
||||
|
||||
namespace TBF.BenchControl.GenericDevices
|
||||
{
|
||||
public interface IStatisticsMonitoring : IComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// Process recent results and monitor obtained statistics
|
||||
/// (failure rates of hardware components, etc.)
|
||||
/// </summary>
|
||||
/// <param name="lastBatchNr">Number of the last saved batch</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
IOperation ProcessStatisticsOp(int lastBatchNr);
|
||||
}
|
||||
}
|
||||
@ -1,27 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TBF.BenchControl.Generic;
|
||||
|
||||
namespace TBF.BenchControl.Output.EventTriggers.Statistics
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return this.GetType().Namespace.Substring(17); } }
|
||||
|
||||
public void ResetStaticProperties() { Trigger.ResetStaticProperties(); }
|
||||
|
||||
public IComponent DummyComponent() { return new Trigger(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new Trigger(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new TriggerCfg(this.GetType().Namespace.Substring(24), this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(TriggerCfg.Serializer, component, this);;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,106 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using log4net;
|
||||
|
||||
namespace TBF.BenchControl.Output.EventTriggers.Statistics
|
||||
{
|
||||
public class Trigger : ComponentBase, IOperation, GenericDevices.IEventTrigger
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(Trigger));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(1)); }
|
||||
|
||||
readonly TriggerCfg triggerCfg;
|
||||
|
||||
Results.Entities.Batch batch;
|
||||
|
||||
|
||||
public Trigger() {}
|
||||
|
||||
public Trigger(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
triggerCfg = cfg as TriggerCfg;
|
||||
ApplyConfig();
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
|
||||
void ApplyConfig()
|
||||
{
|
||||
}
|
||||
|
||||
#region Configuration Change Handling
|
||||
|
||||
public static void OnCfgChange(object sender, CfgChangeArgs args)
|
||||
{
|
||||
if (CfgChangeHandler == null) return;
|
||||
try { CfgChangeHandler(sender, args); }
|
||||
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
|
||||
}
|
||||
|
||||
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
|
||||
|
||||
public override void StartChangeHandler()
|
||||
{
|
||||
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
|
||||
{
|
||||
TriggerCfg newCfg = args.Cfg as TriggerCfg;
|
||||
if (newCfg != null && newCfg.Name.Equals(Name))
|
||||
{
|
||||
if (args.Command == CfgChangeCmd.CfgChange)
|
||||
{
|
||||
triggerCfg.EventSource = newCfg.EventSource;
|
||||
triggerCfg.Culture = newCfg.Culture;
|
||||
triggerCfg.EliminateSpaces = newCfg.EliminateSpaces;
|
||||
triggerCfg.PrintCaption = newCfg.PrintCaption;
|
||||
|
||||
ApplyConfig();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion Configuration Change Handling
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Writes the test cycle results into a file
|
||||
/// Events:
|
||||
/// Event.ResultsWritten
|
||||
/// Event.Busy
|
||||
/// </summary>
|
||||
/// <param name="batch">Results to write into a file</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ProcessResultsOp(Results.Entities.Batch batch)
|
||||
{
|
||||
this.batch = batch;
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
Process(batch);
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
/// <returns>Event.ResultsProcessed</returns>
|
||||
public Event Run()
|
||||
{
|
||||
return Event.ResultsProcessed;
|
||||
}
|
||||
|
||||
/// <summary>Stop this operation</summary>
|
||||
public void Stop()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Process(Results.Entities.Batch batch)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,170 +0,0 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
using Config.Entities;
|
||||
using TBF.BenchControl.Generic;
|
||||
using TBF.Resources;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TBF.BenchControl.Output.EventTriggers.Statistics
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializable configuration of Output.EventTriggers.Standard component.
|
||||
/// </summary>
|
||||
public class TriggerCfg : ComponentCfgBase, Generic.IComponentCfg, Config.Entities.IParamsProvider
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TriggerCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl() { return new Configs.ParamsProvider.ComponentCfgCtrl(this, null); }
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public string EventSource;
|
||||
public Culture Culture;
|
||||
public bool EliminateSpaces;
|
||||
public bool PrintCaption;
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
TriggerCfg() {}
|
||||
|
||||
public TriggerCfg(string name, IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
Name = name;
|
||||
Factory = factory;
|
||||
ParentName = string.Empty;
|
||||
InitializeAll();
|
||||
}
|
||||
|
||||
public string ComponentName { get { return Name; } }
|
||||
|
||||
public void InitializeAll()
|
||||
{
|
||||
EventSource = "Štatistiky výsledkov";
|
||||
Culture = Culture.EN;
|
||||
EliminateSpaces = false;
|
||||
PrintCaption = false;
|
||||
}
|
||||
|
||||
string[] paramNames = new string[]
|
||||
{
|
||||
"Event source",
|
||||
"Culture",
|
||||
"Eliminate spaces",
|
||||
"Print caption",
|
||||
};
|
||||
public string ParamName(int i) { return paramNames[i]; }
|
||||
public int ParamsCount() { return paramNames.Length; }
|
||||
|
||||
public IList<string> ParamValues(int i)
|
||||
{
|
||||
IList<string> listOfValues = new List<string>();
|
||||
if (i == 1)
|
||||
{
|
||||
for (Culture cu = 0; cu < Culture.Count; cu++) listOfValues.Add(cu.ToString());
|
||||
return listOfValues;
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
listOfValues.Add(Strings.yes);
|
||||
listOfValues.Add(Strings.no);
|
||||
return listOfValues;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case -1: return string.Format("Name={0}, FNameFmt={1}, NoSpaces={2}", Name, EventSource, EliminateSpaces);
|
||||
case 0: return EventSource;
|
||||
case 1: return Culture.ToString();
|
||||
case 2: return EliminateSpaces ? Strings.yes : Strings.no;
|
||||
case 3: return PrintCaption ? Strings.yes : Strings.no;
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateParam(int i, string strValue)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: EventSource = strValue; return CfgUpdateFlags.RestartRqrd;
|
||||
case 1:
|
||||
for (Culture cu = 0; cu < Culture.Count; cu++)
|
||||
{
|
||||
if (strValue == cu.ToString())
|
||||
{
|
||||
if (Culture != cu)
|
||||
{
|
||||
Culture = cu;
|
||||
return CfgUpdateFlags.RestartRqrd;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
return CfgUpdateFlags.Error;
|
||||
case 2: EliminateSpaces = (strValue == Strings.yes); return CfgUpdateFlags.RestartRqrd;
|
||||
case 3: PrintCaption = (strValue == Strings.yes); return CfgUpdateFlags.RestartRqrd;
|
||||
default: return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateParam(int i, string strValue, out string message)
|
||||
{
|
||||
message = string.Empty;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0: return true;
|
||||
case 1:
|
||||
for (Culture cu = 0; cu < Culture.Count; cu++)
|
||||
{
|
||||
if (strValue == cu.ToString()) return true;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
if (strValue == Strings.yes || strValue == Strings.no) return true;
|
||||
break;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
}
|
||||
|
||||
message = ParamName(i) + " is invalid";
|
||||
return false;
|
||||
}
|
||||
|
||||
void CopyContentTo(TriggerCfg prms)
|
||||
{
|
||||
prms.EventSource = this.EventSource;
|
||||
prms.Culture = this.Culture;
|
||||
prms.EliminateSpaces = this.EliminateSpaces;
|
||||
prms.PrintCaption = this.PrintCaption;
|
||||
}
|
||||
|
||||
public Config.Entities.IParamsProvider Clone()
|
||||
{
|
||||
TriggerCfg pars = new TriggerCfg();
|
||||
CopyContentTo(pars);
|
||||
return pars;
|
||||
}
|
||||
|
||||
public bool UpdateEmbeddedDbEntity()
|
||||
{
|
||||
return true; /// =OK, do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1233,6 +1233,7 @@ namespace TBF.BenchControl.Sequences
|
||||
string[] writers = (StateMachine.Procedure.ResultsWriter != null) ? StateMachine.Procedure.ResultsWriter.Split(new char[] { '~' }) : new string[0];
|
||||
string[] printers = (StateMachine.Procedure.ResultsPrinter != null) ? StateMachine.Procedure.ResultsPrinter.Split(new char[] { '~' }) : new string[0];
|
||||
string[] eventTriggers = (StateMachine.Procedure.EventTriggers != null) ? StateMachine.Procedure.EventTriggers.Split(new char[] { '~' }) : new string[0];
|
||||
///
|
||||
string[] rsltProcessors = new string[writers.Length + printers.Length + eventTriggers.Length];
|
||||
writers.CopyTo(rsltProcessors, 0);
|
||||
printers.CopyTo(rsltProcessors, writers.Length);
|
||||
@ -1294,14 +1295,29 @@ namespace TBF.BenchControl.Sequences
|
||||
ProcessData.BatchRslts.Batch.ProcedureName,
|
||||
Program.LocalSettings.BatchNr);
|
||||
|
||||
evacuation:
|
||||
|
||||
/// Evacuation is similar to 'Abort session' (no results are saved), but the evacuation is done as well.
|
||||
|
||||
StateMachine.ControlBoard.ManualUIAllowed = true;
|
||||
Event evacRetv = DoEvacuation(purgeEnd);
|
||||
Bridge.OnProcedureCompleted(this, new ProcedureCompletedEventArgs(StateMachine.Procedure));
|
||||
|
||||
///
|
||||
/// Process statistics (in each regular cycle after evacuation when ProcessData.StatisticsMonitoringComp is defined)
|
||||
///
|
||||
if (ProcessData.StatisticsMonitoringComp is IStatisticsMonitoring)
|
||||
{
|
||||
State.Create("MainSeq : Processing statistics")
|
||||
.AddOperation((ProcessData.StatisticsMonitoringComp as IStatisticsMonitoring).ProcessStatisticsOp(ProcessData.BatchRslts.Batch.BatchNr))
|
||||
.AddOperation(checkUiOp)
|
||||
.EnterState();
|
||||
do {
|
||||
e = StateMachine.WaitRunDevsRunOps();
|
||||
if (e.Contains(Event.UiCmdStop)) goto stop;
|
||||
}
|
||||
while (e.Contains(Event.Busy));
|
||||
}
|
||||
|
||||
///
|
||||
/// Procedure completed, branch depending on the result of evacuation
|
||||
///
|
||||
Bridge.OnProcedureCompleted(this, new ProcedureCompletedEventArgs(StateMachine.Procedure));
|
||||
switch (evacRetv)
|
||||
{
|
||||
case Event.Error: goto error;
|
||||
|
||||
@ -17,6 +17,7 @@ namespace TBF.BenchControl.Sequences
|
||||
///
|
||||
public static IBenchInfo BenchInfo;
|
||||
public static IErrorFlags ErrorFlagsComp;
|
||||
public static IStatisticsMonitoring StatisticsMonitoringComp;
|
||||
public static Output.DB.SensusOracle.Database OracleDB;
|
||||
|
||||
///
|
||||
|
||||
@ -232,6 +232,8 @@ namespace TBF.BenchControl
|
||||
if (cmpnt is Elde.ControlBoardDev) ControlBoard = cmpnt as Elde.ControlBoardDev;
|
||||
if (cmpnt is IBenchInfo) ProcessData.BenchInfo = cmpnt as IBenchInfo;
|
||||
if (cmpnt is IErrorFlags) ProcessData.ErrorFlagsComp = cmpnt as IErrorFlags;
|
||||
if (cmpnt is IStatisticsMonitoring) ProcessData.StatisticsMonitoringComp = cmpnt as IStatisticsMonitoring;
|
||||
|
||||
if ((cmpnt is Output.DB.SensusOracle.Database) && (ProcessData.OracleDB == null))
|
||||
{
|
||||
ProcessData.OracleDB = cmpnt as Output.DB.SensusOracle.Database;
|
||||
|
||||
@ -133,7 +133,6 @@ namespace TBF.BenchControl
|
||||
Factories.Add(new Output.DB.SensusOracle.Factory());
|
||||
Factories.Add(new Output.EventTriggers.Iperl.Factory());
|
||||
Factories.Add(new Output.EventTriggers.Standard.Factory());
|
||||
Factories.Add(new Output.EventTriggers.Statistics.Factory());
|
||||
Factories.Add(new Output.FileWriters.Basic.FactorySingle());
|
||||
Factories.Add(new Output.FileWriters.Basic.FactoryCompound());
|
||||
Factories.Add(new Output.FileWriters.Basic.FactoryHeatMeters());
|
||||
@ -185,7 +184,8 @@ namespace TBF.BenchControl
|
||||
Factories.Add(new Elde.ValveEx.ValveFactory());
|
||||
Factories.Add(new Various.ErrorFlags.Factory());
|
||||
Factories.Add(new Various.Evaporation.Factory());
|
||||
Factories.Add(new Various.TankWithLevelMsrmnt.Factory());
|
||||
Factories.Add(new Various.StatisticsMonitoring.Factory());
|
||||
Factories.Add(new Various.TankWithLevelMsrmnt.Factory());
|
||||
Factories.Add(new WaterMeters.Munich.WaterMeterFactory()); /// 'WaterMeters.Munich'
|
||||
Factories.Add(new WaterMeters.WaterMeter.WaterMeterFactory()); /// 'WaterMeter'
|
||||
}
|
||||
|
||||
27
TBF/BenchControl/Various/StatisticsMonitoring/Factory.cs
Normal file
27
TBF/BenchControl/Various/StatisticsMonitoring/Factory.cs
Normal file
@ -0,0 +1,27 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TBF.BenchControl.Generic;
|
||||
|
||||
namespace TBF.BenchControl.Various.StatisticsMonitoring
|
||||
{
|
||||
public class Factory : IComponentFactory
|
||||
{
|
||||
public string ClassName { get { return this.GetType().Namespace.Substring(17); } }
|
||||
|
||||
public void ResetStaticProperties() { ProcessStatistics.ResetStaticProperties(); }
|
||||
|
||||
public IComponent DummyComponent() { return new ProcessStatistics(); }
|
||||
|
||||
public IComponent GetComponent(IComponentCfg cfg, IList<IComponent> components) { return new ProcessStatistics(cfg); }
|
||||
|
||||
public IComponentCfg DefaultConfig() { return new StatisticsCfg(this.GetType().Namespace.Substring(25), this); }
|
||||
|
||||
public IComponentCfg CmpntCfgFromCmpntEntity(Config.Entities.Component component)
|
||||
{
|
||||
return ComponentCfgBase.CreateFromDbEntity(StatisticsCfg.Serializer, component, this);;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,204 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using log4net;
|
||||
using NHibernate;
|
||||
using Events.Entities;
|
||||
using Results.Entities;
|
||||
|
||||
namespace TBF.BenchControl.Various.StatisticsMonitoring
|
||||
{
|
||||
public class ProcessStatistics : ComponentBase, IOperation, GenericDevices.IStatisticsMonitoring
|
||||
{
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(ProcessStatistics));
|
||||
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(1)); }
|
||||
|
||||
readonly StatisticsCfg statisticsCfg;
|
||||
|
||||
int lastBatchNr;
|
||||
|
||||
|
||||
public ProcessStatistics() {}
|
||||
|
||||
public ProcessStatistics(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
statisticsCfg = cfg as StatisticsCfg;
|
||||
ApplyConfig();
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
|
||||
void ApplyConfig()
|
||||
{
|
||||
}
|
||||
|
||||
#region Configuration Change Handling
|
||||
|
||||
public static void OnCfgChange(object sender, CfgChangeArgs args)
|
||||
{
|
||||
if (CfgChangeHandler == null) return;
|
||||
try { CfgChangeHandler(sender, args); }
|
||||
catch (Exception e) { log.Error("CfgChangeHandler(...) failed", e); }
|
||||
}
|
||||
|
||||
public static event EventHandler<CfgChangeArgs> CfgChangeHandler;
|
||||
|
||||
public override void StartChangeHandler()
|
||||
{
|
||||
CfgChangeHandler += delegate(object sender, CfgChangeArgs args)
|
||||
{
|
||||
StatisticsCfg newCfg = args.Cfg as StatisticsCfg;
|
||||
if (newCfg != null && newCfg.Name.Equals(Name))
|
||||
{
|
||||
if (args.Command == CfgChangeCmd.CfgChange)
|
||||
{
|
||||
statisticsCfg.EventSource = newCfg.EventSource;
|
||||
statisticsCfg.iPerlHeadFailureRateThreshold = newCfg.iPerlHeadFailureRateThreshold;
|
||||
|
||||
ApplyConfig();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endregion Configuration Change Handling
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Writes the test cycle results into a file
|
||||
/// Events:
|
||||
/// Event.StatisticsProcessed
|
||||
/// Event.Busy
|
||||
/// </summary>
|
||||
/// <param name="batch">Results to write into a file</param>
|
||||
/// <returns>Reference to the operation</returns>
|
||||
public IOperation ProcessStatisticsOp(int lastBatchNr)
|
||||
{
|
||||
this.lastBatchNr = lastBatchNr;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public void Start()
|
||||
{
|
||||
Process(lastBatchNr, statisticsCfg);
|
||||
}
|
||||
public Event Run()
|
||||
{
|
||||
return Event.StatisticsProcessed;
|
||||
}
|
||||
public void Stop()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Process recent batch results and calculate statistics of iPERL head failures
|
||||
/// </summary>
|
||||
/// <param name="batchNr">Number of the last saved batch</param>
|
||||
void Process(int batchNr, StatisticsCfg statisticsCfg)
|
||||
{
|
||||
const int RequiredUsages = 10;
|
||||
const int MaxBatches = 20;
|
||||
|
||||
float iperlHeadFailureRateThreshold = (float)statisticsCfg.iPerlHeadFailureRateThreshold / 100.0f;
|
||||
|
||||
int completeBatchesProcessed = 0;
|
||||
|
||||
int[] usages = new int[Config.Data.WMsCount];
|
||||
int[] failures = new int[Config.Data.WMsCount];
|
||||
for (int i = 0; i < Config.Data.WMsCount; i++) usages[i] = failures[i] = 0;
|
||||
|
||||
///
|
||||
/// Read results of recent batches (up to 'MaxBatches')
|
||||
/// Take into account only batches where the 1st test in named 'RFID' and
|
||||
/// at least one water meter completed all tests.
|
||||
///
|
||||
try
|
||||
{
|
||||
ISession session = Results.DB.CreateSession();
|
||||
|
||||
int usagesMin;
|
||||
do
|
||||
{
|
||||
usagesMin = 0;
|
||||
IList<Batch> batches = session.QueryOver<Batch>()
|
||||
.Where(x => x.Id == batchNr)
|
||||
.List();
|
||||
batchNr--;
|
||||
if (batches.Count != 1 || batches[0].TestRslts.Count < 1 || batches[0].TestRslts[0].MethodClass != "TestMethods.iPerlCommunication")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isACompleteBatch = false;
|
||||
foreach (var wm in batches[0].WaterMeters)
|
||||
{
|
||||
int i = wm.WMPosition - 1;
|
||||
if (0 <= i && i < Config.Data.WMsCount && usages[i] < RequiredUsages && !wm.Disabled && wm.CompletedFromTests())
|
||||
{
|
||||
isACompleteBatch = true;
|
||||
usages[i]++;
|
||||
if (!wm.MeterTestRslts[0].Passed) failures[i]++;
|
||||
}
|
||||
}
|
||||
|
||||
usagesMin = int.MaxValue;
|
||||
for (int i = 0; i < Config.Data.WMsCount; i++) if (usagesMin > usages[i]) usagesMin = usages[i];
|
||||
|
||||
if (isACompleteBatch) completeBatchesProcessed++;
|
||||
}
|
||||
while ((usagesMin < RequiredUsages) && (batchNr > 0) && (completeBatchesProcessed < MaxBatches));
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Failed to calculate iPERL head usage statistics: {0}", exc.Message);
|
||||
}
|
||||
|
||||
///
|
||||
/// Find out whether at lest one event needs to be triggered
|
||||
///
|
||||
bool doTriggerEvents = false;
|
||||
for (int i = 0; i < Config.Data.WMsCount; i++)
|
||||
{
|
||||
if ((usages[i] > 0) && (iperlHeadFailureRateThreshold > 0) && (float)failures[i] / (float)usages[i] >= iperlHeadFailureRateThreshold)
|
||||
{
|
||||
doTriggerEvents = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (doTriggerEvents)
|
||||
{
|
||||
///
|
||||
/// Trigger events
|
||||
///
|
||||
try
|
||||
{
|
||||
ISession session = Events.DB.CreateSession();
|
||||
Events.DB.LoadSubscribers(session);
|
||||
|
||||
for (int i = 0; i < Config.Data.WMsCount; i++)
|
||||
{
|
||||
if ((usages[i] > 0) && (iperlHeadFailureRateThreshold > 0) && (float)failures[i] / (float)usages[i] >= iperlHeadFailureRateThreshold)
|
||||
{
|
||||
TBF.UiBridge.Bridge.TriggerEvent(session,
|
||||
statisticsCfg.EventSource,
|
||||
EventClass.EquipmentHW,
|
||||
Severity.Error,
|
||||
string.Format("Príliš veľa chýb hlavice č. {0}", i + 1),
|
||||
string.Format("Percento chýb je {0}%", (100 * failures[i]) / usages[i]),
|
||||
SubscriberGroup.Metrology | SubscriberGroup.Maintenance | SubscriberGroup.Production);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
log.ErrorFormat("Failed to trigger events: source = {0}, message = {1}", statisticsCfg.EventSource, exc.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
127
TBF/BenchControl/Various/StatisticsMonitoring/StatisticsCfg.cs
Normal file
127
TBF/BenchControl/Various/StatisticsMonitoring/StatisticsCfg.cs
Normal file
@ -0,0 +1,127 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Xml.Serialization;
|
||||
using Config.Entities;
|
||||
using TBF.BenchControl.Generic;
|
||||
using TBF.Resources;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TBF.BenchControl.Various.StatisticsMonitoring
|
||||
{
|
||||
/// <summary>
|
||||
/// Serializable configuration of Various.StatisticsMonitoring component.
|
||||
/// </summary>
|
||||
public class StatisticsCfg : ComponentCfgBase, Generic.IComponentCfg, Config.Entities.IParamsProvider
|
||||
{
|
||||
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(StatisticsCfg) })[0];
|
||||
public override XmlSerializer GetSerializer() { return Serializer; }
|
||||
|
||||
public IComponentCfgCtrl GetControl() { return new Configs.ParamsProvider.ComponentCfgCtrl(this, null); }
|
||||
|
||||
///
|
||||
/// Serialized parameters
|
||||
///
|
||||
public string EventSource;
|
||||
public int iPerlHeadFailureRateThreshold; /// 0 = off, 1..100% event is triggered when percentage reaches this level
|
||||
|
||||
/// Private parameterless constructor invoked by all other (public) constructors
|
||||
StatisticsCfg() { }
|
||||
|
||||
public StatisticsCfg(string name, IComponentFactory factory)
|
||||
: this()
|
||||
{
|
||||
Name = name;
|
||||
Factory = factory;
|
||||
ParentName = string.Empty;
|
||||
InitializeAll();
|
||||
}
|
||||
|
||||
public string ComponentName { get { return Name; } }
|
||||
|
||||
public void InitializeAll()
|
||||
{
|
||||
EventSource = "Štatistiky"; /// 0
|
||||
iPerlHeadFailureRateThreshold = 20; /// 1
|
||||
}
|
||||
|
||||
string[] paramNames = new string[]
|
||||
{
|
||||
"Event source", /// 0
|
||||
"Threshold for iPERL head failure rate [%] (0=off)", /// 1
|
||||
};
|
||||
public string ParamName(int i) { return paramNames[i]; }
|
||||
public int ParamsCount() { return paramNames.Length; }
|
||||
|
||||
public IList<string> ParamValues(int i)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public string ToString(int i)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case -1: return string.Format("Name={0}, EventSource={1}, FailureRatePct={2}, ...", Name, EventSource, iPerlHeadFailureRateThreshold);
|
||||
case 0: return EventSource;
|
||||
case 1: return iPerlHeadFailureRateThreshold.ToString();
|
||||
default: return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public CfgUpdateFlags UpdateParam(int i, string strValue)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 0: EventSource = strValue; return CfgUpdateFlags.AnyChange;
|
||||
case 1: iPerlHeadFailureRateThreshold = int.Parse(strValue); return CfgUpdateFlags.AnyChange;
|
||||
default: return CfgUpdateFlags.None;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validate string form of a parameter value
|
||||
/// </summary>
|
||||
/// <param name="i">Parameter index</param>
|
||||
/// <param name="strValue">String form of a parameter</param>
|
||||
/// <param name="message">Message in case value is not valid</param>
|
||||
/// <returns>true when string form of a parameter is OK</returns>
|
||||
public bool ValidateParam(int i, string strValue, out string message)
|
||||
{
|
||||
message = string.Empty;
|
||||
int percentage;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0:
|
||||
return true;
|
||||
case 1:
|
||||
if (int.TryParse(strValue, out percentage) && (0 <= percentage) && (percentage <= 100)) return true;
|
||||
message = "Threshold for iPERL head failure rate in % (0 = off)";
|
||||
return false;
|
||||
default:
|
||||
message = "Invalid index";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void CopyContentTo(StatisticsCfg prms)
|
||||
{
|
||||
prms.EventSource = this.EventSource; /// 0
|
||||
prms.iPerlHeadFailureRateThreshold = this.iPerlHeadFailureRateThreshold; /// 1
|
||||
}
|
||||
|
||||
public Config.Entities.IParamsProvider Clone()
|
||||
{
|
||||
StatisticsCfg pars = new StatisticsCfg();
|
||||
CopyContentTo(pars);
|
||||
return pars;
|
||||
}
|
||||
|
||||
public bool UpdateEmbeddedDbEntity()
|
||||
{
|
||||
return true; /// =OK, do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("2.26.1457.0")]
|
||||
[assembly: AssemblyFileVersion("2.26.1457.0")]
|
||||
[assembly: AssemblyVersion("2.26.1458.0")]
|
||||
[assembly: AssemblyFileVersion("2.26.1458.0")]
|
||||
|
||||
@ -626,6 +626,7 @@
|
||||
<Compile Include="BenchControl\GenericDevices\ISequenceCondition.cs" />
|
||||
<Compile Include="BenchControl\GenericDevices\ISimultTestMethod.cs" />
|
||||
<Compile Include="BenchControl\GenericDevices\IDatastreamReader.cs" />
|
||||
<Compile Include="BenchControl\GenericDevices\IStatisticsMonitoring.cs" />
|
||||
<Compile Include="BenchControl\GenericDevices\ITankDraining.cs" />
|
||||
<Compile Include="BenchControl\GenericDevices\ITankDrainingCfg.cs" />
|
||||
<Compile Include="BenchControl\GenericDevices\ITestMethodWith2ndPass.cs" />
|
||||
@ -909,9 +910,6 @@
|
||||
<Compile Include="BenchControl\Output\EventTriggers\Iperl\Factory.cs" />
|
||||
<Compile Include="BenchControl\Output\EventTriggers\Iperl\Trigger.cs" />
|
||||
<Compile Include="BenchControl\Output\EventTriggers\Iperl\TriggerCfg.cs" />
|
||||
<Compile Include="BenchControl\Output\EventTriggers\Statistics\Factory.cs" />
|
||||
<Compile Include="BenchControl\Output\EventTriggers\Statistics\Trigger.cs" />
|
||||
<Compile Include="BenchControl\Output\EventTriggers\Statistics\TriggerCfg.cs" />
|
||||
<Compile Include="BenchControl\Output\EventTriggers\Standard\Factory.cs" />
|
||||
<Compile Include="BenchControl\Output\EventTriggers\Standard\Trigger.cs" />
|
||||
<Compile Include="BenchControl\Output\EventTriggers\Standard\TriggerCfg.cs" />
|
||||
@ -1585,6 +1583,9 @@
|
||||
<Compile Include="BenchControl\Various\ManualLevelMsrmnt\WaterLevelForm.designer.cs">
|
||||
<DependentUpon>WaterLevelForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="BenchControl\Various\StatisticsMonitoring\Factory.cs" />
|
||||
<Compile Include="BenchControl\Various\StatisticsMonitoring\ProcessStatistics.cs" />
|
||||
<Compile Include="BenchControl\Various\StatisticsMonitoring\StatisticsCfg.cs" />
|
||||
<Compile Include="BenchControl\Various\TankWithLevelMsrmnt\Factory.cs" />
|
||||
<Compile Include="BenchControl\Various\TankWithLevelMsrmnt\Tank.cs" />
|
||||
<Compile Include="BenchControl\Various\TankWithLevelMsrmnt\TankCfg.cs" />
|
||||
|
||||
Loading…
Reference in New Issue
Block a user