修改监控部分功能

This commit is contained in:
2026-05-09 17:49:46 +08:00
parent 06a5f9707d
commit 52ece8211b
14 changed files with 456 additions and 383 deletions

View File

@@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SamplePre.Communication
{
public abstract class CommunicationBase
{
/// <summary>
/// 是否连接
/// </summary>
private bool _isConnected = false;
/// <summary>
/// 连接状态变化事件
/// </summary>
public event Action<bool> ConnectionStatusChanged;
/// <summary>
/// 是否连接
/// </summary>
public bool IsConnected
{
get => _isConnected;
set
{
if (_isConnected != value)
{
_isConnected = value;
ConnectionStatusChanged?.Invoke(value);
}
}
}
/// <summary>
/// 下发下位机指令
/// </summary>
/// <param name="Dbno"></param>
/// <param name="start"></param>
/// <param name="bytes"></param>
/// <returns></returns>
public abstract bool WriteArraysBtye<T>(int Dbno, int start, T[] bytes);
/// <summary>
/// 读取监控数据,读取数组
/// </summary>
/// <returns></returns>
public abstract ushort[] ReadArraysShort(int Dbno, int start, int lenth);
/// <summary>
/// 写入数据
/// </summary>
/// <param name="address">地址(如"M0.0", "DB1.DBW2"</param>
/// <param name="value">要写入的值</param>
/// <returns>是否写入成功</returns>
public abstract bool WriteSingleData(string address, object value);
}
}

View File

@@ -1,40 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SamplePre.Communication
{
public interface ICommunication
{
/// <summary>
/// 下发下位机指令
/// </summary>
/// <param name="Dbno"></param>
/// <param name="start"></param>
/// <param name="bytes"></param>
/// <returns></returns>
bool WriteArraysBtye<T>(int Dbno, int start, T[] bytes);
/// <summary>
/// 读取监控数据,读取数组
/// </summary>
/// <returns></returns>
ushort[] ReadArraysShort(int Dbno, int start, int lenth);
/// <summary>
/// 写入数据
/// </summary>
/// <param name="address">地址(如"M0.0", "DB1.DBW2"</param>
/// <param name="value">要写入的值</param>
/// <returns>是否写入成功</returns>
public bool WriteSingleData(string address, object value);
}
}

View File

@@ -11,7 +11,7 @@ using System.Threading.Tasks;
namespace SamplePre.Communication.Communication namespace SamplePre.Communication.Communication
{ {
public class ModbusTcpCommunicator : ICommunication, IDisposable public class ModbusTcpCommunicator : CommunicationBase, IDisposable
{ {
IModbusMaster _modbusMaster = null; IModbusMaster _modbusMaster = null;
TcpClient _tcpClient = null; TcpClient _tcpClient = null;
@@ -19,31 +19,7 @@ namespace SamplePre.Communication.Communication
private readonly int _port; private readonly int _port;
/// <summary>
/// 是否连接
/// </summary>
private bool _isConnected = false;
/// <summary>
/// 是否连接
/// </summary>
public bool IsConnected
{
get => _isConnected;
set
{
if (_isConnected != value)
{
_isConnected = value;
ConnectionStatusChanged?.Invoke(value);
}
}
}
/// <summary>
/// 连接状态变化事件
/// </summary>
public event Action<bool> ConnectionStatusChanged;
/// <summary> /// <summary>
/// 构造函数 /// 构造函数
@@ -150,7 +126,7 @@ namespace SamplePre.Communication.Communication
/// <param name="start"></param> /// <param name="start"></param>
/// <param name="bytes"></param> /// <param name="bytes"></param>
/// <returns></returns> /// <returns></returns>
public bool WriteArraysBtye<T>(int Dbno, int start, T[] data) public override bool WriteArraysBtye<T>(int Dbno, int start, T[] data)
{ {
@@ -184,7 +160,7 @@ namespace SamplePre.Communication.Communication
/// 读取数组 /// 读取数组
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ushort[] ReadArraysShort(int Dbno, int start, int lenth) public override ushort[] ReadArraysShort(int Dbno, int start, int lenth)
{ {
//try //try
@@ -221,7 +197,7 @@ namespace SamplePre.Communication.Communication
} }
public bool WriteSingleData(string address, object value) public override bool WriteSingleData(string address, object value)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@@ -12,7 +12,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace SamplePre.Communication namespace SamplePre.Communication
{ {
public class S7PlcCommunicator : ICommunication, IDisposable public class S7PlcCommunicator : CommunicationBase, IDisposable
{ {
public Plc _plc; public Plc _plc;
private readonly string _ipAddress; private readonly string _ipAddress;
@@ -20,31 +20,31 @@ namespace SamplePre.Communication
private readonly int _slot; private readonly int _slot;
private readonly CpuType _cpuType; private readonly CpuType _cpuType;
/// <summary> ///// <summary>
/// 是否连接 ///// 是否连接
/// </summary> ///// </summary>
private bool _isConnected = false; //private bool _isConnected = false;
/// <summary> ///// <summary>
/// 是否连接 ///// 是否连接
/// </summary> ///// </summary>
public bool IsConnected //public bool IsConnected
{ //{
get => _isConnected; // get => _isConnected;
set // set
{ // {
if (_isConnected != value) // if (_isConnected != value)
{ // {
_isConnected = value; // _isConnected = value;
ConnectionStatusChanged?.Invoke(value); // ConnectionStatusChanged?.Invoke(value);
} // }
} // }
} //}
/// <summary> ///// <summary>
/// 连接状态变化事件 ///// 连接状态变化事件
/// </summary> ///// </summary>
public event Action<bool> ConnectionStatusChanged; //public event Action<bool> ConnectionStatusChanged;
/// <summary> /// <summary>
/// 构造函数 /// 构造函数
@@ -127,7 +127,7 @@ namespace SamplePre.Communication
/// <param name="start"></param> /// <param name="start"></param>
/// <param name="bytes"></param> /// <param name="bytes"></param>
/// <returns></returns> /// <returns></returns>
public bool WriteArraysBtye<T>(int Dbno, int start, T[] bytes) public override bool WriteArraysBtye<T>(int Dbno, int start, T[] bytes)
{ {
try try
@@ -160,7 +160,7 @@ namespace SamplePre.Communication
/// 读取数组 /// 读取数组
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
public ushort[] ReadArraysShort(int Dbno,int start,int lenth) public override ushort[] ReadArraysShort(int Dbno,int start,int lenth)
{ {
try try
@@ -193,7 +193,7 @@ namespace SamplePre.Communication
/// <param name="address">地址(如"M0.0", "DB1.DBW2"</param> /// <param name="address">地址(如"M0.0", "DB1.DBW2"</param>
/// <param name="value">要写入的值</param> /// <param name="value">要写入的值</param>
/// <returns>是否写入成功</returns> /// <returns>是否写入成功</returns>
public bool WriteSingleData(string address, object value) public override bool WriteSingleData(string address, object value)
{ {
try try
{ {

View File

@@ -18,9 +18,9 @@ namespace SamplePre.Communication
/// <param name="connectionParams">连接参数</param> /// <param name="connectionParams">连接参数</param>
/// <returns></returns> /// <returns></returns>
/// <exception cref="NotSupportedException"></exception> /// <exception cref="NotSupportedException"></exception>
public static ICommunication CreateCommunication(CommProtocolType protocolType, string connectionParams) public static CommunicationBase CreateCommunication(CommProtocolType protocolType, string connectionParams)
{ {
ICommunication comm = null; CommunicationBase comm = null;
switch (protocolType) switch (protocolType)
{ {
@@ -41,21 +41,21 @@ namespace SamplePre.Communication
} }
public static ICommunication CreateS7(string connectionParams) public static CommunicationBase CreateS7(string connectionParams)
{ {
string[] params1 = connectionParams.Split(':'); string[] params1 = connectionParams.Split(':');
if(params1 == null || params1.Length < 3) return null; if(params1 == null || params1.Length < 3) return null;
//ICommunication comm = new S7PlcCommunicator(CpuType.S71500, "192.168.10.2", 0, 1); //ICommunication comm = new S7PlcCommunicator(CpuType.S71500, "192.168.10.2", 0, 1);
ICommunication comm = new S7PlcCommunicator(CpuType.S71500, params1[0], int.Parse( params1[1]), int.Parse( params1[2])); CommunicationBase comm = new S7PlcCommunicator(CpuType.S71500, params1[0], int.Parse( params1[1]), int.Parse( params1[2]));
return comm; return comm;
} }
public static ICommunication CreateModbusTcp(string connectionParams) public static CommunicationBase CreateModbusTcp(string connectionParams)
{ {
string[] params1 = connectionParams.Split(':'); string[] params1 = connectionParams.Split(':');
if (params1 == null || params1.Length < 2) return null; if (params1 == null || params1.Length < 2) return null;
ICommunication comm = new ModbusTcpCommunicator(params1[0], int.Parse(params1[1])); CommunicationBase comm = new ModbusTcpCommunicator(params1[0], int.Parse(params1[1]));
return comm; return comm;
} }

View File

@@ -44,7 +44,7 @@ namespace Models.Const
/// <summary> /// <summary>
/// 主PLC对象 /// 主PLC对象
/// </summary> /// </summary>
public static ICommunication MasterPLC; public static CommunicationBase MasterPLC;
/// <summary> /// <summary>
/// 字典数据 /// 字典数据

View File

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SamplePre.Models.Models
{
public class CurrentSopProgress
{
public string sopName { get; set; }
public string sampleName { get; set; }
public string actionName { get; set; }
public float CurrentPercent { get; set; }
}
}

View File

@@ -1,26 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Models.Models
{
/// <summary>
/// 样本记录
/// </summary>
public class sample_record
{
public int id { get; set; }
public string qrcode { get; set; }
public string check_item { get; set; }
public string jizhi { get; set; }
public string xuhao { get; set; }
public string standard_id { get; set; }
public string input_user { get; set; }
public DateTime inpu_date { get; set; }
public string weight { get; set; }
}
}

View File

@@ -26,6 +26,8 @@ namespace SamplePre.ProcessBll.BLL
//读取下位机状态 //读取下位机状态
ushort[] data1 = SystemConst.MasterPLC.ReadArraysShort(Dbno, start, lenth); ushort[] data1 = SystemConst.MasterPLC.ReadArraysShort(Dbno, start, lenth);
return data1; return data1;
} }

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Media;
namespace SamplePreSystem.UI.Converters
{
public class CommunicationColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string str = value.ToString();
if (str.Contains("PLC通信异常"))
{
return new SolidColorBrush(Colors.Red);
}
else
{
return new SolidColorBrush(Colors.Green);
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
}

View File

@@ -22,10 +22,14 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
public string FaultDesc { get; set; } // 故障描述 public string FaultDesc { get; set; } // 故障描述
public FaultType FaultType { get; set; } // 故障类型 public FaultType FaultType { get; set; } // 故障类型
public DateTime FaultDate { get; set; }
private Brush runColor = Brushes.Orange; private Brush runColor = Brushes.Orange;
public Brush RunColor public Brush RunColor
{ {
get { return runColor; } get { return runColor; }

View File

@@ -7,14 +7,12 @@ using SamplePre.Common;
using SamplePre.Communication.Communication; using SamplePre.Communication.Communication;
using SamplePre.Models; using SamplePre.Models;
using SamplePre.Models.Ext; using SamplePre.Models.Ext;
using SamplePre.Models.Models;
using SamplePre.ProcessBll.BLL; using SamplePre.ProcessBll.BLL;
using SamplePre.ProcessBll.SampleSequence; using SamplePre.ProcessBll.SampleSequence;
using SamplePre.UIWpf.MonitorManager.chirld; using SamplePre.UIWpf.MonitorManager.chirld;
using SamplePre.UIWpf.SampleManager.chirld; using SamplePre.UIWpf.SampleManager.chirld;
using SamplePreSystem.UI.Views.MonitorManager; using SamplePreSystem.UI.Views.MonitorManager;
//using SamplePre.UIWpf.Properties;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
@@ -47,6 +45,12 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
SOPManagerBll sopManagerBll = new SOPManagerBll(); SOPManagerBll sopManagerBll = new SOPManagerBll();
/// <summary>
/// u错误队列
/// </summary>
ConcurrentQueueExt<FaultInfo> errQueue = new SamplePre.Common.ConcurrentQueueExt<FaultInfo>();
/// <summary> /// <summary>
/// 所有动作 /// 所有动作
/// </summary> /// </summary>
@@ -58,144 +62,39 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
//所有动作 //所有动作
sys_Actions = actionMangerBll.QuerySysAction(); sys_Actions = actionMangerBll.QuerySysAction();
//获取所有样本信息
GetSampleData(); GetSampleData();
//获取当前SOP所有动作列表
GetCurrentSopByID(CurrentSop.id);
//计算进度百分比
CalculationProgress(CurrentSop.id);
//初始化功能单元 //初始化功能单元
InitWorkUnits(); InitWorkUnits();
///启动数据监控线程 ///启动数据监控线程
UpdateMonitorData(); UpdateMonitorData();
Test(); //错误信息处理
ErrInfoDo();
//获取当前SOP所有动作列表
GetCurrentSopByID(this.CurrentSopID);
}
/// <summary>
/// 获取当前SOP所有动作列表
/// </summary>
/// <param name="sopID"></param>
public void GetCurrentSopByID(string sopID)
{
CurrentstandardActionList = sopManagerBll.QueryStandardActionByStandardId(sopID)?.OrderBy(p => p.process_no).ToList(); ;
}
/// <summary>
/// 计算进度百分比
/// </summary>
/// <param name="actionID"></param>
public void CalculationProgress(string actionID)
{
if (CurrentstandardActionList.Count <= 0) return;
//var item = CurrentstandardActionList.Where(p => p.process_id == actionID && p.ExecFinishFlag == false).FirstOrDefault();
//if (item != null)
//{
// item.ExecFinishFlag = true;
// int finishcount = CurrentstandardActionList.Count(p => p.ExecFinishFlag == true);
// int totalcount = CurrentstandardActionList.Count;
// double percent = (float)finishcount / totalcount;
// CurrentPercent = Math.Round(percent * 100,0);
//}
} }
/// <summary> #region PLC
/// 当前SOP_ID
/// </summary>
[ObservableProperty] [ObservableProperty]
public string currentSopID = ""; public string txtState = "PLC通信异常";
#endregion
#region
/// <summary>
/// 当前百分比
/// </summary>
[ObservableProperty] [ObservableProperty]
public double currentPercent = 40; public List<sample_input> sampleExecList = new List<sample_input>();
/// <summary>
/// 当前SOP动作
/// </summary>
public List<sys_standard_action_ext> CurrentstandardActionList = new List<sys_standard_action_ext>();
public void Test()
{
SopExecInfo.Add(new SopExecInfo()
{
sapmleName = "DCM固相萃取",
actionName = "加液",
starDate = DateTime.Now,
endDate = DateTime.Now,
state = "完成",
doIngShow = false
});
SopExecInfo.Add(new SopExecInfo()
{
sapmleName = "DCM固相萃取",
actionName = "加液",
starDate = DateTime.Now,
endDate = DateTime.Now,
state = "完成",
doIngShow = false
});
SopExecInfo.Add(new SopExecInfo()
{
sapmleName = "DCM固相萃取",
actionName = "加液",
starDate = DateTime.Now,
endDate = DateTime.Now,
state = "完成",
doIngShow = false
});
SopExecInfo.Add(new SopExecInfo()
{
sapmleName = "DCM固相萃取",
actionName = "离心",
starDate = DateTime.Now,
endDate = DateTime.Now,
state = "执行",
doIngShow = true
});
}
private List<sample_input> _sampleExecList = new List<sample_input>();
public List<sample_input> SampleExecList
{
get { return _sampleExecList; }
set {
SetProperty(ref _sampleExecList, value);
}
}
private string _sopExecData;
public string SopExecData
{
get { return _sopExecData; }
set {
SetProperty(ref _sopExecData, value);
}
}
/// <summary> /// <summary>
/// 获取样本信息 /// 获取样本信息
@@ -209,15 +108,18 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
//设置当前SOP——ID //设置当前SOP——ID
string standrad_id = samples.FirstOrDefault()?.standrad_id; string standrad_id = samples.FirstOrDefault()?.standrad_id;
string standrad_name = samples.FirstOrDefault()?.standrad;
if (!string.IsNullOrEmpty(standrad_id)) if (!string.IsNullOrEmpty(standrad_id))
{ {
if(standrad_id.Contains(",")) if (standrad_id.Contains(","))
{ {
CurrentSopID = standrad_id.Split(",")[0]; CurrentSop.id = standrad_id.Split(",")[0];
CurrentSop.standard_name = standrad_name.Split(",")[0];
} }
else else
{ {
CurrentSopID = standrad_id; CurrentSop.id = standrad_id;
CurrentSop.standard_name = standrad_name;
} }
} }
@@ -225,12 +127,116 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
} }
#endregion
#region sop的动作列表
/// <summary>
/// sop动作执行信息
/// </summary>
private List<SopExecInfo> sopExecInfo = new List<SopExecInfo>();
public List<SopExecInfo> SopExecInfo
{
get { return sopExecInfo; }
set { sopExecInfo = value; }
}
/// <summary>
/// 当前SOP动作
/// </summary>
public List<sys_standard_action_ext> CurrentstandardActionList = new List<sys_standard_action_ext>();
/// <summary>
/// 获取当前SOP所有动作列表
/// </summary>
/// <param name="sopID"></param>
public void GetCurrentSopByID(string sopID)
{
CurrentstandardActionList = sopManagerBll.QueryStandardActionByStandardId(sopID)?.OrderBy(p => p.process_no).ToList(); ;
SopExecInfo.Clear();
int index = 1;
foreach (var item in CurrentstandardActionList)
{
if (index == CurrentstandardActionList.Count)
{
SopExecInfo.Add(new SopExecInfo()
{
sapmleName = this.currentSop.standard_name,
actionName = item.action_name,
starDate = DateTime.Now,
endDate = DateTime.Now,
state = "进行中",
doIngShow = true
});
}
else
{
SopExecInfo.Add(new SopExecInfo()
{
sapmleName = this.currentSop.standard_name,
actionName = item.action_name,
starDate = DateTime.Now,
endDate = DateTime.Now,
state = "完成",
doIngShow = false
});
}
index++;
}
}
#endregion
#region sop执行进度
/// <summary>
/// 当前SOP
/// </summary>
[ObservableProperty]
public sys_standard currentSop = new sys_standard();
/// <summary>
/// 当前SOP进度
/// </summary>
[ObservableProperty]
public CurrentSopProgress sopProgress = new CurrentSopProgress();
/// <summary>
/// 计算SOP进度百分比
/// </summary>
/// <param name="actionID"></param>
public void CalculationProgress(string SopId)
{
SopProgress.sopName = this.CurrentSop.standard_name;
SopProgress.sampleName = "xxxxx";
SopProgress.actionName = CurrentstandardActionList.FirstOrDefault()?.action_name;
SopProgress.CurrentPercent = 40;
}
#endregion
#region
private List<WorkUnit> _workUnits = new List<WorkUnit>(); private List<WorkUnit> _workUnits = new List<WorkUnit>();
public List<WorkUnit> WorkUnits public List<WorkUnit> WorkUnits
{ {
get { return _workUnits; } get { return _workUnits; }
set { set
{
SetProperty(ref _workUnits, value); SetProperty(ref _workUnits, value);
@@ -250,26 +256,60 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
var icon = GetIconKind(item.id); var icon = GetIconKind(item.id);
WorkUnits.Add(new WorkUnit() { actionName= "无", state = 0, StateName = "未连通", unitCode = item.id, unitName = item.data_type ,imgPath = imgPath,packIconKind = icon }); WorkUnits.Add(new WorkUnit() { actionName = "无", state = 0, StateName = "未连通", unitCode = item.id, unitName = item.data_type, imgPath = imgPath, packIconKind = icon });
} }
} }
/// <summary> public PackIconKind GetIconKind(string code)
/// 故障信息
/// </summary>
private ObservableCollection<FaultInfo> faultInfos = new ObservableCollection<FaultInfo>();
public ObservableCollection<FaultInfo> FaultInfos
{ {
get { return faultInfos; } switch (code)
set { {
case "300":
return PackIconKind.RobotIndustrialOutline;//Resources.机器人1;
SetProperty(ref faultInfos, value); case "301":
return PackIconKind.TestTube;//Resources.分液1;
case "302":
return PackIconKind.GoogleCirclesCommunities;//Resources.离心机1;
case "303":
return PackIconKind.GoogleCirclesGroup;
case "304":
return PackIconKind.InboxMultiple;//Resources.固相萃取1;
default:
return PackIconKind.ThermometerWater; //Resources.机器人1;
} }
} }
public string GetIcon(string code)
{
switch (code)
{
case "300":
return "/Assets/机器人1.png";//Resources.机器人1;
case "301":
return "/Assets/分液1.png";//Resources.分液1;
case "302":
return "/Assets/离心机1.png";//Resources.离心机1;
case "303":
return "/Assets/氮吹1.png";
case "304":
return "/Assets/固相萃取1.png";//Resources.固相萃取1;
default:
return "/Assets/机器人1.png";//Resources.机器人1;
}
}
/// <summary> /// <summary>
/// 更新监控数据 /// 更新监控数据
@@ -300,6 +340,18 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
//刷新样品列表 //刷新样品列表
GetSampleData(); GetSampleData();
//跟新plc通信状态
if(SystemConst.MasterPLC.IsConnected)
{
TxtState = "PLC通信正常";
}
else
{
TxtState = "PLC通信异常";
this.errQueue.Enqueue(new FaultInfo() { FaultName = "PLC通信异常", FaultDesc = "请检查PLC是否正常", FaultDate = DateTime.Now });
}
await Task.Delay(3000); await Task.Delay(3000);
} }
@@ -325,7 +377,7 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
if (data1 != null && data1.Length > 0) if (data1 != null && data1.Length > 0)
{ {
foreach(var workUnit in WorkUnits) foreach (var workUnit in WorkUnits)
{ {
var unit_actions = sys_Actions.Where(p => p.action_unit == workUnit.unitCode).ToList(); var unit_actions = sys_Actions.Where(p => p.action_unit == workUnit.unitCode).ToList();
foreach (var action in unit_actions) foreach (var action in unit_actions)
@@ -333,13 +385,7 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
int plcCode = int.Parse(action.plc_type); int plcCode = int.Parse(action.plc_type);
ushort state = data1[plcCode];//动作的状态码 ushort state = data1[plcCode];//动作的状态码
//UCFunUnit uCFunUnit = this.dictUnits[unitCode];
if(state >= 2)
{
//处理sop执行状态计算执行百分比
CalculationProgress(action.id);
}
if (state >= workUnit.state || state == 2) if (state >= workUnit.state || state == 2)
{ //发生改变再修改 { //发生改变再修改
@@ -367,11 +413,13 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
//添加故障信息 //添加故障信息
if (workUnit.state == 0) if (workUnit.state == 0)
{ {
Application.Current?.Dispatcher.BeginInvoke(new Action(() => { //Application.Current?.Dispatcher.BeginInvoke(new Action(() => {
FaultInfos.Add(new FaultInfo { FaultName = workUnit.unitName + " - 未连通", FaultType = FaultType.Warning }); // FaultInfos.Add(new FaultInfo { FaultName = workUnit.unitName + " - 未连通", FaultType = FaultType.Warning });
}), DispatcherPriority.Normal); //}), DispatcherPriority.Normal);
errQueue.Enqueue(new FaultInfo { FaultName = workUnit.unitName + " - 未连通", FaultDate = DateTime.Now, FaultType = FaultType.Warning });
} }
} }
@@ -382,55 +430,6 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
} }
public string GetIcon(string code)
{
switch (code)
{
case "300":
return "/Assets/机器人1.png";//Resources.机器人1;
case "301":
return "/Assets/分液1.png";//Resources.分液1;
case "302":
return "/Assets/离心机1.png";//Resources.离心机1;
case "303":
return "/Assets/氮吹1.png";
case "304":
return "/Assets/固相萃取1.png";//Resources.固相萃取1;
default:
return "/Assets/机器人1.png";//Resources.机器人1;
}
}
public PackIconKind GetIconKind(string code)
{
switch (code)
{
case "300":
return PackIconKind.RobotIndustrialOutline;//Resources.机器人1;
case "301":
return PackIconKind.TestTube;//Resources.分液1;
case "302":
return PackIconKind.GoogleCirclesCommunities;//Resources.离心机1;
case "303":
return PackIconKind.GoogleCirclesGroup;
case "304":
return PackIconKind.InboxMultiple;//Resources.固相萃取1;
default:
return PackIconKind.ThermometerWater; //Resources.机器人1;
}
}
public string SetStateData(int state) public string SetStateData(int state)
{ {
@@ -470,49 +469,55 @@ namespace SamplePreSystem.UI.ViewModel.Monitor
} }
#endregion
SocketClient client; #region
/// <summary>
/// 启动socket
/// </summary>
/// <returns></returns>
public async Task StarClientAsync()
{
client = new SocketClient();
//回调函数
client.ReceiveMsgAction = UpdateSopExecInfo;
await client.StartClientAsync();
}
public void SendSocketTest(string msg)
{
client.SendMsgAsync(msg);
}
/// <summary> /// <summary>
/// 更新sop执行信息 /// 故障信息
/// </summary> /// </summary>
/// <param name="receiveData"></param> private ObservableCollection<FaultInfo> faultInfos = new ObservableCollection<FaultInfo>();
public void UpdateSopExecInfo(string receiveData)
public ObservableCollection<FaultInfo> FaultInfos
{ {
SopExecData += receiveData + "\r\n"; get { return faultInfos; }
set
{
SetProperty(ref faultInfos, value);
}
} }
/// <summary> public void ErrInfoDo()
/// sop执行信息
/// </summary>
private List<SopExecInfo> sopExecInfo = new List<SopExecInfo>();
public List<SopExecInfo> SopExecInfo
{ {
get { return sopExecInfo; } Task.Run(() => {
set { sopExecInfo = value; }
while (true)
{
var errInfo = this.errQueue.GetOne();
if(errInfo != null)
{
Application.Current?.Dispatcher.Invoke(() =>
{
FaultInfos.Add(errInfo);
});
}
Task.Delay(1000).Wait();
}
});
} }
#endregion
/// <summary> /// <summary>
/// 打开详情窗口 /// 打开详情窗口
/// </summary> /// </summary>

View File

@@ -6,6 +6,7 @@
xmlns:hc="https://handyorg.github.io/handycontrol" xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:SamplePre.UIWpf.SampleManager" xmlns:local="clr-namespace:SamplePre.UIWpf.SampleManager"
xmlns:cnt="clr-namespace:SamplePreSystem.UI.Converters"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pro="clr-namespace:SamplePreSystem.UI.BaseControls" xmlns:pro="clr-namespace:SamplePreSystem.UI.BaseControls"
@@ -13,6 +14,11 @@
d:DesignWidth="800" d:DesignWidth="800"
Background="#E6E6E6" Background="#E6E6E6"
mc:Ignorable="d"> mc:Ignorable="d">
<UserControl.Resources>
<cnt:CommunicationColorConverter x:Key="CommunicationColorConverter" />
</UserControl.Resources>
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <ColumnDefinition Width="*" />
@@ -58,6 +64,9 @@
VerticalAlignment="Center" VerticalAlignment="Center"
Orientation="Horizontal"> Orientation="Horizontal">
<Border Width="12" Height="12" Style="{StaticResource ColorBreathStyle}" Background="{Binding TxtState, Converter={StaticResource CommunicationColorConverter}}" CornerRadius="90"/>
<TextBlock Text="{Binding TxtState}" FontSize="13" VerticalAlignment="Center" Margin="5,0,30,0"/>
<Button <Button
Width="80" Width="80"
Height="25" Height="25"
@@ -200,9 +209,9 @@
Text="样品进度" /> Text="样品进度" />
<Grid Grid.Row="1"> <Grid Grid.Row="1">
<StackPanel HorizontalAlignment="Left"> <StackPanel HorizontalAlignment="Left">
<TextBlock Margin="5" Text="当前SOPDCM固相萃取" /> <TextBlock Margin="5" Text="{Binding SopProgress.sopName, StringFormat= 当前SOP{0}}" />
<TextBlock Margin="5" Text="当前样品xxx" /> <TextBlock Margin="5" Text="{Binding SopProgress.sampleName, StringFormat= 样品名称:{0}}" />
<TextBlock Margin="5" Text="当前步骤:离心" /> <TextBlock Margin="5" Text="{Binding SopProgress.actionName, StringFormat= 当前动作:{0}}" />
<TextBlock /> <TextBlock />
</StackPanel> </StackPanel>
<pro:RingProgressBar <pro:RingProgressBar
@@ -211,7 +220,7 @@
Height="200" Height="200"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Progress="{Binding CurrentPercent}" /> Progress="{Binding SopProgress.CurrentPercent}" />
<TextBlock <TextBlock
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
@@ -273,10 +282,7 @@
Binding="{Binding state}" Binding="{Binding state}"
Header="状态" /> Header="状态" />
<DataGridTextColumn
Width="*"
Binding="{Binding sapmleName}"
Header="样品名称" />
<DataGridTextColumn <DataGridTextColumn
Width="*" Width="*"
Binding="{Binding actionName}" Binding="{Binding actionName}"

View File

@@ -41,6 +41,31 @@
<Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="HorizontalContentAlignment" Value="Center" />
</Style> </Style>
<Style x:Key="ColorBreathStyle" TargetType="{x:Type FrameworkElement}">
<!-- 第一步:给控件默认添加一个纯色画刷(必须这样写才能做动画) -->
<Setter Property="Opacity" Value="1" />
<!-- 第二步:加载就自动播放 明暗呼吸动画 -->
<Style.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<!-- 动画:透明度 1 → 0.2 → 1实现 亮 → 暗 → 亮 呼吸 -->
<DoubleAnimation
AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetProperty="Opacity"
From="1"
To="0.2"
Duration="0:0:0.8" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary> </ResourceDictionary>
</Application.Resources> </Application.Resources>
</Application> </Application>