5. 插件化驱动架构
IoT Gateway 采用了灵活的插件化驱动架构,支持动态加载和扩展不同设备驱动。这种设计使得网关能够适应各种不同类型的设备,便于扩展和维护。
Iotgateway 网关



5.1 驱动架构概述
驱动架构是 IoT Gateway 的核心设计之一,它允许开发者通过实现统一的接口来扩展网关支持的设备类型。驱动架构的主要组成部分包括:
-
驱动接口:定义了驱动必须实现的方法和属性
-
驱动加载机制:负责动态加载驱动程序集
-
驱动管理:管理已加载的驱动,提供驱动相关的操作
-
驱动实例化:根据设备配置创建驱动实例
5.2 驱动接口设计
5.2.1 IDriver 接口
IDriver 是所有驱动必须实现的核心接口,它定义了驱动的基本功能和行为。
public interface IDriver : IDisposable
{
// 设备是否已连接
bool IsConnected { get; }
// 最小采集周期
int MinPeriod { get; set; }
// 连接设备
bool Connect();
// 关闭连接
void Close();
// 写入数据
Task<DriverReturnValueModel> WriteAsync(string requestId, string method, DriverAddressIoArgModel request);
}
5.2.2 驱动属性
驱动可以定义自己的属性,这些属性可以通过配置文件或 Web 界面进行设置。属性需要使用 ConfigParameterAttribute 进行标记,以便网关能够识别和管理这些属性。
// 驱动属性示例
[ConfigParameter(Description = "IP地址")]
public string IpAddress { get; set; } = "127.0.0.1";
[ConfigParameter(Description = "端口")]
public int Port { get; set; } = 502;
5.2.3 驱动方法
驱动可以定义自己的方法,这些方法可以通过 RPC 命令调用。方法需要使用 MethodAttribute 进行标记,以便网关能够识别和调用这些方法。
// 驱动方法示例
[Method(Description = "读取数据")]
public DriverReturnValueModel Read(DriverAddressIoArgModel request)
{
// 读取数据逻辑
return new DriverReturnValueModel
{
Value = "123",
StatusType = VaribaleStatusTypeEnum.Good
};
}
5.3 驱动加载机制
5.3.1 驱动目录结构
驱动文件存储在网关的 drivers/net6.0 目录下,每个驱动对应一个 DLL 文件。
iotgateway/
└── drivers/
└── net6.0/
├── DriverModbusMaster.dll
├── DriverOPCUA.dll
└── ...
5.3.2 驱动加载流程
-
应用启动时,DriverService 扫描驱动目录
-
加载所有 DLL 文件
-
查找实现了 IDriver 接口的类型
-
将驱动信息添加到驱动列表
-
提供驱动相关的操作接口
5.3.3 驱动加载代码
public void LoadAllDrivers()
{
try
{
_logger.LogInformation("LoadAllDrivers Start");
foreach (var file in driverFiles)
{
var dll = Assembly.LoadFrom(file);
foreach (var type in dll.GetTypes().Where(x => typeof(IDriver).IsAssignableFrom(x) && x.IsClass))
{
DriverInfo driverInfo = new DriverInfo
{
FileName = Path.GetFileName(file),
Type = type
};
DriverInfos.Add(driverInfo);
}
}
_logger.LogInformation($"LoadAllDrivers End,Count{DriverInfos.Count}");
}
catch (Exception ex)
{
_logger.LogError("LoadAllDrivers Error,一般是驱动项目引用的nuget或dll没有复制到驱动文件夹", ex);
}
}
5.4 驱动管理
5.4.1 驱动注册
开发者需要在网关 Web 界面中注册驱动,注册过程包括:
-
选择驱动 DLL 文件
-
输入驱动名称和描述
-
网关自动识别驱动类型和属性
-
保存驱动信息到数据库
5.4.2 驱动配置
驱动注册后,开发者可以为设备配置驱动属性。网关会自动识别驱动的属性,并提供相应的配置界面。
5.4.3 驱动实例化
当创建设备线程时,网关会根据设备配置实例化驱动:
-
加载驱动类型
-
创建驱动实例
-
初始化驱动属性
-
返回驱动实例
// 驱动实例化代码
public void CreateDeviceThread(Device Device)
{
// 加载驱动类型
var driver = _DrvierManager.DriverInfos.Where(x => x.Type.FullName == Device.Driver.AssembleName).SingleOrDefault();
// 创建驱动实例
Type[] types = new Type[1] { typeof(Guid) };
object[] param = new object[1] { Device.ID };
ConstructorInfo constructor = driver.Type.GetConstructor(types);
var DeviceObj = constructor.Invoke(param) as IDriver;
// 初始化驱动属性
foreach (var p in driver.Type.GetProperties())
{
var config = p.GetCustomAttribute(typeof(ConfigParameterAttribute));
var setting = settings.Where(x => x.DeviceConfigName == p.Name).FirstOrDefault();
if (config == null || setting == null)
continue;
// 设置属性值
object value = setting.Value;
// 类型转换
// ...
p.SetValue(DeviceObj, value);
}
// 创建设备线程
var deviceThread = new DeviceThread(Device, DeviceObj, systemManage.GatewayName, _MyMqttClient, interpreter, _MqttServer, _logger);
DeviceThreads.Add(deviceThread);
}
5.5 驱动开发流程
5.5.1 开发环境准备
-
安装 Visual Studio 2022 或更高版本
-
安装 .NET 6.0 SDK
-
克隆 IoT Gateway 代码仓库
-
打开
IoTGateway.sln解决方案
5.5.2 创建驱动项目
-
在解决方案中添加新的类库项目
-
设置目标框架为 .NET 6.0
-
引用
PluginInterface项目 -
实现 IDriver 接口
5.5.3 编写驱动代码
-
定义驱动类,实现 IDriver 接口
-
添加驱动属性,使用
ConfigParameterAttribute标记 -
添加驱动方法,使用
MethodAttribute标记 -
实现驱动的核心功能,如连接设备、读取数据、写入数据等
5.5.4 编译和部署驱动
-
编译驱动项目,生成 DLL 文件
-
将 DLL 文件复制到网关的
drivers/net6.0目录 -
在网关 Web 界面中注册驱动
-
创建设备,选择刚注册的驱动
-
配置设备属性,启动设备
5.6 驱动开发示例
5.6.1 简单驱动示例
using PluginInterface;
using System;
using System.Threading.Tasks;
namespace SampleDriver
{
public class SampleDriver : IDriver
{
// 驱动属性
[ConfigParameter(Description = "IP地址")]
public string IpAddress { get; set; } = "127.0.0.1";
[ConfigParameter(Description = "端口")]
public int Port { get; set; } = 502;
// 设备连接状态
public bool IsConnected { get; private set; }
// 最小采集周期
public int MinPeriod { get; set; } = 1000;
// 连接设备
public bool Connect()
{
// 连接设备逻辑
IsConnected = true;
return true;
}
// 关闭连接
public void Close()
{
// 关闭连接逻辑
IsConnected = false;
}
// 读取数据方法
[Method(Description = "读取数据")]
public DriverReturnValueModel Read(DriverAddressIoArgModel request)
{
// 读取数据逻辑
return new DriverReturnValueModel
{
Value = "123",
StatusType = VaribaleStatusTypeEnum.Good
};
}
// 写入数据方法
public async Task<DriverReturnValueModel> WriteAsync(string requestId, string method, DriverAddressIoArgModel request)
{
// 写入数据逻辑
return new DriverReturnValueModel
{
IsSuccess = true,
Description = "写入成功"
};
}
// 释放资源
public void Dispose()
{
// 释放资源逻辑
}
}
}
5.6.2 驱动项目配置
驱动项目需要引用 PluginInterface 项目,这是网关和驱动之间的接口定义。在项目文件中添加以下引用:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PluginInterface\PluginInterface.csproj" />
</ItemGroup>
</Project>
5.7 驱动开发最佳实践
5.7.1 接口设计
-
遵循单一职责原则:每个驱动只负责一种设备类型或协议
-
保持接口简洁:只暴露必要的方法和属性
-
使用异步编程:对于耗时操作,如网络通信,使用异步方法
-
提供良好的错误处理:捕获和处理异常,返回有意义的错误信息
5.7.2 性能优化
-
减少资源消耗:合理管理资源,及时释放不再使用的资源
-
优化数据采集:根据设备特性优化采集周期和数据处理逻辑
-
使用缓存:对于频繁访问的数据,使用缓存机制
5.7.3 可靠性设计
-
实现自动重连:当设备连接断开时,自动尝试重连
-
添加超时处理:对于网络通信,添加超时处理
-
实现心跳机制:定期检查设备连接状态
-
提供详细的日志:记录驱动的运行状态和错误信息
5.7.4 安全性设计
-
验证输入参数:对所有输入参数进行验证,防止注入攻击
-
加密敏感数据:对于敏感数据,如密码,进行加密存储和传输
-
限制权限:根据最小权限原则设计驱动权限
5.8 驱动测试
5.8.1 单元测试
为驱动编写单元测试,测试驱动的核心功能:
-
驱动初始化
-
设备连接和断开
-
数据读取和写入
-
错误处理
5.8.2 集成测试
将驱动部署到网关中,进行集成测试:
-
驱动加载和注册
-
设备创建和配置
-
数据采集和上传
-
RPC 命令执行
5.8.3 性能测试
测试驱动的性能:
-
数据采集速率
-
资源消耗
-
并发处理能力
5.9 驱动版本管理
5.9.1 版本号规范
使用语义化版本号规范:
-
主版本号:当进行不兼容的 API 更改时递增
-
次版本号:当添加向后兼容的功能时递增
-
修订号:当进行向后兼容的错误修复时递增
5.9.2 版本兼容性
-
保持 API 向后兼容
-
提供迁移指南
-
支持多版本驱动共存
5.10 驱动生态系统
5.10.1 官方驱动
网关提供了一些官方驱动,如:
-
Modbus TCP 驱动
-
Modbus RTU 驱动
-
OPC UA 驱动
-
MQTT 驱动
5.10.2 第三方驱动
开发者可以开发和共享第三方驱动,丰富网关的设备支持。
5.10.3 驱动市场
未来计划建立驱动市场,方便开发者发布和获取驱动。
文档版本 :1.0 更新日期 :2025-11-29 编写人员:辉为科技