mirror of
https://github.com/S7NetPlus/s7netplus.git
synced 2026-02-17 14:28:25 +08:00
Add support for creating DataItem from string (#149)
* Refactor PLCAddress - Change fields into properties - Apply PascalCase naming to all properties - Make Parse public static with out parameters * Support creating DataItem from string * Rename PlcAddress.Address to StartByte
This commit is contained in:
committed by
Raphael Schlameuß
parent
214a7a73c8
commit
bf4550655e
197
S7.Net/PLCAddress.cs
Normal file
197
S7.Net/PLCAddress.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
namespace S7.Net
|
||||
{
|
||||
internal class PLCAddress
|
||||
{
|
||||
private DataType dataType;
|
||||
private int dbNumber;
|
||||
private int startByte;
|
||||
private int bitNumber;
|
||||
private VarType varType;
|
||||
|
||||
public DataType DataType
|
||||
{
|
||||
get => dataType;
|
||||
set => dataType = value;
|
||||
}
|
||||
|
||||
public int DbNumber
|
||||
{
|
||||
get => dbNumber;
|
||||
set => dbNumber = value;
|
||||
}
|
||||
|
||||
public int StartByte
|
||||
{
|
||||
get => startByte;
|
||||
set => startByte = value;
|
||||
}
|
||||
|
||||
public int BitNumber
|
||||
{
|
||||
get => bitNumber;
|
||||
set => bitNumber = value;
|
||||
}
|
||||
|
||||
public VarType VarType
|
||||
{
|
||||
get => varType;
|
||||
set => varType = value;
|
||||
}
|
||||
|
||||
public PLCAddress(string address)
|
||||
{
|
||||
Parse(address, out dataType, out dbNumber, out varType, out startByte, out bitNumber);
|
||||
}
|
||||
|
||||
public static void Parse(string input, out DataType dataType, out int dbNumber, out VarType varType, out int address, out int bitNumber)
|
||||
{
|
||||
bitNumber = -1;
|
||||
dbNumber = 0;
|
||||
|
||||
switch (input.Substring(0, 2))
|
||||
{
|
||||
case "DB":
|
||||
string[] strings = input.Split(new char[] { '.' });
|
||||
if (strings.Length < 2)
|
||||
throw new InvalidAddressException("To few periods for DB address");
|
||||
|
||||
dataType = DataType.DataBlock;
|
||||
dbNumber = int.Parse(strings[0].Substring(2));
|
||||
address = int.Parse(strings[1].Substring(3));
|
||||
|
||||
string dbType = strings[1].Substring(0, 3);
|
||||
switch (dbType)
|
||||
{
|
||||
case "DBB":
|
||||
varType = VarType.Byte;
|
||||
return;
|
||||
case "DBW":
|
||||
varType = VarType.Word;
|
||||
return;
|
||||
case "DBD":
|
||||
varType = VarType.DWord;
|
||||
return;
|
||||
case "DBX":
|
||||
bitNumber = int.Parse(strings[2]);
|
||||
if (bitNumber > 7)
|
||||
throw new InvalidAddressException("Bit can only be 0-7");
|
||||
varType = VarType.Bit;
|
||||
return;
|
||||
default:
|
||||
throw new InvalidAddressException();
|
||||
}
|
||||
case "EB":
|
||||
// Input byte
|
||||
dataType = DataType.Input;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(2));
|
||||
varType = VarType.Byte;
|
||||
return;
|
||||
case "EW":
|
||||
// Input word
|
||||
dataType = DataType.Input;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(2));
|
||||
varType = VarType.Word;
|
||||
return;
|
||||
case "ED":
|
||||
// Input double-word
|
||||
dataType = DataType.Input;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(2));
|
||||
varType = VarType.DWord;
|
||||
return;
|
||||
case "AB":
|
||||
// Output byte
|
||||
dataType = DataType.Output;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(2));
|
||||
varType = VarType.Byte;
|
||||
return;
|
||||
case "AW":
|
||||
// Output word
|
||||
dataType = DataType.Output;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(2));
|
||||
varType = VarType.Word;
|
||||
return;
|
||||
case "AD":
|
||||
// Output double-word
|
||||
dataType = DataType.Output;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(2));
|
||||
varType = VarType.DWord;
|
||||
return;
|
||||
case "MB":
|
||||
// Memory byte
|
||||
dataType = DataType.Memory;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(2));
|
||||
varType = VarType.Byte;
|
||||
return;
|
||||
case "MW":
|
||||
// Memory word
|
||||
dataType = DataType.Memory;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(2));
|
||||
varType = VarType.Word;
|
||||
return;
|
||||
case "MD":
|
||||
// Memory double-word
|
||||
dataType = DataType.Memory;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(2));
|
||||
varType = VarType.DWord;
|
||||
return;
|
||||
default:
|
||||
switch (input.Substring(0, 1))
|
||||
{
|
||||
case "E":
|
||||
case "I":
|
||||
// Input
|
||||
dataType = DataType.Input;
|
||||
varType = VarType.Bit;
|
||||
break;
|
||||
case "A":
|
||||
case "O":
|
||||
// Output
|
||||
dataType = DataType.Output;
|
||||
varType = VarType.Bit;
|
||||
break;
|
||||
case "M":
|
||||
// Memory
|
||||
dataType = DataType.Memory;
|
||||
varType = VarType.Byte;
|
||||
break;
|
||||
case "T":
|
||||
// Timer
|
||||
dataType = DataType.Timer;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(1));
|
||||
varType = VarType.Timer;
|
||||
return;
|
||||
case "Z":
|
||||
case "C":
|
||||
// Counter
|
||||
dataType = DataType.Timer;
|
||||
dbNumber = 0;
|
||||
address = int.Parse(input.Substring(1));
|
||||
varType = VarType.Counter;
|
||||
return;
|
||||
default:
|
||||
throw new InvalidAddressException(string.Format("{0} is not a valid address", input.Substring(0, 1)));
|
||||
}
|
||||
|
||||
string txt2 = input.Substring(1);
|
||||
if (txt2.IndexOf(".") == -1)
|
||||
throw new InvalidAddressException("To few periods for DB address");
|
||||
|
||||
address = int.Parse(txt2.Substring(0, txt2.IndexOf(".")));
|
||||
bitNumber = int.Parse(txt2.Substring(txt2.IndexOf(".") + 1));
|
||||
if (bitNumber > 7)
|
||||
throw new InvalidAddressException("Bit can only be 0-7");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,167 +5,6 @@ using System.Linq;
|
||||
|
||||
namespace S7.Net
|
||||
{
|
||||
|
||||
internal class PLCAddress
|
||||
{
|
||||
public DataType dataType;
|
||||
public int DBNumber;
|
||||
public int Address;
|
||||
public int BitNumber;
|
||||
public VarType varType;
|
||||
|
||||
public PLCAddress(string address)
|
||||
{
|
||||
ParseString(address);
|
||||
}
|
||||
|
||||
private void ParseString(string address)
|
||||
{
|
||||
BitNumber = -1;
|
||||
switch (address.Substring(0, 2))
|
||||
{
|
||||
case "DB":
|
||||
string[] strings = address.Split(new char[] { '.' });
|
||||
if (strings.Length < 2)
|
||||
throw new InvalidAddressException("To few periods for DB address");
|
||||
|
||||
dataType = DataType.DataBlock;
|
||||
DBNumber = int.Parse(strings[0].Substring(2));
|
||||
Address = int.Parse(strings[1].Substring(3));
|
||||
|
||||
string dbType = strings[1].Substring(0, 3);
|
||||
switch (dbType)
|
||||
{
|
||||
case "DBB":
|
||||
varType = VarType.Byte;
|
||||
return;
|
||||
case "DBW":
|
||||
varType = VarType.Word;
|
||||
return;
|
||||
case "DBD":
|
||||
varType = VarType.DWord;
|
||||
return;
|
||||
case "DBX":
|
||||
BitNumber = int.Parse(strings[2]);
|
||||
if (BitNumber > 7)
|
||||
throw new InvalidAddressException("Bit can only be 0-7");
|
||||
varType = VarType.Bit;
|
||||
return;
|
||||
default:
|
||||
throw new InvalidAddressException();
|
||||
}
|
||||
case "EB":
|
||||
// Input byte
|
||||
dataType = DataType.Input;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(2));
|
||||
varType = VarType.Byte;
|
||||
return;
|
||||
case "EW":
|
||||
// Input word
|
||||
dataType = DataType.Input;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(2));
|
||||
varType = VarType.Word;
|
||||
return;
|
||||
case "ED":
|
||||
// Input double-word
|
||||
dataType = DataType.Input;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(2));
|
||||
varType = VarType.DWord;
|
||||
return;
|
||||
case "AB":
|
||||
// Output byte
|
||||
dataType = DataType.Output;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(2));
|
||||
varType = VarType.Byte;
|
||||
return;
|
||||
case "AW":
|
||||
// Output word
|
||||
dataType = DataType.Output;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(2));
|
||||
varType = VarType.Word;
|
||||
return;
|
||||
case "AD":
|
||||
// Output double-word
|
||||
dataType = DataType.Output;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(2));
|
||||
varType = VarType.DWord;
|
||||
return;
|
||||
case "MB":
|
||||
// Memory byte
|
||||
dataType = DataType.Memory;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(2));
|
||||
varType = VarType.Byte;
|
||||
return;
|
||||
case "MW":
|
||||
// Memory word
|
||||
dataType = DataType.Memory;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(2));
|
||||
varType = VarType.Word;
|
||||
return;
|
||||
case "MD":
|
||||
// Memory double-word
|
||||
dataType = DataType.Memory;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(2));
|
||||
varType = VarType.DWord;
|
||||
return;
|
||||
default:
|
||||
switch (address.Substring(0, 1))
|
||||
{
|
||||
case "E":
|
||||
case "I":
|
||||
// Input
|
||||
dataType = DataType.Input;
|
||||
break;
|
||||
case "A":
|
||||
case "O":
|
||||
// Output
|
||||
dataType = DataType.Output;
|
||||
break;
|
||||
case "M":
|
||||
// Memory
|
||||
dataType = DataType.Memory;
|
||||
break;
|
||||
case "T":
|
||||
// Timer
|
||||
dataType = DataType.Timer;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(1));
|
||||
varType = VarType.Timer;
|
||||
return;
|
||||
case "Z":
|
||||
case "C":
|
||||
// Counter
|
||||
dataType = DataType.Timer;
|
||||
DBNumber = 0;
|
||||
Address = int.Parse(address.Substring(1));
|
||||
varType = VarType.Counter;
|
||||
return;
|
||||
default:
|
||||
throw new InvalidAddressException(string.Format("{0} is not a valid address", address.Substring(0, 1)));
|
||||
}
|
||||
|
||||
string txt2 = address.Substring(1);
|
||||
if (txt2.IndexOf(".") == -1)
|
||||
throw new InvalidAddressException("To few periods for DB address");
|
||||
|
||||
Address = int.Parse(txt2.Substring(0, txt2.IndexOf(".")));
|
||||
BitNumber = int.Parse(txt2.Substring(txt2.IndexOf(".") + 1));
|
||||
if (BitNumber > 7)
|
||||
throw new InvalidAddressException("Bit can only be 0-7");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Plc
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace S7.Net
|
||||
public async Task<object> ReadAsync(string variable)
|
||||
{
|
||||
var adr = new PLCAddress(variable);
|
||||
return await ReadAsync(adr.dataType, adr.DBNumber, adr.Address, adr.varType, 1, (byte)adr.BitNumber);
|
||||
return await ReadAsync(adr.DataType, adr.DbNumber, adr.StartByte, adr.VarType, 1, (byte)adr.BitNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -345,7 +345,7 @@ namespace S7.Net
|
||||
public async Task WriteAsync(string variable, object value)
|
||||
{
|
||||
var adr = new PLCAddress(variable);
|
||||
await WriteAsync(adr.dataType, adr.DBNumber, adr.Address, value, adr.BitNumber);
|
||||
await WriteAsync(adr.DataType, adr.DbNumber, adr.StartByte, value, adr.BitNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace S7.Net
|
||||
public object Read(string variable)
|
||||
{
|
||||
var adr = new PLCAddress(variable);
|
||||
return Read(adr.dataType, adr.DBNumber, adr.Address, adr.varType, 1, (byte)adr.BitNumber);
|
||||
return Read(adr.DataType, adr.DbNumber, adr.StartByte, adr.VarType, 1, (byte)adr.BitNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -309,7 +309,7 @@ namespace S7.Net
|
||||
public void Write(string variable, object value)
|
||||
{
|
||||
var adr = new PLCAddress(variable);
|
||||
Write(adr.dataType, adr.DBNumber, adr.Address, value, adr.BitNumber);
|
||||
Write(adr.DataType, adr.DbNumber, adr.StartByte, value, adr.BitNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace S7.Net.Types
|
||||
using System;
|
||||
|
||||
namespace S7.Net.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// Create an instance of a memory block that can be read by using ReadMultipleVars
|
||||
@@ -48,5 +50,42 @@
|
||||
VarType = VarType.Byte;
|
||||
Count = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of <see cref="DataItem"/> from the supplied address.
|
||||
/// </summary>
|
||||
/// <param name="address">The address to create the DataItem for.</param>
|
||||
/// <returns>A new <see cref="DataItem"/> instance with properties parsed from <paramref name="address"/>.</returns>
|
||||
/// <remarks>The <see cref="Count" /> property is not parsed from the address.</remarks>
|
||||
public static DataItem FromAddress(string address)
|
||||
{
|
||||
PLCAddress.Parse(address, out var dataType, out var dbNumber, out var varType, out var startByte,
|
||||
out var bitNumber);
|
||||
|
||||
return new DataItem
|
||||
{
|
||||
DataType = dataType,
|
||||
DB = dbNumber,
|
||||
VarType = varType,
|
||||
StartByteAdr = startByte,
|
||||
BitAdr = (byte) bitNumber
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create an instance of <see cref="DataItem"/> from the supplied address and value.
|
||||
/// </summary>
|
||||
/// <param name="address">The address to create the DataItem for.</param>
|
||||
/// <param name="value">The value to be applied to the DataItem.</param>
|
||||
/// <returns>A new <see cref="DataItem"/> instance with properties parsed from <paramref name="address"/> and the supplied value set.</returns>
|
||||
public static DataItem FromAddressAndValue<T>(string address, T value)
|
||||
{
|
||||
var dataItem = FromAddress(address);
|
||||
dataItem.Value = value;
|
||||
|
||||
if (typeof(T).IsArray) dataItem.Count = ((Array) dataItem.Value).Length;
|
||||
|
||||
return dataItem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user