更新时间:2024-03-22 09:06:15下载pdf
蓝牙 Mesh,也就是将蓝牙设备组成网络,每个蓝牙设备可以通过网络内的蓝牙设备进行通讯,将一端的蓝牙信息通过 Mesh 网络传到较远的另一端。本文介绍了 iOS 版商用照明 App SDK 的蓝牙 Mesh 相关接口和调用示例。
蓝牙技术联盟(Bluetooth Special Interest Group,简称蓝牙 SIG)蓝牙技术全面支持 Mesh 网状网络。标准蓝牙 Mesh 也叫做 SIG Mesh,是蓝牙技术联盟提出的 Mesh 网络的通讯标准。使用蓝牙 Mesh 进行组网及设备功能的更新,均需要满足标准蓝牙 Mesh 的标准。
专有名词 | 说明 |
---|---|
大小类 | 每个 Mesh 设备都对应一款产品,每个产品都有自己的大小类标示,SDK 中以 pcc 和 type 作为大小类标示。 |
Mesh 群组 localId | 2 字节,localId 用于区分每个 Mesh 群组在 Mesh 网中的 唯一标识。当您想控制某个群组中的设备时,就向 Mesh 网发此群组对应的 localId 命令即可。 |
Mesh 节点 nodeId | 2 字节,nodeId 用于区分每个 Mesh 设备在 Mesh 网中的 唯一标识。当您想控制某个设备时,就向 Mesh 网发此设备对应的 nodeId 命令即可 |
本地连接 | 已配网设备通过蓝牙连接,来控制 Mesh 和指令操作。 |
网关连接 | 已配网设备通过网关连接(网关需和设备在一起,距离不能太远),来控制 Mesh 和指令操作。 |
因为设备的操作,例如增删操作、群组操作,都需要本地蓝牙命令执行一次、云端记录一次。因此,向本地 Mesh 网同步操作信息的同时,也需要向云端同步操作信息。
组成:设备类别值由 设备类型 + 大类 + 小类 组成后小端排列。
举例:
产品 | 类别值 | 说明 |
---|---|---|
标准五路灯 | 1510 | 小端转换后得到 1015:
|
标准四路插座 | 2410 | 小端转换后得到 1024:
|
透传型设备 | xx20 | 小端转换后得到 20xx:2 表示透传设备 |
蓝牙 Mesh 的主要操作类都在 ThingSmartBleMesh+SIGMesh.h
文件中。
一个家庭里可以拥有多个蓝牙 Mesh,但建议只创建一个 Mesh。创建前,判断是否已经创建。若尚未创建,可以通过此方法进行创建。
蓝牙 Mesh 中所有操作都建立在家庭数据已经初始化的基础上。完成初始化家庭操作,参考 家庭管理。
接口说明
+ (void)createSIGMeshWithHomeId:(long long)homeId
success:(void(^)(ThingSmartBleMeshModel *meshModel))success
failure:(ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
homeId | 家庭 ID |
success | 成功回调 |
failure | 失败回调 |
示例代码
Objective-C:
ThingSmartHome *home = #<上文初始化的 home 实例>;
long long homeId = home.homeModel.homeId;
[ThingSmartBleMesh createSIGMeshWithHomeId:homeId success:^(ThingSmartBleMeshModel *meshModel) {
// success do...
} failure:^(NSError *error) {
NSLog(@"create mesh error: %@", error);
}];
接口说明
删除蓝牙 Mesh 时,如果蓝牙 Mesh 组里有子设备,会被同时移除。
- (void)removeMeshWithSuccess:(ThingSuccessHandler)success failure:(ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
success | 成功回调 |
failure | 失败回调 |
示例代码
self.mesh = #<ThingSmartBleMesh 实例>;
[self.mesh removeMeshWithSuccess:^{
// success do...
} failure:^(NSError *error) {
XCTFail(@"test remove mesh failure: %@", error);
}];
接口说明
通过初始化 home
实例后,可以查询到对应家庭下的 mesh
列表。
- (void)getSIGMeshListWithSuccess:(void(^)(NSArray <ThingSmartBleMeshModel *> *list))success
failure:(ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
success | 成功回调 |
failure | 失败回调 |
示例代码
ThingSmartHome *home = #<home 实例>
[home getSIGMeshListWithSuccess:^(NSArray<ThingSmartBleMeshModel *> *list) {
// success do
} failure:^(NSError *error) {
NSLog(@"get Bluetooth mesh list error: %@", error);
}];
接口说明
+ (instancetype)bleMeshWithMeshId:(NSString *)meshId homeId:(long long)homeId;
参数说明
参数 | 说明 |
---|---|
meshId | 蓝牙 Mesh ID |
homeId | 家庭 ID |
示例代码
// 通过家庭(ThingSmartHome 实例)home 实例可以查询到类下的 sigMeshModel
ThingSmartBleMeshModel *sigMeshModel = [self getCurrentHome].sigMeshModel;
需要初始化蓝牙 Mesh 网络控制器,对蓝牙 Mesh 设备进行扫描、配网、连接等操作。
meshModel
需要传入 ThingSmartHome
中的 sigMeshModel
参数,而不是 meshModel
。
接口说明
+ (ThingSmartSIGMeshManager * _Nullable)initSIGMeshManager:(ThingSmartBleMeshModel *)meshModel
ttl:(NSInteger)ttl
nodeIds:(NSArray * _Nullable)nodeIds
参数说明
参数 | 说明 |
---|---|
meshModel | 蓝牙 Mesh Model |
ttl | 蓝牙 Mesh 网络中消息可被转发的次数,默认为 8 |
nodeIds | 蓝牙 Mesh 网络中所有设备的 nodeId ,不含低功耗节点 |
必须先通过 ThingSmartBleMesh
初始化蓝牙 Mesh 网络控制器,才能通过此方法获取。
接口说明
+ (ThingSmartSIGMeshManager * _Nullable)getSIGMeshManager:(NSString *)meshId;
参数说明
参数 | 说明 |
---|---|
meshId | 蓝牙 Mesh ID |
蓝牙 Mesh 的操作类集中在 ThingSmartSIGMeshManager
中。
默认上线策略为 ThingSIGMeshOnlineProfileMeshNetworkLogin
。
接口说明
typedef NS_ENUM(NSUInteger, ThingSIGMeshOnlineProfile) {
//连接蓝牙 Mesh 网后设备默认全部在线
ThingSIGMeshOnlineProfileMeshNetworkLogin,
//连接蓝牙 Mesh 网后查询设备在线状态
ThingSIGMeshOnlineProfileMeshQuery,
};
@interface ThingSIGMeshConfigModel : NSObject
@property (nonatomic, assign) ThingSIGMeshOnlineProfile onlineProfile;
@end
- (void)setConfig:(ThingSIGMeshConfigModel *)configModel;
需要连接蓝牙 Mesh 设备时,只需传入 ScanForProxyed
即可,详情请参考 配网 部分。
- (void)startScanWithScanType:(ThingSmartSIGScanType)scanType
meshModel:(ThingSmartBleMeshModel *)meshModel __deprecated_msg("This method is deprecated, Use startSearch instead");
- (void)startSearch;
配网指的是将处于重置状态、未入网的设备,添加到蓝牙 Mesh 网中。常用设备的重置方式如下表所示:
产品类型 | 照明 | 插座 |
---|---|---|
重置操作 | 连续开关 3 次 | 长按开关 3 秒 |
可配网现象 | 灯快闪 | 插座指示灯快闪 |
接口说明
开始扫描设备。扫描附近符合 SIG 标准的蓝牙设备。当扫描到周围有符合协议规范的待配网设备后,可以对这些设备进行配网。配网就是把未加入到蓝牙 Mesh 网络的蓝牙设备,通过一定的通讯过程将其加入到蓝牙 Mesh 网络中。
meshModel
需要传入 ThingSmartHome
中的 sigMeshModel
参数,而不是 meshModel
。
- (void)startScanWithScanType:(ThingSmartSIGScanType)scanType
meshModel:(ThingSmartBleMeshModel *)meshModel __deprecated_msg("This method is deprecated, Use startSearch instead");
- (void)startSearch;
参数说明
参数 | 说明 |
---|---|
scanType | 扫描类型。设备分为未配网设备和已配网设备,扫描到已配网设备则会自动入网。 |
meshModel | 蓝牙 Mesh model 信息。 |
示例代码
//[ThingSmartSIGMeshManager sharedInstance].delegate = self;
// ScanForUnprovision, // 扫描未配网设备
// ScanForProxyed, // 扫描已经配网的设备
//[[ThingSmartSIGMeshManager sharedInstance] startScanWithScanType:ScanForUnprovision
// meshModel:home.sigMeshModel];
ThingSmartSIGMeshManager *manager = [ThingSmartBleMesh getSIGMeshManager:@"meshId"];
manager.delegate = self;
[manager startSearch];
回调接口
扫描到设备后,可在 ThingSmartSIGMeshManagerDelegate
回调中实现以下方法,查询扫描到的设备。
// 扫描到待配网的设备
- (void)sigMeshManager:(ThingSmartSIGMeshManager *)manager
didScanedDevice:(ThingSmartSIGMeshDiscoverDeviceInfo *)device;
参数说明
参数 | 说明 |
---|---|
manager | 蓝牙 Mesh 的管理信息 |
device | 待配网设备信息 |
激活设备过程是标准的蓝牙 Mesh 配网过程。
接口说明
- (void)startActive:(NSArray<ThingSmartSIGMeshDiscoverDeviceInfo *> *)devList meshModel:(ThingSmartBleMeshModel *)meshModel __deprecated_msg("This method is deprecated, Use startActive: instead");
- (void)startActive:(NSArray<ThingSmartSIGMeshDiscoverDeviceInfo *> *)devList;
参数说明
参数 | 说明 |
---|---|
devList | 待激活设备列表 |
meshModel | 蓝牙 Mesh model 信息 |
接口说明
当某一设备激活成功或者失败会通过 ThingSmartSIGMeshManagerDelegate
回调以下方法。
激活子设备成功回调。
- (void)sigMeshManager:(ThingSmartSIGMeshManager *)manager
didActiveSubDevice:(ThingSmartSIGMeshDiscoverDeviceInfo *)device
devId:(NSString *)devId
error:(NSError *)error;
参数说明
参数 | 说明 |
---|---|
manager | 蓝牙 Mesh 的管理信息 |
device | 设备信息 |
devId | 设备 ID |
error | 激活中的错误,若发生错误,name 以及 deviceId 为空 |
接口说明
激活设备失败回调。
- (void)sigMeshManager:(ThingSmartSIGMeshManager *)manager
didFailToActiveDevice:(ThingSmartSIGMeshDiscoverDeviceInfo *)device
error:(NSError *)error;
参数说明
参数 | 说明 |
---|---|
manager | 蓝牙 Mesh 的管理信息 |
device | 设备信息 |
error | 激活过程中返回的错误码 |
在扫描设备和配网中任意阶段,调用以下方法,均会停止对蓝牙设备的配网流程。
接口说明
- (void)stopActiveDevice;
在操作的过程中,会经常判断是否是蓝牙 Mesh 已有设备通过蓝牙入网,来决定使用何种方式下发控制命令和操作命令。
// Mesh 本地连接标识,有设备通过蓝牙连接,此属性为 yes
//BOOL isLogin = [ThingSmartSIGMeshManager sharedInstance].isLogin;
BOOL isLogin = [ThingSmartBleMesh getSIGMeshManager:@"meshId"].isLogin;
蓝牙 Mesh 网关激活子设备。参考 激活子设备。
错误码 | 说明 |
---|---|
701 | 连接错误 |
702 | Composition 回复错误 |
703 | Composition 超时 |
704 | 添加 appkey 失败 |
705 | 添加 appkey 超时 |
706 | network transmit 回复错误 |
707 | network transmit 超时 |
708 | publication model 回复错误 |
709 | publication model 超时 |
710 | 添加 bind 回复错误 |
711 | 添加 bind 超时 |
712 | IdentifySet 超时 |
设备类是 ThingSmartDevice
,里面的 ThingSmartDeviceModel
中的 deviceType
信息可以区分设备类型。其中,Mesh 设备对应 deviceType
类型为 ThingSmartDeviceModelTypeSIGMeshSubDev
。
接口说明
+ (instancetype)deviceWithDeviceId:(NSString *)devId;
参数说明
参数 | 说明 |
---|---|
devId | 设备 ID |
手机蓝牙开启且 Mesh 设备通过蓝牙进行连接控制,下发命令通过蓝牙完成。判断条件为 deviceModel.isOnline && deviceModel.isMeshBleOnline
。
手机蓝牙未开启或距离设备远,Mesh 设备通过网关进行连接控制,下发命令通过 Wi-Fi 完成。判断条件为 deviceModel.isOnline && !deviceModel.isMeshBleOnline
。
接口说明
- (void)getDeviceStatusWithDeviceModel:(ThingSmartDeviceModel *)deviceModel;
参数说明
参数 | 说明 |
---|---|
deviceModel | 设备 model |
移除设备已经简化,所有的设备移除都保持一致。更多信息,参考 移除设备。
在蓝牙 Mesh 网中,可以将一些设备组成群组,使用群组命令控制群组中的设备。例如,将所有灯组添加到某个群组中,通过控制群组的开关、颜色等,直接控制群组中所有的灯具有相同的属性。
对于蓝牙 Mesh 群组的添加,为了保证功能一致,建议同一品类的设备添加进群组。在添加群组之前,可以调用 ThingSmartBleMeshGroup
的以下方法,从服务端查询群组地址。
接口说明
+ (void)getBleMeshGroupAddressFromCluondWithMeshId:(NSString *)meshId
success:(ThingSuccessInt)success
failure:(ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
meshId | 蓝牙 Mesh ID |
success | 成功回调 localId 的 10 进制 |
failure | 失败回调 |
从服务端返回的群组地址需要加上 0x4000
之后,调用即可获得当前 sigMeshModel
下的一个以 groupName
命名的群组。
接口说明
+ (void)createMeshGroupWithGroupName:(NSString *)groupName
meshId:(NSString *)meshId
localId:(NSString *)localId
pcc:(NSString *)pcc
success:(ThingSuccessInt)success
failure:(ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
groupName | 蓝牙 Mesh 群组名字 |
meshId | Mesh ID |
localId | 群组的本地短地址,为 2 字节的 16 进制字符 |
pcc | 群组设备大小类 |
success | 成功回调,返回群组 ID |
failure | 失败回调 |
接口说明
如果需要将某个设备加入群组中,需要调用 ThingSmartSIGMeshManager
以下方法。
- (void)addDeviceToGroupWithDevId:(NSString *)devId
groupAddress:(uint32_t)groupAddress;
参数说明
参数 | 说明 |
---|---|
devId | 设备 ID |
groupAddress | 群组地址 |
回调接口
// ThingSmartSIGMeshManagerDelegate 回调
- (void)sigMeshManager:(ThingSmartSIGMeshManager *)manager
didHandleGroupWithGroupAddress:(nonnull NSString *)groupAddress
deviceNodeId:(nonnull NSString *)nodeId
error:(NSError *)error;
参数说明
参数 | 说明 |
---|---|
manager | 管理信息 |
groupAddress | 群组蓝牙 Mesh 地址,16 进制 |
nodeId | 设备蓝牙 Mesh 节点地址,16 进制 |
error | 错误回调 |
接口说明
通过网关向蓝牙 Mesh 群组内加子设备,可以通过 ThingSmartBleMeshGroup
进行操作。通过蓝牙 Mesh 网关添加蓝牙 Mesh 子设备群组,需要保证子设备的关系归属在蓝牙 Mesh 网关下。
- (void)addSubDeviceWithSubList:(NSArray<ThingSmartDeviceModel *> * _Nonnull )subList success:(nullable ThingSuccessHandler)success failure:(nullable ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
subList | 待操作的网关下子设备 |
success | 操作成功回调 |
failure | 操作失败回调 |
ThingSmartBleMeshGroupDelegate
回调
@protocol ThingSmartBleMeshGroupDelegate <NSObject>
/// 蓝牙 Mesh 设备加入到网关的群组响应
/// 1:超过场景数上限,2:子设备超时,3:设置值超出范围,4:写文件错误,5:其他错误
- (void)meshGroup:(ThingSmartBleMeshGroup *)group addResponseCode:(NSArray <NSNumber *> *)responseCode;
@end
接口说明
- (void)deleteDeviceToGroupWithDevId:(NSString *)devId groupAddress:(uint32_t)groupAddress;
参数说明
参数 | 说明 |
---|---|
devId | 设备 ID |
groupAddress | 群组地址 |
ThingSmartSIGMeshManagerDelegate
回调
- (void)sigMeshManager:(ThingSmartSIGMeshManager *)manager
didHandleGroupWithGroupAddress:(nonnull NSString *)groupAddress
deviceNodeId:(nonnull NSString *)nodeId
error:(NSError *)error;
参数说明
参数 | 说明 |
---|---|
manager | 管理信息 |
groupAddress | 群组蓝牙 Mesh 地址,16 进制 |
nodeId | 设备蓝牙 Mesh 节点地址,16 进制 |
error | 错误 |
接口说明
通过网关向蓝牙 Mesh 群组内删除设备,可以通过 ThingSmartBleMeshGroup
进行操作。通过蓝牙 Mesh 网关删除蓝牙 Mesh 子设备群组,需要保证子设备的关系归属在蓝牙 Mesh 网关下。
- (void)removeSubDeviceWithSubList:(NSArray<ThingSmartDeviceModel *> * _Nonnull )subList success:(nullable ThingSuccessHandler)success failure:(nullable ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
subList | 待操作的网关下子设备 |
success | 操作成功回调 |
failure | 操作失败回调 |
ThingSmartBleMeshGroupDelegate
回调
// ThingSmartBleMeshGroupDelegate 回调
@protocol ThingSmartBleMeshGroupDelegate <NSObject>
/// 蓝牙 Mesh 设备从网关群组移除响应
/// 1:超过场景数上限,2:子设备超时,3:设置值超出范围,4:写文件错误,5:其他错误
- (void)meshGroup:(ThingSmartBleMeshGroup *)group removeResponseCode:(NSArray <NSNumber *> *)responseCode;
@end
类名 | 说明 |
---|---|
ThingSmartBleMeshGroup | 群组类 |
接口说明
若添加或删除成功或者失败,可以通过代理方法收到结果。同时,使用 group
实例进行群组内设备关系变更云端同步。
// 添加设备
- (void)addDeviceWithDeviceId:(NSString *)deviceId success:(ThingSuccessHandler)success failure:(ThingFailureError)failure;
// 删除设备
- (void)removeDeviceWithDeviceId:(NSString *)deviceId success:(ThingSuccessHandler)success failure:(ThingFailureError)failure;
接口说明
调用 ThingSmartSIGMeshManager
以下方法,并配合回调(需固件支持),通过群组地址查询群组中的设备。
- (void)queryGroupMemberWithGroupAddress:(uint32_t)groupAddress;
// 回调
- (void)sigMeshManager:(ThingSmartSIGMeshManager *)manager
queryDeviceModel:(ThingSmartDeviceModel *)deviceModel
groupAddress:(uint32_t)groupAddress;
参数说明
参数 | 说明 |
---|---|
groupAddress | 群组地址 |
由于涂鸦使用 DP 管理设备的功能,因此,蓝牙 Mesh 相关的控制是根据设备的 DP 信息来进行操作。
发送控制指令按照以下格式:{"(dpId)" : "(dpValue)"}
,例如 @{@"101" : @"44"}
。
涂鸦对指令下发进行了简化处理,您无需关注是网关连接、还是本地连接。只要设备在线,就可以下发。
接口说明
// ThingSmartDevice
- (void)publishDps:(NSDictionary *)dps
success:(nullable ThingSuccessHandler)success
failure:(nullable ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
dps | DP 的字典表达格式 |
success | 成功回调 |
failure | 失败回调 |
接口说明
// ThingSmartBleMeshGroup
- (void)publishDps:(NSDictionary *)dps success:(nullable ThingSuccessHandler)success failure:(nullable ThingFailureError)failure;
参数说明
参数 | 说明 |
---|---|
dps | DP 的字典表达格式 |
success | 成功回调 |
failure | 失败回调 |
从 v3.35.5 开始,设备固件升级方式统一。您可以移步 设备管理-固件升级,了解新的升级方法,从而简化升级过程。
接口说明
// 通过 ThingSmartDevice 实例进行查询
- (void)getFirmwareUpgradeInfo:(void (^)(NSArray <ThingSmartFirmwareUpgradeModel *> *upgradeModelList))success failure:(ThingFailureError)failure;
/*
升级的信息会通过结果值返回,可以根据 type 信息去确定是否需要升级
0:升级中
1:无升级
2:有强制或提醒升级
3:有检测升级
// 判断为需要升级后,具体的固件地址在返回值中,下载之后转成固件 data 进行后续操作
*/
参数说明
参数 | 说明 |
---|---|
success | 成功回调 |
failure | 失败回调 |
蓝牙 Mesh 低功耗设备升级之前需要唤醒,不同设备的唤醒方式不同。
子设备升级都是通过蓝牙升级,所以需要判断设备是否处于本地连接。确认本地在线后,再进行后续操作。
BOOL isBLEOnline = device.deviceModel.isMeshBleOnline;
每次都是一对一地升级。
[ThingSmartSIGMeshManager sharedInstance].delegate = self;
[[ThingSmartSIGMeshManager sharedInstance] prepareForOTAWithTargetNodeId:self.device.deviceModel.nodeId];
// ThingSmartSIGMeshManagerDelegate
- (void)notifySIGLoginSuccess {
[ThingSmartSIGMeshManager sharedInstance].delegate = nil;
//weakify(self);
[[ThingSmartSIGMeshManager sharedInstance] startSendOTAPack:_otaData targetVersion:_upgradeModel.version success:^{
//strongify(self);
// 更新版本号
[self updateVersion];
} failure:^{
// log error
}];
}
- (void)updateVersion {
[self.device updateDeviceVersion:_upgradeModel.version type:_upgradeModel.type success:^{
// ota success
} failure:^(NSError *error) {
// log error
}];
}
蓝牙 Mesh 网关升级和普通的设备升级一样。详情请参考 固件升级。
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈