201 lines
7.8 KiB
C#
201 lines
7.8 KiB
C#
using Cowain.Bake.BLL;
|
||
using Cowain.Bake.Common;
|
||
using Cowain.Bake.Common.Core;
|
||
using Cowain.Bake.Common.Enums;
|
||
using Cowain.Bake.Common.Interface;
|
||
using Cowain.Bake.Communication.Interface;
|
||
using Cowain.Bake.Model.Models;
|
||
using Newtonsoft.Json;
|
||
using Opc.Ua;
|
||
using System;
|
||
using System.Collections.Concurrent;
|
||
using System.Linq;
|
||
using Unity;
|
||
|
||
namespace Cowain.Bake.Main.Station
|
||
{
|
||
public class UpdateStation : IServerManager
|
||
{
|
||
readonly ConcurrentDictionary<int, bool[]> _stovePalletSignal;
|
||
public string Name { get; set; }
|
||
|
||
public IUnityContainer _unityContainer { get; set; }
|
||
|
||
|
||
public UpdateStation(IUnityContainer unityContainer)
|
||
{
|
||
_unityContainer = unityContainer;
|
||
_stovePalletSignal = new ConcurrentDictionary<int, bool[]>();
|
||
}
|
||
bool IsConnectPLC(IPLCDevice PLC)
|
||
{
|
||
if (null == PLC || !PLC.IsConnect)
|
||
{
|
||
LogHelper.Instance.GetCurrentClassError($"连接PLC失败:{PLC.Name},PLC为空!");
|
||
return false;
|
||
}
|
||
return true;
|
||
}
|
||
|
||
//LifeCycle PLC请求命令:0=无意义;10=无托盘;20=有托盘
|
||
public int UpdateCavityStatus(DataValue data, Variable node)
|
||
{
|
||
Int16 signalValue = 0;
|
||
Int16 result = (Int16)EResult.OK; //1=OK,2=重新上传
|
||
dynamic d = JsonConvert.DeserializeObject<dynamic>(node.TrigJson); //生命周期
|
||
dynamic reply = JsonConvert.DeserializeObject<dynamic>(node.Json); //反馈收到PLC的周期信号,反馈PLC的命令,0也要反馈,1=OK,2=重新上传
|
||
|
||
var config = _unityContainer.Resolve<DeviceConfigService>().GetConfig(node.StationId);
|
||
IPLCDevice PLC = _unityContainer.Resolve<IPLCDevice>(config.Name);
|
||
if (!IsConnectPLC(PLC)) return 0;
|
||
|
||
var countCavitySignal = PLC.GetValue<System.Int16>((string)d.CountCavitySignal, node.StationId, node.Number);
|
||
if (!countCavitySignal.IsSuccess)
|
||
{
|
||
result = (Int16)EResult.NG;
|
||
LogHelper.Instance.Error($"读取腔体的信号计数失败!原因:{countCavitySignal.Message}");
|
||
}
|
||
|
||
if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Int16)
|
||
{
|
||
signalValue = (System.Int16)data.WrappedValue.Value;
|
||
}
|
||
else
|
||
{
|
||
result = (Int16)EResult.NG;
|
||
LogHelper.Instance.Warn($"没有找到夹具信号这个数据类型,节点名为{node.VarDesc}");
|
||
}
|
||
|
||
var writeResult = PLC.Write<Int16>(reply.CountCavitySignal, countCavitySignal.Content);
|
||
if (!writeResult.IsSuccess)
|
||
{
|
||
LogHelper.Instance.GetCurrentClassWarn($"写腔体的信号计数失败,地址:{reply.CountCavitySignal},值:{countCavitySignal.Content},{writeResult.Message}");
|
||
}
|
||
|
||
writeResult = PLC.Write<Int16>(reply.SignalValue, signalValue);
|
||
if (!writeResult.IsSuccess)
|
||
{
|
||
LogHelper.Instance.GetCurrentClassWarn($"写腔体的信号失败,地址:{reply.SignalValue},值:{signalValue},{writeResult.Message}");
|
||
}
|
||
|
||
writeResult = PLC.Write<Int16>(reply.CavitySignalResult, result);
|
||
if (!writeResult.IsSuccess)
|
||
{
|
||
LogHelper.Instance.GetCurrentClassWarn($"写回复腔体的信号失败,地址:{reply.CavitySignalResult},值:{result},{writeResult.Message}");
|
||
}
|
||
|
||
return _unityContainer.Resolve<CavityInfoService>().UpdateCavitySignal(node.StationId, node.Number, signalValue);
|
||
}
|
||
|
||
public int UpdateDoorStatus(DataValue data, Variable node)
|
||
{
|
||
dynamic d = JsonConvert.DeserializeObject<dynamic>(node.TrigJson);
|
||
string layer = d.Layer;
|
||
bool status = false;
|
||
|
||
if (string.IsNullOrEmpty(layer))
|
||
{
|
||
LogHelper.Instance.Warn($"触发夹具到位信号,但获取相关信息失败{node.TrigJson}");
|
||
return 0;
|
||
}
|
||
|
||
if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Boolean)
|
||
{
|
||
status = (bool)data.WrappedValue.Value;
|
||
}
|
||
else
|
||
{
|
||
LogHelper.Instance.Warn($"没有找到开/关门这个数据类型,节点名为{node.VarDesc}");
|
||
return 0;
|
||
}
|
||
|
||
if (!status)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
if (node.ParamName == EStoveSignal.OpenDoorPlace.ToString())
|
||
{
|
||
status = true;
|
||
}
|
||
|
||
return _unityContainer.Resolve<CavityInfoService>().UpdateDoorStatus(node.StationId, int.Parse(layer), status);
|
||
}
|
||
|
||
public int UpdateLoadStatus(DataValue data, Variable node)
|
||
{
|
||
dynamic d = JsonConvert.DeserializeObject<dynamic>(node.TrigJson);
|
||
string layer = d.Layer;
|
||
string number = d.Number;
|
||
bool[] status = null;
|
||
|
||
if (data.WrappedValue.TypeInfo.ValueRank == 1) //数组,炉子夹具传感器信号
|
||
{
|
||
if (data.WrappedValue.TypeInfo.BuiltInType == Opc.Ua.BuiltInType.Boolean)
|
||
{
|
||
status = (bool[])data.WrappedValue.Value;
|
||
}
|
||
|
||
if (_stovePalletSignal.TryGetValue(node.StationId, out bool[] oldValue)) //有
|
||
{
|
||
if (oldValue.Count() != status.Count())
|
||
{
|
||
LogHelper.Instance.Error($"烤箱到位信号老值与新值长度不匹配,工站:{node.StationId},desc:{string.Join(",", status)}");
|
||
return 0;
|
||
}
|
||
|
||
_stovePalletSignal[node.StationId] = status;
|
||
var diffs = status.Zip(oldValue, (a, b) => a != b).Select((b, i) => new { Value = b, Index = i }).Where(x => x.Value);
|
||
|
||
foreach (var item in diffs)
|
||
{
|
||
if (0 == item.Index)
|
||
{
|
||
continue; //第一个不用
|
||
}
|
||
|
||
int result = _unityContainer.Resolve<CavityInfoService>().UpdateLoadStatus(node.StationId, item.Index, 1, status[item.Index]);
|
||
if (0 != result)
|
||
{
|
||
LogHelper.Instance.Warn($"修改状态数据失败,StationId:{node.StationId},layer:{item.Index},{status[item.Index]}");
|
||
}
|
||
}
|
||
}
|
||
else //重启时,更新所有信号
|
||
{
|
||
|
||
|
||
_stovePalletSignal[node.StationId] = status;
|
||
for (int i = 1; i <= Global.STOVE_LAYERS; ++i) //上位机启动
|
||
{
|
||
int result = _unityContainer.Resolve<CavityInfoService>().UpdateLoadStatus(node.StationId, i, 1, status[i]);
|
||
if (0 != result)
|
||
{
|
||
LogHelper.Instance.Warn($"修改状态数据失败,StationId:{node.StationId},layer:{i},{status[i]}");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else //上下料和人工夹具平台
|
||
{
|
||
var value = (bool)data.WrappedValue.Value;
|
||
int result = _unityContainer.Resolve<CavityInfoService>().UpdateLoadStatus(node.StationId, int.Parse(layer), int.Parse(number), value);
|
||
if (0 != result)
|
||
{
|
||
LogHelper.Instance.Warn($"修改状态数据失败,StationId:{node.StationId},layer:{layer},{number},{value}");
|
||
}
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
public void Start()
|
||
{
|
||
|
||
}
|
||
public void Stop()
|
||
{
|
||
|
||
}
|
||
}
|
||
}
|