为什么要自定义规则节点?
Thingsboard中为我们提供了很多规则节点,使用这些规则节点我们能完成大部分的配置任务,但是可能会有一些比较特殊的需求我们无法使用Thingsboard中提供的节点完成,例如外部节点中只有国外与一些国外厂商或框架交互的节点,而我们需要与国内厂商或者自己开发的系统进行交互就需要自定义节点了。
如何自定义节点?
一、创建项目
自定义节点是需要我们新建一个Java 项目然后编辑jar包引入到Thingsboard安装目录下的 **extensions**
目录的,所以我们需要新建一个项目来自定义节点。注意:并不是定义一个自定义节点即需要新建一个项目,每个项目都可以又N个自定义节点,为了便于管理,我们通常会将实现某个功能所需要的节点在一个项目内编写。
我们可以使用Maven或Gradle来管理项目,当然也可以不使用任何包管理工具,但是不建议这么做,因为官方的Demo使用Maven来管理的。
我们创建项目需要添加包依赖才能进行自定义节点的编写,因此我们需要在**pom.xml**
或gradle.build
文件中添加依赖项下面列出两种包管理工具所需要添加的内容。
Maven
版本信息
<properties>
<!--Thingsboard版本,你使用的版本是多少就写多少-->
<thingsboard.version>3.1.1</thingsboard.version>
<!--Lombok版本-->
<lombok.version>1.16.18</lombok.version>
<!--Guava版本-->
<guava.version>21.0</guava.version>
</properties>
引入依赖包
<dependencies>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>data</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>message</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>util</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>dao-api</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.thingsboard.rule-engine</groupId>
<artifactId>rule-engine-api</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
<version>${guava.version}</version>
</dependency>
</dependencies>
由于默认的maven仓库中并没有Thingsboard的依赖库,所以我们还需要配置使用Thingsboard的依赖库
**
<repositories>
<repository>
<id>thingsboard-repo</id>
<url>https://repo.thingsboard.io/artifactory/libs-release-public</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>top.zczhen</groupId>
<artifactId>CustomRuleNodes</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<!--Thingsboard版本,你使用的版本是多少就写多少-->
<thingsboard.version>3.1.1</thingsboard.version>
<!--Lombok版本-->
<lombok.version>1.16.18</lombok.version>
<!--Guava版本-->
<guava.version>21.0</guava.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>data</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>message</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>util</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>dao-api</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.thingsboard.rule-engine</groupId>
<artifactId>rule-engine-api</artifactId>
<scope>provided</scope>
<version>${thingsboard.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>provided</scope>
<version>${guava.version}</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>thingsboard-repo</id>
<url>https://repo.thingsboard.io/artifactory/libs-release-public</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
</project>
Gradle
版本信息
ext {
tb_version = '3.1.1'
lombok_version = '1.16.18'
guava_version = '21.0'
}
引入依赖包
dependencies {
compileOnly "org.thingsboard.common:data:$tb_version"
compileOnly "org.thingsboard.common:message:$tb_version"
compileOnly "org.thingsboard.common:util:$tb_version"
compileOnly "org.thingsboard.common:dao-api:$tb_version"
compileOnly "org.thingsboard.rule-engine:rule-engine-api:$tb_version"
compileOnly "org.projectlombok:lombok:$lombok_version"
compileOnly "com.google.guava:guava:$guava_version"
}
配置依赖库
repositories {
......
maven {
url 'https://repo.thingsboard.io/artifactory/libs-release-public'
}
}
gradle.build
plugins {
id 'java'
}
group 'top.zczhen'
version '1.0-SNAPSHOT'
ext {
tb_version = '3.1.1'
lombok_version = '1.16.18'
guava_version = '21.0'
}
repositories {
mavenCentral()
maven {
url 'https://repo.thingsboard.io/artifactory/libs-release-public'
}
}
dependencies {
compileOnly "org.thingsboard.common:data:$tb_version"
compileOnly "org.thingsboard.common:message:$tb_version"
compileOnly "org.thingsboard.common:util:$tb_version"
compileOnly "org.thingsboard.common:dao-api:$tb_version"
compileOnly "org.thingsboard.rule-engine:rule-engine-api:$tb_version"
compileOnly "org.projectlombok:lombok:$lombok_version"
compileOnly "com.google.guava:guava:$guava_version"
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}
test {
useJUnitPlatform()
}
开始编码
要自定义规则节点我们需要实现TbNode
接口,该接口的源码如下:
public interface TbNode {
void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException;
void onMsg(TbContext ctx, TbMsg msg) throws ExecutionException, InterruptedException, TbNodeException;
void destroy();
default void onPartitionChangeMsg(TbContext ctx, PartitionChangeMsg msg) {}
}
该接口有四个接口方法,其中init()
、onMsg()
、destory()
三个方法是必须实现的,onPartitionChangeMsg()
方法是默认实现的,从方法名我们可以看出,init()
方法是在节点初始化时调用,onMsg()
方法是在节点处理信息时调用,而destroy()
方法是在节点销毁时调用,但是这样并不好理解,我们并不知道这些方法究竟时在什么时候回被调用,因此我们编写如下代码进行测试。