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

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

@ -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.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SlnMesnac.Common
{
@ -39,7 +41,7 @@ namespace SlnMesnac.Common
//初始化串口并启动接收数据
public static void InstanceSerialPort3()
public void InstanceSerialPort()
{
try
{
@ -49,13 +51,13 @@ namespace SlnMesnac.Common
//端口名 注:因为使用的是USB转RS232 所以去设备管理器中查看一下虚拟com口的名字
serialPort.PortName = port;// portName;
//波特率 霍尼威尔扫码枪115200,普通9600
serialPort.BaudRate = 9600;
serialPort.BaudRate = 0x2580;
//奇偶校验
serialPort.Parity = Parity.None;
//停止位
serialPort.StopBits = StopBits.One;
//数据位
serialPort.DataBits = 8;
serialPort.DataBits = 0x8;
//忽略null字节
serialPort.DiscardNull = true;
@ -64,6 +66,8 @@ namespace SlnMesnac.Common
//开启串口
serialPort.Open();
}
catch (Exception ex)
{
@ -72,42 +76,49 @@ namespace SlnMesnac.Common
}
/// <summary>
/// 接收数据
/// </summary>
/// <param name="sender"></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)
{
int nums = serialPort.BytesToRead;
byte[] receiveBytes = new byte[nums];
serialPort.Read(receiveBytes, 0, nums);
StringBuilder sb = new StringBuilder();
string str = Encoding.ASCII.GetString(receiveBytes).Replace("\r\n", "");
// 业务处理
RefreshMaterialCodeStrEvent?.Invoke(str);
string result = "";
int bytesToRead = serialPort.BytesToRead;
byte[] buf = new byte[bytesToRead];
serialPort.Read(buf, 0x0, bytesToRead);
sb.Clear();
for (int i = 0x0; i < buf.Length; i++)
{
int num = (int)buf[i];
result =result+num.ToString("X2");
}
Console.WriteLine(result);
}
/// <summary>
/// 发送数据方法
/// OK-校验成功关闭灯光NG-校验失败闪烁红灯
/// </summary>
/// <param name="data"></param>
public static void SendData(string data)
public void SendData(string data)
{
try
{
if (serialPort.IsOpen)
{
// 将需要发送的数据转换成字节数组
byte[] sendData = Encoding.ASCII.GetBytes(data);
// 向串口写入数据
serialPort.Write(sendData, 0, sendData.Length);
byte[] buffer = null;
if (data == "NG")
{
buffer = GetBytesByCommand("OpenRed");
}
else if (data == "OK")
{
buffer = GetBytesByCommand("CloseRed");
}
serialPort.Write(buffer, 0x0, 0x4);
}
else
{
@ -118,6 +129,35 @@ namespace SlnMesnac.Common
{
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;
}
}

@ -27,15 +27,31 @@ namespace SlnMesnac.Config
}
/// <summary>
/// 海康相机--IP
/// 海康扫码器--IP
/// </summary>
public string Scanner1IP
public string ScannerIP
{
get { return iniHelper.IniReadValue("system", "Scanner1IP"); }
set { iniHelper.IniWriteValue("system", "Scanner1IP", value); }
get { return iniHelper.IniReadValue("system", "ScannerIP"); }
set { iniHelper.IniWriteValue("system", "ScannerIP", value); }
}
/// <summary>
/// 海康相机--IP
/// </summary>
public string CameraIP
{
get { return iniHelper.IniReadValue("system", "CameraIP"); }
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>
List<ProductModel> GetMesAllRecord();
/// <summary>
/// 根据成品条码从MES查询型号
/// </summary>
/// <returns></returns>
ProductModel GetMaterialTypeByBarCode(string barCode);
/// <summary>
/// 从本地查询所有型号用来展示

@ -63,6 +63,28 @@ FROM
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>

@ -1,6 +1,8 @@
using Microsoft.Extensions.Logging;
using SlnMesnac.Config;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TouchSocket.Core;
using TouchSocket.Sockets;
@ -9,6 +11,7 @@ namespace SlnMesnac.TouchSocket
{
public class TcpServer
{
private DebugConfig config = DebugConfig.Instance;
private ILogger<TcpServer> _logger;
private readonly TcpService _service;
#region 委托事件
@ -28,6 +31,9 @@ namespace SlnMesnac.TouchSocket
public delegate void RefreshMaterialCodeStr(string materialCodeStr, string ip);
public static event RefreshMaterialCodeStr RefreshMaterialCodeStrEvent;
//相机拍照识别结果事件
public delegate void CameraResult(string result);
public static event CameraResult CameraResultEvent;
#endregion
@ -72,13 +78,23 @@ namespace SlnMesnac.TouchSocket
}
else if (mes == "NoRead")
{
client.Logger.Info($"入库扫码器{client.IP}:{client.Port}》NoRead事件{mes}");
client.Logger.Info($"客户端{client.IP}:{client.Port}》NoRead事件{mes}");
// TODO
}
else
{
client.Logger.Info($"入库扫码器{client.IP}:{client.Port}》接收到信息:{mes}");
RefreshMaterialCodeStrEvent?.Invoke(mes.Trim().TrimEnd('\0'), client.IP);
client.Logger.Info($"客户端{client.IP}:{client.Port}》接收到信息:{mes}");
// 区分相机扫码器数据
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>
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();
foreach (var item in clients)
ISocketClient client = _service.SocketClients.GetClients().FirstOrDefault(x => x.IP ==ip);
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)
{
var _server = app.ApplicationServices.GetService<TcpServer>();
_server.Init(5000);
_server.Init(7024);
return app;
}
}

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

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

@ -119,18 +119,19 @@
<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"/>
<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 Grid.Row="2" Grid.RowSpan="2" Orientation="Horizontal" VerticalAlignment="Center" >
<TextBlock Text="提示信息" FontSize="18" Foreground="White"/>
<StackPanel Grid.Row="2" Grid.RowSpan="2" >
<TextBlock Text="提示信息" FontSize="20" Foreground="White"/>
<TextBox FontSize="15" BorderBrush="White"
MinHeight="70" MaxHeight="100" MinWidth="460" IsReadOnly="True" Foreground="{Binding MsgColor}"
VerticalAlignment="Top" Margin="30 0 0 0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
MinHeight="70" IsReadOnly="True" Foreground="{Binding MsgColor}" Margin="30 0 0 0"
AcceptsReturn="True" Text="{Binding Message,Mode=TwoWay}"
Style="{StaticResource MaterialDesignOutlinedTextBox}"
TextWrapping="Wrap"
VerticalScrollBarVisibility="Auto" />
VerticalScrollBarVisibility="Auto" Height="100" Width="600" />
</StackPanel>
</Grid>
</Border>
@ -158,13 +159,12 @@
</Grid>
</Border>
<Border x:Name="HeightHelperPanel" Grid.Row="1" BorderBrush="#0288d1" BorderThickness="1" CornerRadius="10" Background="Transparent" Margin="5,1,5,5">
<StackPanel >
<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>
<Image Source="{Binding ImageData, Converter={StaticResource ByteArrayToImageConverter}}" Height="{Binding ElementName=HeightHelperPanel, Path=ActualHeight}" Width="{Binding ElementName=HeightHelperPanel, Path=ActualWidth}"/>
</StackPanel >
</Border>
</Grid>
</Border>
@ -188,7 +188,7 @@
<RowDefinition Height="*"/>
</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}"
RowHeight="50" AutoGenerateColumns="False" RowHeaderWidth="0" FontSize="20"
GridLinesVisibility="None" ScrollViewer.HorizontalScrollBarVisibility="Auto" LoadingRow="dgvMH_LoadingRow"

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

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

Loading…
Cancel
Save