全部产品
云市场

设备影子

更新时间:2019-02-21 20:14:59

如果当前产品不具备物模型的能力,可以通过设备影子将当前设备的最新状态缓存到云端。云端缓存的是一个最新的 JSON 格式数据,需要用户自己根据实际情况做解析。物模型具备更高级的设备影子能力,能根据各个属性、事件、服务做独立展示,并具有所有操作的历史记录。

说明 设备影子相关接口参见设备 IDeviceShadow

数据上行

  • 获取云端设备影子
  • 更新云端设备影子
  • 删除云端设备影子
  1. // 更新设备影子 需要根据获得到的设备影子读取返回的 version值,在更新的时候 {ver} 替换为version+1
  2. String shadowUpdate = "{" + "\"method\": \"update\"," + "\"state\": {" + "\"reported\": {" +
  3. "\"color\": \"red\"" + ",\"mode\": \"1\"" + "}" + "}," + "\"version\": {ver}" + "}";
  4. // 获取设备影子
  5. String shadowGet = "{" + "\"method\": \"get\"" + "}";
  6. //删除设备影子 color 属性 {ver}需要替换
  7. String shadowDelete = "{" + "\"method\": \"delete\"," + "\"state\": {" + "\"reported\": {" +
  8. "\"color\": \"null\"" + "}" + "}," + "\"version\": {ver}" + "}";
  9. //删除设备影子所有属性 {ver}需要替换
  10. String shadowDeleteAll = "{" + "\"method\": \"delete\"," + "\"state\": {" +
  11. "\"reported\":\"null\"" + "}," + "\"version\": {ver}" + "}";
  12. String requestData = shadowUpdate.replace("{ver}";// shadowGet;shadowDelete.replace("{ver}"
  13. LinkKit.getInstance().getDeviceShadow().shadowUpload(requestData, new IConnectSendListener() {
  14. @Override
  15. public void onResponse(ARequest aRequest, AResponse aResponse) {
  16. try {
  17. if (aRequest instanceof MqttPublishRequest && aResponse != null) {
  18. String dataStr = null;
  19. if (aResponse.data instanceof byte[]) {
  20. dataStr = new String((byte[]) aResponse.data, "UTF-8");
  21. } else if (aResponse.data instanceof String) {
  22. dataStr = (String) aResponse.data;
  23. } else {
  24. dataStr = String.valueOf(aResponse.data);
  25. }
  26. // 返回数据示例
  27. // {"method":"reply","payload":{"status":"success","state":{"reported":{}},"metadata":{"reported":{}}},"timestamp":1547641855,"version":7,"clientToken":"null"}
  28. ShadowResponse<String> response = JSONObject.parseObject(dataStr, new TypeReference<ShadowResponse<String>>() {
  29. }.getType());
  30. if (response != null && response.version != null) {
  31. version = Integer.valueOf(response.version);
  32. }
  33. }
  34. } catch (NumberFormatException e) {
  35. e.printStackTrace();
  36. //ALog.e(TAG, "update version failed.");
  37. } catch (Exception e) {
  38. //ALog.e(TAG, "update response parse exception.");
  39. }
  40. }
  41. @Override
  42. public void onFailure(ARequest aRequest, AError aError) {
  43. //ALog.d(TAG, "onFailure() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
  44. }
  45. });

数据下行

  1. // 监听云端设备影子更新
  2. LinkKit.getInstance().getDeviceShadow().setShadowChangeListener(new IShadowRRPC() {
  3. @Override
  4. public void onSubscribeSuccess(ARequest aRequest) {
  5. // ALog.d(TAG, "设备影子下行订阅成功");
  6. // ALog.d(TAG, "onSubscribeSuccess() called with: aRequest = [" + aRequest + "]");
  7. }
  8. @Override
  9. public void onSubscribeFailed(ARequest aRequest, AError aError) {
  10. // ALog.d(TAG, "设备影子下行订阅失败");
  11. // ALog.d(TAG, "onSubscribeFailed() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
  12. }
  13. @Override
  14. public void onReceived(ARequest aRequest, AResponse aResponse, IConnectRrpcHandle iConnectRrpcHandle) {
  15. // ALog.d(TAG, "onReceived() called with: aRequest = [" + aRequest + "], iConnectRrpcHandle = [" + iConnectRrpcHandle + "]");
  16. // TODO user logic
  17. // ALog.d(TAG, "收到设备影子下行指令");
  18. try {
  19. if (aRequest != null) {
  20. String dataStr = null;
  21. if (aResponse.data instanceof byte[]) {
  22. dataStr = new String((byte[]) aResponse.data, "UTF-8");
  23. } else if (aResponse.data instanceof String) {
  24. dataStr = (String) aResponse.data;
  25. } else {
  26. dataStr = String.valueOf(aResponse.data);
  27. }
  28. ALog.d(TAG, "dataStr = " + dataStr);
  29. // 返回数据示例
  30. // {"method":"reply","payload":{"status":"success","state":{"reported":{}},"metadata":{"reported":{}}},"timestamp":1547641855,"version":7,"clientToken":"null"}
  31. ShadowResponse<String> shadowResponse = JSONObject.parseObject(dataStr, new TypeReference<ShadowResponse<String>>() {
  32. }.getType());
  33. if (shadowResponse != null && shadowResponse.version != null) {
  34. version = Integer.valueOf(shadowResponse.version);
  35. }
  36. AResponse response = new AResponse();
  37. // TODO 用户实现控制设备
  38. // 用户控制设备之后 上报影子的值到云端
  39. // 上报设置之后的值到云端
  40. // 根据当前实际值上报
  41. response.data = shadowUpdate.replace("{ver}", String.valueOf(++version));
  42. // 第一个值 replyTopic 有默认值 用户不需要设置
  43. iConnectRrpcHandle.onRrpcResponse(null, response);
  44. }
  45. } catch (Exception e) {
  46. e.printStackTrace();
  47. }
  48. }
  49. @Override
  50. public void onResponseSuccess(ARequest aRequest) {
  51. ALog.d(TAG, "onResponseSuccess() called with: aRequest = [" + aRequest + "]");
  52. }
  53. @Override
  54. public void onResponseFailed(ARequest aRequest, AError aError) {
  55. ALog.w(TAG, "onResponseFailed() called with: aRequest = [" + aRequest + "], aError = [" + aError + "]");
  56. }
  57. });