using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Management; using System.Data.SqlClient; using System.Data; using System.Threading.Tasks; using System.Net.NetworkInformation; using System.Windows.Forms; using System.Net; using WatsonWebsocket; using System.Runtime.CompilerServices; using System.Threading; using Euresys.Open_eVision_22_12; using Crevis.VirtualFG40Library; using AR; namespace Project { public enum eTarget { Left = 0, Right, None = 9, } public enum remotelist { barcodeupdate, } public class remoteargs : EventArgs { public string strdata { get; set; } public int CamIdx { get; set; } public remotelist Command { get; set; } public remoteargs(remotelist _cmd, int _camidx, string _strdata) { this.strdata = _strdata; this.CamIdx = _camidx; this.Command = _cmd; } } public static class PUB { public static Class.WebSocket[] wsock_ = new Class.WebSocket[2]; public static AR.Log[] log_ = new AR.Log[2]; public static DateTime LastInputTime = DateTime.Now; public static CSetting setting; public static Boolean VisionLicense; public static DateTime parsetime = DateTime.Now; public static Flag flag; public static bool[] DetectReel = new bool[] { false, false }; public static bool[] DetectConv = new bool[] { false, false }; public static int[] DetectReelValue = new int[] { 0, 0 }; public static int[] DetectConvValue = new int[] { 0, 0 }; public static double[] ProcessTime = new double[] { 0, 0 }; public static string[] lastguid = new string[] { string.Empty, string.Empty }; public static string[] lastdata = new string[] { string.Empty, string.Empty }; public static string[] lastcmd = new string[] { string.Empty, string.Empty }; public static string[] lastip = new string[] { string.Empty, string.Empty }; public static DateTime[] lastsend = new DateTime[] { DateTime.Now, DateTime.Now }; public static DateTime[] lastsendStatus = new DateTime[] { DateTime.Now, DateTime.Now }; public static Stack imgque = new Stack(); public static Boolean[] _isCrevisOpen = new bool[] { false, false, false }; public static Boolean[] _isCrevisACQ = new bool[] { false, false, false }; public static bool[] IsLive = new bool[] { false, false }; public static eTarget GetTarget(int camidx) { if (camidx < 0 || camidx > 900) return eTarget.None; if (camidx == PUB.setting.CameraIndexL) return eTarget.Left; else if (camidx == PUB.setting.CameraIndexR && camidx != PUB.setting.CameraIndexL) return eTarget.Right; else return eTarget.None; } // public static System.Windows.Forms.Panel pIvLeft, pIvRight; public static event EventHandler RemoteCommand; public static void RaiseRemoteCommand(remotelist cmd, int camidx, string data) { RemoteCommand?.Invoke(null, new remoteargs(cmd, camidx, data)); } public static void initCore() { //setting setting = new CSetting(); setting.Load(); //log log_[0] = new AR.Log(); log_[0].FileNameFormat = "{yyyyMMdd}_L"; log_[0].TimeFormat = "yyyy-MM-dd HH:mm:ss.fff"; log_[1] = new AR.Log(); log_[1].FileNameFormat = "{yyyyMMdd}_R"; log_[1].TimeFormat = "yyyy-MM-dd HH:mm:ss.fff"; flag = new Flag(); } public static void LogFlush() { PUB.log_[0].Flush(); PUB.log_[1].Flush(); } public static string GetStackTraceInfo( [CallerFilePath] string filenpath = null, [CallerLineNumber] int linenumer = -1, [CallerMemberName] string callMember = null) { var stackFrame = new System.Diagnostics.StackTrace(1).GetFrame(1); string fileName = stackFrame.GetFileName(); if (fileName.isEmpty()) fileName = filenpath; string methodName = stackFrame.GetMethod().ToString(); if (methodName.isEmpty()) methodName = callMember; int lineNumber = stackFrame.GetFileLineNumber(); if (linenumer != -1) lineNumber = linenumer; var TraceInfo = stackFrame.ToString(); return $"File:{fileName},Line:{lineNumber}\nMethod:{methodName}\n{TraceInfo}"; } public static Dictionary ComputerInfo() { string ip = ""; string mac = ""; // string prgmName = Application.ProductName; var nif = NetworkInterface.GetAllNetworkInterfaces(); var host = Dns.GetHostEntry(Dns.GetHostName()); string fullname = System.Net.Dns.GetHostEntry("").HostName; foreach (IPAddress r in host.AddressList) { string str = r.ToString(); if (str != "" && str.Substring(0, 3) == "10.") { ip = str; break; } } string rtn = string.Empty; ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled='TRUE'"); ManagementObjectSearcher query1 = new ManagementObjectSearcher(oq); foreach (ManagementObject mo in query1.Get()) { string[] address = (string[])mo["IPAddress"]; if (address[0] == ip && mo["MACAddress"] != null) { mac = mo["MACAddress"].ToString(); break; } } var username = System.Environment.UserName; var retval = new Dictionary(); retval.Add("IP", ip); retval.Add("MAC", mac); retval.Add("USER", username); retval.Add("HOST", fullname); return retval; } public static Rectangle GetVisionOrientSearchArea( Rectangle baserect, int offsetX, int offsetY, out string VisionOrientMessage) { VisionOrientMessage = ""; var newORectW = baserect.Width + offsetX; var newORectH = baserect.Height + offsetY; var newORectX = baserect.X - ((newORectW - baserect.Width) / 2.0); var newORectY = baserect.Y - ((newORectH - baserect.Height) / 2.0); if (newORectX < 1) { newORectW += (int)newORectY; newORectX = 1; } if (newORectY < 1) { newORectH += (int)newORectY; newORectY = 1; } if (newORectW < 4) newORectW = 0; if (newORectH < 4) newORectH = 0; var newORect = new Rectangle((int)newORectX, (int)newORectY, (int)newORectW, (int)newORectH); if (newORect.Width < 1 || newORect.Height < 1) { VisionOrientMessage = string.Format("Reference area size error({0},{1},{2},{3})", newORect.Left, newORect.Top, newORect.Width, newORect.Height); return Rectangle.Empty; } else return newORect; } public static double GetFreeSpace(string driveletter) { try { var di = new System.IO.DriveInfo(driveletter); var freespace = di.TotalFreeSpace; var totalspace = di.TotalSize; var freeSpaceRate = (freespace * 1.0 / totalspace) * 100.0; return freeSpaceRate; } catch { return 100.0; } } public static string getSavePath(out double freespace) { Boolean path1Exist = false; double freespace1 = 100.0; string savePath1 = ""; freespace = 100.0; savePath1 = System.IO.Path.Combine(PUB.setting.Path_Data, "Images"); if (savePath1 != "" && System.IO.Directory.Exists(savePath1)) { path1Exist = true; //이폴더를 사용 if (savePath1.StartsWith("\\")) return savePath1; //남은잔량을 체크한다. return savePath1; } if (path1Exist) { freespace = freespace1; return savePath1; } //이제 문제가 좀 심각? (폴더가 없다) var savePath = System.IO.Path.Combine(Util.CurrentPath, "Images"); if (System.IO.Directory.Exists(savePath) == false) System.IO.Directory.CreateDirectory(savePath); freespace = GetFreeSpace(savePath.Substring(0, 1)); return savePath; } public static double ChangeValuePopup(double value, string title) { var f = AR.UTIL.InputBox(title, value.ToString()); if (f.Item1) { var val = double.Parse(f.Item2); return val; } else return value; } public static VirtualFG40Library _virtualFG40; public static DateTime[] _CrevisRunTime = new DateTime[] { DateTime.Now, DateTime.Now }; public static DateTime[] _CrevisGrabTime = new DateTime[] { DateTime.Now, DateTime.Now }; static System.Threading.ManualResetEvent[] mre_grab = new System.Threading.ManualResetEvent[] { new System.Threading.ManualResetEvent(true), new System.Threading.ManualResetEvent(true) }; public static EImageBW8[] OrgImage = new EImageBW8[] { null, null }; public static Int32[] _hDevice = new Int32[] { -1, -1 }; public static Int32[] _width = new Int32[] { 0, 0, 0 }; public static Int32[] _height = new Int32[] { 0, 0, 0 }; public static Int32[] _stride = new Int32[] { 0, 0, 0 }; public static Int32[] _bufferSize = new Int32[] { 0, 0, 0 }; public static IntPtr[] camPtr = new IntPtr[] { IntPtr.Zero, IntPtr.Zero }; public static bool[] IsProcess = new bool[] { false, false }; /// /// 카메라버퍼에서 이미지를 읽는다 /// /// /// /// public static Boolean CrevisGrab(int camIdx, Boolean DisplayImage, Panel Piv) { // 1. Excute Acquisition Start command // 2. Grab Image using GrabImage // 3. Image Display // 4. Excute Acquisition Stop command var camTarget = PUB.GetTarget(camIdx);// = eTarget.Left ? PUB.setting.CameraIndexL : PUB.setting.CameraIndexR; if (camTarget == eTarget.None) return false; var logIdx = camTarget == eTarget.Left ? 0 : 1; //작업가능여부확인 if (mre_grab[camIdx].WaitOne(100) == false) return false; //너무빨리 실행되지 않게 한다 var ts = DateTime.Now - _CrevisGrabTime[camIdx]; var fpsterm = (int)(1000f / 12f); if (ts.TotalMilliseconds < fpsterm) { System.Threading.Thread.Sleep((int)(fpsterm - ts.TotalMilliseconds)); return false; } _CrevisGrabTime[camIdx] = DateTime.Now; Int32 status = VirtualFG40Library.MCAM_ERR_SUCCESS; try { mre_grab[camIdx].Reset(); //데이터수집확인 if (PUB._isCrevisACQ[camIdx] == false) { // Acqusition Start status = _virtualFG40.AcqStart(_hDevice[camIdx]); if (status == VirtualFG40Library.MCAM_ERR_RESOURCE_IN_USE) { if (_hDevice[camIdx] > 0) _virtualFG40.AcqStop(_hDevice[camIdx]); PUB._isCrevisACQ[camIdx] = false; } else if (status != VirtualFG40Library.MCAM_ERR_SUCCESS) { PUB.log_[logIdx].AddE(String.Format("Camera ACQ failed : {0}", status)); if (_hDevice[camIdx] > 0) _virtualFG40.AcqStop(_hDevice[camIdx]); //실패하면 멈춘다 PUB._isCrevisACQ[camIdx] = false; } else { PUB._isCrevisACQ[camIdx] = true; PUB.log_[logIdx].AddI("Camera ACQ start"); } //이미지수집에 실패했다면 진행하지 않는다. if (PUB._isCrevisACQ[camIdx] == false) return false; } //이미지 수집 status = _virtualFG40.GrabImage(_hDevice[camIdx], camPtr[camIdx], (UInt32)_bufferSize[camIdx]); if (status != VirtualFG40Library.MCAM_ERR_SUCCESS) { PUB.log_[logIdx].AddE($"Camera capture({camIdx}) error : {status}"); if (_hDevice[camIdx] > 0) _virtualFG40.AcqStop(_hDevice[camIdx]); //실패하면 멈춘다 PUB._isCrevisACQ[camIdx] = false; PUB._isCrevisOpen[camIdx] = false; //연결여부도 끊는다 _virtualFG40.CloseDevice(_hDevice[camIdx]); return false; } else _CrevisGrabTime[camIdx] = DateTime.Now; //이미지생성 확인 if (mre[camIdx].WaitOne(100)) { mre[camIdx].Reset(); if (OrgImage[camIdx] == null || OrgImage[camIdx].IsVoid) { OrgImage[camIdx] = new EImageBW8(_width[camIdx], _height[camIdx]); } //생성된 이미지 복사 using (var grabimg = new EImageBW8()) { grabimg.SetImagePtr(_width[camIdx], _height[camIdx], camPtr[camIdx]); grabimg.CopyTo(OrgImage[camIdx]); //this.iv[camIdx].Invalidate(); //image update DrawImage(camTarget, Piv, grabimg); } mre[camIdx].Set(); } return true; } catch (Exception ex) { if (_hDevice[camIdx] > 0) _virtualFG40.AcqStop(_hDevice[camIdx]); //실패하면 멈춘다 PUB._isCrevisACQ[camIdx] = false; //var stackFrame = new System.Diagnostics.StackTrace(1).GetFrame(1); //string fileName = stackFrame.GetFileName(); //int lineNumber = stackFrame.GetFileLineNumber(); //var TraceInfo = stackFrame.ToString(); //var tracemsg = $"File:{fileName},Line:{lineNumber}\n{TraceInfo}"; PUB.log_[logIdx].AddE($"Crevis Grab({camIdx}):{ex.Message}"); return false; } finally { mre_grab[camIdx].Set(); } } public static string lastlogbarcode = string.Empty; public static string[] lastbcd = new string[] { string.Empty, string.Empty }; public static Boolean RequestNewRead = false; public static ManualResetEvent[] mre = new ManualResetEvent[2]; static string[] prebarcodedata = new string[] { "", "" }; /// /// 이미지를 처리합니다 /// 트리거가 없는 경우에는 릴존재여부와/컨베이어확인을 합니다. /// 트리거가 있다면 릴 영역을 찾아서 ID를 스캔합니다 /// /// /// public static bool CreavisProcess(int camIdx, bool isTrigger, Panel Piv) { var camTarget = PUB.GetTarget(camIdx); if (camTarget == eTarget.None) return false; var logIdx = camTarget == eTarget.Left ? 0 : 1; //이미지사용여부확인 if (mre[camIdx].WaitOne(100) == false) return false; mre[camIdx].Reset(); //이미지가 유효한 경우 처리한다 if (OrgImage[camIdx] == null || OrgImage[camIdx].IsVoid) { mre[camIdx].Set(); return false; } mre[camIdx].Reset(); System.Diagnostics.Stopwatch wat = new System.Diagnostics.Stopwatch(); wat.Restart(); //검사영역확인 var rect_reeldetect = camIdx == PUB.setting.CameraIndexL ? PUB.setting.ROI_ReelDetect_L : PUB.setting.ROI_ReelDetect_R; var rect_convdetect = camIdx == PUB.setting.CameraIndexL ? PUB.setting.ROI_ConvDetect_L : PUB.setting.ROI_ConvDetect_R; try { // //iv[camIdx].Shapes.Clear(); string msg; string bcdlist = string.Empty; int DataCount = 0;// data1.Count; Util_Vision.SCodeData codedata = new Util_Vision.SCodeData(); List datalist = new List(); List ptlist = new List(); var prccnt = 0; string barcodeMessage = string.Empty; //erode 값이 1과 3일때 차이가 발생함, 어두운 녹색라벨혹은, QR이 border에 붙은경우에 erode 3 은 서로 붙게되어서 필터링 되버림 //CvInvoke.CvtColor(OrgImage, OrgCImage, ColorConversion.Gray2Bgr); //릴을 확인 한다 //if (IsProcess[camidx]) //{ using (EImageEncoder enc = new EImageEncoder()) { using (var seg = enc.GrayscaleSingleThresholdSegmenter) { seg.WhiteLayerEncoded = true; seg.BlackLayerEncoded = false; seg.Mode = EGrayscaleSingleThreshold.Absolute; seg.AbsoluteThreshold = 50; } using (ECodedImage2 encimg = new ECodedImage2()) { using (EROIBW8 roiimge = new EROIBW8()) { roiimge.Attach(OrgImage[camIdx]); roiimge.SetPlacement(500, 70, 3008, 2640); //컨베이어전체영역이ㄴ enc.Encode(roiimge, encimg); using (EObjectSelection selection = new EObjectSelection()) { selection.Clear(); selection.AddObjects(encimg); selection.RemoveUsingUnsignedIntegerFeature(EFeature.Area, 1000, ESingleThresholdMode.LessEqual); PUB.DetectReelValue[camIdx] = (int)selection.ElementCount; PUB.DetectReel[camIdx] = selection.ElementCount > 1; } } } } // //else Pub.DetectReel = false; //컨베이어 확인여부 체크필요 var roi_conv = camIdx == PUB.setting.CameraIndexL ? PUB.setting.ROI_ConvDetect_L : PUB.setting.ROI_ConvDetect_R; if (roi_conv.IsEmpty == false) { using (EImageBW8 thimage = new EImageBW8(OrgImage[camIdx].Width, OrgImage[camIdx].Height)) { EasyImage.Copy(OrgImage[camIdx], thimage); var minresidu = EasyImage.AutoThreshold(thimage, EThresholdMode.MinResidue); EasyImage.Threshold(thimage, thimage, minresidu.Value); using (EROIBW8 roimage = new EROIBW8()) { roimage.Attach(thimage); roimage.SetPlacement(roi_conv.X, roi_conv.Y, roi_conv.Width, roi_conv.Height); EasyImage.PixelCount(roimage, new EBW8(64), new EBW8(86), out int val_below, out int val_between, out int val_above); PUB.DetectConvValue[camIdx] = val_below; var det_value = camIdx == PUB.setting.CameraIndexL ? PUB.setting.ConvDetectValueL : PUB.setting.ConvDetectValueR; PUB.DetectConv[camIdx] = val_below < det_value; } } } else PUB.DetectConv[camIdx] = false; //QR코드를 읽는다 List qrdataList = new List(); if (isTrigger) { var qrrlt = Util_Vision.DetectQR(OrgImage[camIdx], null, prccnt++, out msg, PUB.setting.erodevaluestr, PUB.setting.GainOffsetListStr, PUB.setting.blob_area_min, PUB.setting.blob_area_max, PUB.setting.blob_sigmaxy, PUB.setting.blob_sigmayy, PUB.setting.blob_sigmaxx, PUB.setting.blob_minw, PUB.setting.blob_maxw, PUB.setting.blob_minh, PUB.setting.blob_maxh, finddata: PUB.lastdata[camIdx]); qrdataList = qrrlt.Item1; PUB.ProcessTime[camIdx] = qrrlt.Item4; var target = camIdx == PUB.setting.CameraIndexL ? eTarget.Left : eTarget.Right; // var pan = target == eTarget.Left ? pIvLeft : pIvRight; DrawImage(target, Piv, OrgImage[camIdx], qrrlt.Item1, qrrlt.Item2, qrrlt.Item3); DataCount = qrdataList.Count; } else DataCount = 0; //데이터가 확인되었다면 읽은 경우이다 if (DataCount > 0) { var bidx = 0; foreach (var item in qrdataList.OrderByDescending(t => t.sid)) { datalist.Add(item.data); ptlist.Add(item.corner); codedata = item; if (bcdlist.isEmpty() == false) bcdlist += "\n"; bcdlist += $"[#{bidx}] {item.data}"; bidx += 1; } } var tsrun = DateTime.Now - _CrevisRunTime[camIdx]; var dispMessage = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " (" + tsrun.TotalMilliseconds.ToString("N0") + "ms)"; if (barcodeMessage.isEmpty() == false) dispMessage += "\n" + barcodeMessage; if (bcdlist.isEmpty() == false && lastlogbarcode != bcdlist) { if(bcdlist.Equals(prebarcodedata[camIdx])==false) { PUB.log_[logIdx].Add("BARCODE", "New recognition:" + bcdlist); prebarcodedata[camIdx] = bcdlist; } lastlogbarcode = bcdlist; RaiseRemoteCommand(remotelist.barcodeupdate, camIdx, bcdlist); //값이 변경되었으니 표시해준다 } else if (bcdlist.isEmpty() && lastlogbarcode.isEmpty() == false) { RaiseRemoteCommand(remotelist.barcodeupdate, camIdx, string.Empty); lastlogbarcode = string.Empty; } var tsparse = DateTime.Now - parsetime; if (tsparse.TotalMilliseconds >= PUB.setting.GrabDelaySlow) { //var data = codedata.data;//: String.Empty; if (PUB.RequestNewRead) { //신규 요청받고 처음들어온 데이터는 처리하지 말자 - 211213 PUB.RequestNewRead = false; } else { if (PUB.setting.SendRawData) //211210 { if (PUB.BarcodeParsing(camIdx, qrdataList, "CREVIS")) parsetime = DateTime.Now; else parsetime = DateTime.Now.AddMilliseconds(50); } else { if (PUB.BarcodeParsing(camIdx, datalist, "CREVIS")) parsetime = DateTime.Now; else parsetime = DateTime.Now.AddMilliseconds(50); } } } else //이떄에는 용량을 체크한다. 210805 { try { if (PUB.setting.AutoDeleteSeconds > 0 && PUB.setting.AutoDeleteSeconds < 99) { var di = new System.IO.DirectoryInfo(PUB.setting.ImageSavePath); var ttime = DateTime.Now.AddSeconds(-PUB.setting.AutoDeleteSeconds); var dellist = di.GetFiles().Where(t => t.CreationTime <= ttime).FirstOrDefault(); if (dellist != null) dellist.Delete(); } } catch { } } //iv[camIdx].Invalidate(); wat.Stop(); PUB.ProcessTime[camIdx] = wat.ElapsedMilliseconds; _CrevisRunTime[camIdx] = DateTime.Now; return true; } catch (Exception ex) { //var tracemsg = $"File:{fileName},Line:{lineNumber}\n{TraceInfo}"; PUB.log_[logIdx].AddE($"Crevis Process({camIdx}):" + ex.Message); return false; } finally { wat.Stop(); mre[camIdx].Set(); } } /// /// 판넬이미지 변경 /// /// /// /// /// 확인된 qr이 있다면 표시합니다. /// 흰색영역이 마킹된 영역 /// QR로 추정되는 영역 public static void DrawImage(eTarget target, Panel p, EImageBW8 grabimg, List qrdata = null, List rect_area = null, List rect_reel = null) { var roi_reel = target == eTarget.Left ? PUB.setting.ROI_ReelDetect_L : PUB.setting.ROI_ReelDetect_R; var roi_conv = target == eTarget.Left ? PUB.setting.ROI_ConvDetect_L : PUB.setting.ROI_ConvDetect_R; var camIdx = target == eTarget.Left ? PUB.setting.CameraIndexL : PUB.setting.CameraIndexR; var detect_reel = PUB.DetectReel[camIdx]; var detect_conv = PUB.DetectConv[camIdx]; var zoomx = (p.Width * 1f) / grabimg.Width; var zoomy = (p.Height * 1f) / grabimg.Height; using (var g = p.CreateGraphics()) { grabimg.Draw(g, zoomx, zoomy); //이미지의 중앙부분으 포커스를 계산한다. float focus = 0f; if (OrgImage[camIdx].IsVoid == false) { var fw = (int)(OrgImage[camIdx].Width * 0.4f); var fh = (int)(OrgImage[camIdx].Height * 0.4f); var fx = (int)((OrgImage[camIdx].Width - fw) / 2f); var fy = (int)((OrgImage[camIdx].Height - fw) / 2f); //var frect = new Rectangle(fx, fy, fw, fh); g.DrawRectangle(Pens.Gold, fx * zoomx, fy * zoomy, fw * zoomx, fh * zoomy); using (var img = new EROIBW8()) { img.Attach(OrgImage[camIdx]); img.SetPlacement(fx, fy, fw, fh); focus = EasyImage.Focusing(img); } } using (Font f = new Font("Consolas", 10, FontStyle.Bold)) { var msg = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + $"\ncam:{camIdx},focus:{focus}" + $"\nReel:{detect_reel},Value={PUB.DetectReelValue[camIdx]}" + $"\nConv:{detect_conv},Value={PUB.DetectConvValue[camIdx]}"; g.DrawString(msg, f, Brushes.White, 10, 10); } if (roi_reel.IsEmpty == false) { var rect = roi_reel; var x = rect.X * zoomx; var y = rect.Y * zoomy; var w = rect.Width * zoomx; var h = rect.Height * zoomy; g.DrawRectangle(Pens.Lime, x, y, w, h); } if (roi_conv.IsEmpty == false) { var rect = roi_conv; var x = rect.X * zoomx; var y = rect.Y * zoomy; var w = rect.Width * zoomx; var h = rect.Height * zoomy; g.DrawRectangle(Pens.Magenta, x, y, w, h); } //border g.DrawRectangle(Pens.White, p.DisplayRectangle); //검색영역표시(영역검사) if (rect_area != null && rect_area.Any()) { foreach (var item in rect_area) { var x = item.X * zoomx; var y = item.Y * zoomy; var w = item.Width * zoomx; var h = item.Height * zoomy; g.DrawRectangle(Pens.SkyBlue, x, y, w, h); } } //검색영역표시(QR검사) if (rect_reel != null && rect_reel.Any()) { foreach (var item in rect_reel) { var x = item.X * zoomx; var y = item.Y * zoomy; var w = item.Width * zoomx; var h = item.Height * zoomy; g.DrawRectangle(Pens.Blue, x, y, w, h); } } //바코드가 검색되었다면? if (qrdata != null && qrdata.Any()) { using (Font f = new Font("Consolas", 10, FontStyle.Bold)) { foreach (var item in qrdata) { //각코너의 점을 표시한다. var firstX = 0f; var firstY = 0f; foreach (var cn in item.corner) { var x = cn.X * zoomx; var y = cn.Y * zoomy; if (firstX == 0 && firstY == 0) { firstX = x; firstY = y; } } //첫번째 좌표에 데이터를 표시해준다 g.DrawString(item.data, f, Brushes.Lime, firstX, firstY); } } } g.Dispose(); } } public static string[] lastlog = new string[] { string.Empty, string.Empty }; public static DateTime[] logtime = new DateTime[] { DateTime.Now, DateTime.Now }; public static bool[] _trigger = new bool[] { false, false }; public static DateTime[] triggerTime = new DateTime[] { DateTime.Now, DateTime.Now }; public static Boolean[] IsTrigger = new bool[] { false, false }; public static DateTime TriggerStart = DateTime.Now; public static Boolean BarcodeParsing(int camIdx, List data, string source, Boolean force = false) { var camTarget = PUB.GetTarget(camIdx); if (camTarget == eTarget.None) return false; var logIdx = camTarget == eTarget.Left ? 0 : 1; var datatagstr = string.Empty; foreach (var item in data) if (item.data.isEmpty() == false) { if (datatagstr.Length > 0) datatagstr += "\n"; datatagstr += item.data; } PUB.lastbcd[camIdx] = datatagstr; //스트림데이터가 꺼져있다면 처리하지 않는다. if (force == false && PUB.setting.DisableStreamData) { //트리거모드일때 보내는 플래그가 없다면 보내지 않는다. if (PUB.IsTrigger[camIdx] == false) { PUB.log_[logIdx].AddAT($"[SKIP-SEND] No Trigger Signal"); return false; } } //TriggerSend = false; //통신이 연결되어있지 않다면 처리하지 않는다 if (PUB.wsock_[logIdx].IsListening == false || PUB.wsock_[logIdx].ListClients().Count() < 1) { PUB.log_[logIdx].AddAT($"[SKIP-SEND] Disconnected"); return false; } //파일을 저장한다. var path = ""; if (PUB.mre[camIdx].WaitOne(100)) { try { PUB.mre[camIdx].Reset(); path = System.IO.Path.Combine(PUB.setting.ImageSavePath, $"[{camIdx}]barcode_{DateTime.Now.ToString("HHmmssfff")}.jpg"); var fi = new System.IO.FileInfo(path); if (fi.Directory.Exists == false) fi.Directory.Create(); PUB.OrgImage[camIdx].Save(fi.FullName); } catch (Exception ex) { PUB.log_[logIdx].AddE($"Save failed {ex.Message}"); } finally { PUB.mre[camIdx].Set(); } } else { PUB.log_[logIdx].AddE($"Save failed (object is locked)"); } //데이터 생성 var msg = new { guid = PUB.lastguid[camIdx], command = PUB.lastcmd[camIdx], data = data, time = DateTime.Now.ToString(), file = path }; var json = Newtonsoft.Json.JsonConvert.SerializeObject(msg); Boolean sendok = false; try { if (PUB.setting.Log_BarcodeTx) { if (lastlog[camIdx] == datatagstr) { var tsee = DateTime.Now - logtime[camIdx]; if (tsee.TotalSeconds > 60) { PUB.log_[logIdx].AddI(json); lastlog[camIdx] = datatagstr; logtime[camIdx] = DateTime.Now; } } else { PUB.log_[logIdx].AddI(json); lastlog[camIdx] = datatagstr; } } //PUB.ws[camIdx].ListClients().ToList().ForEach(t => PUB.ws[camIdx].SendAsync(t, json).Wait()); PUB.lastsend[camIdx] = DateTime.Now; Send_WSock(camTarget, json); if (msg.guid.isEmpty() == false) PUB.log_[logIdx].Add("Tx", json); sendok = true; } catch (Exception ex) { PUB.log_[logIdx].AddE($"Send failed {ex.Message}"); sendok = false; } if (sendok == false) { try { PUB.log_[logIdx].AddAT("Closing server due to send failure"); Time_WS_Listen[camIdx] = DateTime.Now; PUB.wsock_[logIdx].Stop(); } catch (Exception ex) { PUB.log_[logIdx].AddE($"Server shutdown failed:{ex.Message}"); } return false; } else return true; } public static ManualResetEvent[] mre_send = new ManualResetEvent[2]; public static bool Send_WSock(eTarget camTarget, string data) { if (camTarget == eTarget.None) return false; var camIdx = camTarget == eTarget.Left ? PUB.setting.CameraIndexL : PUB.setting.CameraIndexR; var logIdx = camTarget == eTarget.Left ? 0 : 1; if (PUB.wsock_[logIdx].IsListening == false || PUB.wsock_[logIdx].ListClients().Count() < 1) { PUB.log_[logIdx].AddAT($"[IGNORE-SEND] Not Listening or No Clients"); return false; } if (mre_send[camIdx].WaitOne(1000) == false) { PUB.log_[logIdx].AddE($"send error by mre-lock"); return false; } mre_send[camIdx].Reset(); var ws = PUB.wsock_[logIdx]; try { ws.ListClients().ToList().ForEach(t => ws.SendAsync(t, data).Wait()); PUB.log_[logIdx].AddI($"send Complete {data}"); return true; } catch (Exception ex) { PUB.log_[logIdx].AddE($"send error by {ex.Message}"); return false; } finally { mre_send[camIdx].Set(); } } //마지막으로 전송에 사용한 데이터를 임시 저장한다. -211213 // 데이터 missing 현상 관련 처리 작업 public static string[] lastTxGuid = new string[] { string.Empty, string.Empty }; public static string[] lastTxRID = new string[] { string.Empty, string.Empty }; public static DateTime lastTxTime = DateTime.Now; public static Boolean BarcodeParsing(int camIdx, List data, string source) { if (data == null || data.Count < 1) return false; PUB.lastbcd[camIdx] = string.Join("|", data); var camTarget = PUB.GetTarget(camIdx); if (camTarget == eTarget.None) return false; var logIdx = camTarget == eTarget.Left ? 0 : 1; //스트림데이터가 꺼져있다면 처리하지 않는다. if (PUB.setting.DisableStreamData) { //트리거모드일때 보내는 플래그가 없다면 보내지 않는다. if (IsTrigger[camIdx] == false) return false; } //통신이 연결되어있지 않다면 처리하지 않는다 if (PUB.wsock_[logIdx].IsListening == false || PUB.wsock_[logIdx].ListClients().Count() < 1) return false; //파일을 저장한다. var path = ""; if (PUB.mre[camIdx].WaitOne(100)) { try { path = System.IO.Path.Combine(PUB.setting.ImageSavePath, $"[{camIdx}]barcode_{DateTime.Now.ToString("HHmmssfff")}.jpg"); PUB.mre[camIdx].Reset(); var fi = new System.IO.FileInfo(path); if (fi.Directory.Exists == false) fi.Directory.Create(); PUB.OrgImage[camIdx].Save(fi.FullName); } catch (Exception ex) { PUB.log_[logIdx].AddE($"Save failed {ex.Message}"); } finally { PUB.mre[camIdx].Set(); } } //데이터 생성 var msg = new { guid = PUB.lastguid[camIdx], command = PUB.lastcmd[camIdx], data = data, time = DateTime.Now.ToString(), file = path }; //마지막으로전송한 RID값이 동일한경우 if (lastTxRID[camIdx].Trim() == PUB.lastbcd[camIdx].Trim()) { if (lastTxGuid[camIdx].Trim() != PUB.lastguid[camIdx].Trim()) { var tsTx = DateTime.Now - lastTxTime; if (tsTx.TotalSeconds < 5) { //GUID가 다른데 rid가 같다 / //missing data 의 패턴잉ㅆ다. 2113 //이때는 전송하지 않고 그냥 skip하게한다. PUB.lastguid[camIdx] = string.Empty; PUB.lastcmd[camIdx] = string.Empty; PUB.log_[logIdx].Add($"Only GUID of last transmission data differs, processing skip. (within 5 seconds only)"); return false; } } } //마지막으로 전송한 데이터 값 저장 lastTxGuid[camIdx] = PUB.lastguid[camIdx]; lastTxRID = PUB.lastbcd; lastTxTime = DateTime.Now; var json = Newtonsoft.Json.JsonConvert.SerializeObject(msg); Boolean sendok = false; try { if (PUB.lastbcd[camIdx].isEmpty() == false && PUB.setting.Log_BarcodeTx) { if (lastlog[camIdx] == PUB.lastbcd[camIdx]) { var tsee = DateTime.Now - logtime[camIdx]; if (tsee.TotalSeconds > 60) { PUB.log_[logIdx].AddI(json); lastlog[camIdx] = PUB.lastbcd[camIdx]; logtime[camIdx] = DateTime.Now; } } else { PUB.log_[logIdx].AddI(json); lastlog[camIdx] = PUB.lastbcd[camIdx]; } } //PUB.ws[camIdx].ListClients().ToList().ForEach(t => PUB.ws[camIdx].SendAsync(t, json).Wait()); PUB.lastsend[camIdx] = DateTime.Now; Send_WSock(camTarget, json); if (msg.guid.isEmpty() == false) PUB.log_[logIdx].Add("Tx", json); sendok = true; } catch (Exception ex) { PUB.log_[logIdx].Add($"Send failed {ex.Message}"); sendok = false; } if (sendok == false) { try { PUB.log_[logIdx].AddAT("Closing server due to send failure"); PUB.Time_WS_Listen[camIdx] = DateTime.Now; PUB.wsock_[logIdx].Stop(); } catch (Exception ex) { PUB.log_[logIdx].AddE($"Server shutdown failed:{ex.Message}"); } try { PUB.log_[logIdx].AddAT("Closing socket due to send failure"); PUB.wsock_[logIdx].Stop(); } catch (Exception ex) { PUB.log_[logIdx].AddE($"Socket shutdown failed:{ex.Message}"); } return false; } else return true; } public static DateTime[] Time_WS_Connected = new DateTime[2]; public static DateTime[] Time_WS_Disconnected = new DateTime[2]; public static DateTime[] Time_WS_Listen = new DateTime[2]; public static DateTime[] Time_WS_Listen_Try = new DateTime[2]; public static DateTime[] Time_WS_Recv = new DateTime[2]; public static string[] WS_LastRecv = new string[] { string.Empty, string.Empty }; public static string[] WS_LastSend = new string[] { string.Empty, string.Empty }; public static void ChangeUIPopup(System.Windows.Forms.NumericUpDown valueCtl) { var value = valueCtl.Value.ToString(); var f = AR.UTIL.InputBox("input value", value);// new Dialog.fInput(value); if(f.Item1 == true) { var val = decimal.Parse(f.Item2); if (val < valueCtl.Minimum) { UTIL.MsgE(string.Format("Minimum input value is {0}.", valueCtl.Minimum)); val = valueCtl.Minimum; } if (val > valueCtl.Maximum) { UTIL.MsgE(string.Format("Maximum input value is {0}.", valueCtl.Maximum)); val = valueCtl.Maximum; } valueCtl.Value = val; } } } }