H5控制设备以及数据回显方案设计(物联网)

前言

        我们都知道,我们当前开发的模式是使用Hybird App即原生+H5开发模式。H5在开发相关得设备页面的时候,关于对设备的控制数据的流向,往往只需要关注上述图中原生IOS | Android 实时监控数据,然后根据指定的协议向H5转发的过程,最后H5在设计相关的程序实现数据更新与否的一个回显问题。

        上述数据的流向有时并不是顺通无阻的,可能会因为网络问题,设备恢复延时又或者某一端的程序有问题导致数据不能正常按上述流程走。客户端作为用户体验最密切的一端,即不管是原生还是H5都需要对这个异常情况进行处理。

       于是,在H5端需要关注的数据流向部分简化为如下图

着重根据这部分设计控制设备已经设备数据更新页面回显的方案

设计思路

        根据以上流程,原生IOS | Androidu作为一个数据传送关键部分,与MQTT建立长连接,与H5指定协议,根据协议向H5转发MQTT数据。因此H5处理控制设备或者更新回显设备数据主要也是跟原生端制定协议完成。主要流程描述如下:

1.制定获取设备初始状态、控制设备、获取设备更新数据的协议;

2.H5进入页面时,获取设备上报的初始化或者设备更新后的数据;

3.用户通过APP控制设备,H5端调用原生端下发设备的协议,原生端向后台转发;

4.设备更新,上报最新状态,设备中心将最新数据转发至MQTT,原生端实时监控,进而将数据以协议方式转发至H5;

5.H5拿到最新的数据以更新页面;

6.不同设备以deviceId进行区分,功能点以funcId进行区分;

注意点:这里需要注意的是上述提到的异常情况如:网络问题,设备恢复延时又或者某一端的程序有问题导致H5端拿不到设备最新返回的数据。这个问题一方面需要各端进行优化的同时,H5也需要进行数据回显层面的优化:

1.H5端下发控制设备指令之后,若1s内就收到了回复,不会出现loading,且视此次下发控制设备的指令为成功;

2.1s后没收到请求详情成功的状态,页面则显示loading,防止用户频繁点击。同时在3s后后台接口普还是没有返回的状态下,则将此次指令视为下发失败,关闭loading,页面也将恢复为上次操作成功的值;

注意:这里的回复指的是后台接口的成功的响应,这里这个接口指的是下发设备的接口,主要流程图如下:

 实现

请求协议

获取设备初始状态、控制设备

方法名:requestFunction

功能:H5提供调用参数所需信息,传到原生端后,由原生端请求后台接口

优点:configTopBarWithParams

  1. 由原生端统一配置请求头、token相关参数,不用重复传递接口校验信息
  2. 后续后台接口需要调整时,H5一方进行调整即可

H5示例:

let query = {
    method: 1, // 1:get 2:postjson 3:postform 4put 5delete 6postMultipart
    url: '/smarthome/api/devicequery/deviceattr', // 后台接口相对路径
    params: {}, // 参数
    callBackMethodName:"xxxxxx", // 回调方法的方法名,例:异步=“async.xxxx” 同步=“sync.xxxx”, 接口200,回调该方法
    errorCallBackName:"xxxxxx" // 回调方法的方法名,接口不通,回调该方法
}
dsBridge.call("requestFunction", query);

实现描述:原生端根据参数中“callBackMethodName”、“errorCallBackName”的名称,动态赋值回调方法的名称

功能请求url成功回调失败回调异步
获取设备状态/smarthome/api/devicequery/deviceattrqueryDeviceInfoCallBackerrorCallBackName
更新设备状态/smarthome/api/device/command/controlhttpCallBackerrorCallBackName

使用

获取设备当前状态

调用协议,发送请求以获取设备状态

    // 获取设备状态
    getLightInfo () {
      this.commonObj.funcIds = '75',//一个功能点一个funcIds
      this.$dsBridgeSend.requestFunction(7, this.commonObj)
    },

在queryDeviceInfoCallBack回调方法中对设备上报的数据进行处理,从而进行页面显示

      queryDeviceInfoCallBack: function (response) {
        if (_this.$dsBridgeSend.handleError(response)) {
          const res = JSON.parse(response).result
          // 初始化获取状态后 - 解析状态值
          _this.setStatus(res.status)
          // 导航栏配置
          _this.$dsBridgeSend.pageBarSetting(res.deviceName)
        }
      },

下发控制指令,以通知设备更新状态

    // 来电、信息、通知
    updNoticeRingtone(data) {
      if (this.notice_ringtone_value == data) return false
      this.notice_ringtone_value = data
      let oldChangeId = this.changeIdList[2].changeId;
      let setObj = this.$common.setControlObj(this.commonObj.deviceId, 75, Number(this.notice_ringtone_value))
      setObj.signCode = 'message_ringtone'
      this.$dsBridgeSend.requestFunction(10, setObj)
      this.currentControl = 'message_ringtone';
      ......
      // 下面处理1s内没有成功响应的情况和处理数据恢复为上次成功设置的状态
    }

判断请求状态以及数据回显

        由于一个设备可以拥有多功能属性即多个funcIds,但是用户控制的每个功能点都是一次性的,即一次只能控制一个功能(这里暂不说明联动动能属性),下发设备控制指令也是一对一的。这时便可以设计一个数组,将当前设备所有可能设计的功能点保存起来,且给其分配相关的操作次数的属性,这个属性是判断当前操作有没有成功拿到响应的依据,具体设计如下:

      changeIdList: [
        { type: 'rgb', changeId: 0 },
        { type: 'current_mode', changeId: 0 }, // 开关
        { type: 'indicator_light', changeId: 0 }, // 指示灯开关
        { type: 'luminance_detection', changeId: 0 }, // 靠近感应开关
        .....
     ]

        当控制命令下发之后,1s内后台成功响应,则会进到httpCallBack回调中,在这方法中,可以更新设备状态页面的显示,同时对标识changeId进行自增1的操作,以表示当前控制已经结束。

      httpCallBack: function (response) {
        console.log('httpCallBack')
        const res = JSON.parse(response)
        const signCode = res.result
        console.log(response)
        // 发送指令后 - 获取返回值
        _this.changeIdList.map((i) => {
          i.changeId++
        }
        // 得到回复 结束等待框
        _this.$loading.hide()
        ...
      }

        每次进行新的一轮控制的时候,都将当前的changeId标识设置为旧标识oldChangeId,然后当没有收到httpCallBack成功的响应的时候,changeId标识大小就不会更新,则此时oldChangeId === this.changeIdList[n].changeId,表示当前控制失败,反之则表示成功。执行相应的更新或者回显操作。

    // 来电、信息、通知
    updNoticeRingtone(data) {
      ...
      let oldChangeId = this.changeIdList[2].changeId;
      let setObj = this.$common.setControlObj(this.commonObj.deviceId, 75, data)
      setObj.signCode = 'message_ringtone'
      this.$dsBridgeSend.requestFunction(10, setObj)
      this.currentControl = 'message_ringtone';
      ......
      // 下面处理1s内没有成功响应的情况和处理数据恢复为上次成功设置的状态
      setTimeout(() => {
        if (oldChangeId === this.changeIdList[2].changeId) {
          this.$loading.show()
        }
      }
      setTimeout(() => {
        this.$loading.hide()
        if (oldChangeId === this.changeIdList[2].changeId) {
          this.selectLightValue = this.selectLightValueSave
          this.changeIdList[2].changeId++
      }, 3000)
  },

同时,当1s内后台没有返回接口结果时,页面将显示loading,防止用户频繁点击。这时,继续等待3s,若3s内接口返回结果,同理进到httpCallBack的回调函数中,进行页面数据跟新一系列的操作。反之,3s内接口依然没有返回结果,则视这次控制指令为彻底失败,页面将关闭loading,并恢复上次成功控制的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值