2020-03-05 12:59:43 +00:00
|
|
|
|
///
|
|
|
|
|
|
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
|
|
|
|
|
///
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using log4net;
|
|
|
|
|
|
using NHibernate;
|
2021-09-23 09:46:40 +00:00
|
|
|
|
using Common;
|
2020-03-05 12:59:43 +00:00
|
|
|
|
using Events.Entities;
|
|
|
|
|
|
|
2021-10-26 09:23:57 +00:00
|
|
|
|
namespace TBF.Rig.Output.EventTriggers.Standard
|
2020-03-05 12:59:43 +00:00
|
|
|
|
{
|
|
|
|
|
|
public class Trigger : ComponentBase, IOperation, GenericDevices.IEventTrigger
|
|
|
|
|
|
{
|
|
|
|
|
|
private static readonly ILog log = LogManager.GetLogger(typeof(Trigger));
|
2021-04-07 07:57:42 +00:00
|
|
|
|
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
|
2020-03-05 12:59:43 +00:00
|
|
|
|
|
|
|
|
|
|
readonly TriggerCfg triggerCfg;
|
|
|
|
|
|
string src { get { return triggerCfg.EventSource; } }
|
|
|
|
|
|
|
|
|
|
|
|
Results.Entities.Batch batch;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Trigger() {}
|
|
|
|
|
|
|
|
|
|
|
|
public Trigger(Generic.IComponentCfg cfg)
|
|
|
|
|
|
: base(cfg)
|
|
|
|
|
|
{
|
|
|
|
|
|
triggerCfg = cfg as TriggerCfg;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2021-04-07 07:57:42 +00:00
|
|
|
|
public override void Initialize()
|
|
|
|
|
|
{
|
|
|
|
|
|
log.FatalFormat("{0} initialized: {1}", Name, this);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-03-05 12:59:43 +00:00
|
|
|
|
#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.FailedWMsPct = newCfg.FailedWMsPct;
|
|
|
|
|
|
triggerCfg.Mid1Name = newCfg.Mid1Name;
|
2020-05-04 11:58:57 +00:00
|
|
|
|
triggerCfg.Mid1ErrAfterCorr = newCfg.Mid1ErrAfterCorr;
|
|
|
|
|
|
triggerCfg.Mid1Err = newCfg.Mid1Err;
|
2020-03-05 12:59:43 +00:00
|
|
|
|
triggerCfg.Mid2Name = newCfg.Mid2Name;
|
2020-05-04 11:58:57 +00:00
|
|
|
|
triggerCfg.Mid2ErrAfterCorr = newCfg.Mid2ErrAfterCorr;
|
|
|
|
|
|
triggerCfg.Mid2Err = newCfg.Mid2Err;
|
2020-03-05 12:59:43 +00:00
|
|
|
|
triggerCfg.Mid3Name = newCfg.Mid3Name;
|
2020-05-04 11:58:57 +00:00
|
|
|
|
triggerCfg.Mid3ErrAfterCorr = newCfg.Mid3ErrAfterCorr;
|
|
|
|
|
|
triggerCfg.Mid3Err = newCfg.Mid3Err;
|
2020-03-05 12:59:43 +00:00
|
|
|
|
triggerCfg.Mid4Name = newCfg.Mid4Name;
|
2020-05-04 11:58:57 +00:00
|
|
|
|
triggerCfg.Mid4ErrAfterCorr = newCfg.Mid4ErrAfterCorr;
|
|
|
|
|
|
triggerCfg.Mid4Err = newCfg.Mid4Err;
|
2020-03-05 12:59:43 +00:00
|
|
|
|
triggerCfg.Mid5Name = newCfg.Mid5Name;
|
2020-05-04 11:58:57 +00:00
|
|
|
|
triggerCfg.Mid5ErrAfterCorr = newCfg.Mid5ErrAfterCorr;
|
|
|
|
|
|
triggerCfg.Mid5Err = newCfg.Mid5Err;
|
|
|
|
|
|
triggerCfg.E1 = newCfg.E1;
|
|
|
|
|
|
triggerCfg.E2 = newCfg.E2;
|
|
|
|
|
|
triggerCfg.E3 = newCfg.E3;
|
|
|
|
|
|
triggerCfg.E4 = newCfg.E4;
|
|
|
|
|
|
triggerCfg.E5 = newCfg.E5;
|
|
|
|
|
|
triggerCfg.E6 = newCfg.E6;
|
|
|
|
|
|
triggerCfg.E7 = newCfg.E7;
|
|
|
|
|
|
triggerCfg.E8 = newCfg.E8;
|
|
|
|
|
|
triggerCfg.E9 = newCfg.E9;
|
2020-03-05 12:59:43 +00:00
|
|
|
|
triggerCfg.E10 = newCfg.E10;
|
|
|
|
|
|
triggerCfg.E11 = newCfg.E11;
|
|
|
|
|
|
triggerCfg.E12 = newCfg.E12;
|
|
|
|
|
|
triggerCfg.E13 = newCfg.E13;
|
|
|
|
|
|
triggerCfg.E14 = newCfg.E14;
|
|
|
|
|
|
triggerCfg.E15 = newCfg.E15;
|
|
|
|
|
|
triggerCfg.E16 = newCfg.E16;
|
|
|
|
|
|
triggerCfg.E21 = newCfg.E21;
|
2020-05-04 11:58:57 +00:00
|
|
|
|
triggerCfg.E36 = newCfg.E36;
|
2020-03-05 12:59:43 +00:00
|
|
|
|
#if TURA_IPERL || TURA_SPECIAL
|
|
|
|
|
|
triggerCfg.E26 = newCfg.E26;
|
|
|
|
|
|
triggerCfg.E27 = newCfg.E27;
|
|
|
|
|
|
triggerCfg.E28 = newCfg.E28;
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#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)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (batch == null || batch.WaterMeters == null || batch.WaterMeters.Count == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-04-18 12:01:23 +00:00
|
|
|
|
ISession session = null;
|
2020-03-05 12:59:43 +00:00
|
|
|
|
try
|
|
|
|
|
|
{
|
2023-04-18 12:01:23 +00:00
|
|
|
|
session = TBF.DB.EventsDBSessionFactory.OpenSession();
|
2020-03-05 12:59:43 +00:00
|
|
|
|
Events.DB.LoadSubscribers(session);
|
|
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Event on high percentage of failed meters
|
|
|
|
|
|
///
|
|
|
|
|
|
if (triggerCfg.FailedWMsPct > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
/// Triggering this event is enabled
|
|
|
|
|
|
int failedWMs = batch.FailedMetersCount();
|
|
|
|
|
|
int passedWMs = batch.PassedMetersCount();
|
|
|
|
|
|
if (100 * failedWMs >= triggerCfg.FailedWMsPct * (failedWMs + passedWMs))
|
|
|
|
|
|
{
|
|
|
|
|
|
TBF.UiBridge.Bridge.TriggerEvent(session, src, EventClass.BadResults, Severity.Warning,
|
|
|
|
|
|
"Príliš veľa chybných kusov v jednej dávke",
|
|
|
|
|
|
string.Format("Číslo dávky: {0}\r\nspolu {1} kusov, dobrých {2} ks., chybných {3} ks.",
|
|
|
|
|
|
batch.BatchNr, passedWMs + failedWMs, passedWMs, failedWMs),
|
|
|
|
|
|
SubscriberGroup.Production);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Event MIDx relative error measured against a scale is too large
|
|
|
|
|
|
///
|
|
|
|
|
|
string[] midName = new string[] { triggerCfg.Mid1Name,
|
|
|
|
|
|
triggerCfg.Mid2Name,
|
|
|
|
|
|
triggerCfg.Mid3Name,
|
|
|
|
|
|
triggerCfg.Mid4Name,
|
|
|
|
|
|
triggerCfg.Mid5Name };
|
2020-05-04 11:58:57 +00:00
|
|
|
|
|
|
|
|
|
|
double[] maxMidErr = new double[] { triggerCfg.Mid1Err,
|
|
|
|
|
|
triggerCfg.Mid2Err,
|
|
|
|
|
|
triggerCfg.Mid3Err,
|
|
|
|
|
|
triggerCfg.Mid4Err,
|
|
|
|
|
|
triggerCfg.Mid5Err };
|
|
|
|
|
|
|
|
|
|
|
|
double[] maxMidErrAfterCorr = new double[] { triggerCfg.Mid1ErrAfterCorr,
|
|
|
|
|
|
triggerCfg.Mid2ErrAfterCorr,
|
|
|
|
|
|
triggerCfg.Mid3ErrAfterCorr,
|
|
|
|
|
|
triggerCfg.Mid4ErrAfterCorr,
|
|
|
|
|
|
triggerCfg.Mid5ErrAfterCorr };
|
2020-03-05 12:59:43 +00:00
|
|
|
|
for (int i = 0; i < midName.Length; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!string.IsNullOrEmpty(midName[i]))
|
|
|
|
|
|
{
|
2020-05-04 11:58:57 +00:00
|
|
|
|
/// This MID# enabled
|
|
|
|
|
|
|
2020-03-05 12:59:43 +00:00
|
|
|
|
foreach (var tr in batch.TestRslts)
|
|
|
|
|
|
{
|
2020-05-04 11:58:57 +00:00
|
|
|
|
if (tr.RefFlowmeter() == midName[i])
|
2020-03-05 12:59:43 +00:00
|
|
|
|
{
|
2020-05-04 11:58:57 +00:00
|
|
|
|
/// This test result was obtained using MID#
|
|
|
|
|
|
|
|
|
|
|
|
double midErrAfterCorr = Config.Formulas.ErrorFromVolumes(tr.ConstMasterCorr, tr.ConstMaster);
|
|
|
|
|
|
if (midErrAfterCorr >= maxMidErrAfterCorr[i])
|
|
|
|
|
|
{
|
|
|
|
|
|
TBF.UiBridge.Bridge.TriggerEvent(session, src, EventClass.EquipmentHW, Severity.Error,
|
|
|
|
|
|
string.Format("Príliš veľká chyba merača prietoku {0} po KOREKCII oproti váhe", midName[i]),
|
|
|
|
|
|
string.Format("Číslo dávky: {0}\r\nPrietokomer: {1}\r\nRelatívna chyba po korekcii: {2}%\r\nMax. dovolená chyba: {3}%",
|
|
|
|
|
|
batch.BatchNr, midName[i], Utils.DoubleToStr(midErrAfterCorr, 3), maxMidErrAfterCorr[i]),
|
|
|
|
|
|
SubscriberGroup.Metrology | SubscriberGroup.Maintenance | SubscriberGroup.Production);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tr.ErrorMaster >= maxMidErr[i])
|
|
|
|
|
|
{
|
|
|
|
|
|
TBF.UiBridge.Bridge.TriggerEvent(session, src, EventClass.EquipmentHW, Severity.Error,
|
|
|
|
|
|
string.Format("Príliš veľká chyba merača prietoku {0} oproti váhe", midName[i]),
|
|
|
|
|
|
string.Format("Číslo dávky: {0}\r\nPrietokomer: {1}\r\nRelatívna chyba: {2}%\r\nMax. dovolená chyba: {3}%",
|
|
|
|
|
|
batch.BatchNr, midName[i], Utils.DoubleToStr(tr.ErrorMaster, 3), maxMidErr[i]),
|
|
|
|
|
|
SubscriberGroup.Metrology | SubscriberGroup.Maintenance | SubscriberGroup.Production);
|
|
|
|
|
|
}
|
2020-03-05 12:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Events on Ex flags
|
|
|
|
|
|
///
|
|
|
|
|
|
long eFlags = batch.ErrorFlags();
|
|
|
|
|
|
long iFlags = batch.InfoFlags();
|
|
|
|
|
|
///
|
2023-04-18 12:01:23 +00:00
|
|
|
|
if (triggerCfg.E1) OnExTriggerEvent(session, eFlags, iFlags, 1);
|
|
|
|
|
|
if (triggerCfg.E2) OnExTriggerEvent(session, eFlags, iFlags, 2);
|
|
|
|
|
|
if (triggerCfg.E3) OnExTriggerEvent(session, eFlags, iFlags, 3);
|
|
|
|
|
|
if (triggerCfg.E4) OnExTriggerEvent(session, eFlags, iFlags, 4);
|
|
|
|
|
|
if (triggerCfg.E5) OnExTriggerEvent(session, eFlags, iFlags, 5);
|
|
|
|
|
|
if (triggerCfg.E6) OnExTriggerEvent(session, eFlags, iFlags, 6);
|
|
|
|
|
|
if (triggerCfg.E7) OnExTriggerEvent(session, eFlags, iFlags, 7);
|
|
|
|
|
|
if (triggerCfg.E8) OnExTriggerEvent(session, eFlags, iFlags, 8);
|
|
|
|
|
|
if (triggerCfg.E9) OnExTriggerEvent(session, eFlags, iFlags, 9);
|
2020-03-05 12:59:43 +00:00
|
|
|
|
if (triggerCfg.E10) OnExTriggerEvent(session, eFlags, iFlags, 10);
|
|
|
|
|
|
if (triggerCfg.E11) OnExTriggerEvent(session, eFlags, iFlags, 11);
|
|
|
|
|
|
if (triggerCfg.E12) OnExTriggerEvent(session, eFlags, iFlags, 12);
|
|
|
|
|
|
if (triggerCfg.E13) OnExTriggerEvent(session, eFlags, iFlags, 13);
|
|
|
|
|
|
if (triggerCfg.E14) OnExTriggerEvent(session, eFlags, iFlags, 14);
|
|
|
|
|
|
if (triggerCfg.E15) OnExTriggerEvent(session, eFlags, iFlags, 15);
|
|
|
|
|
|
if (triggerCfg.E16) OnExTriggerEvent(session, eFlags, iFlags, 16);
|
|
|
|
|
|
if (triggerCfg.E21) OnExTriggerEvent(session, eFlags, iFlags, 21);
|
2020-05-04 11:58:57 +00:00
|
|
|
|
if (triggerCfg.E36) OnExTriggerEvent(session, eFlags, iFlags, 36);
|
2020-03-05 12:59:43 +00:00
|
|
|
|
#if TURA_IPERL || TURA_SPECIAL
|
|
|
|
|
|
if (triggerCfg.E26) OnExTriggerEvent(session, eFlags, iFlags, 26);
|
|
|
|
|
|
if (triggerCfg.E27) OnExTriggerEvent(session, eFlags, iFlags, 27);
|
|
|
|
|
|
if (triggerCfg.E28) OnExTriggerEvent(session, eFlags, iFlags, 28);
|
|
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception exc)
|
|
|
|
|
|
{
|
|
|
|
|
|
log.ErrorFormat("Triggering event(s) failed: {0}", exc.Message);
|
|
|
|
|
|
}
|
2023-04-18 12:01:23 +00:00
|
|
|
|
finally
|
|
|
|
|
|
{
|
|
|
|
|
|
if (session != null && session.IsOpen) session.Close();
|
|
|
|
|
|
}
|
2020-03-05 12:59:43 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void OnExTriggerEvent(ISession session, long eFlags, long iFlags, int x)
|
|
|
|
|
|
{
|
|
|
|
|
|
long mask = 1L << (x - 1);
|
|
|
|
|
|
|
|
|
|
|
|
Severity severity;
|
|
|
|
|
|
if ((eFlags & mask) != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
severity = Severity.Error;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if ((iFlags & mask) != 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
severity = Severity.Warning;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
string moreInfo = string.Format("E{0}", x);
|
|
|
|
|
|
|
|
|
|
|
|
TBF.UiBridge.Bridge.TriggerEvent(session, src, EventClass.TestingProcess, severity,
|
|
|
|
|
|
string.Format("Príznak chyby procesu E{0} je aktívny", x),
|
|
|
|
|
|
string.Format("Číslo dávky: {0}\r\n{1}", batch.BatchNr, moreInfo),
|
|
|
|
|
|
SubscriberGroup.Production);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|