Matter 设备

更新时间:2024-03-04 08:45:15下载pdf

什么是 Matter?

Matter 协议是 CSA 联盟 与 Google、Amazon、Apple 共同推进的物联网标准连接方案,旨在实现所有 IoT 设备的兼容性,实现一套协议控制所有设备。本文介绍 Matter 设备接入后的相关管理和控制功能。

准备工作

在使用 Matter 设备前,您需要完成 开发项目工程配置 以及 实现 Matter 设备配网,详情请参考 Matter 设备配网 系列文档。

完成上述流程后,即可添加 Matter 设备到 App 中进行使用。

判断 Matter 设备

接口说明

DeviceBean.java

boolean isMatter();

代码示例
Java:

DeviceBean deviceBean = ThingHomeSdk.getDataInstance().getDeviceBean(devId);
if(deviceBean != null) {
  boolean isMatter = deviceBean.isMatter();
}

控制 Matter 设备

与普通设备一样,调用 publishDps 进行下发即可。

IThingDevice iThingDevice = ThingHomeSdk.newDeviceInstance(devId);
iThingDevice.publishDps(dps, new IResultCallback() {
  @Override
  public void onError(String code, String error) {

  }

  @Override
  public void onSuccess() {

  }
});

Matter 设备目前支持的通道情况如下:

设备类型 支持通道 备注
涂鸦 Matter 基于 Wi-Fi
  • Matter 局域网通道
  • MQTT 通道
涂鸦局域网通道待后续硬件固件支持
涂鸦 Matter 网关
  • Matter 局域网通道
  • 涂鸦局域网通道
  • MQTT 通道
-
涂鸦 Matter Thread 设备
  • Matter 局域网通道
  • 涂鸦局域网通道
  • MQTT 通道
-
三方 Matter 设备 Matter 局域网通道 -

判断 Matter 在线状态

与其他设备一样,可以使用 DeviceBeanisOnline 字段综合判断设备的在离线状态。

接口说明

DeviceBean.java

boolean getIsOnline();

代码示例
Java:

DeviceBean deviceBean = ThingHomeSdk.getDataInstance().getDeviceBean(devId);
if(deviceBean != null) {
  boolean isMatter = deviceBean.getIsOnline();
}

跨 Fabric

跨 Fabric(Multiple Fabrics) 是 Matter 设备的特色功能,让设备基于 Matter 支持跨不同厂商生态使用的特性,可以同时在多个支持 Matter 生态的 App 上激活使用。您的 Matter 设备不仅可以在涂鸦相关的 App(例如 智能生活)中使用,同时也可以在苹果 Home、谷歌 Home、亚马逊 Alexa 等等中使用。

Fabric 是 Matter 定义的同一安全域下节点(即设备)的集合,在该安全域下节点能够彼此认证,建立安全通信。一个 Fabric 共享同一证书机构(Certificate Authority,CA)的根证书(Root of Trust),同时约定一个唯一 64 位标识符的 Fabric ID。

跨 Fabric 包含 Fabrics 分享Fabrics 管理 两个模块。

通道可用性检查

在使用 Fabrics 分享Fabrics 管理 API 之前,可以使用本方法来判断 App 是否可以和设备进行通讯。

  • 从 HomeKit SDK 5.2.0 开始,SDK 支持了多种通道进行 Fabrics 分享Fabrics 管理,提供了新的前置通道可用性检查方式。
  • 多通道通讯方式需要设备侧对应的固件支持,新接口内部同样兼容之前的设备,推荐配套迁移到新的方式使用。

SDK 5.2.0 及以上版本的通道可用性检查

接口说明

boolean checkPipelineAvailable();

代码示例

Java:

IThingMatterMultipleFabricDevice mThingMatterFabricDevice; 
...
private void preCheck(String devId){
   mThingMatterFabricDevice = ThingHomeSdk.newMatterMultipleFabricDeviceInstance(devId);
   boolean pipelineAvailable = mThingMatterFabricDevice.checkPipelineAvailable();
}

SDK 5.2.0 以下版本的通道可用性检查

接口说明

boolean isMatterOnline();

代码示例

Java:

private void preCheck(String devId){
   mThingMatterFabricDevice = ThingHomeSdk.newMatterMultipleFabricDeviceInstance(devId);
   boolean isMatterOnline = mThingMatterFabricDevice.isMatterOnline();
}

Fabrics 分享

业务流程

涂鸦相关 AppMatter 设备云端其他 App生成 Multiple Fabric 分享配网码流程通道可用性检查读取最大支持 Fabric 数量返回支持数量 maxNum,如:5读取当前已使用 Fabric 数量返回已使用数量 usedNum,如:2提示分享已达最大数量获取设备连接 SSID名称(可选)仅 Matter 基于 Wi-Fi支持返回 SSID 名称展示 设备连接 SSID关闭分享配网窗口关闭窗口结果提示无法进行分享获取 passcodeModel 数据返回 passcodeModel 模型打开分享配网窗口处理打开配网窗口打开分享配网窗口结果展示 分享二维码手动配网码alt[关闭窗口失败][关闭窗口成功]alt[maxNum - usedNum <= 0][maxNum - usedNum > 0]Multiple Fabric 分享配网流程确认与设备在同一个局-域网中扫描分享二维码或输入-手动配网码进行 Matter 分享配网配网结束使用设备涂鸦相关 AppMatter 设备云端其他 AppFabrics 分享流程

从 HomeKit SDK 5.2.0 开始,大幅简化了生成 Multiple Fabric 分享配网码的 API 使用方式,并且支持了多种通道通讯方式以提高成功率。

SDK 5.2.0 及以上版本的 Fabric 分享

在使用 API 前,建议配合 SDK 5.2.0 及以上版本的通道可用性检查 使用。

打开分享配网窗口

内部包含了 读取最大支持 Fabric 数量读取当前已使用 Fabric 数量获取设备连接 SSID 名称关闭配网窗口打开分享配网窗口 这一系列流程阶段,无需像 5.2.0 以下版本一样逐步调用,仅需一个接口即可完成上述流程。

接口说明

void sendEnhancedCommissioningCommand(boolean forceRefresh, IThingMultipleFabricCallback callback);

代码示例

Java:

private void openECM() {
mThingMatterMultipleFabricDevice.sendEnhancedCommissioningCommand(true, new IThingMultipleFabricCallback() {
@Override
public void onNetworkInfo(String ssid) {
    Log.d(TAG,"device ssId: "+ssid);
}

@Override
public void onSuccess(IThingMatterMultipleFabricDevice.SetupCodePayload setupCodePayload) {
    Log.d(TAG,"open ecm success: "+setupCodePayload.toString());
}

@Override
public void onError(String errorCode, String errorMessage) {
    Log.d(TAG,"open ecm fail: "+errorCode);
}
});

SDK 5.2.0 以下版本的 Fabric 分享

需按照业务流程图的说明,实现对应流程的 API 调用,在使用 API 前建议配合 SDK 5.2.0 以下版本的通道可用性检查 使用。

读取最大支持 Fabric 数量

通常 Matter 设备根据自身性能的差异,对于最大支持 Fabric 的定义是不同的。

接口说明

void readSupportedFabrics(IThingDataCallback<Integer> callback);

代码示例
Java:

mThingMatterFabricDevice.readSupportedFabrics(new IThingDataCallback<Integer>() {
  @Override
  public void onSuccess(Integer result) {
    Log.i("readSupportedFabrics", " SupportedFabrics:" + result);
  }

  @Override
  public void onError(String errorCode, String errorMessage) {
    Log.e("readSupportedFabrics", "matter share errorCode:" + errorCode + " errorMsg:" + errorMessage);
  }
});

读取当前已使用 Fabric 数量

接口说明

void readCommissionedFabrics(IThingDataCallback<Integer> callback);

代码示例
Java:

mThingMatterFabricDevice.readCommissionedFabrics(new IThingDataCallback<Integer>() {
  @Override
  public void onSuccess(Integer result) {
    Log.i("readCommissionedFabrics", " currentCount:" + result);
  }

  @Override
  public void onError(String errorCode, String errorMessage) {
    Log.e("readCommissionedFabrics", "matter share errorCode:" + errorCode + " errorMsg:" + errorMessage);
  }
});

获取设备连接 SSID 名称

Matter Wi-Fi 设备可以获取到设备当前连接的 SSID 名称,对于 有线网关Thread 设备 无法获取到。

接口说明

void getWifiDeviceSsid(IThingDataCallback<String> callback);

代码示例
Java:

mThingMatterFabricDevice.getWifiDeviceSsid(new IThingDataCallback<String>() {
  @Override
  public void onSuccess(String result) {
    Log.d("getWifiDeviceSsid", "--getWifiName:--=" + result);
  }

  @Override
  public void onError(String errorCode, String errorMessage) {
    Log.e("getWifiDeviceSsid", "--getWifiName--error--=" + errorMessage);
  }
});

打开分享配网窗口

先获取 MultipleFabricPasscode 模型对象。

接口说明

// 获取 MultipleFabricPasscode 对象
void getMultipleFabricPasscode(IThingDataCallback<MultipleFabricPasscode> callback);

// 强制刷新获取 MultipleFabricPasscode 对象
void getMultipleFabricPasscodeForceRefresh(IThingDataCallback<MultipleFabricPasscode> callback);

代码示例
Java:

mThingMatterFabricDevice.getMultipleFabricPasscode(new IThingDataCallback<IThingMatterMultipleFabricDevice.MultipleFabricPasscode>() {
  @Override
  public void onSuccess(IThingMatterMultipleFabricDevice.MultipleFabricPasscode result) {
    if (result == null) {
      return;
    }
    L.d("getMultipleFabricPasscode", "getMultipleFabricPasscode success");
    revokeCommissioningCommand(result);
  }

  @Override
  public void onError(String errorCode, String errorMessage) {
    Log.e("getMultipleFabricPasscode", "matter share errorCode:" + errorCode + " errorMsg:" + errorMessage);
  }
});

mThingMatterFabricDevice.getMultipleFabricPasscodeForceRefresh(new IThingDataCallback<IThingMatterMultipleFabricDevice.MultipleFabricPasscode>() {
  @Override
  public void onSuccess(IThingMatterMultipleFabricDevice.MultipleFabricPasscode result) {
    if (result == null) {
      return;
    }
    Log.d("getMultipleFabricPasscodeForceRefresh", "getMultipleFabricPasscodeForceRefresh success");
  }

  @Override
  public void onError(String errorCode, String errorMessage) {
    Log.e("getMultipleFabricPasscodeForceRefresh", "matter share errorCode:" + errorCode + " errorMsg:" + errorMessage);
  }
});

使用上一步获取到的 passcodeModel 进行打开设备分享配网窗口。

接口说明

void sendEnhancedCommissioningCommand(MultipleFabricPasscode multipleFabricPasscode, IThingDataCallback<SetupCodePayload> callback);

代码示例
Java:

mThingMatterFabricDevice.sendEnhancedCommissioningCommand(multipleFabricPasscode, new IThingDataCallback<IThingMatterMultipleFabricDevice.SetupCodePayload>() {
  @Override
  public void onSuccess(IThingMatterMultipleFabricDevice.SetupCodePayload result) {
    Log.i("sendEnhancedCommissioningCommand", "matter share SetupCodePayload:" + result);
  }

  @Override
  public void onError(String errorCode, String errorMessage) {

    Log.e("sendEnhancedCommissioningCommand", "matter share errorCode:" + errorCode + " errorMsg:" + errorMessage);
  }
});

关闭分享配网窗口

由于分享配网窗口不能在已经打开的状态下再次打开,所以需要先关闭分享配网窗口,再打开配网窗口。

接口说明

void revokeCommissioningCommand(IThingDataCallback<Void> callback);

代码示例
Java:

mThingMatterFabricDevice.revokeCommissioningCommand(new IThingDataCallback<Void>() {
  @Override
  public void onSuccess(Void result) {
    Log.i("revokeCommissioningCommand", "success");
  }

  @Override
  public void onError(String errorCode, String errorMessage) {
    //接口 error

    Log.e("revokeCommissioningCommand", "matter share errorCode:" + errorCode + " errorMsg:" + errorMessage);
  }
});

Fabrics 管理

Matter 支持跨 App 分享使用,可以使用以下 API 来获取当前使用者列表以及移除分享权限。

从 HomeKit SDK 5.2.0 开始,支持多种通道通讯方式以提高成功率,Fabric 管理对外 API 使用方式无变化。

获取 Fabric 列表

接口说明

void readFabrics(IThingDataCallback<List<OperationalFabricInfo>> callback);

数据模型

OperationalFabricInfo 模型字段含义说明:

属性 类型 说明
vendorId Integer 厂商 ID
nodeId Long 配网时,此 Fabric 提供的 nodeId
fabricId Long 配网时,此 Fabric 提供的 fabricId
fabricIndex String 配网时,此 Fabric 的 index
label NSString 配网时,此 Fabric 提供的 label
isCurrent boolean 是否是当前 App

代码示例
Java:

public void readFabrics() {
  if (mThingMatterFabricDevice == null) {
    return;
  }
  mThingMatterFabricDevice.readFabrics(new IThingDataCallback<List<OperationalFabricInfo>>() {
    @Override
    public void onSuccess(List<OperationalFabricInfo> result) {
      if (result != null) {
        Log.d("readFabrics", "ReadFabrics success: Result = " + Arrays.toString(result.toArray()));
      }
    }

    @Override
    public void onError(String errorCode, String errorMessage) {

      Log.e("readFabrics", "ReadFabrics error: ErrorCode = " + errorCode + "; ErrorMessage = " + errorMessage);
    }
  });
}

移除指定的 Fabric

移除的 fabricIndex 不能是当前 App 使用的,可以通过 OperationalFabricInfoisCurrent 字段判断是否是当前 App。

接口说明

void removeFabric(Integer fabricIndex, IThingDataCallback<Integer> callback);

代码示例
Java:

mThingMatterFabricDevice.removeFabric(Integer.parseInt(fabricIndex), new IThingDataCallback<Integer>() {
  @Override
  public void onSuccess(Integer result) {
    if (result ==0){
      Log.i("removeFabric","RemoveFabric success");
    }
  }

  @Override
  public void onError(String errorCode, String errorMessage) {
    Log.e("removeFabric", "RemoveFabric error: ErrorCode = " + errorCode + "; ErrorMessage = " + errorMessage);
  }
});

错误码定义

错误码 含义
3027 设备所有通道均不在线
3051 打开分享配网窗口失败
3037 读取设备属性失败,例如:
  • 获取设备支持分享次数失败
  • 获取设备已使用次数失败
  • 读取设备配网窗口状态失败
  • 获取 fabricList 失败
  • 获取设备基础信息失败
3055 移除设备 fabricIndex 失败
3057 请求云端 API 接口失败,例如:获取云端 fabric passcode 接口失败
3058 关闭设备配网窗口失败
3059 计算可用 fabric 次数=0