Iotgateway技术手册-5. 插件化驱动架构

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 驱动加载流程

  1. 应用启动时,DriverService 扫描驱动目录

  2. 加载所有 DLL 文件

  3. 查找实现了 IDriver 接口的类型

  4. 将驱动信息添加到驱动列表

  5. 提供驱动相关的操作接口

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 界面中注册驱动,注册过程包括:

  1. 选择驱动 DLL 文件

  2. 输入驱动名称和描述

  3. 网关自动识别驱动类型和属性

  4. 保存驱动信息到数据库

5.4.2 驱动配置

驱动注册后,开发者可以为设备配置驱动属性。网关会自动识别驱动的属性,并提供相应的配置界面。

5.4.3 驱动实例化

当创建设备线程时,网关会根据设备配置实例化驱动:

  1. 加载驱动类型

  2. 创建驱动实例

  3. 初始化驱动属性

  4. 返回驱动实例

复制代码
// 驱动实例化代码
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 开发环境准备

  1. 安装 Visual Studio 2022 或更高版本

  2. 安装 .NET 6.0 SDK

  3. 克隆 IoT Gateway 代码仓库

  4. 打开 IoTGateway.sln 解决方案

5.5.2 创建驱动项目

  1. 在解决方案中添加新的类库项目

  2. 设置目标框架为 .NET 6.0

  3. 引用 PluginInterface 项目

  4. 实现 IDriver 接口

5.5.3 编写驱动代码

  1. 定义驱动类,实现 IDriver 接口

  2. 添加驱动属性,使用 ConfigParameterAttribute 标记

  3. 添加驱动方法,使用 MethodAttribute 标记

  4. 实现驱动的核心功能,如连接设备、读取数据、写入数据等

5.5.4 编译和部署驱动

  1. 编译驱动项目,生成 DLL 文件

  2. 将 DLL 文件复制到网关的 drivers/net6.0 目录

  3. 在网关 Web 界面中注册驱动

  4. 创建设备,选择刚注册的驱动

  5. 配置设备属性,启动设备

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 编写人员:辉为科技

相关推荐
No0d1es17 小时前
2025年12月 GESP CCF编程能力等级认证C++一级真题
开发语言·c++·青少年编程·gesp·ccf
荒诞硬汉17 小时前
面向对象(三)
java·开发语言
郝学胜-神的一滴17 小时前
深入理解Linux中的Try锁机制
linux·服务器·开发语言·c++·程序人生
liliangcsdn17 小时前
bash中awk如何切分输出
开发语言·bash
peixiuhui17 小时前
Iotgateway技术手册-3. 架构设计
.net·iot·核心板·iotgateway·开源网关·arm工控板
csbysj202017 小时前
JSON.parse() 方法详解
开发语言
奔波霸的伶俐虫17 小时前
redisTemplate.opsForList()里面方法怎么用
java·开发语言·数据库·python·sql
普马萨特17 小时前
移动网络信号指标与单位整理(2G/3G/4G/5G Android vs IoT)
android·网络·物联网
yesyesido17 小时前
智能文件格式转换器:文本/Excel与CSV无缝互转的在线工具
开发语言·python·excel