/// /// Copyright (c) 2020 Sensus Slovensko a.s. /// using System; using log4net; using NHibernate; using Common; using Events.Entities; namespace TBF.Rig.Output.EventTriggers.Standard { 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; string src { get { return triggerCfg.EventSource; } } Results.Entities.Batch batch; public Trigger() {} public Trigger(Generic.IComponentCfg cfg) : base(cfg) { triggerCfg = cfg as TriggerCfg; } public override void Initialize() { log.FatalFormat("{0} initialized: {1}", Name, this); } #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 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; triggerCfg.Mid1ErrAfterCorr = newCfg.Mid1ErrAfterCorr; triggerCfg.Mid1Err = newCfg.Mid1Err; triggerCfg.Mid2Name = newCfg.Mid2Name; triggerCfg.Mid2ErrAfterCorr = newCfg.Mid2ErrAfterCorr; triggerCfg.Mid2Err = newCfg.Mid2Err; triggerCfg.Mid3Name = newCfg.Mid3Name; triggerCfg.Mid3ErrAfterCorr = newCfg.Mid3ErrAfterCorr; triggerCfg.Mid3Err = newCfg.Mid3Err; triggerCfg.Mid4Name = newCfg.Mid4Name; triggerCfg.Mid4ErrAfterCorr = newCfg.Mid4ErrAfterCorr; triggerCfg.Mid4Err = newCfg.Mid4Err; triggerCfg.Mid5Name = newCfg.Mid5Name; 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; 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; triggerCfg.E36 = newCfg.E36; #if TURA_IPERL || TURA_SPECIAL triggerCfg.E26 = newCfg.E26; triggerCfg.E27 = newCfg.E27; triggerCfg.E28 = newCfg.E28; #endif } } }; } #endregion Configuration Change Handling /// /// Writes the test cycle results into a file /// Events: /// Event.ResultsWritten /// Event.Busy /// /// Results to write into a file /// Reference to the operation public IOperation ProcessResultsOp(Results.Entities.Batch batch) { this.batch = batch; return this; } /// Start this operation public void Start() { Process(batch); } /// Run this operation /// Event.ResultsProcessed public Event Run() { return Event.ResultsProcessed; } /// Stop this operation public void Stop() { } void Process(Results.Entities.Batch batch) { if (batch == null || batch.WaterMeters == null || batch.WaterMeters.Count == 0) { return; } ISession session = null; try { session = TBF.DB.EventsDBSessionFactory.OpenSession(); 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 }; 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 }; for (int i = 0; i < midName.Length; i++) { if (!string.IsNullOrEmpty(midName[i])) { /// This MID# enabled foreach (var tr in batch.TestRslts) { if (tr.RefFlowmeter() == midName[i]) { /// 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); } } } } } /// /// Events on Ex flags /// long eFlags = batch.ErrorFlags(); long iFlags = batch.InfoFlags(); /// 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); 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); if (triggerCfg.E36) OnExTriggerEvent(session, eFlags, iFlags, 36); #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); } finally { if (session != null && session.IsOpen) session.Close(); } } 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); } } }