本文介紹云云對接SDK中進階功能的使用,包括自定義配置文件路徑、配置動態創建網橋設備、調用SDK中封裝的接口進行物模型數據上報、設備屬性和事件批量上報、屬性設置和服務調用。
自定義配置管理
默認情況下,網橋的配置文件和設備證書的映射關系配置文件,都是從固定路徑的固定文件(分別是application.conf和devices.conf)中讀取的。
云云對接SDK提供自定義配置能力,您只需在調用bootstrap方法前,先調用ConfigFactory.init方法,自定義配置文件的路徑,自定義實例實現對應的接口。
使用自定義配置管理,必須實現getDeviceIdentity
和getOriginalIdentity
方法。
代碼示例:
private static DeviceConfigManager selfDefineDeviceConfigManager = new DeviceConfigManager() {
@Override
public DeviceIdentity getDeviceIdentity(String originalIdentity) {
// 根據originalIdentity返回設備信息
return devicesMap.get(originalIdentity);
}
@Override
public String getOriginalIdentity(String productKey, String deviceName) {
// 根據設備信息返回originalIdentity
return null;
}
};
BridgeBootstrap bridgeBootstrap = new BridgeBootstrap();
ConfigFactory.init(ConfigFactory.getBridgeConfigManager("application-self-define.conf"),selfDefineDeviceConfigManager);
bridgeBootstrap.bootstrap();
動態創建網橋設備
當在大量的服務器上部署網橋應用,如果為每一個網橋服務器指定不同的網橋設備,信息會比較繁瑣。為解決此問題,您可配置網橋信息文件application.conf,動態創建網橋設備。
您需在配置文件中,傳入參數productKey和popClientProfile,云云對接SDK將調用物聯網平臺開放的API,以服務器MAC地址作為設備名稱,創建一個網橋設備。
動態創建網橋設備,僅需修改網橋配置文件,調用代碼與基礎用法一致。
popClientprofile的所有參數必須配置完整。如果當前MAC地址為已有設備名稱,會直接使用該設備作為網橋設備。
參數deviceName和deviceSecret值必須為空,如果已指定網橋設備信息,不會再動態創建設備。
建議使用專用的調測設備調試程序,不要直接在本地機器上調試,以免影響正式的生產環境。
在多個本地PC上調試程序,每次都會將當前機器的MAC地址注冊為網橋,并將devices.conf文件中的所有設備與該網橋關聯。
表 1. 配置參數說明
參數 | 是否必需 | 說明 |
productKey | 是 | 網橋設備所屬產品的ProductKey。 |
subDeviceConnectMode | 否 | 網橋掛載設備模式:
大型網橋、小型網橋的掛載設備下線策略不同,請參見設備下線。 |
http2Endpoint | 是 | HTTP2網關服務地址。網橋設備和物聯網平臺通過HTTP2協議建立長連接通道。 地址結構:
|
authEndpoint | 是 | 設備認證服務地址。 地址結構:
|
popClientProfile | 是 | 配置此參數,云云對接SDK將調用阿里云物聯網平臺開放接口自動創建一個網橋設備。 具體參數配置見下表popClientProfile。 |
表 2. popClientProfile
參數 | 是否必需 | 描述 |
accessKey | 是 | 您的阿里云賬號的AccessKey ID。 在物聯網平臺控制臺,鼠標移動到您的賬號頭像上,然后單擊AccessKey管理,創建或查看AccessKey。 |
accessSecret | 是 | 您的阿里云賬號的AccessKey Secret。 |
name | 是 | 將要創建網橋設備的所在地域ID。 地域的表達方法,請參見地域和可用區。 |
region | 是 | |
product | 是 | 產品名稱,固定為Iot。 |
endpoint | 是 | 調用指定地域API的節點地址。結構為 變量${RegionId}需替換成您的服務所在地域代碼。RegionId的表達方法,請參見地域和可用區。 例如:華東2(上海)地域的endpoint為 |
以企業版實例為例,動態創建小型網橋設備的配置代碼如下:
// 服務地址
http2Endpoint = "https://${IotInstanceId}.http2.iothub.aliyuncs.com:443"
authEndpoint = "https://${IotInstanceId}.auth.iothub.aliyuncs.com/auth/bridge"
// 網橋設備信息
productKey = ${YourProductKey}
popClientProfile = {
accessKey = ${YourAliyunAccessKey}
accessSecret = ${YourAliyunAccessSecret}
name = cn-shanghai
region = cn-shanghai
product = Iot
endpoint = iot.cn-shanghai.aliyuncs.com
}
調用物模型數據上報接口
云云對接SDK中封裝了部分數據上報接口,包括屬性上報接口 reportProperty、事件上報接口fireEvent和更新設備標簽接口updateDeviceTag。設備可通過以上接口向物聯網平臺上報相應消息。
調用示例:
TslUplinkHandler tslUplinkHandler = new TslUplinkHandler();
//上報屬性。
//已定義testProp屬性。
String requestId = String.valueOf(random.nextInt(1000));
//上報屬性時,不攜帶時間戳。
tslUplinkHandler.reportProperty(requestId, originalIdentity, "testProp", random.nextInt(100));
//上報屬性時,攜帶時間戳。
//tslUplinkHandler.reportProperty(requestId, originalIdentity, "testProp", random.nextInt(100), System.currentTimeMillis());
//上報事件。
//已定義testEvent事件。
requestId = String.valueOf(random.nextInt(1000));
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("testEventParam", 123);
//上報事件時,不攜帶時間戳。
tslUplinkHandler.fireEvent(originalIdentity, "testEvent", ThingEventTypes.INFO, params);
//上報事件時,攜帶時間戳
//tslUplinkHandler.fireEvent(originalIdentity, "testEvent", ThingEventTypes.INFO, params, System.currentTimeMillis());
//上報設備標簽。
//已定義設備標簽key為testDeviceTag。
requestId = String.valueOf(random.nextInt(1000));
tslUplinkHandler.updateDeviceTag(requestId, originalIdentity, "testDeviceTag", String.valueOf(random.nextInt(1000)));
以上示例中參數說明如下。
參數 | 說明 |
requestId | 請求消息ID。 |
originalIdentity | 設備的原始身份標識符。 |
testProp | 屬性的identifier。本示例的產品已定義功能屬性標識符為testProp。本示例上報了該屬性的值。 |
random.nextInt(100) | 上報的屬性值。定義屬性時,可設置其取值范圍。在本示例中,使用 |
testEvent | 事件的identifier。本示例的產品已定義功能事件標識符為testEvent。本示例上報了該事件。 |
ThingEventTypes.INFO | 事件類型。ThingEventTypes表示事件類型,INFO表示事件類型值為INFO(信息)。 本示例產品定義事件testEvent時,選擇的事件類型為信息(INFO)。 如果事件類型定義為故障,則該參數為 |
params | 事件的輸出參數。事件輸出參數的identifier、數據類型、取值范圍等已在定義事件時定義。本示例中,上報事件的出參identifier是testEventParam,參數值是123。 |
testDeviceTag | 設備標簽鍵(key),String類型。本示例中為testDeviceTag。 實際使用時,請根據設備標簽鍵規范和您的需求設置。更多信息,請參見設備標簽。 |
String.valueOf(random.nextInt(1000)) | 設備標簽值(value),String類型。本示例中,用 |
System.currentTimeMillis() | 獲取當前系統時間的毫秒數。 |
調用設備屬性、事件批量上報接口
云云對接SDK封裝了數據批量上報接口,通過BatchPostEventPropertyMessage 對象實例,鏈式調用addProperty和addEvent方法,分別添加屬性和事件數據后,再通過TslUplinkHandler調用對象實例BatchPostEventPropertyMessage ,實現設備數據批量上報。
調用示例:
TslUplinkHandler tslUplinkHandler = new TslUplinkHandler();
//批量上報屬性和事件
String requestId = String.valueOf(random.nextInt(1000));
long startTime = System.currentTimeMillis() - 3000;
//構造批量上報的報文
BatchPostEventPropertyMessage batchPostEventPropertyMessage = new BatchPostEventPropertyMessage();
Map<String, Object> aiEventParams = new HashMap<>();
aiEventParams.put("EventContent", "hello world");
batchPostEventPropertyMessage
.addProperty("PowerConsumption", 1000, startTime)
.addProperty("PowerConsumption", 123, startTime + 1000)
.addProperty("LightAdjustLevel", 23, startTime)
.addProperty("LightAdjustLevel", 44, startTime + 1000)
.addProperty("LightAdjustLevel", 47, startTime + 2000)
.addEvent("AIEvent", aiEventParams, startTime);
batchPostEventPropertyMessage.setId(requestId);
//發起上報
tslUplinkHandler.batchPostEventPropertyMessage(originalIdentity, batchPostEventPropertyMessage);
以上示例中參數說明如下。
參數 | 說明 |
requestId | 請求消息ID。 |
startTime | 屬性和事件上報時間戳。類型為UTC毫秒級時間。可根據實際業務自定義。 |
aiEventParams | 上報事件的具體信息。 |
PowerConsumption | 屬性的identifier。本示例的產品已定義功能屬性標識符為PowerConsumption、LightAdjustLevel。本示例上報了兩屬性不同時間點的值。 |
LightAdjustLevel | |
AIEvent | 事件的identifier。本示例的產品已定義功能事件標識符為AIEvent。本示例上報了該事件。 |
originalIdentity | 設備的原始身份標識符。 |
調用屬性設置、服務調用接口
云云對接SDK中封裝了屬性設置接口PropertySetHandler和服務調用接口ServiceInvokeHandler。設備端可通過以上接口接收物聯網平臺下發的指令,實現數據更新。
調用示例:
BridgeBootstrap bridgeBootstrap = new BridgeBootstrap();
//屬性設置
bridgeBootstrap.setPropertySetHandler(new PropertySetHandler() {
@Override
public void onPropertySet(PropertySetMessage msg) {
log.info("on property set, {}", msg.getParams());
//如果調用replySuccess,則SDK會向物聯網平臺發送/property/set_reply消息,code為200
msg.replySuccess();
//如果調用replyFail,則SDK會向物聯網平臺發送/property/set_reply消息,code為調用方指定的code
//msg.replyFail(400);
}
});
//服務調用
bridgeBootstrap.setServiceInvokeHandler(new ServiceInvokeHandler() {
@Override
public void onServiceInvoke(ServiceInvokeMessage message) {
log.info("on service invoke, {}", message.getParams());
//如果調用replySuccess,則SDK會向物聯網平臺發送/service/{service.identifier}_reply消息,code為200
message.replySuccess();
//如果調用replyFail,則SDK會向物聯網平臺發送/service/{service.identifier}_reply消息,code為調用方指定的code
//msg.replyFail(400);
}
});