合并修改

This commit is contained in:
2025-04-30 16:13:13 +08:00
294 changed files with 60700 additions and 6623 deletions

View File

@ -0,0 +1,399 @@
using System;
using System.ComponentModel;
using System.Drawing.Imaging;
using AntdUI;
using DH.Commons.Enums;
using DVPCameraType;
using HalconDotNet;
using OpenCvSharp;
namespace DH.Commons.Base
{
public class MatSet
{
public DateTime ImageTime { get; set; } = DateTime.Now;
private string id = "";
public string Id
{
get
{
if (string.IsNullOrWhiteSpace(id))
{
id = ImageTime.ToString("HHmmssfff");
}
return id;
}
set
{
id = value;
}
}
public string CameraId { get; set; }
public Mat _mat { get; set; } = null;
public ImageFormat _imageFormat { get; set; } = ImageFormat.Jpeg;
public virtual void Dispose()
{
_mat?.Dispose();
_mat = null;
}
}
public class CameraBase : NotifyProperty
{
// public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
// 私有字段 + 带通知的属性与DetectionLabel风格一致
private bool _isEnabled = false;
private bool _isallPicEnabled = true;//默认全画幅
private bool _isRGBEnabled = true;//默认彩色
private bool _isContinueMode = false;
private bool _isSavePicEnabled = false;
private bool _isZoomCamera = false;
private string _imageSaveDirectory;
private EnumCamType _CamType;
private dvpStreamFormat _dvpstreamFormat = dvpStreamFormat.S_RGB24;
private ImageFormat _imageFormat = ImageFormat.Jpeg;
private bool _isHardwareTrigger = true;
private string _serialNumber = string.Empty;
private string _cameraName = string.Empty;
private string _cameraIP = string.Empty;
private string _computerIP = string.Empty;
private bool _isDirectHardwareTrigger = false;
private float _gain =6;
private int _rotateImage = 0;
private float _exposure = 200;
private float _triggerDelay = 0;
private decimal _roiX = 0;
private decimal _roiY = 0;
private decimal _roiW = 2448;
private decimal _roiH = 2048;
private int _lineDebouncerTime = 0;
public volatile int SnapshotCount = 0;
[Category("相机设置")]
[DisplayName("图像格式")]
[Description("相机采集图像格式")]
public dvpStreamFormat DvpImageFormat
{
get => _dvpstreamFormat;
set
{
if (_dvpstreamFormat == value) return;
_dvpstreamFormat = value;
OnPropertyChanged(nameof(DvpImageFormat));
}
}
[Category("采图模式")]
[DisplayName("连续模式")]
[Description("是否连续模式。true连续模式采图false触发模式采图")]
public bool IsContinueMode
{
get => _isContinueMode;
set
{
if (_isContinueMode == value) return;
_isContinueMode = value;
OnPropertyChanged(nameof(IsContinueMode));
}
}
public bool IsZoomCamera
{
get => _isZoomCamera;
set
{
if (_isZoomCamera == value) return;
_isZoomCamera = value;
OnPropertyChanged(nameof(IsZoomCamera));
}
}
public virtual bool IsEnabled
{
get => _isEnabled;
set
{
if (_isEnabled == value) return;
_isEnabled = value;
OnPropertyChanged(nameof(IsEnabled));
}
}
public virtual bool IsAllPicEnabled
{
get => _isallPicEnabled;
set
{
if (_isallPicEnabled == value) return;
_isallPicEnabled = value;
OnPropertyChanged(nameof(IsAllPicEnabled));
}
}
public virtual bool IsSavePicEnabled
{
get => _isSavePicEnabled;
set
{
if (_isSavePicEnabled == value) return;
_isSavePicEnabled = value;
OnPropertyChanged(nameof(IsSavePicEnabled));
}
}
[Category("图片保存")]
[DisplayName("图片保存文件夹")]
[Description("图片保存文件夹")]
public virtual string ImageSaveDirectory
{
get => _imageSaveDirectory;
set
{
if (_imageSaveDirectory == value) return;
_imageSaveDirectory = value;
OnPropertyChanged(nameof(ImageSaveDirectory));
}
}
[Category("图片保存")]
[DisplayName("图片保存格式")]
[Description("图片保存格式")]
public ImageFormat ImageFormat
{
get => _imageFormat;
set
{
if (_imageFormat == value) return;
_imageFormat = value;
OnPropertyChanged(nameof(ImageFormat));
}
}
[Category("设备配置")]
[DisplayName("相机类型")]
[Description("相机类型")]
public EnumCamType CamType
{
get => _CamType;
set
{
if (_CamType == value) return;
_CamType = value;
OnPropertyChanged(nameof(CamType));
}
}
[Category("采图模式")]
[DisplayName("硬触发")]
[Description("是否硬触发模式。true硬触发false软触发")]
public bool IsHardwareTrigger
{
get => _isHardwareTrigger;
set
{
if (_isHardwareTrigger == value) return;
_isHardwareTrigger = value;
OnPropertyChanged(nameof(IsHardwareTrigger));
}
}
public string SerialNumber
{
get => _serialNumber;
set
{
if (_serialNumber == value) return;
_serialNumber = value;
OnPropertyChanged(nameof(SerialNumber));
}
}
public string CameraName
{
get => _cameraName;
set
{
if (_cameraName == value) return;
_cameraName = value;
OnPropertyChanged(nameof(CameraName));
}
}
public string CameraIP
{
get => _cameraIP;
set
{
if (_cameraIP == value) return;
_cameraIP = value;
OnPropertyChanged(nameof(CameraIP));
}
}
public string ComputerIP
{
get => _computerIP;
set
{
if (_computerIP == value) return;
_computerIP = value;
OnPropertyChanged(nameof(ComputerIP));
}
}
[Category("采图模式")]
[DisplayName("是否传感器直接硬触发")]
[Description("是否传感器直接硬触发。true传感器硬触发不通过软件触发false通过软件触发IO 的硬触发模式")]
public bool IsDirectHardwareTrigger
{
get => _isDirectHardwareTrigger;
set
{
if (_isDirectHardwareTrigger == value) return;
_isDirectHardwareTrigger = value;
OnPropertyChanged(nameof(IsDirectHardwareTrigger));
}
}
[Category("相机设置")]
[DisplayName("增益")]
[Description("Gain增益,-1:不设置不同型号相机的增益请参考mvs")]
public float Gain
{
get => _gain;
set
{
if (_gain.Equals(value)) return;
_gain = value;
OnPropertyChanged(nameof(Gain));
}
}
[Category("图像旋转")]
[DisplayName("默认旋转")]
[Description("默认旋转,相机开启后默认不旋转")]
public virtual int RotateImage
{
get => _rotateImage;
set
{
if (_rotateImage.Equals(value)) return;
_rotateImage = value;
OnPropertyChanged(nameof(RotateImage));
}
}
[Category("取像配置")]
[DisplayName("曝光")]
[Description("曝光")]
public virtual float Exposure
{
get => _exposure;
set
{
if (_exposure.Equals(value)) return;
_exposure = value;
OnPropertyChanged(nameof(Exposure));
}
}
[Category("相机设置")]
[DisplayName("硬触发后的延迟")]
[Description("TriggerDelay:硬触发后的延迟,单位us 微秒")]
public float TriggerDelay
{
get => _triggerDelay;
set
{
if (_triggerDelay.Equals(value)) return;
_triggerDelay = value;
OnPropertyChanged(nameof(TriggerDelay));
}
}
public decimal ROIX
{
get => _roiX;
set
{
if (_roiX == value) return;
_roiX = value;
OnPropertyChanged(nameof(ROIX));
}
}
public decimal ROIY
{
get => _roiY;
set
{
if (_roiY == value) return;
_roiY = value;
OnPropertyChanged(nameof(ROIY));
}
}
public decimal ROIW
{
get => _roiW;
set
{
if (_roiW == value) return;
_roiW = value;
OnPropertyChanged(nameof(ROIW));
}
}
public decimal ROIH
{
get => _roiH;
set
{
if (_roiH == value) return;
_roiH = value;
OnPropertyChanged(nameof(ROIH));
}
}
[Category("相机设置")]
[DisplayName("滤波时间")]
[Description("LineDebouncerTimeI/O去抖时间 单位us")]
public int LineDebouncerTime
{
get => _lineDebouncerTime;
set
{
if (_lineDebouncerTime == value) return;
_lineDebouncerTime = value;
OnPropertyChanged(nameof(LineDebouncerTime));
}
}
// 其他方法保持原有逻辑
public MatSet CopyImageSet(MatSet srcSet)
{
MatSet imageSet = new MatSet
{
Id = srcSet.Id,
_mat = srcSet._mat.Clone(),
// ImageSaveOption = srcSet.ImageSaveOption.Copy(),
ImageTime = srcSet.ImageTime
};
return imageSet;
}
public Action<DateTime, CameraBase, MatSet> OnHImageOutput { get; set; }
public virtual bool CameraConnect() { return false; }
public virtual bool CameraDisConnect() { return false; }
public virtual void SetExposure(int exposureTime, string cameraName) { }
public virtual void SetGain(int gain, string cameraName) { }
internal virtual void SetAcquisitionMode(int mode) { }
internal virtual void SetAcqRegion(int offsetV, int offsetH, int imageH, int imageW, string cameraName) { }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,389 @@

using DH.Commons.Enums;
using OpenCvSharp.Internal;
using System;
using System.ComponentModel;
using System.IO;
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using static DH.Commons.Enums.EnumHelper;
using Timer = System.Threading.Timer;
namespace DH.Commons.Base
{
public abstract class DeviceBase : IDisposable
{
#region Event
[JsonIgnore]
[Browsable(false)]
public Action<DateTime, Exception> OnExceptionOccured { get; set; }
//public event Action<DateTime, LogLevel, string> OnLog;
public event Action<LogMsg> OnLog;
// public event Action<IDevice, DeviceState> OnDeviceStateChanged;
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region field
int RetryTime = 3;
/// <summary>
/// 和设备暂停状态关联的信号量
/// </summary>
private readonly ManualResetEvent pauseHandle = new ManualResetEvent(true);
readonly Timer stateChangedTimer;
#endregion
#region Property
#region State
private EnumHelper.DeviceState _currentStateToBe = EnumHelper.DeviceState.DSUninit;
/// <summary>
/// 当前设备状态
/// </summary>
[JsonIgnore]
internal EnumHelper.DeviceState CurrentStateToBe
{
get
{
return _currentStateToBe;
}
set
{
if (value != _currentStateToBe)
{
var initialState = _currentStateToBe;
_currentStateToBe = value;
if (_currentStateToBe != EnumHelper.DeviceState.DSExcept)
{
// OnStateChanged(initialState);
}
else
{
stateChangedTimer.Change(Timeout.Infinite, Timeout.Infinite);
}
}
}
}
//private EnumHelper.DeviceState initialState = EnumHelper.DeviceState.DSUninit;
private EnumHelper.DeviceState _currentState = EnumHelper.DeviceState.DSUninit;
public EnumHelper.DeviceState CurrentState
{
get
{
return _currentState;
}
set
{
_currentState = value;
if (value != EnumHelper.DeviceState.TBD)
{
// OnDeviceStateChanged?.Invoke(this, _currentState);
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CurrentState"));
}
//else
//{
// initialState = _currentState;
//}
}
}
#endregion
/// <summary>
/// 设备标识符 从数据库获取
/// </summary>
public string Id { get; set; }
/// <summary>
/// 设备名称 从数据库获取
/// </summary>
public string Name { get; set; }
//private IInitialConfig initialConfig = null;
///// <summary>
///// 设备初始化配置 从数据库获取
///// </summary>
//public virtual IInitialConfig InitialConfig
//{
// get => initialConfig;
// set
// {
// initialConfig = value;
// Id = initialConfig.Id;
// Name = initialConfig.Name;
// LoggerHelper.LogPath = initialConfig.LogPath;
// LoggerHelper.LogPrefix = initialConfig.Name;
// }
//}
#endregion
#region
public DeviceBase()
{
RegisterFileWriterException();
// stateChangedTimer = new Timer(new TimerCallback(CheckDeviceOpTimeOut), null, Timeout.Infinite, Timeout.Infinite);
}
#endregion
#region
protected virtual void Init()
{
LogAsync(DateTime.Now, LogLevel.Information, $"{Name}初始化完成");
}
protected virtual void Start()
{
LogAsync(DateTime.Now, LogLevel.Information, $"{Name}启动");
}
protected virtual void Stop()
{
LogAsync(DateTime.Now, LogLevel.Information, $"{Name}停止");
}
//public abstract void AttachToProcess(IProcess process);
#endregion
/// <summary>
/// 常用操作封装方法
/// </summary>
/// <param name="opConfig"></param>
/// <returns></returns>
//public virtual ResponseMessage RunWrap(IOperationConfig opConfig)
//{
// ResponseMessage msg = new ResponseMessage();
// msg.Message = "设备基类默认操作";
// return msg;
//}
#region
//[DeviceExceptionAspect]
//public void StateChange(EnumHelper.DeviceState stateToBe)
//{
// if (CurrentState == stateToBe)
// {
// return;
// }
// if (!stateToBe.CheckPreStateValid((int)CurrentStateToBe))
// {
// string currentStateStr = CurrentStateToBe.GetEnumDescription();
// string stateToBeStr = stateToBe.GetEnumDescription();
// throw new ProcessException($"{InitialConfig.Name}设备的当前状态为{currentStateStr},无法切换至{stateToBeStr}");
// }
// CurrentState = EnumHelper.DeviceState.TBD;
// CurrentStateToBe = stateToBe;
//}
//[DeviceExceptionAspect]
//private void OnStateChanged(EnumHelper.DeviceState initialState)
//{
// try
// {
// if (CurrentStateToBe != EnumHelper.DeviceState.DSExcept)
// {
// }
// else
// {
// if (CurrentState == EnumHelper.DeviceState.DSExcept)
// {
// return;
// }
// else
// {
// throw new ProcessException($"{InitialConfig.Name}设备操作超时");
// }
// }
// if (RetryTime >= 0)
// {
// if (initialState == CurrentStateToBe)
// {
// CurrentState = CurrentStateToBe;
// return;
// }
// #region 状态切换操作
// switch (CurrentStateToBe)
// {
// case EnumHelper.DeviceState.DSInit:
// if (initialState == EnumHelper.DeviceState.DSOpen)
// {
// return;
// }
// else
// {
// Init();
// }
// break;
// case EnumHelper.DeviceState.DSOpen:
// if (initialState == EnumHelper.DeviceState.DSInit)
// {
// Start();
// }
// else if (initialState == EnumHelper.DeviceState.DSPause)
// {
// Resume();
// pauseHandle.Set();
// }
// break;
// case EnumHelper.DeviceState.DSPause:
// pauseHandle.Reset();
// Pause();
// break;
// case EnumHelper.DeviceState.DSClose:
// if (initialState != DeviceState.DSUninit)
// {
// Stop();
// }
// break;
// default:
// break;
// }
// RetryTime = 3;
// CurrentState = CurrentStateToBe;
// #endregion
// }
// stateChangedTimer.Change(Timeout.Infinite, Timeout.Infinite);
// }
// catch (Exception ex)
// {
// RetryTime--;
// if (RetryTime > 0)
// {
// OnStateChanged(initialState);
// }
// else
// {
// if (CurrentState != EnumHelper.DeviceState.DSExcept)
// {
// RetryTime = 3;
// throw new ProcessException($"设备{InitialConfig.Name}的{CurrentStateToBe.GetEnumDescription()}操作重复3次失败", ex, ExceptionLevel.Warning);
// }
// }
// }
//}
//private void CheckDeviceOpTimeOut(object state)
//{
// stateChangedTimer?.Change(Timeout.Infinite, Timeout.Infinite);
// if (CurrentState != EnumHelper.DeviceState.DSExcept)
// {
// StateChange(EnumHelper.DeviceState.DSExcept);
// }
//}
#endregion
#region
private void RegisterFileWriterException()
{
LoggerHelper.OnLogExceptionRaised -= LoggerHelper_OnLogExceptionRaised;
// CSVHelper.OnCSVExceptionRaised -= LoggerHelper_OnLogExceptionRaised;
LoggerHelper.OnLogExceptionRaised += LoggerHelper_OnLogExceptionRaised;
// CSVHelper.OnCSVExceptionRaised += LoggerHelper_OnLogExceptionRaised;
}
// public CSVHelper CSVHelper { get; set; } = new CSVHelper();
public LoggerHelper LoggerHelper { get; set; } = new LoggerHelper();
public virtual void LogAsync(LogMsg msg)
{
msg.MsgSource = Name;
msg.ThreadId = Thread.CurrentThread.ManagedThreadId;
//OnLog?.BeginInvoke(msg, null, null);
OnLog?.Invoke(msg);
//if (InitialConfig.IsEnableLog)
//{
LoggerHelper.LogAsync(msg);
//}
}
public virtual void LogAsync(DateTime dt, LogLevel logLevel, string msg)
{
LogAsync(new LogMsg(dt, logLevel, msg));
}
private void LoggerHelper_OnLogExceptionRaised(DateTime dt, string msg)
{
OnLog?.Invoke(new LogMsg(dt, LogLevel.Error, msg));
}
/// <summary>
/// CSV异步数据输出
/// </summary>
/// <param name="csvFile">CSV输出文件的文件全路径</param>
/// <param name="csvData">CSV输出数据</param>
/// <param name="csvHead">CSV文件表头</param>
public virtual void CSVRecordAsync(string csvFile, string csvData, string csvHead = "")
{
// CSVHelper.CSVOutputAsync(csvFile, csvData, csvHead);
}
#endregion
#region
//object _alarmLock = new object();
//protected virtual async void SaveAlarmCSVAsync(DateTime now, string deviceName, IWarningSet ws)
//{
// await Task.Run(() =>
// {
// LogAsync(now, LogLevel.Warning, $"{ws.WarningCode}-{ws.WarningDescription} {(ws.CurrentStatus ? "发生" : "取消")}");
// if (string.IsNullOrWhiteSpace(this.InitialConfig.LogPath) || !InitialConfig.IsEnableCSV)
// return;
// string path = Path.Combine(InitialConfig.LogPath, $"Alarm_{Name}_{now.ToString("yyyyMMdd")}.csv");
// string head = "Time,Source,AlarmCode,AlarmDescription,AlarmStatus";
// string data = $"{now.ToString("HH:mm:ss.fff")},{deviceName},{ws.WarningCode},{ws.WarningDescription},{(ws.CurrentStatus ? "报警发生" : "报警取消")}";
// CSVRecordAsync(path, data, head);
// });
//}
#endregion
#region IDisposable Support
private bool disposedValue = false; // 要检测冗余调用
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
//释放托管状态(托管对象)。
stateChangedTimer?.Dispose();
pauseHandle?.Dispose();
}
// TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。
// TODO: 将大型字段设置为 null。
disposedValue = true;
}
}
// TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。
// ~DeviceBase()
// {
// // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
// Dispose(false);
// }
// 添加此代码以正确实现可处置模式。
public void Dispose()
{
// 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。
Dispose(true);
// TODO: 如果在以上内容中替代了终结器,则取消注释以下行。
// GC.SuppressFinalize(this);
}
#endregion
}
}

View File

@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using AntdUI;
namespace DH.Commons.Base
{
public class GlobalConfig : NotifyProperty
{
bool _EnableVibrator=false;
bool _EnableBelt = false;
int _ClearTime=0;
string _name;
private BindingList<PLCItem> _InitProcessList = new BindingList<PLCItem>();
private BindingList<PLCItem> _StartProcessList = new BindingList<PLCItem>();
private BindingList<PLCItem> _StopProcessList = new BindingList<PLCItem>();
private BindingList<PLCItem> _StartResetList = new BindingList<PLCItem>();
private BindingList<PLCItem> _StopResetList = new BindingList<PLCItem>();
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged(nameof(Name));
}
}
}
public bool EnableBelt
{
get => _EnableBelt;
set
{
if (_EnableBelt != value)
{
_EnableBelt = value;
OnPropertyChanged(nameof(EnableBelt));
}
}
}
public bool EnableVibrator
{
get => _EnableVibrator;
set
{
if (_EnableVibrator != value)
{
_EnableVibrator = value;
OnPropertyChanged(nameof(EnableVibrator));
}
}
}
public int ClearTime
{
get => _ClearTime;
set
{
if (_ClearTime != value)
{
_ClearTime = value;
OnPropertyChanged(nameof(ClearTime));
}
}
}
public BindingList<PLCItem> InitProcessList
{
get => _InitProcessList;
set
{
if (_InitProcessList == value) return;
_InitProcessList = value;
OnPropertyChanged(nameof(InitProcessList));
}
}
public BindingList<PLCItem> StartProcessList
{
get => _StartProcessList;
set
{
if (_StartProcessList == value) return;
_StartProcessList = value;
OnPropertyChanged(nameof(StartProcessList));
}
}
public BindingList<PLCItem> StopProcessList
{
get => _StopProcessList;
set
{
if (_StopProcessList == value) return;
_StopProcessList = value;
OnPropertyChanged(nameof(StopProcessList));
}
}
public BindingList<PLCItem> StartResetList
{
get => _StartResetList;
set
{
if (_StartResetList == value) return;
_StartResetList = value;
OnPropertyChanged(nameof(StartResetList));
}
}
public BindingList<PLCItem> StopResetList
{
get => _StopResetList;
set
{
if (_StopResetList == value) return;
_StopResetList = value;
OnPropertyChanged(nameof(StopResetList));
}
}
string _imgSavePath;
string _dbSavePath;
string _configSavePath;
public string ImgSavePath
{
get => _imgSavePath;
set
{
if (_imgSavePath != value)
{
_imgSavePath = value;
OnPropertyChanged(nameof(ImgSavePath));
}
}
}
public string DbSavePath
{
get => _dbSavePath;
set
{
if (_dbSavePath != value)
{
_dbSavePath = value;
OnPropertyChanged(nameof(DbSavePath));
}
}
}
public string ConfigSavePath
{
get => _configSavePath;
set
{
if (_configSavePath != value)
{
_configSavePath = value;
OnPropertyChanged(nameof(ConfigSavePath));
}
}
}
}
}

378
DH.Commons/Base/PLCBase.cs Normal file
View File

@ -0,0 +1,378 @@
using System.ComponentModel;
using System.IO.Ports;
using System.Text.Json.Serialization;
using AntdUI;
using DH.Commons.Enums; // 请确保此命名空间包含EnumPLCType
namespace DH.Commons.Base
{
public class PLCBase : NotifyProperty
{
// 私有字段
private bool _enable;
private bool _connected;
private string _plcName;
private EnumPLCType _plcType;
private string _com = "COM1";
private int _baudRate = 9600;
private int _dataBit = 8;
private StopBits _stopBit = StopBits.One;
private Parity _parity = Parity.None;
private string _ip = "192.168.6.61";
private int _port = 502;
private BindingList<PLCItem> _PLCItemList = new BindingList<PLCItem>();
[Category("设备配置")]
[DisplayName("是否启用")]
[Description("是否启用")]
public bool Enable
{
get => _enable;
set
{
if (_enable == value) return;
_enable = value;
OnPropertyChanged(nameof(Enable));
}
}
[Category("状态监控")]
[DisplayName("连接状态")]
[Description("PLC连接状态")]
public bool Connected
{
get => _connected;
set
{
if (_connected == value) return;
_connected = value;
OnPropertyChanged(nameof(Connected));
}
}
[Category("设备配置")]
[DisplayName("PLC名称")]
[Description("PLC设备名称")]
public string PLCName
{
get => _plcName;
set
{
if (_plcName == value) return;
_plcName = value;
OnPropertyChanged(nameof(PLCName));
}
}
[Category("设备配置")]
[DisplayName("PLC类型")]
[Description("PLC通信协议类型")]
public EnumPLCType PLCType
{
get => _plcType;
set
{
if (_plcType == value) return;
_plcType = value;
OnPropertyChanged(nameof(PLCType));
}
}
[Category("串口配置")]
[DisplayName("COM端口")]
[Description("串口号如COM1")]
public string COM
{
get => _com;
set
{
if (_com == value) return;
_com = value;
OnPropertyChanged(nameof(COM));
}
}
[Category("串口配置")]
[DisplayName("波特率")]
[Description("串口通信波特率")]
public int BaudRate
{
get => _baudRate;
set
{
if (_baudRate == value) return;
_baudRate = value;
OnPropertyChanged(nameof(BaudRate));
}
}
[Category("串口配置")]
[DisplayName("数据位")]
[Description("数据位长度(5/6/7/8)")]
public int DataBit
{
get => _dataBit;
set
{
if (_dataBit == value) return;
_dataBit = value;
OnPropertyChanged(nameof(DataBit));
}
}
[Category("串口配置")]
[DisplayName("停止位")]
[Description("停止位设置")]
public StopBits StopBit
{
get => _stopBit;
set
{
if (_stopBit == value) return;
_stopBit = value;
OnPropertyChanged(nameof(StopBit));
}
}
[Category("串口配置")]
[DisplayName("校验位")]
[Description("奇偶校验方式")]
public Parity Parity
{
get => _parity;
set
{
if (_parity == value) return;
_parity = value;
OnPropertyChanged(nameof(Parity));
}
}
[Category("网络配置")]
[DisplayName("IP地址")]
[Description("PLC网络地址")]
public string IP
{
get => _ip;
set
{
if (_ip == value) return;
_ip = value;
OnPropertyChanged(nameof(IP));
}
}
[Category("网络配置")]
[DisplayName("端口号")]
[Description("网络通信端口")]
public int Port
{
get => _port;
set
{
if (_port == value) return;
_port = value;
OnPropertyChanged(nameof(Port));
}
}
[Category("点位配置")]
[DisplayName("点位配置")]
[Description("点位配置")]
public BindingList<PLCItem> PLCItemList
{
get => _PLCItemList;
set
{
if (_PLCItemList == value) return;
_PLCItemList = value;
OnPropertyChanged(nameof(PLCItemList));
}
}
public virtual bool PLCConnect()
{
Connected = true;
return true;
}
public virtual bool PLCDisConnect()
{
Connected = false;
return true;
}
public virtual Int16 ReadInt16(string address) { return 0; }
public virtual Int32 ReadInt32(string address) { return 0; }
public virtual UInt16 ReadUInt16(string address) { return 0; }
public virtual UInt32 ReadUInt32(string address) { return 0; }
public virtual float ReadFloat(string address) { return 0; }
public virtual bool ReadBool(string address) { return false; }
public virtual bool WriteInt16(string address, Int16 value, bool waitForReply = true) { return false; }
public virtual bool WriteInt32(string address, Int32 value, bool waitForReply = true) { return false; }
public virtual bool WriteUInt16(string address, UInt16 value, bool waitForReply = true) { return false; }
public virtual bool WriteUInt32(string address, UInt32 value, bool waitForReply = true) { return false; }
public virtual bool WriteFloat(string address, float value, bool waitForReply = true) { return false; }
public virtual bool WriteBool(string address, bool value, bool waitForReply = true) { return false; }
}
public class PLCItem : NotifyProperty
{
private bool _selected;
private string _name = string.Empty;
private EnumPLCDataType _type;
private string _value = string.Empty;
private bool _startexecute;
private int _startindex;
private string _address;
/// <summary>
/// 是否选中
/// </summary>
public bool Selected
{
get => _selected;
set
{
if (_selected != value)
{
_selected = value;
OnPropertyChanged(nameof(Selected));
}
}
}
/// <summary>
/// 参数名称
/// </summary>
public string Name
{
get => _name;
set
{
if (_name != value)
{
_name = value;
OnPropertyChanged(nameof(Name));
}
}
}
public EnumPLCDataType Type
{
get => _type;
set
{
if (_type != value)
{
_type = value;
OnPropertyChanged(nameof(Type));
}
}
}
/// <summary>
/// 参数类型
/// </summary>
public string Address
{
get => _address;
set
{
if (_address != value)
{
_address = value;
OnPropertyChanged(nameof(Address));
}
}
}
/// <summary>
/// 参数值
/// </summary>
public string Value
{
get => _value;
set
{
if (_value != value)
{
_value = value;
OnPropertyChanged(nameof(Value));
}
}
}
/// <summary>
/// 启用状态
/// </summary>
public bool StartExecute
{
get => _startexecute;
set
{
if (_startexecute != value)
{
_startexecute = value;
OnPropertyChanged(nameof(StartExecute));
}
}
}
/// <summary>
/// 顺序
/// </summary>
public int StartIndex
{
get => _startindex;
set
{
if (_startindex != value)
{
_startindex = value;
OnPropertyChanged(nameof(StartIndex));
}
}
}
private CellLink[] cellLinks;
[JsonIgnore]
public CellLink[] CellLinks
{
get { return cellLinks; }
set
{
if (cellLinks == value) return;
cellLinks = value;
OnPropertyChanged(nameof(CellLinks));
}
}
//private CellTag[] cellTags;
//[JsonIgnore]
//public CellTag[] CellTags
//{
// get { return cellTags; }
// set
// {
// if (cellTags == value) return;
// cellTags = value;
// OnPropertyChanged(nameof(CellTags));
// }
//}
}
}

View File

@ -0,0 +1,78 @@
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using DH.Commons.Enums;
using DH.Commons.Helper;
using HalconDotNet;
using OpenCvSharp;
namespace DH.Commons.Base
{
/// <summary>
/// 视觉处理引擎1.传统视觉 2.深度学习
/// CV深度学习 四大领域
/// Image Classification 图像分类:判别图中物体是什么,比如是猫还是狗;
/// Semantic Segmentation 语义分割:对图像进行像素级分类,预测每个像素属于的类别,不区分个体;
/// Object Detection 目标检测:寻找图像中的物体并进行定位;
/// Instance Segmentation 实例分割:定位图中每个物体,并进行像素级标注,区分不同个体;
/// </summary>
public abstract class VisionEngineBase : DeviceBase
{
public List<DetectionConfig> DetectionConfigs = new List<DetectionConfig>();
#region event
public event Action<string, List<double>> OnCropParamsOutput;
public event Action<string, Bitmap, List<IShapeElement>> OnDetectionDone;
public event Action<string> OnDetectionWarningStop;//有无检测 需要报警停机
#endregion
//public VisionEngineInitialConfigBase IConfig
//{
// get => InitialConfig as VisionEngineInitialConfigBase;
//}
// public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
public string BatchNO { get; set; }
public HTuple hv_ModelID;
public abstract DetectStationResult RunInference(MatSet originImgSet, string detectionId = null);
//public abstract void SaveDetectResultAsync(DetectStationResult detectResult);
public virtual void DetectionDone(string detectionId, Bitmap image, List<IShapeElement> detectionResults)
{
OnDetectionDone?.Invoke(detectionId, image, detectionResults);
}
public virtual void DetectionWarningStop(string detectionDes)
{
OnDetectionWarningStop?.Invoke(detectionDes);
}
public ImageSaveHelper ImageSaveHelper { get; set; } = new ImageSaveHelper();
public virtual void SaveImageAsync(string fullname, Bitmap saveMap, ImageFormat imageFormat)
{
if (saveMap != null)
{
ImageSaveSet imageSaveSet = new ImageSaveSet()
{
FullName = fullname,
SaveImage = saveMap.CopyBitmap(),
ImageFormat = imageFormat.DeepSerializeClone()
};
ImageSaveHelper.ImageSaveAsync(imageSaveSet);
}
}
}
}

View File

@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
namespace DH.Commons.Base
{
public class VisualLocalization
{
// 配置属性
public string CameraName { get; set; }
public string ModelPath { get; set; }
public string ImgPath { get; set; }
public string Threshold { get; set; }
public string Direction { get; set; }
public string Speed { get; set; }
public string MSpeed { get; set; }
// 配置文件路径
private const string ConfigFile = "VisualConfigs.json";
private static readonly object _fileLock = new object();
/// <summary>
/// 保存当前配置(存在则更新,不存在则新增)
/// </summary>
public void Save()
{
lock (_fileLock)
{
var list = LoadAll();
var existing = list.FirstOrDefault(c => c.CameraName == CameraName);
if (existing != null)
{
// 更新现有配置
existing.ModelPath = ModelPath;
existing.ImgPath = ImgPath;
existing.Threshold = Threshold;
existing.Direction = Direction;
existing.Speed = Speed;
existing.MSpeed = MSpeed;
}
else
{
list.Add(this);
}
SaveAll(list);
}
}
/// <summary>
/// 获取全部配置列表
/// </summary>
public static List<VisualLocalization> LoadAll()
{
lock (_fileLock)
{
if (!File.Exists(ConfigFile)) return new List<VisualLocalization>();
var json = File.ReadAllText(ConfigFile);
return JsonSerializer.Deserialize<List<VisualLocalization>>(json)
?? new List<VisualLocalization>();
}
}
private static void SaveAll(List<VisualLocalization> list)
{
var options = new JsonSerializerOptions
{
WriteIndented = true,
IgnoreNullValues = true
};
File.WriteAllText(ConfigFile, JsonSerializer.Serialize(list, options));
}
}
}