refactor: 简化PLC模拟器Buffer的初始化逻辑。

This commit is contained in:
SL 2026-06-05 09:59:19 +08:00
parent 1526692d4e
commit 187984f5b9
2 changed files with 97 additions and 113 deletions

View File

@ -1,4 +1,5 @@
using Aitex.Core.RT.IOCore;
using System;
using Aitex.Core.RT.IOCore;
using MECF.Framework.Common.IOCore;
using MECF.Framework.Common.PLC;
@ -18,56 +19,22 @@ namespace SicSimulator.Instances
reason = string.Empty;
data = null;
switch (variable)
{
case "GVL_IO.PM1_DI_G":
data = IoManager.Instance.GetDiBuffer("PM1.PLC")[0];
break;
case "GVL_IO.PM1_DO_G":
data = IoManager.Instance.GetDoBuffer("PM1.PLC")[0];
break;
case "GVL_IO.PM1_AI_G":
data = IoManager.Instance.GetAiBuffer("PM1.PLC")[0];
break;
case "GVL_IO.PM1_AI_G_2":
data = IoManager.Instance.GetAiBuffer("PM1.PLC")[1];
break;
case "GVL_IO.PM1_AI_G_3":
data = IoManager.Instance.GetAiBuffer("PM1.PLC")[2];
break;
case "GVL_IO.PM1_AO_G":
data = IoManager.Instance.GetAoBuffer("PM1.PLC")[0];
break;
case "GVL_IO.PM1_AO_G_2":
data = IoManager.Instance.GetAoBuffer("PM1.PLC")[1];
break;
case "GVL_IO.PM1_AO_G_3":
data = IoManager.Instance.GetAoBuffer("PM1.PLC")[2];
break;
if (!TryParseIoVariable(variable, out var pmSource, out var ioType, out var bufferIndex))
return true;
case "GVL_IO.PM2_DI_G":
data = IoManager.Instance.GetDiBuffer("PM2.PLC")[0];
switch (ioType)
{
case "DI":
data = IoManager.Instance.GetDiBuffer(pmSource)[bufferIndex];
break;
case "GVL_IO.PM2_DO_G":
data = IoManager.Instance.GetDoBuffer("PM2.PLC")[0];
case "DO":
data = IoManager.Instance.GetDoBuffer(pmSource)[bufferIndex];
break;
case "GVL_IO.PM2_AI_G":
data = IoManager.Instance.GetAiBuffer("PM2.PLC")[0];
case "AI":
data = IoManager.Instance.GetAiBuffer(pmSource)[bufferIndex];
break;
case "GVL_IO.PM2_AI_G_2":
data = IoManager.Instance.GetAiBuffer("PM2.PLC")[1];
break;
case "GVL_IO.PM2_AI_G_3":
data = IoManager.Instance.GetAiBuffer("PM2.PLC")[2];
break;
case "GVL_IO.PM2_AO_G":
data = IoManager.Instance.GetAoBuffer("PM2.PLC")[0];
break;
case "GVL_IO.PM2_AO_G_2":
data = IoManager.Instance.GetAoBuffer("PM2.PLC")[1];
break;
case "GVL_IO.PM2_AO_G_3":
data = IoManager.Instance.GetAoBuffer("PM2.PLC")[2];
case "AO":
data = IoManager.Instance.GetAoBuffer(pmSource)[bufferIndex];
break;
}
@ -77,60 +44,25 @@ namespace SicSimulator.Instances
public bool WriteArrayElement(string variable, int index, object value, out string reason)
{
reason = string.Empty;
switch (variable)
if (!TryParseIoVariable(variable, out var pmSource, out var ioType, out var bufferIndex))
return true;
switch (ioType)
{
case "GVL_IO.PM1_DI_G":
case "DI":
break;
case "GVL_IO.PM1_DO_G":
IoManager.Instance.GetDoBuffer("PM1.PLC")[0][index] = (bool)value;
case "DO":
IoManager.Instance.GetDoBuffer(pmSource)[bufferIndex][index] = (bool)value;
break;
case "GVL_IO.PM1_AI_G":
IoManager.Instance.GetAiBuffer("PM1.PLC")[0][index] = (float)value;
case "AI":
IoManager.Instance.GetAiBuffer(pmSource)[bufferIndex][index] = (float)value;
break;
case "GVL_IO.PM1_AI_G_2":
IoManager.Instance.GetAiBuffer("PM1.PLC")[1][index] = (float)value;
break;
case "GVL_IO.PM1_AI_G_3":
IoManager.Instance.GetAiBuffer("PM1.PLC")[2][index] = (float)value;
break;
case "GVL_IO.PM1_AO_G":
IoManager.Instance.GetAoBuffer("PM1.PLC")[0][index] = (float)value;
break;
case "GVL_IO.PM1_AO_G_2":
IoManager.Instance.GetAoBuffer("PM1.PLC")[1][index] = (float)value;
break;
case "GVL_IO.PM1_AO_G_3":
IoManager.Instance.GetAoBuffer("PM1.PLC")[2][index] = (float)value;
break;
case "GVL_IO.PM2_DI_G":
break;
case "GVL_IO.PM2_DO_G":
IoManager.Instance.GetDoBuffer("PM2.PLC")[0][index] = (bool)value;
break;
case "GVL_IO.PM2_AI_G":
IoManager.Instance.GetAiBuffer("PM2.PLC")[0][index] = (float)value;
break;
case "GVL_IO.PM2_AI_G_2":
IoManager.Instance.GetAiBuffer("PM2.PLC")[1][index] = (float)value;
break;
case "GVL_IO.PM2_AI_G_3":
IoManager.Instance.GetAiBuffer("PM2.PLC")[2][index] = (float)value;
break;
case "GVL_IO.PM2_AO_G":
IoManager.Instance.GetAoBuffer("PM2.PLC")[0][index] = (float)value;
break;
case "GVL_IO.PM2_AO_G_2":
IoManager.Instance.GetAoBuffer("PM2.PLC")[1][index] = (float)value;
break;
case "GVL_IO.PM2_AO_G_3":
IoManager.Instance.GetAoBuffer("PM2.PLC")[2][index] = (float)value;
case "AO":
IoManager.Instance.GetAoBuffer(pmSource)[bufferIndex][index] = (float)value;
break;
}
return true;
}
@ -168,6 +100,49 @@ namespace SicSimulator.Instances
{
return counter;
}
// GVL_IO.PM{n}_{DI|DO|AI|AO}_G[_N] => PM{n}.PLC, type, index (N-1, default 0)
private static bool TryParseIoVariable(string variable, out string pmSource, out string ioType, out int bufferIndex)
{
pmSource = null;
ioType = null;
bufferIndex = 0;
var dotIndex = variable.LastIndexOf('.');
if (dotIndex < 0)
return false;
var name = variable.Substring(dotIndex + 1);
var pmEnd = name.IndexOf('_');
if (pmEnd <= 2 || !name.StartsWith("PM"))
return false;
pmSource = name.Substring(0, pmEnd) + ".PLC";
var rest = name.Substring(pmEnd + 1);
if (rest.StartsWith("DI_")) ioType = "DI";
else if (rest.StartsWith("DO_")) ioType = "DO";
else if (rest.StartsWith("AI_")) ioType = "AI";
else if (rest.StartsWith("AO_")) ioType = "AO";
else return false;
const string groupMarker = "_G";
var gIndex = rest.LastIndexOf(groupMarker, StringComparison.Ordinal);
if (gIndex < 0)
return false;
var indexPart = rest.Substring(gIndex + groupMarker.Length);
if (indexPart.Length == 0)
bufferIndex = 0;
else if (indexPart.StartsWith("_") && int.TryParse(indexPart.Substring(1), out var suffixNum))
bufferIndex = suffixNum - 1;
else
return false;
return true;
}
}
}

View File

@ -20,8 +20,11 @@ namespace SicSimulator.Instances
private string _source;
public const int BufferSize =600;
public const int BufferSize = 600;
public const int DiBlockCount = 1;
public const int DoBlockCount = 1;
public const int AiBlockCount = 5;
public const int AoBlockCount = 5;
PeriodicJob _threadTimer;
@ -32,24 +35,30 @@ namespace SicSimulator.Instances
{
_source = source;
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.DI, Offset = 0, Size = BufferSize, BoolValue = new bool[BufferSize] });
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.DO, Offset = 0, Size = BufferSize, BoolValue = new bool[BufferSize] });
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.AI, Offset = 0, Size = BufferSize, FloatValue = new float[BufferSize] });
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.AO, Offset = 0, Size = BufferSize, FloatValue = new float[BufferSize] });
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.AI, Offset = 1, Size = BufferSize, FloatValue = new float[BufferSize] });
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.AO, Offset = 1, Size = BufferSize, FloatValue = new float[BufferSize] });
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.AI, Offset = 2, Size = BufferSize, FloatValue = new float[BufferSize] });
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.AO, Offset = 2, Size = BufferSize, FloatValue = new float[BufferSize] });
for (int i = 0; i < DiBlockCount; i++)
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.DI, Offset = i, Size = BufferSize, BoolValue = new bool[BufferSize] });
for (int i = 0; i < DoBlockCount; i++)
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.DO, Offset = i, Size = BufferSize, BoolValue = new bool[BufferSize] });
for (int i = 0; i < AiBlockCount; i++)
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.AI, Offset = i, Size = BufferSize, FloatValue = new float[BufferSize] });
for (int i = 0; i < AoBlockCount; i++)
_buffers.Add(new PlcBuffer() { Buffer = new byte[BufferSize], Type = IoType.AO, Offset = i, Size = BufferSize, FloatValue = new float[BufferSize] });
List<IoBlockItem> lstBuffers = new List<IoBlockItem>();
lstBuffers.Add(new IoBlockItem() { Type = IoType.DI, Index = 0, Size = BufferSize });
lstBuffers.Add(new IoBlockItem() { Type = IoType.DO, Index = 0, Size = BufferSize });
lstBuffers.Add(new IoBlockItem() { Type = IoType.AI, Index = 0, Size = BufferSize });
lstBuffers.Add(new IoBlockItem() { Type = IoType.AO, Index = 0, Size = BufferSize });
lstBuffers.Add(new IoBlockItem() { Type = IoType.AI, Index = 1, Size = BufferSize });
lstBuffers.Add(new IoBlockItem() { Type = IoType.AO, Index = 1, Size = BufferSize });
lstBuffers.Add(new IoBlockItem() { Type = IoType.AI, Index = 2, Size = BufferSize });
lstBuffers.Add(new IoBlockItem() { Type = IoType.AO, Index = 2, Size = BufferSize });
for (int i = 0; i < DiBlockCount; i++)
lstBuffers.Add(new IoBlockItem() { Type = IoType.DI, Index = i, Size = BufferSize });
for (int i = 0; i < DoBlockCount; i++)
lstBuffers.Add(new IoBlockItem() { Type = IoType.DO, Index = i, Size = BufferSize });
for (int i = 0; i < AiBlockCount; i++)
lstBuffers.Add(new IoBlockItem() { Type = IoType.AI, Index = i, Size = BufferSize });
for (int i = 0; i < AoBlockCount; i++)
lstBuffers.Add(new IoBlockItem() { Type = IoType.AO, Index = i, Size = BufferSize });
SimulatorIoManager.Instance.CreateBuffer(source, lstBuffers);
SimulatorIoManager.Instance.SetIoMap(source, ioMapPathFile, module);