根据deviceName获取deviceId
先复习如何获取升级包,贴出代码
TransportProtos.SessionInfoProto sessionInfo = deviceSessionCtx.getSessionInfo();
TransportProtos.GetOtaPackageRequestMsg getOtaPackageRequestMsg = TransportProtos.GetOtaPackageRequestMsg.newBuilder()
.setDeviceIdMSB(sessionInfo.getDeviceIdMSB())
.setDeviceIdLSB(sessionInfo.getDeviceIdLSB())
.setTenantIdMSB(sessionInfo.getTenantIdMSB())
.setTenantIdLSB(sessionInfo.getTenantIdLSB())
.setType(type.name())
.build();
transportService.process(deviceSessionCtx.getSessionInfo(), getOtaPackageRequestMsg,
new OtaPackageCallback(ctx, msgId, getOtaPackageRequestMsg, requestId, chunkSize, chunk));
想要获取升级包,就要构造一条消息,想要构造一条消息,就要设备的sessionInfo,而sessionInfo从何而来,我们只知道deviceName,这可如何是好?
通过看 org.thingsboard.server.transport.mqtt.session 包 GatewaySessionHandler 类 checkDeviceConnected方法,完美解决我的问题,这个方法是这样的:
private ListenableFuture<GatewayDeviceSessionCtx> checkDeviceConnected(String deviceName) {
GatewayDeviceSessionCtx ctx = devices.get(deviceName);
if (ctx == null) {
log.debug("[{}] Missing device [{}] for the gateway session", sessionId, deviceName);
return onDeviceConnect(deviceName, DEFAULT_DEVICE_TYPE);
} else {
return Futures.immediateFuture(ctx);
}
}
方法的参数是deviceName,返回值是GatewayDeviceSessionCtx,GatewayDeviceSessionCtx里面有个成员变量sessionInfo,这个sessionInfo就是我们苦苦寻找的sessionInfo,真是踏破铁鞋无觅处,得来全不费工夫,有了它,我们就能构造消息,有了消息,就能获取升级包。
但这个方法是私有方法,外界无法直接调用,这倒不是问题,我们再写一个public方法,包一层,而且直接返回sessionInfo,我写的方法可供参考:
public ListenableFuture<TransportProtos.SessionInfoProto> getDeviceSessionInfo(String deviceName) {
final SettableFuture<TransportProtos.SessionInfoProto> futureToSet = SettableFuture.create();
ListenableFuture<GatewayDeviceSessionCtx> listenableFuture = checkDeviceConnected(deviceName);
Futures.addCallback(checkDeviceConnected(deviceName),
new FutureCallback<>() {
@Override
public void onSuccess(@Nullable GatewayDeviceSessionCtx deviceCtx) {
futureToSet.set(deviceCtx.getSessionInfo());
}
@Override
public void onFailure(Throwable t) {
log.debug("[{}] Failed to process device ota request command: {}", sessionId, deviceName, t);
}
}, context.getExecutor());
return futureToSet;
}
由于要提取精华,只要sessionInfo,所以再搞一个future,并返回,等checkDeviceConnected的future有数据了,就设置future的值。
MqttTransportHandler类中,正好有GatewaySessionHandler对象,可以直接调用gatewaySessionHandler.getDeviceSessionInfo(deviceName)获取到sessionInfo。
至此,获取任意设备的升级包的所有障碍全部扫除,接下来处理网关发送的获取升级包请求。