ThingsBoard 自定义创建设备的规则节点
正文、配图与代码来自原稿。在规则链中按配置创建设备(已存在则更新),适合自动开户、批量接入场景。
1、定义 TbCreateDeviceNode
java
package org.thingsboard.rule.engine.custom.createDevice;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import org.thingsboard.common.util.JacksonUtil;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.rule.engine.api.util.TbNodeUtils;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.msg.TbMsg;
import java.util.UUID;
import static org.thingsboard.common.util.DonAsynchron.withCallback;
@RuleNode(
type = ComponentType.ACTION,
name = "create device",
configClazz = TbCreateDeviceNodeConfiguration.class,
nodeDescription = "Create device",
nodeDetails = "Create device",
uiResources = {"static/rulenode/rulenode-core-config.js"},
icon = "add_circle")
@Slf4j
public class TbCreateDeviceNode implements TbNode {
private TbCreateDeviceNodeConfiguration config;
@Override
public void init(TbContext ctx, TbNodeConfiguration configuration) throws TbNodeException {
this.config = TbNodeUtils.convert(configuration, TbCreateDeviceNodeConfiguration.class);
}
@Override
public void onMsg(TbContext ctx, TbMsg msg) {
try {
withCallback(createDevice(ctx),
saveDevice -> ctx.tellSuccess(msg),
t -> ctx.tellFailure(msg, t), ctx.getDbCallbackExecutor());
} catch (Exception e) {
ctx.tellFailure(msg, e);
}
}
private ListenableFuture<Device> createDevice(TbContext ctx) {
log.info("config:" + config);
if (ObjectUtils.isEmpty(config.getName())) {
throw new RuntimeException("设备名称不能为空");
}
if (ObjectUtils.isEmpty(config.getDeviceProfileId())) {
throw new RuntimeException("设备配置ID不能为空");
}
if (ObjectUtils.isEmpty(config.getCustomerId())) {
// 未指定客户时挂到 Public / 默认客户 UUID(按你环境调整)
config.setCustomerId("13814000-1dd2-11b2-8080-808080808080");
}
Device oldDevice = ctx.getDeviceService()
.findDeviceByTenantIdAndName(ctx.getTenantId(), config.getName());
if (!ObjectUtils.isEmpty(oldDevice)) {
oldDevice.setName(config.getName());
oldDevice.setLabel(config.getLabel());
oldDevice.setTenantId(ctx.getTenantId());
oldDevice.setDeviceProfileId(DeviceProfileId.fromString(config.getDeviceProfileId()));
oldDevice.setAdditionalInfo(JacksonUtil.valueToTree(config.getAdditionalInfo()));
oldDevice.setCustomerId(new CustomerId(UUID.fromString(config.getCustomerId())));
return Futures.immediateFuture(ctx.getDeviceService().saveDevice(oldDevice));
}
Device device = new Device();
device.setName(config.getName());
device.setLabel(config.getLabel());
device.setTenantId(ctx.getTenantId());
device.setDeviceProfileId(DeviceProfileId.fromString(config.getDeviceProfileId()));
device.setAdditionalInfo(JacksonUtil.valueToTree(config.getAdditionalInfo()));
device.setCustomerId(new CustomerId(UUID.fromString(config.getCustomerId())));
return Futures.immediateFuture(ctx.getDeviceService().saveDevice(device));
}
}2、定义 TbCreateDeviceNodeConfiguration
java
package org.thingsboard.rule.engine.custom.createDevice;
import lombok.Data;
import org.thingsboard.rule.engine.api.NodeConfiguration;
@Data
public class TbCreateDeviceNodeConfiguration
implements NodeConfiguration<TbCreateDeviceNodeConfiguration> {
private String name;
private String label;
private String deviceProfileId;
private AdditionalInfo additionalInfo;
private String customerId;
@Override
public TbCreateDeviceNodeConfiguration defaultConfiguration() {
TbCreateDeviceNodeConfiguration configuration = new TbCreateDeviceNodeConfiguration();
configuration.setName("");
configuration.setLabel("");
configuration.setDeviceProfileId("");
configuration.setAdditionalInfo(new AdditionalInfo());
configuration.setCustomerId("");
return configuration;
}
}配置 JSON 示意(UI 里设备配置常以实体对象形式出现,落地时取 id 字符串即可):
json
{
"name": "test1",
"label": "",
"deviceProfileId": "53562990-7fc3-11ee-b35b-ab3138b75231",
"additionalInfo": {
"gateway": false,
"overwriteActivityTime": false,
"description": ""
},
"customerId": null
}3、定义 AdditionalInfo
java
package org.thingsboard.rule.engine.custom.createDevice;
import lombok.Data;
@Data
public class AdditionalInfo {
private Boolean gateway = false;
private Boolean overwriteActivityTime = false;
private String description = "";
}4、项目结构

5、小结
- 同名设备走 更新,否则 新建。
deviceProfileId、客户 ID 必填策略按业务调整;生产环境勿写死客户 UUID。- 名称、标签等可用模板从消息注入(见 模板化)。
