@@ -1,47 +1,47 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using HBLConsole.Interface; | |||
//using System; | |||
//using System.Collections.Generic; | |||
//using System.Linq; | |||
//using System.Text; | |||
//using System.Threading.Tasks; | |||
//using HBLConsole.Interface; | |||
namespace HBLConsole.Business.Devices | |||
{ | |||
public class MORKD : IControl | |||
{ | |||
//namespace HBLConsole.Business.Devices | |||
//{ | |||
// public class MORKD : IControl | |||
// { | |||
private volatile static MORKD _Instance; | |||
public static MORKD GetInstance => _Instance ?? (_Instance = new MORKD()); | |||
private MORKD() { } | |||
// private volatile static MORKD _Instance; | |||
// public static MORKD GetInstance => _Instance ?? (_Instance = new MORKD()); | |||
// private MORKD() { } | |||
public void DataParse<T>(T order) | |||
{ | |||
// public void DataParse<T>(T order) | |||
// { | |||
} | |||
// } | |||
public void Init() | |||
{ | |||
// public void Init() | |||
// { | |||
} | |||
// } | |||
public void Main() | |||
{ | |||
// public void Main() | |||
// { | |||
} | |||
// } | |||
public void ReadData() | |||
{ | |||
// public void ReadData() | |||
// { | |||
} | |||
// } | |||
public void SimOrder() | |||
{ | |||
// public void SimOrder() | |||
// { | |||
} | |||
// } | |||
public void ConnectOk() | |||
{ | |||
// public void ConnectOk() | |||
// { | |||
} | |||
} | |||
} | |||
// } | |||
// } | |||
//} |
@@ -11,6 +11,7 @@ using BPA.Message.Enum; | |||
using HBLConsole.GVL; | |||
using BPA.Utility; | |||
using Newtonsoft.Json; | |||
using HBLConsole.Communication; | |||
namespace HBLConsole.Business.MessageServer | |||
{ | |||
@@ -85,8 +86,25 @@ namespace HBLConsole.Business.MessageServer | |||
if (recipeBomInfo is RecipeBoms recipeBom) | |||
{ | |||
Json<BatchingInfoPar>.Data.recipeBoms = recipeBom; | |||
MessageLog.GetInstance.Show("接收到辅料信息"); | |||
} | |||
//写配方数据到PLC | |||
List<ushort> recipeBoms = new List<ushort>(); | |||
foreach (var item in Json<BatchingInfoPar>.Data.recipeBoms.RecipeIds) | |||
{ | |||
foreach (var rec in item.Recipes) | |||
{ | |||
recipeBoms.Add((ushort)rec); | |||
} | |||
} | |||
if (recipeBoms.Count > 0) | |||
{ | |||
if (ModbusTcpHelper.GetInstance.Write(1100, WriteType.HoldingRegisters, recipeBoms.ToArray())) | |||
{ | |||
MessageLog.GetInstance.Show("成功写入配方数据"); | |||
} | |||
} | |||
MessageLog.GetInstance.Show("接收到辅料信息"); | |||
} | |||
/// <summary> | |||
@@ -20,24 +20,27 @@ namespace HBLConsole.Communication | |||
Json<CommunicationPar>.Read(); | |||
foreach (var item in Json<CommunicationPar>.Data.communicationSets) | |||
{ | |||
if (item.IsActive) | |||
if (item.ClientDeviceType == GVL.GeneralConfig.DeviceType.ToString()) | |||
{ | |||
switch (item.deviceType) | |||
if (item.IsActive) | |||
{ | |||
case EDeviceType.Siemens: | |||
break; | |||
case EDeviceType.ModbusRtu: | |||
break; | |||
case EDeviceType.ModbusTcp: | |||
if (item.Device is ModbusTcp modbus) | |||
{ | |||
ModbusTcpHelper.GetInstance.ModbusTcpConnect(modbus.IP, modbus.PortNum); | |||
} | |||
break; | |||
case EDeviceType.SerialPort: | |||
break; | |||
default: | |||
break; | |||
switch (item.deviceType) | |||
{ | |||
case EDeviceType.Siemens: | |||
break; | |||
case EDeviceType.ModbusRtu: | |||
break; | |||
case EDeviceType.ModbusTcp: | |||
if (item.Device is ModbusTcp modbus) | |||
{ | |||
ModbusTcpHelper.GetInstance.ModbusTcpConnect(modbus.IP, modbus.PortNum); | |||
} | |||
break; | |||
case EDeviceType.SerialPort: | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
} | |||
} | |||
@@ -16,4 +16,10 @@ | |||
<ProjectReference Include="..\HBLConsole.Service\HBLConsole.Service.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Reference Include="BPA.Message"> | |||
<HintPath>D:\BPACommon_output\net5.0\BPA.Message.dll</HintPath> | |||
</Reference> | |||
</ItemGroup> | |||
</Project> |
@@ -63,28 +63,54 @@ namespace HBLConsole.Factory | |||
Type type = Assembly.Load(NameSpace).GetType($"{NameSpace}.MessageServer.{DeviceType}"); | |||
if (type == null) | |||
type = Assembly.Load(NameSpace).GetType($"{NameSpace}.MessageServer.Base"); | |||
return (AbstractMessageServer)Activator.CreateInstance(type); | |||
return Activator.CreateInstance(type) as AbstractMessageServer; | |||
} | |||
IControl business; | |||
/// <summary> | |||
/// 设备初始化 | |||
/// </summary> | |||
public void DeviceInit() | |||
{ | |||
string NameSpace = "HBLConsole.Business";//Load 加载的是dll的名称,GetType获取的是全命名空间下的类 | |||
Type type = Assembly.Load(NameSpace).GetType($"{NameSpace}.Devices.{DeviceType}"); | |||
IControl business = (IControl)type?.GetProperty("GetInstance").GetValue(null); | |||
//string NameSpace = "HBLConsole.Business";//Load 加载的是dll的名称,GetType获取的是全命名空间下的类 | |||
//Type type = Assembly.Load(NameSpace).GetType($"{NameSpace}.Devices.{DeviceType}"); | |||
//IControl business = (IControl)type?.GetProperty("GetInstance").GetValue(null); | |||
//GetBatchingInfo(); | |||
//business?.Init(); | |||
//ActionManagerment.GetInstance.Register(new Action<object>((o) => { business?.DataParse(o); }), "DataParse"); | |||
//ActionManagerment.GetInstance.Register(new Action(() => { business?.ConnectOk(); }), "ConnectOk"); | |||
//ConnectHelper.GetInstance.Init(); | |||
string NameSpace = $"HBLConsole.{DeviceType}";//Load 加载的是dll的名称,GetType获取的是全命名空间下的类 | |||
Type type = Assembly.Load(NameSpace).GetType($"{NameSpace}.Control_{DeviceType}"); | |||
business = Activator.CreateInstance(type) as IControl; | |||
//IControl business = (IControl)type?.GetProperty("GetInstance").GetValue(null); | |||
GetBatchingInfo(); | |||
business?.Init(); | |||
ActionManagerment.GetInstance.Register(new Action<object>((o) => { business?.DataParse(o); }), "DataParse"); | |||
ActionManagerment.GetInstance.Register(new Action(() => { business?.ConnectOk(); }), "ConnectOk"); | |||
ActionManagerment.GetInstance.Register(new Action<object>((o) => { business?.SimOrder(o); }), "SimOrder"); | |||
ConnectHelper.GetInstance.Init(); | |||
} | |||
public IGvl GetGvl() | |||
{ | |||
Type type = Assembly.Load("HBLConsole.GVL").GetType($"HBLConsole.GVL.{DeviceType}"); | |||
return (IGvl)Activator.CreateInstance(type); | |||
Type type = business?.GetType(); | |||
foreach (var item in type?.GetProperties()) | |||
{ | |||
var interfaces = item.PropertyType.GetInterfaces(); | |||
if (interfaces != null) | |||
{ | |||
foreach (var inters in interfaces) | |||
{ | |||
if (inters.Name.Equals("IGvl")) | |||
{ | |||
return (type?.GetProperty(item.Name).GetValue(business, null)) as IGvl; | |||
} | |||
} | |||
} | |||
} | |||
return default; | |||
} | |||
} | |||
} |
@@ -1,263 +1,252 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using HBLConsole.Interface; | |||
using System.Collections.Concurrent; | |||
using HBLConsole.Attributes; | |||
namespace HBLConsole.GVL | |||
{ | |||
/// <summary> | |||
/// MORKS 设备数据 | |||
/// </summary> | |||
public class MORKS : IGvl | |||
{ | |||
/// <summary> | |||
/// 机器人取面 | |||
/// PLC -> M0.3 | |||
/// ModbusTcp -> 323 | |||
/// </summary> | |||
public bool RobotTakeNoodle { get; set; } | |||
/// <summary> | |||
/// 机器人出餐 | |||
/// PLC -> M0.4 | |||
/// ModbusTcp -> 324 | |||
/// </summary> | |||
public bool RobotOutMeal { get; set; } | |||
/// <summary> | |||
/// 移动转台 | |||
/// PLC -> M0.5 | |||
/// ModbusTcp -> 325 | |||
/// </summary> | |||
public bool MoveTurntable { get; set; } | |||
#region 临时变量 | |||
/// <summary> | |||
/// 允许运行 | |||
/// </summary> | |||
[Circuit(new string[] { "机器人取面", "取碗控制" }, "允许运行")] | |||
public bool AllowRun { get; set; } | |||
/// <summary> | |||
/// //机器人任务互锁信号 | |||
/// </summary> | |||
[Circuit(new string[] { "机器人取面", "出面控制" }, "机器人互锁", new bool[] { true, false })] | |||
public bool RobotTaskInterlock { get; set; } | |||
/// <summary> | |||
/// 取碗互锁信号 | |||
/// </summary> | |||
[Circuit("取碗控制", "取碗互锁", true)] | |||
public bool TakeBowlInterlock { get; set; } | |||
/// <summary> | |||
/// 取面互锁信号 | |||
/// </summary> | |||
[Circuit(new string[] { "机器人取面", "出面控制" }, "取面互锁信号", new bool[] { true, true })] | |||
public bool TakeNoodleInterlock { get; set; } | |||
/// <summary> | |||
/// 出面中 | |||
/// </summary> | |||
[Circuit("机器人取面", "出面中", true)] | |||
public bool OutNoodleing { get; set; } | |||
/// <summary> | |||
/// 允许取面 | |||
/// </summary> | |||
[Circuit(new string[] { "转台控制", "机器人取面" }, "允许取面", new bool[] { true, false })] | |||
public bool AllowTakeNoodle { get; set; } | |||
/// <summary> | |||
/// 转台互锁信号 | |||
/// </summary> | |||
public bool TurntableInterlock { get; set; } | |||
#endregion | |||
/// <summary> | |||
/// 初始化完成 | |||
/// PLC -> M100.0 | |||
/// ModbusTcp -> 1120 | |||
/// </summary> | |||
[Circuit(new string[] { "允许运行", "转台控制", "转台控制" }, "初始化完成")] | |||
public bool InitComplete { get; set; } | |||
/// <summary> | |||
/// 取碗机构空闲,True:忙碌,false:空闲 | |||
/// PLC -> M100.1 | |||
/// ModbusTcp -> 1121 | |||
/// </summary> | |||
[Circuit("取碗控制", "取碗机构空闲", true)] | |||
public bool TakeBowlIdle { get; set; } | |||
/// <summary> | |||
/// 温度到达,True:表示到达,false:未到达 | |||
/// PLC -> M100.2 | |||
/// ModbusTcp -> 1122 | |||
/// </summary> | |||
[Circuit("允许运行", "温度到达")] | |||
public bool TemperatureReached { get; set; } | |||
/// <summary> | |||
/// 允许到面,配料完成 | |||
/// PLC -> M100.3 | |||
/// ModbusTcp -> 1123 | |||
/// </summary> | |||
[Circuit("出面控制", "允许到面")] | |||
public bool AllowFallNoodle { get; set; } | |||
/// <summary> | |||
/// 机器人取面完成 | |||
/// PLC -> M100.4 | |||
/// ModbusTcp -> 1124 | |||
/// </summary> | |||
public bool RbTakeNoodleComplete { get; set; } | |||
/// <summary> | |||
/// 机器人倒面完成 | |||
/// PLC -> M100.5 | |||
/// ModbusTcp -> 1125 | |||
/// </summary> | |||
public bool RbFallNoodleComplete { get; set; } | |||
/// <summary> | |||
/// 机器人出餐完成,上报取餐完成 | |||
/// PLC -> M100.6 | |||
/// ModbusTcp -> 1126 | |||
/// </summary> | |||
public bool RbOutMealComplete { get; set; } | |||
/// <summary> | |||
/// 机器人空闲 | |||
/// PLC -> M100.7 | |||
/// ModbusTcp -> 1127 | |||
/// </summary> | |||
[Circuit(new string[] { "机器人取面", "出面控制" }, "机器人空闲")] | |||
public bool RobotIdle { get; set; } | |||
/// <summary> | |||
/// 取餐口检测 | |||
/// PLC -> M101.0 | |||
/// ModbusTcp -> 1128 | |||
/// </summary> | |||
[Circuit("出面控制", "取餐口检测", true)] | |||
public bool TakeMealDetect { get; set; } | |||
/// <summary> | |||
/// 缺碗信号,false:缺碗,true:有碗 | |||
/// PLC -> M101.1 | |||
/// ModbusTcp -> 1129 | |||
/// </summary> | |||
public bool MissingBowl { get; set; } | |||
/// <summary> | |||
/// 设备初始化中,执行中等于1,2秒后复位 | |||
/// PLC -> M101.2 | |||
/// ModbusTcp -> 1130 | |||
/// </summary> | |||
public bool DeviceIniting { get; set; } | |||
/// <summary> | |||
/// 转台下限检测 | |||
/// PLC -> M101.3 | |||
/// ModbusTcp -> 1131 | |||
/// </summary> | |||
[Circuit("转台控制", "转台下限检测有物料")] | |||
public bool TurntableLowerLimit { get; set; } | |||
/// <summary> | |||
/// 缺碗信号 2 | |||
/// PLC -> M101.4 | |||
/// ModbusTcp -> 1132 | |||
/// </summary> | |||
public bool MissingBowlSignal2 { get; set; } | |||
/// <summary> | |||
/// 转台上限检测 | |||
/// PLC -> M101.5 | |||
/// ModbusTcp -> 1133 | |||
/// </summary> | |||
public bool TurntableUpLimit { get; set; } | |||
/// <summary> | |||
/// 转台移动到位 | |||
/// PLC -> M101.7 | |||
/// ModbusTcp -> 1135 | |||
/// </summary> | |||
[Circuit(new string[] { "转台控制", "机器人取面" }, "转台移动到位")] | |||
public bool TurntableMoveInPlace { get; set; } | |||
/// <summary> | |||
/// 煮面炉状态,True:忙碌,false:空闲 | |||
/// M102.0 - M102.5 | |||
/// 1136 - 1141 | |||
/// </summary> | |||
public bool[] NoodleCookerStatus { get; set; } = new bool[6] { false, false, false, false, false, false }; | |||
/// <summary> | |||
/// 煮面完成,上升后给信号 | |||
/// M103.0 - M103.5 | |||
/// 1144 - 1149 | |||
/// </summary> | |||
public bool[] CookNoodlesComplete { get; set; } = new bool[6] { false, false, false, false, false, false }; | |||
/// <summary> | |||
/// 配方编号 | |||
/// PLC -> VW0 | |||
/// ModbusTcp -> 100 | |||
/// </summary> | |||
public ushort RecipeNumber { get; set; } | |||
/// <summary> | |||
/// 转台位置 | |||
/// PLC -> VW2 | |||
/// ModbusTcp -> 101 | |||
/// </summary> | |||
public ushort TurntableLoc { get; set; } | |||
/// <summary> | |||
/// 到面至煮面炉位置 | |||
/// PLC -> VW4 | |||
/// ModbusTcp -> 102 | |||
/// </summary> | |||
public ushort FallNoodleLoc { get; set; } | |||
/// <summary> | |||
/// 取面位置 | |||
/// PLC -> VW6 | |||
/// ModbusTcp -> 103 | |||
/// </summary> | |||
public ushort TakeNoodleLoc { get; set; } | |||
/// <summary> | |||
/// 机器人取面位置队列 | |||
/// </summary> | |||
[Circuit(new string[] { "转台控制", "机器人取面" }, "有机器人取面队列")] | |||
public ConcurrentQueue<OrderLocInfo> RBTakeNoodleTask { get; set; } = new ConcurrentQueue<OrderLocInfo>(); | |||
/// <summary> | |||
/// 出碗队列 | |||
/// </summary> | |||
[Circuit("取碗控制", "有取碗队列数量")] | |||
public ConcurrentQueue<OrderLocInfo> TakeBowlTask { get; set; } = new ConcurrentQueue<OrderLocInfo>(); | |||
} | |||
public class OrderLocInfo | |||
{ | |||
public string SuborderId { get; set; } | |||
public ushort Loc { get; set; } | |||
public ushort RecipeNumber { get; set; } | |||
public int BatchingId { get; set; } | |||
} | |||
} | |||
//using System; | |||
//using System.Collections.Generic; | |||
//using System.Linq; | |||
//using System.Text; | |||
//using System.Threading.Tasks; | |||
//using HBLConsole.Interface; | |||
//using System.Collections.Concurrent; | |||
//using HBLConsole.Attributes; | |||
//using HBLConsole.Model; | |||
//namespace HBLConsole.GVL | |||
//{ | |||
// /// <summary> | |||
// /// MORKS 设备数据 | |||
// /// </summary> | |||
// public class MORKS : IGvl | |||
// { | |||
// /// <summary> | |||
// /// 机器人取面 | |||
// /// PLC -> M0.3 | |||
// /// ModbusTcp -> 323 | |||
// /// </summary> | |||
// public bool RobotTakeNoodle { get; set; } | |||
// /// <summary> | |||
// /// 机器人出餐 | |||
// /// PLC -> M0.4 | |||
// /// ModbusTcp -> 324 | |||
// /// </summary> | |||
// public bool RobotOutMeal { get; set; } | |||
// /// <summary> | |||
// /// 移动转台 | |||
// /// PLC -> M0.5 | |||
// /// ModbusTcp -> 325 | |||
// /// </summary> | |||
// public bool MoveTurntable { get; set; } | |||
// #region 临时变量 | |||
// /// <summary> | |||
// /// 允许运行 | |||
// /// </summary> | |||
// [Circuit(new string[] { "机器人取面", "取碗控制" }, "允许运行")] | |||
// public bool AllowRun { get; set; } | |||
// /// <summary> | |||
// /// //机器人任务互锁信号 | |||
// /// </summary> | |||
// [Circuit(new string[] { "机器人取面", "出面控制" }, "机器人互锁", new bool[] { true, false })] | |||
// public bool RobotTaskInterlock { get; set; } | |||
// /// <summary> | |||
// /// 取碗互锁信号 | |||
// /// </summary> | |||
// [Circuit("取碗控制", "取碗互锁", true)] | |||
// public bool TakeBowlInterlock { get; set; } | |||
// /// <summary> | |||
// /// 取面互锁信号 | |||
// /// </summary> | |||
// [Circuit(new string[] { "机器人取面", "出面控制" }, "取面互锁信号", new bool[] { true, true })] | |||
// public bool TakeNoodleInterlock { get; set; } | |||
// /// <summary> | |||
// /// 出面中 | |||
// /// </summary> | |||
// [Circuit("机器人取面", "出面中", true)] | |||
// public bool OutNoodleing { get; set; } | |||
// /// <summary> | |||
// /// 允许取面 | |||
// /// </summary> | |||
// [Circuit(new string[] { "转台控制", "机器人取面" }, "允许取面", new bool[] { true, false })] | |||
// public bool AllowTakeNoodle { get; set; } | |||
// /// <summary> | |||
// /// 转台互锁信号 | |||
// /// </summary> | |||
// public bool TurntableInterlock { get; set; } | |||
// #endregion | |||
// /// <summary> | |||
// /// 初始化完成 | |||
// /// PLC -> M100.0 | |||
// /// ModbusTcp -> 1120 | |||
// /// </summary> | |||
// [Circuit(new string[] { "允许运行", "转台控制", "转台控制" }, "初始化完成")] | |||
// public bool InitComplete { get; set; } | |||
// /// <summary> | |||
// /// 取碗机构空闲,True:忙碌,false:空闲 | |||
// /// PLC -> M100.1 | |||
// /// ModbusTcp -> 1121 | |||
// /// </summary> | |||
// [Circuit("取碗控制", "取碗机构空闲", true)] | |||
// public bool TakeBowlIdle { get; set; } | |||
// /// <summary> | |||
// /// 温度到达,True:表示到达,false:未到达 | |||
// /// PLC -> M100.2 | |||
// /// ModbusTcp -> 1122 | |||
// /// </summary> | |||
// [Circuit("允许运行", "温度到达")] | |||
// public bool TemperatureReached { get; set; } | |||
// /// <summary> | |||
// /// 允许到面,配料完成 | |||
// /// PLC -> M100.3 | |||
// /// ModbusTcp -> 1123 | |||
// /// </summary> | |||
// [Circuit("出面控制", "允许到面")] | |||
// public bool AllowFallNoodle { get; set; } | |||
// /// <summary> | |||
// /// 机器人取面完成 | |||
// /// PLC -> M100.4 | |||
// /// ModbusTcp -> 1124 | |||
// /// </summary> | |||
// public bool RbTakeNoodleComplete { get; set; } | |||
// /// <summary> | |||
// /// 机器人倒面完成 | |||
// /// PLC -> M100.5 | |||
// /// ModbusTcp -> 1125 | |||
// /// </summary> | |||
// public bool RbFallNoodleComplete { get; set; } | |||
// /// <summary> | |||
// /// 机器人出餐完成,上报取餐完成 | |||
// /// PLC -> M100.6 | |||
// /// ModbusTcp -> 1126 | |||
// /// </summary> | |||
// public bool RbOutMealComplete { get; set; } | |||
// /// <summary> | |||
// /// 机器人空闲 | |||
// /// PLC -> M100.7 | |||
// /// ModbusTcp -> 1127 | |||
// /// </summary> | |||
// [Circuit(new string[] { "机器人取面", "出面控制" }, "机器人空闲")] | |||
// public bool RobotIdle { get; set; } | |||
// /// <summary> | |||
// /// 取餐口检测 | |||
// /// PLC -> M101.0 | |||
// /// ModbusTcp -> 1128 | |||
// /// </summary> | |||
// [Circuit("出面控制", "取餐口检测", true)] | |||
// public bool TakeMealDetect { get; set; } | |||
// /// <summary> | |||
// /// 缺碗信号,false:缺碗,true:有碗 | |||
// /// PLC -> M101.1 | |||
// /// ModbusTcp -> 1129 | |||
// /// </summary> | |||
// public bool MissingBowl { get; set; } | |||
// /// <summary> | |||
// /// 设备初始化中,执行中等于1,2秒后复位 | |||
// /// PLC -> M101.2 | |||
// /// ModbusTcp -> 1130 | |||
// /// </summary> | |||
// public bool DeviceIniting { get; set; } | |||
// /// <summary> | |||
// /// 转台下限检测 | |||
// /// PLC -> M101.3 | |||
// /// ModbusTcp -> 1131 | |||
// /// </summary> | |||
// [Circuit("转台控制", "转台下限检测有物料")] | |||
// public bool TurntableLowerLimit { get; set; } | |||
// /// <summary> | |||
// /// 缺碗信号 2 | |||
// /// PLC -> M101.4 | |||
// /// ModbusTcp -> 1132 | |||
// /// </summary> | |||
// public bool MissingBowlSignal2 { get; set; } | |||
// /// <summary> | |||
// /// 转台上限检测 | |||
// /// PLC -> M101.5 | |||
// /// ModbusTcp -> 1133 | |||
// /// </summary> | |||
// public bool TurntableUpLimit { get; set; } | |||
// /// <summary> | |||
// /// 转台移动到位 | |||
// /// PLC -> M101.7 | |||
// /// ModbusTcp -> 1135 | |||
// /// </summary> | |||
// [Circuit(new string[] { "转台控制", "机器人取面" }, "转台移动到位")] | |||
// public bool TurntableMoveInPlace { get; set; } | |||
// /// <summary> | |||
// /// 煮面炉状态,True:忙碌,false:空闲 | |||
// /// M102.0 - M102.5 | |||
// /// 1136 - 1141 | |||
// /// </summary> | |||
// public bool[] NoodleCookerStatus { get; set; } = new bool[6] { false, false, false, false, false, false }; | |||
// /// <summary> | |||
// /// 煮面完成,上升后给信号 | |||
// /// M103.0 - M103.5 | |||
// /// 1144 - 1149 | |||
// /// </summary> | |||
// public bool[] CookNoodlesComplete { get; set; } = new bool[6] { false, false, false, false, false, false }; | |||
// /// <summary> | |||
// /// 配方编号 | |||
// /// PLC -> VW0 | |||
// /// ModbusTcp -> 100 | |||
// /// </summary> | |||
// public ushort RecipeNumber { get; set; } | |||
// /// <summary> | |||
// /// 转台位置 | |||
// /// PLC -> VW2 | |||
// /// ModbusTcp -> 101 | |||
// /// </summary> | |||
// public ushort TurntableLoc { get; set; } | |||
// /// <summary> | |||
// /// 到面至煮面炉位置 | |||
// /// PLC -> VW4 | |||
// /// ModbusTcp -> 102 | |||
// /// </summary> | |||
// public ushort FallNoodleLoc { get; set; } | |||
// /// <summary> | |||
// /// 取面位置 | |||
// /// PLC -> VW6 | |||
// /// ModbusTcp -> 103 | |||
// /// </summary> | |||
// public ushort TakeNoodleLoc { get; set; } | |||
// /// <summary> | |||
// /// 机器人取面位置队列 | |||
// /// </summary> | |||
// [Circuit(new string[] { "转台控制", "机器人取面" }, "有机器人取面队列")] | |||
// public ConcurrentQueue<OrderLocInfo> RBTakeNoodleTask { get; set; } = new ConcurrentQueue<OrderLocInfo>(); | |||
// /// <summary> | |||
// /// 出碗队列 | |||
// /// </summary> | |||
// [Circuit("取碗控制", "有取碗队列数量")] | |||
// public ConcurrentQueue<OrderLocInfo> TakeBowlTask { get; set; } = new ConcurrentQueue<OrderLocInfo>(); | |||
// } | |||
//} |
@@ -5,6 +5,7 @@ using System.Text; | |||
using System.Threading.Tasks; | |||
using BPA.Message; | |||
using BPA.Message.Enum; | |||
using BPA.Models; | |||
namespace HBLConsole.GVL | |||
{ | |||
@@ -22,6 +22,9 @@ | |||
<Reference Include="BPA.Message"> | |||
<HintPath>D:\BPACommon_output\net5.0\BPA.Message.dll</HintPath> | |||
</Reference> | |||
<Reference Include="BPA.Models"> | |||
<HintPath>D:\BPACommon_output\net5.0\BPA.Models.dll</HintPath> | |||
</Reference> | |||
<Reference Include="BPA.Utility"> | |||
<HintPath>D:\BPACommon_output\net5.0\BPA.Utility.dll</HintPath> | |||
</Reference> | |||
@@ -11,7 +11,7 @@ namespace HBLConsole.Interface | |||
void Main(); | |||
void Init(); | |||
void ReadData(); | |||
void SimOrder(); | |||
void SimOrder<T>(T simOrder); | |||
void DataParse<T>(T order); | |||
void ConnectOk(); | |||
} | |||
@@ -0,0 +1,38 @@ | |||
using System; | |||
using HBLConsole.Interface; | |||
namespace HBLConsole.MORKD | |||
{ | |||
public class Control_MORKD : IControl | |||
{ | |||
public void ConnectOk() | |||
{ | |||
} | |||
public void DataParse<T>(T order) | |||
{ | |||
} | |||
public void Init() | |||
{ | |||
} | |||
public void Main() | |||
{ | |||
} | |||
public void ReadData() | |||
{ | |||
} | |||
public void SimOrder<T>(T simOrder) | |||
{ | |||
} | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using HBLConsole.Interface; | |||
namespace HBLConsole.MORKD | |||
{ | |||
public class GVL_MORKD : IGvl | |||
{ | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>net5.0</TargetFramework> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\HBLConsole.Attribute\HBLConsole.Attributes.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.Communication\HBLConsole.Communication.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.Factory\HBLConsole.Factory.csproj" /> | |||
</ItemGroup> | |||
</Project> |
@@ -0,0 +1,598 @@ | |||
//#define test | |||
using BPA.Message; | |||
using HBLConsole.Communication; | |||
using HBLConsole.Factory; | |||
using HBLConsole.Interface; | |||
using HBLConsole.Model; | |||
using HBLConsole.Service; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using BPA.Message.Enum; | |||
namespace HBLConsole.MORKS | |||
{ | |||
public class Control_MORKS : IControl | |||
{ | |||
public GVL_MORKS mORKS { get; set; } = new GVL_MORKS(); | |||
public void Init() | |||
{ | |||
Test(); | |||
ActionManagerment.GetInstance.Register(new Action(() => { DeviceInit(); }), "InitCommand"); | |||
} | |||
public void ConnectOk() | |||
{ | |||
//WriteRecipeBoms(); | |||
ReadData(); | |||
Main(); | |||
//ResetProgram(); | |||
MessageLog.GetInstance.Show("MORKS 设备初始化完成"); | |||
} | |||
/// <summary> | |||
/// 测试程序 | |||
/// </summary> | |||
private void Test() | |||
{ | |||
#if test | |||
ThreadManagerment.GetInstance.StartLong(new Action(() => | |||
{ | |||
while (Json<MorkOrderPushPar>.GetInstance.Base.morkOrderPushes.Count > 0) | |||
{ | |||
var result = Json<MorkOrderPushPar>.GetInstance.Base.morkOrderPushes.ElementAt(0); | |||
SimpleFactory.GetInstance.OrderChanged(result.OrderPush.SuborderId, ORDER_STATUS.COOKING); | |||
MessageLog.GetInstance.Show($"{result.OrderPush.GoodsName},{ORDER_STATUS.COOKING}"); | |||
Thread.Sleep(5000); | |||
SimpleFactory.GetInstance.OrderChanged(result.OrderPush.SuborderId, ORDER_STATUS.COMPLETED_COOK); | |||
MessageLog.GetInstance.Show($"{result.OrderPush.GoodsName},{ORDER_STATUS.COMPLETED_COOK}"); | |||
Thread.Sleep(5000); | |||
SimpleFactory.GetInstance.OrderChanged(result.OrderPush.SuborderId, ORDER_STATUS.COMPLETED_TAKE); | |||
MessageLog.GetInstance.Show($"{result.OrderPush.GoodsName},{ORDER_STATUS.COMPLETED_TAKE}"); | |||
Thread.Sleep(5000); | |||
Json<MorkOrderPushPar>.GetInstance.Base.morkOrderPushes.RemoveAt(0); | |||
} | |||
Thread.Sleep(500); | |||
}), "test"); | |||
#endif | |||
} | |||
private void Readbool(ushort startAddress, ushort len, Action<bool[]> action) | |||
{ | |||
object result; | |||
result = ModbusTcpHelper.GetInstance.Read(startAddress, ReadType.Coils, len); | |||
if (result != null) | |||
{ | |||
if (result is bool[] bools) | |||
{ | |||
if (bools.Length == len) | |||
{ | |||
action(bools); | |||
} | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 复位程序 | |||
/// </summary> | |||
private void ResetProgram() | |||
{ | |||
ThreadManagerment.GetInstance.StartLong(new Action(() => | |||
{ | |||
if (RTrig.GetInstance("ResetProgram").Start(mORKS.DeviceIniting)) | |||
{ | |||
ThreadManagerment.GetInstance.StopTask("MainTask", new Action(() => | |||
{ | |||
mORKS.AllowRun = false; | |||
TakeBowlId = string.Empty; | |||
IngredientsCompleteId = string.Empty; | |||
CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, }; | |||
mORKS.RobotTaskInterlock = false; | |||
OutMealId = string.Empty; | |||
mORKS.TakeBowlInterlock = false; | |||
mORKS.TakeNoodleInterlock = false; | |||
mORKS.OutNoodleing = false; | |||
Main(); | |||
})); | |||
} | |||
Thread.Sleep(10); | |||
}), "ResetProgram"); | |||
} | |||
/// <summary> | |||
/// 数据读取 | |||
/// </summary> | |||
public void ReadData() | |||
{ | |||
ThreadManagerment.GetInstance.StartLong(new Action(() => | |||
{ | |||
Readbool(323, 3, new Action<bool[]>((bools) => | |||
{ | |||
mORKS.RobotTakeNoodle = bools[0]; | |||
mORKS.RobotOutMeal = bools[1]; | |||
mORKS.MoveTurntable = bools[2]; | |||
})); | |||
Readbool(1120, 16, new Action<bool[]>((bools) => | |||
{ | |||
mORKS.InitComplete = bools[0]; | |||
mORKS.TakeBowlIdle = bools[1]; | |||
mORKS.TemperatureReached = bools[2]; | |||
mORKS.AllowFallNoodle = bools[3]; | |||
mORKS.RbTakeNoodleComplete = bools[4]; | |||
mORKS.RbFallNoodleComplete = bools[5]; | |||
mORKS.RbOutMealComplete = bools[6]; | |||
mORKS.RobotIdle = bools[7]; | |||
mORKS.TakeMealDetect = bools[8]; | |||
mORKS.MissingBowl = bools[9]; | |||
mORKS.DeviceIniting = bools[10]; | |||
mORKS.TurntableLowerLimit = bools[11]; | |||
mORKS.MissingBowlSignal2 = bools[12]; | |||
mORKS.TurntableUpLimit = bools[13]; | |||
mORKS.TurntableMoveInPlace = bools[15]; | |||
})); | |||
Readbool(1136, 6, new Action<bool[]>((bools) => | |||
{ | |||
for (int i = 0; i < 6; i++) | |||
{ | |||
mORKS.NoodleCookerStatus[i] = bools[i]; | |||
} | |||
})); | |||
Readbool(1144, 6, new Action<bool[]>((bools) => | |||
{ | |||
for (int i = 0; i < 6; i++) | |||
{ | |||
mORKS.CookNoodlesComplete[i] = bools[i]; | |||
} | |||
})); | |||
Thread.Sleep(500); | |||
}), "ReadPLCData"); | |||
} | |||
public void SimOrder<T>(T simOrder) | |||
{ | |||
if (simOrder != null) | |||
{ | |||
if (simOrder is SimOrderData simOrderData) | |||
{ | |||
string subId = Guid.NewGuid().ToString(); | |||
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = simOrderData.NoodleLoc, SuborderId = subId }); | |||
mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = simOrderData.BowlLoc, SuborderId = subId }); | |||
MessageLog.GetInstance.Show($"添加订单:面条位置【{simOrderData.NoodleLoc}】,碗位置【{simOrderData.BowlLoc}】"); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 数据解析 | |||
/// </summary> | |||
public void DataParse<T>(T order) | |||
{ | |||
if (order is MorkOrderPush morkOrderPush) | |||
{ | |||
foreach (var item in morkOrderPush.GoodBatchings) | |||
{ | |||
var res = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.FirstOrDefault(p => p.BatchingId == item.BatchingId); | |||
if (res != null) | |||
{ | |||
if (ushort.TryParse(res.BatchingLoc, out ushort loc)) | |||
{ | |||
if (loc >= 1 && loc <= 5) | |||
{ | |||
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId, BatchingId = res.BatchingId }); | |||
} | |||
else if (loc >= 10 && loc <= 11) | |||
{ | |||
int index = Array.FindIndex(Json<BatchingInfoPar>.Data.recipeBoms.RecipeIds.ToArray(), p => p.RecipeId == morkOrderPush.RecipeId); | |||
index++; | |||
mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() { Loc = loc, SuborderId = morkOrderPush.SuborderId, RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0 }); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
#region 临时变量 | |||
/// <summary> | |||
/// 取碗订单ID | |||
/// </summary> | |||
string TakeBowlId = string.Empty; | |||
/// <summary> | |||
/// 配料完成订单ID | |||
/// </summary> | |||
string IngredientsCompleteId = string.Empty; | |||
/// <summary> | |||
/// 煮面口对应的订单ID | |||
/// </summary> | |||
string[] CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, }; | |||
/// <summary> | |||
/// 出餐订单ID | |||
/// </summary> | |||
string OutMealId = string.Empty; | |||
/// <summary> | |||
/// 转台位置轮询 | |||
/// </summary> | |||
List<ushort> TurntableLoc = new List<ushort>(); | |||
#endregion | |||
public void Main() | |||
{ | |||
ThreadManagerment.GetInstance.StartLong(new Action(() => | |||
{ | |||
mORKS.AllowRun = mORKS.InitComplete && !mORKS.TemperatureReached; | |||
TakeBowlTask(); | |||
TakeNoodleTask(); | |||
OutNoodleTask(); | |||
SingleDetect(); | |||
TurntableControl(); | |||
Thread.Sleep(100); | |||
}), "MainTask"); | |||
} | |||
/// <summary> | |||
/// 取碗控制 | |||
/// </summary> | |||
private void TakeBowlTask() | |||
{ | |||
if (mORKS.AllowRun && mORKS.TakeBowlTask.Count > 0 && !mORKS.TakeBowlIdle && !mORKS.TakeBowlInterlock) | |||
{ | |||
if (mORKS.TakeBowlTask.TryDequeue(out OrderLocInfo orderLocInfo)) | |||
{ | |||
TakeBowlId = orderLocInfo.SuborderId; | |||
TakeBowlControl(orderLocInfo.Loc); | |||
SetRecipeNumber(orderLocInfo.RecipeNumber); | |||
SimpleFactory.GetInstance.OrderChanged(TakeBowlId, ORDER_STATUS.COOKING); | |||
MessageLog.GetInstance.Show($"订单【{TakeBowlId}】执行取碗控制,位置:[{orderLocInfo.Loc}]"); | |||
} | |||
mORKS.TakeBowlInterlock = true; | |||
} | |||
} | |||
/// <summary> | |||
/// 转台控制 | |||
/// </summary> | |||
private void TurntableControl() | |||
{ | |||
if (mORKS.TurntableMoveInPlace && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0) | |||
{ | |||
if (mORKS.TurntableLowerLimit) | |||
{ | |||
SetTurntableLoc(mORKS.RBTakeNoodleTask.ElementAt(0).Loc); | |||
MoveTurntable(); | |||
mORKS.AllowTakeNoodle = true; | |||
TurntableLoc.Clear(); | |||
MessageLog.GetInstance.Show("转台位置OK"); | |||
} | |||
else | |||
{ | |||
if (!mORKS.TurntableInterlock) | |||
{ | |||
var result = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKS.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList(); | |||
if (result != null) | |||
{ | |||
foreach (var item in result) | |||
{ | |||
if (ushort.TryParse(item.BatchingLoc, out ushort loc)) | |||
{ | |||
if (TurntableLoc.Contains(loc)) | |||
{ | |||
SetTurntableLoc(loc); | |||
MoveTurntable(); | |||
mORKS.TurntableInterlock = true; | |||
TurntableLoc.Add(loc); | |||
return; | |||
} | |||
} | |||
} | |||
MessageLog.GetInstance.Show("转台位置缺少物料"); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 取面任务 | |||
/// </summary> | |||
private void TakeNoodleTask() | |||
{ | |||
//取面控制 | |||
if (mORKS.AllowRun && mORKS.RobotIdle && !mORKS.RobotTaskInterlock && mORKS.AllowTakeNoodle && mORKS.TurntableMoveInPlace && !mORKS.TakeNoodleInterlock && !mORKS.OutNoodleing && mORKS.RBTakeNoodleTask.Count > 0) | |||
{ | |||
int loc = Array.FindIndex(mORKS.NoodleCookerStatus, p => p == false);//查找煮面炉空闲位置 | |||
if (loc >= 0 && loc <= 5) | |||
{ | |||
if (mORKS.RBTakeNoodleTask.TryDequeue(out OrderLocInfo orderLocInfo)) | |||
{ | |||
//设置转台位置 | |||
SetTurntableLoc(orderLocInfo.Loc); | |||
//设置倒面位置 | |||
CookNodelId[loc] = orderLocInfo.SuborderId; | |||
SetFallNoodleLoc((ushort)(loc + 1)); | |||
//机器人开始取面 | |||
RobotTakeNoodle(); | |||
SimpleFactory.GetInstance.OrderChanged(orderLocInfo.SuborderId, ORDER_STATUS.COOKING); | |||
MessageLog.GetInstance.Show($"订单【{orderLocInfo.SuborderId}】,转台:[{orderLocInfo}],煮面栏:[{loc + 1}]"); | |||
mORKS.TakeNoodleInterlock = true; | |||
} | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 出餐控制 | |||
/// </summary> | |||
private void OutNoodleTask() | |||
{ | |||
if (mORKS.AllowFallNoodle && mORKS.RobotTaskInterlock && !mORKS.TakeNoodleInterlock && mORKS.RobotIdle && !mORKS.TakeMealDetect) | |||
{ | |||
int loc = Array.FindIndex(CookNodelId, p => p == IngredientsCompleteId && p.Length > 0); | |||
if (loc >= 0 && loc <= 5) | |||
{ | |||
if (mORKS.CookNoodlesComplete[loc]) | |||
{ | |||
SetTakeNoodleLoc((ushort)(loc + 1)); | |||
RobotOutMeal(); | |||
CookNoodleStatusReset((ushort)(loc + 1)); | |||
ResetAllowFallNoodle(); | |||
OutMealId = IngredientsCompleteId; | |||
IngredientsCompleteId = string.Empty; | |||
CookNodelId[loc] = string.Empty; | |||
MessageLog.GetInstance.Show($"{loc + 1}号位置出餐控制"); | |||
mORKS.OutNoodleing = true; | |||
} | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 信号检测 | |||
/// </summary> | |||
private void SingleDetect() | |||
{ | |||
//允许倒面信号检测 | |||
if (RTrig.GetInstance("AllowFallNoodle").Start(mORKS.AllowFallNoodle)) | |||
{ | |||
IngredientsCompleteId = TakeBowlId; | |||
TakeBowlId = string.Empty; | |||
MessageLog.GetInstance.Show($"允许到面,{IngredientsCompleteId}"); | |||
mORKS.TakeBowlInterlock = false; | |||
} | |||
//出餐完成信号检测 | |||
if (RTrig.GetInstance("CompleteChange").Start(mORKS.RbOutMealComplete)) | |||
{ | |||
SimpleFactory.GetInstance.OrderChanged(OutMealId, ORDER_STATUS.COMPLETED_COOK); | |||
MessageLog.GetInstance.Show($"订单【{OutMealId}】制作完成"); | |||
mORKS.OutNoodleing = false; | |||
} | |||
//取餐完成逻辑处理 | |||
if (DelayRTrig.GetInstance("CompleteChange1").Start(mORKS.RbOutMealComplete && !mORKS.TakeMealDetect, 2)) | |||
{ | |||
SimpleFactory.GetInstance.OrderChanged(OutMealId, ORDER_STATUS.COMPLETED_TAKE); | |||
MessageLog.GetInstance.Show($"订单【{OutMealId}】取餐完成"); | |||
var RemoveItem = Json<MorkOrderPushPar>.Data.morkOrderPushes.FirstOrDefault(p => p.OrderPush.SuborderId == OutMealId); | |||
if (RemoveItem != null) | |||
{ | |||
Json<MorkOrderPushPar>.Data.morkOrderPushes.Remove(RemoveItem); | |||
} | |||
ResetCookComplete(); | |||
OutMealId = string.Empty; | |||
} | |||
//机器人取面完成信号检测 | |||
if (RTrig.GetInstance("TakeNoodleComplete").Start(mORKS.RbTakeNoodleComplete)) | |||
{ | |||
mORKS.TakeNoodleInterlock = false; | |||
mORKS.AllowTakeNoodle = false; | |||
MessageLog.GetInstance.Show("取面完成"); | |||
TakeNoodleCompleteReset(); | |||
} | |||
//转台到位检测 | |||
if (RTrig.GetInstance("TurntableInPlace").Start(mORKS.TurntableMoveInPlace)) | |||
{ | |||
mORKS.TurntableInterlock = false; | |||
} | |||
int OutMealRequstCount = mORKS.CookNoodlesComplete.Where(p => p == true).ToList().Count; | |||
int mlCount = mORKS.NoodleCookerStatus.Where(p => p == true).ToList().Count; | |||
mORKS.RobotTaskInterlock = OutMealRequstCount > 0 && mORKS.AllowFallNoodle && (mlCount >= 2 || mORKS.RBTakeNoodleTask.Count == 0); | |||
} | |||
#region PLC 控制函数 | |||
/// <summary> | |||
/// 写入配方数据到 PLC | |||
/// </summary> | |||
private void WriteRecipeBoms() | |||
{ | |||
List<ushort> recipeBoms = new List<ushort>(); | |||
foreach (var item in Json<BatchingInfoPar>.Data.recipeBoms.RecipeIds) | |||
{ | |||
foreach (var rec in item.Recipes) | |||
{ | |||
recipeBoms.Add((ushort)rec); | |||
} | |||
} | |||
if (recipeBoms.Count > 0) | |||
{ | |||
if (ModbusTcpHelper.GetInstance.Write(1100, WriteType.HoldingRegisters, recipeBoms.ToArray())) | |||
{ | |||
MessageLog.GetInstance.Show("成功写入配方数据"); | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 转台移动 | |||
/// </summary> | |||
private void MoveTurntable() | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(325, WriteType.Coils, true); | |||
} | |||
/// <summary> | |||
/// 取面完成复位 | |||
/// </summary> | |||
private void TakeNoodleCompleteReset() | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(1124, WriteType.Coils, false); | |||
} | |||
/// <summary> | |||
/// 指定煮面口状态复位 | |||
/// </summary> | |||
/// <param name="num"></param> | |||
private void CookNoodleStatusReset(int num) | |||
{ | |||
if (num >= 1 && num <= 6) | |||
{ | |||
ushort addRess = (ushort)(1136 + num - 1); | |||
ModbusTcpHelper.GetInstance.Write(addRess, WriteType.Coils, false); | |||
MessageLog.GetInstance.Show($"{num}号煮面口占用复位"); | |||
} | |||
} | |||
/// <summary> | |||
/// 写配方编号 | |||
/// </summary> | |||
/// <param name="num"></param> | |||
private void SetRecipeNumber(ushort num) | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(100, WriteType.HoldingRegisters, num); | |||
} | |||
/// <summary> | |||
/// 设置转台位置 | |||
/// </summary> | |||
/// <param name="loc"></param> | |||
private void SetTurntableLoc(ushort loc) | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(101, WriteType.HoldingRegisters, loc); | |||
} | |||
/// <summary> | |||
/// 设置倒面位置 | |||
/// </summary> | |||
/// <param name="loc"></param> | |||
private void SetFallNoodleLoc(ushort loc) | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(102, WriteType.HoldingRegisters, loc); | |||
} | |||
/// <summary> | |||
/// 设置取面位置 | |||
/// </summary> | |||
/// <param name="loc"></param> | |||
private void SetTakeNoodleLoc(ushort loc) | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(103, WriteType.HoldingRegisters, loc); | |||
} | |||
/// <summary> | |||
/// 取碗控制 | |||
/// </summary> | |||
/// <param name="loc"></param> | |||
private void TakeBowlControl(ushort loc) | |||
{ | |||
if (loc == 10) | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(321, WriteType.Coils, true); | |||
} | |||
else if (loc == 11) | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(322, WriteType.Coils, true); | |||
} | |||
} | |||
/// <summary> | |||
/// 机器人取面 | |||
/// </summary> | |||
private void RobotTakeNoodle() | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(323, WriteType.Coils, true); | |||
} | |||
/// <summary> | |||
/// 机器人取餐 | |||
/// </summary> | |||
private void RobotOutMeal() | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(324, WriteType.Coils, true); | |||
var result = ModbusTcpHelper.GetInstance.Read(324, ReadType.Coils); | |||
if (result is bool res) | |||
while (!res) | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(324, WriteType.Coils, true); | |||
} | |||
} | |||
/// <summary> | |||
/// 制作完成信号复位 | |||
/// </summary> | |||
private void ResetCookComplete() | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(1126, WriteType.Coils, false); | |||
} | |||
/// <summary> | |||
/// 复位允许取面信号 | |||
/// </summary> | |||
private void ResetAllowFallNoodle() | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(1123, WriteType.Coils, false); | |||
} | |||
/// <summary> | |||
/// 设备初始化 | |||
/// </summary> | |||
public async void DeviceInit() | |||
{ | |||
ModbusTcpHelper.GetInstance.Write(320, WriteType.Coils, true); | |||
await Task.Delay(1000); | |||
ModbusTcpHelper.GetInstance.Write(320, WriteType.Coils, false); | |||
} | |||
#endregion | |||
} | |||
} | |||
@@ -0,0 +1,252 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using HBLConsole.Interface; | |||
using System.Collections.Concurrent; | |||
using HBLConsole.Attributes; | |||
using HBLConsole.Model; | |||
namespace HBLConsole.MORKS | |||
{ | |||
/// <summary> | |||
/// MORKS 设备数据 | |||
/// </summary> | |||
public class GVL_MORKS : IGvl | |||
{ | |||
/// <summary> | |||
/// 机器人取面 | |||
/// PLC -> M0.3 | |||
/// ModbusTcp -> 323 | |||
/// </summary> | |||
public bool RobotTakeNoodle { get; set; } | |||
/// <summary> | |||
/// 机器人出餐 | |||
/// PLC -> M0.4 | |||
/// ModbusTcp -> 324 | |||
/// </summary> | |||
public bool RobotOutMeal { get; set; } | |||
/// <summary> | |||
/// 移动转台 | |||
/// PLC -> M0.5 | |||
/// ModbusTcp -> 325 | |||
/// </summary> | |||
public bool MoveTurntable { get; set; } | |||
#region 临时变量 | |||
/// <summary> | |||
/// 允许运行 | |||
/// </summary> | |||
[Circuit(new string[] { "机器人取面", "取碗控制" }, "允许运行")] | |||
public bool AllowRun { get; set; } | |||
/// <summary> | |||
/// //机器人任务互锁信号 | |||
/// </summary> | |||
[Circuit(new string[] { "机器人取面", "出面控制" }, "机器人互锁", new bool[] { true, false })] | |||
public bool RobotTaskInterlock { get; set; } | |||
/// <summary> | |||
/// 取碗互锁信号 | |||
/// </summary> | |||
[Circuit("取碗控制", "取碗互锁", true)] | |||
public bool TakeBowlInterlock { get; set; } | |||
/// <summary> | |||
/// 取面互锁信号 | |||
/// </summary> | |||
[Circuit(new string[] { "机器人取面", "出面控制" }, "取面互锁信号", new bool[] { true, true })] | |||
public bool TakeNoodleInterlock { get; set; } | |||
/// <summary> | |||
/// 出面中 | |||
/// </summary> | |||
[Circuit("机器人取面", "出面中", true)] | |||
public bool OutNoodleing { get; set; } | |||
/// <summary> | |||
/// 允许取面 | |||
/// </summary> | |||
[Circuit(new string[] { "转台控制", "机器人取面" }, "允许取面", new bool[] { true, false })] | |||
public bool AllowTakeNoodle { get; set; } | |||
/// <summary> | |||
/// 转台互锁信号 | |||
/// </summary> | |||
public bool TurntableInterlock { get; set; } | |||
#endregion | |||
/// <summary> | |||
/// 初始化完成 | |||
/// PLC -> M100.0 | |||
/// ModbusTcp -> 1120 | |||
/// </summary> | |||
[Circuit(new string[] { "允许运行", "转台控制", "转台控制" }, "初始化完成")] | |||
public bool InitComplete { get; set; } | |||
/// <summary> | |||
/// 取碗机构空闲,True:忙碌,false:空闲 | |||
/// PLC -> M100.1 | |||
/// ModbusTcp -> 1121 | |||
/// </summary> | |||
[Circuit("取碗控制", "取碗机构空闲", true)] | |||
public bool TakeBowlIdle { get; set; } | |||
/// <summary> | |||
/// 温度到达,True:表示到达,false:未到达 | |||
/// PLC -> M100.2 | |||
/// ModbusTcp -> 1122 | |||
/// </summary> | |||
[Circuit("允许运行", "温度到达")] | |||
public bool TemperatureReached { get; set; } | |||
/// <summary> | |||
/// 允许到面,配料完成 | |||
/// PLC -> M100.3 | |||
/// ModbusTcp -> 1123 | |||
/// </summary> | |||
[Circuit("出面控制", "允许到面")] | |||
public bool AllowFallNoodle { get; set; } | |||
/// <summary> | |||
/// 机器人取面完成 | |||
/// PLC -> M100.4 | |||
/// ModbusTcp -> 1124 | |||
/// </summary> | |||
public bool RbTakeNoodleComplete { get; set; } | |||
/// <summary> | |||
/// 机器人倒面完成 | |||
/// PLC -> M100.5 | |||
/// ModbusTcp -> 1125 | |||
/// </summary> | |||
public bool RbFallNoodleComplete { get; set; } | |||
/// <summary> | |||
/// 机器人出餐完成,上报取餐完成 | |||
/// PLC -> M100.6 | |||
/// ModbusTcp -> 1126 | |||
/// </summary> | |||
public bool RbOutMealComplete { get; set; } | |||
/// <summary> | |||
/// 机器人空闲 | |||
/// PLC -> M100.7 | |||
/// ModbusTcp -> 1127 | |||
/// </summary> | |||
[Circuit(new string[] { "机器人取面", "出面控制" }, "机器人空闲")] | |||
public bool RobotIdle { get; set; } | |||
/// <summary> | |||
/// 取餐口检测 | |||
/// PLC -> M101.0 | |||
/// ModbusTcp -> 1128 | |||
/// </summary> | |||
[Circuit("出面控制", "取餐口检测", true)] | |||
public bool TakeMealDetect { get; set; } | |||
/// <summary> | |||
/// 缺碗信号,false:缺碗,true:有碗 | |||
/// PLC -> M101.1 | |||
/// ModbusTcp -> 1129 | |||
/// </summary> | |||
public bool MissingBowl { get; set; } | |||
/// <summary> | |||
/// 设备初始化中,执行中等于1,2秒后复位 | |||
/// PLC -> M101.2 | |||
/// ModbusTcp -> 1130 | |||
/// </summary> | |||
public bool DeviceIniting { get; set; } | |||
/// <summary> | |||
/// 转台下限检测 | |||
/// PLC -> M101.3 | |||
/// ModbusTcp -> 1131 | |||
/// </summary> | |||
[Circuit("转台控制", "转台下限检测有物料")] | |||
public bool TurntableLowerLimit { get; set; } | |||
/// <summary> | |||
/// 缺碗信号 2 | |||
/// PLC -> M101.4 | |||
/// ModbusTcp -> 1132 | |||
/// </summary> | |||
public bool MissingBowlSignal2 { get; set; } | |||
/// <summary> | |||
/// 转台上限检测 | |||
/// PLC -> M101.5 | |||
/// ModbusTcp -> 1133 | |||
/// </summary> | |||
public bool TurntableUpLimit { get; set; } | |||
/// <summary> | |||
/// 转台移动到位 | |||
/// PLC -> M101.7 | |||
/// ModbusTcp -> 1135 | |||
/// </summary> | |||
[Circuit(new string[] { "转台控制", "机器人取面" }, "转台移动到位")] | |||
public bool TurntableMoveInPlace { get; set; } | |||
/// <summary> | |||
/// 煮面炉状态,True:忙碌,false:空闲 | |||
/// M102.0 - M102.5 | |||
/// 1136 - 1141 | |||
/// </summary> | |||
public bool[] NoodleCookerStatus { get; set; } = new bool[6] { false, false, false, false, false, false }; | |||
/// <summary> | |||
/// 煮面完成,上升后给信号 | |||
/// M103.0 - M103.5 | |||
/// 1144 - 1149 | |||
/// </summary> | |||
public bool[] CookNoodlesComplete { get; set; } = new bool[6] { false, false, false, false, false, false }; | |||
/// <summary> | |||
/// 配方编号 | |||
/// PLC -> VW0 | |||
/// ModbusTcp -> 100 | |||
/// </summary> | |||
public ushort RecipeNumber { get; set; } | |||
/// <summary> | |||
/// 转台位置 | |||
/// PLC -> VW2 | |||
/// ModbusTcp -> 101 | |||
/// </summary> | |||
public ushort TurntableLoc { get; set; } | |||
/// <summary> | |||
/// 到面至煮面炉位置 | |||
/// PLC -> VW4 | |||
/// ModbusTcp -> 102 | |||
/// </summary> | |||
public ushort FallNoodleLoc { get; set; } | |||
/// <summary> | |||
/// 取面位置 | |||
/// PLC -> VW6 | |||
/// ModbusTcp -> 103 | |||
/// </summary> | |||
public ushort TakeNoodleLoc { get; set; } | |||
/// <summary> | |||
/// 机器人取面位置队列 | |||
/// </summary> | |||
[Circuit(new string[] { "转台控制", "机器人取面" }, "有机器人取面队列")] | |||
public ConcurrentQueue<OrderLocInfo> RBTakeNoodleTask { get; set; } = new ConcurrentQueue<OrderLocInfo>(); | |||
/// <summary> | |||
/// 出碗队列 | |||
/// </summary> | |||
[Circuit("取碗控制", "有取碗队列数量")] | |||
public ConcurrentQueue<OrderLocInfo> TakeBowlTask { get; set; } = new ConcurrentQueue<OrderLocInfo>(); | |||
} | |||
} |
@@ -0,0 +1,24 @@ | |||
<Project Sdk="Microsoft.NET.Sdk"> | |||
<PropertyGroup> | |||
<TargetFramework>net5.0</TargetFramework> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\HBLConsole.Attribute\HBLConsole.Attributes.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.Communication\HBLConsole.Communication.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.Factory\HBLConsole.Factory.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.Interface\HBLConsole.Interface.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.Model\HBLConsole.Model.csproj" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Reference Include="BPA.Message"> | |||
<HintPath>D:\BPACommon_output\net5.0\BPA.Message.dll</HintPath> | |||
</Reference> | |||
<Reference Include="BPA.Models"> | |||
<HintPath>D:\BPACommon_output\net5.0\BPA.Models.dll</HintPath> | |||
</Reference> | |||
</ItemGroup> | |||
</Project> |
@@ -10,6 +10,7 @@ using HBLConsole.Communication; | |||
using BPA.Message; | |||
using HBLConsole.Business; | |||
using HBLConsole.Factory; | |||
using BPA.Message.Enum; | |||
namespace HBLConsole.MainConsole | |||
{ | |||
@@ -24,14 +25,23 @@ namespace HBLConsole.MainConsole | |||
public void DataInit() | |||
{ | |||
Json<SetPar>.Read(); | |||
if (Enum.TryParse(Json<SetPar>.Data.ClientDeviceType, out DeviceClientType dct)) | |||
{ | |||
GeneralConfig.DeviceType = dct; | |||
} | |||
else { GeneralConfig.DeviceType = DeviceClientType.MORKS; } | |||
Json<MorkOrderPushPar>.Read(); | |||
Json<BatchingInfoPar>.Read(); | |||
MessageLog.GetInstance.Show($"启动【{GeneralConfig.DeviceType}】设备"); | |||
} | |||
public void DataSave() | |||
{ | |||
Json<MorkOrderPushPar>.Save(); | |||
Json<BatchingInfoPar>.Save(); | |||
Json<SetPar>.Save(); | |||
TextHelper.GetInstance.SaveLogInfo(MessageLog.GetInstance.LogInfo, "LogInfo"); | |||
} | |||
@@ -45,11 +55,11 @@ namespace HBLConsole.MainConsole | |||
Topics.Add(TOPIC.GetInstance.GetOrderPushTopic(GeneralConfig.DeviceType, InternetInfo.ClientId)); | |||
Topics.Add(TOPIC.GetInstance.GetBusinessTopic(GeneralConfig.DeviceType, InternetInfo.ClientId)); | |||
SimpleFactory.GetInstance.DeviceInit();//设备初始化 | |||
//MQTT 连接成功 | |||
MqttHelper.GetInstance.ConnectOk = new Action(() => | |||
{ | |||
SimpleFactory.GetInstance.DeviceInit();//设备初始化 | |||
MqttHelper.GetInstance.MqttSubscriptionAsync(Topics.ToArray());//主题订阅 | |||
HeartbeatReport.GetInstance.Init();//心跳上报 | |||
@@ -67,11 +77,9 @@ namespace HBLConsole.MainConsole | |||
MqttHelper.GetInstance.Reconnection = new Action(() => { MqttHelper.GetInstance.MqttSubscriptionAsync(Topics.ToArray()); }); | |||
//MQTT 连接 | |||
MqttHelper.GetInstance.MqttInitAsync(InternetInfo.MqttUserName, | |||
InternetInfo.MqttPassword, | |||
InternetInfo.MqttAddress, | |||
InternetInfo.MqttPort, | |||
DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")); | |||
MqttHelper.GetInstance.MqttInitAsync(InternetInfo.MqttUserName, InternetInfo.MqttPassword, | |||
InternetInfo.MqttAddress, InternetInfo.MqttPort, DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss")); | |||
}), "业务逻辑初始化"); | |||
} | |||
@@ -0,0 +1,52 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.ObjectModel; | |||
using System.ComponentModel.DataAnnotations; | |||
using System.ComponentModel.DataAnnotations.Schema; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace HBLConsole.Model | |||
{ | |||
[Table(nameof(AlarmSet))] | |||
public class AlarmSet | |||
{ | |||
public AlarmSet() | |||
{ | |||
AnalogAlarmModels.Clear(); | |||
foreach (var item in Enum.GetNames(typeof(EAnalogAlarmType))) | |||
{ | |||
AnalogAlarmModels.Add(new AnalogAlarmModel() | |||
{ | |||
AlarmTag = item, | |||
SortTag = (EAnalogAlarmType)Enum.Parse(typeof(EAnalogAlarmType), item) | |||
}); | |||
} | |||
} | |||
[Key] | |||
public int Id { get; set; } | |||
/// <summary> | |||
/// 模拟量报警信息 | |||
/// </summary> | |||
public ObservableCollection<AnalogAlarmModel> AnalogAlarmModels { get; set; } = new ObservableCollection<AnalogAlarmModel>(); | |||
/// <summary> | |||
/// 离散量报警信息 | |||
/// </summary> | |||
public DiscreteAlarmInfo DiscreteAlarmInfoSet { get; set; } = new DiscreteAlarmInfo(); | |||
/// <summary> | |||
/// 设置外键 | |||
/// </summary> | |||
[ForeignKey("VariableInfoId")] | |||
public int VariableInfoId { get; set; } | |||
/// <summary> | |||
/// 设置导航属性 | |||
/// </summary> | |||
public VariableInfo VariableInfo { get; set; } | |||
} | |||
} |
@@ -0,0 +1,55 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.ComponentModel.DataAnnotations; | |||
using System.ComponentModel.DataAnnotations.Schema; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace HBLConsole.Model | |||
{ | |||
/// <summary> | |||
/// 模拟量报警模块 | |||
/// </summary> | |||
public class AnalogAlarmModel | |||
{ | |||
[Key] | |||
public int Id { get; set; } | |||
/// <summary> | |||
/// 设定报警值 | |||
/// </summary> | |||
public int AlarmValue { get; set; } = 0; | |||
/// <summary> | |||
/// 是否启用该报警 | |||
/// </summary> | |||
public bool IsEnable { get; set; } | |||
/// <summary> | |||
/// 报警信息 | |||
/// </summary> | |||
public string AlarmInfo { get; set; } | |||
/// <summary> | |||
/// 报警标签 | |||
/// </summary> | |||
public string AlarmTag { get; set; } | |||
/// <summary> | |||
/// 排序标签 | |||
/// </summary> | |||
public EAnalogAlarmType SortTag { get; set; } | |||
/// <summary> | |||
/// 设置外键 | |||
/// </summary> | |||
[ForeignKey("AlarmSetId")] | |||
public int AlarmSetId { get; set; } | |||
/// <summary> | |||
/// 设置导航属性 | |||
/// </summary> | |||
public AlarmSet AlarmSet { get; set; } | |||
} | |||
} |
@@ -44,7 +44,10 @@ namespace HBLConsole.Model | |||
public EDeviceType deviceType { get { return _mdeviceType; } set { _mdeviceType = value; OnPropertyChanged(); } } | |||
private EDeviceType _mdeviceType; | |||
/// <summary> | |||
/// 客户端启动设备类型 | |||
/// </summary> | |||
public string ClientDeviceType { get; set; } | |||
public RelayCommand<object> RemoveCommand { get; set; } | |||
} | |||
@@ -0,0 +1,41 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.ComponentModel.DataAnnotations; | |||
using System.ComponentModel.DataAnnotations.Schema; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace HBLConsole.Model | |||
{ | |||
/// <summary> | |||
/// 布尔量报警信息 | |||
/// </summary> | |||
[Table(nameof(DiscreteAlarmInfo))] | |||
public class DiscreteAlarmInfo | |||
{ | |||
[Key] | |||
public int Id { get; set; } | |||
/// <summary> | |||
/// 沿报警(上升沿,下降沿) | |||
/// </summary> | |||
public string TrigAlarm { get; set; } | |||
/// <summary> | |||
/// 报警信息 | |||
/// </summary> | |||
public string AlarmInfo { get; set; } | |||
/// <summary> | |||
/// 设置外键 | |||
/// </summary> | |||
[ForeignKey("AlarmSetId")] | |||
public int AlarmSetId { get; set; } | |||
/// <summary> | |||
/// 设置导航属性 | |||
/// </summary> | |||
public AlarmSet AlarmSet { get; set; } | |||
} | |||
} |
@@ -0,0 +1,17 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace HBLConsole.Model | |||
{ | |||
public class OrderLocInfo | |||
{ | |||
public string SuborderId { get; set; } | |||
public ushort Loc { get; set; } | |||
public ushort RecipeNumber { get; set; } | |||
public int BatchingId { get; set; } | |||
} | |||
} |
@@ -17,13 +17,4 @@ namespace HBLConsole.Model | |||
public ConcurrentDictionary<string, List<Condition>> Conditions = new ConcurrentDictionary<string, List<Condition>>(); | |||
} | |||
//public class Condition | |||
//{ | |||
// public bool ConditionMet { get; set; } | |||
// public string propertyIllustrate { get; set; } | |||
// public string ToolTip { get; set; } | |||
// public bool IsNot { get; set; } | |||
//} | |||
} |
@@ -0,0 +1,74 @@ | |||
using Microsoft.Toolkit.Mvvm.Input; | |||
using Newtonsoft.Json; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.ObjectModel; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace HBLConsole.Model | |||
{ | |||
/// <summary> | |||
/// 属性绑定信息 | |||
/// </summary> | |||
public class PropBindInfo : VariableInfo | |||
{ | |||
public PropBindInfo() | |||
{ | |||
ComboBoxItemInit(); | |||
CancelCommand = new RelayCommand(() => { IsOpen = false; }); | |||
ConfirmCommand = new RelayCommand(() => { IsOpen = false; }); | |||
} | |||
/// <summary> | |||
/// 数据类型下拉列表 | |||
/// </summary> | |||
public ObservableCollection<string> dataType { get; set; } = new ObservableCollection<string>(); | |||
/// <summary> | |||
/// 报警类型下拉列表 | |||
/// </summary> | |||
public ObservableCollection<string> alarmType { get; set; } = new ObservableCollection<string>(); | |||
/// <summary> | |||
/// 报警设置窗离散量报警类型 | |||
/// </summary> | |||
public ObservableCollection<string> PopupDiscreteAlarmType { get; set; } = new ObservableCollection<string>(); | |||
/// <summary> | |||
/// 是否显示报警设置框 | |||
/// </summary> | |||
public bool IsOpen { get { return _mIsOpen; } set { _mIsOpen = value; OnPropertyChanged(); } } | |||
private bool _mIsOpen; | |||
/// <summary> | |||
/// 报警设置框取消操作 | |||
/// </summary> | |||
public RelayCommand CancelCommand { get; set; } | |||
/// <summary> | |||
/// 报警设置框确认按钮 | |||
/// </summary> | |||
public RelayCommand ConfirmCommand { get; set; } | |||
/// <summary> | |||
/// 下拉列表初始化 | |||
/// </summary> | |||
private void ComboBoxItemInit() | |||
{ | |||
dataType.Clear(); | |||
alarmType.Clear(); | |||
PopupDiscreteAlarmType.Clear(); | |||
string[] DataTypeNames = Enum.GetNames(typeof(EDataType)); | |||
foreach (var item in DataTypeNames) { dataType.Add(item); } | |||
string[] AlarmTypeNames = Enum.GetNames(typeof(EAlarmType)); | |||
foreach (var item in AlarmTypeNames) { alarmType.Add(item); } | |||
string[] PopupAlarmTypes = Enum.GetNames(typeof(EAlongTriggerType)); | |||
foreach (var item in PopupAlarmTypes) { PopupDiscreteAlarmType.Add(item); } | |||
} | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace HBLConsole.Model | |||
{ | |||
/// <summary> | |||
/// 设置参数 | |||
/// </summary> | |||
public class SetPar | |||
{ | |||
public string ClientDeviceType { get; set; } | |||
} | |||
} |
@@ -8,9 +8,17 @@ namespace HBLConsole.Model | |||
{ | |||
public class SimOrderData | |||
{ | |||
public int NoodleLoc { get; set; } | |||
public int BowlLoc { get; set; } | |||
public bool NoodleIsEnableRandom { get; set; } | |||
public bool BowlIsEnableRandom { get; set; } | |||
/// <summary> | |||
/// 面条位置(1 -- 5) | |||
/// </summary> | |||
public ushort NoodleLoc { get; set; } | |||
/// <summary> | |||
/// 碗位置(10 -- 11) | |||
/// </summary> | |||
public ushort BowlLoc { get; set; } | |||
/// <summary> | |||
/// 浇头位置 (6 -- 9) | |||
/// </summary> | |||
public ushort SoupLoc { get; set; } | |||
} | |||
} |
@@ -0,0 +1,73 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.ComponentModel.DataAnnotations; | |||
using System.ComponentModel.DataAnnotations.Schema; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using Microsoft.Toolkit.Mvvm.ComponentModel; | |||
using Newtonsoft.Json; | |||
namespace HBLConsole.Model | |||
{ | |||
/// <summary> | |||
/// 变量信息 | |||
/// </summary> | |||
[Table(nameof(VariableInfo))] | |||
public class VariableInfo : ObservableObject | |||
{ | |||
[Key] | |||
public int ID { get { return _mID; } set { _mID = value; OnPropertyChanged(); } } | |||
private int _mID; | |||
/// <summary> | |||
/// 变量名 | |||
/// </summary> | |||
public string VarName | |||
{ | |||
get { return _mVarName; } | |||
set | |||
{ | |||
_mVarName = value; | |||
OnPropertyChanged(); | |||
//if (DelegationNotifi.GetInstance.VarNameChanged != null) | |||
// DelegationNotifi.GetInstance.VarNameChanged(_mID); | |||
} | |||
} | |||
private string _mVarName; | |||
/// <summary> | |||
/// 地址 | |||
/// </summary> | |||
public string Address { get { return _mAddress; } set { _mAddress = value; OnPropertyChanged(); } } | |||
private string _mAddress; | |||
/// <summary> | |||
/// 数据类型 | |||
/// </summary> | |||
public string DataType { get { return _mDataType; } set { _mDataType = value; OnPropertyChanged(); } } | |||
private string _mDataType; | |||
/// <summary> | |||
/// 是否启用报警 | |||
/// </summary> | |||
public bool IsEnableAlarm { get { return _mIsEnableAlarm; } set { _mIsEnableAlarm = value; OnPropertyChanged(); } } | |||
private bool _mIsEnableAlarm; | |||
/// <summary> | |||
/// 当前值 | |||
/// </summary> | |||
public string CurrentValue { get { return _mCurrentValue; } set { _mCurrentValue = value; OnPropertyChanged(); } } | |||
private string _mCurrentValue; | |||
/// <summary> | |||
/// 报警设置信息 | |||
/// </summary> | |||
public AlarmSet AlarmSetProp { get { return _mAlarmSetProp; } set { _mAlarmSetProp = value; OnPropertyChanged(); } } | |||
private AlarmSet _mAlarmSetProp = new AlarmSet(); | |||
} | |||
} |
@@ -0,0 +1,81 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using Microsoft.EntityFrameworkCore; | |||
using System.IO; | |||
namespace HBLConsole.Service | |||
{ | |||
public class SqlHelper<T> : DbContext where T : class, new() | |||
{ | |||
private volatile static SqlHelper<T> _Instance; | |||
public static SqlHelper<T> GetInstance => _Instance ?? (_Instance = new SqlHelper<T>()); | |||
private SqlHelper() { } | |||
private string path | |||
{ | |||
get | |||
{ | |||
Directory.CreateDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AccessFile")); | |||
return $"{AppDomain.CurrentDomain.BaseDirectory}AccessFile\\{typeof(T).Name}.db"; | |||
} | |||
} | |||
Dictionary<T, bool> IsEnsureCreated = new Dictionary<T, bool>(); | |||
private static readonly object addLock = new object(); | |||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) | |||
{ | |||
optionsBuilder.UseSqlite($"FileName={path}"); | |||
} | |||
public DbSet<T> DbObj { get; set; } | |||
protected override void OnModelCreating(ModelBuilder modelBuilder) | |||
{ | |||
//一对一关系映射 | |||
//modelBuilder.Entity<VariableInfo>().HasOne(p => p.AlarmSetProp).WithOne(p => p.VariableInfo).HasForeignKey<AlarmSet>(p => p.VariableInfoId); | |||
//modelBuilder.Entity<AlarmSet>().HasOne(P => P.DiscreteAlarmInfoSet).WithOne(P => P.AlarmSet).HasForeignKey<DiscreteAlarmInfo>(P => P.AlarmSetId); | |||
////一对多关系映射 | |||
//modelBuilder.Entity<AnalogAlarmModel>().HasOne(p => p.AlarmSet).WithMany(p => p.AnalogAlarmModels).HasForeignKey(p => p.AlarmSetId); | |||
} | |||
public List<T> GetData() | |||
{ | |||
Database.EnsureCreated(); | |||
return DbObj.ToList(); | |||
} | |||
public void Save() | |||
{ | |||
//if (DbObj != null) | |||
//{ | |||
// if (Entry(DbObj).State == EntityState.Modified) | |||
// { | |||
//Database.EnsureDeleted(); | |||
Database.EnsureCreated(); | |||
SaveChanges(); | |||
// } | |||
//} | |||
} | |||
public void Add(T data) | |||
{ | |||
//lock (addLock) | |||
//{ | |||
//if (!IsEnsureCreated[data]) | |||
//Database.EnsureCreated(); | |||
//if (DbObj.Contains(data)) | |||
// DbObj.Update(data); | |||
//else | |||
DbObj.Add(data); | |||
// } | |||
} | |||
} | |||
} |
@@ -25,7 +25,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HBLConsole.Abstract", "HBLC | |||
EndProject | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HBLConsole.Factory", "HBLConsole.Factory\HBLConsole.Factory.csproj", "{1B19BE8D-AFB9-4635-B114-8648B0C8BDF7}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HBLConsole.Attributes", "HBLConsole.Attribute\HBLConsole.Attributes.csproj", "{9F022DDD-B69C-4AC9-AFB0-0A688EAA1F64}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HBLConsole.Attributes", "HBLConsole.Attribute\HBLConsole.Attributes.csproj", "{9F022DDD-B69C-4AC9-AFB0-0A688EAA1F64}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HBLConsole.MORKS", "HBLConsole.MORKS\HBLConsole.MORKS.csproj", "{B14C829F-CE03-4DBC-93A7-5E3D2787E280}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HBLConsole.MORKD", "HBLConsole.MORKD\HBLConsole.MORKD.csproj", "{FE578C47-A26C-48EF-A06A-EF359B04737F}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
@@ -81,6 +85,14 @@ Global | |||
{9F022DDD-B69C-4AC9-AFB0-0A688EAA1F64}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{9F022DDD-B69C-4AC9-AFB0-0A688EAA1F64}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{9F022DDD-B69C-4AC9-AFB0-0A688EAA1F64}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{B14C829F-CE03-4DBC-93A7-5E3D2787E280}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{B14C829F-CE03-4DBC-93A7-5E3D2787E280}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{B14C829F-CE03-4DBC-93A7-5E3D2787E280}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{B14C829F-CE03-4DBC-93A7-5E3D2787E280}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{FE578C47-A26C-48EF-A06A-EF359B04737F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{FE578C47-A26C-48EF-A06A-EF359B04737F}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{FE578C47-A26C-48EF-A06A-EF359B04737F}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{FE578C47-A26C-48EF-A06A-EF359B04737F}.Release|Any CPU.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
@@ -26,7 +26,7 @@ namespace HBLConsole | |||
protected override void OnStartup(StartupEventArgs e) | |||
{ | |||
base.OnStartup(e); | |||
GeneralConfig.DeviceType = DeviceClientType.MORKS; | |||
SystemHelper.GetInstance.AutoStart(false); | |||
SystemHelper.GetInstance.CreateDesktopShortcut(); | |||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; | |||
@@ -0,0 +1,38 @@ | |||
using HBLConsole.Model; | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Globalization; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Windows.Data; | |||
namespace HBLConsole.Converter | |||
{ | |||
/// <summary> | |||
/// 报警类型文本转换 | |||
/// </summary> | |||
public class AlarmTypeTextConvert : IValueConverter | |||
{ | |||
//当值从绑定源传播给绑定目标时,调用方法Convert,绑定源是控件的数据,绑定目标是后台值 | |||
//界面传递给后台数据 | |||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
if (value != null) | |||
{ | |||
if (value.ToString() == "Bool") | |||
return EAlarmType.离散量报警.ToString(); | |||
else | |||
return EAlarmType.模拟量报警.ToString(); | |||
} | |||
return EAlarmType.无.ToString(); | |||
} | |||
//当值从绑定目标传播给绑定源时,调用此方法ConvertBack | |||
//从后台数据传递给界面 | |||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
return value.ToString(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Globalization; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Windows; | |||
using System.Windows.Data; | |||
namespace HBLConsole.Converter | |||
{ | |||
/// <summary> | |||
/// 模拟量报警显示转换 | |||
/// </summary> | |||
public class AnalogAlarmConvert : IValueConverter | |||
{ | |||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
if (value != null) | |||
{ | |||
return value.ToString() != "Bool" ? Visibility.Visible : Visibility.Collapsed; | |||
} | |||
return Visibility.Visible; | |||
} | |||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,31 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Globalization; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Windows; | |||
using System.Windows.Data; | |||
namespace HBLConsole.Converter | |||
{ | |||
/// <summary> | |||
/// 离散量报警显示转换 | |||
/// </summary> | |||
public class DiscreteAlarmConvert : IValueConverter | |||
{ | |||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
if (value != null) | |||
{ | |||
return value.ToString() == "Bool" ? Visibility.Visible : Visibility.Collapsed; | |||
} | |||
return Visibility.Visible; | |||
} | |||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,39 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Globalization; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Windows.Data; | |||
namespace HBLConsole.Converter | |||
{ | |||
public class IsEnableConvert : IValueConverter | |||
{ | |||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
bool returnValue = false; | |||
if (value != null) | |||
{ | |||
switch (value.ToString()) | |||
{ | |||
case "无": | |||
returnValue = false; | |||
break; | |||
case "离散量报警": | |||
case "模拟量报警": | |||
returnValue = true; | |||
break; | |||
default: | |||
break; | |||
} | |||
} | |||
return returnValue; | |||
} | |||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -0,0 +1,34 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Globalization; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Windows.Data; | |||
namespace HBLConsole.Converter | |||
{ | |||
public class TextDisplayConvert : IValueConverter | |||
{ | |||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
if (value != null && bool.TryParse(value.ToString(), out bool result)) | |||
{ | |||
if (result) | |||
{ | |||
return "取消报警"; | |||
} | |||
else | |||
{ | |||
return "启用报警"; | |||
} | |||
} | |||
return "启用报警"; | |||
} | |||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) | |||
{ | |||
throw new NotImplementedException(); | |||
} | |||
} | |||
} |
@@ -194,6 +194,8 @@ | |||
<ItemGroup> | |||
<ProjectReference Include="..\HBLConsole.MainConsole\HBLConsole.MainConsole.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.Model\HBLConsole.Model.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.MORKD\HBLConsole.MORKD.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.MORKS\HBLConsole.MORKS.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.PryUserControl\HBLConsole.PryUserControl.csproj" /> | |||
<ProjectReference Include="..\HBLConsole.Service\HBLConsole.Service.csproj" /> | |||
</ItemGroup> | |||
@@ -77,6 +77,24 @@ | |||
</Grid.RowDefinitions> | |||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal"> | |||
<TextBlock Style="{StaticResource TextBlockStyle}" Text="请选择客户端启动设备类型:" /> | |||
<ComboBox | |||
Margin="0,0,20,0" | |||
VerticalAlignment="Center" | |||
BorderBrush="#FF23CACA" | |||
Width="150" | |||
BorderThickness="1" | |||
FontFamily="楷体" | |||
FontSize="20" | |||
Foreground="#ff23caca" | |||
IsEditable="False" | |||
ItemsSource="{Binding ClientDevices}" | |||
SelectedIndex="0" | |||
Style="{StaticResource ComboBoxStyle}" | |||
Text="{Binding ClientDeviceType}" /> | |||
<Button | |||
Width="140" | |||
Margin="0,0,20,0" | |||
@@ -212,10 +212,11 @@ | |||
<RadioButton | |||
Margin="-10,0,0,0" | |||
Command="{Binding NavChangedCommand}" | |||
CommandParameter="ProcessMonitoringView" | |||
Content="流程监控" | |||
Style="{StaticResource ParallelogramRadioButtonStyle}" /> | |||
<RadioButton | |||
Margin="-10,0,0,0" | |||
Command="{Binding NavChangedCommand}" | |||
@@ -1,12 +1,180 @@ | |||
<UserControl x:Class="HBLConsole.View.ProcessMonitoringView" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:HBLConsole.View" | |||
mc:Ignorable="d" | |||
d:DesignHeight="450" d:DesignWidth="800"> | |||
<UserControl | |||
x:Class="HBLConsole.View.ProcessMonitoringView" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:HBLConsole.View" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:pry="clr-namespace:HBLConsole.PryUserControl;assembly=HBLConsole.PryUserControl" | |||
xmlns:vm="clr-namespace:HBLConsole.ViewModel" | |||
d:DesignHeight="450" | |||
d:DesignWidth="800" | |||
mc:Ignorable="d"> | |||
<UserControl.DataContext> | |||
<vm:ProcessMonitoringViewModel /> | |||
</UserControl.DataContext> | |||
<UserControl.Resources> | |||
<ResourceDictionary> | |||
<ResourceDictionary.MergedDictionaries> | |||
<ResourceDictionary Source="../Resources/ResourceDictionarys/BasicStyle.xaml"> | |||
<!--#region 开关按钮样式--> | |||
<Style x:Key="ToggleButStyle" TargetType="{x:Type ToggleButton}"> | |||
<Setter Property="IsChecked" Value="False" /> | |||
<Setter Property="FontFamily" Value="楷体" /> | |||
<Setter Property="Foreground" Value="#ddd" /> | |||
<Setter Property="IsEnabled" Value="False" /> | |||
<Setter Property="FontSize" Value="18" /> | |||
<Setter Property="Margin" Value="0,0,10,0" /> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type ToggleButton}"> | |||
<!--<Grid x:Name="gr" SnapsToDevicePixels="True">--> | |||
<Border | |||
Name="br" | |||
Background="#FF1E9614" | |||
CornerRadius="5"> | |||
<ContentPresenter | |||
x:Name="contentPresenter" | |||
Margin="4,2" | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
Content="{TemplateBinding Content}" | |||
ContentStringFormat="{TemplateBinding ContentStringFormat}" | |||
ContentTemplate="{TemplateBinding ContentTemplate}" | |||
Focusable="False" | |||
RecognizesAccessKey="True" | |||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> | |||
</Border> | |||
<!--</Grid>--> | |||
<ControlTemplate.Triggers> | |||
<Trigger Property="IsChecked" Value="True"> | |||
<Setter TargetName="br" Property="Background" Value="#FF1E9614" /> | |||
</Trigger> | |||
<Trigger Property="IsChecked" Value="False"> | |||
<Setter TargetName="br" Property="Background" Value="#FFF11A38" /> | |||
</Trigger> | |||
<Trigger Property="IsMouseOver" Value="True"> | |||
<!--<Setter TargetName="tb" Property="Foreground" Value="#2695FF" />--> | |||
</Trigger> | |||
</ControlTemplate.Triggers> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<!--#endregion--> | |||
<!--#region ListBox样式--> | |||
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}"> | |||
<Setter Property="OverridesDefaultStyle" Value="True" /> | |||
<Setter Property="SnapsToDevicePixels" Value="True" /> | |||
<Setter Property="BorderBrush" Value="{x:Null}" /> | |||
<Setter Property="Foreground" Value="White" /> | |||
<Setter Property="FontSize" Value="20" /> | |||
<Setter Property="HorizontalContentAlignment" Value="Center" /> | |||
<Setter Property="VerticalContentAlignment" Value="Center" /> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type ListBoxItem}"> | |||
<Border x:Name="border" CornerRadius="8"> | |||
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" /> | |||
</Border> | |||
<!--<ControlTemplate.Triggers> | |||
<Trigger Property="IsSelected" Value="True"> | |||
<Setter TargetName="border" Property="Background"> | |||
<Setter.Value> | |||
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> | |||
<GradientStop Offset="0.5" Color="#FF6B6B6B" /> | |||
<GradientStop Offset="0.5" Color="#FF535353" /> | |||
<GradientStop Offset="0.022" Color="#FF535353" /> | |||
<GradientStop Offset="0.991" Color="#FF555555" /> | |||
</LinearGradientBrush> | |||
</Setter.Value> | |||
</Setter> | |||
</Trigger> | |||
</ControlTemplate.Triggers>--> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style> | |||
<!--#endregion--> | |||
</ResourceDictionary> | |||
</ResourceDictionary.MergedDictionaries> | |||
</ResourceDictionary> | |||
</UserControl.Resources> | |||
<Grid> | |||
<ScrollViewer | |||
HorizontalScrollBarVisibility="Visible" | |||
Style="{StaticResource ScrollViewerStyle}" | |||
VerticalScrollBarVisibility="Visible"> | |||
<ItemsControl ItemsSource="{Binding processConditions}"> | |||
<ItemsControl.ItemTemplate> | |||
<DataTemplate> | |||
<StackPanel Margin="0,10" VerticalAlignment="Center"> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="200" /> | |||
<ColumnDefinition /> | |||
</Grid.ColumnDefinitions> | |||
<pry:BeveledButton | |||
x:Name="bb" | |||
IsParallelogram="False" | |||
StrokeThickness="1"> | |||
<pry:BeveledButton.FillColor> | |||
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5"> | |||
<GradientStop Color="#ff1247EC" /> | |||
<GradientStop Offset="1" Color="#111247EC" /> | |||
</LinearGradientBrush> | |||
</pry:BeveledButton.FillColor> | |||
</pry:BeveledButton> | |||
<TextBlock | |||
Margin="2" | |||
VerticalAlignment="Center" | |||
FontFamily="楷体" | |||
FontSize="16" | |||
Foreground="Aqua" | |||
Text="{Binding ProcessTitl}" /> | |||
</Grid> | |||
<ListBox | |||
x:Name="lstEnt" | |||
Margin="0,3,0,0" | |||
Background="{x:Null}" | |||
BorderBrush="{x:Null}" | |||
BorderThickness="0" | |||
ItemContainerStyle="{StaticResource ResourceKey=ListBoxItemStyle1}" | |||
ItemsSource="{Binding Conditions}"> | |||
<ListBox.ItemsPanel> | |||
<ItemsPanelTemplate> | |||
<StackPanel Orientation="Horizontal" /> | |||
</ItemsPanelTemplate> | |||
</ListBox.ItemsPanel> | |||
<ListBox.ItemTemplate> | |||
<DataTemplate> | |||
<ToggleButton | |||
Content="{Binding propertyIllustrate}" | |||
IsChecked="{Binding ConditionMet}" | |||
Style="{StaticResource ToggleButStyle}" | |||
ToolTip="{Binding ToolTip}" /> | |||
</DataTemplate> | |||
</ListBox.ItemTemplate> | |||
</ListBox> | |||
</StackPanel> | |||
</DataTemplate> | |||
</ItemsControl.ItemTemplate> | |||
</ItemsControl> | |||
</ScrollViewer> | |||
</Grid> | |||
</UserControl> |
@@ -0,0 +1,453 @@ | |||
<UserControl | |||
x:Class="HBLConsole.View.VariableConfig" | |||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |||
xmlns:convert="clr-namespace:HBLConsole.Converter" | |||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |||
xmlns:local="clr-namespace:HBLConsole.View" | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:pry="clr-namespace:HBLConsole.PryUserControl;assembly=HBLConsole.PryUserControl" | |||
xmlns:vm="clr-namespace:HBLConsole.ViewModel" | |||
d:DesignHeight="450" | |||
d:DesignWidth="1000" | |||
mc:Ignorable="d"> | |||
<UserControl.DataContext> | |||
<vm:VariableConfig /> | |||
</UserControl.DataContext> | |||
<UserControl.Resources> | |||
<ResourceDictionary Source="../Resources/ResourceDictionarys/BasicStyle.xaml"> | |||
<ResourceDictionary.MergedDictionaries> | |||
<ResourceDictionary> | |||
<convert:TextDisplayConvert x:Key="textDisplayConvert" /> | |||
<convert:IsEnableConvert x:Key="isEnableConvert" /> | |||
<convert:AnalogAlarmConvert x:Key="analogAlarmConvert" /> | |||
<convert:DiscreteAlarmConvert x:Key="discreteAlarmConvert" /> | |||
<convert:AlarmTypeTextConvert x:Key="alarmTypeTextConvert" /> | |||
<SolidColorBrush x:Key="BorderSolid" Color="#5523CACA" /> | |||
<SolidColorBrush x:Key="FontColor" Color="#FF2AB2E7" /> | |||
<SolidColorBrush x:Key="TitleFontColor" Color="#ddd" /> | |||
<SolidColorBrush x:Key="CursorColor" Color="Aqua" /> | |||
<SolidColorBrush x:Key="TitleBorderColor" Color="#FF2AB2E7" /> | |||
<Style x:Key="TextBlockStyle" TargetType="TextBlock"> | |||
<Setter Property="FontFamily" Value="楷体" /> | |||
<Setter Property="FontSize" Value="18" /> | |||
<Setter Property="Foreground" Value="{StaticResource TextBlockForeground}" /> | |||
<Setter Property="VerticalAlignment" Value="Center" /> | |||
<Setter Property="HorizontalAlignment" Value="Center" /> | |||
</Style> | |||
<Style x:Key="TextBoxStyle" TargetType="TextBox"> | |||
<Setter Property="FontFamily" Value="楷体" /> | |||
<Setter Property="FontSize" Value="22" /> | |||
<Setter Property="Background" Value="Transparent" /> | |||
<Setter Property="Foreground" Value="{StaticResource TextBlockForeground}" /> | |||
<Setter Property="BorderBrush" Value="#FF23CACA" /> | |||
<Setter Property="CaretBrush" Value="Aqua" /> | |||
<Setter Property="VerticalAlignment" Value="Center" /> | |||
</Style> | |||
</ResourceDictionary> | |||
</ResourceDictionary.MergedDictionaries> | |||
</ResourceDictionary> | |||
</UserControl.Resources> | |||
<Grid Margin="10"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="30" /> | |||
<RowDefinition Height="30" /> | |||
<RowDefinition /> | |||
</Grid.RowDefinitions> | |||
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal"> | |||
<!--<Button | |||
Margin="20,0,20,0" | |||
Command="{Binding GenerateData}" | |||
Content="添加数据" /> | |||
<Button | |||
Margin="20,0,20,0" | |||
Command="{Binding SaveData}" | |||
Content="保存数据" />--> | |||
</StackPanel> | |||
<!--#region 表格标题栏设置--> | |||
<Grid Grid.Row="1" Background="#dd2AB2E7"> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="0.3*" /> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
<ColumnDefinition Width="0.7*" /> | |||
<ColumnDefinition Width="0" /> | |||
<ColumnDefinition Width="0.7*" /> | |||
<ColumnDefinition Width="0.5*" /> | |||
</Grid.ColumnDefinitions> | |||
<TextBlock | |||
Grid.Column="0" | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
FontSize="16" | |||
Foreground="{StaticResource TitleFontColor}" | |||
Text="ID" /> | |||
<Grid Grid.Column="1"> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
FontSize="16" | |||
Foreground="{StaticResource TitleFontColor}" | |||
Text="名称" /> | |||
<Border BorderBrush="{StaticResource TitleBorderColor}" BorderThickness="1,0,1,0" /> | |||
</Grid> | |||
<TextBlock | |||
Grid.Column="2" | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
FontSize="16" | |||
Foreground="{StaticResource TitleFontColor}" | |||
Text="地址" /> | |||
<Grid Grid.Column="3"> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
FontSize="16" | |||
Foreground="{StaticResource TitleFontColor}" | |||
Text="数据类型" /> | |||
<Border BorderBrush="{StaticResource TitleBorderColor}" BorderThickness="1,0,1,0" /> | |||
</Grid> | |||
<TextBlock | |||
Grid.Column="4" | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
FontSize="16" | |||
Foreground="{StaticResource TitleFontColor}" | |||
Text="报警类型" /> | |||
<Grid Grid.Column="5"> | |||
<TextBlock | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
FontSize="16" | |||
Foreground="{StaticResource TitleFontColor}" | |||
Text="是否启用报警" /> | |||
<Border BorderBrush="{StaticResource TitleBorderColor}" BorderThickness="0,0,1,0" /> | |||
</Grid> | |||
<TextBlock | |||
Grid.Column="6" | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
FontSize="16" | |||
Foreground="{StaticResource TitleFontColor}" | |||
Text="报警配置" /> | |||
</Grid> | |||
<!--#endregion--> | |||
<!--#region 表格数据显示--> | |||
<ScrollViewer | |||
Grid.Row="2" | |||
HorizontalScrollBarVisibility="Hidden" | |||
VerticalScrollBarVisibility="Hidden"> | |||
<ItemsControl ItemsSource="{Binding varialeInfos}"> | |||
<ItemsControl.ItemTemplate> | |||
<DataTemplate> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="0.3*" /> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
<ColumnDefinition Width="0.7*" /> | |||
<ColumnDefinition Width="0" /> | |||
<ColumnDefinition Width="0.7*" /> | |||
<ColumnDefinition Width="0.5*" /> | |||
</Grid.ColumnDefinitions> | |||
<TextBlock | |||
Grid.Column="0" | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
Background="Transparent" | |||
FontSize="14" | |||
Foreground="{StaticResource FontColor}" | |||
Text="{Binding ID}" /> | |||
<Grid Grid.Column="1"> | |||
<TextBox | |||
Background="Transparent" | |||
CaretBrush="{StaticResource CursorColor}" | |||
Foreground="{StaticResource FontColor}" | |||
Style="{StaticResource InputTextboxStyle}" | |||
Text="{Binding VarName}" /> | |||
<Border BorderBrush="{StaticResource BorderSolid}" BorderThickness="1,0,1,0" /> | |||
</Grid> | |||
<TextBox | |||
Grid.Column="2" | |||
Background="Transparent" | |||
CaretBrush="{StaticResource CursorColor}" | |||
Foreground="{StaticResource FontColor}" | |||
Style="{StaticResource InputTextboxStyle}" | |||
Text="{Binding Address}" /> | |||
<Grid Grid.Column="3"> | |||
<ComboBox | |||
VerticalAlignment="Center" | |||
BorderBrush="Transparent" | |||
BorderThickness="1" | |||
FontFamily="楷体" | |||
FontSize="20" | |||
Foreground="{StaticResource FontColor}" | |||
IsEditable="False" | |||
ItemsSource="{Binding dataType}" | |||
SelectedValue="{Binding DataType}" | |||
Style="{StaticResource ComboBoxStyle}" | |||
Text="{Binding DataType}" /> | |||
<Border BorderBrush="{StaticResource BorderSolid}" BorderThickness="1,0,1,0" /> | |||
</Grid> | |||
<Grid Grid.Column="5"> | |||
<CheckBox | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
Background="#ff23CACA" | |||
Content="{Binding IsEnableAlarm, Converter={StaticResource textDisplayConvert}}" | |||
FontSize="16" | |||
Foreground="{StaticResource FontColor}" | |||
IsChecked="{Binding IsEnableAlarm}" | |||
Template="{StaticResource CbTemplate}" /> | |||
<Border BorderBrush="{StaticResource BorderSolid}" BorderThickness="0,0,1,0" /> | |||
</Grid> | |||
<Grid Grid.Column="6"> | |||
<Grid> | |||
<ToggleButton | |||
Name="tb" | |||
Width="{Binding RelativeSource={RelativeSource AncestorType=Grid, AncestorLevel=1}, Path=ActualWidth}" | |||
Height="{Binding RelativeSource={RelativeSource AncestorType=Grid, AncestorLevel=1}, Path=ActualHeight}" | |||
Background="Transparent" | |||
BorderThickness="0" | |||
Content="编辑" | |||
FontSize="14" | |||
IsChecked="{Binding IsOpen}" | |||
IsEnabled="{Binding IsEnableAlarm}" | |||
Style="{StaticResource EditToggleButtonStyle}" /> | |||
</Grid> | |||
<!-- 当 StaysOpen 设置为 True 时 popup失去焦点的时候不会自动关闭 --> | |||
<Popup | |||
AllowsTransparency="True" | |||
Focusable="False" | |||
IsOpen="{Binding IsOpen}" | |||
Placement="Left" | |||
PlacementTarget="{Binding ElementName=tb}" | |||
StaysOpen="False"> | |||
<Border Background="#081424" ClipToBounds="True"> | |||
<Grid Margin="0"> | |||
<Grid.Background> | |||
<ImageBrush ImageSource="../Resource/Images/边框1.png" /> | |||
</Grid.Background> | |||
<Grid.RowDefinitions> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
</Grid.RowDefinitions> | |||
<!--#region 离散量报警设置--> | |||
<StackPanel | |||
Grid.Row="0" | |||
Margin="10" | |||
Orientation="Vertical" | |||
Visibility="{Binding DataType, Converter={StaticResource discreteAlarmConvert}}"> | |||
<Grid Margin="5"> | |||
<pry:TitleTextBlock /> | |||
<TextBlock | |||
Margin="10,5,30,5" | |||
Background="Transparent" | |||
FontSize="16" | |||
Foreground="#dd01FFFF" | |||
Text="离散量报警设置" /> | |||
</Grid> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
</Grid.ColumnDefinitions> | |||
<TextBlock | |||
Margin="5" | |||
Style="{StaticResource TextBlockStyle}" | |||
Text="选择触发条件:" /> | |||
<ComboBox | |||
Grid.Column="1" | |||
Width="180" | |||
Margin="5" | |||
VerticalAlignment="Center" | |||
BorderBrush="#FF23CACA" | |||
BorderThickness="1" | |||
FontFamily="楷体" | |||
FontSize="20" | |||
Foreground="#ff23caca" | |||
IsEditable="False" | |||
ItemsSource="{Binding PopupDiscreteAlarmType}" | |||
SelectedIndex="1" | |||
Style="{StaticResource ComboBoxStyle}" | |||
Text="{Binding AlarmSetProp.DiscreteAlarmInfoSet.TrigAlarm}" /> | |||
</Grid> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
</Grid.ColumnDefinitions> | |||
<TextBlock | |||
Grid.Column="0" | |||
Margin="5" | |||
Style="{StaticResource TextBlockStyle}" | |||
Text="输入报警信息:" /> | |||
<TextBox | |||
Grid.Column="1" | |||
Grid.ColumnSpan="2" | |||
Margin="5" | |||
Style="{StaticResource TextBoxStyle}" | |||
Text="{Binding AlarmSetProp.DiscreteAlarmInfoSet.AlarmInfo}" /> | |||
</Grid> | |||
</StackPanel> | |||
<!--#endregion--> | |||
<!--#region 模拟量报警设置--> | |||
<StackPanel | |||
Grid.Row="1" | |||
Margin="10" | |||
Visibility="{Binding DataType, Converter={StaticResource analogAlarmConvert}}"> | |||
<Grid Margin="5"> | |||
<pry:TitleTextBlock /> | |||
<TextBlock | |||
Margin="10,5,30,5" | |||
Background="Transparent" | |||
FontSize="16" | |||
Foreground="#dd01FFFF" | |||
Text="模拟量报警设置" /> | |||
</Grid> | |||
<ItemsControl ItemsSource="{Binding AlarmSetProp.AnalogAlarmModels}"> | |||
<ItemsControl.ItemTemplate> | |||
<DataTemplate> | |||
<Grid> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
</Grid.ColumnDefinitions> | |||
<Grid.RowDefinitions> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
</Grid.RowDefinitions> | |||
<CheckBox | |||
Margin="5,5,0,0" | |||
HorizontalAlignment="Left" | |||
VerticalAlignment="Center" | |||
Background="#ff23CACA" | |||
Content="{Binding AlarmTag}" | |||
FontSize="14" | |||
Foreground="#ff23CACA" | |||
IsChecked="{Binding IsEnable}" | |||
Template="{StaticResource CbTemplate}" /> | |||
<TextBlock | |||
Grid.Column="1" | |||
Margin="0,5,5,0" | |||
Style="{StaticResource TextBlockStyle}" | |||
Text="请输入报警值:" /> | |||
<TextBox | |||
Grid.Column="2" | |||
Width="100" | |||
Margin="0,5,5,0" | |||
IsEnabled="{Binding IsEnable}" | |||
Style="{StaticResource TextBoxStyle}" | |||
Text="{Binding AlarmValue}" /> | |||
<TextBlock | |||
Grid.Row="1" | |||
Grid.Column="0" | |||
Margin="5" | |||
Style="{StaticResource TextBlockStyle}" | |||
Text="输入报警信息:" /> | |||
<TextBox | |||
Grid.Row="1" | |||
Grid.Column="1" | |||
Grid.ColumnSpan="2" | |||
Margin="5" | |||
IsEnabled="{Binding IsEnable}" | |||
Style="{StaticResource TextBoxStyle}" | |||
Text="{Binding AlarmInfo}" /> | |||
</Grid> | |||
</DataTemplate> | |||
</ItemsControl.ItemTemplate> | |||
</ItemsControl> | |||
</StackPanel> | |||
<!--#endregion--> | |||
<!--#region 按钮控制--> | |||
<Grid Grid.Row="2" Margin="10"> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition /> | |||
<ColumnDefinition /> | |||
</Grid.ColumnDefinitions> | |||
<Button | |||
Margin="10,5,10,10" | |||
Command="{Binding CancelCommand}" | |||
Content="取消" | |||
FontFamily="楷体" | |||
FontSize="20" | |||
Foreground="#aa01FFFF" | |||
Template="{StaticResource CancelButtonTemp}" /> | |||
<Button | |||
Grid.Column="1" | |||
Margin="10,5,10,10" | |||
Command="{Binding ConfirmCommand}" | |||
Content="确认" | |||
FontFamily="楷体" | |||
FontSize="20" | |||
Foreground="#aa01FFFF" | |||
Template="{StaticResource ConfirmButtonTemp}" /> | |||
</Grid> | |||
<!--#endregion--> | |||
</Grid> | |||
</Border> | |||
</Popup> | |||
</Grid> | |||
<Border | |||
Grid.ColumnSpan="8" | |||
BorderBrush="{StaticResource BorderSolid}" | |||
BorderThickness="1" /> | |||
</Grid> | |||
</DataTemplate> | |||
</ItemsControl.ItemTemplate> | |||
</ItemsControl> | |||
</ScrollViewer> | |||
<!--#endregion--> | |||
</Grid> | |||
</UserControl> |
@@ -0,0 +1,44 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Diagnostics; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Windows; | |||
using System.Windows.Controls; | |||
using System.Windows.Data; | |||
using System.Windows.Documents; | |||
using System.Windows.Input; | |||
using System.Windows.Media; | |||
using System.Windows.Media.Imaging; | |||
using System.Windows.Navigation; | |||
using System.Windows.Shapes; | |||
namespace HBLConsole.View | |||
{ | |||
/// <summary> | |||
/// VariableConfig.xaml 的交互逻辑 | |||
/// </summary> | |||
public partial class VariableConfig : UserControl | |||
{ | |||
public VariableConfig() | |||
{ | |||
InitializeComponent(); | |||
this.IsVisibleChanged += VariableConfig_IsVisibleChanged; | |||
} | |||
private void VariableConfig_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e) | |||
{ | |||
var obj = (VariableConfig)sender; | |||
if (!obj.IsVisible) | |||
{ | |||
//if (DelegationNotifi.GetInstance.VariableSave != null) | |||
//{ | |||
// DelegationNotifi.GetInstance.VariableSave(); | |||
//} | |||
//DelegationNotifi.GetInstance.VariableSave = null; | |||
//DelegationNotifi.GetInstance.VarNameChanged = null; | |||
} | |||
} | |||
} | |||
} |
@@ -6,7 +6,6 @@ using System.Threading.Tasks; | |||
using Microsoft.Toolkit.Mvvm.Input; | |||
using HBLConsole.Service; | |||
using System.Threading; | |||
using HBLConsole.Business.Devices; | |||
using System.ComponentModel; | |||
using System.Runtime.CompilerServices; | |||
using HBLConsole.Communication; | |||
@@ -19,148 +18,53 @@ namespace HBLConsole.ViewModel | |||
{ | |||
public class DebugViewModel : ViewModelBase | |||
{ | |||
static bool First = false; | |||
public DebugViewModel() | |||
{ | |||
WindowName = "调试模式"; | |||
SimOrderCommand = new RelayCommand(() => | |||
{ | |||
if (IsEnableRandom) | |||
NoodleLoc = (ushort)(new Random().Next(1, 6)); | |||
else | |||
NoodleLoc = (ushort)NoodleLoc; | |||
if (BowlIsEnableRandom) | |||
BowlLoc = (ushort)(new Random().Next(10, 12)); | |||
else | |||
BowlLoc = (ushort)BowlLoc; | |||
ActionManagerment.GetInstance.Send("SimOrder", new SimOrderData() | |||
{ | |||
NoodleIsEnableRandom = IsEnableRandom, | |||
BowlLoc = BowlLoc, | |||
NoodleLoc = NoodleLoc, | |||
BowlIsEnableRandom = BowlIsEnableRandom | |||
}, new Action(() => | |||
{ | |||
BowlLoc = MORKS.GetInstance.BowlLoc; | |||
NoodleLoc = MORKS.GetInstance.NoodleLoc; | |||
})); | |||
}); | |||
}); | |||
InitCommand = new RelayCommand(() => { MORKS.GetInstance.DeviceInit(); }); | |||
if (!First) ProcessCondition(); | |||
} | |||
private void ProcessCondition() | |||
{ | |||
First = true; | |||
Type type = MORKS.GetInstance.mORKS.GetType(); | |||
//添加流程监控信息 | |||
foreach (var item in type.GetProperties()) | |||
InitCommand = new RelayCommand(() => | |||
{ | |||
if (item.CustomAttributes.Count() > 0) | |||
{ | |||
string? propertyInfo = item.GetCustomAttribute<CircuitAttribute>()?.PropertyIllustrate; | |||
string[]? Classifiactions = item.GetCustomAttribute<CircuitAttribute>()?.Classifiaction; | |||
if (Classifiactions != null) | |||
{ | |||
foreach (var itemClassifiactions in Classifiactions) | |||
{ | |||
if (ProcessData.GetInstance.Conditions.ContainsKey(itemClassifiactions)) | |||
{ | |||
if (propertyInfo != null) | |||
{ | |||
int index = Array.FindIndex(ProcessData.GetInstance.Conditions[itemClassifiactions].ToArray(), p => p.propertyIllustrate == propertyInfo); | |||
if (index >= 0) | |||
{ | |||
ProcessData.GetInstance.Conditions[itemClassifiactions].ElementAt(index).ToolTip = item.Name; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
var Conditions = ProcessData.GetInstance.Conditions; | |||
if (Conditions != null) | |||
{ | |||
foreach (var item in Conditions) | |||
{ | |||
ProcessConditions process = new ProcessConditions(); | |||
process.ProcessTitl = item.Key; | |||
foreach (var values in item.Value) | |||
{ | |||
process.Conditions.Add(new Condition() { propertyIllustrate = values.propertyIllustrate }); | |||
} | |||
processConditions.Add(process); | |||
} | |||
} | |||
//更新流程监控图 | |||
ThreadManagerment.GetInstance.StartLong(new Action(() => | |||
{ | |||
foreach (var item in type.GetProperties()) | |||
{ | |||
if (item.CustomAttributes.Count() > 0) | |||
{ | |||
string? propertyInfo = item.GetCustomAttribute<CircuitAttribute>()?.PropertyIllustrate; | |||
string[]? Classifiactions = item.GetCustomAttribute<CircuitAttribute>()?.Classifiaction; | |||
if (Classifiactions != null) | |||
{ | |||
foreach (string? Titles in Classifiactions) | |||
{ | |||
if (Titles != null && propertyInfo != null) | |||
{ | |||
bool? isNot = ProcessData.GetInstance.Conditions[Titles]?.FirstOrDefault(p => p.propertyIllustrate == propertyInfo)?.IsNot; | |||
int index = Array.FindIndex(processConditions.ToArray(), p => p.ProcessTitl == Titles); | |||
if (index >= 0) | |||
{ | |||
int PropertyIndex = Array.FindIndex(processConditions.ElementAt(index).Conditions.ToArray(), p => p.propertyIllustrate == propertyInfo); | |||
if (PropertyIndex >= 0) | |||
{ | |||
var res = type.GetProperty(item.Name)?.GetValue(MORKS.GetInstance.mORKS, null); | |||
if (res != null) | |||
{ | |||
if (res is bool blen) | |||
{ | |||
if (isNot != null) | |||
{ | |||
processConditions.ElementAt(index).Conditions.ElementAt(PropertyIndex).ConditionMet = (bool)isNot ? !blen : blen; | |||
} | |||
} | |||
else if (res is ConcurrentQueue<GVL.OrderLocInfo> OrderLocInfoS) | |||
{ | |||
processConditions.ElementAt(index).Conditions.ElementAt(PropertyIndex).ConditionMet = OrderLocInfoS.Count > 0; | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
Thread.Sleep(1000); | |||
}), "UpdateValue"); | |||
//MORKS.GetInstance.DeviceInit(); | |||
ActionManagerment.GetInstance.Send("InitCommand"); | |||
}); | |||
} | |||
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged; | |||
private static void OnStaticPropertyChanged([CallerMemberName] string PropName = "") | |||
{ | |||
StaticPropertyChanged?.Invoke(null, new PropertyChangedEventArgs(PropName)); | |||
} | |||
public RelayCommand SimOrderCommand { get; set; } | |||
public RelayCommand InitCommand { get; set; } | |||
public static int NoodleLoc { get { return _mNoodleLoc; } set { _mNoodleLoc = value; OnStaticPropertyChanged(); } } | |||
private static int _mNoodleLoc = 1; | |||
public static ushort NoodleLoc { get { return _mNoodleLoc; } set { _mNoodleLoc = value; OnStaticPropertyChanged(); } } | |||
private static ushort _mNoodleLoc = 1; | |||
public static int BowlLoc { get { return _mBowlLoc; } set { _mBowlLoc = value; OnStaticPropertyChanged(); } } | |||
private static int _mBowlLoc = 10; | |||
public static ushort BowlLoc { get { return _mBowlLoc; } set { _mBowlLoc = value; OnStaticPropertyChanged(); } } | |||
private static ushort _mBowlLoc = 10; | |||
public static bool IsEnableRandom { get { return _mIsEnableRandom; } set { _mIsEnableRandom = value; OnStaticPropertyChanged(); } } | |||
@@ -11,6 +11,7 @@ using System.Reflection; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using System.Windows; | |||
using BPA.Message.Enum; | |||
namespace HBLConsole.ViewModel | |||
{ | |||
@@ -20,41 +21,82 @@ namespace HBLConsole.ViewModel | |||
{ | |||
WindowName = "设备管理"; | |||
foreach (var item in Enum.GetNames(typeof(DeviceClientType))) | |||
{ | |||
ClientDevices.Add(item); | |||
} | |||
NewConnectCommand = new RelayCommand(() => { NewConnect(); }); | |||
SaveDeviceData(); | |||
VisibleDeviceData(); | |||
ActionManagerment.GetInstance.Register(new Func<object, object>((p) => | |||
{ | |||
if (p is DeviceManagermentResult dm) | |||
{ | |||
return Json<CommunicationPar>.Data.communicationSets.FirstOrDefault(s => s.DeviceName.ToUpper() == dm.DeviceName.ToUpper()) == null; | |||
} | |||
return false; | |||
}), "AddDeviceVerify"); | |||
ClientDeviceType = Json<SetPar>.Data.ClientDeviceType; | |||
} | |||
private void SaveDeviceData() | |||
{ | |||
ActionManagerment.GetInstance.Register(new Action(() => | |||
{ | |||
Json<CommunicationPar>.Data.communicationSets.Clear(); | |||
foreach (var item in communicationSets) | |||
{ | |||
item.RemoveAction = null; | |||
Json<CommunicationPar>.Data.communicationSets.Add(item); | |||
int index = Array.FindIndex(Json<CommunicationPar>.Data.communicationSets.ToArray(), p => p.DeviceName == item.DeviceName && p.ClientDeviceType == item.ClientDeviceType); | |||
if (index >= 0) | |||
{ | |||
Json<CommunicationPar>.Data.communicationSets.RemoveAt(index); | |||
Json<CommunicationPar>.Data.communicationSets.Add(item); | |||
} | |||
else | |||
{ | |||
Json<CommunicationPar>.Data.communicationSets.Add(item); | |||
} | |||
} | |||
Json<CommunicationPar>.Save(); | |||
}), "DataSave"); | |||
Json<CommunicationPar>.Read(); | |||
communicationSets.Clear(); | |||
foreach (var item in Json<CommunicationPar>.Data.communicationSets) | |||
{ | |||
item.RemoveAction = RemoveDevice; | |||
communicationSets.Add(item); | |||
} | |||
} | |||
ActionManagerment.GetInstance.Register(new Func<object, object>((p) => | |||
private void VisibleDeviceData() | |||
{ | |||
if (communicationSets.Count <= 0) | |||
{ | |||
if (p is DeviceManagermentResult dm) | |||
Json<CommunicationPar>.Read(); | |||
foreach (var item in Json<CommunicationPar>.Data.communicationSets) | |||
{ | |||
return communicationSets.FirstOrDefault(s => s.DeviceName == dm.DeviceName) == null; | |||
if (item.ClientDeviceType == GVL.GeneralConfig.DeviceType.ToString()) | |||
{ | |||
item.RemoveAction = RemoveDevice; | |||
communicationSets.Add(item); | |||
} | |||
} | |||
return false; | |||
}), "AddDeviceVerify"); | |||
} | |||
} | |||
public string ClientDeviceType | |||
{ | |||
get { return _mClientDeviceType; } | |||
set { _mClientDeviceType = value; OnPropertyChanged(); Json<SetPar>.Data.ClientDeviceType = value; } | |||
} | |||
private string _mClientDeviceType; | |||
public static ObservableCollection<CommunicationSet> communicationSets { get; set; } = new ObservableCollection<CommunicationSet>(); | |||
public ObservableCollection<string> ClientDevices { get; set; } = new ObservableCollection<string>(); | |||
public RelayCommand NewConnectCommand { get; set; } | |||
public RelayCommand SaveConnectSetCommand { get; set; } | |||
@@ -66,8 +108,8 @@ namespace HBLConsole.ViewModel | |||
{ | |||
DeviceManagermentSetView deviceManagermentSetView = new DeviceManagermentSetView(); | |||
var result = deviceManagermentSetView.ShowDialog(); | |||
var ResultTag = (DeviceManagermentResult)deviceManagermentSetView.Tag; | |||
if (ResultTag != null) | |||
var ResultTag = deviceManagermentSetView.Tag as DeviceManagermentResult; | |||
if (ResultTag != null && result != null) | |||
{ | |||
if ((bool)result) | |||
{ | |||
@@ -76,19 +118,21 @@ namespace HBLConsole.ViewModel | |||
{ | |||
CommunicationSet communicationObj = new CommunicationSet(); | |||
EDeviceType eDeviceType = (EDeviceType)Enum.Parse(typeof(EDeviceType), ResultTag.DeviceType); | |||
string NameSpace = "HBLConsole.Model";//Load 加载的是dll的名称,GetType获取的是全命名空间下的类 | |||
//if (Enum.TryParse(ResultTag.DeviceType, out EDataType eDeviceType)) | |||
//{ | |||
string? NameSpace = "HBLConsole.Model";//Load 加载的是dll的名称,GetType获取的是全命名空间下的类 | |||
Type type = Assembly.Load(NameSpace)?.GetType($"{NameSpace}.{ResultTag.DeviceType}"); | |||
if (type != null) | |||
{ | |||
communicationObj.Device = (IDeviceType)Activator.CreateInstance(type); | |||
communicationObj.Device = Activator.CreateInstance(type) as IDeviceType; | |||
} | |||
communicationObj.DeviceName = $"{ResultTag.DeviceName}【{eDeviceType}】"; | |||
communicationObj.deviceType = eDeviceType; | |||
communicationObj.RemoveAction = RemoveDevice; | |||
communicationObj.ClientDeviceType = GVL.GeneralConfig.DeviceType.ToString(); | |||
communicationSets.Add(communicationObj); | |||
//} | |||
} | |||
} | |||
} | |||
@@ -1,5 +1,5 @@ | |||
using HBLConsole.Attributes; | |||
using HBLConsole.Business.Devices; | |||
//using HBLConsole.Business.Devices; | |||
using HBLConsole.Model; | |||
using HBLConsole.Service; | |||
using System; | |||
@@ -10,21 +10,39 @@ using System.Reflection; | |||
using System.Text; | |||
using System.Threading; | |||
using System.Threading.Tasks; | |||
using HBLConsole.Factory; | |||
using HBLConsole.Interface; | |||
namespace HBLConsole.ViewModel | |||
{ | |||
public class ProcessMonitoringViewModel : ViewModelBase | |||
{ | |||
static Type type; | |||
static IGvl InterfaceGVL; | |||
public ProcessMonitoringViewModel() | |||
{ | |||
WindowName = "流程监控"; | |||
ProcessCondition(); | |||
if (type == null) | |||
{ | |||
InterfaceGVL = SimpleFactory.GetInstance.GetGvl(); | |||
type = InterfaceGVL?.GetType(); | |||
if (ProcessData.GetInstance.Conditions?.Count <= 0) | |||
{ | |||
if (InterfaceGVL != null && type != null) | |||
{ | |||
GetProcessInfo(); | |||
UpdateProcess(); | |||
} | |||
} | |||
} | |||
} | |||
private void ProcessCondition() | |||
/// <summary> | |||
/// 获取流程信息 | |||
/// </summary> | |||
private void GetProcessInfo() | |||
{ | |||
Type type = MORKS.GetInstance.mORKS.GetType(); | |||
//添加流程监控信息 | |||
foreach (var item in type.GetProperties()) | |||
{ | |||
@@ -66,9 +84,13 @@ namespace HBLConsole.ViewModel | |||
processConditions.Add(process); | |||
} | |||
} | |||
} | |||
//更新流程监控图 | |||
/// <summary> | |||
/// 更新流程 | |||
/// </summary> | |||
private void UpdateProcess() | |||
{ | |||
ThreadManagerment.GetInstance.StartLong(new Action(() => | |||
{ | |||
foreach (var item in type.GetProperties()) | |||
@@ -91,7 +113,7 @@ namespace HBLConsole.ViewModel | |||
int PropertyIndex = Array.FindIndex(processConditions.ElementAt(index).Conditions.ToArray(), p => p.propertyIllustrate == propertyInfo); | |||
if (PropertyIndex >= 0) | |||
{ | |||
var res = type.GetProperty(item.Name)?.GetValue(MORKS.GetInstance.mORKS, null); | |||
var res = type.GetProperty(item.Name)?.GetValue(InterfaceGVL, null); | |||
if (res != null) | |||
{ | |||
if (res is bool blen) | |||
@@ -100,9 +122,8 @@ namespace HBLConsole.ViewModel | |||
{ | |||
processConditions.ElementAt(index).Conditions.ElementAt(PropertyIndex).ConditionMet = (bool)isNot ? !blen : blen; | |||
} | |||
} | |||
else if (res is ConcurrentQueue<GVL.OrderLocInfo> OrderLocInfoS) | |||
else if (res is ConcurrentQueue<OrderLocInfo> OrderLocInfoS) | |||
{ | |||
processConditions.ElementAt(index).Conditions.ElementAt(PropertyIndex).ConditionMet = OrderLocInfoS.Count > 0; | |||
} | |||
@@ -0,0 +1,116 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Collections.ObjectModel; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
using Microsoft.Toolkit.Mvvm.ComponentModel; | |||
using Microsoft.Toolkit.Mvvm.Input; | |||
using System.Diagnostics; | |||
using Microsoft.EntityFrameworkCore; | |||
using HBLConsole.Model; | |||
using HBLConsole.Service; | |||
namespace HBLConsole.ViewModel | |||
{ | |||
internal class VariableConfig : ObservableObject | |||
{ | |||
public VariableConfig() | |||
{ | |||
//DelegationNotifi.GetInstance.VariableSave = new Action(() => { SaveDataAsync(); }); | |||
//DelegationNotifi.GetInstance.VarNameChanged = new Action<int>((p) => | |||
//{ | |||
// if ((p - 1) >= 0) | |||
// { | |||
// if (varialeInfos?.Count >= p) | |||
// { | |||
// if (varialeInfos.ElementAt(p - 1).VarName != null) | |||
// { | |||
// if (varialeInfos.ElementAt(p - 1).VarName.Length > 0) | |||
// { | |||
// if (varialeInfos.Count == p) AddRow(); | |||
// } | |||
// } | |||
// } | |||
// } | |||
//}); | |||
GetLocalDataAsync(); | |||
} | |||
/// <summary> | |||
/// 异步获取本地数据 | |||
/// </summary> | |||
private Task<bool> GetLocalDataAsync() | |||
{ | |||
//SqlHelper<VariableInfo>.GetInstance.Database.EnsureCreated(); | |||
////多表查询 | |||
var DataList = SqlHelper<VariableInfo>.GetInstance.DbObj.ToList(); | |||
App.Current.Dispatcher.Invoke(new Action(() => { varialeInfos.Clear(); })); | |||
foreach (var item in DataList) | |||
{ | |||
PropBindInfo propBindInfo = new PropBindInfo(); | |||
propBindInfo.ID = item.ID; | |||
propBindInfo.VarName = item.VarName; | |||
propBindInfo.Address = item.Address; | |||
propBindInfo.DataType = item.DataType; | |||
propBindInfo.IsEnableAlarm = item.IsEnableAlarm; | |||
propBindInfo.CurrentValue = item.CurrentValue; | |||
var result = item.AlarmSetProp.AnalogAlarmModels.Where(p => p.AlarmSetId == item.ID).ToList(); | |||
result = result?.OrderBy(p => p.SortTag).ToList(); | |||
propBindInfo.AlarmSetProp.AnalogAlarmModels.Clear(); | |||
result?.ForEach(p => { propBindInfo.AlarmSetProp.AnalogAlarmModels.Add(p); }); | |||
propBindInfo.AlarmSetProp.DiscreteAlarmInfoSet = item.AlarmSetProp.DiscreteAlarmInfoSet; | |||
App.Current?.Dispatcher.Invoke(new Action(() => { varialeInfos.Add(propBindInfo); })); | |||
} | |||
if (varialeInfos.Count <= 0) AddRow(); | |||
return Task.FromResult(true); | |||
} | |||
/// <summary> | |||
/// 异步保存数据 | |||
/// </summary> | |||
/// <returns></returns> | |||
private Task<bool> SaveDataAsync() | |||
{ | |||
SqlHelper<VariableInfo>.GetInstance.DbObj.RemoveRange(SqlHelper<VariableInfo>.GetInstance.DbObj.ToArray()); | |||
foreach (var item in varialeInfos) | |||
{ | |||
SqlHelper<VariableInfo>.GetInstance.Add(new VariableInfo() | |||
{ | |||
ID = item.ID, | |||
VarName = item.VarName, | |||
Address = item.Address, | |||
DataType = item.DataType, | |||
IsEnableAlarm = item.IsEnableAlarm, | |||
CurrentValue = item.CurrentValue, | |||
AlarmSetProp = item.AlarmSetProp, | |||
}); | |||
} | |||
SqlHelper<VariableInfo>.GetInstance.Save(); | |||
return Task.FromResult(true); | |||
} | |||
/// <summary> | |||
/// 添加行 | |||
/// </summary> | |||
private void AddRow() | |||
{ | |||
App.Current.Dispatcher.Invoke(new Action(() => | |||
{ | |||
varialeInfos.Add(new PropBindInfo() | |||
{ | |||
ID = varialeInfos.Count + 1, | |||
}); | |||
})); | |||
} | |||
/// <summary> | |||
/// 变量信息 | |||
/// </summary> | |||
public ObservableCollection<PropBindInfo> varialeInfos { get; set; } = new ObservableCollection<PropBindInfo>(); | |||
} | |||
} |