插件管理

当平台内置的协议管理无法覆盖当前设备或第三方系统的对接方式时,可以通过插件包扩展平台能力。插件包本质上是一个独立的 Spring Boot Jar,既可以上传到平台由平台托管启动,也可以部署在外部服务器上独立运行,再通过 WebSocket 与平台通信。

官方提供了插件包示例工程,业务开发时通常只需要在 custom 包中编写采集、解析、下发等逻辑,平台通信、心跳、重连、配置同步等通用能力已经封装在 system 包中。

适用场景

1、设备数据需要通过 HTTP 接口、数据库轮询、OPC UA、PLC、串口等方式主动采集,再上报到平台。
2、平台内置 MQTT、TCP、HTTP 等协议组件无法满足项目的特殊对接逻辑,也可在插件包自行实现协议交互。
3、需要把第三方系统的数据转换成平台设备属性、事件或状态,并统一进入平台的数据处理链路。
4、需要接收平台下发的设备指令,再由插件自行调用外部接口、写 OPC UA 节点、发送 TCP/串口指令等。

平台上如何使用

1、打开插件管理页面,创建一个插件,注意运行模式选择外部独立接入的话,不需要上传插件jar到平台,直接本地启动你的插件包程序即可。把配置中的密钥、地址换成平台的插件Key、密钥即可。

img_1.png

2、创建好之后,去到网络组件页面,网络类型选择PLUGIN,然后选择刚才创建的插件,点击确定,启动它。后续就跟普通网络组件一样的操作。

img_2.png

3、如果插件类型选择的是外部独立接入,那么平台无法直接启动,需要插件包自己注册到平台。

插件包结构

插件包示例工程目录如下:

src/main/java/com/thinglinks/plugin/demo
├── DemoPluginApplication.java
├── custom
│   ├── handler/ExampleCommandHandler.java   # 下发指令示例
│   └── task/DemoCollectorTask.java          # 定时采集上报示例
└── system
    ├── Tl.java                              # 推荐使用的静态工具类
    ├── client/                              # 平台 WebSocket、心跳、重连
    ├── config/                              # 插件配置缓存
    └── model/                               # 上报/下发消息模型
custom 是业务代码目录,建议把真实项目里的采集任务、协议解析、外部接口调用、设备指令下发等逻辑都放在这里。
system 是平台固定能力目录,包含平台通信、配置同步、消息模型和工具类,正常情况下不要修改或删除,否则可能导致插件无法与平台通信。

开发流程

1、复制官方插件包示例工程作为业务插件工程。
2、在 custom 包中实现采集上报、下发处理、第三方系统对接等业务逻辑。
3、通过 Tl 工具类读取插件配置、上报设备数据、注册平台下发处理器。
4、执行 Maven 打包,生成插件 Jar。
5、在平台 网络组件 → 插件管理 中新增插件,上传 Jar 或配置外部接入参数。
6、创建网络组件并选择 PLUGIN 类型,绑定插件后启动网络组件。

打包上传

在插件工程根目录执行:

mvn clean package -DskipTests

生成文件示例:

target/thinglinks-plugin-1.0.0.jar

平台页面进入 网络组件 → 插件管理,点击新增插件并填写基础信息。平台托管运行时需要上传插件 Jar;外部独立接入时可以不上传 Jar,只需要维护插件 Key、密钥和连接信息。

推荐填写内容
字段说明
插件名称按业务含义填写,便于识别
插件 Key平台生成即可,也可以自定义全局唯一 Key
版本插件版本号,如 1.0.0
运行模式选择平台进程托管或外部独立接入
密钥平台生成即可,外部接入时需要带上该密钥
插件 Jar平台进程托管时上传打包后的 Jar
插件配置按 key/value 维护业务参数

主类、命令路径、健康路径、Java 参数、启动参数等字段一般可以保持默认,插件模板和平台已经提供默认启动行为。

运行模式

平台进程托管

平台托管适合资源占用较小、部署简单、希望由平台统一管理生命周期的插件。启动网络组件时,平台会自动启动插件进程,并注入平台 WS 地址、插件 Key、密钥、配置文件路径等参数;停止网络组件时,平台会停止插件进程。

外部独立接入

外部接入适合采集任务较多、协议连接较重、依赖特殊运行环境,或不希望占用平台服务器资源的插件。插件部署在外部机器上,通过平台提供的 WS 地址、插件 Key 和密钥接入平台。停止网络组件后,平台会拒绝该插件继续连接。

如果插件中包含大量定时任务、长连接、批量轮询或比较耗费 CPU/内存的逻辑,建议优先选择外部独立接入,避免影响平台主服务。

插件配置

插件配置在平台页面以 key/value 形式维护,适合放采集地址、点位信息、第三方接口地址、采集周期、token、开关参数等业务配置。

示例配置:

{
  "opcUaEndpoint": "opc.tcp://127.0.0.1:4840",
  "collectIntervalMs": 10000,
  "apiUrl": "http://127.0.0.1:9000/data",
  "enabled": true
}
配置同步规则
1、插件连接平台成功后,平台会主动下发一次最新配置。
2、页面修改配置并保存后,如果插件在线,平台会立即同步最新配置。
3、平台托管启动时,会把配置写入插件本地配置文件作为初始配置。
4、插件侧不需要自己处理配置同步消息,system 包会自动缓存最新配置。

业务代码可以通过 Tl 工具类读取配置:

String endpoint = Tl.str("opcUaEndpoint");
Integer interval = Tl.integer("collectIntervalMs");
Boolean enabled = Tl.bool("enabled");
Map<String, Object> all = Tl.config();

上报设备数据

插件上报推荐使用 Tl.up。最小上报只需要填写设备编号和属性数据:

import com.thinglinks.plugin.demo.system.Tl;
import com.thinglinks.plugin.demo.system.model.DecodeMessage;

import java.util.Date;
import java.util.Map;

public void report() {
    DecodeMessage message = new DecodeMessage();
    message.setDeviceSn("device_001");
    message.setProperties(Map.of("temperature", 25.6, "online", true));
    message.setReportTime(new Date());

    Tl.up(message);
}

如果需要上报时自动创建设备,可以补充产品编号和设备名称:

message.setIsRegister(true);
message.setProductSn("PRODUCT_SN");
message.setDeviceName("温度采集器");
常用上报字段
字段说明
deviceSn设备编号,单设备上报必填
properties属性数据,key 建议与物模型标识一致
reportTime上报时间,不填时平台可按接收时间处理
isRegister是否自动注册设备
productSn自动注册时使用的产品编号
deviceName自动注册时使用的设备名称
subDevices网关或批量上报的子设备列表
isStore是否存储,默认 true
isOnline是否在线,默认 true

接收平台下发

插件接收平台下发时,推荐使用 Tl.onDown 注册处理器。平台下发普通 DOWN 消息后,会先进入通过 Tl.onDown 注册的处理器;如果没有处理,再交给默认的 PluginCommandHandler

import com.thinglinks.plugin.demo.system.Tl;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Component;

@Component
public class MyCommandHandler {
    @PostConstruct
    public void init() {
        Tl.onDown(message -> {
            if ("setTemperature".equals(message.getFunctionCode())) {
                Object value = message.getProperties().get("temperature");
                // 在这里写 OPC UA 写节点、HTTP 请求、TCP/串口指令等业务逻辑
                return true;
            }
            return false;
        });
    }
}
Tl.onDown 可以注册多个处理器。返回 true 表示当前处理器已经接收并处理该指令;返回 false 表示继续交给后续处理器。
常用下发字段
字段说明
componentId网络组件 ID
deviceSn目标设备编号
functionCode功能码或命令码,建议业务按它分发
properties结构化参数
params原始字符串参数,复杂内容可放 JSON 字符串
customConfig平台透传的自定义配置字符串

插件中的指令下发需要自己实现与真实设备或第三方系统的通信逻辑。协议管理里的 MQTT、TCP 等组件通常只需要配置 topic、消息格式等,平台会按协议组件自动下发;插件模式下,平台只负责把指令交给插件,后续如何写设备、调接口、发指令由插件业务代码自行完成。

外部独立运行

外部独立接入时,在平台插件管理里复制平台 WS 地址、插件 Key 和密钥,然后启动插件:

img.png

通信规则

插件与平台之间通过 WebSocket 通信,主要包含三类消息:

消息类型说明
HEARTBEAT插件心跳和运行信息
UP插件上报平台,payloadDecodeMessageDecodeMessage 列表
DOWN平台下发插件,payloadPluginDownMessage

系统指令也会通过 DOWN 下发,但由 system 包自动处理:

系统指令说明
THINGLINKS_PLUGIN_CONFIG_SYNC平台同步插件配置
THINGLINKS_PLUGIN_STOP平台要求外部插件退出

业务代码通常不需要关心这些系统指令,只处理自己的业务 functionCode 即可。

注意事项

1、system 包中的平台通信、心跳、重连、配置缓存、消息模型等工具不要随意修改或删除,否则可能导致插件无法连接平台。
2、插件上报只表达设备数据本身,不包含 needReplyreplyTopicreplyContent 这类协议包回复字段。需要回复真实设备或第三方系统时,请在插件业务代码中自行处理。
3、插件下发不是平台协议组件的自动下发,平台只把指令发送给插件,插件需要自己完成设备通信逻辑。
4、资源占用较大的插件建议外部独立部署,避免大量定时任务、轮询任务或长连接影响平台主服务。
5、插件配置适合维护业务参数,不建议把敏感信息硬编码在代码里;生产环境请妥善保管插件密钥和第三方 token。
6、设备编号、产品编号如果是测试值,可以临时写在代码里;真实项目建议通过插件配置或业务逻辑动态维护。