Sic08/Modules/Mainframe/Devices/SiemensIoProvider.cs

370 lines
12 KiB
C#
Raw Normal View History

2023-04-13 15:35:13 +08:00
using System;
using System.Xml;
using Aitex.Core.RT.Device;
2023-03-03 15:42:13 +08:00
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;
2023-04-13 15:35:13 +08:00
namespace SicModules.Devices
2023-03-03 15:42:13 +08:00
{
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()
{
}
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);
var diData = ReadDIn();
2023-03-03 15:42:13 +08:00
//if (IsCommunicationError) return CommunicationError();
if (diData != null)
2023-03-03 15:42:13 +08:00
{
var diBuffer = ParseDI(diData);
2023-03-03 15:42:13 +08:00
if (diBuffer != null)
{
_buffer.SetDiBuffer(_source, 0, diBuffer);
}
}
var doData = ReadDOut();
2023-03-03 15:42:13 +08:00
//if (IsCommunicationError) return CommunicationError();
if (doData != null)
2023-03-03 15:42:13 +08:00
{
var doBuffer = ParseDO(doData);
2023-03-03 15:42:13 +08:00
if (doBuffer != null)
{
_buffer.SetDoBuffer(_source, 0, doBuffer);
}
}
var aiData = ReadAIn();
2023-03-03 15:42:13 +08:00
//if (IsCommunicationError) return CommunicationError();
if (aiData != null)
2023-03-03 15:42:13 +08:00
{
var aiBuffer = ParseAI(aiData);
2023-03-03 15:42:13 +08:00
if (aiBuffer != null)
{
_buffer.SetAiBuffer(_source, 0, aiBuffer);
2023-03-03 15:42:13 +08:00
}
}
var aoData = ReadAOut();
2023-03-03 15:42:13 +08:00
//if (IsCommunicationError) return CommunicationError();
if (aoData != null)
2023-03-03 15:42:13 +08:00
{
var aoBuffer = ParseAO(aoData);
2023-03-03 15:42:13 +08:00
if (aoBuffer != null)
{
_buffer.SetAoBuffer(_source, 0, aoBuffer);
2023-03-03 15:42:13 +08:00
}
}
}
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[500]);
//_buffer.SetAoBufferFloat(_source, 0, new float[500]);
return true;
}
protected byte[] ReadDIn()
{
if (!_trigConnected.M)
return null;
if (_ads.BulkReadRenderResult(_diVariable, diLength, out var data))
2023-03-03 15:42:13 +08:00
return data;
return null;
}
private byte[] ReadDOut()
{
if (!_trigConnected.M)
return null;
if (_ads.BulkReadRenderResult(_doVariable, doLength, out var data))
2023-03-03 15:42:13 +08:00
return (byte[])data;
return null;
}
protected byte[] ReadAIn()
{
if (!_trigConnected.M)
return null;
if (_ads.BulkReadRenderResult(_aiVariable, aiLength, out var data))
2023-03-03 15:42:13 +08:00
return data;
return null;
}
private byte[] ReadAOut()
{
if (!_trigConnected.M)
return null;
if (_ads.BulkReadRenderResult(_aoVariable, aoLength, out var data))
2023-03-03 15:42:13 +08:00
return (byte[])data;
return null;
}
private bool[] ParseDI(byte[] inputValue)
{
var diList = Singleton<IoManager>.Instance.GetDIList($"{Module}.io");
2023-03-03 15:42:13 +08:00
var result = new bool[1000];
2023-03-03 15:42:13 +08:00
foreach (var diAccessor in diList)
{
var addr = diAccessor.Addr;
var index = int.Parse(addr);
var Offset = index % 8;
var val = index % 8 == 0 ? index / 8 : (index - index % 8) / 8;
2023-03-03 15:42:13 +08:00
result[diAccessor.Index] = ((inputValue[val] >> Offset) & 0x1) == 1;
}
return result;
}
private bool[] ParseDO(byte[] outputValue)
{
//Addr="OUTPUT[0].4"
var doList = Singleton<IoManager>.Instance.GetDOList($"{Module}.io");
2023-03-03 15:42:13 +08:00
var cache = new bool[1000];
2023-03-03 15:42:13 +08:00
foreach (var doAccessor in doList)
{
var addr = doAccessor.Addr;
var index = int.Parse(addr);
var whichBit = index % 8;
var whichByte = index % 8 == 0 ? index / 8 : (index - index % 8) / 8;
2023-03-03 15:42:13 +08:00
cache[doAccessor.Index] = ((outputValue[whichByte] >> whichBit) & 0x1) == 1;
2023-03-03 15:42:13 +08:00
}
return cache;
2023-03-03 15:42:13 +08:00
}
private float[] ParseAI(byte[] inputValue)
{
var aiList = Singleton<IoManager>.Instance.GetAIList($"{Module}.io");
var result = new float[500];
2023-03-03 15:42:13 +08:00
foreach (var aiAccessor in aiList)
{
var addr = aiAccessor.Addr;
var index = int.Parse(addr);
var valve = BitConverter.ToSingle(new byte[] { inputValue[index * 4 + 3], inputValue[index * 4 + 2], inputValue[index * 4 + 1], inputValue[index * 4] }, 0);
2023-03-03 15:42:13 +08:00
result[aiAccessor.Index] = valve;
}
return result;
}
private float[] ParseAO(byte[] outputValue)
{
//Addr="OUTPUT[30]"
var aoList = Singleton<IoManager>.Instance.GetAOList($"{Module}.io");
2023-03-03 15:42:13 +08:00
var result = new float[500];
2023-03-03 15:42:13 +08:00
foreach (var aoAccessor in aoList)
{
var addr = aoAccessor.Addr;
var index = int.Parse(addr);
var valve = BitConverter.ToSingle(new[]
{
outputValue[index * 4 + 3],
outputValue[index * 4 + 2],
outputValue[index * 4 + 1],
outputValue[index * 4]
},
0);
2023-03-03 15:42:13 +08:00
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();
}
2023-03-13 17:37:55 +08:00
protected override void ReadDo(int offset, bool[] buffer)
{
throw new NotImplementedException();
}
protected override short[] ReadAo(int offset, int size)
{
throw new NotImplementedException();
}
2023-03-03 15:42:13 +08:00
protected override void WriteDo(int offset, bool[] buffer)
{
throw new NotImplementedException();
}
public override bool SetValue(AOAccessor aoItem, float value)
2023-03-03 15:42:13 +08:00
{
if (!_trigConnected.M)
return false;
//// 获取下标转换成16进制 IEEE 754浮点数然后整个写下去
var addr = aoItem.Addr;
var index = int.Parse(addr);
var address = _aoVariable.Substring(0, 9) + (int.Parse(_aoVariable.Substring(9, 3)) + index * 4);
var data = new byte[4];
2023-03-03 15:42:13 +08:00
if (index <= 48)
{
data = BitConverter.GetBytes(value);
}
else if (index >= 49)
{
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 var reason))
2023-03-03 15:42:13 +08:00
{
LOG.Write(reason);
return false;
}
lock (_locker)
{
////获取单个DWORD数据修改其中一位然后整个Byte写下去
2023-03-03 15:42:13 +08:00
var addr = doItem.Addr;
var add = int.Parse(addr);
var indexByte = add % 8;
var index = add % 8 == 0 ? add / 8 : (add - add % 8) / 8;
2023-03-03 15:42:13 +08:00
var val = 1 << indexByte;
var output = ReadDOut();
2023-03-03 15:42:13 +08:00
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));
2023-03-03 15:42:13 +08:00
var stringSeparators = new string[] { "DBB" };
var result = _doVariable.Split(stringSeparators, StringSplitOptions.None);
int.TryParse(result[1], out var startIndex);
var finalIndex = startIndex + index;
var address = $"{result[0]}DBB{finalIndex}";
var data = new byte[] { output[index] };
2023-03-03 15:42:13 +08:00
return _ads.BulkWriteByteRenderResult(address, data);
}
}
}
}