Files
6098/Cowain.Bake.Main/Station/TrigStation.cs

226 lines
7.9 KiB
C#

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<PLCBlockingCollection>().MsgBlock.Take();
int msgCount = _unityContainer.Resolve<PLCBlockingCollection>().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<dynamic>(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<BasicInfoViewModel>().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<BasicInfoViewModel>().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<T>(string func, DataValue data, Variable node)
{
//取得实例
var instnce = _unityContainer.Resolve<T>();
Type t = instnce.GetType();
//取得方法
MethodInfo mi = t.GetMethod(func);
//调用方法
mi.Invoke(instnce, new object[]
{
data,
node
});
}
public void TrigReply<T>(string func, int curValue, string param, Variable node)
{
//取得实例
var instnce = _unityContainer.Resolve<T>(); //上下料实例
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;
}
}
}