阿里云IoT 提供一型一密和一机一密的连接阿里云物联网平台方式,所以合作客户如果要使用升级服务或其他云服务,需要适配一定的hal层接口即可使用。
本文将介绍一型一密(含预注册和非预注册)和一机一密的厂商hal层适配流程。

1. 连云方式选择

首先需要选择是通过一型一密还是一机一密的连云方式,通过cfg.json文件进行配置,cfg.json文件位于MINIAPP_RESROOT resources目录下。在cfg.json中配置”one_device_one_secret”: false表示使用一机一密,配置”one_type_one_secret_pre_registration”: true表示使用一型一密预注册的方式,即需要将设备的device_name列表先上传至HaaS Studio平台,配置”one_type_one_secret_no_pre_registration”: true表示使用一型一密非预注册的方式,即不需要将设备的device_name列表先上传至HaaS Studio平台。
一机一密:
“linksdk”: { “one_device_one_secret”: true }
一型一密预注册:
“linksdk”: { “one_type_one_secret_pre_registration”: true }
一型一密非预注册:
“linksdk”: { “one_type_one_secret_no_pre_registration”: true }

2. 企业实例

企业独享实例开通后,需要实现以下接口,来获取实例ID:

/
readInstanceId
MAXLEN:64
return value: 0:success fail:-1
**/
int readInstanceId(char
instanceId);

企业实例ID可以在HaaS控制台设备管理-产品模块查看,如果显示是公共实例,不需要传企业实例ID。
image.png

3. 一型一密厂商实现部分

一型一密需要用户在HaaS Studio中,将对应产品的动态注册开关打开:
image.png

3.1 预注册方式

一型一密预注册方式需要用户将设备的device_name信息提前上传到HaaS Studio上去,只有上传了device_name信息的设备,才能将设备激活并连至接阿里云物联网平台。
如果使用一型一密预注册方式,通过c接口的方式注入设备三元组信息,需要实现的接口如下:

/
readProductKey
MAXLEN:64
return value: 0:success fail:-1
**/
int readProductKey(char
productKey);
/
readProductSecret
MAXLEN:64
**/
int readProductSecret(char
productSecret);
/
readDeviceName
MAXLEN:64
return value: 0:success fail:-1
**/
int readDeviceName(char
deviceName);
/
readDeviceSecret
MAXLEN:64
return value: 0:success fail:-1
**/
int readDevicetSecret(char
deviceSecret);
/
writeDeviceSecret
MAXLEN:64
return value: 0:success fail:-1
**/
int writeDevicetSecret(const char
deviceSecret);
/
read & print all info
*
/
int readProductAndDeviceInfo();

将包含这些接口的c文件打包成libgetdevicename.so,放在”MINIAPP_RESROOT messageknife”路径下即可。注:如果是cpp文件,每个接口的前面需要加上extern “C”。

3.2 非预注册方式

一型一密非预注册方式不需要用户将设备的device_name信息提前上传到HaaS Studio上去,即可将设备激活并连接至阿里云物联网平台。
如果使用一型一密非预注册方式,通过c接口的方式注入设备三元组信息,需要实现的接口如下:

/
readProductKey
MAXLEN:64
return value: 0:success fail:-1
**/
int readProductKey(char
productKey);
/
readProductSecret
MAXLEN:64
**/
int readProductSecret(char
productSecret);
/
readDeviceName
MAXLEN:64
return value: 0:success fail:-1
**/
int readDeviceName(char
deviceName);
/
writeDeviceToken
MAXLEN:64
return value: 0:success fail:-1
**/
int writeDevicetToken(const char
deviceToken);
/
writeClientId
MAXLEN:128
return value: 0:success fail:-1
**/
int writeClientId(const char
clientId);
/
writeUserName
MAXLEN:64
return value: 0:success fail:-1
**/
int writeUserName(const char
userName);
/
readDeviceToken
MAXLEN:64
return value: 0:success fail:-1
**/
int readDevicetToken(char
deviceToken);
/
readClientId
MAXLEN:128
return value: 0:success fail:-1
**/
int readClientId(char
clientId);
/
readUserName
MAXLEN:64
return value: 0:success fail:-1
**/
int readUserName(char
userName);
/
read & print all info
*
/
int readProductAndDeviceInfo();
  1. 将包含这些接口的c文件打包成libgetdevicename.so,放在"MINIAPP_RESROOT messageknife"路径下即可。注:如果是cpp文件,每个接口的前面需要加上extern "C"

4. 一机一密厂商实现部分

一机一密可以通过c接口或js接口将设备三元组信息注入到LinkSDK模块。

4.1 c接口注入三元组信息

如果使用一机一密,通过c接口的方式注入设备三元组信息,需要实现的接口如下:

/
readProductKey
MAXLEN:64
return value: 0:success fail:-1
**/
int readProductKey(char
productKey);
/
readDeviceName
MAXLEN:64
return value: 0:success fail:-1
**/
int readDeviceName(char
deviceName);
/
readDeviceSecret
MAXLEN:64
return value: 0:success fail:-1
**/
int readDeviceSecret(char
deviceSecret);

将包含这些接口的c文件打包成libgetdeviceinfo.so,放在”MINIAPP_RESROOT messageknife”路径下即可。注:如果是cpp文件,每个接口的前面需要加上extern “C”。

4.2 js接口注入三元组信息

如果使用一机一密,通过js接口的方式注入设备三元组信息,将如下代码拷贝到js代码中即可,并实现其中的getDeviceInfo()函数,用于获取设备三元组信息,并将获取到的三元组信息传参给registerDeviceInfo()函数:

mounted() {
    (async ()=>{
      if(await this.getDeviceInfo() === false) { // 首先需要判断设备本地有无三元组信息,如果没有,则去服务器获取三元组,然后注册到设备上
        // TODO: 此处需要用户自行去获取设备三元组信息,并将获取到的三元组信息传参给registerDeviceInfo()函数
        let deviceInfo = this.getDeviceInfo(); // 需要用户自行实现
        if(await this.registerDeviceInfo(deviceInfo.product_key, deviceInfo.device_name, deviceInfo.device_secret) === true) { // product_key, device_name, device_secret需要传参进去
          this.device = iot.device(); // 连接阿里云物联网平台
          this.initMqttListener(); // 监听物联网平台消息
        }
      } else {
        this.device = iot.device(); // 连接阿里云物联网平台
        this.initMqttListener(); // 监听物联网平台消息
      }
    })()
  },
  methods: {
    async registerDeviceInfo(product_key, device_name, device_secret, region) { // 注册三元组到设备上
      const storage = $falcon.jsapi.storage;
      let result_set_product_key = await storage.setGlobalStorage({
        key: 'product_key',               // key
        data: product_key,                // value
      });
      let result_set_device_name = await storage.setGlobalStorage({
        key: 'device_name',               // key
        data: device_name,                // value
      });
      let result_set_device_secret = await storage.setGlobalStorage({
        key: 'device_secret',             // key
        data: device_secret,              // value
      });
      let result_set_device_region = await storage.setGlobalStorage({
        key: 'region',             // key
        data: region,              // value
      });
      if (result_set_product_key && !result_set_product_key.error
          && result_set_device_name && !result_set_device_name.error
          && result_set_device_secret && !result_set_device_secret.error
          && result_set_device_region && !result_set_device_region.error)
      {
        console.log('deviveInfo set succeeded!');
        return true;
      } else {
        console.log('deviveInfo set failed!');
        return false;
      }
    },
    async getDeviceInfo() { // 读取设备上的三元组
      const storage = $falcon.jsapi.storage;
      let result_get_product_key = await storage.getGlobalStorage({key: 'product_key'});
      let result_get_device_name = await storage.getGlobalStorage({key: 'device_name'});
      let result_get_device_secret = await storage.getGlobalStorage({key: 'device_secret'});
      if (result_get_product_key && !result_get_product_key.error
          && result_get_device_name && !result_get_device_name.error
          && result_get_device_secret && !result_get_device_secret.error)
      {
        if (result_get_product_key.product_key.length === 0 || result_get_device_name.device_name.length === 0 || result_get_device_secret.device_secret.length === 0) {
          console.log('deviveInfo is not complete!');
          return false;
        }
        console.log('product_key', result_get_product_key.product_key);
        console.log('device_name', result_get_device_name.device_name);
        console.log('device_secret', result_get_device_secret.device_secret);
        console.log('deviveInfo get succeeded!');
        return true;
      } else {
        console.log('deviveInfo has not registered!');
        return false;
      }
    },
    initMqttListener() {
      /* 服务下发事件 */
      this.device.on("service", (id, payload) => {
        console.log("id ", id);
        console.log("payload ", payload);
        this.list.push({
          type: "service",
          id: id,
          payload: JSON.stringify(payload),
        });
      });

      /* 属性下发事件 */
      this.device.on("props", (payload) => {
        console.log("props payload ", payload);
        this.list.push({ type: "property", payload: JSON.stringify(payload) });
        this.LightSwitch = payload.LightSwitch;
      });

      /* 网络连接事件 */
      this.device.on("connect", function () {
        console.log("(re)connected");
      });

      /* 网络断开事件 */
      this.device.on("disconnect", function () {
        console.log("disconnect ");
      });
    },
    getDeviceInfo(product_key, device_name, device_secret) {
      // TODO: 实现获取设备三元组信息的逻辑
      ...
      return {
          "product_key": "xxxxxx",
        "device_name": "xxxxxx",
        "device_secret": "xxxxxx"
      }
    }
  },