using Cowain.Bake.Common; using Cowain.Bake.Common.Core; using Cowain.Bake.Common.Interface; using Cowain.Bake.Communication.PLC; using Cowain.Bake.Main.ViewModels; using Cowain.Bake.Model.Models; using Newtonsoft.Json; using Opc.Ua; using System; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; using Unity; namespace Cowain.Bake.Main.Station { public class TrigStation : ITrigService { IUnityContainer _unityContainer; readonly CancellationTokenSource cts = new CancellationTokenSource(); public TrigStation(IUnityContainer unityContainer) { _unityContainer = unityContainer; //怕消息先后导致异常,所以只能单个去 //for (int i = 0; i < 3; i++) //还有心跳,就放开这个功能 { Start(); } } public void Start() { Task.Run( () => { while (true) { if (Global.AppExit) { return; } BlockData item = _unityContainer.Resolve().MsgBlock.Take(); int msgCount = _unityContainer.Resolve().MsgBlock.Count; if ("Heart" == item.Node.ParamName) //消息队列太多,就删除心跳 { if (msgCount >= 5) { LogHelper.Instance.Error($"----------消费者消息数:{msgCount}"); continue; } Task.Run(() => ExecuteHeartTask(item.Data, item.Node)); } else { RecvTrigInfo(item.Data, item.Node); } } }); } void ExecuteHeartTask(DataValue data, Variable node) { RecvTrigInfo(data, node); } //多线程处理 public void RecvTrigInfo(DataValue data, Variable node) { int value = 0; dynamic d = JsonConvert.DeserializeObject(node.TrigJson); string service = d.Service; string func = d.Func; string trigValue = d.TrigValue; string param = d.Param; //方法的参数,如果是扫码,则是扫码的编号 MethodInfo mi = null; if (string.IsNullOrEmpty(service) || string.IsNullOrEmpty(func)) { LogHelper.Instance.Error("解析触发信号信息失败!解析内容:" + node.TrigJson); return; } Type type = Type.GetType(MyPath.SIGNAL_TRIGGER + service); if (!string.IsNullOrEmpty(trigValue)) { value = GetTrigValue(data); if (data.Value.GetType().IsArray) { if (value == 0) //节点的值跟所触发的信号相同(6098,扫码是数组) { return; } } else { if (value != int.Parse(trigValue)) //节点值 { return; } } //LogHelper.Instance.Info($"5--------------信号,线程ID:{System.Threading.Thread.CurrentThread.ManagedThreadId},{node.VarDesc}:{param},func:{func},value:{value},{node.Json}"); //执行到这,信号都会丢, _unityContainer.Resolve().SetEvent("开始:" + node.VarDesc); mi = this.GetType().GetMethod(ReflexFun.TRIG_REPLY).MakeGenericMethod(new Type[] { type }); //回复信息; mi.Invoke(this, new object[] { func, value, param, node }); //_unityContainer.Resolve().SetEvent("结束0:" + node.VarDesc); } else { mi = this.GetType().GetMethod(ReflexFun.TRIG_INSTANCE).MakeGenericMethod(new Type[] { type }); //夹具信号,报警这些; mi.Invoke(this, new object[] { func, data, node }); } } public void TrigInstance(string func, DataValue data, Variable node) { //取得实例 var instnce = _unityContainer.Resolve(); Type t = instnce.GetType(); //取得方法 MethodInfo mi = t.GetMethod(func); //调用方法 mi.Invoke(instnce, new object[] { data, node }); } public void TrigReply(string func, int curValue, string param, Variable node) { //取得实例 var instnce = _unityContainer.Resolve(); //上下料实例 Type t = instnce.GetType(); //取得方法 MethodInfo mi = t.GetMethod(func); //调用方法 mi.Invoke(instnce, new object[] { curValue, param, node }); } private int GetTrigValue(DataValue data) { int value = 0; if (data.WrappedValue.TypeInfo.ValueRank == 1) //数组 { if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Boolean) //下料扫码 { bool[] values = (bool[])data.Value; for (int i = 0; i < values.Count(); i++) { if (values[i]) { double temp = Math.Pow(2, i); //o value += (int)temp; } } } else //上料扫码 { Int16[] values = (Int16[])data.Value; for (int i = 0; i < values.Count(); i++) { double temp = values[i] * Math.Pow(2, i); //ok value += (int)temp; } LogHelper.Instance.Fatal($"接收扫码信号:{string.Join(",", values)},{value}"); } } else { if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.UInt16) { value = (UInt16)data.WrappedValue.Value; } else if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Int16) { value = (Int16)data.WrappedValue.Value; } else if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Int32) { value = (Int32)data.WrappedValue.Value; } else if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.UInt32) { value = (int)data.WrappedValue.Value; } else if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Boolean) { value = ((bool)data.WrappedValue.Value) ? 1 : 0; } else { value = (int)data.WrappedValue.Value; } } return value; } } }