1. 蓝牙 Mesh (涂鸦)

涂鸦蓝牙有三条技术线路。蓝牙设备与手机一对一相连的蓝牙单点设备 SingleBLE,涂鸦自研的蓝牙拓扑通信 TuyaMesh 和蓝牙技术联盟发布的蓝牙拓扑通信 SigMesh。除了以上三种之外,还有一些多协议设备也会使用到蓝牙技术,比如同时具备 Wi-Fi 能力和 BLE 能力的 双模设备,也可以使用蓝牙进行配网,当然 Wi-Fi 设备原本的配网仍然可用。

蓝牙技术分类 产品举例
SingleBLE 体脂秤、手环、温控器、电动牙刷、门锁等
SigMesh 一路、二路、五路等灯泡、插座、传感器等 Sigmesh 子设备
TuyaMesh 与 Sigmesh 产品类似,协议为 Tuya 自研
双模设备 Sigmesh 网关、IPC 设备以及新版多协议 Wi-Fi 设备等均有可能

双模配网的蓝牙配网部分,使用的是 SingleBLE 技术为设备配网,将放到 SingleBLE 章节进行说明。

提示

开发蓝牙 Mesh 时,请先熟悉 TuyaHomeSdk。Mesh 的所有操作都建立在家庭数据已经初始化的基础上。 一个家庭里可以拥有多个 Mesh(建议一个家庭只创建一个)

1.1. 准备

手机系统要求

BLE 使用需要 Android 4.3 以及以上版本,TuyaHomesdk 从 Android 4.4 开始支持。

Manifest 的权限

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

使用蓝牙前需要检测权限已被授予

  • APP 在使用蓝牙连接或者扫描操作前 需要检查 APP 定位权限是否被允许。
  • 检查蓝牙状态是否为开启。

    该部分检查逻辑,TuyaHomeSdk 未提供 API,开发者可自行检测。每次扫描和连接前都要进行检测,否则 APP 无法正常使用蓝牙。

1.2. 部分基础概念

大小类介绍

Mesh 产品目前分为五大类

灯大类(01): 1-5路RGBWC彩灯
电工类(02)1-6路插座
传感器类(04):门磁、PIR(传感类主要是一些周期性上报的传感数据)
执行器类(10):马达、报警器之类用于执行的设备
适配器(08):网关(带有mesh及其他通信节点的适配器)

小类编号

1-5路灯(01-051-6路排插(01-06)
.....

举例

四路灯          0401
五路插座        0502
......

Mesh 节点 NodeId, 2 字节

NodeId 用于区分每个 Mesh 设备在 Mesh 网中的「唯一标识」,比如想控制某个设备就向 Mesh 网发此设备对应的 NodeId 命令即可

Mesh 群组 localId,2 字节

LocalId 用于区分每个 Mesh 群组在 Mesh 网中的「唯一标识」,比如想控制某个群组中的设备就向 Mesh 网发此群组对应的 LocalId 命令即可

设备操作需要多步操作

因为设备的操作,例如增删操作、群组操作,都需要本地蓝牙命令执行一次、云端记录一次 向本地 Mesh 网同步操作信息的同时也需要向云端同步操作信息

本地连接和网关连接

本地连接:已配网设备通过蓝牙连接,来控制 Mesh 和指令操作

网关连接:已配网设备通过网关连接(网关需和设备在一起,距离不能太远),来控制 Mesh 和指令操作

1.3. 管理

1.3.1. 创建 Mesh

接口说明

void createBlueMesh(String meshName, ITuyaResultCallback<BlueMeshBean> callback);

参数说明

参数 类型 说明
meshName String mesh 的名称(不超过 16 字节)
callback ITuyaResultCallback 回调

示例代码

TuyaHomeSdk.newHomeInstance("homeId").createBlueMesh("meshName", new ITuyaResultCallback<BlueMeshBean>() {
    @Override
    public void onError(String errorCode, String errorMsg) {
    }

    @Override    
    public void onSuccess(BlueMeshBean blueMeshBean) {
    }
});

1.3.2. 删除 Mesh

接口说明

void removeMesh(IResultCallback callback);

参数说明

参数 类型 说明
callback IResultCallback 回调

示例代码

TuyaHomeSdk.newBlueMeshDeviceInstance(meshId).removeMesh(new IResultCallback() {
    @Override
    public void onError(String errorCode, String errorMsg) {
    }

    @Override
    public void onSuccess() {
    }
});

1.3.3. 获取家庭下的 Mesh 列表

接口说明

List<BlueMeshBean> getMeshList();

示例代码

ITuyaHome mTuyaHome = TuyaHomeSdk.newHomeInstance("homeId");
if (mTuyaHome.getHomeBean() != null){
    List<BlueMeshBean> meshList = mTuyaHome.getHomeBean().getMeshList();
    BlueMeshBean meshBean= meshList.get(0);
}

1.3.4. 获取 Mesh 下的子设备列表

接口说明

List<DeviceBean> getMeshSubDevList();

示例代码

List<DeviceBean> meshSubDevList = TuyaHomeSdk.newBlueMeshDeviceInstance("meshId").getMeshSubDevList();

1.3.5. 获取 Mesh 实例和销毁

建议在家庭切换的时候 销毁当 Mesh 然后重新初始化家庭中的 Mesh

接口调用

//初始化mesh
TuyaHomeSdk.getTuyaBlueMeshClient().initMesh(String meshId);       

//销毁当前mesh
TuyaHomeSdk.getTuyaBlueMeshClient().destroyMesh();

1.3.6. Mesh 子设备连接和断开

ITuyaBlueMeshClient 提供 开始连接、断开连接、开启扫描、停止扫描

接口调用

// 开启连接
TuyaHomeSdk.getTuyaBlueMeshClient().startClient(mBlueMeshBean);

//断开连接
TuyaHomeSdk.getTuyaBlueMeshClient().stopClient();

//开启扫描
TuyaHomeSdk.getTuyaBlueMeshClient().startSearch()

//停止扫描
TuyaHomeSdk.getTuyaBlueMeshClient().stopSearch();

注意事项

  • 开启连接后,会在后台不断的去扫描周围可连接设备,直到连接成功为止。
  • 后台一直扫描会消耗资源,可以通过通过开启扫描和停止扫描来控制后台的扫描
  • 当未 startClient() 时候,调用 startSearch()stopSearch() 是没有效果的
  • 当已经连接到 Mesh 网的时候,调用 startSearch()stopSearch() 是没有效果的

1.4. 配网

mesh 配网主要分为两种,一种是针对普通蓝牙 mesh 设备(又称 mesh 子设备),例如灯、插座、低功耗等,可以理解为只要不带网关,就是普通蓝牙设备,一种是对 mesh 网关配网

1.4.1. 设备重置

产品类型 重置操作 可配网现象
连续开关三次 灯快闪
插座 长按开关 3s 插座指示灯快闪
网关 长按开关 3s 红灯和蓝灯快闪
低功耗设备 长按开关 3s 再按一次出现长亮即可配网,且配网需在灯亮期间完成
报警器 长按开关 3s 灯快闪

处于重置状态的设备,默认名字为 out_of_mesh,默认密码为 123456

1.4.2. 扫描待配网子设备

扫描前需要检查蓝牙和位置权限;扫描附近的待配网 Mesh 设备

接口说明

//开启扫描
void startSearch();
//停止扫描
void stopSearch();

示例代码

ITuyaBlueMeshSearchListener iTuyaBlueMeshSearchListener = new ITuyaBlueMeshSearchListener() {
    @Override
    public void onSearched(SearchDeviceBean deviceBean) {
    }

    @Override
    public void onSearchFinish() {
    }
};

SearchBuilder searchBuilder = new SearchBuilder()
                //要扫描设备的名称(默认会是out_of_mesh,设备处于配网状态下的名称)
                .setMeshName("out_of_mesh") 
                .setTimeOut(100) //扫描时长 单位秒
                .setTuyaBlueMeshSearchListener(iTuyaBlueMeshSearchListener).build();

ITuyaBlueMeshSearch mMeshSearch = TuyaHomeSdk.getTuyaBlueMeshConfig().newTuyaBlueMeshSearch(searchBuilder);

//开启扫描
mMeshSearch.startSearch();

//停止扫描
mMeshSearch.stopSearch();

1.4.3. Mesh 子设备配网

接口说明

//开启配网
void startActivator();

//停止配网
void stopActivator();

参数说明

参数 String 说明
mSearchDeviceBeans List 待配网的设备集合
timeout Int 配网的超时时间设置,默认是 100s.
ssid String 配网之后,设备工作 Wi-Fi 的名称。(家庭网络)
password String 配网之后,设备工作 Wi-Fi 的密码。(家庭网络)
mMeshBean MeshBean MeshBean
homeId Long 设备要加入的 Mesh 网 所属家庭的 HomeId
version String 普通设备配网是 1.0 网关配网是 2.2

代码示例

//普通设备入网
TuyaBlueMeshActivatorBuilder tuyaBlueMeshActivatorBuilder = new TuyaBlueMeshActivatorBuilder()
                .setSearchDeviceBeans(foundDevices)
                .setVersion("1.0")
                .setBlueMeshBean(mMeshBean)
                .setTimeOut(timeOut)
                .setTuyaBlueMeshActivatorListener(new ITuyaBlueMeshActivatorListener() {
     @Override
     public void onSuccess(DeviceBean deviceBean) {
     }

     @Override
     public void onError(String errorCode, String errorMsg) {
     }

     @Override
     public void onFinish() {
     }});

ITuyaBlueMeshActivator iTuyaBlueMeshActivator = TuyaHomeSdk.getTuyaBlueMeshConfig().newActivator(tuyaBlueMeshActivatorBuilder);
//开始入网
iTuyaBlueMeshActivator.startActivator();

//停止入网
iTuyaBlueMeshActivator.stopActivator();

1.4.4. Mesh 网关配网

接口说明

//开启配网
void startActivator();
//停止配网
void stopActivator();

参数说明

参数 String 说明
mSearchDeviceBeans List 待配网的设备集合
timeout Int 配网的超时时间设置,默认是 100s.
ssid String 配网之后,设备工作 Wi-Fi 的名称。(家庭网络)
password String 配网之后,设备工作 Wi-Fi 的密码。(家庭网络)
mMeshBean MeshBean MeshBean
homeId Long 设备要加入的 Mesh 网 所属家庭的 HomeId
version String 普通设备配网是 1.0 网关配网是 2.2

代码示例

//网关入网
TuyaBlueMeshActivatorBuilder tuyaBlueMeshActivatorBuilder = new TuyaBlueMeshActivatorBuilder()
                .setWifiSsid(mSsid)
                .setWifiPassword(mPassword)
                .setSearchDeviceBeans(foundDevices)
                .setVersion("2.2  ")
                .setBlueMeshBean(mMeshBean)
                .setHomeId("homeId")
                .setTuyaBlueMeshActivatorListener(new ITuyaBlueMeshActivatorListener() {
                  @Override
                  public void onSuccess(DeviceBean devBean) {
                    //单个设备配网成功回调
                    L.d(TAG, "startConfig  success");
                  }

                  @Override
                  public void onError(String errorCode, String errorMsg) {
                    //单个设备配网失败回调
                    //errorCode 见错误码
                  L.d(TAG, "errorCode: " + errorCode + " errorMsg: " + errorMsg);
                  }

                  @Override
                  public void onFinish() {
                    //所有设备配网结束回调          
                  }
                });
ITuyaBlueMeshActivator iTuyaBlueMeshActivator = TuyaHomeSdk.getTuyaBlueMeshConfig().newWifiActivator(tuyaBlueMeshActivatorBuilder);

//开始入网
iTuyaBlueMeshActivator.startActivator();

//停止入网
//iTuyaBlueMeshActivator.stopActivator();

1.4.5. 配网错误码

Code 说明
13007 登录设备失败
13004 重置设备地址失败
13005 设备地址已满
13007 ssid为空
13011 配网超时

1.5. 设备

1.5.1. Mesh 设备判断方法

使用方法

DeviceBean deviceBean=TuyaHomeSdk.getDataInstance().getDeviceBean(mDevId);
// blue mesh 设备判断 (子设备+网关)
if(deviceBean.isBlueMesh()){
    L.d(TAG, "This device is blue mesh device");
 }

// blue mesh 网关设备判断
if(deviceBean.isBlueMeshWifi()){
    L.d(TAG, "This device is blue mesh wifi device");
}

1.5.2. 子设备重命名

接口说明

void renameMeshSubDev(String devId, String name, IResultCallback callback);

参数说明

参数 类型 说明
devId String 设备 Id
name String 重命名名称
callback IResultCallback 回调

代码示例

mTuyaBlueMesh.renameMeshSubDev(devBean.getDevId(),"设备名称", new IResultCallback() {
            @Override
            public void onError(String code, String errorMsg) {
            }

            @Override
            public void onSuccess() {
            }
        });

1.5.3. Mesh 本地连接和网关连接

示例代码

DeviceBean deviceBean=TuyaHomeSdk.getDataInstance().getDeviceBean(mDevId);
DeviceBean gwBean=TuyaHomeSdk.getDataInstance().getDeviceBean(deviceBean.getParentId());

//综合在线状态  (包括本地在线和网关在线)
boolean online=deviceBean.getIsOnline()
//设备本地蓝牙在线状态
boolean localOnline=deviceBean.getIsLocalOnline()
//设备网关在线状态  (需要网关在线且子设备在线 才认为网关真实在线)
boolean wifiOnline=deviceBean.isCloudOnline() && gwBean.getIsOnline()

1.5.4. 子设备移除

接口说明

void removeMeshSubDev(String devId, IResultCallback callback);

参数说明

参数 类型 说明
devId String 设备 Id
pcc String 设备大小类
callback IResultCallback 回调

代码示例

mTuyaBlueMesh.removeMeshSubDev(devBean.getDevId(), new IResultCallback(){
  @Override
  public void onError(String code, String errorMsg) {
    Toast.makeText(mContext, "子设备移除失败 "+ errorMsg,     Toast.LENGTH_LONG).show();
  }

  @Override
  public void onSuccess() {
    Toast.makeText(mContext, "子设备移除成功", Toast.LENGTH_LONG).show();
  }
});

1.5.5. 子设备状态查询

云端获取到的 dp 点数据可能不是当前设备实时的数据,可以通过该命令去查询设备的当前数据值,结果通过 IMeshDevListeneronDpUpdate 方法返回

接口说明

void querySubDevStatusByLocal(String pcc, String nodeId, IResultCallback callback);

参数说明

参数 类型 说明
pcc String 设备大小类
nodeId String 设备 nodeId
callback IResultCallback 回调

代码示例

mTuyaBlueMeshDevice.querySubDevStatusByLocal(devBean.getCategory(), devBean.getNodeId(), new IResultCallback() {
            @Override
            public void onError(String code, String errorMsg) {
            }

            @Override
            public void onSuccess() {
            }
        });

1.6. 群组

ITuyaGroup 类提供了对 Mesh 群组的操作

1.6.1. Mesh 群组判断方法

可以通过群组中是否具备 MeshId 来区分 Mesh 群组和普通 Wi-Fi 群组

代码调用

GroupBean groupBean=TuyaHomeSdk.getDataInstance().getGroupBean("groupId");
if(!TextUtils.isEmpty(groupBean.getMeshId())){    
    L.d(TAG, "This group is mesh group");
}

1.6.2. 创建群组

Mesh 网内支持创建 28672 个群组 返回时 id 范围 8000 ~ EFFF ( 16 进制) 由本地进行维护

接口说明

void addGroup(String name, String pcc, String localId,IAddGroupCallback callback);

参数说明

参数 说明
name 群组名称
pcc 群组中设备的大小类 (支持跨小类创建 FF01 表示覆盖灯大类)
localId 群组的 localId (范围 8000 ~ EFFF 16 进制字符串)
callback 回调

示例代码

mITuyaBlueMesh.addGroup("群组名称","大小类", "8001", new IAddGroupCallback() {
   @Override
   public void onError(String errorCode, String errorMsg) {
   }   

   @Override
   public void onSuccess(long groupId) {
   }
});

1.6.3. 添加子设备到群组

接口说明

void addDevice(String devId,IResultCallback callback);

参数说明

参数 类型 说明
devId String 设备 Id
callback IResultCallback 回调

示例代码

ITuyaGroup mGroup = TuyaHomeSdk.newBlueMeshGroupInstance(groupId);
mGroup.addDevice("devId", new IResultCallback() {
  @Override
  public void onError(String code, String errorMsg) {
  }

  @Override
  public void onSuccess() {
  }
});

1.6.4. 从群组中移除子设备

接口说明

void removeDevice(String devId,IResultCallback callback);

参数说明

参数 类型 说明
devId String 设备 Id
callback IResultCallback 回调

示例代码

ITuyaGroup mGroup = TuyaHomeSdk.newBlueMeshGroupInstance(groupId);
mGroup.removeDevice("devId", new IResultCallback() {
  @Override
  public void onError(String code, String errorMsg) {
  }

  @Override
  public void onSuccess() {
  }
});

1.6.5. 删除群组

接口说明

void dismissGroup(IResultCallback callback);

参数说明

参数 类型 说明
callback IResultCallback 回调

接口说明

ITuyaGroup mGroup = TuyaHomeSdk.newBlueMeshGroupInstance(groupId);
mGroup.dismissGroup(new IResultCallback() {
  @Override
  public void onError(String code, String errorMsg) {
  }

  @Override
  public void onSuccess() {
  }
});

1.6.6. 重命名群组

接口说明

void renameGroup(String groupName,IResultCallback callback);

参数说明

参数 类型 说明
groupName String 重命名名称
callback IResultCallback 回调

示例代码

ITuyaGroup mGroup = TuyaHomeSdk.newBlueMeshGroupInstance(groupId);
mGroup.renameGroup("群组名称",new IResultCallback() {
  @Override
  public void onError(String code, String errorMsg) {
  }

  @Override
  public void onSuccess() {
  }
});

1.7. 控制

ITuyaBlueMeshDevice 类提供了对 Mesh 设备的操作

1.7.1. 指令下发-控制设备

发送控制指令按照以下格式:

{"(dpId)":"(dpValue)"}

接口说明

void publishDps(String nodeId, String pcc, String dps, IResultCallback callback);

参数说明

参数 说明
nodeId 子设备本地编号
pcc 设备产品大小类
dps 控制指令
callback 回调

示例代码

String dps = {"1":false};
ITuyaBlueMeshDevice mTuyaBlueMeshDevice=TuyaHomeSdk.newBlueMeshDeviceInstance("meshId");
mTuyaBlueMeshDevice.publishDps(devBean.getNodeId(), devBean.getCategory(), dps, new IResultCallback() {
  @Override
  public void onError(String s, String s1) {
  }

  @Override
  public void onSuccess() {
  }
});

1.7.2. 指令下发-控制群组

发送控制指令按照以下格式:

{
  "(dpId)":"(dpValue)"
}

接口说明

void multicastDps(String localId, String pcc, String dps, IResultCallback callback)

参数说明

参数 说明
localId 群组本地编号
pcc 设备产品大小类
dps 控制指令
callback 回调

示例代码

String dps = {"1":false};
ITuyaBlueMeshDevice mTuyaBlueMeshDevice= TuyaHomeSdk.newBlueMeshDeviceInstance("meshId");
mTuyaBlueMeshDevice.multicastDps(groupBean.getLocalId(), devBean.getCategory(), dps, new IResultCallback() {
   @Override
   public void onError(String errorCode, String errorMsg) {
   }

   @Override
   public void onSuccess() {
   }
});

1.7.3. 数据监听

Mesh 网内相关信息( dp 数据、状态变更、设备名称、设备移除)会实时同步到 IMeshDevListener

示例代码

mTuyaBlueMeshDevice.registerMeshDevListener(new IMeshDevListener() {

   /**
    * 数据更新
    * @param nodeId    更新设备的nodeId
    * @param dps       dp数据
    * @param isFromLocal   数据来源 true表示从本地蓝牙  false表示从云端
    */
   @Override
   public void onDpUpdate(String nodeId, String dps,boolean isFromLocal) {
   //可以通过node来找到相对应的DeviceBean
   DeviceBean deviceBean = mTuyaBlueMeshDevice.getMeshSubDevBeanByNodeId(nodeId);
   }

   /**
    * 设备状态的上报
    * @param online    在线设备列表
    * @param offline   离线设备列表
    * @param gwId      状态的来源 gwId不为空表示来自云端(gwId是上报数据的网关Id)   为空则表示来自本地蓝牙
    */
   @Override
   public void onStatusChanged(List<String> online, List<String> offline,String gwId) {
   }

   /**
    * 网络状态变化
    * @param devId
    * @param status
    */
   @Override
   public void onNetworkStatusChanged(String devId, boolean status) {

   }

   /**
    * raw类型数据上报
    * @param bytes
    */
   @Override
   public void onRawDataUpdate(byte[] bytes) {

   }

   /**
    * 设备信息变更(名称等)
    * @param bytes
    */            
   @Override
   public void onDevInfoUpdate(String devId) {
   }
   /**
    * 设备移除
    * @param devId
    */
   @Override
   public void onRemoved(String devId) {
   }
});

1.8. 固件升级

与 SIG Mesh 固件升级逻辑一致。 SIG Mesh 固件升级

results matching ""

    No results matching ""