/// /// Copyright (c) 2023 Sensus Slovensko a.s. /// using System; using System.Collections.Generic; using log4net; using Common; using TBF.Rig.GenericDevices; namespace TBF.Rig.DataEntry.Uni { public class EntryFormNoStartEnd : ComponentBase, IOperation, IDataEntry, IHasCycleBeginForm, IHasCycleEndForm { private static readonly ILog log = LogManager.GetLogger(typeof(EntryFormNoStartEnd)); public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); } const string DfltOcrWorkspaceFolder = "C:\\TBF\\OCR\\"; const string DfltOcrWorkspaceExt = ".vrws"; static Dictionary ocrDictionary = new Dictionary(); readonly EntryFormCfg myCfg; public string OcrWorkspace { get { return (myCfg != null && myCfg.ProcParams != null) ? myCfg.ProcParams.OcrWorkspace : string.Empty; } } public string OcrStream { get { return (myCfg != null && myCfg.ProcParams != null) ? myCfg.ProcParams.OcrStream : string.Empty; } } IRegReader[] regReaders; public string[] StartImages { get { return startImages; } set { if (myCfg.DebugLevel == DebugMode.Simulate) { startImages = new string[] { "C:\\TBF\\Images\\Test\\Image1.bmp", "C:\\TBF\\Images\\Test\\Image2.bmp", "C:\\TBF\\Images\\Test\\Image3.bmp", "C:\\TBF\\Images\\Test\\Image4.bmp", "C:\\TBF\\Images\\Test\\Image5.bmp", "C:\\TBF\\Images\\Test\\Image1.bmp", "C:\\TBF\\Images\\Test\\Image2.bmp", "C:\\TBF\\Images\\Test\\Image3.bmp", "C:\\TBF\\Images\\Test\\Image4.bmp", "C:\\TBF\\Images\\Test\\Image5.bmp", "C:\\TBF\\Images\\Test\\Image1.bmp", "C:\\TBF\\Images\\Test\\Image2.bmp", "C:\\TBF\\Images\\Test\\Image3.bmp", "C:\\TBF\\Images\\Test\\Image4.bmp", "C:\\TBF\\Images\\Test\\Image5.bmp", "C:\\TBF\\Images\\Test\\Image1.bmp", "C:\\TBF\\Images\\Test\\Image2.bmp", "C:\\TBF\\Images\\Test\\Image3.bmp", "C:\\TBF\\Images\\Test\\Image4.bmp", "C:\\TBF\\Images\\Test\\Image5.bmp" }; } else { startImages = value; } } } string[] startImages; public string[] EndImages { get { return endImages; } set { endImages = value; } } string[] endImages; public bool SaveImages { get { return !string.IsNullOrEmpty(myCfg.TestStartPicName) || !string.IsNullOrEmpty(myCfg.TestEndPicName); // or return myCfg.SaveImages; } } string[] wmCycleEndState; public string WMCycleEndState(int wmNr) { return (wmNr >= 0 && wmNr < wmCycleEndState.Length) ? wmCycleEndState[wmNr] : string.Empty; } double[] wmStartState; public double WMStartState(int wmNr) { return (wmNr >= 0 && wmNr < wmStartState.Length) ? wmStartState[wmNr] : 0; } double[] wmEndState; public double WMEndState(int wmNr) { return (wmNr >= 0 && wmNr < wmEndState.Length) ? wmEndState[wmNr] : 0; } string[] wmStartStateStr; System.Windows.Forms.Form modelessDlg; public bool Completed { get { return (modelessDlg is IHasCompleted) ? (modelessDlg as IHasCompleted).Completed : true; } } Unit volumeUnit; double refVolume; double errLimLo; double errLimHi; bool resultSaved; /// Set in Run() when results are saved IList waterMeters; /// Reference to ...ProcessData.BatchRslts.WaterMeters[] public string TestStartImgName(int wmNr0, string testName) { if (myCfg == null || waterMeters == null || wmNr0 < 0 || wmNr0 >= waterMeters.Count) return string.Empty; var wm = waterMeters[wmNr0]; /// {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} return string.Format(myCfg.TestStartPicName, testName, wm.SerialNr, wm.SerialNrAux, wm.RadioAddress, wm.Remark, wm.ArchivePath, wm.YearOfProduction, wm.Batch.StartTime, wm.Batch.BatchNr, wm.WMPosition); } public string TestEndImgName(int wmNr0, string testName) { if (myCfg == null || waterMeters == null || wmNr0 < 0 || wmNr0 >= waterMeters.Count) return string.Empty; var wm = waterMeters[wmNr0]; /// {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} return string.Format(myCfg.TestEndPicName, testName, wm.SerialNr, wm.SerialNrAux, wm.RadioAddress, wm.Remark, wm.ArchivePath, wm.YearOfProduction, wm.Batch.StartTime, wm.Batch.BatchNr, wm.WMPosition); } public enum CurrentOp { None, FormAtCycleBeginning, FormAtCycleEnd, TestStartStates, TestEndStates, DeferredTestEval, } CurrentOp currentOp; public EntryFormNoStartEnd() { } public EntryFormNoStartEnd(Generic.IComponentCfg cfg) : base(cfg) { myCfg = cfg as EntryFormCfg; } public override void Initialize() { wmStartState = new double[TBF.Data.WMsCount]; wmStartStateStr = new string[TBF.Data.WMsCount]; wmEndState = new double[TBF.Data.WMsCount]; wmCycleEndState = new string[TBF.Data.WMsCount]; volumeUnit = (Sequences.ProcessData.BenchInfo != null && Sequences.ProcessData.BenchInfo.VolumeUnit != Unit.None) ? Sequences.ProcessData.BenchInfo.VolumeUnit : Unit.l; currentOp = CurrentOp.None; log.FatalFormat("{0} initialized: {1}", Name, this); } /// Reference to the operation public IOperation ShowCycleBeginFormOp( IRegReader[] regReadersOptional = null) { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.FormAtCycleBeginning; this.waterMeters = Sequences.ProcessData.BatchRslts.Batch.WaterMeters; this.regReaders = regReadersOptional; log.DebugFormat( "DATA_ENTRY_BEGIN_ASSIGN OptionalSlots={0}, OptionalReaders={1}, StoredSlots={2}, StoredReaders={3}", regReadersOptional == null ? 0 : regReadersOptional.Length, regReadersOptional == null ? 0 : Array.FindAll(regReadersOptional, reader => reader != null).Length, this.regReaders == null ? 0 : this.regReaders.Length, this.regReaders == null ? 0 : Array.FindAll(this.regReaders, reader => reader != null).Length); return this; } /// Reference to the operation public IOperation ShowCycleEndFormOp(IList waterMeters) { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.FormAtCycleEnd; this.waterMeters = waterMeters; return this; } /// Reference to the operation public IOperation ShowTestStartFormOp(IRegReader[] regReaders) { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.TestStartStates; this.waterMeters = Sequences.ProcessData.BatchRslts.Batch.WaterMeters; this.regReaders = regReaders; return this; } /// Reference to the operation public IOperation ShowTestEndFormOp(IRegReader[] regReaders, double refVolume, double errLimLo, double errLimHi) { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.TestEndStates; this.waterMeters = Sequences.ProcessData.BatchRslts.Batch.WaterMeters; this.regReaders = regReaders; this.refVolume = refVolume; this.errLimLo = errLimLo; this.errLimHi = errLimHi; return this; } /// null (not implemented) public IOperation ShowAdvancedTestStartFormOp(IRegReader[] regReaders, IList waterMeters, bool isCondOp = false) { return null; } public IOperation ShowTestCollectFormOp(IRegReader[] regReaders, double volumeRef, double errLimLo, double errLimHi) { return null; } /// Reference to the operation public IOperation ShowDeferredTestEvalFormOp(IRegReader[] regReaders, double refVolume, double errLimLo, double errLimHi) { if (currentOp != CurrentOp.None) throw new Exception("Sequence error"); currentOp = CurrentOp.DeferredTestEval; this.waterMeters = Sequences.ProcessData.BatchRslts.Batch.WaterMeters; this.regReaders = regReaders; this.refVolume = refVolume; this.errLimLo = errLimLo; this.errLimHi = errLimHi; return this; } delegate void EntryFormDlgt(EntryFormNoStartEnd myRef); /// void OpenBeginningDlg(EntryFormNoStartEnd myRef) { string ocrMessage; var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage); DEItem.ClearItems(); for (int i = 0; i < myCfg.GetBgItemsCount(); i++) { if (myCfg.BgItemContent[i] != Ct.None) { DEItem.AddItem(myCfg.BgItemContent[i], myCfg.BgItemCaption[i], myCfg.BgItemAction[i], myCfg.BgItemWidth[i]); } } DEItem.ClearColumns(); for (int i = 0; i < myCfg.GetBgColumnsCount(); i++) { if (myCfg.BgColumnContent[i] != Ct.None) { DEItem.AddColumn(myCfg.BgColumnContent[i], myCfg.BgColumnCaption[i], myCfg.BgColumnAction[i], myCfg.BgColumnWidth[i]); } } log.DebugFormat( "DATA_ENTRY_BEGIN_OPEN AutoRead={0}, StoredSlots={1}, StoredReaders={2}, " + "WaterMeters={3}, OptoHeadsEnabled=0x{4:X12}", myCfg.BgIsAutoReadingSerialNo, regReaders == null ? 0 : regReaders.Length, regReaders == null ? 0 : Array.FindAll(regReaders, reader => reader != null).Length, waterMeters == null ? 0 : waterMeters.Count, Program.LocalSettings.OptoHeadsEnabled); if (regReaders != null) { modelessDlg = new CycleBgEnForm(waterMeters, regReaders, TBF.Data.LineSize, myCfg.BgTitle, myCfg.BgSize, myCfg.BgIsLrOrder, myCfg.BgIsCameraPicture, myCfg.BgFormCloseKeys, DEItem.GetItems(), DEItem.GetColumns(), false, regReaders, myCfg.BgIsAutoReadingSerialNo, myCfg.BgAutoCloseGap); } else { modelessDlg = new CycleBgEnForm(waterMeters, TBF.Data.LineSize, myCfg.BgTitle, myCfg.BgSize, myCfg.BgIsLrOrder, myCfg.BgIsCameraPicture, myCfg.BgFormCloseKeys, DEItem.GetItems(), DEItem.GetColumns(), myCfg.BgIsAutoReadingSerialNo, myCfg.BgAutoCloseGap, false); } modelessDlg.Show(); } /// void OpenEndDlg(EntryFormNoStartEnd myRef) { string ocrMessage; var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage); DEItem.ClearItems(); for (int i = 0; i < myCfg.GetEnItemsCount(); i++) { if (myCfg.EnItemContent[i] != Ct.None) { DEItem.AddItem(myCfg.EnItemContent[i], myCfg.EnItemCaption[i], myCfg.EnItemAction[i], myCfg.EnItemWidth[i]); } } DEItem.ClearColumns(); for (int i = 0; i < myCfg.GetEnColumnsCount(); i++) { if (myCfg.EnColumnContent[i] != Ct.None) { DEItem.AddColumn(myCfg.EnColumnContent[i], myCfg.EnColumnCaption[i], myCfg.EnColumnAction[i], myCfg.EnColumnWidth[i]); } } modelessDlg = new CycleBgEnForm(waterMeters, TBF.Data.LineSize, myCfg.EnTitle, myCfg.EnSize, myCfg.EnIsLrOrder, myCfg.EnIsCameraPicture, myCfg.EnFormCloseKeys, DEItem.GetItems(), DEItem.GetColumns(), myCfg.BgIsAutoReadingSerialNo, myCfg.BgAutoCloseGap, true); modelessDlg.Show(); } /// void OpenTestStartStatesDlg(EntryFormNoStartEnd myRef) { string ocrMessage; var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage); DEItem.ClearColumns(); for (int i = 0; i < myCfg.GetTestColumnsCount(); i++) { if (myCfg.TestColumnContent[i] != Ct.None) { DEItem.AddColumn(myCfg.TestColumnContent[i], myCfg.TestColumnCaption[i], myCfg.TestColumnAction[i], myCfg.TestColumnWidth[i]); } } bool isCompound = waterMeters[0].Batch.Compound; modelessDlg = new TestStartEndForm(waterMeters, myRef.regReaders, TBF.Data.LineSize, myCfg.TestTitle, myCfg.TestSize, myCfg.TestStartBoxAlwaysEn, myCfg.TestIsLrOrder, myCfg.TestFormCloseKeys, DEItem.GetColumns(), isCompound, volumeUnit, myCfg.TestIsCameraPicture, startImages,endImages, ocr, ocrMessage, myRef.OcrStream, myCfg.BgIsAutoReadingSerialNo, myCfg.BgAutoCloseGap, myCfg.DataEntryReadTimeoutSec); modelessDlg.Show(); } /// void OpenTestEndStatesDlg(EntryFormNoStartEnd myRef) { string ocrMessage; var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage); DEItem.ClearColumns(); for (int i = 0; i < myCfg.GetTestColumnsCount(); i++) { if (myCfg.TestColumnContent[i] != Ct.None) { DEItem.AddColumn(myCfg.TestColumnContent[i], myCfg.TestColumnCaption[i], myCfg.TestColumnAction[i], myCfg.TestColumnWidth[i]); } } bool isCompound = waterMeters[0].Batch.Compound; modelessDlg = new TestStartEndForm(waterMeters, myRef.regReaders, TBF.Data.LineSize, myCfg.TestTitle, myCfg.TestSize, myCfg.TestStartBoxAlwaysEn, myCfg.TestIsLrOrder, myCfg.TestFormCloseKeys, DEItem.GetColumns(), isCompound, volumeUnit, myCfg.TestIsCameraPicture, startImages, endImages, ocr, ocrMessage, myRef.OcrStream, myCfg.BgIsAutoReadingSerialNo, myCfg.BgAutoCloseGap, myCfg.DataEntryReadTimeoutSec, wmStartStateStr, refVolume, errLimLo, errLimHi); modelessDlg.Show(); } /// void OpenDeferredTestEvalDlg(EntryFormNoStartEnd myRef) { string ocrMessage; var ocr = GetOcr(myRef.OcrWorkspace, out ocrMessage); DEItem.ClearColumns(); for (int i = 0; i < myCfg.GetTestColumnsCount(); i++) { if (myCfg.TestColumnContent[i] != Ct.None) { DEItem.AddColumn(myCfg.TestColumnContent[i], myCfg.TestColumnCaption[i], myCfg.TestColumnAction[i], myCfg.TestColumnWidth[i]); } } bool isCompound = waterMeters[0].Batch.Compound; modelessDlg = new TestStartEndForm(waterMeters, myRef.regReaders, TBF.Data.LineSize, myCfg.TestTitle, myCfg.TestSize, myCfg.TestStartBoxAlwaysEn, myCfg.TestIsLrOrder, myCfg.TestFormCloseKeys, DEItem.GetColumns(), isCompound, volumeUnit, myCfg.TestIsCameraPicture, startImages, endImages, ocr, ocrMessage, myRef.OcrStream, myCfg.BgIsAutoReadingSerialNo, myCfg.BgAutoCloseGap, myCfg.DataEntryReadTimeoutSec, wmStartStateStr, refVolume, errLimLo, errLimHi); modelessDlg.Show(); } /// OcrVidi GetOcr(string ocrWorkspace, out string message) { message = string.Empty; if (string.IsNullOrEmpty(ocrWorkspace)) return null; /// No OCR was configured string fullPath = (ocrWorkspace.Contains("\\") || ocrWorkspace.Contains("/")) ? ocrWorkspace.Replace('/', '\\') : System.IO.Path.Combine(DfltOcrWorkspaceFolder, ocrWorkspace); if (!fullPath.Contains(".")) fullPath = fullPath + DfltOcrWorkspaceExt; OcrVidi ocrVidi; if (ocrDictionary.TryGetValue(fullPath, out ocrVidi)) { log.InfoFormat("existing OcrVidi({0}) was retrieved from dictionary", fullPath); return ocrVidi; } try { ocrVidi = new OcrVidi(fullPath); ocrDictionary.Add(fullPath, ocrVidi); log.WarnFormat("new OcrVidi({0}) was added to dictionary", fullPath); return ocrVidi; } catch (Exception e) { if (e.InnerException != null) { log.ErrorFormat("new OcrVidi({0}) thrown {1}: {2} / {3}", fullPath, e.GetType().ToString(), e.Message, e.InnerException.Message); } else { log.ErrorFormat("new OcrVidi({0}) thrown {1}: {2}", fullPath, e.GetType().ToString(), e.Message); } log.ErrorFormat("Stack trace:\r\n{0}", e.StackTrace); message = string.Format("Cannot load OCR workspace:\r\n{0}\r\nOCR workspace file is {1}", e.Message, fullPath); return null; } } /// Start this operation public void Start() { resultSaved = false; switch (currentOp) { case CurrentOp.FormAtCycleBeginning: if (myCfg.BgShowForm) { Program.MainWnd.Invoke(new EntryFormDlgt(OpenBeginningDlg), this); } break; case CurrentOp.FormAtCycleEnd: if (myCfg.EnShowForm) { Program.MainWnd.Invoke(new EntryFormDlgt(OpenEndDlg), this); } break; case CurrentOp.TestStartStates: if (myCfg.TestStartEndShowForm) { Program.MainWnd.Invoke(new EntryFormDlgt(OpenTestStartStatesDlg), this); } break; case CurrentOp.TestEndStates: if (myCfg.TestStartEndShowForm) { Program.MainWnd.Invoke(new EntryFormDlgt(OpenTestEndStatesDlg), this); } break; case CurrentOp.DeferredTestEval: Program.MainWnd.Invoke(new EntryFormDlgt(OpenDeferredTestEvalDlg), this); break; } } /// Run this operation /// Event.ResultsPrinted public Event Run() { if ((modelessDlg is IHasCompleted) && !(modelessDlg as IHasCompleted).Completed) { return Event.ModelessFormIsOpen; } if (!resultSaved) /// This is to save the result only once { if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.TestStartStates) { /// Fixed start test - start TestStartEndForm dlg = (modelessDlg as TestStartEndForm); if (dlg != null) { volumeUnit = dlg.VolumeUnit; for (int i = 0; i < waterMeters.Count; i++) { if (!((i < waterMeters.Count && waterMeters[i].Disabled) || (i < regReaders.Length && regReaders[i] == null))) { wmStartState[i] = dlg.WMStartState[i]; } } wmStartStateStr = dlg.WMStartStateStr; } } else if (modelessDlg is TestStartEndForm && currentOp == CurrentOp.TestEndStates) { /// Fixed start test - end TestStartEndForm dlg = (modelessDlg as TestStartEndForm); if (dlg != null) { volumeUnit = dlg.VolumeUnit; for (int i = 0; i < waterMeters.Count; i++) { if (!((i < waterMeters.Count && waterMeters[i].Disabled) || (i < regReaders.Length && regReaders[i] == null))) { wmEndState[i] = dlg.WMEndState[i]; } } } } resultSaved = true; modelessDlg = null; } return Event.ModelessFormClosed; /// Form closed } /// Stop this operation public void Stop() { if (modelessDlg is IHasCompleted) { UiBridge.Bridge.OnCloseModelessForm(this, null); modelessDlg = null; } currentOp = CurrentOp.None; } } }