完善modbus协议连读
This commit is contained in:
parent
78c1314627
commit
caf348a38b
@ -226,6 +226,8 @@ namespace PLC.ModBusMaster
|
|||||||
/// 批量读后缓存
|
/// 批量读后缓存
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private Dictionary<string, object> _cache = new();
|
private Dictionary<string, object> _cache = new();
|
||||||
|
private Dictionary<string, string> _cacheType = new();
|
||||||
|
private Dictionary<string, ushort> _cacheStart = new();
|
||||||
[Method("多地址读取", description: "多地址读取缓存")]
|
[Method("多地址读取", description: "多地址读取缓存")]
|
||||||
public DriverReturnValueModel ReadMultiple(DriverAddressIoArgModel ioArg)
|
public DriverReturnValueModel ReadMultiple(DriverAddressIoArgModel ioArg)
|
||||||
{
|
{
|
||||||
@ -240,6 +242,7 @@ namespace PLC.ModBusMaster
|
|||||||
var startAddress = ushort.Parse(args[1]);//开始地址
|
var startAddress = ushort.Parse(args[1]);//开始地址
|
||||||
var length = ushort.Parse(args[2]);//读取字数
|
var length = ushort.Parse(args[2]);//读取字数
|
||||||
var cacheKey = args[3];//缓存字典名
|
var cacheKey = args[3];//缓存字典名
|
||||||
|
_cacheStart[cacheKey] = startAddress;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -248,31 +251,36 @@ namespace PLC.ModBusMaster
|
|||||||
case "1":
|
case "1":
|
||||||
var coils = _master.ReadCoils(slaveId, startAddress, length);
|
var coils = _master.ReadCoils(slaveId, startAddress, length);
|
||||||
_cache[cacheKey] = coils;
|
_cache[cacheKey] = coils;
|
||||||
|
_cacheType[cacheKey] = "bool";
|
||||||
break;
|
break;
|
||||||
case "2":
|
case "2":
|
||||||
var inputs = _master.ReadInputs(slaveId, startAddress, length);
|
var inputs = _master.ReadInputs(slaveId, startAddress, length);
|
||||||
_cache[cacheKey] = inputs;
|
_cache[cacheKey] = inputs;
|
||||||
|
_cacheType[cacheKey] = "bool";
|
||||||
break;
|
break;
|
||||||
case "3":
|
case "3":
|
||||||
var holdingRs = _master.ReadHoldingRegisters(slaveId, startAddress, length);
|
var holdingRs = _master.ReadHoldingRegisters(slaveId, startAddress, length);
|
||||||
_cache[cacheKey] = holdingRs;
|
_cache[cacheKey] = holdingRs;
|
||||||
|
_cacheType[cacheKey] = "ushort";
|
||||||
break;
|
break;
|
||||||
case "4":
|
case "4":
|
||||||
var inputRs = _master.ReadInputRegisters(slaveId, startAddress, length);
|
var inputRs = _master.ReadInputRegisters(slaveId, startAddress, length);
|
||||||
_cache[cacheKey] = inputRs;
|
_cache[cacheKey] = inputRs;
|
||||||
|
_cacheType[cacheKey] = "ushort";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DriverReturnValueModel()
|
return new DriverReturnValueModel()
|
||||||
{
|
{
|
||||||
StatusType = VaribaleStatusTypeEnum.Good,
|
StatusType = VaribaleStatusTypeEnum.Good,
|
||||||
Value = Newtonsoft.Json.JsonConvert.SerializeObject(_cache[cacheKey])
|
Value = _cache[cacheKey]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.LogError(ex, $"Device:[{_device}],ReadMultiple(),Error");
|
_logger.LogError(ex, $"Device:[{_device}],ReadMultiple(),Error");
|
||||||
_cache[cacheKey] = null;
|
_cache[cacheKey] = null;
|
||||||
|
_cacheStart[cacheKey] = 0;
|
||||||
return new DriverReturnValueModel()
|
return new DriverReturnValueModel()
|
||||||
{
|
{
|
||||||
StatusType = VaribaleStatusTypeEnum.Bad
|
StatusType = VaribaleStatusTypeEnum.Bad
|
||||||
@ -298,57 +306,115 @@ namespace PLC.ModBusMaster
|
|||||||
{
|
{
|
||||||
var args = ioArg.Address.Split(',');
|
var args = ioArg.Address.Split(',');
|
||||||
cacheName = args[0];
|
cacheName = args[0];
|
||||||
startIndex = int.Parse(args[1]);
|
startIndex = ushort.Parse(args[1]) - _cacheStart[cacheName];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
startIndex = int.Parse(ioArg.Address);
|
startIndex = ushort.Parse(ioArg.Address) - _cacheStart[cacheName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_cache.ContainsKey(cacheName) && _cache[cacheName] != null)
|
if (_cache.ContainsKey(cacheName) && _cache[cacheName] != null)
|
||||||
{
|
{
|
||||||
var cacheBuffers = (ushort[])_cache[cacheName];
|
if (_cacheType[cacheName] == "ushort")
|
||||||
var rawBuffers = cacheBuffers.Skip(startIndex).Take(cacheBuffers.Length - startIndex).ToArray();
|
|
||||||
|
|
||||||
|
|
||||||
var retBuffers = ChangeBuffersOrder(rawBuffers, ioArg.EndianType);
|
|
||||||
if (ioArg.ValueType == DataTypeEnum.AsciiString)
|
|
||||||
retBuffers = rawBuffers;
|
|
||||||
|
|
||||||
if (ioArg.ValueType.ToString().Contains("Uint16"))
|
|
||||||
ret.Value = retBuffers[0];
|
|
||||||
else if (ioArg.ValueType.ToString().Contains("Int16"))
|
|
||||||
ret.Value = (short)retBuffers[0];
|
|
||||||
else if (ioArg.ValueType.ToString().Contains("Bcd16"))
|
|
||||||
ret.Value = ModBusDataConvert.GetBCD(GetBytes(retBuffers));
|
|
||||||
else if (ioArg.ValueType.ToString().Contains("Uint32"))
|
|
||||||
ret.Value = (uint)(retBuffers[0] << 16) + retBuffers[1];
|
|
||||||
else if (ioArg.ValueType.ToString().Contains("Int32"))
|
|
||||||
ret.Value = (retBuffers[0] << 16) + retBuffers[1];
|
|
||||||
else if (ioArg.ValueType.ToString().Contains("Bcd32"))
|
|
||||||
{
|
{
|
||||||
var newBuffers = new ushort[2] { retBuffers[1], retBuffers[0] };
|
var cacheBuffers = (ushort[])_cache[cacheName];
|
||||||
ret.Value = ModBusDataConvert.GetBCD(GetBytes(newBuffers));
|
var wordLen = GetModbusReadCount(0, ioArg.ValueType);
|
||||||
}
|
var rawBuffers = cacheBuffers.Skip(startIndex).Take(wordLen).ToArray();
|
||||||
else if (ioArg.ValueType.ToString().Contains("Float"))
|
|
||||||
{
|
|
||||||
var bytes = new[]
|
var retBuffers = ChangeBuffersOrder(rawBuffers, ioArg.EndianType);
|
||||||
|
if (ioArg.ValueType == DataTypeEnum.AsciiString)
|
||||||
|
retBuffers = rawBuffers;
|
||||||
|
|
||||||
|
|
||||||
|
ret.StatusType = VaribaleStatusTypeEnum.Good;
|
||||||
|
if (ioArg.ValueType == DataTypeEnum.Uint16)
|
||||||
|
ret.Value = retBuffers[0];
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Int16)
|
||||||
|
ret.Value = (short)retBuffers[0];
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Bcd16)
|
||||||
|
ret.Value = ModBusDataConvert.GetBCD(GetBytes(retBuffers));
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Uint32)
|
||||||
|
ret.Value = (uint)(retBuffers[0] << 16) + retBuffers[1];
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Int32)
|
||||||
|
ret.Value = (retBuffers[0] << 16) + retBuffers[1];
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Bcd32)
|
||||||
{
|
{
|
||||||
|
var newBuffers = new ushort[2] { retBuffers[1], retBuffers[0] };
|
||||||
|
ret.Value = ModBusDataConvert.GetBCD(GetBytes(newBuffers));
|
||||||
|
}
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Float)
|
||||||
|
{
|
||||||
|
var bytes = new[]
|
||||||
|
{
|
||||||
(byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff),
|
(byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff),
|
||||||
(byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff)
|
(byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff)
|
||||||
};
|
};
|
||||||
ret.Value = BitConverter.ToSingle(bytes, 0);
|
ret.Value = BitConverter.ToSingle(bytes, 0);
|
||||||
|
}
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Uint64)
|
||||||
|
{
|
||||||
|
var bytes = new[]
|
||||||
|
{
|
||||||
|
(byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[2] & 0xff), (byte)((retBuffers[2] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[3] & 0xff), (byte)((retBuffers[3] >> 8) & 0xff)
|
||||||
|
};
|
||||||
|
ret.Value = BitConverter.ToUInt64(bytes, 0);
|
||||||
|
}
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Int64)
|
||||||
|
{
|
||||||
|
var bytes = new[]
|
||||||
|
{
|
||||||
|
(byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[2] & 0xff), (byte)((retBuffers[2] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[3] & 0xff), (byte)((retBuffers[3] >> 8) & 0xff)
|
||||||
|
};
|
||||||
|
ret.Value = BitConverter.ToInt64(bytes, 0);
|
||||||
|
}
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Double)
|
||||||
|
{
|
||||||
|
var bytes = new[]
|
||||||
|
{
|
||||||
|
(byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[2] & 0xff), (byte)((retBuffers[2] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[3] & 0xff), (byte)((retBuffers[3] >> 8) & 0xff)
|
||||||
|
};
|
||||||
|
ret.Value = BitConverter.ToDouble(bytes, 0);
|
||||||
|
}
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.AsciiString)
|
||||||
|
{
|
||||||
|
var str = Encoding.ASCII.GetString(GetBytes(retBuffers).Where(x => x is >= 32 and <= 126).ToArray());
|
||||||
|
if (str.Contains('\0'))
|
||||||
|
str = str.Split('\0')[0];
|
||||||
|
ret.Value = str;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
|
||||||
|
ret.Message = "类型未定义";
|
||||||
|
_logger.LogError($"Device:[{_device}],[{ioArg.ValueType}]类型未定义");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (ioArg.ValueType.ToString().Contains("AsciiString"))
|
else if (_cacheType[cacheName] == "bool")
|
||||||
{
|
{
|
||||||
var str = Encoding.ASCII.GetString(GetBytes(retBuffers).ToArray());
|
ret.StatusType = VaribaleStatusTypeEnum.Good;
|
||||||
if (str.Contains('\0'))
|
|
||||||
str = str.Split('\0')[0];
|
var cacheBuffers = (bool[])_cache[cacheName];
|
||||||
ret.Value = str;
|
var boolValue = cacheBuffers.Skip(startIndex).ToArray()[0];
|
||||||
|
if (ioArg.ValueType == DataTypeEnum.Bool)
|
||||||
|
ret.Value = boolValue;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret.Value = boolValue ? 1 : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.StatusType = VaribaleStatusTypeEnum.Good;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -628,22 +694,22 @@ namespace PLC.ModBusMaster
|
|||||||
if (ioArg.ValueType == DataTypeEnum.AsciiString)
|
if (ioArg.ValueType == DataTypeEnum.AsciiString)
|
||||||
retBuffers = rawBuffers;
|
retBuffers = rawBuffers;
|
||||||
|
|
||||||
if (ioArg.ValueType.ToString().Contains("Uint16"))
|
if (ioArg.ValueType == DataTypeEnum.Uint16)
|
||||||
ret.Value = retBuffers[0];
|
ret.Value = retBuffers[0];
|
||||||
else if (ioArg.ValueType.ToString().Contains("Int16"))
|
else if (ioArg.ValueType == DataTypeEnum.Int16)
|
||||||
ret.Value = (short)retBuffers[0];
|
ret.Value = (short)retBuffers[0];
|
||||||
else if (ioArg.ValueType.ToString().Contains("Bcd16"))
|
else if (ioArg.ValueType == DataTypeEnum.Bcd16)
|
||||||
ret.Value = ModBusDataConvert.GetBCD(GetBytes(retBuffers));
|
ret.Value = ModBusDataConvert.GetBCD(GetBytes(retBuffers));
|
||||||
else if (ioArg.ValueType.ToString().Contains("Uint32"))
|
else if (ioArg.ValueType == DataTypeEnum.Uint32)
|
||||||
ret.Value = (uint)(retBuffers[0] << 16) + retBuffers[1];
|
ret.Value = (uint)(retBuffers[0] << 16) + retBuffers[1];
|
||||||
else if (ioArg.ValueType.ToString().Contains("Int32"))
|
else if (ioArg.ValueType == DataTypeEnum.Int32)
|
||||||
ret.Value = (retBuffers[0] << 16) + retBuffers[1];
|
ret.Value = (retBuffers[0] << 16) + retBuffers[1];
|
||||||
else if (ioArg.ValueType.ToString().Contains("Bcd32"))
|
else if (ioArg.ValueType == DataTypeEnum.Bcd32)
|
||||||
{
|
{
|
||||||
var newBuffers = new ushort[2] { retBuffers[1], retBuffers[0] };
|
var newBuffers = new ushort[2] { retBuffers[1], retBuffers[0] };
|
||||||
ret.Value = ModBusDataConvert.GetBCD(GetBytes(newBuffers));
|
ret.Value = ModBusDataConvert.GetBCD(GetBytes(newBuffers));
|
||||||
}
|
}
|
||||||
else if (ioArg.ValueType.ToString().Contains("Float"))
|
else if (ioArg.ValueType == DataTypeEnum.Float)
|
||||||
{
|
{
|
||||||
var bytes = new[]
|
var bytes = new[]
|
||||||
{
|
{
|
||||||
@ -652,24 +718,52 @@ namespace PLC.ModBusMaster
|
|||||||
};
|
};
|
||||||
ret.Value = BitConverter.ToSingle(bytes, 0);
|
ret.Value = BitConverter.ToSingle(bytes, 0);
|
||||||
}
|
}
|
||||||
else if (ioArg.ValueType.ToString().Contains("Double"))
|
else if (ioArg.ValueType == DataTypeEnum.Uint64)
|
||||||
{
|
{
|
||||||
var bytes = new[]
|
var bytes = new[]
|
||||||
{
|
{
|
||||||
(byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff),
|
(byte)(retBuffers[3] & 0xff), (byte)((retBuffers[3] >> 8) & 0xff),
|
||||||
(byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff),
|
|
||||||
(byte)(retBuffers[2] & 0xff), (byte)((retBuffers[2] >> 8) & 0xff),
|
(byte)(retBuffers[2] & 0xff), (byte)((retBuffers[2] >> 8) & 0xff),
|
||||||
(byte)(retBuffers[3] & 0xff), (byte)((retBuffers[3] >> 8) & 0xff)
|
(byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff)
|
||||||
|
};
|
||||||
|
ret.Value = BitConverter.ToUInt64(bytes, 0);
|
||||||
|
}
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Int64)
|
||||||
|
{
|
||||||
|
var bytes = new[]
|
||||||
|
{
|
||||||
|
(byte)(retBuffers[3] & 0xff), (byte)((retBuffers[3] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[2] & 0xff), (byte)((retBuffers[2] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff)
|
||||||
|
};
|
||||||
|
ret.Value = BitConverter.ToInt64(bytes, 0);
|
||||||
|
}
|
||||||
|
else if (ioArg.ValueType == DataTypeEnum.Double)
|
||||||
|
{
|
||||||
|
var bytes = new[]
|
||||||
|
{
|
||||||
|
(byte)(retBuffers[3] & 0xff), (byte)((retBuffers[3] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[2] & 0xff), (byte)((retBuffers[2] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff),
|
||||||
|
(byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff)
|
||||||
};
|
};
|
||||||
ret.Value = BitConverter.ToDouble(bytes, 0);
|
ret.Value = BitConverter.ToDouble(bytes, 0);
|
||||||
}
|
}
|
||||||
else if (ioArg.ValueType.ToString().Contains("AsciiString"))
|
else if (ioArg.ValueType == DataTypeEnum.AsciiString)
|
||||||
{
|
{
|
||||||
var str = Encoding.ASCII.GetString(GetBytes(retBuffers).ToArray());
|
var str = Encoding.ASCII.GetString(GetBytes(retBuffers).Where(x => x is >= 32 and <= 126).ToArray());
|
||||||
if (str.Contains('\0'))
|
if (str.Contains('\0'))
|
||||||
str = str.Split('\0')[0];
|
str = str.Split('\0')[0];
|
||||||
ret.Value = str;
|
ret.Value = str;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
|
||||||
|
ret.Message = "类型未定义";
|
||||||
|
_logger.LogError($"Device:[{_device}],[{ioArg.ValueType}]类型未定义");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -679,6 +773,7 @@ namespace PLC.ModBusMaster
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user