如果当前产品不具备物模型的能力,可以通过设备影子将当前设备的最新状态缓存到云端。云端缓存的是一个最新的JSON格式数据,需要用户自己根据实际情况做解析。物模型具备更高级的设备影子能力,能根据各个属性、事件、服务做独立展示,并具有所有操作的历史记录。
数据上行
说明 设备影子相关接口参见设备 IDeviceShadow。
- 获取云端设备影子
- 更新云端设备影子
- 删除云端设备影子
private int version = 1;
// 更新设备影子,需要根据获得到的设备影子读取返回的 version值,在更新的时候 {ver} 替换为version+1
private String shadowUpdate = "{" + "\"method\": \"update\"," + "\"state\": {" + "\"reported\": {" +
"\"color\": \"red\"" + ",\"mode\": \"1\"" + "}" + "}," + "\"version\": {ver}" + "}";
// 获取设备影子
private String shadowGet = "{" + "\"method\": \"get\"" + "}";
//删除设备影子 color 属性 {ver}需要替换
private String shadowDelete = "{" + "\"method\": \"delete\"," + "\"state\": {" + "\"reported\": {" +
"\"color\": \"null\"" + "}" + "}," + "\"version\": {ver}" + "}";
/**
* 设备影子更新
*/
public void shadowUpdate() {
ALog.d(TAG, "shadowUpdate");
version++;
shadowUpstream(shadowUpdate.replace("{ver}", String.valueOf(version)));
}
/**
* 获取设备影子
*/
public void shadowGet() {
ALog.d(TAG, "shadowGet");
shadowUpstream(shadowGet);
}
/**
* 删除设备影子
*/
public void shadowDelete() {
ALog.d(TAG, "shadowDelete");
version++;
shadowUpstream(shadowDelete.replace("{ver}", String.valueOf(version)));
}
private void shadowUpstream(String requestData) {
if (requestData == null) {
ALog.e(TAG, "shadowUpstream error requestData=null.");
return;
}
LinkKit.getInstance().getDeviceShadow().shadowUpload(requestData, new IConnectSendListener() {
@Override
public void onResponse(ARequest aRequest, AResponse aResponse) {
ALog.d(TAG, "onResponse() called with: aRequest = [" + aRequest + "], aResponse = [" + (aResponse == null ? null : aResponse.data) + "]");
try {
if (aRequest instanceof MqttPublishRequest && aResponse != null) {
String dataStr = null;
if (aResponse.data instanceof byte[]) {
dataStr = new String((byte[]) aResponse.data, "UTF-8");
} else if (aResponse.data instanceof String) {
dataStr = (String) aResponse.data;
} else {
dataStr = String.valueOf(aResponse.data);
}
ALog.d(TAG, "dataStr = " + dataStr);
// {"method":"reply","payload":{"status":"success","state":{"reported":{}},"metadata":{"reported":{}}},"timestamp":1547641855,"version":7,"clientToken":"null"}
ShadowResponse<String> response = JSONObject.parseObject(dataStr, new TypeReference<ShadowResponse<String>>() {
}.getType());
if (response != null && response.version != null) {
version = Integer.valueOf(response.version);
}
}
} catch (NumberFormatException e) {
e.printStackTrace();
ALog.e(TAG, "update version failed.");
} catch (Exception e) {
ALog.e(TAG, "update response parse exception.");
}
}
@Override
public void onFailure(ARequest aRequest, AError aError) {
ALog.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
}
});
}
数据下行
监听云端设备影子数据更新,通过云端API下发设备影子更新数据到设备端,设备端收到云端下行的设备影子数据后,根据desired
的值去执行设备更新。
/**
* 先订阅设备影子的更新 topic
* 云端下发设备影子数据之后
*/
public void listenDownStream() {
ThreadPool.execute(new Runnable() {
@Override
public void run() {
LinkKit.getInstance().getDeviceShadow().setShadowChangeListener(new IShadowRRPC() {
@Override
public void onSubscribeSuccess(ARequest aRequest) {
ALog.d(TAG, "设备影子下行订阅成功");
ALog.d(TAG, "onSubscribeSuccess() called with: aRequest = [" + aRequest + "]");
}
@Override
public void onSubscribeFailed(ARequest aRequest, AError aError) {
ALog.d(TAG, "设备影子下行订阅失败");
ALog.d(TAG, "onSubscribeFailed() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
}
@Override
public void onReceived(ARequest aRequest, AResponse aResponse, IConnectRrpcHandle iConnectRrpcHandle) {
ALog.d(TAG, "onReceived() called with: aRequest = [" + aRequest + "], iConnectRrpcHandle = [" + iConnectRrpcHandle + "]");
// TODO user logic
ALog.d(TAG, "收到设备影子下行指令");
try {
if (aRequest != null) {
String dataStr = null;
if (aResponse.data instanceof byte[]) {
dataStr = new String((byte[]) aResponse.data, "UTF-8");
} else if (aResponse.data instanceof String) {
dataStr = (String) aResponse.data;
} else {
dataStr = String.valueOf(aResponse.data);
}
ALog.d(TAG, "dataStr = " + dataStr);
// 返回数据示例
//{"method":"control","payload":{"state":{"desired":{"mode":2,"color":"white"},"reported":{"mode":"1","color":"red"}},"metadata":{"desired":{"mode":{"timestamp":1547642408},"color":{"timestamp":1547642408}},"reported":{"mode":{"timestamp":1547642408},"color":{"timestamp":1547642408}}}},"timestamp":1547642408,"version":12}
// 仅供参考
ShadowResponse<String> shadowResponse = JSONObject.parseObject(dataStr, new TypeReference<ShadowResponse<String>>() {
}.getType());
if (shadowResponse != null && shadowResponse.version != null) {
version = Integer.valueOf(shadowResponse.version);
}
AResponse response = new AResponse();
// TODO 用户实现控制设备
// 用户控制设备之后,上报影子的值到云端
// 上报设置之后的值到云端
// 根据当前实际值上报
response.data = shadowUpdate.replace("{ver}", String.valueOf(++version));
// 第一个值 replyTopic 有默认值,您不需要设置
iConnectRrpcHandle.onRrpcResponse(null, response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onResponseSuccess(ARequest aRequest) {
ALog.d(TAG, "onResponseSuccess() called with: aRequest = [" + aRequest + "]");
}
@Override
public void onResponseFailed(ARequest aRequest, AError aError) {
ALog.w(TAG, "onResponseFailed() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
}
});
}
});
}
文档内容是否对您有帮助?