change-修改相机通信方式

master
liuwf 5 months ago
parent f8893916da
commit 6bc16fa3bb

@ -1,4 +1,5 @@
using Microsoft.Extensions.Logging; using HslCommunication.Profinet.GE;
using Microsoft.Extensions.Logging;
using SlnMesnac.Common; using SlnMesnac.Common;
using SlnMesnac.Config; using SlnMesnac.Config;
using SlnMesnac.Model.domain; using SlnMesnac.Model.domain;
@ -8,9 +9,11 @@ using SlnMesnac.Repository.service.Impl;
using SlnMesnac.TouchSocket; using SlnMesnac.TouchSocket;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Security.Cryptography.Xml; using System.Security.Cryptography.Xml;
using System.Threading; using System.Threading;
using System.Threading.Tasks;
using TouchSocket.Core; using TouchSocket.Core;
namespace SlnMesnac.Business namespace SlnMesnac.Business
@ -18,20 +21,27 @@ namespace SlnMesnac.Business
public class LogoBusiness public class LogoBusiness
{ {
private ILogger<LogoBusiness> _logger; private TcpServer tcpServer = null;
private ILogger<LogoBusiness> logger;
private PlcAbsractFactory plc = null; private PlcAbsractFactory plc = null;
private CCameraHik hikHelper = CCameraHik.Instance;
private DebugConfig config = DebugConfig.Instance; private DebugConfig config = DebugConfig.Instance;
private IBaseMaterialService baseMaterialService; private IBaseMaterialService baseMaterialService;
private ILogoIdentifyService logoIdentifyService; private ILogoIdentifyService logoIdentifyService;
private ILogoConfigService logoConfigService;
public PaddleOCRSharp.PaddleOCREngine engine = null; public PaddleOCRSharp.PaddleOCREngine engine = null;
private GunHelper gunHelper = GunHelper.Instance;
private static LogoBusiness instance; private static LogoBusiness instance;
// 存放照片路径
public static string PicturePath = System.Environment.CurrentDirectory + "/picture/";
/// <summary>
/// 存储海康相机识别结果
/// </summary>
private static bool HikCameraResult = false;
#region 委托定义 刷新界面扫描信息 #region 委托定义 刷新界面扫描信息
public delegate void RefreshBoxInfo(string boxCode, string boxTime, string model, byte[] imageData, bool isSuccess); public delegate void RefreshBoxInfo(string boxCode, string boxTime, string model, byte[] imageData, bool isSuccess);
@ -43,25 +53,33 @@ namespace SlnMesnac.Business
#endregion #endregion
private LogoBusiness(IBaseMaterialService baseMaterialService,ILogoIdentifyService logoIdentifyService,PlcPool _plcPool) private LogoBusiness(ILogger<LogoBusiness> logger,ILogoConfigService logoConfigService, IBaseMaterialService baseMaterialService,ILogoIdentifyService logoIdentifyService,PlcPool _plcPool,TcpServer _tcpServer)
{ {
this.logger = logger;
tcpServer = _tcpServer;
TcpServer.RefreshMaterialCodeStrEvent += BarCodeHandler; TcpServer.RefreshMaterialCodeStrEvent += BarCodeHandler;
TcpServer.CameraResultEvent += ReceiveCameraResult;
this.baseMaterialService = baseMaterialService; this.baseMaterialService = baseMaterialService;
this.logoIdentifyService = logoIdentifyService; this.logoIdentifyService = logoIdentifyService;
this.logoConfigService = logoConfigService;
plc= _plcPool.GetPlcByKey("plc"); gunHelper.InstanceSerialPort();
plc = _plcPool.GetPlcByKey("plc");
BarCodeHandler("2741001000021E680369","");
} }
private void ReceiveCameraResult(string result)
{
logger.LogInformation($"相机返回结果:{result}");
public static LogoBusiness GetInstance(IBaseMaterialService baseMaterialService, ILogoIdentifyService ocrVerfiyService, PlcPool _plcPool) }
public static LogoBusiness GetInstance(ILogger<LogoBusiness> logger,ILogoConfigService logoConfigService,IBaseMaterialService baseMaterialService, ILogoIdentifyService ocrVerfiyService, PlcPool _plcPool, TcpServer _tcpServer)
{ {
if (instance == null) if (instance == null)
{ {
instance = new LogoBusiness(baseMaterialService, ocrVerfiyService, _plcPool); instance = new LogoBusiness(logger,logoConfigService,baseMaterialService, ocrVerfiyService, _plcPool,_tcpServer);
} }
return instance; return instance;
} }
@ -72,62 +90,85 @@ namespace SlnMesnac.Business
/// </summary> /// </summary>
/// <param name="materialCodeStr"></param> /// <param name="materialCodeStr"></param>
/// <param name="ip"></param> /// <param name="ip"></param>
public void BarCodeHandler(string materialCodeStr, string ip) public async void BarCodeHandler(string materialCodeStr, string ip)
{ {
// 传入照片
byte[] ImageData = null;
try try
{ {
#region 初始操作:复位海康上次结果,删除海康上次保存文件
HikCameraResult = false;
FileHelper.DeleteAllPictures(config.CameraFilePath);
#endregion
bool judge = FoamtJudge(materialCodeStr); bool judge = FoamtJudge(materialCodeStr);
if (!judge) if (!judge)
{ {
WarningAndStop($"箱体码{materialCodeStr}格式不正确,停线报警!"); WarningAndStop($"箱体码{materialCodeStr}格式不正确,停线报警!");
return; return;
} }
_logger.LogInformation($"扫描到箱体码:{materialCodeStr}"); logger.LogInformation($"扫描到箱体码:{materialCodeStr}");
// 1.触发相机拍照 // 1.触发相机拍照
bool TriggerFlag = hikHelper.TriggerGather(); tcpServer.SendCommand(config.CameraIP, "Execute");
if (!TriggerFlag)
{ //2.根据箱体码查询型号根据型号判断是否需要校验LOGO
WarningAndStop($"软触发相机拍照失败,停线报警"); ProductModel mode = logoConfigService.GetMaterialTypeByBarCode(materialCodeStr);
return; LogoConfig logoConfig = logoConfigService.GetByMaterialType(mode.MaterialCode);
} // 海康校验结果
// 2.等待接收海康结果 bool hikFlag = false;
bool flag = JudgeIsSuccess();
if (flag) if (logoConfig.IsChecked == 1)
{ {
//校验成功下发放行 // 需要校验
PlcPass(); // 2.等待接收海康结果
RefreshMessageEvent?.Invoke("Logo识别成功下发放行"); hikFlag = await JudgeIsSuccessAsync();
_logger.LogInformation($"箱体码:{materialCodeStr}Logo识别成功下发放行"); if (hikFlag)
{
//校验成功下发放行
Pass();
RefreshMessageEvent?.Invoke("Logo识别成功下发放行");
logger.LogInformation($"箱体码:{materialCodeStr}Logo识别成功下发放行");
}
else
{
//校验成功下发放行
WarningAndStop($"Logo识别失败禁止放行");
}
} }
else else
{ {
//校验成功下发放行 // 不需要校验
WarningAndStop($"Logo识别失败禁止放行"); hikFlag = true;
Pass();
RefreshMessageEvent?.Invoke("Logo无需识别下发放行");
logger.LogInformation($"箱体码:{materialCodeStr}Logo无需识别下发放行");
} }
// 3.查询mes获取箱体信息 #region 更新数据库
BaseMaterialInfo baseMaterialInfo = baseMaterialService.GetMaterialInfoByMaterialCode(materialCodeStr.Substring(7, 10));
string productName = GetSubstringBetweenCommas(baseMaterialInfo.MaterialName);
#region 回传MES信息和更新本地数据库
// TODO 回传MES信息
LogoIdentify record = new LogoIdentify(); LogoIdentify record = new LogoIdentify();
record.ProductCode = materialCodeStr; record.ProductCode = materialCodeStr;
record.MaterialName = productName; record.MaterialType = logoConfig.MaterialType;
record.Result = flag ? 1 : 0; record.MaterialName = logoConfig.MaterialName;
record.isChecked = logoConfig.IsChecked;
record.Result = hikFlag ? 1 : 0;
record.RecordTime = DateTime.Now; record.RecordTime = DateTime.Now;
logoIdentifyService.InsertRecord(record); logoIdentifyService.InsertRecord(record);
#endregion #endregion
// TODO , 传入照片 ImageData = FileHelper.FindPhoto(config.CameraFilePath);
byte[] ImageData = null ; if(ImageData != null)
// 刷新界面、刷新图片,照片按照日期存储本地 {
RefreshBoxInfoEvent?.Invoke(materialCodeStr, DateTime.Now.ToString(),productName,ImageData,flag); FileHelper.SaveImage(ImageData, materialCodeStr + ".jpg", PicturePath);
// 刷新界面、刷新图片,照片按照日期存储本地
RefreshBoxInfoEvent?.Invoke(materialCodeStr, DateTime.Now.ToString(), logoConfig.MaterialName, ImageData, hikFlag);
}
else
{
WarningAndStop($"读取相机保存照片文件夹失败,请检查文件夹:{config.CameraFilePath}是否存在");
}
} }
catch (Exception ex) catch (Exception ex)
{ {
WarningAndStop($"BarCodeHandler异常,识别Logo失败,原因:{ex.Message},箱体条码:{materialCodeStr}"); WarningAndStop($"BarCodeHandler异常,识别Logo失败,原因:{ex.Message},箱体条码:{materialCodeStr}");
@ -140,19 +181,36 @@ namespace SlnMesnac.Business
/// 判断Logo校验是否成功 /// 判断Logo校验是否成功
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public bool JudgeIsSuccess() public async Task<bool> JudgeIsSuccessAsync()
{ {
bool result = false; bool result = false;
// 设置计时器
//TODO 等待接受海康的校验结果 Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
//至多等待2.5s海康的校验结果
result = await Task.Run(() =>
{
while (true)
{
if (HikCameraResult == true)
{
return true;
}
// 检查是否超过两秒
if (stopwatch.ElapsedMilliseconds > 2500)
{
return false;
}
Thread.Sleep(100);
}
});
return result; return result;
} }
/// <summary> /// <summary>
/// 箱体码格式校验 /// 箱体码格式校验
/// </summary> /// </summary>
@ -162,7 +220,7 @@ namespace SlnMesnac.Business
{ {
if (!string.IsNullOrEmpty(code)) if (!string.IsNullOrEmpty(code))
{ {
if(code.Substring(0,1)=="B" && code.Length == 21) if(code.Length == 20)
{ {
return true; return true;
} }
@ -207,29 +265,34 @@ namespace SlnMesnac.Business
#region PLC交互部分 #region PLC交互部分
//M100停止点位 //M100停止点位
public void PlcPass() public void Pass()
{ {
if(plc!=null && plc.IsConnected) if(plc!=null && plc.IsConnected)
{ {
plc.writeInt16ByAddress("M100",0); plc.writeInt16ByAddress("M100",0);
} }
// 声光电报警复位
gunHelper.SendData("OK");
} }
public void PlcStop() public void Stop()
{ {
if (plc != null && plc.IsConnected) if (plc != null && plc.IsConnected)
{ {
plc.writeInt16ByAddress("M100", 1); plc.writeInt16ByAddress("M100", 1);
} }
// 声光电报警复位
gunHelper.SendData("NG");
} }
#endregion #endregion
#region 记录日志刷新界面及下发PLC报警 #region 记录日志刷新界面及下发PLC报警
public void WarningAndStop(string message) public void WarningAndStop(string message)
{ {
_logger.LogError(message); logger.LogError(message);
RefreshMessageEvent?.Invoke(message, true); RefreshMessageEvent?.Invoke(message, true);
PlcStop(); Stop();
} }
#endregion #endregion

@ -1,452 +1,450 @@
using Microsoft.Extensions.DependencyInjection; //using Microsoft.Extensions.DependencyInjection;
using MvCamCtrl.NET; //using MvCamCtrl.NET;
using MvCamCtrl.NET.CameraParams; //using MvCamCtrl.NET.CameraParams;
using SlnMesnac.Config; //using SlnMesnac.Config;
using System; //using System;
using System.Collections.Generic; //using System.Collections.Generic;
using System.Drawing; //using System.Drawing;
using System.IO; //using System.IO;
using System.Linq; //using System.Linq;
using System.Text; //using System.Text;
using System.Threading; //using System.Threading;
namespace SlnMesnac.Common //namespace SlnMesnac.Common
{ //{
public class CCameraHik // public class CCameraHik
{ // {
#region 单例实现 // #region 单例实现
private static readonly Lazy<CCameraHik> lazy = new Lazy<CCameraHik>(() => new CCameraHik()); // private static readonly Lazy<CCameraHik> lazy = new Lazy<CCameraHik>(() => new CCameraHik());
public static CCameraHik Instance // public static CCameraHik Instance
{ // {
get // get
{ // {
return lazy.Value; // return lazy.Value;
} // }
} // }
#endregion // #endregion
public delegate void RefreshCamera(string ip,bool flag); // public delegate void RefreshCamera(string ip,bool flag);
public static event RefreshCamera RefreshCameraEvent; // public static event RefreshCamera RefreshCameraEvent;
private DebugConfig config = DebugConfig.Instance; // private DebugConfig config = DebugConfig.Instance;
/// <summary> // /// <summary>
/// 已经打开的设备集合 // /// 已经打开的设备集合
/// </summary> // /// </summary>
public static Dictionary<string, CCamera> m_MyCameras = new Dictionary<string, CCamera>(); // public static Dictionary<string, CCamera> m_MyCameras = new Dictionary<string, CCamera>();
/// <summary> // /// <summary>
/// 枚举到的设备集合 // /// 枚举到的设备集合
/// </summary> // /// </summary>
List<CCameraInfo> m_ltDeviceList = new List<CCameraInfo>(); // List<CCameraInfo> m_ltDeviceList = new List<CCameraInfo>();
Thread m_hReceiveThread1 = null; // Thread m_hReceiveThread1 = null;
Thread m_hReceiveThread2 = null; // Thread m_hReceiveThread2 = null;
bool m_bGrabbing = false; // bool m_bGrabbing = false;
// 存放照片路径 // // 存放照片路径
public string PicturePath = System.Environment.CurrentDirectory + "/picture/"; // public string PicturePath = System.Environment.CurrentDirectory + "/picture/";
// ch:用于从驱动获取图像的缓存 | en:Buffer for getting image from driver // // ch:用于从驱动获取图像的缓存 | en:Buffer for getting image from driver
private static Object BufForDriverLock = new Object(); // private static Object BufForDriverLock = new Object();
CImage m_pcImgForDriver = null; // 图像信息 // CImage m_pcImgForDriver = null; // 图像信息
CFrameSpecInfo m_pcImgSpecInfo = null; // 图像的水印信息 // CFrameSpecInfo m_pcImgSpecInfo = null; // 图像的水印信息
UInt32 m_nCurWidth = 0; // UInt32 m_nCurWidth = 0;
UInt32 m_nCurHeight = 0; // UInt32 m_nCurHeight = 0;
MvGvspPixelType m_emPixelType = MvGvspPixelType.PixelType_Gvsp_Mono8; // MvGvspPixelType m_emPixelType = MvGvspPixelType.PixelType_Gvsp_Mono8;
/// <summary> // /// <summary>
/// 枚举设备 // /// 枚举设备
/// </summary> // /// </summary>
public void DeviceListAndStart() // public void DeviceListAndStart()
{ // {
// ch:创建设备列表 | en:Create Device List // // ch:创建设备列表 | en:Create Device List
System.GC.Collect(); // System.GC.Collect();
//枚举设备 // //枚举设备
int nRet = CSystem.EnumDevices(CSystem.MV_GIGE_DEVICE | CSystem.MV_USB_DEVICE, ref m_ltDeviceList); // int nRet = CSystem.EnumDevices(CSystem.MV_GIGE_DEVICE | CSystem.MV_USB_DEVICE, ref m_ltDeviceList);
if (0 != nRet) // if (0 != nRet)
{ // {
// ShowErrorMsg("Enumerate devices fail!", 0); // // ShowErrorMsg("Enumerate devices fail!", 0);
return; // return;
} // }
//打开设备 // //打开设备
foreach (CCameraInfo deviceInfo in m_ltDeviceList) // foreach (CCameraInfo deviceInfo in m_ltDeviceList)
{ // {
bool flag = OpenDevice(deviceInfo); // bool flag = OpenDevice(deviceInfo);
if(!flag) // if(!flag)
{ // {
// TODO 重连 // // TODO 重连
} // }
} // }
Console.WriteLine("设备数:"+m_ltDeviceList.Count); // Console.WriteLine("设备数:"+m_ltDeviceList.Count);
StartGrab(); // StartGrab();
} // }
public bool OpenDevice(CCameraInfo device) // public bool OpenDevice(CCameraInfo device)
{ // {
try // try
{ // {
CCamera item = new CCamera(); // CCamera item = new CCamera();
int nRet = item.CreateHandle(ref device); // int nRet = item.CreateHandle(ref device);
if (CErrorDefine.MV_OK != nRet) // if (CErrorDefine.MV_OK != nRet)
{ // {
return false; // return false;
} // }
nRet = item.OpenDevice(); // nRet = item.OpenDevice();
if (CErrorDefine.MV_OK != nRet) // if (CErrorDefine.MV_OK != nRet)
{ // {
item.DestroyHandle(); // item.DestroyHandle();
Console.WriteLine("Device open fail!", nRet); // Console.WriteLine("Device open fail!", nRet);
return false; // return false;
} // }
// ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera) // // ch:探测网络最佳包大小(只对GigE相机有效) | en:Detection network optimal package size(It only works for the GigE camera)
if (device.nTLayerType == CSystem.MV_GIGE_DEVICE) // if (device.nTLayerType == CSystem.MV_GIGE_DEVICE)
{ // {
int nPacketSize = item.GIGE_GetOptimalPacketSize(); // int nPacketSize = item.GIGE_GetOptimalPacketSize();
if (nPacketSize > 0) // if (nPacketSize > 0)
{ // {
nRet = item.SetIntValue("GevSCPSPacketSize", (uint)nPacketSize); // nRet = item.SetIntValue("GevSCPSPacketSize", (uint)nPacketSize);
if (nRet != CErrorDefine.MV_OK) // if (nRet != CErrorDefine.MV_OK)
{ // {
Console.WriteLine("Set Packet Size failed!", nRet); // Console.WriteLine("Set Packet Size failed!", nRet);
} // }
} // }
} // }
// 设置触发模式 // // 设置触发模式
item.SetEnumValue("TriggerMode", (uint)MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON); // item.SetEnumValue("TriggerMode", (uint)MV_CAM_TRIGGER_MODE.MV_TRIGGER_MODE_ON);
// ch:触发源设为软触发 | en:Set trigger source as Software // // ch:触发源设为软触发 | en:Set trigger source as Software
item.SetEnumValue("TriggerSource", (uint)MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE); // item.SetEnumValue("TriggerSource", (uint)MV_CAM_TRIGGER_SOURCE.MV_TRIGGER_SOURCE_SOFTWARE);
// ch:取图前的必要操作步骤 | en:Necessary operation before grab // // ch:取图前的必要操作步骤 | en:Necessary operation before grab
CGigECameraInfo cGigEDeviceInfo = (CGigECameraInfo)device; // CGigECameraInfo cGigEDeviceInfo = (CGigECameraInfo)device;
uint nIp1 = ((cGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24); // uint nIp1 = ((cGigEDeviceInfo.nCurrentIp & 0xff000000) >> 24);
uint nIp2 = ((cGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16); // uint nIp2 = ((cGigEDeviceInfo.nCurrentIp & 0x00ff0000) >> 16);
uint nIp3 = ((cGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8); // uint nIp3 = ((cGigEDeviceInfo.nCurrentIp & 0x0000ff00) >> 8);
uint nIp4 = (cGigEDeviceInfo.nCurrentIp & 0x000000ff); // uint nIp4 = (cGigEDeviceInfo.nCurrentIp & 0x000000ff);
string ip = $"{nIp1}.{nIp2}.{nIp3}.{nIp4}"; // string ip = $"{nIp1}.{nIp2}.{nIp3}.{nIp4}";
Console.WriteLine("DevIP:" + ip); // Console.WriteLine("DevIP:" + ip);
RefreshCameraEvent?.Invoke(ip, true); // RefreshCameraEvent?.Invoke(ip, true);
m_MyCameras.Add(ip, item); // m_MyCameras.Add(ip, item);
Console.WriteLine("open success"); // Console.WriteLine("open success");
return true; // return true;
} // }
catch (Exception ex) // catch (Exception ex)
{ // {
Console.WriteLine("open()"+ex.Message); // Console.WriteLine("open()"+ex.Message);
return false; // return false;
} // }
} // }
// ch:取图前的必要操作步骤 | en:Necessary operation before grab // // ch:取图前的必要操作步骤 | en:Necessary operation before grab
private Int32 NecessaryOperBeforeGrab(CCamera m_MyCamera) // private Int32 NecessaryOperBeforeGrab(CCamera m_MyCamera)
{ // {
// ch:取图像宽 | en:Get Iamge Width // // ch:取图像宽 | en:Get Iamge Width
CIntValue pcWidth = new CIntValue(); // CIntValue pcWidth = new CIntValue();
int nRet = m_MyCamera.GetIntValue("Width", ref pcWidth); // int nRet = m_MyCamera.GetIntValue("Width", ref pcWidth);
if (CErrorDefine.MV_OK != nRet) // if (CErrorDefine.MV_OK != nRet)
{ // {
//ShowErrorMsg("Get Width Info Fail!", nRet); // //ShowErrorMsg("Get Width Info Fail!", nRet);
return nRet; // return nRet;
} // }
m_nCurWidth = (UInt32)pcWidth.CurValue; // m_nCurWidth = (UInt32)pcWidth.CurValue;
// ch:取图像高 | en:Get Iamge Height // // ch:取图像高 | en:Get Iamge Height
CIntValue pcHeight = new CIntValue(); // CIntValue pcHeight = new CIntValue();
nRet = m_MyCamera.GetIntValue("Height", ref pcHeight); // nRet = m_MyCamera.GetIntValue("Height", ref pcHeight);
if (CErrorDefine.MV_OK != nRet) // if (CErrorDefine.MV_OK != nRet)
{ // {
// ShowErrorMsg("Get Height Info Fail!", nRet); // // ShowErrorMsg("Get Height Info Fail!", nRet);
return nRet; // return nRet;
} // }
m_nCurHeight = (UInt32)pcHeight.CurValue; // m_nCurHeight = (UInt32)pcHeight.CurValue;
// ch:取像素格式 | en:Get Pixel Format // // ch:取像素格式 | en:Get Pixel Format
CEnumValue pcPixelFormat = new CEnumValue(); // CEnumValue pcPixelFormat = new CEnumValue();
nRet = m_MyCamera.GetEnumValue("PixelFormat", ref pcPixelFormat); // nRet = m_MyCamera.GetEnumValue("PixelFormat", ref pcPixelFormat);
if (CErrorDefine.MV_OK != nRet) // if (CErrorDefine.MV_OK != nRet)
{ // {
// ShowErrorMsg("Get Pixel Format Fail!", nRet); // // ShowErrorMsg("Get Pixel Format Fail!", nRet);
return nRet; // return nRet;
} // }
m_emPixelType = (MvGvspPixelType)pcPixelFormat.CurValue; // m_emPixelType = (MvGvspPixelType)pcPixelFormat.CurValue;
return CErrorDefine.MV_OK; // return CErrorDefine.MV_OK;
} // }
public void StartGrab() // public void StartGrab()
{ // {
m_bGrabbing = true; // m_bGrabbing = true;
foreach (KeyValuePair<string,CCamera> pair in m_MyCameras) // foreach (KeyValuePair<string,CCamera> pair in m_MyCameras)
{ // {
int nRet = NecessaryOperBeforeGrab(pair.Value); // int nRet = NecessaryOperBeforeGrab(pair.Value);
if (CErrorDefine.MV_OK != nRet) // if (CErrorDefine.MV_OK != nRet)
{ // {
// TODO重新销毁打开 // // TODO重新销毁打开
return; // return;
} // }
if (config.Scanner1IP == pair.Key) // if (config.Scanner1IP == pair.Key)
{ // {
m_hReceiveThread1 = new Thread(() => ReceiveThreadProcess(pair.Key,pair.Value)); // m_hReceiveThread1 = new Thread(() => ReceiveThreadProcess(pair.Key,pair.Value));
m_hReceiveThread1.Start(); // m_hReceiveThread1.Start();
// ch:开始采集 | en:Start Grabbing // // ch:开始采集 | en:Start Grabbing
nRet = pair.Value.StartGrabbing(); // nRet = pair.Value.StartGrabbing();
if (CErrorDefine.MV_OK != nRet) // if (CErrorDefine.MV_OK != nRet)
{ // {
m_bGrabbing = false; // m_bGrabbing = false;
m_hReceiveThread1.Join(); // m_hReceiveThread1.Join();
// ShowErrorMsg("Start Grabbing Fail!", nRet); // // ShowErrorMsg("Start Grabbing Fail!", nRet);
return; // return;
} // }
} // }
pair.Value.SetEnumValue("ExposureAuto", 0); // pair.Value.SetEnumValue("ExposureAuto", 0);
nRet = pair.Value.SetFloatValue("ExposureTime", 45000.0f); // nRet = pair.Value.SetFloatValue("ExposureTime", 45000.0f);
if (nRet != CErrorDefine.MV_OK) // if (nRet != CErrorDefine.MV_OK)
{ // {
// ShowErrorMsg("Set Exposure Time Fail!", nRet); // // ShowErrorMsg("Set Exposure Time Fail!", nRet);
} // }
pair.Value.SetEnumValue("GainAuto", 0); // pair.Value.SetEnumValue("GainAuto", 0);
nRet = pair.Value.SetFloatValue("Gain", 10.0f); // nRet = pair.Value.SetFloatValue("Gain", 10.0f);
if (nRet != CErrorDefine.MV_OK) // if (nRet != CErrorDefine.MV_OK)
{ // {
// ShowErrorMsg("Set Gain Fail!", nRet); // // ShowErrorMsg("Set Gain Fail!", nRet);
} // }
nRet = pair.Value.SetFloatValue("AcquisitionFrameRate", 9.4f); // nRet = pair.Value.SetFloatValue("AcquisitionFrameRate", 9.4f);
if (nRet != CErrorDefine.MV_OK) // if (nRet != CErrorDefine.MV_OK)
{ // {
// ShowErrorMsg("Set Frame Rate Fail!", nRet); // // ShowErrorMsg("Set Frame Rate Fail!", nRet);
} // }
// }
// }
}
}
// public void StopGrab()
// {
public void StopGrab()
{ // try
// {
try // m_bGrabbing = false;
{ // if (m_hReceiveThread1 != null && m_hReceiveThread1.IsAlive)
m_bGrabbing = false; // {
if (m_hReceiveThread1 != null && m_hReceiveThread1.IsAlive) // m_hReceiveThread1.Join(); // 等待线程结束
{ // }
m_hReceiveThread1.Join(); // 等待线程结束 // if (m_hReceiveThread2 != null && m_hReceiveThread2.IsAlive)
} // {
if (m_hReceiveThread2 != null && m_hReceiveThread2.IsAlive) // m_hReceiveThread2.Join(); // 等待线程结束
{ // }
m_hReceiveThread2.Join(); // 等待线程结束 // foreach (KeyValuePair<string, CCamera> pair in m_MyCameras)
} // {
foreach (KeyValuePair<string, CCamera> pair in m_MyCameras) // // ch:停止采集 | en:Stop Grabbing
{ // int nRet = pair.Value.StopGrabbing();
// ch:停止采集 | en:Stop Grabbing // if (nRet != CErrorDefine.MV_OK)
int nRet = pair.Value.StopGrabbing(); // {
if (nRet != CErrorDefine.MV_OK) // Console.WriteLine($"相机{pair.Key} Stop Grabbing Fail!", nRet);
{ // }
Console.WriteLine($"相机{pair.Key} Stop Grabbing Fail!", nRet); // // 销毁句柄
} // nRet = pair.Value.CloseDevice();
// 销毁句柄 // if (nRet != CErrorDefine.MV_OK)
nRet = pair.Value.CloseDevice(); // {
if (nRet != CErrorDefine.MV_OK) // Console.WriteLine($"相机{pair.Key} 关闭设备 Fail!", nRet);
{ // }
Console.WriteLine($"相机{pair.Key} 关闭设备 Fail!", nRet); // // 销毁句柄
} // nRet = pair.Value.DestroyHandle();
// 销毁句柄 // if (nRet != CErrorDefine.MV_OK)
nRet = pair.Value.DestroyHandle(); // {
if (nRet != CErrorDefine.MV_OK) // Console.WriteLine($"相机{pair.Key} 销毁句柄 Fail!", nRet);
{ // }
Console.WriteLine($"相机{pair.Key} 销毁句柄 Fail!", nRet); // }
}
} // }
// catch (Exception ex)
} // {
catch (Exception ex) // Console.WriteLine($"stopGarb异常:" + ex.Message);
{ // }
Console.WriteLine($"stopGarb异常:" + ex.Message);
} // }
} // /// <summary>
// /// 箱体码扫码成功以后触发OCR相机拍照解析
/// <summary> // /// </summary>
/// 箱体码扫码成功以后触发OCR相机拍照解析 // /// <returns></returns>
/// </summary> // public bool TriggerGather()
/// <returns></returns> // {
public bool TriggerGather()
{
//采集前确保照片文件夹为空,防止照片比对出错 // //采集前确保照片文件夹为空,防止照片比对出错
DeleteAllPictures(PicturePath); // DeleteAllPictures(PicturePath);
// 两个相机采集照片 // // 两个相机采集照片
foreach (KeyValuePair<string,CCamera> pair in m_MyCameras) // foreach (KeyValuePair<string,CCamera> pair in m_MyCameras)
{ // {
// 采集一次 // // 采集一次
// ch:触发命令 | en:Trigger command // // ch:触发命令 | en:Trigger command
int nRet = pair.Value.SetCommandValue("TriggerSoftware"); // int nRet = pair.Value.SetCommandValue("TriggerSoftware");
if (CErrorDefine.MV_OK != nRet) // if (CErrorDefine.MV_OK != nRet)
{ // {
return false; // return false;
} // }
} // }
return true; // return true;
} // }
/// <summary> // /// <summary>
/// 照片接收线程 // /// 照片接收线程
/// </summary> // /// </summary>
/// <param name="ip"></param> // /// <param name="ip"></param>
/// <param name="m_MyCamera"></param> // /// <param name="m_MyCamera"></param>
public void ReceiveThreadProcess(string ip ,CCamera m_MyCamera) // public void ReceiveThreadProcess(string ip ,CCamera m_MyCamera)
{ // {
int nRet = CErrorDefine.MV_OK; // int nRet = CErrorDefine.MV_OK;
while (m_bGrabbing) // while (m_bGrabbing)
{ // {
if (ip == config.Scanner1IP) // if (ip == config.Scanner1IP)
{ // {
Console.WriteLine($"{DateTime.Now} 线程1等待接收数据 -->"); // Console.WriteLine($"{DateTime.Now} 线程1等待接收数据 -->");
} // }
CFrameout pcFrameInfo = new CFrameout(); // CFrameout pcFrameInfo = new CFrameout();
CDisplayFrameInfo pcDisplayInfo = new CDisplayFrameInfo(); // CDisplayFrameInfo pcDisplayInfo = new CDisplayFrameInfo();
CPixelConvertParam pcConvertParam = new CPixelConvertParam(); // CPixelConvertParam pcConvertParam = new CPixelConvertParam();
nRet = m_MyCamera.GetImageBuffer(ref pcFrameInfo, 1000); // nRet = m_MyCamera.GetImageBuffer(ref pcFrameInfo, 1000);
if (CErrorDefine.MV_OK == nRet) // if (CErrorDefine.MV_OK == nRet)
{ // {
lock (BufForDriverLock) // lock (BufForDriverLock)
{ // {
if (null != m_pcImgForDriver) // if (null != m_pcImgForDriver)
{ // {
m_pcImgForDriver.Destory(); // m_pcImgForDriver.Destory();
m_pcImgForDriver = null; // m_pcImgForDriver = null;
} // }
m_pcImgForDriver = pcFrameInfo.Image.Clone() as CImage; // m_pcImgForDriver = pcFrameInfo.Image.Clone() as CImage;
m_pcImgSpecInfo = pcFrameInfo.FrameSpec; // m_pcImgSpecInfo = pcFrameInfo.FrameSpec;
} // }
pcDisplayInfo.Image = pcFrameInfo.Image; // pcDisplayInfo.Image = pcFrameInfo.Image;
SaveAndChangeJpg(ip,m_MyCamera); // SaveAndChangeJpg(ip,m_MyCamera);
m_MyCamera.FreeImageBuffer(ref pcFrameInfo); // m_MyCamera.FreeImageBuffer(ref pcFrameInfo);
} // }
} // }
} // }
/// <summary> // /// <summary>
/// 保存照片OCR解析删除照片 // /// 保存照片OCR解析删除照片
/// </summary> // /// </summary>
/// <param name="ip"></param> // /// <param name="ip"></param>
/// <param name="m_MyCamera"></param> // /// <param name="m_MyCamera"></param>
private void SaveAndChangeJpg(string ip,CCamera m_MyCamera) // private void SaveAndChangeJpg(string ip,CCamera m_MyCamera)
{ // {
string testPath = PicturePath + "3.jpg"; // string testPath = PicturePath + "3.jpg";
CSaveImgToFileParam stSaveFileParam = new CSaveImgToFileParam(); // CSaveImgToFileParam stSaveFileParam = new CSaveImgToFileParam();
lock (BufForDriverLock) // lock (BufForDriverLock)
{ // {
if (null == m_pcImgForDriver || 0 == m_pcImgForDriver.FrameLen) // if (null == m_pcImgForDriver || 0 == m_pcImgForDriver.FrameLen)
{ // {
return; // return;
} // }
stSaveFileParam.ImageType = MV_SAVE_IAMGE_TYPE.MV_IMAGE_JPEG; // stSaveFileParam.ImageType = MV_SAVE_IAMGE_TYPE.MV_IMAGE_JPEG;
stSaveFileParam.Image = m_pcImgForDriver; // stSaveFileParam.Image = m_pcImgForDriver;
stSaveFileParam.Quality = 80; // stSaveFileParam.Quality = 80;
stSaveFileParam.MethodValue = 2; // stSaveFileParam.MethodValue = 2;
stSaveFileParam.ImagePath = PicturePath + $"photo_{ip}.jpg"; // stSaveFileParam.ImagePath = PicturePath + $"photo_{ip}.jpg";
int nRet = m_MyCamera.SaveImageToFile(ref stSaveFileParam); // int nRet = m_MyCamera.SaveImageToFile(ref stSaveFileParam);
if (CErrorDefine.MV_OK != nRet) // if (CErrorDefine.MV_OK != nRet)
{ // {
Console.WriteLine("保存照片失败"); // Console.WriteLine("保存照片失败");
return; // return;
} // }
} // }
} // }
// 删除指定文件里的照片 // // 删除指定文件里的照片
private void DeletePhoto(string filePath) // private void DeletePhoto(string filePath)
{ // {
try // try
{ // {
// Check if the file exists // // Check if the file exists
if (File.Exists(filePath)) // if (File.Exists(filePath))
{ // {
// Delete the file // // Delete the file
File.Delete(filePath); // File.Delete(filePath);
Console.WriteLine("Photo deleted successfully."); // Console.WriteLine("Photo deleted successfully.");
} // }
else // else
{ // {
Console.WriteLine("File does not exist."); // Console.WriteLine("File does not exist.");
} // }
} // }
catch (Exception ex) // catch (Exception ex)
{ // {
Console.WriteLine("Error deleting photo: " + ex.Message); // Console.WriteLine("Error deleting photo: " + ex.Message);
} // }
} // }
/// <summary> // /// <summary>
/// 删除文件夹所有照片 // /// 删除文件夹所有照片
/// </summary> // /// </summary>
/// <param name="path"></param> // /// <param name="path"></param>
static void DeleteAllPictures(string path) // static void DeleteAllPictures(string path)
{ // {
try // try
{ // {
// 检查照片路径是否存在 // // 检查照片路径是否存在
if (Directory.Exists(path)) // if (Directory.Exists(path))
{ // {
// 获取文件夹中的所有文件 // // 获取文件夹中的所有文件
string[] files = Directory.GetFiles(path); // string[] files = Directory.GetFiles(path);
// 遍历文件并删除 // // 遍历文件并删除
foreach (string file in files) // foreach (string file in files)
{ // {
File.Delete(file); // File.Delete(file);
Console.WriteLine($"Deleted file: {file}"); // Console.WriteLine($"Deleted file: {file}");
} // }
Console.WriteLine("All pictures deleted successfully."); // Console.WriteLine("All pictures deleted successfully.");
} // }
else // else
{ // {
Console.WriteLine("无路径"); // Console.WriteLine("无路径");
} // }
} // }
catch (Exception ex) // catch (Exception ex)
{ // {
Console.WriteLine($"DeleteAllPictures异常: {ex.Message}"); // Console.WriteLine($"DeleteAllPictures异常: {ex.Message}");
} // }
} // }
} // }
} //}

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace SlnMesnac.Common
{
public static class FileHelper
{
/// <summary>
/// 查找指定目录下的文件
/// </summary>
/// <param name="directoryPath"></param>
/// <param name="photoName"></param>
/// <returns></returns>
public static byte[] FindPhoto(string directoryPath)
{
try
{
// 获取目录中的所有文件
string[] files = Directory.GetFiles(directoryPath, "*.jpg");
// 检查是否有文件
if (files.Length == 0)
{
Console.WriteLine("文件夹中没有照片文件");
return null;
}
// 假设这里简单地选择第一个文件作为示例
string firstFile = files[0];
Console.WriteLine($"找到文件:{firstFile}");
// 读取第一个文件的字节数组
byte[] bytes = File.ReadAllBytes(firstFile);
Console.WriteLine($"文件大小:{bytes.Length} 字节");
// 返回照片的字节数组
return bytes;
}
catch (Exception ex)
{
Console.WriteLine($"读取文件夹出错:{ex.Message}");
return null;
}
}
/// <summary>
/// 删除文件夹所有照片
/// </summary>
/// <param name="path"></param>
public static void DeleteAllPictures(string path)
{
try
{
// 检查照片路径是否存在
if (Directory.Exists(path))
{
// 获取文件夹中的所有文件
string[] files = Directory.GetFiles(path);
// 遍历文件并删除
foreach (string file in files)
{
File.Delete(file);
Console.WriteLine($"Deleted file: {file}");
}
Console.WriteLine("All pictures deleted successfully.");
}
else
{
Console.WriteLine("无路径");
}
}
catch (Exception ex)
{
Console.WriteLine($"DeleteAllPictures异常: {ex.Message}");
}
}
public static void SaveImage(byte[] imageData, string imageName, string savePath)
{
// 根据当前日期创建目录路径
string currentDate = DateTime.Now.ToString("yyyy-MM-dd");
string directoryPath = Path.Combine(savePath, currentDate);
// 确保目录存在,如果不存在则创建
Directory.CreateDirectory(directoryPath);
// 将目录路径与照片名称组合
string filePath = Path.Combine(directoryPath, imageName);
try
{
// 将照片字节数组写入文件
File.WriteAllBytes(filePath, imageData);
Console.WriteLine($"图片 '{imageName}' 已成功保存至 '{filePath}'。");
}
catch (Exception ex)
{
Console.WriteLine($"保存图片 '{imageName}' 到 '{filePath}' 时出错: {ex.Message}");
}
}
}
}

@ -5,6 +5,8 @@ using System.Collections.Generic;
using System.IO.Ports; using System.IO.Ports;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SlnMesnac.Common namespace SlnMesnac.Common
{ {
@ -39,7 +41,7 @@ namespace SlnMesnac.Common
//初始化串口并启动接收数据 //初始化串口并启动接收数据
public static void InstanceSerialPort3() public void InstanceSerialPort()
{ {
try try
{ {
@ -49,13 +51,13 @@ namespace SlnMesnac.Common
//端口名 注:因为使用的是USB转RS232 所以去设备管理器中查看一下虚拟com口的名字 //端口名 注:因为使用的是USB转RS232 所以去设备管理器中查看一下虚拟com口的名字
serialPort.PortName = port;// portName; serialPort.PortName = port;// portName;
//波特率 霍尼威尔扫码枪115200,普通9600 //波特率 霍尼威尔扫码枪115200,普通9600
serialPort.BaudRate = 9600; serialPort.BaudRate = 0x2580;
//奇偶校验 //奇偶校验
serialPort.Parity = Parity.None; serialPort.Parity = Parity.None;
//停止位 //停止位
serialPort.StopBits = StopBits.One; serialPort.StopBits = StopBits.One;
//数据位 //数据位
serialPort.DataBits = 8; serialPort.DataBits = 0x8;
//忽略null字节 //忽略null字节
serialPort.DiscardNull = true; serialPort.DiscardNull = true;
@ -64,6 +66,8 @@ namespace SlnMesnac.Common
//开启串口 //开启串口
serialPort.Open(); serialPort.Open();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -71,43 +75,50 @@ namespace SlnMesnac.Common
} }
} }
/// <summary> /// <summary>
/// 接收数据 /// 接收数据
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="e"></param> /// <param name="e"></param>
private static void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e) private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{ {
string result = "";
int bytesToRead = serialPort.BytesToRead;
byte[] buf = new byte[bytesToRead];
serialPort.Read(buf, 0x0, bytesToRead);
int nums = serialPort.BytesToRead; for (int i = 0x0; i < buf.Length; i++)
byte[] receiveBytes = new byte[nums]; {
serialPort.Read(receiveBytes, 0, nums); int num = (int)buf[i];
result =result+num.ToString("X2");
StringBuilder sb = new StringBuilder(); }
Console.WriteLine(result);
string str = Encoding.ASCII.GetString(receiveBytes).Replace("\r\n", "");
// 业务处理
RefreshMaterialCodeStrEvent?.Invoke(str);
sb.Clear();
} }
/// <summary> /// <summary>
/// 发送数据方法 /// 发送数据方法
/// OK-校验成功关闭灯光NG-校验失败闪烁红灯
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
public static void SendData(string data) public void SendData(string data)
{ {
try try
{ {
if (serialPort.IsOpen) if (serialPort.IsOpen)
{ {
// 将需要发送的数据转换成字节数组 byte[] buffer = null;
byte[] sendData = Encoding.ASCII.GetBytes(data); if (data == "NG")
{
// 向串口写入数据 buffer = GetBytesByCommand("OpenRed");
serialPort.Write(sendData, 0, sendData.Length); }
else if (data == "OK")
{
buffer = GetBytesByCommand("CloseRed");
}
serialPort.Write(buffer, 0x0, 0x4);
} }
else else
{ {
@ -118,6 +129,35 @@ namespace SlnMesnac.Common
{ {
Console.WriteLine($"发送数据时发生错误:{ex.Message}"); Console.WriteLine($"发送数据时发生错误:{ex.Message}");
} }
}
/// <summary>
/// 蜂鸣报警灯常用指令
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
private byte[] GetBytesByCommand(string command)
{
byte[] buffer = null;
switch (command)
{
// 打开红灯+蜂鸣
case "OpenRed": buffer = new byte[] { 0xA0, 0x00, 0x02, 0xA2 }; break;
// 关闭红灯+蜂鸣
case "CloseRed": buffer = new byte[] { 0xA0, 0x00, 0x00, 0xA0 }; break;
////闪烁红灯+蜂鸣
//case "FlashRed": buffer = new byte[] { 0xA0, 0x07, 0x02, 0xA9 }; break;
//// 打开绿灯
//case "OpenGreen": buffer = new byte[] { 0xA0, 0x00, 0x01, 0xA1 }; break;
//// 关闭绿灯
//case "CloseGreen": buffer = new byte[] { 0xA0, 0x00, 0x00, 0xA0 }; break;
//// 闪烁绿灯
//case "FlashGreen": buffer = new byte[] { 0xA0, 0x00, 0x02, 0xA2 }; break;
default:return null;
}
return buffer;
} }
} }

@ -26,16 +26,32 @@ namespace SlnMesnac.Config
} }
/// <summary>
/// 海康扫码器--IP
/// </summary>
public string ScannerIP
{
get { return iniHelper.IniReadValue("system", "ScannerIP"); }
set { iniHelper.IniWriteValue("system", "ScannerIP", value); }
}
/// <summary> /// <summary>
/// 海康相机--IP /// 海康相机--IP
/// </summary> /// </summary>
public string Scanner1IP public string CameraIP
{ {
get { return iniHelper.IniReadValue("system", "Scanner1IP"); } get { return iniHelper.IniReadValue("system", "CameraIP"); }
set { iniHelper.IniWriteValue("system", "Scanner1IP", value); } set { iniHelper.IniWriteValue("system", "CameraIP", value); }
} }
/// <summary>
/// 海康相机拍照存放路径
/// </summary>
public string CameraFilePath
{
get { return iniHelper.IniReadValue("system", "CameraFilePath"); }
set { iniHelper.IniWriteValue("system", "CameraFilePath", value); }
}
} }
} }

@ -20,6 +20,11 @@ namespace SlnMesnac.Repository.service
/// <returns></returns> /// <returns></returns>
List<ProductModel> GetMesAllRecord(); List<ProductModel> GetMesAllRecord();
/// <summary>
/// 根据成品条码从MES查询型号
/// </summary>
/// <returns></returns>
ProductModel GetMaterialTypeByBarCode(string barCode);
/// <summary> /// <summary>
/// 从本地查询所有型号用来展示 /// 从本地查询所有型号用来展示

@ -63,6 +63,28 @@ FROM
return list; return list;
} }
/// <summary>
/// 根据成品条码从MES查询型号
/// </summary>
/// <returns></returns>
public ProductModel GetMaterialTypeByBarCode(string barCode)
{
ProductModel model = null;
try
{
string sql = $"SELECT a.BAR_CODE, b.ORDER_NO, b.MATERIAL_CODE,b.MATERIAL_NAME,b.ORDER_QTY FROM IMOS_TM_PRINT_INFO a LEFT JOIN IMOS_PR_ORDER b ON a.ORDER_NUMBER = lpad( b.ORDER_NO, '12', '0' ) WHERE a.BAR_CODE = '{barCode}'";
// 查询MES所有型号
model = _rep.Context.SqlQueryable<ProductModel>(sql).First();
}
catch (Exception ex)
{
_logger.LogError($"从MES查询数据库所有型号失败:{ex.Message}");
}
return model;
}
/// <summary> /// <summary>
/// 模糊查询,从本地查询某个型号 /// 模糊查询,从本地查询某个型号
/// </summary> /// </summary>

@ -1,6 +1,8 @@
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using SlnMesnac.Config;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using TouchSocket.Core; using TouchSocket.Core;
using TouchSocket.Sockets; using TouchSocket.Sockets;
@ -9,6 +11,7 @@ namespace SlnMesnac.TouchSocket
{ {
public class TcpServer public class TcpServer
{ {
private DebugConfig config = DebugConfig.Instance;
private ILogger<TcpServer> _logger; private ILogger<TcpServer> _logger;
private readonly TcpService _service; private readonly TcpService _service;
#region 委托事件 #region 委托事件
@ -28,6 +31,9 @@ namespace SlnMesnac.TouchSocket
public delegate void RefreshMaterialCodeStr(string materialCodeStr, string ip); public delegate void RefreshMaterialCodeStr(string materialCodeStr, string ip);
public static event RefreshMaterialCodeStr RefreshMaterialCodeStrEvent; public static event RefreshMaterialCodeStr RefreshMaterialCodeStrEvent;
//相机拍照识别结果事件
public delegate void CameraResult(string result);
public static event CameraResult CameraResultEvent;
#endregion #endregion
@ -72,13 +78,23 @@ namespace SlnMesnac.TouchSocket
} }
else if (mes == "NoRead") else if (mes == "NoRead")
{ {
client.Logger.Info($"入库扫码器{client.IP}:{client.Port}》NoRead事件{mes}"); client.Logger.Info($"客户端{client.IP}:{client.Port}》NoRead事件{mes}");
// TODO
} }
else else
{ {
client.Logger.Info($"入库扫码器{client.IP}:{client.Port}》接收到信息:{mes}"); client.Logger.Info($"客户端{client.IP}:{client.Port}》接收到信息:{mes}");
RefreshMaterialCodeStrEvent?.Invoke(mes.Trim().TrimEnd('\0'), client.IP); // 区分相机扫码器数据
if (client.IP == config.ScannerIP)
{
RefreshMaterialCodeStrEvent?.Invoke(mes.Trim().TrimEnd('\0'), client.IP);
}
else if (client.IP == config.CameraIP)
{
// 相机返回数据
CameraResultEvent?.Invoke(mes.Trim().TrimEnd('\0'));
}
} }
} }
@ -113,13 +129,28 @@ namespace SlnMesnac.TouchSocket
/// <summary> /// <summary>
/// 向所有客户端发送心跳 /// 向所有客户端发送心跳
/// </summary> /// </summary>
public void SendHeartBeat() //public void SendHeartBeat()
//{
// var clients = _service.SocketClients.GetClients();
// foreach (var item in clients)
// {
// _service.Send(item.Id, "heartbeat");
// }
//}
/// <summary>
/// 向指定相机发送指令
/// </summary>
public void SendCommand(string ip, string command)
{ {
var clients = _service.SocketClients.GetClients(); ISocketClient client = _service.SocketClients.GetClients().FirstOrDefault(x => x.IP ==ip);
foreach (var item in clients) if (client != null)
{ {
_service.Send(item.Id,"heartbeat"); _service.Send(client.Id, command);
} }
} }
} }
} }

@ -21,7 +21,7 @@ namespace SlnMesnac.TouchSocket
public static IApplicationBuilder UseTouchSocketExtensions(this IApplicationBuilder app) public static IApplicationBuilder UseTouchSocketExtensions(this IApplicationBuilder app)
{ {
var _server = app.ApplicationServices.GetService<TcpServer>(); var _server = app.ApplicationServices.GetService<TcpServer>();
_server.Init(5000); _server.Init(7024);
return app; return app;
} }
} }

@ -1,8 +1,10 @@
using GalaSoft.MvvmLight; using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Win32; using Microsoft.Win32;
using SlnMesnac.Business; using SlnMesnac.Business;
using SlnMesnac.Common;
using SlnMesnac.Model.domain; using SlnMesnac.Model.domain;
using SlnMesnac.Repository.service; using SlnMesnac.Repository.service;
using SqlSugar; using SqlSugar;
@ -22,16 +24,31 @@ namespace SlnMesnac.WPF.ViewModel
public partial class IndexViewModel: ObservableObject public partial class IndexViewModel: ObservableObject
{ {
private ILogoIdentifyService logoIdentifyService; private ILogoIdentifyService logoIdentifyService;
private GunHelper gunHelper = GunHelper.Instance;
public RelayCommand ResetCommand { get; set;}
public IndexViewModel() public IndexViewModel()
{ {
logoIdentifyService = App.ServiceProvider.GetService<ILogoIdentifyService>(); logoIdentifyService = App.ServiceProvider.GetService<ILogoIdentifyService>();
LogoBusiness.RefreshMessageEvent += RefreshMessage; LogoBusiness.RefreshMessageEvent += RefreshMessage;
LogoBusiness.RefreshBoxInfoEvent += RefreshBoxInfo; LogoBusiness.RefreshBoxInfoEvent += RefreshBoxInfo;
ResetCommand = new RelayCommand(Reset);
RefreshDataGrid(); RefreshDataGrid();
} }
/// <summary>
/// 复位方法
/// 复位PLC放行复位报警灯
/// </summary>
/// <exception cref="NotImplementedException"></exception>
private void Reset()
{
// TODO 复位PLC放行
// 复位报警灯
gunHelper.SendData("OK");
}
/// <summary> /// <summary>
/// 测试方法 /// 测试方法
/// </summary> /// </summary>
@ -99,6 +116,7 @@ namespace SlnMesnac.WPF.ViewModel
ImageData = imageData; ImageData = imageData;
RefreshResultColor(isSuccess); RefreshResultColor(isSuccess);
RefreshDataGrid(); RefreshDataGrid();
} }
/// <summary> /// <summary>
/// 刷新界面提示信息 /// 刷新界面提示信息
@ -115,7 +133,7 @@ namespace SlnMesnac.WPF.ViewModel
{ {
MsgColor = System.Windows.Media.Brushes.White; MsgColor = System.Windows.Media.Brushes.White;
} }
Message = $"{DateTime.Now} :{message}"; Message = $"{DateTime.Now.ToString("HH:mm:ss")}:{message}";
} }
#endregion #endregion

@ -39,8 +39,11 @@ namespace SlnMesnac.WPF.ViewModel
public class MainWindowViewModel : ViewModelBase public class MainWindowViewModel : ViewModelBase
{ {
private readonly ILogger<MainWindowViewModel> _logger; private readonly ILogger<MainWindowViewModel> _logger;
private readonly ILogger<LogoBusiness> _logger2;
private IBaseMaterialService? baseMaterialService; private IBaseMaterialService? baseMaterialService;
private ILogoIdentifyService? ocrVerfiyService; private ILogoIdentifyService? ocrVerfiyService;
private ILogoConfigService? logoConfigService;
private TcpServer? tcpServer;
private PlcPool plcPool = null; private PlcPool plcPool = null;
private IndexPage indexPage = new IndexPage(); private IndexPage indexPage = new IndexPage();
private StatisticsPageView statisticsPageView = new StatisticsPageView(); private StatisticsPageView statisticsPageView = new StatisticsPageView();
@ -55,15 +58,18 @@ namespace SlnMesnac.WPF.ViewModel
UserContent = indexPage; UserContent = indexPage;
baseMaterialService = App.ServiceProvider.GetService<IBaseMaterialService>(); baseMaterialService = App.ServiceProvider.GetService<IBaseMaterialService>();
ocrVerfiyService = App.ServiceProvider.GetService<ILogoIdentifyService>(); ocrVerfiyService = App.ServiceProvider.GetService<ILogoIdentifyService>();
logoConfigService = App.ServiceProvider.GetService<ILogoConfigService>();
plcPool = App.ServiceProvider.GetService<PlcPool>(); plcPool = App.ServiceProvider.GetService<PlcPool>();
tcpServer = App.ServiceProvider.GetService<TcpServer>();
_logger = App.ServiceProvider.GetService<ILogger<MainWindowViewModel>>(); _logger = App.ServiceProvider.GetService<ILogger<MainWindowViewModel>>();
LogoBusiness.GetInstance(baseMaterialService, ocrVerfiyService, plcPool); _logger2 = App.ServiceProvider.GetService<ILogger<LogoBusiness>>();
LogoBusiness.GetInstance(_logger2, logoConfigService,baseMaterialService, ocrVerfiyService, plcPool, tcpServer);
ControlOnClickCommand = new RelayCommand<object>(obj => ControlOnClick(obj)); ControlOnClickCommand = new RelayCommand<object>(obj => ControlOnClick(obj));
FormControlCommand = new RelayCommand<object>(x => FormControl(x)); FormControlCommand = new RelayCommand<object>(x => FormControl(x));
TcpServer.RefreshStateEvent += RefreshScanner; TcpServer.RefreshStateEvent += RefreshScanner;
CCameraHik.RefreshCameraEvent += RefreshCamare;
hikHelper.DeviceListAndStart();
//PLC状态刷新 //PLC状态刷新
StartState(); StartState();
RefreshTime(); RefreshTime();
@ -159,7 +165,7 @@ namespace SlnMesnac.WPF.ViewModel
#endregion #endregion
private CCameraHik hikHelper = CCameraHik.Instance;
@ -195,31 +201,18 @@ namespace SlnMesnac.WPF.ViewModel
/// <param name="flag"></param> /// <param name="flag"></param>
public void RefreshScanner(string ip, bool flag) public void RefreshScanner(string ip, bool flag)
{ {
if (flag) if (config.CameraIP == ip)
{
ScannerStatus = 1;
}
else
{
ScannerStatus = 2;
}
}
/// <summary>
/// 相机状态刷新
/// </summary>
/// <param name="ip"></param>
/// <param name="flag"></param>
public void RefreshCamare(string ip,bool flag)
{
if (config.Scanner1IP==ip)
{ {
EnergyCameraStatus = flag ? 1 : 2; EnergyCameraStatus = flag ? 1 : 2;
}else if(config.ScannerIP == ip)
{
ScannerStatus = flag ? 1 : 2;
} }
} }
/// <summary> /// <summary>
/// 窗体控制 /// 窗体控制
/// </summary> /// </summary>
@ -234,7 +227,7 @@ namespace SlnMesnac.WPF.ViewModel
// 关闭当前窗口 // 关闭当前窗口
case "Exit": case "Exit":
{ {
hikHelper.StopGrab();
Environment.Exit(0); Environment.Exit(0);
} }

@ -11,7 +11,7 @@
<UserControl.Resources> <UserControl.Resources>
<converters:IsCheckedConverter x:Key="IsCheckedConverter"/> <converters:IsCheckedConverter x:Key="IsCheckedConverter"/>
<converters:IsSuccessConverter x:Key="IsSuccessConverter"/> <converters:IsSuccessConverter x:Key="IsSuccessConverter"/>
<converters:ByteArrayToImageConverter x:Key="ByteArrayToImageConverter"/> <converters:ByteArrayToImageConverter x:Key="ByteArrayToImageConverter"/>
<Style x:Key="DataGridTextColumnCenterSytle" TargetType="{x:Type TextBlock}"> <Style x:Key="DataGridTextColumnCenterSytle" TargetType="{x:Type TextBlock}">
<Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="VerticalAlignment" Value="Center" />
@ -119,18 +119,19 @@
<StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center" > <StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center" >
<TextBlock Text="产品型号" FontSize="18" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0 0 30 0"/> <TextBlock Text="产品型号" FontSize="18" Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0 0 30 0"/>
<TextBox FontSize="18" Text="{Binding ProductModel,Mode=TwoWay}" BorderBrush="White" Foreground="White" Width="250" IsReadOnly="True" Margin="0 0 0 0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" /> <TextBox FontSize="18" Text="{Binding ProductModel,Mode=TwoWay}" BorderBrush="White" Foreground="White" Width="250" IsReadOnly="True" Margin="0 0 0 0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" />
<Button Content="复 位" Command="{Binding ResetCommand}"
Style="{StaticResource MaterialDesignRaisedSecondaryDarkButton}" Background="#FF1CC57B" Width="130" Height="50" Margin="50 0 0 0"/>
</StackPanel> </StackPanel>
<StackPanel Grid.Row="2" Grid.RowSpan="2" Orientation="Horizontal" VerticalAlignment="Center" > <StackPanel Grid.Row="2" Grid.RowSpan="2" >
<TextBlock Text="提示信息" FontSize="18" Foreground="White"/> <TextBlock Text="提示信息" FontSize="20" Foreground="White"/>
<TextBox FontSize="15" BorderBrush="White" <TextBox FontSize="15" BorderBrush="White"
MinHeight="70" MaxHeight="100" MinWidth="460" IsReadOnly="True" Foreground="{Binding MsgColor}" MinHeight="70" IsReadOnly="True" Foreground="{Binding MsgColor}" Margin="30 0 0 0"
VerticalAlignment="Top" Margin="30 0 0 0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
AcceptsReturn="True" Text="{Binding Message,Mode=TwoWay}" AcceptsReturn="True" Text="{Binding Message,Mode=TwoWay}"
Style="{StaticResource MaterialDesignOutlinedTextBox}" Style="{StaticResource MaterialDesignOutlinedTextBox}"
TextWrapping="Wrap" TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" /> VerticalScrollBarVisibility="Auto" Height="100" Width="600" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</Border> </Border>
@ -154,17 +155,16 @@
<TextBlock Text="识别结果:" FontSize="20" FontWeight="Bold" Foreground="White" VerticalAlignment="Center" /> <TextBlock Text="识别结果:" FontSize="20" FontWeight="Bold" Foreground="White" VerticalAlignment="Center" />
<TextBlock Text="{Binding ResultTxt,Mode=TwoWay}" FontSize="20" FontWeight="Bold" Foreground="{Binding ResultColor}" VerticalAlignment="Center" Margin="0 0 40 0" /> <TextBlock Text="{Binding ResultTxt,Mode=TwoWay}" FontSize="20" FontWeight="Bold" Foreground="{Binding ResultColor}" VerticalAlignment="Center" Margin="0 0 40 0" />
</StackPanel> </StackPanel>
</Grid> </Grid>
</Border> </Border>
<Border x:Name="HeightHelperPanel" Grid.Row="1" BorderBrush="#0288d1" BorderThickness="1" CornerRadius="10" Background="Transparent" Margin="5,1,5,5"> <Border HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="HeightHelperPanel" Grid.Row="1" BorderBrush="#0288d1" BorderThickness="1" CornerRadius="10" Background="Transparent" Margin="5,1,5,5">
<StackPanel > <StackPanel>
<Image Source="{Binding ImageData, Converter={StaticResource ByteArrayToImageConverter}}" Height="{Binding ElementName=HeightHelperPanel, Path=ActualHeight}" Width="{Binding ElementName=HeightHelperPanel, Path=ActualWidth}"/> <Image Source="{Binding ImageData, Converter={StaticResource ByteArrayToImageConverter}}" Height="{Binding ElementName=HeightHelperPanel, Path=ActualHeight}" Width="{Binding ElementName=HeightHelperPanel, Path=ActualWidth}"/>
</StackPanel > </StackPanel >
</Border> </Border>
</Grid> </Grid>
</Border> </Border>
@ -188,7 +188,7 @@
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<DataGrid Grid.Row="0" ItemsSource="{Binding LogoIdentifyDataGrid}" Background="#00000000" <DataGrid Grid.Row="0" ItemsSource="{Binding LogoIdentifyDataGrid}" Background="#00000000"
ColumnHeaderHeight="35" Height="{Binding Path=ActualHeight, ElementName=ScanPanel}" ColumnHeaderHeight="35" Height="{Binding Path=ActualHeight, ElementName=ScanPanel}"
RowHeight="50" AutoGenerateColumns="False" RowHeaderWidth="0" FontSize="20" RowHeight="50" AutoGenerateColumns="False" RowHeaderWidth="0" FontSize="20"
GridLinesVisibility="None" ScrollViewer.HorizontalScrollBarVisibility="Auto" LoadingRow="dgvMH_LoadingRow" GridLinesVisibility="None" ScrollViewer.HorizontalScrollBarVisibility="Auto" LoadingRow="dgvMH_LoadingRow"

@ -7,6 +7,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Documents; using System.Windows.Documents;
using System.Windows.Input; using System.Windows.Input;
@ -33,5 +34,7 @@ namespace SlnMesnac.WPF.Views
{ {
e.Row.Header = (e.Row.GetIndex() + 1).ToString(); e.Row.Header = (e.Row.GetIndex() + 1).ToString();
} }
} }
} }

@ -24,7 +24,7 @@
"PlcConfig": [ "PlcConfig": [
{ {
"configId": 1, "configId": 1,
"plcType": "MelsecBinaryPlc", "plcType": "SiemensPlc",
"plcIp": "127.0.0.1", "plcIp": "127.0.0.1",
"plcPort": 6000, "plcPort": 6000,
"plcKey": "plc", "plcKey": "plc",

Loading…
Cancel
Save