This commit is contained in:
parallelbgls
2024-07-26 17:34:07 +08:00
parent e38c16e899
commit 21c8e34934

View File

@@ -11,7 +11,7 @@ namespace Modbus.Net.Modbus
{ {
public class ModbusRtuDataReceiver public class ModbusRtuDataReceiver
{ {
private ModbusRtuProtocolReceiver _receiver; private List<ModbusRtuProtocolReceiver> _receivers;
private readonly IConfigurationRoot configuration = new ConfigurationBuilder() private readonly IConfigurationRoot configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) .SetBasePath(Directory.GetCurrentDirectory())
@@ -59,142 +59,154 @@ namespace Modbus.Net.Modbus
public ModbusRtuDataReceiver(MachineDataType dataType) public ModbusRtuDataReceiver(MachineDataType dataType)
{ {
_receiver = new ModbusRtuProtocolReceiver(ConfigurationReader.GetValue("Receiver", "d:connectionString"), int.Parse(ConfigurationReader.GetValue("Receiver", "g:slaveAddress"))); _receivers = new List<ModbusRtuProtocolReceiver>();
var machineName = ConfigurationReader.GetValue("Receiver", "a:id"); var receiversDef = configuration.GetSection("Modbus.Net").GetSection("Receiver").GetChildren();
var addressMapName = ConfigurationReader.GetValue("Receiver", "e:addressMap"); foreach (var receiverDef in receiversDef)
var endian = ValueHelper.GetInstance(Endian.Parse(ConfigurationReader.GetValue("Receiver", "i:endian")));
_receiver.DataProcess = receiveContent =>
{ {
var returnTime = DateTime.Now; var _receiver = new ModbusRtuProtocolReceiver(receiverDef.GetValue<string>("d:connectionString"), receiverDef.GetValue<int>("g:slaveAddress"));
byte[] returnBytes = null; var machineName = receiverDef.GetValue<string>("a:id");
var readContent = new byte[receiveContent.Count * 2]; var addressMapName = receiverDef.GetValue<string>("e:addressMap");
var values = receiveContent.WriteContent; var endian = ValueHelper.GetInstance(Endian.Parse(receiverDef.GetValue<string>("i:endian")));
var valueDic = new Dictionary<string, double>(); _receiver.DataProcess = receiveContent =>
var returnDic = new Dictionary<string, ReturnUnit<double>>();
List<AddressUnit> addressMap = AddressReader<string, int, int>.ReadAddresses(addressMapName).ToList();
if (values != null)
{ {
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: switch (receiveContent.FunctionCode)
{
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++)
{ {
var pos = (addressMap[i].Address - 1) * 2; case (byte)ModbusProtocolFunctionCode.WriteMultiRegister:
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++)
{ {
byte result = 0; Array.Copy(receiveContent.WriteContent, 0, threex, receiveContent.StartAddress * 2, receiveContent.WriteContent.Length);
for (int j = i; j < i + 8; j++) 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;
byte bit = boolContent[j] ? (byte)1 : (byte)0;
// 使用左移位运算将位合并到结果字节中
result = (byte)((result << 1) | bit);
} }
byteList.Add(result); else
{
zerox[receiveContent.StartAddress] = false;
}
returnBytes = new WriteDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.StartAddress, receiveContent.WriteContent);
break;
} }
readContent = byteList.ToArray(); case (byte)ModbusProtocolFunctionCode.WriteMultiCoil:
returnBytes = new ReadDataModbusProtocol().Format(receiveContent.SlaveAddress, receiveContent.FunctionCode, receiveContent.WriteByteCount, readContent); {
break; 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 (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
if (returnBytes != null) return returnBytes; {
else return null; 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);
}
} }
public async Task<bool> ConnectAsync() public async Task<bool> ConnectAsync()
{ {
return await _receiver.ConnectAsync(); var result = await Task.FromResult(Parallel.ForEach(_receivers, async _receiver =>
{
await _receiver.ConnectAsync();
}));
return result.IsCompleted;
} }
} }
} }