Compare commits
10 Commits
e38c16e899
...
e7cad88bcf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7cad88bcf | ||
|
|
7f304e826f | ||
|
|
51ded333d9 | ||
|
|
62e6fcbfb1 | ||
|
|
0f757d6996 | ||
|
|
80d6e843af | ||
|
|
40b2b39d2b | ||
|
|
c3c4125a4b | ||
|
|
b4c57a42d0 | ||
|
|
21c8e34934 |
@@ -28,9 +28,9 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 是否为大端
|
||||
/// </summary>
|
||||
protected new bool LittleEndian => false;
|
||||
public override bool LittleEndian => true;
|
||||
|
||||
protected new bool LittleEndianBit => false;
|
||||
public override bool LittleEndianBit => false;
|
||||
|
||||
/// <summary>
|
||||
/// 覆盖的获取实例的方法
|
||||
@@ -154,9 +154,9 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 是否为大端
|
||||
/// </summary>
|
||||
protected new bool LittleEndian => true;
|
||||
public override bool LittleEndian => true;
|
||||
|
||||
protected new bool LittleEndianBit => false;
|
||||
public override bool LittleEndianBit => true;
|
||||
|
||||
/// <summary>
|
||||
/// 覆盖的获取实例的方法
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace Modbus.Net.HJ212
|
||||
{
|
||||
public class HJ212Controller : FifoController
|
||||
public class HJ212Controller : NoResponseController
|
||||
{
|
||||
public HJ212Controller(string ip, int port) : base(int.Parse(ConfigurationReader.GetValue("TCP:" + ip + ":" + port, "FetchSleepTime")))
|
||||
{
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace Modbus.Net.HJ212
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="connectionString">连接地址</param>
|
||||
public HJ212Machine(TKey id, string connectionString, string st, string cn, string pw, string mn)
|
||||
: base(id, null, true)
|
||||
public HJ212Machine(TKey id, string alias, string connectionString, string st, string cn, string pw, string mn)
|
||||
: base(id, alias, null, true)
|
||||
{
|
||||
BaseUtility = new HJ212Utility(connectionString);
|
||||
ST = st;
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
namespace Modbus.Net.HJ212
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Modbus.Net.HJ212
|
||||
{
|
||||
/// <summary>
|
||||
/// HJ212协议连接器
|
||||
@@ -9,6 +15,45 @@
|
||||
{
|
||||
}
|
||||
|
||||
public override async Task<byte[]> SendReceiveAsync(byte[] content)
|
||||
{
|
||||
if (content.Length <= 1000)
|
||||
return await base.SendReceiveAsync(content);
|
||||
else
|
||||
{
|
||||
string contentString = Encoding.ASCII.GetString(content);
|
||||
string[] formats = { "yyyyMMddHHmmssffff", "yyyyMMddHHmmssfff", "yyyyMMddHHmmss" };
|
||||
DateTime startTime = DateTime.ParseExact(contentString.Substring(3, 18), formats, CultureInfo.InvariantCulture, DateTimeStyles.None);
|
||||
int dataStartIdx = contentString.IndexOf("&&") + 2;
|
||||
string head = contentString.Substring(0, dataStartIdx).Substring(21);
|
||||
string[] contentUnitAll = contentString.Substring(dataStartIdx).Split(';')[1].Split(',');
|
||||
List<string> contentSplitAll = new List<string>();
|
||||
string newContent = "DataTime=" + startTime.ToString("yyyyMMddHHmmss") + ";";
|
||||
foreach (var contentUnit in contentUnitAll)
|
||||
{
|
||||
if (newContent.Length + contentUnit.Length > 1000 - dataStartIdx)
|
||||
{
|
||||
contentSplitAll.Add("QN=" + startTime.ToString("yyyyMMddHHmmssffff") + head + newContent[..^1]);
|
||||
startTime = startTime.AddSeconds(1);
|
||||
newContent = "DataTime=" + startTime.ToString("yyyyMMddHHmmss") + ";" + contentUnit + ",";
|
||||
}
|
||||
else
|
||||
{
|
||||
newContent += contentUnit + ",";
|
||||
}
|
||||
}
|
||||
contentSplitAll.Add("QN=" + startTime.ToString("yyyyMMddHHmmssffff") + head + newContent[..^1]);
|
||||
var receiveBytesAll = new List<byte>();
|
||||
foreach (var contentSplit in contentSplitAll)
|
||||
{
|
||||
var extBytes = BytesExtend(Encoding.ASCII.GetBytes(contentSplit));
|
||||
var receiveBytes = await SendReceiveWithoutExtAndDecAsync(extBytes);
|
||||
receiveBytesAll.AddRange(receiveBytes == null ? null : receiveBytes.Length == 0 ? receiveBytes : BytesDecact(receiveBytes));
|
||||
}
|
||||
return receiveBytesAll.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查接收的数据是否正确
|
||||
/// </summary>
|
||||
@@ -19,4 +64,4 @@
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,14 +33,14 @@ namespace Modbus.Net.HJ212
|
||||
{
|
||||
var writeRequestHJ212InputStruct =
|
||||
new WriteRequestHJ212InputStruct((string)setContents[0], (string)setContents[1], (string)setContents[2], (string)setContents[3], (List<Dictionary<string, string>>)setContents[4], (DateTime)setContents[5]);
|
||||
var writeRequestOpcOutputStruct =
|
||||
var writeRequestHJ212OutputStruct =
|
||||
await
|
||||
Wrapper.SendReceiveAsync<WriteRequestHJ212OutputStruct>(Wrapper[typeof(WriteRequestHJ212Protocol)],
|
||||
writeRequestHJ212InputStruct);
|
||||
return new ReturnStruct<bool>
|
||||
{
|
||||
Datas = writeRequestOpcOutputStruct?.GetValue != null,
|
||||
IsSuccess = writeRequestOpcOutputStruct?.GetValue != null,
|
||||
Datas = writeRequestHJ212OutputStruct?.GetValue != null,
|
||||
IsSuccess = writeRequestHJ212OutputStruct?.GetValue != null,
|
||||
ErrorCode = 0,
|
||||
ErrorMsg = null,
|
||||
};
|
||||
|
||||
@@ -20,10 +20,10 @@ namespace Modbus.Net.Modbus
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusMachine(TKey id, ModbusType connectionType, string connectionString,
|
||||
public ModbusMachine(TKey id, string alias, ModbusType connectionType, string connectionString,
|
||||
IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress,
|
||||
Endian endian)
|
||||
: base(id, getAddresses, keepConnect, slaveAddress, masterAddress)
|
||||
: base(id, alias, getAddresses, keepConnect, slaveAddress, masterAddress)
|
||||
{
|
||||
BaseUtility = new ModbusUtility(connectionType, connectionString, slaveAddress, masterAddress, endian);
|
||||
AddressFormater = new AddressFormaterModbus();
|
||||
@@ -41,10 +41,10 @@ namespace Modbus.Net.Modbus
|
||||
/// <param name="slaveAddress">从站号</param>
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="endian">端格式</param>
|
||||
public ModbusMachine(TKey id, ModbusType connectionType, string connectionString,
|
||||
public ModbusMachine(TKey id, string alias, ModbusType connectionType, string connectionString,
|
||||
IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, byte slaveAddress, byte masterAddress,
|
||||
Endian endian)
|
||||
: this(id, connectionType, connectionString, getAddresses, true, slaveAddress, masterAddress, endian)
|
||||
: this(id, alias, connectionType, connectionString, getAddresses, true, slaveAddress, masterAddress, endian)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata.Ecma335;
|
||||
using System.Threading.Tasks;
|
||||
using AddressUnit = Modbus.Net.AddressUnit<string, int, int>;
|
||||
using DataReturnDef = Modbus.Net.DataReturnDef<string, double>;
|
||||
@@ -11,8 +12,7 @@ namespace Modbus.Net.Modbus
|
||||
{
|
||||
public class ModbusRtuDataReceiver
|
||||
{
|
||||
private ModbusRtuProtocolReceiver _receiver;
|
||||
|
||||
private Dictionary<ModbusRtuProtocolReceiver, DateTime> _receivers;
|
||||
private readonly IConfigurationRoot configuration = new ConfigurationBuilder()
|
||||
.SetBasePath(Directory.GetCurrentDirectory())
|
||||
.AddJsonFile("appsettings.json")
|
||||
@@ -57,144 +57,158 @@ namespace Modbus.Net.Modbus
|
||||
}
|
||||
}
|
||||
|
||||
public ModbusRtuDataReceiver(MachineDataType dataType)
|
||||
public ModbusRtuDataReceiver(MachineDataType dataType, int minimumElapse = 0)
|
||||
{
|
||||
_receiver = new ModbusRtuProtocolReceiver(ConfigurationReader.GetValue("Receiver", "d:connectionString"), int.Parse(ConfigurationReader.GetValue("Receiver", "g:slaveAddress")));
|
||||
var machineName = ConfigurationReader.GetValue("Receiver", "a:id");
|
||||
var addressMapName = ConfigurationReader.GetValue("Receiver", "e:addressMap");
|
||||
var endian = ValueHelper.GetInstance(Endian.Parse(ConfigurationReader.GetValue("Receiver", "i:endian")));
|
||||
_receiver.DataProcess = receiveContent =>
|
||||
_receivers = new Dictionary<ModbusRtuProtocolReceiver,DateTime>();
|
||||
var receiversDef = configuration.GetSection("Modbus.Net").GetSection("Receiver").GetChildren();
|
||||
foreach (var receiverDef in receiversDef)
|
||||
{
|
||||
var returnTime = DateTime.Now;
|
||||
byte[] returnBytes = null;
|
||||
var readContent = new byte[receiveContent.Count * 2];
|
||||
var values = receiveContent.WriteContent;
|
||||
var valueDic = new Dictionary<string, double>();
|
||||
var returnDic = new Dictionary<string, ReturnUnit<double>>();
|
||||
List<AddressUnit> addressMap = AddressReader<string, int, int>.ReadAddresses(addressMapName).ToList();
|
||||
if (values != null)
|
||||
var machineName = receiverDef.GetValue<string>("a:id");
|
||||
var _receiver = new ModbusRtuProtocolReceiver(receiverDef.GetValue<string>("e:connectionString"), receiverDef.GetValue<int>("h:slaveAddress"));
|
||||
var addressMapName = receiverDef.GetValue<string>("f:addressMap");
|
||||
var endian = ValueHelper.GetInstance(Endian.Parse(receiverDef.GetValue<string>("j:endian")));
|
||||
_receiver.DataProcess = receiveContent =>
|
||||
{
|
||||
switch (receiveContent.FunctionCode)
|
||||
var returnTime = DateTime.Now;
|
||||
byte[] returnBytes = null;
|
||||
var readContent = new byte[receiveContent.Count * 2];
|
||||
var values = receiveContent.WriteContent;
|
||||
var valueDic = new Dictionary<string, double>();
|
||||
var returnDic = new Dictionary<string, ReturnUnit<double>>();
|
||||
List<AddressUnit> addressMap = AddressReader<string, int, int>.ReadAddresses(addressMapName).ToList();
|
||||
if (values != null)
|
||||
{
|
||||
case (byte)ModbusProtocolFunctionCode.WriteMultiRegister:
|
||||
{
|
||||
Array.Copy(receiveContent.WriteContent, 0, threex, receiveContent.StartAddress * 2, receiveContent.WriteContent.Length);
|
||||
returnBytes = new WriteDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.StartAddress, receiveContent.Count);
|
||||
break;
|
||||
}
|
||||
case (byte)ModbusProtocolFunctionCode.WriteSingleCoil:
|
||||
{
|
||||
if (receiveContent.WriteContent[0] == 255)
|
||||
{
|
||||
zerox[receiveContent.StartAddress] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
zerox[receiveContent.StartAddress] = false;
|
||||
}
|
||||
returnBytes = new WriteDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.StartAddress, receiveContent.WriteContent);
|
||||
break;
|
||||
}
|
||||
case (byte)ModbusProtocolFunctionCode.WriteMultiCoil:
|
||||
{
|
||||
var pos = 0;
|
||||
List<bool> bitList = new List<bool>();
|
||||
for (int i = 0; i < receiveContent.WriteByteCount; i++)
|
||||
{
|
||||
var bitArray = endian.GetBits(receiveContent.WriteContent, ref pos);
|
||||
bitList.AddRange(bitArray.ToList());
|
||||
}
|
||||
Array.Copy(bitList.ToArray(), 0, zerox, receiveContent.StartAddress, bitList.Count);
|
||||
returnBytes = new WriteDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.StartAddress, receiveContent.Count);
|
||||
break;
|
||||
}
|
||||
case (byte)ModbusProtocolFunctionCode.WriteSingleRegister:
|
||||
{
|
||||
Array.Copy(receiveContent.WriteContent, 0, threex, receiveContent.StartAddress * 2, receiveContent.Count * 2);
|
||||
returnBytes = new WriteDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.StartAddress, receiveContent.Count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < addressMap.Count; i++)
|
||||
switch (receiveContent.FunctionCode)
|
||||
{
|
||||
var pos = (addressMap[i].Address - 1) * 2;
|
||||
var subpos = addressMap[i].SubAddress;
|
||||
string valueString = null;
|
||||
if (addressMap[i].Area == "4X")
|
||||
{
|
||||
valueString = endian.GetValue(threex, ref pos, ref subpos, addressMap[i].DataType).ToString();
|
||||
}
|
||||
else if (addressMap[i].Area == "0X")
|
||||
{
|
||||
valueString = zerox[addressMap[i].Address - 1].ToString();
|
||||
}
|
||||
if (valueString == "True") valueString = "1";
|
||||
if (valueString == "False") valueString = "0";
|
||||
var value = double.Parse(valueString);
|
||||
value = value * addressMap[i].Zoom;
|
||||
value = Math.Round(value, addressMap[i].DecimalPos);
|
||||
AddValueToValueDic(valueDic, returnDic, addressMap[i], value, dataType);
|
||||
}
|
||||
if (ReturnValueDictionary != null)
|
||||
{
|
||||
var dataReturn = new DataReturnDef();
|
||||
dataReturn.MachineId = machineName;
|
||||
dataReturn.ReturnValues = new ReturnStruct<Dictionary<string, ReturnUnit<double>>>() { IsSuccess = true, Datas = returnDic };
|
||||
ReturnValueDictionary(dataReturn);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//_logger.LogError(ex, "Error");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (receiveContent.FunctionCode)
|
||||
{
|
||||
case (byte)ModbusProtocolFunctionCode.ReadHoldRegister:
|
||||
{
|
||||
Array.Copy(threex, receiveContent.StartAddress, readContent, 0, readContent.Length);
|
||||
returnBytes = new ReadDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, (byte)receiveContent.Count, readContent);
|
||||
break;
|
||||
}
|
||||
case (byte)ModbusProtocolFunctionCode.ReadCoilStatus:
|
||||
{
|
||||
var bitCount = receiveContent.WriteByteCount * 8;
|
||||
var boolContent = new bool[bitCount];
|
||||
Array.Copy(zerox, receiveContent.StartAddress, boolContent, 0, bitCount);
|
||||
var byteList = new List<byte>();
|
||||
for (int i = 0; i < receiveContent.WriteByteCount; i++)
|
||||
case (byte)ModbusProtocolFunctionCode.WriteMultiRegister:
|
||||
{
|
||||
byte result = 0;
|
||||
for (int j = i; j < i + 8; j++)
|
||||
Array.Copy(receiveContent.WriteContent, 0, threex, receiveContent.StartAddress * 2, receiveContent.WriteContent.Length);
|
||||
returnBytes = new WriteDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.StartAddress, receiveContent.Count);
|
||||
break;
|
||||
}
|
||||
case (byte)ModbusProtocolFunctionCode.WriteSingleCoil:
|
||||
{
|
||||
if (receiveContent.WriteContent[0] == 255)
|
||||
{
|
||||
// 将布尔值转换为对应的位
|
||||
|
||||
byte bit = boolContent[j] ? (byte)1 : (byte)0;
|
||||
|
||||
// 使用左移位运算将位合并到结果字节中
|
||||
|
||||
result = (byte)((result << 1) | bit);
|
||||
zerox[receiveContent.StartAddress] = true;
|
||||
}
|
||||
byteList.Add(result);
|
||||
else
|
||||
{
|
||||
zerox[receiveContent.StartAddress] = false;
|
||||
}
|
||||
returnBytes = new WriteDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.StartAddress, receiveContent.WriteContent);
|
||||
break;
|
||||
}
|
||||
readContent = byteList.ToArray();
|
||||
returnBytes = new ReadDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.WriteByteCount, readContent);
|
||||
break;
|
||||
case (byte)ModbusProtocolFunctionCode.WriteMultiCoil:
|
||||
{
|
||||
var pos = 0;
|
||||
List<bool> bitList = new List<bool>();
|
||||
for (int i = 0; i < receiveContent.WriteByteCount; i++)
|
||||
{
|
||||
var bitArray = endian.GetBits(receiveContent.WriteContent, ref pos);
|
||||
bitList.AddRange(bitArray.ToList());
|
||||
}
|
||||
Array.Copy(bitList.ToArray(), 0, zerox, receiveContent.StartAddress, bitList.Count);
|
||||
returnBytes = new WriteDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.StartAddress, receiveContent.Count);
|
||||
break;
|
||||
}
|
||||
case (byte)ModbusProtocolFunctionCode.WriteSingleRegister:
|
||||
{
|
||||
Array.Copy(receiveContent.WriteContent, 0, threex, receiveContent.StartAddress * 2, receiveContent.Count * 2);
|
||||
returnBytes = new WriteDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.StartAddress, receiveContent.Count);
|
||||
break;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < addressMap.Count; i++)
|
||||
{
|
||||
var pos = (addressMap[i].Address - 1) * 2;
|
||||
var subpos = addressMap[i].SubAddress;
|
||||
string valueString = null;
|
||||
if (addressMap[i].Area == "4X")
|
||||
{
|
||||
valueString = endian.GetValue(threex, ref pos, ref subpos, addressMap[i].DataType).ToString();
|
||||
}
|
||||
else if (addressMap[i].Area == "0X")
|
||||
{
|
||||
valueString = zerox[addressMap[i].Address - 1].ToString();
|
||||
}
|
||||
if (valueString == "True") valueString = "1";
|
||||
if (valueString == "False") valueString = "0";
|
||||
var value = double.Parse(valueString);
|
||||
value = value * addressMap[i].Zoom;
|
||||
value = Math.Round(value, addressMap[i].DecimalPos);
|
||||
AddValueToValueDic(valueDic, returnDic, addressMap[i], value, dataType);
|
||||
}
|
||||
if (machineName == "EventData" || (returnTime - _receivers[_receiver]).TotalSeconds + 0.5 >= minimumElapse)
|
||||
{
|
||||
if (ReturnValueDictionary != null)
|
||||
{
|
||||
var dataReturn = new DataReturnDef();
|
||||
dataReturn.MachineId = machineName;
|
||||
dataReturn.ReturnValues = new ReturnStruct<Dictionary<string, ReturnUnit<double>>>() { IsSuccess = true, Datas = returnDic };
|
||||
ReturnValueDictionary(dataReturn);
|
||||
_receivers[_receiver] = returnTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//_logger.LogError(ex, "Error");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (returnBytes != null) return returnBytes;
|
||||
else return null;
|
||||
};
|
||||
else
|
||||
{
|
||||
switch (receiveContent.FunctionCode)
|
||||
{
|
||||
case (byte)ModbusProtocolFunctionCode.ReadHoldRegister:
|
||||
{
|
||||
Array.Copy(threex, receiveContent.StartAddress, readContent, 0, readContent.Length);
|
||||
returnBytes = new ReadDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, (byte)receiveContent.Count, readContent);
|
||||
break;
|
||||
}
|
||||
case (byte)ModbusProtocolFunctionCode.ReadCoilStatus:
|
||||
{
|
||||
var bitCount = receiveContent.WriteByteCount * 8;
|
||||
var boolContent = new bool[bitCount];
|
||||
Array.Copy(zerox, receiveContent.StartAddress, boolContent, 0, bitCount);
|
||||
var byteList = new List<byte>();
|
||||
for (int i = 0; i < receiveContent.WriteByteCount; i++)
|
||||
{
|
||||
byte result = 0;
|
||||
for (int j = i; j < i + 8; j++)
|
||||
{
|
||||
// 将布尔值转换为对应的位
|
||||
|
||||
byte bit = boolContent[j] ? (byte)1 : (byte)0;
|
||||
|
||||
// 使用左移位运算将位合并到结果字节中
|
||||
|
||||
result = (byte)((result << 1) | bit);
|
||||
}
|
||||
byteList.Add(result);
|
||||
}
|
||||
readContent = byteList.ToArray();
|
||||
returnBytes = new ReadDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.WriteByteCount, readContent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (returnBytes != null) return returnBytes;
|
||||
else return null;
|
||||
};
|
||||
_receivers.Add(_receiver, DateTime.MinValue);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> ConnectAsync()
|
||||
{
|
||||
return await _receiver.ConnectAsync();
|
||||
var result = await Task.FromResult(Parallel.ForEach(_receivers, async _receiver =>
|
||||
{
|
||||
await _receiver.Key.ConnectAsync();
|
||||
}));
|
||||
return result.IsCompleted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace Modbus.Net.Siemens
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="src">本机模块位,0到7,仅200使用,其它型号不要填写</param>
|
||||
/// <param name="dst">PLC模块位,0到7,仅200使用,其它型号不要填写</param>
|
||||
public SiemensMachine(TKey id, SiemensType connectionType, string connectionString, SiemensMachineModel model,
|
||||
public SiemensMachine(TKey id, string alias, SiemensType connectionType, string connectionString, SiemensMachineModel model,
|
||||
IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, bool keepConnect, byte slaveAddress, byte masterAddress, byte src = 1, byte dst = 0)
|
||||
: base(id, getAddresses, keepConnect, slaveAddress, masterAddress)
|
||||
: base(id, alias, getAddresses, keepConnect, slaveAddress, masterAddress)
|
||||
{
|
||||
BaseUtility = new SiemensUtility(connectionType, connectionString, model, slaveAddress, masterAddress, src, dst);
|
||||
AddressFormater = new AddressFormaterSiemens();
|
||||
@@ -44,9 +44,9 @@ namespace Modbus.Net.Siemens
|
||||
/// <param name="masterAddress">主站号</param>
|
||||
/// <param name="src">本机模块位,0到7,仅200使用,其它型号不要填写</param>
|
||||
/// <param name="dst">PLC模块位,0到7,仅200使用,其它型号不要填写</param>
|
||||
public SiemensMachine(TKey id, SiemensType connectionType, string connectionString, SiemensMachineModel model,
|
||||
public SiemensMachine(TKey id, string alias, SiemensType connectionType, string connectionString, SiemensMachineModel model,
|
||||
IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, byte slaveAddress, byte masterAddress, byte src = 1, byte dst = 0)
|
||||
: this(id, connectionType, connectionString, model, getAddresses, true, slaveAddress, masterAddress, src, dst)
|
||||
: this(id, alias, connectionType, connectionString, model, getAddresses, true, slaveAddress, masterAddress, src, dst)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,16 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
public abstract class ValueHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否为小端格式
|
||||
/// </summary>
|
||||
public abstract bool LittleEndian { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 位是否为小端格式
|
||||
/// </summary>
|
||||
public abstract bool LittleEndianBit { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 兼容数据类型对应的字节长度
|
||||
/// </summary>
|
||||
@@ -347,12 +357,12 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 协议中的内容构造是否小端的,默认是小端构造协议。
|
||||
/// </summary>
|
||||
public static bool LittleEndian => true;
|
||||
public override bool LittleEndian => true;
|
||||
|
||||
/// <summary>
|
||||
/// 协议中的比特位内容构造是否小端的,默认是小端构造协议。
|
||||
/// </summary>
|
||||
public static bool LittleEndianBit => true;
|
||||
public override bool LittleEndianBit => true;
|
||||
|
||||
/// <summary>
|
||||
/// 将一个byte数字转换为一个byte元素的数组。
|
||||
@@ -1228,7 +1238,7 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 是否为大端
|
||||
/// </summary>
|
||||
protected new bool LittleEndian => false;
|
||||
public override bool LittleEndian => false;
|
||||
|
||||
/// <summary>
|
||||
/// 覆盖的获取实例的方法
|
||||
@@ -1471,12 +1481,12 @@ namespace Modbus.Net
|
||||
/// <summary>
|
||||
/// 是否为小端
|
||||
/// </summary>
|
||||
protected new bool LittleEndian => false;
|
||||
public override bool LittleEndian => false;
|
||||
|
||||
/// <summary>
|
||||
/// 是否为小端位
|
||||
/// </summary>
|
||||
protected new bool LittleEndianBit => false;
|
||||
public override bool LittleEndianBit => false;
|
||||
|
||||
/// <summary>
|
||||
/// 覆盖的实例获取方法
|
||||
|
||||
@@ -398,4 +398,59 @@ namespace Modbus.Net
|
||||
addressUnits);
|
||||
}
|
||||
}
|
||||
|
||||
public class ReadAddressesDesc
|
||||
{
|
||||
public string Area { get; set; }
|
||||
|
||||
public int Address { get; set; }
|
||||
|
||||
public int GetCount { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 固定读取地址的范围,无视所有其它规则
|
||||
/// </summary>
|
||||
public class AddressCombinerStatic<TKey> : AddressCombiner<TKey, int, int> where TKey : IEquatable<TKey>
|
||||
{
|
||||
protected IEnumerable<ReadAddressesDesc> ReadAddresses { get; set; }
|
||||
|
||||
protected AddressTranslator AddressTranslator { get; set; }
|
||||
|
||||
public AddressCombinerStatic(IEnumerable<ReadAddressesDesc> readAddresses, AddressTranslator addressTranslator)
|
||||
{
|
||||
AddressTranslator = addressTranslator;
|
||||
ReadAddresses = readAddresses;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 组合地址
|
||||
/// </summary>
|
||||
/// <param name="addresses">需要组合的地址</param>
|
||||
/// <returns>组合后的地址</returns>
|
||||
public override IEnumerable<CommunicationUnit<TKey, int, int>> Combine(IEnumerable<AddressUnit<TKey, int, int>> addresses)
|
||||
{
|
||||
List<CommunicationUnit<TKey, int, int>> communicationUnits = new List<CommunicationUnit<TKey, int, int>>();
|
||||
foreach (var readAddress in ReadAddresses)
|
||||
{
|
||||
var originalAddresses = new List<AddressUnit<TKey, int, int>>();
|
||||
foreach (var address in addresses)
|
||||
{
|
||||
if (address.Area == readAddress.Area && address.Address >= readAddress.Address && address.Address < readAddress.Address + readAddress.GetCount)
|
||||
originalAddresses.Add(address);
|
||||
}
|
||||
communicationUnits.Add(new CommunicationUnit<TKey, int, int>
|
||||
{
|
||||
Area = readAddress.Area,
|
||||
Address = readAddress.Address,
|
||||
GetCount = readAddress.GetCount * (int)
|
||||
Math.Ceiling(AddressTranslator.GetAreaByteLength(readAddress.Area)),
|
||||
DataType = typeof(byte),
|
||||
GetOriginalCount = originalAddresses.Count,
|
||||
OriginalAddresses = originalAddresses.ToList()
|
||||
});
|
||||
}
|
||||
return communicationUnits;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,8 +25,8 @@ namespace Modbus.Net
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
/// <param name="slaveAddress">从站地址</param>
|
||||
/// <param name="masterAddress">主站地址</param>
|
||||
protected BaseMachine(TKey id, IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, bool keepConnect, byte slaveAddress,
|
||||
byte masterAddress) : base(id, getAddresses, keepConnect)
|
||||
protected BaseMachine(TKey id, string alias, IEnumerable<AddressUnit<TUnitKey, int, int>> getAddresses, bool keepConnect, byte slaveAddress,
|
||||
byte masterAddress) : base(id, alias, getAddresses, keepConnect)
|
||||
{
|
||||
SlaveAddress = slaveAddress;
|
||||
MasterAddress = masterAddress;
|
||||
@@ -149,6 +149,10 @@ namespace Modbus.Net
|
||||
var localMainPos = (int)localPos;
|
||||
//字节坐标的子地址位置
|
||||
var localSubPos = (int)((localPos - localMainPos) * 8);
|
||||
if (ValueHelper.GetInstance(BaseUtility.Endian).LittleEndianBit == true && AddressTranslator.GetAreaByteLength(communicateAddress.Area) > 1 && ValueHelper.ByteLength[address.DataType.FullName] < AddressTranslator.GetAreaByteLength(communicateAddress.Area))
|
||||
{
|
||||
localMainPos =(int)(2 * ((int)(localMainPos / AddressTranslator.GetAreaByteLength(communicateAddress.Area)) * AddressTranslator.GetAreaByteLength(communicateAddress.Area)) + (AddressTranslator.GetAreaByteLength(communicateAddress.Area) - 1) - localMainPos);
|
||||
}
|
||||
|
||||
//根据类型选择返回结果的键是通讯标识还是地址
|
||||
string key;
|
||||
@@ -510,8 +514,8 @@ namespace Modbus.Net
|
||||
/// </summary>
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="getAddresses">需要与设备通讯的地址</param>
|
||||
protected BaseMachine(TKey id, IEnumerable<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>> getAddresses)
|
||||
: this(id, getAddresses, false)
|
||||
protected BaseMachine(TKey id, string alias, IEnumerable<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>> getAddresses)
|
||||
: this(id, alias, getAddresses, false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -521,11 +525,22 @@ namespace Modbus.Net
|
||||
/// <param name="id">设备的ID号</param>
|
||||
/// <param name="getAddresses">需要与设备通讯的地址</param>
|
||||
/// <param name="keepConnect">是否保持连接</param>
|
||||
protected BaseMachine(TKey id, IEnumerable<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>> getAddresses, bool keepConnect)
|
||||
protected BaseMachine(TKey id, string alias, IEnumerable<AddressUnit<TUnitKey, TAddressKey, TSubAddressKey>> getAddresses, bool keepConnect)
|
||||
{
|
||||
Id = id;
|
||||
GetAddresses = getAddresses;
|
||||
KeepConnect = keepConnect;
|
||||
if (alias.Contains(':'))
|
||||
{
|
||||
var aliasArray = alias.Split(':');
|
||||
ProjectName = aliasArray[0];
|
||||
MachineName = aliasArray[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
ProjectName = "";
|
||||
MachineName = alias;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly int _maxErrorCount = 3;
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
namespace Modbus.Net.Machine
|
||||
{
|
||||
public class BaseServer
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ namespace AnyType.Controllers
|
||||
Value = 0,
|
||||
Type = unitValue.DataType.Name
|
||||
};
|
||||
var machine = new ModbusMachine("1", ModbusType.Tcp, "10.10.18.251:502", addressUnits, true, 2, 0, Endian.BigEndianLsb);
|
||||
var machine = new ModbusMachine("1", "", ModbusType.Tcp, "10.10.18.251:502", addressUnits, true, 2, 0, Endian.BigEndianLsb);
|
||||
//启动任务
|
||||
await MachineJobSchedulerCreator.CreateScheduler("Trigger1", -1, 1).Result.From(machine.Id, machine, MachineDataType.CommunicationTag).Result.Query("Query1",
|
||||
returnValues =>
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.3.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.1.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace TripleAdd.Controllers
|
||||
{
|
||||
if (machine == null)
|
||||
{
|
||||
machine = new ModbusMachine<string, string>("1", ModbusType.Tcp, "10.10.18.251", new List<AddressUnit>()
|
||||
machine = new ModbusMachine<string, string>("1", "", ModbusType.Tcp, "10.10.18.251", new List<AddressUnit>()
|
||||
{
|
||||
new AddressUnit() {Id = "1", Area = "4X", Address = 1, CommunicationTag = "Add1", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
|
||||
new AddressUnit() {Id = "2", Area = "4X", Address = 2, CommunicationTag = "Add2", DataType = typeof(ushort), Zoom = 1, DecimalPos = 0},
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace Modbus.Net.Tests
|
||||
},
|
||||
};
|
||||
|
||||
_baseMachine = new SiemensMachine<int, int>(2, SiemensType.Tcp, _machineIp, SiemensMachineModel.S7_1200, _addressUnits, true, 2, 0, 1, 0)
|
||||
_baseMachine = new SiemensMachine<int, int>(2, "", SiemensType.Tcp, _machineIp, SiemensMachineModel.S7_1200, _addressUnits, true, 2, 0, 1, 0)
|
||||
{
|
||||
ProjectName = "Project 1",
|
||||
MachineName = "Test 2"
|
||||
|
||||
@@ -16,9 +16,9 @@ namespace Modbus.Net.Tests
|
||||
[TestInitialize]
|
||||
public void Init()
|
||||
{
|
||||
_modbusTcpMachine = new ModbusMachine<string, string>("1", ModbusType.Tcp, _machineIp, null, true, 1, 0, Endian.BigEndianLsb);
|
||||
_modbusTcpMachine = new ModbusMachine<string, string>("1", "",ModbusType.Tcp, _machineIp, null, true, 1, 0, Endian.BigEndianLsb);
|
||||
|
||||
_modbusTcpMachine2 = new ModbusMachine<string, string>("2", ModbusType.Tcp, _machineIp, null, true, 1, 0, Endian.LittleEndianLsb);
|
||||
_modbusTcpMachine2 = new ModbusMachine<string, string>("2", "", ModbusType.Tcp, _machineIp, null, true, 1, 0, Endian.LittleEndianLsb);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace Modbus.Net.Tests
|
||||
[TestMethod]
|
||||
public void GetUtility()
|
||||
{
|
||||
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, ModbusType.Tcp, _machineIp, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, "", ModbusType.Tcp, _machineIp, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
var utility = baseMachine.GetUtilityMethods<IUtilityMethodDatas>();
|
||||
var methods = utility.GetType().GetRuntimeMethods();
|
||||
Assert.AreEqual(methods.FirstOrDefault(method => method.Name == "GetDatasAsync") != null, true);
|
||||
@@ -24,7 +24,7 @@ namespace Modbus.Net.Tests
|
||||
[TestMethod]
|
||||
public async Task InvokeUtility()
|
||||
{
|
||||
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, ModbusType.Tcp, _machineIp, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, "", ModbusType.Tcp, _machineIp, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
await baseMachine.BaseUtility.ConnectAsync();
|
||||
var success = await baseMachine.BaseUtility.GetUtilityMethods<IUtilityMethodDatas>().SetDatasAsync("4X 1", new object[] { (byte)11 }, 1);
|
||||
Assert.AreEqual(success.IsSuccess, true);
|
||||
@@ -36,7 +36,7 @@ namespace Modbus.Net.Tests
|
||||
[TestMethod]
|
||||
public async Task InvokeMachine()
|
||||
{
|
||||
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, ModbusType.Tcp, _machineIp, new List<AddressUnit>
|
||||
BaseMachine<int, int> baseMachine = new ModbusMachine<int, int>(1, "",ModbusType.Tcp, _machineIp, new List<AddressUnit>
|
||||
{
|
||||
new AddressUnit
|
||||
{
|
||||
|
||||
@@ -16,8 +16,8 @@ namespace Modbus.Net.Tests
|
||||
[TestInitialize]
|
||||
public void Init()
|
||||
{
|
||||
_modbusRtuMachine1 = new ModbusMachine<string, string>("1", ModbusType.Rtu, _machineCom, null, true, 1, 0, Endian.BigEndianLsb);
|
||||
_modbusRtuMachine2 = new ModbusMachine<string, string>("2", ModbusType.Rtu, _machineCom, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
_modbusRtuMachine1 = new ModbusMachine<string, string>("1", "", ModbusType.Rtu, _machineCom, null, true, 1, 0, Endian.BigEndianLsb);
|
||||
_modbusRtuMachine2 = new ModbusMachine<string, string>("2", "", ModbusType.Rtu, _machineCom, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@@ -22,11 +22,11 @@ namespace Modbus.Net.Tests
|
||||
[TestInitialize]
|
||||
public void Init()
|
||||
{
|
||||
_modbusTcpMachine = new ModbusMachine<string, string>("1", ModbusType.Tcp, _machineIp, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
_modbusTcpMachine = new ModbusMachine<string, string>("1", "", ModbusType.Tcp, _machineIp, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
|
||||
_modbusRtuMachine = new ModbusMachine<string, string>("2", ModbusType.Rtu, _machineCom, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
_modbusRtuMachine = new ModbusMachine<string, string>("2", "", ModbusType.Rtu, _machineCom, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
|
||||
_modbusAsciiMachine = new ModbusMachine<string, string>("3", ModbusType.Ascii, _machineCom2, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
_modbusAsciiMachine = new ModbusMachine<string, string>("3", "", ModbusType.Ascii, _machineCom2, null, true, 2, 0, Endian.BigEndianLsb);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace Modbus.Net.Tests
|
||||
[TestInitialize]
|
||||
public void Init()
|
||||
{
|
||||
_siemensTcpMachine = new SiemensMachine<string, string>("1", SiemensType.Tcp, _machineIp, SiemensMachineModel.S7_1200, null, true, 2, 0);
|
||||
_siemensTcpMachine = new SiemensMachine<string, string>("1", "", SiemensType.Tcp, _machineIp, SiemensMachineModel.S7_1200, null, true, 2, 0);
|
||||
|
||||
_siemensPpiMachine = new SiemensMachine<string, string>("2", SiemensType.Ppi, _machineCom, SiemensMachineModel.S7_200, null, true, 2, 0, 1, 0);
|
||||
_siemensPpiMachine = new SiemensMachine<string, string>("2", "", SiemensType.Ppi, _machineCom, SiemensMachineModel.S7_200, null, true, 2, 0, 1, 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"TCP": {
|
||||
"ConnectionTimeout": "5000",
|
||||
"FetchSleepTime": "100",
|
||||
"FullDuplex": "False",
|
||||
"FullDuplex": "True",
|
||||
"Modbus": {
|
||||
"ModbusPort": "502",
|
||||
"IP": "192.168.1.1"
|
||||
@@ -16,7 +16,7 @@
|
||||
"UDP": {
|
||||
"ConnectionTimeout": "5000",
|
||||
"FetchSleepTime": "100",
|
||||
"FullDuplex": "False",
|
||||
"FullDuplex": "True",
|
||||
"Modbus": {
|
||||
"ModbusPort": "502",
|
||||
"IP": "192.168.1.1"
|
||||
@@ -46,7 +46,8 @@
|
||||
"Host": "opc.tcp://localhost/test"
|
||||
},
|
||||
"Controller": {
|
||||
"WaitingListCount": "100"
|
||||
"WaitingListCount": "100",
|
||||
"NoResponse": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user