更新时间:2024-05-15 07:29:42下载pdf
通俗地讲,蓝牙 Mesh 就是把多个蓝牙单点设备组成一个 Mesh 网络,每个节点可以和别的节点自由通讯。通过手机直连 Mesh 网中任意一个设备,即能访问控制 Mesh 网中所有的设备。本文介绍涂鸦自研的蓝牙拓扑通信相关实现,以及设备的配网、控制、管理等开发指导。更多有关蓝牙 Mesh 的概念介绍,请参考 蓝牙 Mesh(SIG)。
<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" />
该部分检查逻辑,Cube SDK 未提供 API,您可自行检测。
一个家庭里可以拥有多个 Mesh,但建议只创建一个 Mesh。
接口说明
void createBlueMesh(String meshName, IThingResultCallback<BlueMeshBean> callback);
参数说明
参数 | 类型 | 说明 |
---|---|---|
meshName | String | Mesh 的名称,不能超过 16 字节 |
callback | IThingResultCallback | 回调 |
示例代码
ThingHomeSdk.newHomeInstance("homeId").createBlueMesh("meshName", new IThingResultCallback<BlueMeshBean>() {
@Override
public void onError(String errorCode, String errorMsg) {
}
@Override
public void onSuccess(BlueMeshBean blueMeshBean) {
}
});
接口说明
void removeMesh(IResultCallback callback);
参数说明
参数 | 类型 | 说明 |
---|---|---|
callback | IResultCallback | 回调 |
示例代码
ThingHomeSdk.newBlueMeshDeviceInstance(meshId).removeMesh(new IResultCallback() {
@Override
public void onError(String errorCode, String errorMsg) {
}
@Override
public void onSuccess() {
}
});
接口说明
List<BlueMeshBean> getMeshList();
示例代码
IThingHome mThingHome = ThingHomeSdk.newHomeInstance("homeId");
if (mThingHome.getHomeBean() != null){
List<BlueMeshBean> meshList = mThingHome.getHomeBean().getMeshList();
BlueMeshBean meshBean= meshList.get(0);
}
接口说明
List<DeviceBean> getMeshSubDevList();
示例代码
List<DeviceBean> meshSubDevList = ThingHomeSdk.newBlueMeshDeviceInstance("meshId").getMeshSubDevList();
建议在切换家庭时,销毁当前 Mesh,然后重新初始化家庭中的 Mesh。
接口说明
//初始化 Mesh
ThingHomeSdk.getThingBlueMeshClient().initMesh(String meshId);
//销毁当前 Mesh
ThingHomeSdk.getThingBlueMeshClient().destroyMesh();
IThingBlueMeshClient
提供开始连接、断开连接、开启扫描、停止扫描等接口。
接口说明
// 开启连接
ThingHomeSdk.getThingBlueMeshClient().startClient(mBlueMeshBean);
//断开连接
ThingHomeSdk.getThingBlueMeshClient().stopClient();
//开启扫描
ThingHomeSdk.getThingBlueMeshClient().startSearch()
//停止扫描
ThingHomeSdk.getThingBlueMeshClient().stopSearch();
开启连接后,会在应用后台不断的去扫描周围可连接设备,直到连接成功为止。后台一直扫描会消耗资源,可以通过开启扫描和停止扫描来控制后台的扫描:
startClient()
)时,调用 startSearch()
和 stopSearch()
属于无效操作。startSearch()
和 stopSearch()
也属于无效操作。Mesh 配网主要分为两种:
普通蓝牙 Mesh 设备,又称 Mesh 子设备
Mesh 网关配网
常见的子设备有智能灯、智能插座、低功耗产品等。只要不带 Mesh 网关,都可以等同于普通蓝牙 Mesh 设备。
处于重置状态的设备,默认名字为 out_of_mesh
,默认密码为 123456
。重置设备可以通过以下常见方式操作:
产品类型 | 重置操作 | 可配网现象 |
---|---|---|
智能灯 | 连续开关三次 | 灯快闪 |
智能插座 | 长按开关 3s | 插座指示灯快闪 |
网关产品 | 长按开关 3s | 红灯和蓝灯快闪 |
低功耗设备 | 长按开关 3s | 再按一次出现长亮即可配网,且配网需在灯亮期间完成 |
报警器 | 长按开关 3s | 灯快闪 |
扫描前需要检查蓝牙和位置权限,扫描附近的待配网 Mesh 设备。
接口说明
//开启扫描
void startSearch();
//停止扫描
void stopSearch();
示例代码
IThingBlueMeshSearchListener iThingBlueMeshSearchListener = new IThingBlueMeshSearchListener() {
@Override
public void onSearched(SearchDeviceBean deviceBean) {
}
@Override
public void onSearchFinish() {
}
};
SearchBuilder searchBuilder = new SearchBuilder()
//要扫描设备的名称(默认会是 out_of_mesh,设备处于配网状态下的名称)
.setMeshName("out_of_mesh")
.setTimeOut(100) //扫描时长 单位秒
.setThingBlueMeshSearchListener(iThingBlueMeshSearchListener).build();
IThingBlueMeshSearch mMeshSearch = ThingHomeSdk.getThingBlueMeshConfig().newThingBlueMeshSearch(searchBuilder);
//开启扫描
mMeshSearch.startSearch();
//停止扫描
mMeshSearch.stopSearch();
接口说明
//开启配网
void startActivator();
//停止配网
void stopActivator();
参数说明
参数 | String | 说明 |
---|---|---|
mSearchDeviceBeans | List | 待配网的设备集合 |
timeout | Int | 配网的超时时间设置,默认是 100s |
ssid | String | 配网之后,设备连接的 Wi-Fi 的名称 |
password | String | 配网之后,设备连接的 Wi-Fi 的密码 |
mMeshBean | MeshBean | MeshBean |
homeId | Long | 设备要加入的 Mesh 网的所属家庭 |
version | String |
|
示例代码
//普通设备入网
ThingBlueMeshActivatorBuilder thingBlueMeshActivatorBuilder = new ThingBlueMeshActivatorBuilder()
.setSearchDeviceBeans(foundDevices)
.setVersion("1.0")
.setBlueMeshBean(mMeshBean)
.setTimeOut(timeOut)
.setThingBlueMeshActivatorListener(new IThingBlueMeshActivatorListener() {
@Override
public void onSuccess(DeviceBean deviceBean) {
}
@Override
public void onError(String errorCode, String errorMsg) {
}
@Override
public void onFinish() {
}});
IThingBlueMeshActivator iThingBlueMeshActivator = ThingHomeSdk.getThingBlueMeshConfig().newActivator(thingBlueMeshActivatorBuilder);
//开始入网
iThingBlueMeshActivator.startActivator();
//停止入网
iThingBlueMeshActivator.stopActivator();
接口说明
//开启配网
void startActivator();
//停止配网
void stopActivator();
参数说明
参数 | String | 说明 |
---|---|---|
mSearchDeviceBeans | List | 待配网的设备集合 |
timeout | Int | 配网的超时时间设置,默认值:100s |
ssid | String | 配网之后,设备连接的 Wi-Fi 的名称 |
password | String | 配网之后,设备连接的 Wi-Fi 的密码 |
mMeshBean | MeshBean | MeshBean |
homeId | Long | 设备要加入的 Mesh 网的所属家庭 |
version | String |
|
示例代码
//网关入网
ThingBlueMeshActivatorBuilder thingBlueMeshActivatorBuilder = new ThingBlueMeshActivatorBuilder()
.setWifiSsid(mSsid)
.setWifiPassword(mPassword)
.setSearchDeviceBeans(foundDevices)
.setVersion("2.2 ")
.setBlueMeshBean(mMeshBean)
.setHomeId("homeId")
.setThingBlueMeshActivatorListener(new IThingBlueMeshActivatorListener() {
@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() {
//所有设备配网结束回调
}
});
IThingBlueMeshActivator iThingBlueMeshActivator = ThingHomeSdk.getThingBlueMeshConfig().newWifiActivator(thingBlueMeshActivatorBuilder);
//开始入网
iThingBlueMeshActivator.startActivator();
//停止入网
//iThingBlueMeshActivator.stopActivator();
错误码 | 说明 |
---|---|
13007 | 登录设备失败 |
13004 | 重置设备地址失败 |
13005 | 设备地址已满 |
13007 | SSID 为空 |
13011 | 配网超时 |
接口说明
DeviceBean deviceBean=ThingHomeSdk.getDataInstance().getDeviceBean(mDevId);
// 蓝牙 Mesh 设备判断 (子设备+网关)
if(deviceBean.isBlueMesh()){
L.d(TAG, "This device is blue mesh device");
}
// 蓝牙 Mesh 网关设备判断
if(deviceBean.isBlueMeshWifi()){
L.d(TAG, "This device is blue mesh wifi device");
}
接口说明
void renameMeshSubDev(String devId, String name, IResultCallback callback);
参数说明
参数 | 类型 | 说明 |
---|---|---|
devId | String | 设备 ID |
name | String | 设备新名称 |
callback | IResultCallback | 回调 |
示例代码
mThingBlueMesh.renameMeshSubDev(devBean.getDevId(),"设备名称", new IResultCallback() {
@Override
public void onError(String code, String errorMsg) {
}
@Override
public void onSuccess() {
}
});
示例代码
DeviceBean deviceBean=ThingHomeSdk.getDataInstance().getDeviceBean(mDevId);
DeviceBean gwBean=ThingHomeSdk.getDataInstance().getDeviceBean(deviceBean.getParentId());
//综合在线状态 (包括本地在线和网关在线)
boolean online=deviceBean.getIsOnline()
//设备本地蓝牙在线状态
boolean localOnline=deviceBean.getIsLocalOnline()
//设备网关在线状态 (需要网关在线且子设备在线 才认为网关真实在线)
boolean wifiOnline=deviceBean.isCloudOnline() && gwBean.getIsOnline()
接口说明
void removeMeshSubDev(String devId, IResultCallback callback);
参数说明
参数 | 类型 | 说明 |
---|---|---|
devId | String | 设备 ID |
pcc | String | 设备大小类 |
callback | IResultCallback | 回调 |
示例代码
mThingBlueMesh.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();
}
});
云端查询到的 DP 数据可能不是当前设备实时的数据。您可以通过该命令去查询设备的当前数据值,结果通过 IMeshDevListener
的 onDpUpdate
方法返回。
接口说明
void querySubDevStatusByLocal(String pcc, String nodeId, IResultCallback callback);
参数说明
参数 | 类型 | 说明 |
---|---|---|
pcc | String | 设备大小类 |
nodeId | String | 设备 NodeId |
callback | IResultCallback | 回调 |
示例代码
mThingBlueMeshDevice.querySubDevStatusByLocal(devBean.getCategory(), devBean.getNodeId(), new IResultCallback() {
@Override
public void onError(String code, String errorMsg) {
}
@Override
public void onSuccess() {
}
});
IThingGroup
类提供了对 Mesh 群组的操作。
可以通过群组中是否具备 MeshId 来区分 Mesh 群组和普通 Wi-Fi 群组。
接口说明
GroupBean groupBean=ThingHomeSdk.getDataInstance().getGroupBean("groupId");
if(!TextUtils.isEmpty(groupBean.getMeshId())){
L.d(TAG, "This group is a Bluetooth mesh group");
}
Mesh 网内支持创建 28672 个群组,返回时 ID 范围为 16 进制的 8000 ~ EFFF,由本地进行维护。
接口说明
void addGroup(String name, String pcc, String localId,IAddGroupCallback callback);
参数说明
参数 | 说明 |
---|---|
name | 群组名称 |
pcc | 群组中设备的大小类,支持跨小类创建,FF01 表示覆盖灯大类 |
localId | 群组的 LocalId,范围为 16 进制的 8000 ~ EFFF |
callback | 回调 |
示例代码
mIThingBlueMesh.addGroup("群组名称","大小类", "8001", new IAddGroupCallback() {
@Override
public void onError(String errorCode, String errorMsg) {
}
@Override
public void onSuccess(long groupId) {
}
});
接口说明
void addDevice(String devId,IResultCallback callback);
参数说明
参数 | 类型 | 说明 |
---|---|---|
devId | String | 设备 ID |
callback | IResultCallback | 回调 |
示例代码
IThingGroup mGroup = ThingHomeSdk.newBlueMeshGroupInstance(groupId);
mGroup.addDevice("devId", new IResultCallback() {
@Override
public void onError(String code, String errorMsg) {
}
@Override
public void onSuccess() {
}
});
接口说明
void removeDevice(String devId,IResultCallback callback);
参数说明
参数 | 类型 | 说明 |
---|---|---|
devId | String | 设备 ID |
callback | IResultCallback | 回调 |
示例代码
IThingGroup mGroup = ThingHomeSdk.newBlueMeshGroupInstance(groupId);
mGroup.removeDevice("devId", new IResultCallback() {
@Override
public void onError(String code, String errorMsg) {
}
@Override
public void onSuccess() {
}
});
接口说明
void dismissGroup(IResultCallback callback);
参数说明
参数 | 类型 | 说明 |
---|---|---|
callback | IResultCallback | 回调 |
接口说明
IThingGroup mGroup = ThingHomeSdk.newBlueMeshGroupInstance(groupId);
mGroup.dismissGroup(new IResultCallback() {
@Override
public void onError(String code, String errorMsg) {
}
@Override
public void onSuccess() {
}
});
接口说明
void renameGroup(String groupName,IResultCallback callback);
参数说明
参数 | 类型 | 说明 |
---|---|---|
groupName | String | 新的群组名称 |
callback | IResultCallback | 回调 |
示例代码
IThingGroup mGroup = ThingHomeSdk.newBlueMeshGroupInstance(groupId);
mGroup.renameGroup("群组名称",new IResultCallback() {
@Override
public void onError(String code, String errorMsg) {
}
@Override
public void onSuccess() {
}
});
由于涂鸦使用 DP 管理设备的功能,因此,蓝牙 Mesh 相关的控制是根据设备的 DP 信息来进行操作。IThingBlueMeshDevice
类提供了对 Mesh 设备的操作。
发送控制指令按照以下格式:
{
"(dpId)":"(dpValue)"
}
DP 指令详情,请参考 设备控制。
接口说明
void publishDps(String nodeId, String pcc, String dps, IResultCallback callback);
参数说明
参数 | 说明 |
---|---|
nodeId | 子设备本地编号 |
pcc | 设备产品大小类 |
dps | 控制指令 |
callback | 回调 |
示例代码
String dps = {"1":false};
IThingBlueMeshDevice mThingBlueMeshDevice=ThingHomeSdk.newBlueMeshDeviceInstance("meshId");
mThingBlueMeshDevice.publishDps(devBean.getNodeId(), devBean.getCategory(), dps, new IResultCallback() {
@Override
public void onError(String s, String s1) {
}
@Override
public void onSuccess() {
}
});
接口说明
void multicastDps(String localId, String pcc, String dps, IResultCallback callback)
参数说明
参数 | 说明 |
---|---|
localId | 群组本地编号 |
pcc | 设备产品大小类 |
dps | 控制指令 |
callback | 回调 |
示例代码
String dps = {"1":false};
IThingBlueMeshDevice mThingBlueMeshDevice= ThingHomeSdk.newBlueMeshDeviceInstance("meshId");
mThingBlueMeshDevice.multicastDps(groupBean.getLocalId(), devBean.getCategory(), dps, new IResultCallback() {
@Override
public void onError(String errorCode, String errorMsg) {
}
@Override
public void onSuccess() {
}
});
Mesh 网内相关信息,例如 DP 数据、状态变更、设备名称、设备移除等,会实时同步到 IMeshDevListener
。
示例代码
mThingBlueMeshDevice.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 = mThingBlueMeshDevice.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) {
}
});
涂鸦 Mesh 设备的固件升级与蓝牙 Mesh 逻辑一致,详情请参考 蓝牙 Mesh 固件升级 章节。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈