diff --git a/App/SicSimulator/Instances/SimulatorAdsPlcService.cs b/App/SicSimulator/Instances/SimulatorAdsPlcService.cs index 079dcf3..958714d 100644 --- a/App/SicSimulator/Instances/SimulatorAdsPlcService.cs +++ b/App/SicSimulator/Instances/SimulatorAdsPlcService.cs @@ -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; + } + } } \ No newline at end of file diff --git a/App/SicSimulator/Instances/SimulatorModulePlc.cs b/App/SicSimulator/Instances/SimulatorModulePlc.cs index 395b3a1..dce55e8 100644 --- a/App/SicSimulator/Instances/SimulatorModulePlc.cs +++ b/App/SicSimulator/Instances/SimulatorModulePlc.cs @@ -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 lstBuffers = new List(); - 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);