Sic.Framework-Nanjing-Baishi/MECF.Framework.RT.Equipment.../Devices/SiemensIoProvider.cs

444 lines
16 KiB
C#
Raw 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 Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.Util;
using MECF.Framework.Common.IOCore;
using MECF.Framework.Common.PLC;
using MECF.Framework.RT.Core.IoProviders;
using MECF.Framework.RT.Core.IoProviders.Siemens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace Aitex.Core.RT.Device.Devices
{
public partial class SiemensIoProvider : IoProvider
{
private string _diVariable;
private string _doVariable;
private string _aiVariable;
private string _aoVariable;
private ushort diLength;
private ushort doLength;
private ushort aiLength;
private ushort aoLength;
private IAdsPlc _ads;
private static object _locker = new object();
private R_TRIG _trigConnected = new R_TRIG();
protected override void SetParameter(XmlElement nodeParameter)
{
_diVariable = nodeParameter.GetAttribute("diVariable");
_doVariable = nodeParameter.GetAttribute("doVariable");
_aiVariable = nodeParameter.GetAttribute("aiVariable");
_aoVariable = nodeParameter.GetAttribute("aoVariable");
ushort.TryParse(nodeParameter.GetAttribute("diLength"), out diLength);
ushort.TryParse(nodeParameter.GetAttribute("doLength"), out doLength);
ushort.TryParse(nodeParameter.GetAttribute("aiLength"), out aiLength);
ushort.TryParse(nodeParameter.GetAttribute("aoLength"), out aoLength);
}
private bool MonitorAdsConnection()
{
//if (_SiemensClient == null)
//{
// _SiemensClient = DEVICE.GetDevice<PMModule>(Module + "." + Module)?.Siemens;
//}
//if (_SiemensClient != null) return _SiemensClient.IsTrue;
//return false;
if (_ads == null)
{
_ads = DEVICE.GetOptionDevice($"{Module}.MainPLC", typeof(SicAds)) as IAdsPlc;
}
return _ads != null && _ads.CheckIsConnected();
}
//public bool IsCommunicationError
//{
// get { return _ads.IsCommunicationError; }
//}
protected override void Close()
{
}
protected override void Open()
{
}
public override void Initialize(string module, string name, List<IoBlockItem> lstBuffers, IIoBuffer buffer, XmlElement nodeParameter, string ioMappingPathFile, string ioModule)
{
base.Initialize(module, name, lstBuffers, buffer, nodeParameter, ioMappingPathFile, ioModule);
}
protected override bool OnTimer()
{
_trigConnected.CLK = MonitorAdsConnection();
if (!_trigConnected.M)
return true;
lock (_locker)
{
// PLC数据以32位二级制存储软件读取的值与DINT相同
// 如果是DINT类型数据直接使用无需转换
// 如果是REAL类型数据先使用BitConverter.GetBytes获取有4个元素的字节数组再使用BitConverter.ToSingle得到float类型值
// 如果是DWORD类型数据先使用BitConverter.GetBytes获取有4个元素的字节数组再进行位运算得到每位的值
//int[] input = ReadInput();
//Console.WriteLine(input[0]);
//byte[] byteArr = BitConverter.GetBytes(input[0]);
//float fValve = BitConverter.ToSingle(byteArr, 0);
byte[] DI = ReadDIn();
//if (IsCommunicationError) return CommunicationError();
if (DI != null)
{
bool[] diBuffer = ParseDI(DI);
if (diBuffer != null)
{
_buffer.SetDiBuffer(_source, 0, diBuffer);
}
}
byte[] DO = ReadDOut();
//if (IsCommunicationError) return CommunicationError();
if (DO != null)
{
bool[] doBuffer = ParseDO(DO);
if (doBuffer != null)
{
_buffer.SetDoBuffer(_source, 0, doBuffer);
}
}
byte[] AI = ReadAIn();
//if (IsCommunicationError) return CommunicationError();
if (AI != null)
{
float[] aiBuffer = ParseAI(AI);
if (aiBuffer != null)
{
_buffer.SetAiBufferFloat(_source, 0, aiBuffer);
}
}
byte[] AO = ReadAOut();
//if (IsCommunicationError) return CommunicationError();
if (AO != null)
{
float[] aoBuffer = ParseAO(AO);
if (aoBuffer != null)
{
_buffer.SetAoBufferFloat(_source, 0, aoBuffer);
}
}
}
return true;
}
private bool CommunicationError()
{
//_buffer.SetDiBuffer(_source, 0, new bool[1000]);
//_buffer.SetDoBuffer(_source, 0, new bool[1000]);
//_buffer.SetAiBufferFloat(_source, 0, new float[1000]);
//_buffer.SetAoBufferFloat(_source, 0, new float[1000]);
return true;
}
protected byte[] ReadDIn()
{
if (!_trigConnected.M)
return null;
if (_ads.BulkReadRenderResult(_diVariable, diLength, out byte[] data))
return data;
return null;
}
private byte[] ReadDOut()
{
if (!_trigConnected.M)
return null;
if (_ads.BulkReadRenderResult(_doVariable, doLength, out byte[] data))
return (byte[])data;
return null;
}
protected byte[] ReadAIn()
{
if (!_trigConnected.M)
return null;
if (_ads.BulkReadRenderResult(_aiVariable, aiLength, out byte[] data))
return data;
return null;
}
private byte[] ReadAOut()
{
if (!_trigConnected.M)
return null;
if (_ads.BulkReadRenderResult(_aoVariable, aoLength, out byte[] data))
return (byte[])data;
return null;
}
private bool[] ParseDI(byte[] inputValue)
{
List<DIAccessor> diList = Singleton<IoManager>.Instance.GetDIList($"{Module}.io");
bool[] result = new bool[1000];
foreach (var diAccessor in diList)
{
var addr = diAccessor.Addr;
int index = int.Parse(addr);
int Offset = index % 8;
int val = index % 8 == 0 ? index / 8 : (index - index % 8) / 8;
result[diAccessor.Index] = ((inputValue[val] >> Offset) & 0x1) == 1;
}
return result;
}
private bool[] ParseDO(byte[] outputValue)
{
//Addr="OUTPUT[0].4"
List<DOAccessor> doList = Singleton<IoManager>.Instance.GetDOList($"{Module}.io");
bool[] result = new bool[1000];
foreach (var doAccessor in doList)
{
var addr = doAccessor.Addr;
int index = int.Parse(addr);
int Offset = index % 8;
int val = index % 8 == 0 ? index / 8 : (index - index % 8) / 8;
result[doAccessor.Index] = ((outputValue[val] >> Offset) & 0x1) == 1;
}
return result;
}
private float[] ParseAI(byte[] inputValue)
{
List<AIAccessor> aiList = Singleton<IoManager>.Instance.GetAIList($"{Module}.io");
float[] result = new float[500];
foreach (var aiAccessor in aiList)
{
var addr = aiAccessor.Addr;
int index = int.Parse(addr);
float valve = 0.0f;
if (index <= 71 || index >= 108 && index <= 117 || index >= 181 || index == 119 || index == 123 || index == 124 || index == 125)
{
if (index >= 181)
index += 181; // 跳过181个AO
valve = BitConverter.ToSingle(new byte[] { inputValue[index * 4 + 3], inputValue[index * 4 + 2], inputValue[index * 4 + 1], inputValue[index * 4] }, 0);
}
else if (index >= 72 && index <= 103)
{
valve = BitConverter.ToSingle(new byte[] { inputValue[index * 4 + 3], inputValue[index * 4 + 2], inputValue[index * 4 + 1], inputValue[index * 4] }, 0);
}
else if (index >= 104 && index <= 107 || index >= 118 && index <= 128)
{
valve = BitConverter.ToUInt32(new byte[] { inputValue[index * 4 + 3], inputValue[index * 4 + 2], inputValue[index * 4 + 1], inputValue[index * 4] }, 0);
}
else if (index == 129)
{
valve = BitConverter.ToSingle(new byte[] { inputValue[index * 4 + 3], inputValue[index * 4 + 2], inputValue[index * 4 + 1], inputValue[index * 4] }, 0);
}
else if (index >= 130 && index <= 180)
{
valve = BitConverter.ToInt32(new byte[] { inputValue[index * 4 + 3], inputValue[index * 4 + 2], inputValue[index * 4 + 1], inputValue[index * 4] }, 0);
}
result[aiAccessor.Index] = valve;
}
return result;
}
private float[] ParseAO(byte[] outputValue)
{
//Addr="OUTPUT[30]"
List<AOAccessor> aoList = Singleton<IoManager>.Instance.GetAOList($"{Module}.io");
float[] result = new float[500];
foreach (var aoAccessor in aoList)
{
var addr = aoAccessor.Addr;
int index = int.Parse(addr);
float valve = 0.0f;
if (index >= 92 && index <= 103)
{
valve = BitConverter.ToSingle(new byte[] { outputValue[index * 4 + 3], outputValue[index * 4 + 2], outputValue[index * 4 + 1], outputValue[index * 4] }, 0);
}
else if (index >= 104 && index <= 107)
{
valve = BitConverter.ToSingle(new byte[] { outputValue[index * 4 + 3], outputValue[index * 4 + 2], outputValue[index * 4 + 1], outputValue[index * 4] }, 0);
}
else if (index <= 117 || index >= 181 || index == 129 || index == 122 || index == 123 || index == 124 || index == 125)
{
if (index >= 181)
index += 100; // 跳过100个AI
valve = BitConverter.ToSingle(new byte[] { outputValue[index * 4 + 3], outputValue[index * 4 + 2], outputValue[index * 4 + 1], outputValue[index * 4] }, 0);
}
else if (index >= 118 && index <= 128 && index != 119)
{
valve = BitConverter.ToUInt32(new byte[] { outputValue[index * 4 + 3], outputValue[index * 4 + 2], outputValue[index * 4 + 1], outputValue[index * 4] }, 0);
}
else if (index >= 130 && index <= 180)
{
valve = BitConverter.ToInt32(new byte[] { outputValue[index * 4 + 3], outputValue[index * 4 + 2], outputValue[index * 4 + 1], outputValue[index * 4] }, 0);
}
result[aoAccessor.Index] = valve;
}
return result;
}
protected override short[] ReadAi(int offset, int size)
{
throw new NotImplementedException();
}
protected override bool[] ReadDi(int offset, int size)
{
throw new NotImplementedException();
}
protected override void WriteAo(int offset, short[] buffer)
{
throw new NotImplementedException();
}
protected override void ReadDo(int offset, bool[] buffer)
{
throw new NotImplementedException();
}
protected override short[] ReadAo(int offset, int size)
{
throw new NotImplementedException();
}
protected override void WriteDo(int offset, bool[] buffer)
{
throw new NotImplementedException();
}
public override bool SetValue(AOAccessor aoItem, short value)
{
if (!_trigConnected.M)
return false;
//....
return true;
}
public override bool SetValueFloat(AOAccessor aoItem, float value)
{
if (!_trigConnected.M)
return false;
//// 获取下标转换成Byte数组然后写下去
var addr = aoItem.Addr;
int index = int.Parse(addr);
int offset = 0;
if (index >= 181)
offset = 100; // 跳过100个AI
string address = _aoVariable.Substring(0, 9) + (int.Parse(_aoVariable.Substring(9, 3)) + (index + offset) * 4);
byte[] data = new byte[4];
if (index >= 92 && index <= 103)
{
data = BitConverter.GetBytes(value);
}
else if (index <= 117 || index >= 181 || index == 129 || index == 119 || index == 122 || index == 123 || index == 124 || index == 125)
{
data = BitConverter.GetBytes(value);
}
else if (index >= 118 && index <= 128)
{
data = BitConverter.GetBytes((uint)value);
}
else if (index >= 130 && index <= 180)
{
data = BitConverter.GetBytes((int)value);
}
Array.Reverse(data);
return _ads.BulkWriteByteRenderResult(address, data);
}
public override bool SetValue(DOAccessor doItem, bool value)
{
if (!_trigConnected.M)
{
return false;
}
if (!IO.CanSetDO(doItem.Name, value, out string reason))
{
LOG.Write(reason);
return false;
}
lock (_locker)
{
////获取单个DWORD数据修改其中一位然后整个Byte写下去
var addr = doItem.Addr;
int add = int.Parse(addr);
int indexByte = add % 8;
int index = add % 8 == 0 ? add / 8 : (add - add % 8) / 8;
var val = 1 << indexByte;
byte[] output = ReadDOut();
if (output == null)
{
LOG.Write("ReadDOut = null , in SetValue()");
return false;
}
output[index] = value
? Convert.ToByte(Convert.ToUInt16(output[index]) | val)
: Convert.ToByte((Convert.ToUInt16(output[index]) & ~val));
string[] stringSeparators = new string[] { "DBB" };
string[] result = _doVariable.Split(stringSeparators, StringSplitOptions.None);
int.TryParse(result[1], out int startIndex);
int finalIndex = startIndex + index;
string address = $"{result[0]}DBB{finalIndex}";
byte[] data = new byte[] { output[index] };
return _ads.BulkWriteByteRenderResult(address, data);
}
}
}
}