使用优秀开源代码driver-box开发记录
        【摘要】 driverbox插件注册:懒汉式单例模式创建interval里的插件管理器单例插件管理器中使用策略模式注册不同的插件注册结果是把不同实现的plugin.Plugin对象存储在插件管理器中插件管理器map变量中的key为ProtocolName,支持的ProtocolName有:dlt645mirrormqtttcp_serverwebsockethttp_serverhttp_client...
    
    
    
    driverbox
- 插件注册:
- 懒汉式单例模式创建interval里的插件管理器
 - 单例插件管理器中使用策略模式注册不同的插件
 - 注册结果是把不同实现的plugin.Plugin对象存储在插件管理器中
 - 插件管理器map变量中的key为ProtocolName,支持的ProtocolName有:
- dlt645
 - mirror
 - mqtt
 - tcp_server
 - websocket
 - http_server
 - http_client
 - driverbox
 - bacnet
 - modbus
 
 
 - 加载json配置文件:
- 初始化配置文件位置:./res/driver/
 - 饿汉式单例模式将config.Config加载到map中
 - 配置文件中config.Config.ProtocolName需要唯一,否则加载时报错
 - json配置文件内容:与config.Config中内容对应
 - 通过driverKey实现devicePoints中点位与设备物模型属性绑定与数值换算
 - res/library/driver目录下的每一个lua文件的文件名对应devices中driverKey
 - 通过protocolKey实现通信内容与driver-box内置标准化数据结构的互转
 - res/library/protocol目录下的每一个lua文件的文件名对应connections中protocolKey
 - json配置文件示例:
 
 
{
  "deviceModels": [
    {
      "name": "name1",
      "modelId": "modelId1",
      "description": "",
      "attributes": null,
      "devicePoints": [
        {
          "name": "name1",
          "readWrite": "RW",
          "reportMode": "realTime",
          "valueType": "int"
        }
      ],
      "devices": [
        {
          "id": "deviceid1",
          "description": "",
          "ttl": "",
          "tags": null,
          "connectionKey": "4g",
          "properties": null,
          "driverKey": ""
        }
      ]
    }
  ],
  "connections": {
    "4g": {
      "address": "192.168.1.2:8888",
      "batchReadLen": 50,
      "batchWriteLen": 10,
      "enable": true,
      "minInterval": 500,
      "mode": "tcp",
      "timeout": 5000,
      "virtual": false,
      "protocolKey": ""
    }
  },
  "protocolName": "modbus"
}
- 启动插件:
- 配置config.Config转换为核心缓存中config.Model、config.Device,检查配置并更新到持久化json文件
 - 根据config.Config配置中protocolName,找到对应的plugin.Plugin对象并初始化
 - plugin.Plugin对象加载到核心缓存
 - 运行Plugin接口的Initialize方法,根据config.Config.connections打开串口
 - 对config.Config中同一个DeviceModels,根据Devices.ConnectionKey给devices分组
 - ConnectionConfig.Enable=true则每1s启动cronb任务根据Duration判断是否执行
 - 根据DevicePoints生成下发指令,插件自动解析接收数据
 
 - 基于driverbox只通过配置json实现DLT645设备解析:
 
{
  "deviceModels": [
    {
      "name": "deviceModelName",
      "modelId": "deviceModelId",
      "description": "description_xxx",
      "attributes": null,
      "devicePoints": [
        {
          "dataMaker": "00010000",
          "decimals": 2,
          "description": "电能描述",
          "duration": "10s",
          "name": "电能",
          "quantity": 4,
          "readWrite": "R",
          "reportMode": "realTime",
          "scale": 0.01,
          "units": "KWh",
          "valueType": "float"
        }
      ],
      "devices": [
        {
          "id": "290110213565",
          "description": "deviceid",
          "ttl": "",
          "tags": null,
          "connectionKey": "COM2400EVEN81",
          "properties": {
            "slaveId": "290110213565"
          },
          "driverKey": ""
        }
      ]
    }
  ],
  "connections": {
    "COM2400EVEN81": {
      "address": "com4",
      "autoReconnect": true,
      "baudRate": 2400,
      "dataBits": 8,
      "discover": true,
      "enable": true,
      "minInterval": 500,
      "parity": "E",
      "protocolKey": "",
      "protocolLogEnabled": true,
      "retry": 3,
      "stopBits": 1,
      "timeout": 1000,
      "virtual": false
    }
  },
  "protocolName": "dlt645"
}
- 新建插件:
- 代码实现Plugin、Connector接口
 - plugins类中新增插件加载方法并在main函数中调用方法
 - 每个插件中LuaVM实例根据json配置文件同目录的converter.lua加载
 - 解析结果中DeviceData、PointData对应config.Config中的Devices、DevicePoints
 
 - Export模块实现:
- 在插件的callback包中将解析完成的deviceData作为export.Exports的参数传入
 
 - 场景联动模块实现:
- export与plugin均以单例模式加载到全局变量中
 - 配置:json文件存储在路径LinkConfigPath,文件名即linkedge.Config中的ID
 - json配置文件示例:
 
 
{
  "id": "abcdefg.json",
  "enable": true,
  "name": "abcdefg.json",
  "tags": [
    "tagA",
    "tagB"
  ],
  "description": "描述",
  "silentPeriod": 10,
  "trigger": [
    {
      "type": "schedule",
      "cron": "* * * * *"
    },
    {
      "type": "devicePoint",
      "devSn": "device_1",
      "point": "onOff",
      "contition": "=",
      "value": "1"
    }
  ],
  "condition": [
    {
      "type": "devicePoint",
      "devSn": "device_1",
      "point": "onOff",
      "contition": "=",
      "value": "1"
    },
    {
      "type": "executeTime",
      "begin": 1713943756000,
      "end": 1713943756000
    },
    {
      "type": "years",
      "years": [
        2020,
        2021
      ]
    },
    {
      "type": "months",
      "months": [
        1,
        2
      ]
    },
    {
      "type": "days",
      "days": [
        1,
        2,
        3
      ]
    },
    {
      "type": "weeks",
      "weeks": [
        0,
        1,
        2
      ]
    },
    {
      "type": "times",
      "begin_times": "09:00",
      "end_times": "18:00"
    }
  ],
  "action": [
    {
      "type": "devicePoint",
      "condition": [
      ],
      "attr": {
      },
      "sleep": "3s",
      "devSn": "device_1",
      "point": "onOff",
      "value": "1"
    },
    {
      "type": "linkEdge",
      "id": "xxxxxx"
    }
  ]
}
- 加载:在export.Init方法中,通过restful包注册处理函数,通过api加载并启动场景,并持久化到路径LinkConfigPath
 
            【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
                cloudbbs@huaweicloud.com
                
            
        
        
        
        
        - 点赞
 - 收藏
 - 关注作者
 
            
           
评论(0)