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

201 lines
7.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()
{
}
}
}