2015-01-11 update 1

This commit is contained in:
parallelbgls@outlook.com
2016-01-11 15:29:45 +08:00
parent f134328835
commit 2cbd5c1e4d
32 changed files with 384 additions and 281 deletions

View File

@@ -7,7 +7,7 @@ using System.Web.Http;
using System.Web.Http.Routing;
using CrossLampControl.WebApi.Models;
using ModBus.Net;
using ModBus.Net.Simense;
using ModBus.Net.Siemens;
namespace CrossLampControl.WebApi.Controllers
{
@@ -17,15 +17,15 @@ namespace CrossLampControl.WebApi.Controllers
public CrossLampController()
{
_utility = new SimenseUtility(SimenseType.Tcp, "192.168.3.241", SimenseMachineModel.S7_200);
_utility.AddressTranslator = new AddressTranslatorSimense();
_utility = new SiemensUtility(SiemensType.Tcp, "192.168.3.241", SiemensMachineModel.S7_200);
_utility.AddressTranslator = new AddressTranslatorSiemens();
}
[HttpGet]
public Lamp GetLamp()
{
Lamp light = new Lamp();
object[] lampsbyte = _utility.GetDatas(2, 0, "Q0", new KeyValuePair<Type, int>(typeof(bool), 7));
object[] lampsbyte = _utility.GetDatas(2, 0, "Q 0", new KeyValuePair<Type, int>(typeof(bool), 7));
bool[] lamps =
ValueHelper.Instance.ObjectArrayToDestinationArray<bool>(
lampsbyte);

View File

@@ -11,7 +11,7 @@ namespace ModBus.Net
{
public override string FormatAddress(string area, int address)
{
return area + "." + address;
return area + ":" + address;
}
}
}

View File

@@ -65,10 +65,10 @@ namespace ModBus.Net.FBox
try
{
var readRequestFBoxInputStruct = new ReadRequestFBoxInputStruct(startAddress, (ushort)getByteCount, AddressTranslator);
var readRequestSimenseOutputStruct =
var readRequestSiemensOutputStruct =
(ReadRequestFBoxOutputStruct)await
Wrapper.SendReceiveAsync(Wrapper[typeof(ReadRequestFBoxProtocal)], readRequestFBoxInputStruct);
return readRequestSimenseOutputStruct.GetValue;
return readRequestSiemensOutputStruct.GetValue;
}
catch (Exception)
{

View File

@@ -104,15 +104,15 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="FBox\SignalRConnector.cs" />
<Compile Include="FBox\SignalRProtocalLinker.cs" />
<Compile Include="Simense\AddressFormaterSimense.cs" />
<Compile Include="Simense\AddressTranslatorSimense.cs" />
<Compile Include="Simense\SimenseMachine.cs" />
<Compile Include="Simense\SimenseProtocal.cs" />
<Compile Include="Simense\SimenseStructDefinition.cs" />
<Compile Include="Simense\SimenseTcpProtocal.cs" />
<Compile Include="Simense\SimenseProtocalLinkerBytesExtend.cs" />
<Compile Include="Simense\SimenseTcpProtocalLinker.cs" />
<Compile Include="Simense\SimenseUtility.cs" />
<Compile Include="Siemens\AddressFormaterSiemens.cs" />
<Compile Include="Siemens\AddressTranslatorSiemens.cs" />
<Compile Include="Siemens\SiemensMachine.cs" />
<Compile Include="Siemens\SiemensProtocal.cs" />
<Compile Include="Siemens\SiemensStructDefinition.cs" />
<Compile Include="Siemens\SiemensTcpProtocal.cs" />
<Compile Include="Siemens\SiemensProtocalLinkerBytesExtend.cs" />
<Compile Include="Siemens\SiemensTcpProtocalLinker.cs" />
<Compile Include="Siemens\SiemensUtility.cs" />
<Compile Include="TaskManager.cs" />
<Compile Include="TcpConnector.cs">
<SubType>Code</SubType>

View File

@@ -10,7 +10,15 @@ namespace ModBus.Net.Modbus
{
public override string FormatAddress(string area, int address)
{
return area + address;
return area + " " + address;
}
}
public class AddressFormaterModbus : AddressFormater
{
public override string FormatAddress(string area, int address)
{
return area + " " + address;
}
}
}

View File

@@ -21,14 +21,14 @@ namespace ModBus.Net.Modbus
{
{"Q", 0},
{"M", 10000},
{"N", 20000},
{"N", 30000},
{"I", 0},
{"S", 10000},
{"IW", 0},
{"SW", 5000},
{"MW", 0},
{"NW", 10000},
{"MW", 0},
{"QW", 20000},
{"NW", 21000},
};
ReadFunctionCodeDictionary = new Dictionary<string, int>
{
@@ -57,15 +57,9 @@ namespace ModBus.Net.Modbus
public override KeyValuePair<int, int> AddressTranslate(string address, bool isRead)
{
address = address.ToUpper();
int i = 0;
int t;
while (!int.TryParse(address[i].ToString(), out t) && i < address.Length)
{
i++;
}
if (i == 0 || i >= address.Length) throw new FormatException();
string head = address.Substring(0, i);
string tail = address.Substring(i);
string[] splitString = address.Split(' ');
string head = splitString[0];
string tail = splitString[1];
return isRead
? new KeyValuePair<int, int>(TransDictionary[head] + int.Parse(tail) - 1,
ReadFunctionCodeDictionary[head])
@@ -73,4 +67,42 @@ namespace ModBus.Net.Modbus
WriteFunctionCodeDictionary[head]);
}
}
/// <summary>
/// Modbus数据单元翻译器
/// </summary>
public class AddressTranslatorModbus : AddressTranslator
{
protected Dictionary<string, int> ReadFunctionCodeDictionary;
protected Dictionary<string, int> WriteFunctionCodeDictionary;
public AddressTranslatorModbus()
{
ReadFunctionCodeDictionary = new Dictionary<string, int>
{
{"0X", (int)ModbusProtocalReadDataFunctionCode.ReadCoilStatus},
{"1X", (int)ModbusProtocalReadDataFunctionCode.ReadInputStatus},
{"3X", (int)ModbusProtocalReadDataFunctionCode.ReadInputRegister},
{"4X", (int)ModbusProtocalReadDataFunctionCode.ReadHoldRegister},
};
WriteFunctionCodeDictionary = new Dictionary<string, int>
{
{"0X", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiCoil},
{"4X", (int)ModbusProtocalWriteDataFunctionCode.WriteMultiRegister},
};
}
public override KeyValuePair<int, int> AddressTranslate(string address, bool isRead)
{
address = address.ToUpper();
string[] splitString = address.Split(' ');
string head = splitString[0];
string tail = splitString[1];
return isRead
? new KeyValuePair<int, int>(int.Parse(tail) - 1,
ReadFunctionCodeDictionary[head])
: new KeyValuePair<int, int>(int.Parse(tail) - 1,
WriteFunctionCodeDictionary[head]);
}
}
}

View File

@@ -8,7 +8,7 @@ namespace ModBus.Net.Modbus
IEnumerable<AddressUnit> getAddresses, bool keepConnect) : base(getAddresses, keepConnect)
{
BaseUtility = new ModbusUtility(connectionType, connectionString);
AddressFormater = new AddressFormaterBase();
AddressFormater = new AddressFormaterModbus();
AddressCombiner = new AddressCombinerContinus();
}

View File

@@ -50,14 +50,14 @@ namespace ModBus.Net.Modbus
{
ConnectionString = null;
ModbusType = (ModbusType)connectionType;
AddressTranslator = new AddressTranslatorBase();
AddressTranslator = new AddressTranslatorModbus();
}
public ModbusUtility(ModbusType connectionType, string connectionString)
{
ConnectionString = connectionString;
ModbusType = connectionType;
AddressTranslator = new AddressTranslatorBase();
AddressTranslator = new AddressTranslatorModbus();
}
public override void SetConnectionType(int connectionType)

View File

@@ -4,12 +4,13 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ModBus.Net.Simense
namespace ModBus.Net.Siemens
{
public class AddressFormaterSimense : AddressFormater
public class AddressFormaterSiemens : AddressFormater
{
public override string FormatAddress(string area, int address)
{
/*
if (area.Length > 1 &&
area.ToUpper().Substring(0, 2) == "DB")
{
@@ -19,6 +20,8 @@ namespace ModBus.Net.Simense
{
return area.ToUpper() + address;
}
*/
return area + " " + address;
}
}
}

View File

@@ -1,13 +1,13 @@
using System;
using System.Collections.Generic;
namespace ModBus.Net.Simense
namespace ModBus.Net.Siemens
{
public class AddressTranslatorSimense : AddressTranslator
public class AddressTranslatorSiemens : AddressTranslator
{
protected Dictionary<string, int> AreaCodeDictionary;
public AddressTranslatorSimense()
public AddressTranslatorSiemens()
{
AreaCodeDictionary = new Dictionary<string, int>
{
@@ -28,7 +28,7 @@ namespace ModBus.Net.Simense
public override KeyValuePair<int, int> AddressTranslate(string address, bool isRead)
{
address = address.ToUpper();
/*address = address.ToUpper();
if (address.Substring(0, 2) == "DB")
{
var addressSplit = address.Split('.');
@@ -51,6 +51,19 @@ namespace ModBus.Net.Simense
return
new KeyValuePair<int, int>(int.Parse(tail),
AreaCodeDictionary[head]);
*/
string[] splitString = address.Split(' ');
string head = splitString[0];
string tail = splitString[1];
if (head.Substring(0, 2) == "DB")
{
head = head.Substring(2);
return new KeyValuePair<int, int>(int.Parse(tail),
int.Parse(head)*256 + AreaCodeDictionary["DB"]);
}
return
new KeyValuePair<int, int>(int.Parse(tail),
AreaCodeDictionary[head]);
}
}
}

View File

@@ -0,0 +1,21 @@
using System.Collections.Generic;
namespace ModBus.Net.Siemens
{
public class SiemensMachine : BaseMachine
{
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit> getAddresses, bool keepConnect) : base(getAddresses, keepConnect)
{
BaseUtility = new SiemensUtility(connectionType, connectionString, model);
AddressFormater = new AddressFormaterSiemens();
AddressCombiner = new AddressCombinerContinus();
}
public SiemensMachine(SiemensType connectionType, string connectionString, SiemensMachineModel model,
IEnumerable<AddressUnit> getAddresses)
: this(connectionType, connectionString, model, getAddresses, false)
{
}
}
}

View File

@@ -2,9 +2,9 @@
using System.Collections.Generic;
using System.Linq;
namespace ModBus.Net.Simense
namespace ModBus.Net.Siemens
{
public enum SimenseTypeCode : byte
public enum SiemensTypeCode : byte
{
Bool = 0x01,
Byte = 0x02,
@@ -15,7 +15,7 @@ namespace ModBus.Net.Simense
HC = 0x20,
};
public enum SimenseAccessResult : byte
public enum SiemensAccessResult : byte
{
NoError = 0xFF,
HardwareFault = 0x01,
@@ -25,21 +25,21 @@ namespace ModBus.Net.Simense
ObjNotExistOrLengthError = 0x0A,
};
public enum SimenseDataType : byte
public enum SiemensDataType : byte
{
Error = 0x00,
BitAccess = 0x03,
OtherAccess = 0x04
};
public abstract class SimenseProtocal : BaseProtocal
public abstract class SiemensProtocal : BaseProtocal
{
}
internal class CreateReferenceSimenseInputStruct : InputStruct
internal class CreateReferenceSiemensInputStruct : InputStruct
{
public CreateReferenceSimenseInputStruct(byte tdpuSize, ushort srcTsap, ushort dstTsap)
public CreateReferenceSiemensInputStruct(byte tdpuSize, ushort srcTsap, ushort dstTsap)
{
TdpuSize = tdpuSize;
TsapSrc = srcTsap;
@@ -53,9 +53,9 @@ namespace ModBus.Net.Simense
public ushort TsapDst;
}
internal class CreateReferenceSimenseOutputStruct : OutputStruct
internal class CreateReferenceSiemensOutputStruct : OutputStruct
{
public CreateReferenceSimenseOutputStruct(byte tdpuSize, ushort srcTsap, ushort dstTsap)
public CreateReferenceSiemensOutputStruct(byte tdpuSize, ushort srcTsap, ushort dstTsap)
{
TdpuSize = tdpuSize;
TsapSrc = srcTsap;
@@ -67,11 +67,11 @@ namespace ModBus.Net.Simense
public ushort TsapDst { get; private set; }
}
internal class CreateReferenceSimenseProtocal : SpecialProtocalUnit
internal class CreateReferenceSiemensProtocal : SpecialProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (CreateReferenceSimenseInputStruct)message;
var r_message = (CreateReferenceSiemensInputStruct)message;
const ushort head = 0x0300;
const ushort len = 0x0016;
const byte contentLen = 0x11;
@@ -115,13 +115,13 @@ namespace ModBus.Net.Simense
break;
}
}
return new CreateReferenceSimenseOutputStruct(tdpuSize, srcTsap, dstTsap);
return new CreateReferenceSiemensOutputStruct(tdpuSize, srcTsap, dstTsap);
}
}
internal class EstablishAssociationSimenseInputStruct : InputStruct
internal class EstablishAssociationSiemensInputStruct : InputStruct
{
public EstablishAssociationSimenseInputStruct(ushort pduRef, ushort maxCalling, ushort maxCalled, ushort maxPdu)
public EstablishAssociationSiemensInputStruct(ushort pduRef, ushort maxCalling, ushort maxCalled, ushort maxPdu)
{
PduRef = pduRef;
MaxCalling = maxCalling;
@@ -135,9 +135,9 @@ namespace ModBus.Net.Simense
public ushort MaxPdu { get; private set; }
}
internal class EstablishAssociationSimenseOutputStruct : OutputStruct
internal class EstablishAssociationSiemensOutputStruct : OutputStruct
{
public EstablishAssociationSimenseOutputStruct(ushort pduRef, ushort maxCalling, ushort maxCalled, ushort maxPdu)
public EstablishAssociationSiemensOutputStruct(ushort pduRef, ushort maxCalling, ushort maxCalled, ushort maxPdu)
{
PduRef = pduRef;
MaxCalling = maxCalling;
@@ -151,11 +151,11 @@ namespace ModBus.Net.Simense
public ushort MaxPdu { get; private set; }
}
internal class EstablishAssociationSimenseProtocal : ProtocalUnit
internal class EstablishAssociationSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (EstablishAssociationSimenseInputStruct) message;
var r_message = (EstablishAssociationSiemensInputStruct) message;
const byte protoId = 0x32;
const byte rosctr = 0x01;
const ushort redId = 0x0000;
@@ -179,13 +179,13 @@ namespace ModBus.Net.Simense
ushort maxCalling = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
ushort maxCalled = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
ushort maxPdu = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
return new EstablishAssociationSimenseOutputStruct(pduRef,maxCalling,maxCalled,maxPdu);
return new EstablishAssociationSiemensOutputStruct(pduRef,maxCalling,maxCalled,maxPdu);
}
}
public class ReadRequestSimenseInputStruct : InputStruct
public class ReadRequestSiemensInputStruct : InputStruct
{
public ReadRequestSimenseInputStruct(ushort pduRef, SimenseTypeCode getType, string startAddress, ushort getCount, AddressTranslator addressTranslator)
public ReadRequestSiemensInputStruct(ushort pduRef, SiemensTypeCode getType, string startAddress, ushort getCount, AddressTranslator addressTranslator)
{
PduRef = pduRef;
TypeCode = (byte) getType;
@@ -205,9 +205,9 @@ namespace ModBus.Net.Simense
public int Offset { get; private set; }
}
public class ReadRequestSimenseOutputStruct : OutputStruct
public class ReadRequestSiemensOutputStruct : OutputStruct
{
public ReadRequestSimenseOutputStruct(ushort pduRef, SimenseAccessResult accessResult, SimenseDataType dataType, ushort getLength, byte[] value)
public ReadRequestSiemensOutputStruct(ushort pduRef, SiemensAccessResult accessResult, SiemensDataType dataType, ushort getLength, byte[] value)
{
PduRef = pduRef;
AccessResult = accessResult;
@@ -217,17 +217,17 @@ namespace ModBus.Net.Simense
}
public ushort PduRef { get; private set; }
public SimenseAccessResult AccessResult { get; private set; }
public SimenseDataType DataType { get; private set; }
public SiemensAccessResult AccessResult { get; private set; }
public SiemensDataType DataType { get; private set; }
public ushort GetLength { get; private set; }
public byte[] GetValue { get; private set; }
}
public class ReadRequestSimenseProtocal : ProtocalUnit
public class ReadRequestSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (ReadRequestSimenseInputStruct) message;
var r_message = (ReadRequestSiemensInputStruct) message;
const byte protoId = 0x32;
const byte rosctr = 0x01;
const ushort redId = 0x0000;
@@ -261,14 +261,14 @@ namespace ModBus.Net.Simense
int byteLength = length/8;
var values = new Byte[byteLength];
Array.Copy(messageBytes, pos, values, 0, byteLength);
return new ReadRequestSimenseOutputStruct(pduRef, (SimenseAccessResult) accessResult,
(SimenseDataType) dataType, length, values);
return new ReadRequestSiemensOutputStruct(pduRef, (SiemensAccessResult) accessResult,
(SiemensDataType) dataType, length, values);
}
}
public class WriteRequestSimenseInputStruct : InputStruct
public class WriteRequestSiemensInputStruct : InputStruct
{
public WriteRequestSimenseInputStruct(ushort pduRef, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
public WriteRequestSiemensInputStruct(ushort pduRef, string startAddress, object[] writeValue, AddressTranslator addressTranslator)
{
PduRef = pduRef;
var address = addressTranslator.AddressTranslate(startAddress, true);
@@ -286,24 +286,24 @@ namespace ModBus.Net.Simense
public object[] WriteValue { get; private set; }
}
public class WriteRequestSimenseOutputStruct : OutputStruct
public class WriteRequestSiemensOutputStruct : OutputStruct
{
public WriteRequestSimenseOutputStruct(ushort pduRef, SimenseAccessResult accessResult)
public WriteRequestSiemensOutputStruct(ushort pduRef, SiemensAccessResult accessResult)
{
PduRef = pduRef;
AccessResult = accessResult;
}
public ushort PduRef { get; private set; }
public SimenseAccessResult AccessResult {get; private set; }
public SiemensAccessResult AccessResult {get; private set; }
}
public class WriteRequestSimenseProtocal : ProtocalUnit
public class WriteRequestSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
var r_message = (WriteRequestSimenseInputStruct) message;
var r_message = (WriteRequestSiemensInputStruct) message;
byte[] valueBytes = ValueHelper.Instance.ObjectArrayToByteArray(r_message.WriteValue);
const byte protoId = 0x32;
const byte rosctr = 0x01;
@@ -316,14 +316,14 @@ namespace ModBus.Net.Simense
const byte variableSpec = 0x12;
const byte vAddrLg = 0x0A;
const byte syntaxId = 0x10;
const byte typeR = (byte)SimenseTypeCode.Byte;
const byte typeR = (byte)SiemensTypeCode.Byte;
ushort numberOfElements = (ushort)valueBytes.Length;
ushort dbBlock = r_message.DbBlock;
byte area = r_message.Area;
int offsetBit = r_message.Offset * 8;
byte[] offsetBitBytes = ValueHelper.Instance.GetBytes(offsetBit);
const byte reserved = 0x00;
const byte type = (byte)SimenseDataType.OtherAccess;
const byte type = (byte)SiemensDataType.OtherAccess;
ushort numberOfWriteBits = (ushort)(valueBytes.Length*8);
return Format(new byte[7], protoId, rosctr, redId, pduRef, parLg, datLg, serviceId, numberOfVariables
, variableSpec, vAddrLg, syntaxId, typeR, numberOfElements, dbBlock, area,
@@ -336,13 +336,13 @@ namespace ModBus.Net.Simense
ushort pduRef = ValueHelper.Instance.GetUShort(messageBytes, ref pos);
pos = 14;
byte accessResult = ValueHelper.Instance.GetByte(messageBytes, ref pos);
return new WriteRequestSimenseOutputStruct(pduRef, (SimenseAccessResult)accessResult);
return new WriteRequestSiemensOutputStruct(pduRef, (SiemensAccessResult)accessResult);
}
}
public class ReadTimeSimenseInputStruct : InputStruct
public class ReadTimeSiemensInputStruct : InputStruct
{
public ReadTimeSimenseInputStruct(ushort pduRef)
public ReadTimeSiemensInputStruct(ushort pduRef)
{
PduRef = pduRef;
}
@@ -350,9 +350,9 @@ namespace ModBus.Net.Simense
public ushort PduRef { get; private set; }
}
public class ReadTimeSimenseOutputStruct : OutputStruct
public class ReadTimeSiemensOutputStruct : OutputStruct
{
public ReadTimeSimenseOutputStruct(ushort pduRef, DateTime dateTime, TodClockStatus todClockStatus)
public ReadTimeSiemensOutputStruct(ushort pduRef, DateTime dateTime, TodClockStatus todClockStatus)
{
PduRef = pduRef;
DateTime = dateTime;
@@ -364,7 +364,7 @@ namespace ModBus.Net.Simense
public TodClockStatus TodClockStatus { get; private set; }
}
public class ReadTimeSimenseProtocal : ProtocalUnit
public class ReadTimeSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
@@ -377,9 +377,9 @@ namespace ModBus.Net.Simense
}
}
public class WriteTimeSimenseInputStruct : InputStruct
public class WriteTimeSiemensInputStruct : InputStruct
{
public WriteTimeSimenseInputStruct(ushort pduRef, DateTime dateTime, TodClockStatus todClockStatus)
public WriteTimeSiemensInputStruct(ushort pduRef, DateTime dateTime, TodClockStatus todClockStatus)
{
PduRef = pduRef;
DateTime = dateTime;
@@ -391,9 +391,9 @@ namespace ModBus.Net.Simense
public TodClockStatus TodClockStatus { get; private set; }
}
public class WriteTimeSimenseOutputStruct : OutputStruct
public class WriteTimeSiemensOutputStruct : OutputStruct
{
public WriteTimeSimenseOutputStruct(ushort pduRef, byte errCod)
public WriteTimeSiemensOutputStruct(ushort pduRef, byte errCod)
{
PduRef = pduRef;
ErrCod = errCod;
@@ -403,7 +403,7 @@ namespace ModBus.Net.Simense
public byte ErrCod { get;private set; }
}
public class WriteTimeSimenseProtocal : ProtocalUnit
public class WriteTimeSiemensProtocal : ProtocalUnit
{
public override byte[] Format(InputStruct message)
{
@@ -416,7 +416,7 @@ namespace ModBus.Net.Simense
}
}
public class SimenseProtocalErrorException : ProtocalErrorException
public class SiemensProtocalErrorException : ProtocalErrorException
{
public int ErrorClass { get; private set; }
public int ErrorCode { get; private set; }
@@ -436,7 +436,7 @@ namespace ModBus.Net.Simense
{0xEF, "Layer 2 specific error"},
};
public SimenseProtocalErrorException(int errCls, int errCod)
public SiemensProtocalErrorException(int errCls, int errCod)
: base(ProtocalErrorDictionary[errCls] + " : " + errCod)
{
ErrorClass = errCls;

View File

@@ -1,8 +1,8 @@
using System;
namespace ModBus.Net.Simense
namespace ModBus.Net.Siemens
{
public class SimenseTcpProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
public class SiemensTcpProtocalLinkerBytesExtend : ProtocalLinkerBytesExtend
{
public override byte[] BytesExtend(byte[] content)
{

View File

@@ -1,4 +1,4 @@
namespace ModBus.Net.Simense
namespace ModBus.Net.Siemens
{
public struct TodClockStatus
{

View File

@@ -1,8 +1,8 @@
using System.Threading.Tasks;
namespace ModBus.Net.Simense
namespace ModBus.Net.Siemens
{
public class SimenseTcpProtocal : SimenseProtocal
public class SiemensTcpProtocal : SiemensProtocal
{
private ushort _taspSrc;
private ushort _tsapDst;
@@ -14,11 +14,11 @@ namespace ModBus.Net.Simense
private string _ip;
private int connectTryCount;
public SimenseTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ConfigurationManager.IP)
public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu) : this(tdpuSize, tsapSrc, tsapDst, maxCalling, maxCalled, maxPdu, ConfigurationManager.IP)
{
}
public SimenseTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu, string ip)
public SiemensTcpProtocal(byte tdpuSize, ushort tsapSrc, ushort tsapDst, ushort maxCalling, ushort maxCalled, ushort maxPdu, string ip)
{
_taspSrc = tsapSrc;
_tsapDst = tsapDst;
@@ -72,24 +72,24 @@ namespace ModBus.Net.Simense
public override async Task<bool> ConnectAsync()
{
connectTryCount++;
ProtocalLinker = new SimenseTcpProtocalLinker(_ip);
ProtocalLinker = new SiemensTcpProtocalLinker(_ip);
if (await ProtocalLinker.ConnectAsync())
{
connectTryCount = 0;
var inputStruct = new CreateReferenceSimenseInputStruct(_tdpuSize, _taspSrc, _tsapDst);
var inputStruct = new CreateReferenceSiemensInputStruct(_tdpuSize, _taspSrc, _tsapDst);
return
await await
ForceSendReceiveAsync(this[typeof (CreateReferenceSimenseProtocal)], inputStruct)
ForceSendReceiveAsync(this[typeof (CreateReferenceSiemensProtocal)], inputStruct)
.ContinueWith(async answer =>
{
if (!ProtocalLinker.IsConnected) return false;
var inputStruct2 = new EstablishAssociationSimenseInputStruct(0x0101, _maxCalling,
var inputStruct2 = new EstablishAssociationSiemensInputStruct(0x0101, _maxCalling,
_maxCalled,
_maxPdu);
var outputStruct2 =
(EstablishAssociationSimenseOutputStruct)
(EstablishAssociationSiemensOutputStruct)
await
SendReceiveAsync(this[typeof (EstablishAssociationSimenseProtocal)],
SendReceiveAsync(this[typeof (EstablishAssociationSiemensProtocal)],
inputStruct2);
return true;
});

View File

@@ -1,8 +1,8 @@
using System;
namespace ModBus.Net.Simense
namespace ModBus.Net.Siemens
{
public class SimenseTcpProtocalLinker : TcpProtocalLinker
public class SiemensTcpProtocalLinker : TcpProtocalLinker
{
public override bool CheckRight(byte[] content)
{
@@ -17,10 +17,10 @@ namespace ModBus.Net.Simense
{
case 0x03:
if (content[17] == 0x00 && content[18] == 0x00) return true;
throw new SimenseProtocalErrorException(content[17],content[18]);
throw new SiemensProtocalErrorException(content[17],content[18]);
case 0x07:
if (content[27] == 0x00 && content[28] == 0x00) return true;
throw new SimenseProtocalErrorException(content[27],content[28]);
throw new SiemensProtocalErrorException(content[27],content[28]);
}
return true;
default:
@@ -28,7 +28,7 @@ namespace ModBus.Net.Simense
}
}
public SimenseTcpProtocalLinker(string ip)
public SiemensTcpProtocalLinker(string ip)
: base(ip, 102)
{

View File

@@ -1,16 +1,16 @@
using System;
using System.Threading.Tasks;
namespace ModBus.Net.Simense
namespace ModBus.Net.Siemens
{
public enum SimenseType
public enum SiemensType
{
Ppi = 0,
Mpi = 1,
Tcp = 2
};
public enum SimenseMachineModel
public enum SiemensMachineModel
{
S7_200 = 0,
S7_200_Smart = 1,
@@ -21,7 +21,7 @@ namespace ModBus.Net.Simense
};
public class SimenseUtility : BaseUtility
public class SiemensUtility : BaseUtility
{
private byte _tdpuSize;
private ushort _taspSrc;
@@ -30,42 +30,42 @@ namespace ModBus.Net.Simense
private ushort _maxCalled;
private ushort _maxPdu;
private SimenseType _simenseType;
private SiemensType _siemensType;
public SimenseType ConnectionType
public SiemensType ConnectionType
{
get
{
return _simenseType;
return _siemensType;
}
set
{
_simenseType = value;
switch (_simenseType)
_siemensType = value;
switch (_siemensType)
{
case SimenseType.Ppi:
case SiemensType.Ppi:
{
throw new NotImplementedException();
}
case SimenseType.Mpi:
case SiemensType.Mpi:
{
throw new NotImplementedException();
}
case SimenseType.Tcp:
case SiemensType.Tcp:
{
Wrapper = ConnectionString == null ? new SimenseTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu) : new SimenseTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu, ConnectionString);
Wrapper = ConnectionString == null ? new SiemensTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu) : new SiemensTcpProtocal(_tdpuSize, _taspSrc, _tsapDst, _maxCalling, _maxCalled, _maxPdu, ConnectionString);
break;
}
}
}
}
public SimenseUtility(SimenseType connectionType, string connectionString, SimenseMachineModel model)
public SiemensUtility(SiemensType connectionType, string connectionString, SiemensMachineModel model)
{
ConnectionString = connectionString;
switch (model)
{
case SimenseMachineModel.S7_200:
case SiemensMachineModel.S7_200:
{
_tdpuSize = 0x09;
_taspSrc = 0x1001;
@@ -75,8 +75,8 @@ namespace ModBus.Net.Simense
_maxPdu = 0x03c0;
break;
}
case SimenseMachineModel.S7_300:
case SimenseMachineModel.S7_400:
case SiemensMachineModel.S7_300:
case SiemensMachineModel.S7_400:
{
_tdpuSize = 0x1a;
_taspSrc = 0x4b54;
@@ -86,8 +86,8 @@ namespace ModBus.Net.Simense
_maxPdu = 0x00f0;
break;
}
case SimenseMachineModel.S7_1200:
case SimenseMachineModel.S7_1500:
case SiemensMachineModel.S7_1200:
case SiemensMachineModel.S7_1500:
{
_tdpuSize = 0x09;
_taspSrc = 0x4b54;
@@ -99,23 +99,23 @@ namespace ModBus.Net.Simense
}
}
ConnectionType = connectionType;
AddressTranslator = new AddressTranslatorSimense();
AddressTranslator = new AddressTranslatorSiemens();
}
public override void SetConnectionType(int connectionType)
{
ConnectionType = (SimenseType) connectionType;
ConnectionType = (SiemensType) connectionType;
}
protected override async Task<byte[]> GetDatasAsync(byte belongAddress, byte materAddress, string startAddress, int getByteCount)
{
try
{
var readRequestSimenseInputStruct = new ReadRequestSimenseInputStruct(0xd3c7, SimenseTypeCode.Byte, startAddress, (ushort)getByteCount, AddressTranslator);
var readRequestSimenseOutputStruct =
(ReadRequestSimenseOutputStruct) await
Wrapper.SendReceiveAsync(Wrapper[typeof(ReadRequestSimenseProtocal)], readRequestSimenseInputStruct);
return readRequestSimenseOutputStruct.GetValue;
var readRequestSiemensInputStruct = new ReadRequestSiemensInputStruct(0xd3c7, SiemensTypeCode.Byte, startAddress, (ushort)getByteCount, AddressTranslator);
var readRequestSiemensOutputStruct =
(ReadRequestSiemensOutputStruct) await
Wrapper.SendReceiveAsync(Wrapper[typeof(ReadRequestSiemensProtocal)], readRequestSiemensInputStruct);
return readRequestSiemensOutputStruct.GetValue;
}
catch (Exception)
{
@@ -127,11 +127,11 @@ namespace ModBus.Net.Simense
{
try
{
var writeRequestSimenseInputStruct = new WriteRequestSimenseInputStruct(0xd3c8, startAddress, setContents, AddressTranslator);
var writeRequestSimenseOutputStruct =
(WriteRequestSimenseOutputStruct) await
Wrapper.SendReceiveAsync(Wrapper[typeof(WriteRequestSimenseProtocal)], writeRequestSimenseInputStruct);
if (writeRequestSimenseOutputStruct.AccessResult == SimenseAccessResult.NoError)
var writeRequestSiemensInputStruct = new WriteRequestSiemensInputStruct(0xd3c8, startAddress, setContents, AddressTranslator);
var writeRequestSiemensOutputStruct =
(WriteRequestSiemensOutputStruct) await
Wrapper.SendReceiveAsync(Wrapper[typeof(WriteRequestSiemensProtocal)], writeRequestSiemensInputStruct);
if (writeRequestSiemensOutputStruct.AccessResult == SiemensAccessResult.NoError)
return true;
else
return false;

View File

@@ -1,21 +0,0 @@
using System.Collections.Generic;
namespace ModBus.Net.Simense
{
public class SimenseMachine : BaseMachine
{
public SimenseMachine(SimenseType connectionType, string connectionString, SimenseMachineModel model,
IEnumerable<AddressUnit> getAddresses, bool keepConnect) : base(getAddresses, keepConnect)
{
BaseUtility = new SimenseUtility(connectionType, connectionString, model);
AddressFormater = new AddressFormaterSimense();
AddressCombiner = new AddressCombinerContinus();
}
public SimenseMachine(SimenseType connectionType, string connectionString, SimenseMachineModel model,
IEnumerable<AddressUnit> getAddresses)
: this(connectionType, connectionString, model, getAddresses, false)
{
}
}
}

View File

@@ -12,7 +12,7 @@ namespace ModBus.Net
public static int Restore = 0;
}
public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
/*public class LimitedConcurrencyLevelTaskScheduler : TaskScheduler
{
/// <summary>
/// Whether the current thread is processing work items.
@@ -161,21 +161,36 @@ namespace ModBus.Net
if (lockTaken) Monitor.Exit(_tasks);
}
}
}
}*/
public class TaskManager
{
/// <summary>
/// 正在运行的设备
/// </summary>
private HashSet<BaseMachine> _machines;
/// <summary>
/// 不在运行的设备
/// </summary>
private HashSet<BaseMachine> _unlinkedMachines;
private TaskFactory<Dictionary<string,ReturnUnit>> _tasks;
//private TaskFactory<Dictionary<string,ReturnUnit>> _tasks;
private TaskScheduler _scheduler;
private CancellationTokenSource _cts;
//private CancellationTokenSource _cts;
/// <summary>
/// 正常读取的计时器
/// </summary>
private Timer _timer;
/// <summary>
/// 重连计时器
/// </summary>
private Timer _timer2;
private bool _keepConnect;
/// <summary>
/// 保持连接
/// </summary>
public bool KeepConnect
{
get { return _keepConnect; }
@@ -200,7 +215,7 @@ namespace ModBus.Net
private int _getCycle;
/// <summary>
/// 毫秒
/// 获取间隔,毫秒
/// </summary>
public int GetCycle
{
@@ -237,14 +252,15 @@ namespace ModBus.Net
{
_getCycle = value;
}
_timer = new Timer(MaintainTasks, null, 0, _getCycle * 1000);
_timer2 = new Timer(MaintainTasks2, null, _getCycle * 2000, _getCycle * 2000);
_timer = new Timer(MaintainTasks, null, 0, _getCycle);
_timer2 = new Timer(MaintainTasks2, null, _getCycle * 2, _getCycle * 2);
//调试行,调试时请注释上面两行并取消下面一行的注释,每台设备只会执行一次数据获取。
//MaintainTasks(null);
}
}
}
public int MaxRunningTasks
/*public int MaxRunningTasks
{
get { return _scheduler.MaximumConcurrencyLevel; }
set
@@ -252,17 +268,27 @@ namespace ModBus.Net
TaskStop();
_scheduler = new LimitedConcurrencyLevelTaskScheduler(value);
}
}
}*/
public TaskManager(int maxRunningTask, int getCycle, bool keepConnect)
/// <summary>
/// 构造一个TaskManager
/// </summary>
/// <param name="maxRunningTask">同时可以运行的任务数</param>
/// <param name="getCycle">读取数据的时间间隔(秒)</param>
/// <param name="keepConnect">读取数据后是否保持连接</param>
public TaskManager(/*int maxRunningTask,*/ int getCycle, bool keepConnect)
{
_scheduler = new LimitedConcurrencyLevelTaskScheduler(maxRunningTask);
//_scheduler = new LimitedConcurrencyLevelTaskScheduler(maxRunningTask);
_machines = new HashSet<BaseMachine>(new BaseMachineEqualityComparer());
_unlinkedMachines = new HashSet<BaseMachine>(new BaseMachineEqualityComparer());
_getCycle = getCycle;
KeepConnect = keepConnect;
}
/// <summary>
/// 添加一台设备
/// </summary>
/// <param name="machine">设备</param>
public void AddMachine(BaseMachine machine)
{
machine.KeepConnect = KeepConnect;
@@ -272,6 +298,10 @@ namespace ModBus.Net
}
}
/// <summary>
/// 添加多台设备
/// </summary>
/// <param name="machines">设备的列表</param>
public void AddMachines(IEnumerable<BaseMachine> machines)
{
lock (_machines)
@@ -283,20 +313,36 @@ namespace ModBus.Net
}
}
/// <summary>
/// 根据设备的连接地址移除设备
/// </summary>
/// <param name="machineToken">设备的连接地址</param>
public void RemoveMachineWithToken(string machineToken)
{
lock (_machines)
{
_machines.RemoveWhere(p => p.ConnectionToken == machineToken);
}
lock (_unlinkedMachines)
{
_unlinkedMachines.RemoveWhere(p => p.ConnectionToken == machineToken);
}
}
/// <summary>
/// 根据设备的id移除设备
/// </summary>
/// <param name="id">设备的id</param>
public void RemoveMachineWithId(int id)
{
lock (_machines)
{
_machines.RemoveWhere(p => p.Id == id);
}
lock (_unlinkedMachines)
{
_unlinkedMachines.RemoveWhere(p => p.Id == id);
}
}
public void MoveMachineToUnlinked(int id)
@@ -335,12 +381,20 @@ namespace ModBus.Net
}
}
/// <summary>
/// 移除设备
/// </summary>
/// <param name="machine">设备的实例</param>
public void RemoveMachine(BaseMachine machine)
{
lock (_machines)
{
_machines.Remove(machine);
}
lock (_unlinkedMachines)
{
_unlinkedMachines.Remove(machine);
}
}
private void MaintainTasks(object sender)
@@ -380,7 +434,7 @@ namespace ModBus.Net
try
{
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(30));
cts.CancelAfter(TimeSpan.FromSeconds(_getCycle * 10));
await RunTask(machine).WithCancellation(cts.Token);
}
catch
@@ -393,8 +447,8 @@ namespace ModBus.Net
public void TaskStart()
{
TaskStop();
_cts = new CancellationTokenSource();
_tasks = new TaskFactory<Dictionary<string,ReturnUnit>>(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler);
//_cts = new CancellationTokenSource();
//_tasks = new TaskFactory<Dictionary<string,ReturnUnit>>(_cts.Token, TaskCreationOptions.None, TaskContinuationOptions.None, _scheduler);
GetCycle = TimeRestore.Restore;
}
@@ -403,10 +457,10 @@ namespace ModBus.Net
lock (_machines)
{
GetCycle = Timeout.Infinite;
if (_cts != null)
{
_cts.Cancel();
}
//if (_cts != null)
//{
// _cts.Cancel();
//}
if (_machines != null)
{
foreach (var machine in _machines)
@@ -414,7 +468,7 @@ namespace ModBus.Net
machine.Disconnect();
}
}
_tasks = null;
//_tasks = null;
}
}
@@ -422,9 +476,13 @@ namespace ModBus.Net
{
try
{
//调试代码,调试时取消下面一下代码的注释,会同步调用获取数据。
//var ans = machine.GetDatas();
//设置Cancellation Token
CancellationTokenSource cts = new CancellationTokenSource();
//超时后取消任务
cts.CancelAfter(TimeSpan.FromSeconds(_getCycle));
//读取数据
var ans = await machine.GetDatasAsync().WithCancellation(cts.Token);
if (!machine.IsConnected)
{

View File

@@ -11,7 +11,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NA200H.UI.WPF", "NA200H.UI.
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CrossLampControl.WebApi", "CrossLampControl.WebApi\CrossLampControl.WebApi.csproj", "{252FDEE7-8671-46D3-A05B-CB7668804700}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simense_S7_200.UI.WPF.TaskTest", "Simense_S7_200.UI.WPF.TaskTest\Simense_S7_200.UI.WPF.TaskTest.csproj", "{02CE1787-291A-47CB-A7F7-929DA1D920A2}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Siemens_S7_200.UI.WPF.TaskTest", "Simense_S7_200.UI.WPF.TaskTest\Siemens_S7_200.UI.WPF.TaskTest.csproj", "{02CE1787-291A-47CB-A7F7-929DA1D920A2}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{64472271-8B95-4036-ACF9-C10941C1DB0A}"
ProjectSection(SolutionItems) = preProject

View File

@@ -59,7 +59,7 @@ namespace NA200H.UI.ConsoleApp
//第一步:先生成一个输入结构体,然后向这个结构体中填写数据
AddressTranslator addressTranslator = new AddressTranslatorNA200H();
ReadDataModbusInputStruct readCoilStatusInputStruct = new ReadDataModbusInputStruct(0x02, "N1", 0x0a, addressTranslator);
ReadDataModbusInputStruct readCoilStatusInputStruct = new ReadDataModbusInputStruct(0x02, "N 1", 0x0a, addressTranslator);
//第二步:再生成一个输出结构体,执行相应协议的发送指令,并将输出信息自动转换到输出结构体中
ReadDataModbusOutputStruct readCoilStatusOutputStruct = (ReadDataModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(ReadDataModbusProtocal)], readCoilStatusInputStruct);
//第三步:读取这个输出结构体的信息。
@@ -75,7 +75,7 @@ namespace NA200H.UI.ConsoleApp
Console.Read();
Console.Read();
ReadDataModbusInputStruct readHoldRegisterInputStruct = new ReadDataModbusInputStruct(0x02, "NW1", 4, addressTranslator);
ReadDataModbusInputStruct readHoldRegisterInputStruct = new ReadDataModbusInputStruct(0x02, "NW 1", 4, addressTranslator);
ReadDataModbusOutputStruct readHoldRegisterOutputStruct = (ReadDataModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(ReadDataModbusProtocal)], readHoldRegisterInputStruct);
ushort[] array2 =
ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(
@@ -89,7 +89,7 @@ namespace NA200H.UI.ConsoleApp
Console.Read();
Console.Read();
WriteDataModbusInputStruct writeMultiCoilInputStruct = new WriteDataModbusInputStruct(0x02, "Q20", new object[] { true, false, true, true, false, false, true, true, true, false }, addressTranslator);
WriteDataModbusInputStruct writeMultiCoilInputStruct = new WriteDataModbusInputStruct(0x02, "Q 20", new object[] { true, false, true, true, false, false, true, true, true, false }, addressTranslator);
WriteDataModbusOutputStruct writeMultiCoilOutputStruct = (WriteDataModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(WriteDataModbusProtocal)], writeMultiCoilInputStruct);
Console.WriteLine(writeMultiCoilOutputStruct.StartAddress);
Console.WriteLine(writeMultiCoilOutputStruct.WriteCount);
@@ -97,7 +97,7 @@ namespace NA200H.UI.ConsoleApp
Console.Read();
Console.Read();
WriteDataModbusInputStruct writeMultiRegisterInputStruct = new WriteDataModbusInputStruct(0x02, "NW1", new object[] { (ushort)25, (ushort)18, (ushort)17 }, addressTranslator);
WriteDataModbusInputStruct writeMultiRegisterInputStruct = new WriteDataModbusInputStruct(0x02, "NW 1", new object[] { (ushort)25, (ushort)18, (ushort)17 }, addressTranslator);
WriteDataModbusOutputStruct writeMultiRegisterOutputStruct = (WriteDataModbusOutputStruct)wrapper.SendReceive(wrapper[typeof(WriteDataModbusProtocal)], writeMultiRegisterInputStruct);
Console.WriteLine(writeMultiRegisterOutputStruct.StartAddress);
Console.WriteLine(writeMultiRegisterOutputStruct.WriteCount);
@@ -119,17 +119,17 @@ namespace NA200H.UI.ConsoleApp
Console.Read();
*/
/*BaseProtocal wrapper = new SimenseTcpProtocal(0x09, 0x1001, 0x1000, 0x0001, 0x0001, 0x03c0, ip);
/*BaseProtocal wrapper = new SiemensTcpProtocal(0x09, 0x1001, 0x1000, 0x0001, 0x0001, 0x03c0, ip);
if (!wrapper.ProtocalLinker.IsConnected) return;
AddressTranslator addressTranslator = new AddressTranslatorSimense();
AddressTranslator addressTranslator = new AddressTranslatorSiemens();
var readRequestSimenseInputStruct = new ReadRequestSimenseInputStruct(0xaacc, SimenseTypeCode.Byte, "V0", 4, addressTranslator);
var readRequestSimenseOutputStruct =
(ReadRequestSimenseOutputStruct)
wrapper.SendReceive(wrapper[typeof(ReadRequestSimenseProtocal)], readRequestSimenseInputStruct);
var readRequestSiemensInputStruct = new ReadRequestSiemensInputStruct(0xaacc, SiemensTypeCode.Byte, "V 0", 4, addressTranslator);
var readRequestSiemensOutputStruct =
(ReadRequestSiemensOutputStruct)
wrapper.SendReceive(wrapper[typeof(ReadRequestSiemensProtocal)], readRequestSiemensInputStruct);
ushort[] array =
ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(
ValueHelper.Instance.ByteArrayToObjectArray(readRequestSimenseOutputStruct.GetValue,
ValueHelper.Instance.ByteArrayToObjectArray(readRequestSiemensOutputStruct.GetValue,
new KeyValuePair<Type, int>(typeof (ushort), 2)));
for (int i = 0; i < array.Length; i++)
{
@@ -138,12 +138,12 @@ namespace NA200H.UI.ConsoleApp
Console.Read();
Console.Read();
var writeRequestSimenseInputStruct = new WriteRequestSimenseInputStruct(0xaadd, "V100",
var writeRequestSiemensInputStruct = new WriteRequestSiemensInputStruct(0xaadd, "V 100",
new object[] { (ushort)280, (ushort)12, (ushort)56, (ushort)72, (ushort)88, (ushort)525, (ushort)477, (ushort)151, (ushort)52 }, addressTranslator);
var writeRequestSimenseOutputStruct =
(WriteRequestSimenseOutputStruct)
wrapper.SendReceive(wrapper[typeof(WriteRequestSimenseProtocal)], writeRequestSimenseInputStruct);
Console.WriteLine(writeRequestSimenseOutputStruct.AccessResult.ToString());
var writeRequestSiemensOutputStruct =
(WriteRequestSiemensOutputStruct)
wrapper.SendReceive(wrapper[typeof(WriteRequestSiemensProtocal)], writeRequestSiemensInputStruct);
Console.WriteLine(writeRequestSiemensOutputStruct.AccessResult.ToString());
Console.Read();
Console.Read();
*/

View File

@@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Threading;
using ModBus.Net;
using System.Windows;
using ModBus.Net.Simense;
using ModBus.Net.Siemens;
namespace NA200H.UI.WPF
@@ -23,10 +23,10 @@ namespace NA200H.UI.WPF
{
//utility = new ModbusUtility(ModbusType.Tcp, "192.168.3.247");
//utility.AddressTranslator = new AddressTranslatorNA200H();
//object[] getNum = utility.GetDatas(0x02, 0x00, "NW1", new KeyValuePair<Type, int>(typeof(ushort), 4));
utility = new SimenseUtility(SimenseType.Tcp, "192.168.3.191", SimenseMachineModel.S7_200);
utility.AddressTranslator = new AddressTranslatorSimense();
object[] getNum = utility.GetDatas(0x02, 0x00, "V1", new KeyValuePair<Type, int>(typeof(ushort), 4));
//object[] getNum = utility.GetDatas(0x02, 0x00, "NW 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
utility = new SiemensUtility(SiemensType.Tcp, "192.168.3.191", SiemensMachineModel.S7_200);
utility.AddressTranslator = new AddressTranslatorSiemens();
object[] getNum = utility.GetDatas(0x02, 0x00, "V 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
ushort[] getNumUshorts = ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNum);
SetValue(getNumUshorts);
}
@@ -45,11 +45,11 @@ namespace NA200H.UI.WPF
ushort.TryParse(Add1.Text, out add1);
ushort.TryParse(Add2.Text, out add2);
ushort.TryParse(Add3.Text, out add3);
//utility.SetDatas(0x02, 0x00, "NW1", new object[] { add1, add2, add3 });
utility.SetDatas(0x02, 0x00, "V1", new object[] { add1, add2, add3 });
//utility.SetDatas(0x02, 0x00, "NW 1", new object[] { add1, add2, add3 });
utility.SetDatas(0x02, 0x00, "V 1", new object[] { add1, add2, add3 });
Thread.Sleep(100);
//object[] getNum = utility.GetDatas(0x02, 0x00, "NW1", new KeyValuePair<Type, int>(typeof(ushort), 4));
object[] getNum = utility.GetDatas(0x02, 0x00, "V1", new KeyValuePair<Type, int>(typeof(ushort), 4));
//object[] getNum = utility.GetDatas(0x02, 0x00, "NW 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
object[] getNum = utility.GetDatas(0x02, 0x00, "V 1", new KeyValuePair<Type, int>(typeof(ushort), 4));
ushort[] getNumUshorts = ValueHelper.Instance.ObjectArrayToDestinationArray<ushort>(getNum);
SetValue(getNumUshorts);
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1"/>
</startup>
</configuration>
</configuration>

View File

@@ -1,4 +1,4 @@
<Application x:Class="Simense_S7_200.UI.WPF.TaskTest.App"
<Application x:Class="Siemens_S7_200.UI.WPF.TaskTest.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">

View File

@@ -6,7 +6,7 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows;
namespace Simense_S7_200.UI.WPF.TaskTest
namespace Siemens_S7_200.UI.WPF.TaskTest
{
/// <summary>
/// App.xaml 的交互逻辑

View File

@@ -1,8 +1,8 @@
<Window x:Class="Simense_S7_200.UI.WPF.TaskTest.MainWindow"
<Window x:Class="Siemens_S7_200.UI.WPF.TaskTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox x:Name="simenseItems" HorizontalAlignment="Left" Height="237" Margin="108,36,0,0" VerticalAlignment="Top" Width="145"/>
<ListBox x:Name="siemensItems" HorizontalAlignment="Left" Height="237" Margin="108,36,0,0" VerticalAlignment="Top" Width="145"/>
</Grid>
</Window>

View File

@@ -13,9 +13,9 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ModBus.Net;
using ModBus.Net.Simense;
using ModBus.Net.Siemens;
namespace Simense_S7_200.UI.WPF.TaskTest
namespace Siemens_S7_200.UI.WPF.TaskTest
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
@@ -34,9 +34,9 @@ namespace Simense_S7_200.UI.WPF.TaskTest
new AddressUnit() {Id = 1, Area = "V", Address = 2, CommunicationTag = "D2", DataType = typeof (float), Zoom = 1}
};
//初始化任务管理器
TaskManager task = new TaskManager(20, 300, true);
TaskManager task = new TaskManager(300, true);
//向任务管理器中添加设备
task.AddMachine(new SimenseMachine(SimenseType.Tcp, "192.168.3.191",SimenseMachineModel.S7_200, addressUnits,
task.AddMachine(new SiemensMachine(SiemensType.Tcp, "192.168.3.191",SiemensMachineModel.S7_200, addressUnits,
true));
//增加值返回时的处理函数
task.ReturnValues += (returnValues) =>
@@ -46,7 +46,7 @@ namespace Simense_S7_200.UI.WPF.TaskTest
if (returnValues.Value != null)
{
value = from val in returnValues.Value select val.Key + val.Value;
simenseItems.Dispatcher.Invoke(() => simenseItems.ItemsSource = value);
siemensItems.Dispatcher.Invoke(() => siemensItems.ItemsSource = value);
}
else
{

View File

@@ -7,11 +7,11 @@ using System.Windows;
// 有关程序集的常规信息通过以下
// 特性集控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Simense_S7_200.UI.WPF.TaskTest")]
[assembly: AssemblyTitle("Siemens_S7_200.UI.WPF.TaskTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Simense_S7_200.UI.WPF.TaskTest")]
[assembly: AssemblyProduct("Siemens_S7_200.UI.WPF.TaskTest")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

View File

@@ -1,17 +1,17 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.34209
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将丢失。
// 重新生成代码,这些更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Simense_S7_200.UI.WPF.TaskTest.Properties
{
namespace Siemens_S7_200.UI.WPF.TaskTest.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
@@ -22,48 +22,40 @@ namespace Simense_S7_200.UI.WPF.TaskTest.Properties
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
internal Resources() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Simense_S7_200.UI.WPF.TaskTest.Properties.Resources", typeof(Resources).Assembly);
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Siemens_S7_200.UI.WPF.TaskTest.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 为所有资源查找重写当前线程的 CurrentUICulture 属性,
/// 方法是使用此强类型资源类
/// 使用此强类型资源类,为所有资源查找
/// 重写当前线程的 CurrentUICulture 属性
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set
{
set {
resourceCulture = value;
}
}

View File

@@ -1,28 +1,24 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Simense_S7_200.UI.WPF.TaskTest.Properties
{
namespace Siemens_S7_200.UI.WPF.TaskTest.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
public static Settings Default {
get {
return defaultInstance;
}
}

View File

@@ -7,12 +7,13 @@
<ProjectGuid>{02CE1787-291A-47CB-A7F7-929DA1D920A2}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Simense_S7_200.UI.WPF.TaskTest</RootNamespace>
<AssemblyName>Simense_S7_200.UI.WPF.TaskTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<RootNamespace>Siemens_S7_200.UI.WPF.TaskTest</RootNamespace>
<AssemblyName>Siemens_S7_200.UI.WPF.TaskTest</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>

View File

@@ -17,7 +17,7 @@ Table of Content:
* Siemens Tcp protocal (acturally it is the same as Profinet)
* All communications can be asyncronized.
* A task manager that you can easily manage multiple connections.
* .net 4.5 and Visual Studio 2013 support (In the future, it will upgrade to .net 4.6 and Visual Studio 2015)
* .net 4.5 and Visual Studio 2013 support (In the future, it will be upgraded to .net 4.6 and Visual Studio 2015)
##<a name="usage"></a> Usage
@@ -73,22 +73,21 @@ The highest api that you can manage many PLC links and all links are async so th
The fastest way you can write is to use TaskManager. TaskTest Project is a good example.
```C#
List<AddressUnit> addressUnits = new List<AddressUnit>
{
new AddressUnit() {Id = 0, Area = "V", Address = 0, CommunicationTag = "D1", DataType = typeof (ushort), Zoom = 1},
new AddressUnit() {Id = 1, Area = "V", Address = 2, CommunicationTag = "D2", DataType = typeof (float), Zoom = 1}
};
TaskManager task = new TaskManager(20, 300, true);
task.AddMachine(new SimenseMachine(SimenseType.Tcp, "192.168.3.191",SimenseMachineModel.S7_200, addressUnits, true));
TaskManager task = new TaskManager(300, true);
task.AddMachine(new SiemensMachine(SiemensType.Tcp, "192.168.3.191",SiemensMachineModel.S7_200, addressUnits, true));
task.ReturnValues += (returnValues) =>
{
value = new List<string>();
if (returnValues.Value != null)
{
value = from val in returnValues.Value select val.Key + val.Value;
simenseItems.Dispatcher.Invoke(() => simenseItems.ItemsSource = value);
siemensItems.Dispatcher.Invoke(() => siemensItems.ItemsSource = value);
}
else
{
@@ -98,10 +97,11 @@ task.ReturnValues += (returnValues) =>
task.TaskStart();
```
Here are the details to use the TaskManager.
1. Initialize the task manager.
Three arguments are: the max tasks you can run in a same time; How long did the next send message call happens(milliseconds); and you should keep the connection when a single message called complete.
Three arguments are: <s>the max tasks you can run in a same time;</s> How long did the next send message call happens(milliseconds); and you should keep the connection when a single message called complete.
2. Add the addresses that you want to communicate to PLC. Area are defined in AddressTranslator in each type of communiction.
Basically you can write only Id, Area, Address, CommunicationTag, DataType and Zoom, and it should work. And there are other fields that you can use.
@@ -113,9 +113,9 @@ Add a machine like siemens machine to the task manager.
4. Implement ReturnValues event.
The argument return values is a key value pair. The architechture is:
Key : the link address of machine (in sample is the second parameter).<p>
Value : Dictionary.<p>
----------Key : CommunicationTag in AddressUnit.<p>
----------Value : ReturnUnit.<p>
---------------------PlcValue : The return data, all in double type.<p>
---------------------UnitExtend : UnitExtend in AddressUnit. You should cast this class to your own class extends by UnitExtend.
* Key : the link address of machine (in sample is the second parameter).<p>
* Value : Dictionary.<p>
* Key : CommunicationTag in AddressUnit.<p>
* Value : ReturnUnit.<p>
* PlcValue : The return data, all in double type.<p>
* UnitExtend : UnitExtend in AddressUnit. You should cast this class to your own class extends by UnitExtend.