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

201 lines
7.8 KiB
C#
Raw Normal View History

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()
{
}
}
}