物聯網很多業務場景中,時常需要獲取設備的實時狀態,以便根據不同狀態(在線或離線)做不同處理。阿里云物聯網平臺提供多個云端API來獲取設備的狀態信息。本文介紹這些API的調用方法。
原理
以下五個API可以獲得設備狀態。請根據業務需要,選擇調用的接口。
API | 描述 | 優缺點 |
---|---|---|
GetDeviceStatus | 獲取單個設備的狀態。 | 通過會話來獲取設備狀態,返回結果可能會因為網絡和心跳包延遲而延時更新。 |
BatchGetDeviceState | 批量獲取多個設備的狀態。 | |
QueryDeviceDetail | 查詢單個設備的詳細信息
除設備狀態外,還可以獲得其他設備信息。 |
|
BatchQueryDeviceDetail | 批量查詢多個設備的詳細信息
除設備狀態外,還可以獲得其他設備信息。 |
|
RRpc | 向指定設備發送查詢狀態的請求消息,并同步返回響應。 | 該接口查詢到的設備狀態信息準確度高。
說明 本文示例中,只介紹調用RRpc查詢設備狀態的服務端SDK配置;更完整的設備狀態查詢配置方法,請參見服務端檢測設備是否在線。
|
實現
本文示例使用Java SDK,需準備Java開發環境。
在Maven項目中,需添加如下pom依賴,安裝阿里云IoT SDK。
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-iot</artifactId>
<version>6.11.0</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.13</version>
</dependency>
Config.*參數值中,需傳入您的阿里云賬號AccessKey信息和設備信息。
// 地域ID,根據您的物聯網平臺服務地域獲取對應ID,http://bestwisewords.com/document_detail/40654.html
private static String regionId = "cn-shanghai";
// 您的阿里云賬號AccessKey ID
private static String accessKeyID = "Config.accessKey";
// 您的阿里云賬號AccesseKey Secret
private static String accessKeySecret = "Config.accessKeySecret";
// 要查詢的設備所屬產品的ProductKey
private static String productKey = "Config.productKey";
// 要查詢的設備的名稱DeviceName
private static String deviceName = "Config.deviceName";
完整代碼示例如下:
/*
* Copyright ? 2019 Alibaba. All rights reserved.
*/
package com.aliyun.iot.demo.checkstatus;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.codec.binary.Base64;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.iot.model.v20180120.BatchGetDeviceStateRequest;
import com.aliyuncs.iot.model.v20180120.BatchGetDeviceStateResponse;
import com.aliyuncs.iot.model.v20180120.BatchGetDeviceStateResponse.DeviceStatus;
import com.aliyuncs.iot.model.v20180120.BatchQueryDeviceDetailRequest;
import com.aliyuncs.iot.model.v20180120.BatchQueryDeviceDetailResponse;
import com.aliyuncs.iot.model.v20180120.BatchQueryDeviceDetailResponse.DataItem;
import com.aliyuncs.iot.model.v20180120.GetDeviceStatusRequest;
import com.aliyuncs.iot.model.v20180120.GetDeviceStatusResponse;
import com.aliyuncs.iot.model.v20180120.QueryDeviceDetailRequest;
import com.aliyuncs.iot.model.v20180120.QueryDeviceDetailResponse;
import com.aliyuncs.iot.model.v20180120.RRpcRequest;
import com.aliyuncs.iot.model.v20180120.RRpcResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
public class GetDeviceStatusByApi {
// ===================需要用戶填寫的參數開始===========================
// 修改Config.*的參數為您的實際信息
// 地域ID,根據您的物聯網平臺服務地域獲取對應ID,http://bestwisewords.com/document_detail/40654.html
private static String regionId = "cn-shanghai";
// 用戶賬號AccessKey ID
private static String accessKeyID = "Config.accessKey";
// 用戶賬號AccesseKey Secret
private static String accessKeySecret = "Config.accessKeySecret";
// 要查詢的設備所屬的產品ProductKey
private static String productKey = "Config.productKey";
// 要查詢的設備名稱deviceName
private static String deviceName = "Config.deviceName";
// ===================需要用戶填寫的參數結束===========================
private static DefaultAcsClient client = null;
private static DefaultAcsClient getClient(String accessKeyID, String accessKeySecret) {
if (client != null) {
return client;
}
try {
IClientProfile profile = DefaultProfile.getProfile(regionId, accessKeyID, accessKeySecret);
DefaultProfile.addEndpoint(regionId, regionId, "Iot", "iot." + regionId + ".aliyuncs.com");
client = new DefaultAcsClient(profile);
} catch (Exception e) {
System.out.println("create OpenAPI Client failed !! exception:" + e.getMessage());
}
return client;
}
/**
* 設備狀態獲取
* 方法一、二、三、四是基于狀態查詢的,獲取的狀態值可能會因為網絡和心跳包延遲而延時更新;
* 方法五是基于同步通信的,結果比較精準
*
* @param args
* @throws ServerException
* @throws ClientException
*/
public static void main(String[] args) throws ServerException, ClientException {
// 獲取服務端請求客戶端
DefaultAcsClient client = getClient(accessKeyID, accessKeySecret);
GetDeviceStatusByApi api = new GetDeviceStatusByApi();
// 方法一
api.ByGetDeviceStatus(client);
// 方法二
api.ByBatchGetDeviceState(client);
// 方法三
api.ByQueryDeviceDetail(client);
// 方法四
api.ByBatchQueryDeviceDetail(client);
// 方法五
api.ByRRpc(client);
}
/**
* 查詢單設備運行狀態
* GetDeviceStatus http://bestwisewords.com/document_detail/69617.html
*
* @param client 服務端請求客戶端
* @throws ServerException
* @throws ClientException
*/
public void ByGetDeviceStatus(DefaultAcsClient client) throws ServerException, ClientException {
// 填充請求
GetDeviceStatusRequest request = new GetDeviceStatusRequest();
request.setProductKey(productKey); // 目標設備產品key
request.setDeviceName(deviceName); // 目標設備名
// 獲取結果
GetDeviceStatusResponse response = (GetDeviceStatusResponse) client.getAcsResponse(request);
if (response != null && response.getSuccess()) {
GetDeviceStatusResponse.Data data = response.getData();
// ONLINE:設備在線。
// OFFLINE:設備離線。
// UNACTIVE:設備未激活。
// DISABLE:設備已禁用。
if ("ONLINE".equals(data.getStatus())) {
System.out.println("GetDeviceStatus 檢測:" + deviceName + " 設備在線");
} else { // 其他狀態歸結為設備不在線,也可以根據業務情況自行區分處理
System.out.println("GetDeviceStatus 檢測:" + deviceName + " 設備不在線");
}
} else {
System.out.println("GetDeviceStatus 檢測:" + "接口調用不成功,可能設備 " + deviceName + " 不存在");
}
}
/**
* 批量查詢設備運行狀態
* BatchGetDeviceState http://bestwisewords.com/document_detail/69906.html
*
* @param client 服務端請求客戶端
* @throws ServerException
* @throws ClientException
*/
public void ByBatchGetDeviceState(DefaultAcsClient client) throws ServerException, ClientException {
// 填充請求
BatchGetDeviceStateRequest request = new BatchGetDeviceStateRequest();
request.setProductKey(productKey); // 目標設備產品key
List<String> deviceNames = new ArrayList<String>(); // 目標設備名列表
deviceNames.add(deviceName);
request.setDeviceNames(deviceNames);
// 獲取結果
BatchGetDeviceStateResponse response = (BatchGetDeviceStateResponse) client.getAcsResponse(request);
if (response != null && response.getSuccess()) {
List<DeviceStatus> dsList = response.getDeviceStatusList();
for (DeviceStatus ds : dsList) {
// ONLINE:設備在線。
// OFFLINE:設備離線。
// UNACTIVE:設備未激活。
// DISABLE:設備已禁用。
if ("ONLINE".equals(ds.getStatus())) {
System.out.println("BatchGetDeviceState 檢測:" + ds.getDeviceName() + " 設備在線");
} else { // 其他狀態歸結為設備不在線,也可以根據業務情況自行區分處理
System.out.println("BatchGetDeviceState 檢測:" + ds.getDeviceName() + " 設備不在線");
}
}
} else {
System.out.println("BatchGetDeviceState 檢測:" + "接口調用不成功,可能設備 " + deviceName + " 不存在");
}
}
/**
* 查詢單設備詳細信息
* QueryDeviceDetail http://bestwisewords.com/document_detail/69594.html
*
* @param client 服務端請求客戶端
* @throws ServerException
* @throws ClientException
*/
public void ByQueryDeviceDetail(DefaultAcsClient client) throws ServerException, ClientException {
// 填充請求
QueryDeviceDetailRequest request = new QueryDeviceDetailRequest();
request.setProductKey(productKey); // 目標設備產品key
request.setDeviceName(deviceName); // 目標設備名
// 獲取結果
QueryDeviceDetailResponse response = (QueryDeviceDetailResponse) client.getAcsResponse(request);
if (response != null && response.getSuccess()) {
QueryDeviceDetailResponse.Data data = response.getData();
// ONLINE:設備在線。
// OFFLINE:設備離線。
// UNACTIVE:設備未激活。
// DISABLE:設備已禁用。
if ("ONLINE".equals(data.getStatus())) {
System.out.println("QueryDeviceDetail 檢測:" + deviceName + " 設備在線");
} else { // 其他狀態歸結為設備不在線,也可以根據業務情況自行區分處理
System.out.println("QueryDeviceDetail 檢測:" + deviceName + " 設備不在線");
}
} else {
System.out.println("QueryDeviceDetail 檢測:" + "接口調用不成功,可能設備 " + deviceName + " 不存在");
}
}
/**
* 批量查詢設備詳細信息
* BatchQueryDeviceDetai http://bestwisewords.com/document_detail/123470.html
*
* @param client 服務端請求客戶端
* @throws ServerException
* @throws ClientException
*/
public void ByBatchQueryDeviceDetail(DefaultAcsClient client) throws ServerException, ClientException {
// 填充請求
BatchQueryDeviceDetailRequest request = new BatchQueryDeviceDetailRequest();
request.setProductKey(productKey); // 目標設備產品key
List<String> deviceNames = new ArrayList<String>(); // 目標設備名列表
deviceNames.add(deviceName);
request.setDeviceNames(deviceNames);
// 獲取結果
BatchQueryDeviceDetailResponse response = (BatchQueryDeviceDetailResponse) client.getAcsResponse(request);
if (response != null && response.getSuccess()) {
List<DataItem> diList = response.getData();
for (DataItem di : diList) {
// ONLINE:設備在線。
// OFFLINE:設備離線。
// UNACTIVE:設備未激活。
// DISABLE:設備已禁用。
if ("ONLINE".equals(di.getStatus())) {
System.out.println("BatchQueryDeviceDetail 檢測:" + di.getDeviceName() + " 設備在線");
} else { // 其他狀態歸結為設備不在線,也可以根據業務情況自行區分處理
System.out.println("BatchQueryDeviceDetail 檢測:" + di.getDeviceName() + " 設備不在線");
}
}
} else {
System.out.println("BatchQueryDeviceDetail 檢測:" + "接口調用不成功,可能設備 " + deviceName + " 不存在");
}
}
/**
* RRPC 檢測設備狀態
* RRpc http://bestwisewords.com/document_detail/69797.html
*
* @param client 服務端請求客戶端
* @throws ServerException
* @throws ClientException
*/
public void ByRRpc(DefaultAcsClient client) throws ServerException, ClientException {
// 填充請求
RRpcRequest request = new RRpcRequest();
request.setProductKey(productKey);// 目標設備產品key
request.setDeviceName(deviceName);// 目標設備名
request.setRequestBase64Byte(Base64.encodeBase64String("Hello World".getBytes())); // 消息內容,必須base64編碼字符串
request.setTimeout(5000); // 響應超時設置,可根據實際需要填寫數值
// 獲取結果
RRpcResponse response = (RRpcResponse) client.getAcsResponse(request);
if (response != null) { // 不要使用response.getSuccess()判斷,非SUCCESS都是false;直接使用RrpcCode判斷即可
// UNKNOWN:系統異常
// SUCCESS:成功
// TIMEOUT:設備響應超時
// OFFLINE:設備離線
// HALFCONN:設備離線(設備連接斷開,但是斷開時間未超過一個心跳周期)
if ("SUCCESS".equals(response.getRrpcCode())) {
System.out.println("RRPC 檢測:" + deviceName + " 設備在線");
} else if (response.getRrpcCode() == null) {
System.out.println("RRPC 檢測:" + deviceName + " 設備可能不存在");
} else { // 其他狀態歸結為設備不在線,也可以根據業務情況自行區分處理
System.out.println("RRPC 檢測:" + deviceName + " 設備不在線:");
}
// RRPC 還可以實現更復雜的設備狀態檢測方法
// 請參考 http://bestwisewords.com/document_detail/101133.html
} else {
System.out.println("RRPC 檢測:" + "接口調用不成功");
}
}
}