1.合并@sugerlcc的Modbus驱动写入PR

2.引入NLog,默认写入本地
3.Driver构造函数增加Logger和Device参数,用于记录日志
This commit is contained in:
iioter 2022-08-06 18:21:00 +08:00
parent 91494c873d
commit 9c71e1a286
31 changed files with 503 additions and 122 deletions

View File

@ -23,6 +23,8 @@
<PackageReference Include="MQTTnet.AspNetCore" Version="3.1.2" />
<PackageReference Include="MQTTnet.Extensions.ManagedClient" Version="3.1.2" />
<PackageReference Include="MQTTnet.Extensions.Rpc" Version="3.1.2" />
<PackageReference Include="NLog" Version="5.0.1" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.1.0" />
<PackageReference Include="System.IO.Ports" Version="6.0.0" />
</ItemGroup>

View File

@ -8,6 +8,8 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MQTTnet.AspNetCore.Extensions;
using WalkingTec.Mvvm.Core;
using NLog;
using NLog.Web;
namespace IoTGateway
{
@ -48,7 +50,8 @@ namespace IoTGateway
option.ListenAnyIP(1888, l => l.UseMqtt());
option.ListenAnyIP(518);
});
});
})
.UseNLog();
}
}
}

35
IoTGateway/nlog.config Normal file
View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
internalLogLevel="Info"
internalLogFile="./logs/internal-nlog-AspNetCore.txt">
<!-- enable asp.net core layout renderers -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!-- the targets to write to -->
<targets>
<!-- File Target for own log messages with extra web details using some ASP.NET core renderers -->
<target xsi:type="File" name="ownFile-web" fileName="./logs/${logger}/${shortdate}/iotgateway.log"
maxArchiveDays="7"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}" />
<!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
<target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
</targets>
<!-- rules to map from logger name to target -->
<rules>
<!--Output hosting lifetime messages to console target for faster startup detection -->
<logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole, ownFile-web" final="true" />
<!--Skip non-critical Microsoft logs and so log only own logs (BlackHole) -->
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<logger name="System.Net.Http.*" maxlevel="Info" final="true" />
<logger name="*" minlevel="Trace" writeTo="ownFile-web" />
</rules>
</nlog>

View File

@ -3,6 +3,8 @@ using IoTClient.Enums;
using PluginInterface;
using System;
using System.Text;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
namespace DriverAllenBradley
{
@ -11,6 +13,9 @@ namespace DriverAllenBradley
public class AllenBradley : IDriver
{
private AllenBradleyClient plc = null;
public ILogger _logger { get; set; }
private readonly Device _device;
#region
[ConfigParameter("设备Id")]
@ -30,9 +35,12 @@ namespace DriverAllenBradley
#endregion
public AllenBradley(Guid deviceId)
public AllenBradley(Device device, ILogger logger)
{
DeviceId = deviceId;
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}

View File

@ -14,5 +14,6 @@
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
</Project>

View File

@ -9,5 +9,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,6 @@
using PluginInterface;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
using PluginInterface;
namespace DriverFaunc
{
@ -20,6 +22,9 @@ namespace DriverFaunc
private ushort _hndl;
private int _result = -1;
public ILogger _logger { get; set; }
private readonly Device _device;
public bool IsConnected
{
get
@ -39,9 +44,12 @@ namespace DriverFaunc
}
}
public Fanuc(Guid deviceId)
public Fanuc(Device device, ILogger logger)
{
DeviceId = deviceId;
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}
public bool Close()

View File

@ -15,5 +15,6 @@
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
</Project>

View File

@ -4,6 +4,8 @@ using System;
using System.Text;
using HslCommunication.CNC.Fanuc;
using HslCommunication;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
namespace DriverFanucHsl
{
@ -12,6 +14,9 @@ namespace DriverFanucHsl
public class FanucHsl : IDriver
{
private FanucSeries0i fanuc;
public ILogger _logger { get; set; }
private readonly Device _device;
#region
[ConfigParameter("设备Id")]
@ -31,7 +36,7 @@ namespace DriverFanucHsl
#endregion
public FanucHsl(Guid deviceId)
public FanucHsl(Device device, ILogger logger)
{
// 授权示例 Authorization example
if (!Authorization.SetAuthorizationCode("输入你的授权号"))
@ -39,10 +44,13 @@ namespace DriverFanucHsl
//return; // 激活失败应该退出系统
}
DeviceId = deviceId;
}
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}
public bool IsConnected
{
get

View File

@ -14,5 +14,6 @@
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
</Project>

View File

@ -1,6 +1,9 @@
using PluginInterface;
using System;
using Microsoft.Extensions.Logging;
using OpenNETCF.MTConnect;
using Device = IoTGateway.Model.Device;
namespace DriverMTConnect
{
internal class MTConnectClient : IDriver
@ -26,9 +29,15 @@ namespace DriverMTConnect
EntityClient m_client = null;
public MTConnectClient(Guid deviceId)
public ILogger _logger { get; set; }
private readonly Device _device;
public MTConnectClient(Device device, ILogger logger)
{
DeviceId = deviceId;
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}
public bool Close()

View File

@ -14,5 +14,6 @@
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
</Project>

View File

@ -3,6 +3,8 @@ using IoTClient.Enums;
using PluginInterface;
using System;
using System.Text;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
namespace DriverMitsubishi
{
@ -12,6 +14,9 @@ namespace DriverMitsubishi
public class Mitsubishi : IDriver
{
private MitsubishiClient plc = null;
public ILogger _logger { get; set; }
private readonly Device _device;
#region
[ConfigParameter("设备Id")]
@ -34,9 +39,12 @@ namespace DriverMitsubishi
#endregion
public Mitsubishi(Guid deviceId)
public Mitsubishi(Device device, ILogger logger)
{
DeviceId = deviceId;
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}

View File

@ -12,6 +12,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
</ItemGroup>

View File

@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DriverModbusMaster
{
public class ModbusDataConvert
{
/// <summary>
/// 赋值string
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
/// <returns></returns>
public static void SetString(ushort[] src, int start, string value)
{
byte[] bytesTemp = Encoding.UTF8.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytesTemp);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取string
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="len"></param>
/// <returns></returns>
public static string GetString(ushort[] src, int start, int len)
{
ushort[] temp = new ushort[len];
for (int i = 0; i < len; i++)
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp);
string res = Encoding.UTF8.GetString(bytesTemp).Trim(new char[] { '\0' });
return res;
}
/// <summary>
/// 赋值Real类型数据
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetReal(ushort[] src, int start, float value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取float类型数据
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns></returns>
public static float GetReal(ushort[] src, int start)
{
ushort[] temp = new ushort[2];
for (int i = 0; i < 2; i++)
{
temp[i] = src[i + start];
}
byte[] bytesTemp = Ushorts2Bytes(temp);
float res = BitConverter.ToSingle(bytesTemp, 0);
return res;
}
/// <summary>
/// 赋值Short类型数据
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <param name="value"></param>
public static void SetShort(ushort[] src, int start, short value)
{
byte[] bytes = BitConverter.GetBytes(value);
ushort[] dest = Bytes2Ushorts(bytes);
dest.CopyTo(src, start);
}
/// <summary>
/// 获取short类型数据
/// </summary>
/// <param name="src"></param>
/// <param name="start"></param>
/// <returns></returns>
public static short GetShort(ushort[] src, int start)
{
ushort[] temp = new ushort[1];
temp[0] = src[start];
byte[] bytesTemp = Ushorts2Bytes(temp);
short res = BitConverter.ToInt16(bytesTemp, 0);
return res;
}
public static bool[] GetBools(ushort[] src, int start, int num)
{
ushort[] temp = new ushort[num];
for (int i = start; i < start + num; i++)
{
temp[i] = src[i + start];
}
byte[] bytes = Ushorts2Bytes(temp);
bool[] res = Bytes2Bools(bytes);
return res;
}
private static bool[] Bytes2Bools(byte[] b)
{
bool[] array = new bool[8 * b.Length];
for (int i = 0; i < b.Length; i++)
{
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右移一位
}
}
return array;
}
private static byte Bools2Byte(bool[] array)
{
if (array != null && array.Length > 0)
{
byte b = 0;
for (int i = 0; i < 8; i++)
{
if (array[i])
{
byte nn = (byte)(1 << i);//左移一位相当于×2
b += nn;
}
}
return b;
}
return 0;
}
private static ushort[] Bytes2Ushorts(byte[] src, bool reverse = false)
{
int len = src.Length;
byte[] srcPlus = new byte[len + 1];
src.CopyTo(srcPlus, 0);
int count = len >> 1;
if (len % 2 != 0)
{
count += 1;
}
ushort[] dest = new ushort[count];
if (reverse)
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] << 8 | srcPlus[2 * i + 1] & 0xff);
}
}
else
{
for (int i = 0; i < count; i++)
{
dest[i] = (ushort)(srcPlus[i * 2] & 0xff | srcPlus[2 * i + 1] << 8);
}
}
return dest;
}
private static byte[] Ushorts2Bytes(ushort[] src, bool reverse = false)
{
int count = src.Length;
byte[] dest = new byte[count << 1];
if (reverse)
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 8);
dest[i * 2 + 1] = (byte)(src[i] >> 0);
}
}
else
{
for (int i = 0; i < count; i++)
{
dest[i * 2] = (byte)(src[i] >> 0);
dest[i * 2 + 1] = (byte)(src[i] >> 8);
}
}
return dest;
}
}
}

View File

@ -1,10 +1,9 @@
using Modbus.Device;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
using Modbus.Device;
using Modbus.Serial;
using PluginInterface;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Net;
using System.Net.Sockets;
using System.Text;
@ -14,21 +13,24 @@ namespace DriverModbusMaster
[DriverSupported("ModbusUDP")]
[DriverSupported("ModbusRtu")]
[DriverSupported("ModbusAscii")]
[DriverInfoAttribute("ModbusMaster", "V1.0.0", "Copyright IoTGateway© 2021-12-19")]
[DriverInfoAttribute("ModbusMaster", "V1.1.0", "Copyright IoTGateway© 2022-8-6")]
public class ModbusMaster : IDriver
{
private TcpClient clientTcp = null;
private UdpClient clientUdp = null;
private SerialPort port = null;
private Modbus.Device.ModbusMaster master = null;
private SerialPortAdapter adapter = null;
private TcpClient? _tcpClient;
private UdpClient? _udpClient;
private SerialPort? _serialPort;
private Modbus.Device.ModbusMaster? _master;
private SerialPortAdapter? _adapter;
public ILogger _logger { get; set; }
private readonly Device _device;
#region
[ConfigParameter("设备Id")]
public Guid DeviceId { get; set; }
[ConfigParameter("PLC类型")]
public PLC_TYPE PLCType { get; set; } = PLC_TYPE.S71200;
public PLC_TYPE PlcType { get; set; } = PLC_TYPE.S71200;
[ConfigParameter("主站类型")]
public Master_TYPE Master_TYPE { get; set; } = Master_TYPE.Tcp;
@ -65,11 +67,13 @@ namespace DriverModbusMaster
#endregion
public ModbusMaster(Guid deviceId)
public ModbusMaster(Device device, ILogger logger)
{
DeviceId = deviceId;
}
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}
public bool IsConnected
{
@ -80,14 +84,14 @@ namespace DriverModbusMaster
case Master_TYPE.Tcp:
case Master_TYPE.RtuOnTcp:
case Master_TYPE.AsciiOnTcp:
return clientTcp != null && master != null && clientTcp.Connected;
return _tcpClient != null && _master != null && _tcpClient.Connected;
case Master_TYPE.Udp:
case Master_TYPE.RtuOnUdp:
case Master_TYPE.AsciiOnUdp:
return clientUdp != null && master != null && clientUdp.Client.Connected;
return _udpClient != null && _master != null && _udpClient.Client.Connected;
case Master_TYPE.Rtu:
case Master_TYPE.Ascii:
return port != null && master != null && port.IsOpen;
return _serialPort != null && _master != null && _serialPort.IsOpen;
default:
return false;
}
@ -98,68 +102,68 @@ namespace DriverModbusMaster
{
try
{
_logger.LogInformation($"Device:[{_device.DeviceName}],Connect()");
switch (Master_TYPE)
{
case Master_TYPE.Tcp:
clientTcp = new TcpClient(IpAddress.ToString(), Port);
clientTcp.ReceiveTimeout = Timeout;
clientTcp.SendTimeout = Timeout;
master = ModbusIpMaster.CreateIp(clientTcp);
_tcpClient = new TcpClient(IpAddress, Port);
_tcpClient.ReceiveTimeout = Timeout;
_tcpClient.SendTimeout = Timeout;
_master = ModbusIpMaster.CreateIp(_tcpClient);
break;
case Master_TYPE.Udp:
clientUdp = new UdpClient(IpAddress.ToString(), Port);
clientUdp.Client.ReceiveTimeout = Timeout;
clientUdp.Client.SendTimeout = Timeout;
master = ModbusIpMaster.CreateIp(clientUdp);
_udpClient = new UdpClient(IpAddress, Port);
_udpClient.Client.ReceiveTimeout = Timeout;
_udpClient.Client.SendTimeout = Timeout;
_master = ModbusIpMaster.CreateIp(_udpClient);
break;
case Master_TYPE.Rtu:
port = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits);
port.ReadTimeout = Timeout;
port.WriteTimeout = Timeout;
port.Open();
adapter = new SerialPortAdapter(port);
master = ModbusSerialMaster.CreateRtu(adapter);
_serialPort = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits);
_serialPort.ReadTimeout = Timeout;
_serialPort.WriteTimeout = Timeout;
_serialPort.Open();
_adapter = new SerialPortAdapter(_serialPort);
_master = ModbusSerialMaster.CreateRtu(_adapter);
break;
case Master_TYPE.RtuOnTcp:
clientTcp = new TcpClient(IpAddress.ToString(), Port);
clientTcp.ReceiveTimeout = Timeout;
clientTcp.SendTimeout = Timeout;
master = ModbusSerialMaster.CreateRtu(clientTcp);
_tcpClient = new TcpClient(IpAddress, Port);
_tcpClient.ReceiveTimeout = Timeout;
_tcpClient.SendTimeout = Timeout;
_master = ModbusSerialMaster.CreateRtu(_tcpClient);
break;
case Master_TYPE.RtuOnUdp:
clientUdp = new UdpClient(IpAddress.ToString(), Port);
clientUdp.Client.ReceiveTimeout = Timeout;
clientUdp.Client.SendTimeout = Timeout;
master = ModbusSerialMaster.CreateRtu(clientUdp);
_udpClient = new UdpClient(IpAddress, Port);
_udpClient.Client.ReceiveTimeout = Timeout;
_udpClient.Client.SendTimeout = Timeout;
_master = ModbusSerialMaster.CreateRtu(_udpClient);
break;
case Master_TYPE.Ascii:
port = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits);
port.ReadTimeout = Timeout;
port.WriteTimeout = Timeout;
port.Open();
adapter = new SerialPortAdapter(port);
master = ModbusSerialMaster.CreateAscii(adapter);
_serialPort = new SerialPort(PortName, BaudRate, Parity, DataBits, StopBits);
_serialPort.ReadTimeout = Timeout;
_serialPort.WriteTimeout = Timeout;
_serialPort.Open();
_adapter = new SerialPortAdapter(_serialPort);
_master = ModbusSerialMaster.CreateAscii(_adapter);
break;
case Master_TYPE.AsciiOnTcp:
clientTcp = new TcpClient(IpAddress.ToString(), Port);
clientTcp.ReceiveTimeout = Timeout;
clientTcp.SendTimeout = Timeout;
master = ModbusSerialMaster.CreateAscii(clientTcp);
_tcpClient = new TcpClient(IpAddress, Port);
_tcpClient.ReceiveTimeout = Timeout;
_tcpClient.SendTimeout = Timeout;
_master = ModbusSerialMaster.CreateAscii(_tcpClient);
break;
case Master_TYPE.AsciiOnUdp:
clientUdp = new UdpClient(IpAddress.ToString(), Port);
clientUdp.Client.ReceiveTimeout = Timeout;
clientUdp.Client.SendTimeout = Timeout;
master = ModbusSerialMaster.CreateAscii(clientUdp);
break;
default:
_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;
_master.Transport.ReadTimeout = Timeout;
_master.Transport.WriteTimeout = Timeout;
}
catch (Exception ex)
{
_logger.LogError($"Device:[{_device.DeviceName}],Connect(),Error", ex);
return false;
}
return IsConnected;
@ -169,14 +173,15 @@ namespace DriverModbusMaster
{
try
{
clientTcp?.Close();
clientUdp?.Close();
port?.Close();
_logger.LogInformation($"Device:[{_device.DeviceName}],Close()");
_tcpClient?.Close();
_udpClient?.Close();
_serialPort?.Close();
return !IsConnected;
}
catch (Exception)
catch (Exception ex)
{
_logger.LogError($"Device:[{_device.DeviceName}],Close(),Error", ex);
return false;
}
}
@ -185,14 +190,15 @@ namespace DriverModbusMaster
{
try
{
clientTcp?.Dispose();
clientUdp?.Dispose();
port?.Dispose();
master?.Dispose();
_tcpClient?.Dispose();
_udpClient?.Dispose();
_serialPort?.Dispose();
_master?.Dispose();
_logger.LogInformation($"Device:[{_device.DeviceName}],Dispose()");
}
catch (Exception)
catch (Exception ex)
{
_logger.LogError($"Device:[{_device.DeviceName}],Dispose(),Error", ex);
}
}
@ -214,6 +220,7 @@ namespace DriverModbusMaster
{
ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
ret.Message = ex.Message;
_logger.LogInformation($"Device:[{_device.DeviceName}],ReadHoldingRegisters(),Error", ex);
}
return ret;
@ -238,6 +245,7 @@ namespace DriverModbusMaster
{
ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
ret.Message = ex.Message;
_logger.LogInformation($"Device:[{_device.DeviceName}],ReadInputRegisters(),Error", ex);
}
return ret;
@ -252,7 +260,7 @@ namespace DriverModbusMaster
{
if (IsConnected)
{
var retBool = master.ReadCoils(SlaveAddress, ushort.Parse(ioarg.Address), 1)[0];
var retBool = _master.ReadCoils(SlaveAddress, ushort.Parse(ioarg.Address), 1)[0];
if (ioarg.ValueType == DataTypeEnum.Bit)
{
if (retBool)
@ -274,6 +282,7 @@ namespace DriverModbusMaster
{
ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
ret.Message = ex.Message;
_logger.LogInformation($"Device:[{_device.DeviceName}],ReadCoil(),Error", ex);
}
return ret;
@ -287,7 +296,7 @@ namespace DriverModbusMaster
{
if (IsConnected)
{
var retBool = master.ReadInputs(SlaveAddress, ushort.Parse(ioarg.Address), 1)[0];
var retBool = _master.ReadInputs(SlaveAddress, ushort.Parse(ioarg.Address), 1)[0];
if (ioarg.ValueType == DataTypeEnum.Bit)
{
if (retBool)
@ -309,6 +318,7 @@ namespace DriverModbusMaster
{
ret.StatusType = VaribaleStatusTypeEnum.UnKnow;
ret.Message = ex.Message;
_logger.LogInformation($"Device:[{_device.DeviceName}],ReadInput(),Error", ex);
}
return ret;
@ -336,16 +346,16 @@ namespace DriverModbusMaster
else
{
ushort startAddress, count;
ret = AnalyseAddress(ioarg, out startAddress, out count);
if(ret.StatusType!= VaribaleStatusTypeEnum.Good)
ret = AnalyzeAddress(ioarg, out startAddress, out count);
if (ret.StatusType != VaribaleStatusTypeEnum.Good)
return ret;
try
{
var rawBuffers = new ushort[] { };
if (FunCode == 3)
rawBuffers = master.ReadHoldingRegisters(SlaveAddress, startAddress, count);
rawBuffers = _master.ReadHoldingRegisters(SlaveAddress, startAddress, count);
else if (FunCode == 4)
rawBuffers = master.ReadInputRegisters(SlaveAddress, startAddress, count);
rawBuffers = _master.ReadInputRegisters(SlaveAddress, startAddress, count);
var retBuffers = ChangeBuffersOrder(rawBuffers, ioarg.ValueType);
if (ioarg.ValueType == DataTypeEnum.AsciiString)
@ -356,9 +366,9 @@ namespace DriverModbusMaster
else if (ioarg.ValueType.ToString().Contains("Int16"))
ret.Value = (short)retBuffers[0];
else if (ioarg.ValueType.ToString().Contains("Uint32"))
ret.Value = (UInt32)(retBuffers[0] << 16) + retBuffers[1];
ret.Value = (uint)(retBuffers[0] << 16) + retBuffers[1];
else if (ioarg.ValueType.ToString().Contains("Int32"))
ret.Value = (Int32)(retBuffers[0] << 16) + retBuffers[1];
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) };
@ -366,7 +376,7 @@ namespace DriverModbusMaster
}
else if (ioarg.ValueType.ToString().Contains("AsciiString"))
{
var str= Encoding.ASCII.GetString(GetBytes(retBuffers).ToArray());
var str = Encoding.ASCII.GetString(GetBytes(retBuffers).ToArray());
if (str.Contains('\0'))
str = str.Split('\0')[0];
ret.Value = str;
@ -377,6 +387,7 @@ namespace DriverModbusMaster
{
ret.StatusType = VaribaleStatusTypeEnum.Bad;
ret.Message = ex.Message;
_logger.LogInformation($"Device:[{_device.DeviceName}],ReadRegistersBuffers(),Error", ex);
}
}
@ -387,10 +398,9 @@ namespace DriverModbusMaster
{
if (dataType.ToString().Contains("32") || dataType.ToString().Contains("Float"))
return 2;
else if (dataType.ToString().Contains("64") || dataType.ToString().Contains("Double"))
if (dataType.ToString().Contains("64") || dataType.ToString().Contains("Double"))
return 4;
else
return 1;
return 1;
}
//预留了大小端转换的
@ -454,18 +464,16 @@ namespace DriverModbusMaster
private List<byte> GetBytes(ushort[] retBuffers)
{
List<byte> vs = new();
for (int i = 0; i < retBuffers.Length; i++)
foreach (var retBuffer in retBuffers)
{
vs.Add((byte)(retBuffers[i] & 0xFF));
vs.Add((byte)((retBuffers[i] & 0xFF00) >> 8));
vs.Add((byte)(retBuffer & 0xFF));
vs.Add((byte)((retBuffer & 0xFF00) >> 8));
}
return vs;
}
private DriverReturnValueModel AnalyseAddress(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
@ -489,46 +497,70 @@ namespace DriverModbusMaster
ret.Message = ex.Message;
StartAddress = 0;
ReadCount = 0;
_logger.LogInformation($"Device:[{_device.DeviceName}],AnalyzeAddress(),Error", ex);
return ret;
}
}
public async Task<RpcResponse> WriteAsync(string RequestId, string Method, DriverAddressIoArgModel Ioarg)
public async Task<RpcResponse> WriteAsync(string requestId, string method, DriverAddressIoArgModel ioarg)
{
RpcResponse rpcResponse = new() { IsSuccess = false };
try
{
ushort address = ushort.Parse(Ioarg.Address);
if (!IsConnected)
rpcResponse.Description = "设备连接已断开";
else
{
DriverReturnValueModel ret = new() { StatusType = VaribaleStatusTypeEnum.Good };
ushort address, count;
ret = AnalyzeAddress(ioarg, out address, out count);
//功能码01
if (Method == nameof(ReadCoil))
if (method == nameof(ReadCoil))
{
bool value = Ioarg.Value.ToString() == "1" || Ioarg.Value.ToString().ToLower() == "true";
master.WriteSingleCoilAsync(SlaveAddress, address, value);
var value = ioarg.Value.ToString() == "1" || ioarg.Value.ToString().ToLower() == "true";
await _master.WriteSingleCoilAsync(SlaveAddress, address, value);
rpcResponse.IsSuccess = true;
return rpcResponse;
}
//功能码03
else if (Method == nameof(ReadHoldingRegisters))
if (method == nameof(ReadHoldingRegisters))
{
master.WriteSingleRegisterAsync(SlaveAddress, address, ushort.Parse(Ioarg.Value.ToString()));
ushort[] shortArray = new ushort[count];
switch (ioarg.ValueType)
{
case DataTypeEnum.AsciiString:
ModbusDataConvert.SetString(shortArray, 0, ioarg.Value.ToString());
await _master.WriteMultipleRegistersAsync(SlaveAddress, address, shortArray);
break;
case DataTypeEnum.Float:
float f = 0;
float.TryParse(ioarg.Value.ToString(), out f);
ModbusDataConvert.SetReal(shortArray, 0, f);
await _master.WriteMultipleRegistersAsync(SlaveAddress, address, shortArray);
break;
default:
await _master.WriteSingleRegisterAsync(SlaveAddress, address, ushort.Parse(ioarg.Value.ToString()));
break;
}
rpcResponse.IsSuccess = true;
return rpcResponse;
}
else
rpcResponse.Description = $"不支持写入:{Method}";
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.DeviceName}],WriteAsync(),Error", ex);
}
return rpcResponse;
}
}
public enum PLC_TYPE
{
S7200 = 0,

View File

@ -10,6 +10,7 @@
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
<ItemGroup>

View File

@ -5,6 +5,8 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Automation.OPCClient;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
namespace DriverOPCDaClient
{
@ -12,6 +14,9 @@ namespace DriverOPCDaClient
{
OPCClientWrapper opcDaClient = null;
public ILogger _logger { get; set; }
private readonly Device _device;
#region
[ConfigParameter("设备Id")] public Guid DeviceId { get; set; }
@ -28,10 +33,12 @@ namespace DriverOPCDaClient
#endregion
public OPCDaClient(Guid deviceId)
public OPCDaClient(Device device, ILogger logger)
{
DeviceId = deviceId;
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}

View File

@ -14,5 +14,6 @@
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
</Project>

View File

@ -6,6 +6,8 @@ using Opc.Ua;
using Opc.Ua.Client;
using System.Collections.Generic;
using System.Threading.Tasks;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
using Opc.Ua.Configuration;
using OpcUaHelper;
@ -16,6 +18,9 @@ namespace DriverOPCUaClient
public class OPCUaClient : IDriver
{
OpcUaClientHelper opcUaClient = null;
public ILogger _logger { get; set; }
private readonly Device _device;
#region
[ConfigParameter("设备Id")]
@ -32,10 +37,12 @@ namespace DriverOPCUaClient
#endregion
public OPCUaClient(Guid deviceId)
public OPCUaClient(Device device, ILogger logger)
{
DeviceId = deviceId;
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}

View File

@ -14,5 +14,6 @@
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
</Project>

View File

@ -3,6 +3,8 @@ using IoTClient.Enums;
using PluginInterface;
using System;
using System.Text;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
namespace DriverOmronFins
{
@ -11,6 +13,9 @@ namespace DriverOmronFins
public class OmronFins : IDriver
{
private OmronFinsClient plc = null;
public ILogger _logger { get; set; }
private readonly Device _device;
#region
[ConfigParameter("设备Id")]
@ -30,9 +35,12 @@ namespace DriverOmronFins
#endregion
public OmronFins(Guid deviceId)
public OmronFins(Device device, ILogger logger)
{
DeviceId = deviceId;
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}

View File

@ -9,5 +9,6 @@
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
</Project>

View File

@ -2,6 +2,8 @@
using S7.Net;
using System;
using System.Text;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
namespace DriverSiemensS7
{
@ -15,6 +17,9 @@ namespace DriverSiemensS7
public class SiemensS7 : IDriver
{
private Plc plc = null;
public ILogger _logger { get; set; }
private readonly Device _device;
#region
[ConfigParameter("设备Id")]
@ -43,9 +48,12 @@ namespace DriverSiemensS7
#endregion
public SiemensS7(Guid deviceId)
public SiemensS7(Device device, ILogger logger)
{
DeviceId = deviceId;
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}

View File

@ -11,5 +11,6 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\PluginInterface\PluginInterface.csproj" />
<ProjectReference Include="..\..\..\IoTGateway.Model\IoTGateway.Model.csproj" />
</ItemGroup>
</Project>

View File

@ -2,6 +2,8 @@
using SimpleTCP;
using System;
using System.Text;
using IoTGateway.Model;
using Microsoft.Extensions.Logging;
namespace DriverSimTcpClient
{
@ -17,6 +19,9 @@ namespace DriverSimTcpClient
/// 缓存最新的服务器返回的原始数据
/// </summary>
private byte[] latestRcvData;
public ILogger _logger { get; set; }
private readonly Device _device;
#region
[ConfigParameter("设备Id")]
@ -42,9 +47,12 @@ namespace DriverSimTcpClient
#endregion
public SimTcpClient(Guid deviceId)
public SimTcpClient(Device device, ILogger logger)
{
DeviceId = deviceId;
_device = device;
_logger = logger;
_logger.LogInformation($"Device:[{_device.DeviceName}],Create()");
}

View File

@ -3,6 +3,7 @@ using Microsoft.Extensions.Configuration;
using PluginInterface;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using WalkingTec.Mvvm.Core;
using IoTGateway.DataAccess;
using IoTGateway.Model;
@ -83,8 +84,9 @@ namespace Plugin
else
{
var settings = DC.Set<DeviceConfig>().Where(x => x.DeviceId == Device.ID).AsNoTracking().ToList();
Type[] types = new Type[1] { typeof(Guid) };
object[] param = new object[1] { Device.ID };
Type[] types = new Type[2] { typeof(Device) ,typeof(ILogger) };
object[] param = new object[2] { Device , _logger };
ConstructorInfo constructor = driver.Type.GetConstructor(types);
var DeviceObj = constructor.Invoke(param) as IDriver;

View File

@ -1,4 +1,5 @@
using System;
using Microsoft.Extensions.Logging;
namespace PluginInterface
{
@ -8,6 +9,10 @@ namespace PluginInterface
public bool IsConnected { get; }
public int Timeout { get; }
public uint MinPeriod { get; }
public ILogger _logger { get; set; }
public bool Connect();
public bool Close();
//标准数据读取

View File

@ -8,6 +8,7 @@
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="6.0.0" />
</ItemGroup>
</Project>

View File

@ -20,7 +20,7 @@
>
## 交流
| 公众号:工业物联网网关 | [QQ群:712105424](https://qm.qq.com/cgi-bin/qm/qr?k=e3Y8biyVdhDxx3LPbjvNY3TSNOEAmjp7&jump_from=webapi) |
| 公众号:工业物联网网关 | 微信群 |
| ------ | ---- |
| ![wx](./images/wx.jpg) | ![qq](./images/qq.png) |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 31 KiB