diff --git a/Plugins/Drivers/DriverModbusMaster/MasterType.cs b/Plugins/Drivers/DriverModbusMaster/MasterType.cs new file mode 100644 index 0000000..d95eb1e --- /dev/null +++ b/Plugins/Drivers/DriverModbusMaster/MasterType.cs @@ -0,0 +1,13 @@ +namespace DriverModbusMaster; + +public enum MasterType +{ + Tcp = 0, + Udp = 1, + Rtu = 2, + RtuOnTcp = 3, + RtuOnUdp = 4, + Ascii = 5, + AsciiOnTcp = 6, + AsciiOnUdp = 7, +} \ No newline at end of file diff --git a/Plugins/Drivers/DriverModbusMaster/ModbusDataConver.cs b/Plugins/Drivers/DriverModbusMaster/ModbusDataConver.cs index c6a6fe4..471bbba 100644 --- a/Plugins/Drivers/DriverModbusMaster/ModbusDataConver.cs +++ b/Plugins/Drivers/DriverModbusMaster/ModbusDataConver.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Text; namespace DriverModbusMaster { @@ -15,11 +11,14 @@ namespace DriverModbusMaster /// /// /// - public static void SetString(ushort[] src, int start, string value) + public static void SetString(ushort[] src, int start, string? value) { - byte[] bytesTemp = Encoding.UTF8.GetBytes(value); - ushort[] dest = Bytes2Ushorts(bytesTemp); - dest.CopyTo(src, start); + if (value != null) + { + byte[] bytesTemp = Encoding.UTF8.GetBytes(value); + ushort[] dest = Bytes2Ushorts(bytesTemp); + dest.CopyTo(src, start); + } } /// @@ -36,8 +35,9 @@ namespace DriverModbusMaster { temp[i] = src[i + start]; } + byte[] bytesTemp = Ushorts2Bytes(temp); - string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' }); + string res = Encoding.UTF8.GetString(bytesTemp).Trim(new[] { '\0' }); return res; } @@ -69,6 +69,7 @@ namespace DriverModbusMaster { temp[i] = src[i + start]; } + byte[] bytesTemp = Ushorts2Bytes(temp); float res = BitConverter.ToSingle(bytesTemp, 0); return res; @@ -112,6 +113,7 @@ namespace DriverModbusMaster { temp[i] = src[i + start]; } + byte[] bytes = Ushorts2Bytes(temp); bool[] res = Bytes2Bools(bytes); @@ -127,14 +129,15 @@ namespace DriverModbusMaster { for (int j = 0; j < 8; j++) { - array[i * 8 + j] = (b[i] & 1) == 1;//判定byte的最后一位是否为1,若为1,则是true;否则是false - b[i] = (byte)(b[i] >> 1);//将byte右移一位 + array[i * 8 + j] = (b[i] & 1) == 1; //判定byte的最后一位是否为1,若为1,则是true;否则是false + b[i] = (byte)(b[i] >> 1); //将byte右移一位 } } + return array; } - private static byte Bools2Byte(bool[] array) + private static byte Bools2Byte(bool[]? array) { if (array != null && array.Length > 0) { @@ -143,12 +146,14 @@ namespace DriverModbusMaster { if (array[i]) { - byte nn = (byte)(1 << i);//左移一位,相当于×2 + byte nn = (byte)(1 << i); //左移一位,相当于×2 b += nn; } } + return b; } + return 0; } @@ -186,7 +191,6 @@ namespace DriverModbusMaster private static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false) { - int count = src.Length; byte[] dest = new byte[count << 1]; if (reverse) @@ -205,7 +209,8 @@ namespace DriverModbusMaster dest[i * 2 + 1] = (byte)(src[i] >> 8); } } + return dest; } } -} +} \ No newline at end of file diff --git a/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs b/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs index 9e37f47..9ee1140 100644 --- a/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs +++ b/Plugins/Drivers/DriverModbusMaster/ModbusMaster.cs @@ -12,7 +12,7 @@ namespace DriverModbusMaster [DriverSupported("ModbusUDP")] [DriverSupported("ModbusRtu")] [DriverSupported("ModbusAscii")] - [DriverInfoAttribute("ModbusMaster", "V1.1.0", "Copyright IoTGateway© 2022-8-6")] + [DriverInfo("ModbusMaster", "V1.1.0", "Copyright IoTGateway© 2022-8-6")] public class ModbusMaster : IDriver { private TcpClient? _tcpClient; @@ -23,46 +23,34 @@ namespace DriverModbusMaster public ILogger _logger { get; set; } private readonly string _device; + #region 配置参数 - [ConfigParameter("设备Id")] - public Guid DeviceId { get; set; } + [ConfigParameter("设备Id")] public string DeviceId { get; set; } - [ConfigParameter("PLC类型")] - public PLC_TYPE PlcType { get; set; } = PLC_TYPE.S71200; + [ConfigParameter("PLC类型")] public PlcType PlcType { get; set; } = PlcType.S71200; - [ConfigParameter("主站类型")] - public Master_TYPE Master_TYPE { get; set; } = Master_TYPE.Tcp; + [ConfigParameter("主站类型")] public MasterType MasterType { get; set; } = MasterType.Tcp; - [ConfigParameter("IP地址")] - public string IpAddress { get; set; } = "127.0.0.1"; + [ConfigParameter("IP地址")] public string IpAddress { get; set; } = "127.0.0.1"; - [ConfigParameter("端口号")] - public int Port { get; set; } = 502; + [ConfigParameter("端口号")] public int Port { get; set; } = 502; - [ConfigParameter("串口名")] - public string PortName { get; set; } = "COM1"; + [ConfigParameter("串口名")] public string PortName { get; set; } = "COM1"; - [ConfigParameter("波特率")] - public int BaudRate { get; set; } = 9600; + [ConfigParameter("波特率")] public int BaudRate { get; set; } = 9600; - [ConfigParameter("数据位")] - public int DataBits { get; set; } = 8; + [ConfigParameter("数据位")] public int DataBits { get; set; } = 8; - [ConfigParameter("校验位")] - public Parity Parity { get; set; } = Parity.None; + [ConfigParameter("校验位")] public Parity Parity { get; set; } = Parity.None; - [ConfigParameter("停止位")] - public StopBits StopBits { get; set; } = StopBits.One; + [ConfigParameter("停止位")] public StopBits StopBits { get; set; } = StopBits.One; - [ConfigParameter("从站号")] - public byte SlaveAddress { get; set; } = 1; + [ConfigParameter("从站号")] public byte SlaveAddress { get; set; } = 1; - [ConfigParameter("超时时间ms")] - public int Timeout { get; set; } = 3000; + [ConfigParameter("超时时间ms")] public int Timeout { get; set; } = 3000; - [ConfigParameter("最小通讯周期ms")] - public uint MinPeriod { get; set; } = 3000; + [ConfigParameter("最小通讯周期ms")] public uint MinPeriod { get; set; } = 3000; #endregion @@ -78,18 +66,18 @@ namespace DriverModbusMaster { get { - switch (Master_TYPE) + switch (MasterType) { - case Master_TYPE.Tcp: - case Master_TYPE.RtuOnTcp: - case Master_TYPE.AsciiOnTcp: + case MasterType.Tcp: + case MasterType.RtuOnTcp: + case MasterType.AsciiOnTcp: return _tcpClient != null && _master != null && _tcpClient.Connected; - case Master_TYPE.Udp: - case Master_TYPE.RtuOnUdp: - case Master_TYPE.AsciiOnUdp: + case MasterType.Udp: + case MasterType.RtuOnUdp: + case MasterType.AsciiOnUdp: return _udpClient != null && _master != null && _udpClient.Client.Connected; - case Master_TYPE.Rtu: - case Master_TYPE.Ascii: + case MasterType.Rtu: + case MasterType.Ascii: return _serialPort != null && _master != null && _serialPort.IsOpen; default: return false; @@ -102,21 +90,21 @@ namespace DriverModbusMaster try { _logger.LogInformation($"Device:[{_device}],Connect()"); - switch (Master_TYPE) + switch (MasterType) { - case Master_TYPE.Tcp: + case MasterType.Tcp: _tcpClient = new TcpClient(IpAddress, Port); _tcpClient.ReceiveTimeout = Timeout; _tcpClient.SendTimeout = Timeout; _master = ModbusIpMaster.CreateIp(_tcpClient); break; - case Master_TYPE.Udp: + case MasterType.Udp: _udpClient = new UdpClient(IpAddress, Port); _udpClient.Client.ReceiveTimeout = Timeout; _udpClient.Client.SendTimeout = Timeout; _master = ModbusIpMaster.CreateIp(_udpClient); break; - case Master_TYPE.Rtu: + case MasterType.Rtu: _serialPort = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits); _serialPort.ReadTimeout = Timeout; _serialPort.WriteTimeout = Timeout; @@ -124,19 +112,19 @@ namespace DriverModbusMaster _adapter = new SerialPortAdapter(_serialPort); _master = ModbusSerialMaster.CreateRtu(_adapter); break; - case Master_TYPE.RtuOnTcp: + case MasterType.RtuOnTcp: _tcpClient = new TcpClient(IpAddress, Port); _tcpClient.ReceiveTimeout = Timeout; _tcpClient.SendTimeout = Timeout; _master = ModbusSerialMaster.CreateRtu(_tcpClient); break; - case Master_TYPE.RtuOnUdp: + case MasterType.RtuOnUdp: _udpClient = new UdpClient(IpAddress, Port); _udpClient.Client.ReceiveTimeout = Timeout; _udpClient.Client.SendTimeout = Timeout; _master = ModbusSerialMaster.CreateRtu(_udpClient); break; - case Master_TYPE.Ascii: + case MasterType.Ascii: _serialPort = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits); _serialPort.ReadTimeout = Timeout; _serialPort.WriteTimeout = Timeout; @@ -144,19 +132,20 @@ namespace DriverModbusMaster _adapter = new SerialPortAdapter(_serialPort); _master = ModbusSerialMaster.CreateAscii(_adapter); break; - case Master_TYPE.AsciiOnTcp: + case MasterType.AsciiOnTcp: _tcpClient = new TcpClient(IpAddress, Port); _tcpClient.ReceiveTimeout = Timeout; _tcpClient.SendTimeout = Timeout; _master = ModbusSerialMaster.CreateAscii(_tcpClient); break; - case Master_TYPE.AsciiOnUdp: + case MasterType.AsciiOnUdp: _udpClient = new UdpClient(IpAddress, Port); _udpClient.Client.ReceiveTimeout = Timeout; _udpClient.Client.SendTimeout = Timeout; _master = ModbusSerialMaster.CreateAscii(_udpClient); break; } + _master.Transport.ReadTimeout = Timeout; _master.Transport.WriteTimeout = Timeout; } @@ -165,6 +154,7 @@ namespace DriverModbusMaster _logger.LogError($"Device:[{_device}],Connect(),Error", ex); return false; } + return IsConnected; } @@ -220,8 +210,8 @@ namespace DriverModbusMaster ret.StatusType = VaribaleStatusTypeEnum.UnKnow; ret.Message = ex.Message; _logger.LogInformation($"Device:[{_device}],ReadHoldingRegisters(),Error", ex); - } + return ret; } @@ -245,8 +235,8 @@ namespace DriverModbusMaster ret.StatusType = VaribaleStatusTypeEnum.UnKnow; ret.Message = ex.Message; _logger.LogInformation($"Device:[{_device}],ReadInputRegisters(),Error", ex); - } + return ret; } @@ -269,6 +259,7 @@ namespace DriverModbusMaster } else ret.Value = retBool; + ret.StatusType = VaribaleStatusTypeEnum.Good; } else @@ -282,8 +273,8 @@ namespace DriverModbusMaster ret.StatusType = VaribaleStatusTypeEnum.UnKnow; ret.Message = ex.Message; _logger.LogInformation($"Device:[{_device}],ReadCoil(),Error", ex); - } + return ret; } @@ -305,6 +296,7 @@ namespace DriverModbusMaster } else ret.Value = retBool; + ret.StatusType = VaribaleStatusTypeEnum.Good; } else @@ -318,8 +310,8 @@ namespace DriverModbusMaster ret.StatusType = VaribaleStatusTypeEnum.UnKnow; ret.Message = ex.Message; _logger.LogInformation($"Device:[{_device}],ReadInput(),Error", ex); - } + return ret; } @@ -337,7 +329,7 @@ namespace DriverModbusMaster } //读功能码03、或04 - private DriverReturnValueModel ReadRegistersBuffers(byte FunCode, DriverAddressIoArgModel ioarg) + private DriverReturnValueModel ReadRegistersBuffers(byte funCode, DriverAddressIoArgModel ioarg) { DriverReturnValueModel ret = new() { StatusType = VaribaleStatusTypeEnum.Good }; if (!IsConnected) @@ -351,9 +343,9 @@ namespace DriverModbusMaster try { var rawBuffers = new ushort[] { }; - if (FunCode == 3) + if (funCode == 3) rawBuffers = _master.ReadHoldingRegisters(SlaveAddress, startAddress, count); - else if (FunCode == 4) + else if (funCode == 4) rawBuffers = _master.ReadInputRegisters(SlaveAddress, startAddress, count); var retBuffers = ChangeBuffersOrder(rawBuffers, ioarg.ValueType); @@ -370,7 +362,11 @@ namespace DriverModbusMaster ret.Value = (retBuffers[0] << 16) + retBuffers[1]; else if (ioarg.ValueType.ToString().Contains("Float")) { - var bytes = new byte[] { (byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff), (byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff) }; + var bytes = new[] + { + (byte)(retBuffers[1] & 0xff), (byte)((retBuffers[1] >> 8) & 0xff), + (byte)(retBuffers[0] & 0xff), (byte)((retBuffers[0] >> 8) & 0xff) + }; ret.Value = BitConverter.ToSingle(bytes, 0); } else if (ioarg.ValueType.ToString().Contains("AsciiString")) @@ -380,7 +376,6 @@ namespace DriverModbusMaster str = str.Split('\0')[0]; ret.Value = str; } - } catch (Exception ex) { @@ -388,8 +383,8 @@ namespace DriverModbusMaster ret.Message = ex.Message; _logger.LogInformation($"Device:[{_device}],ReadRegistersBuffers(),Error", ex); } - } + return ret; } @@ -408,36 +403,35 @@ namespace DriverModbusMaster var newBuffers = new ushort[buffers.Length]; if (dataType.ToString().Contains("32") || dataType.ToString().Contains("Float")) { - var A = buffers[0] & 0xff00;//A - var B = buffers[0] & 0x00ff;//B - var C = buffers[1] & 0xff00;//C - var D = buffers[1] & 0x00ff;//D + var a = buffers[0] & 0xff00; //A + var b = buffers[0] & 0x00ff; //B + var c = buffers[1] & 0xff00; //C + var d = buffers[1] & 0x00ff; //D if (dataType.ToString().Contains("_1")) { - newBuffers[0] = (ushort)(A + B);//AB - newBuffers[1] = (ushort)(C + D);//CD + newBuffers[0] = (ushort)(a + b); //AB + newBuffers[1] = (ushort)(c + d); //CD } else if (dataType.ToString().Contains("_2")) { - newBuffers[0] = (ushort)((A >> 8) + (B << 8));//BA - newBuffers[1] = (ushort)((C >> 8) + (D << 8));//DC + newBuffers[0] = (ushort)((a >> 8) + (b << 8)); //BA + newBuffers[1] = (ushort)((c >> 8) + (d << 8)); //DC } else if (dataType.ToString().Contains("_3")) { - newBuffers[0] = (ushort)((C >> 8) + (D << 8));//DC - newBuffers[1] = (ushort)((A >> 8) + (B << 8));//BA + newBuffers[0] = (ushort)((c >> 8) + (d << 8)); //DC + newBuffers[1] = (ushort)((a >> 8) + (b << 8)); //BA } else { - newBuffers[0] = (ushort)(C + D);//CD - newBuffers[1] = (ushort)(A + B);//AB + newBuffers[0] = (ushort)(c + d); //CD + newBuffers[1] = (ushort)(a + b); //AB } } else if (dataType.ToString().Contains("64") || dataType.ToString().Contains("Double")) { if (dataType.ToString().Contains("_1")) { - } else { @@ -458,6 +452,7 @@ namespace DriverModbusMaster else newBuffers[0] = buffers[0]; } + return newBuffers; } @@ -469,33 +464,35 @@ namespace DriverModbusMaster vs.Add((byte)(retBuffer & 0xFF)); vs.Add((byte)((retBuffer & 0xFF00) >> 8)); } + return vs; } - private DriverReturnValueModel AnalyzeAddress(DriverAddressIoArgModel ioarg, out ushort StartAddress, out ushort ReadCount) + private DriverReturnValueModel AnalyzeAddress(DriverAddressIoArgModel ioarg, out ushort startAddress, + out ushort readCount) { DriverReturnValueModel ret = new() { StatusType = VaribaleStatusTypeEnum.Good }; try { if (ioarg.ValueType == DataTypeEnum.AsciiString) { - StartAddress = ushort.Parse(ioarg.Address.Split(',')[0]); - ReadCount = ushort.Parse(ioarg.Address.Split(',')[1]); + startAddress = ushort.Parse(ioarg.Address.Split(',')[0]); + readCount = ushort.Parse(ioarg.Address.Split(',')[1]); } else { - StartAddress = ushort.Parse(ioarg.Address); - ReadCount = GetModbusReadCount(3, ioarg.ValueType); + startAddress = ushort.Parse(ioarg.Address); + readCount = GetModbusReadCount(3, ioarg.ValueType); } - return ret; + return ret; } catch (Exception ex) { ret.StatusType = VaribaleStatusTypeEnum.AddressError; ret.Message = ex.Message; - StartAddress = 0; - ReadCount = 0; + startAddress = 0; + readCount = 0; _logger.LogInformation($"Device:[{_device}],AnalyzeAddress(),Error", ex); return ret; } @@ -510,9 +507,8 @@ namespace DriverModbusMaster rpcResponse.Description = "设备连接已断开"; else { - DriverReturnValueModel ret = new() { StatusType = VaribaleStatusTypeEnum.Good }; ushort address, count; - ret = AnalyzeAddress(ioarg, out address, out count); + AnalyzeAddress(ioarg, out address, out count); //功能码01 if (method == nameof(ReadCoil)) @@ -522,6 +518,7 @@ namespace DriverModbusMaster rpcResponse.IsSuccess = true; return rpcResponse; } + //功能码03 if (method == nameof(ReadHoldingRegisters)) { @@ -542,42 +539,25 @@ namespace DriverModbusMaster break; default: - await _master.WriteSingleRegisterAsync(SlaveAddress, address, ushort.Parse(ioarg.Value.ToString())); + await _master.WriteSingleRegisterAsync(SlaveAddress, address, + ushort.Parse(ioarg.Value.ToString())); break; } + rpcResponse.IsSuccess = true; return rpcResponse; } + rpcResponse.Description = $"不支持写入:{method}"; } } catch (Exception ex) { - rpcResponse.Description = $"写入失败,[Method]:{method},[Ioarg]:{ioarg},[ex]:{ex}"; + rpcResponse.Description = $"写入失败,[method]:{method},[ioarg]:{ioarg},[ex]:{ex}"; _logger.LogInformation($"Device:[{_device}],WriteAsync(),Error", ex); } + return rpcResponse; } } - - public enum PLC_TYPE - { - S7200 = 0, - S7300 = 1, - S7400 = 2, - S71200 = 3, - S71500 = 4, - } - - public enum Master_TYPE - { - Tcp = 0, - Udp = 1, - Rtu = 2, - RtuOnTcp = 3, - RtuOnUdp = 4, - Ascii = 5, - AsciiOnTcp = 6, - AsciiOnUdp = 7, - } -} +} \ No newline at end of file diff --git a/Plugins/Drivers/DriverModbusMaster/PlcType.cs b/Plugins/Drivers/DriverModbusMaster/PlcType.cs new file mode 100644 index 0000000..ba1eee7 --- /dev/null +++ b/Plugins/Drivers/DriverModbusMaster/PlcType.cs @@ -0,0 +1,10 @@ +namespace DriverModbusMaster; + +public enum PlcType +{ + S7200 = 0, + S7300 = 1, + S7400 = 2, + S71200 = 3, + S71500 = 4, +} \ No newline at end of file