# BeaconPlus iOS开发套件说明
- 持续更新中... 本套SDK仅支持基于miniBeaconPlus固件的设备,不再支持其他公司生产的产品。相对于之前的单一通道设备SDK来说,现在的这一套BeaconSET+ SDK支持的特性更多。当然开发过程中也遇到过诸多问题,我们会在本文档说明设计缘由以及注意事项。所以,请仔细阅读此文档以便尽快上手进行项目开发。
请按需阅读以下每个部分,第一部分我们会说明这套SDK的整体架构,第二部分会帮助开发者上手开发,第三部分会提及开发过程中的注意事项,第四部分可以查阅到错误码的对应说明。
# 设计说明
我们在SDK里把手机对设备的操作分成了两个阶段:广播阶段和连接阶段。为了便于理解,我们先来看看我们都提供了哪些可以操作的类以及它们的职责:
MTCentralManager: 全局管理,可以检查当前手机的蓝牙状态,监听系统的蓝牙状态改变。另外最重要的是可以扫描以及连接到这些设备;
MTPeripheral: 设备实例,当CentralManager发现一个新设备时,会对应为其生成一个MTPeripheral实例,以真实的物理设备为单位,一个设备对应一个MTPeripheral实例。它包括了MTConnectionHandler和MTFrameHandler两个属性(下文会继续描述这两个属性的作用)。
*MTFrameHandler:*广播包解析,这个类可以解析某个设备所广播出来的所有数据包,也就是说,它是扫描阶段的核心,所有由MTCentralManager扫描出来的广播数据都由它来解析成对应的数据帧实例。
*MTConnectionHandler:*连接状态操作,所有连接上设备后发生的操作都是由此类完成,包括监听连接状态改变,读取数据,写入数据等。
*MTSensorHandler:*传感器操作,所有连接上设备后发生的传感器操作都是由此类完成,包括读取温湿度和设置红外参数。
*MinewFrame:*数据帧,每个此类(或者子类)实例都对应一种数据帧,一般会由MTFrameHandler生成,如果设备正在广播多种数据帧,就会生成多个对应的MinewFrame实例。这些实例可以通过MTFrameHandler获取到。
*MTOTAManager:*空中升级,此类只能用来更新设备固件,它操作的是MTConnectionHandler实例。
# 整体架构:
# 广播阶段
这个阶段主要是扫描周围的miniBeaconPlus设备和解析这些设备上的广播数据,首先MTCentralManager发起扫描,MTCentralManager会为每一个物理设备生成一个MTPeripheral实例,开发者可以通过它的MTFrameHandler属性拿到关于此设备的所有广播数据。
# 连接阶段
当MTCentralManager扫描到物理设备并生成MTPeripheral实例后,就可以连接到设备,此时针对设备的连接操作都是通过MTConnectionHandler来完成的。
# OTA单独说明
常规的OTA逻辑比较复杂,所以单独封装了MTOTAManager来执行OTA操作,必须在已经和设备建立连接的状态下才能进行。
# 开始上手
# 准备工作
# 开发环境:
Xcode9+,由于使用的DFU和Zip框架基于Swift4.0开发,所以请使用Xcode9及更高版本进行开发;
iOS8,限制最低系统版本为iOS8;
# 导入到工程
# 手动导入
- 将开发套件的三个framework文件:MTBeaconPlus.framework, iOSDFULibrary.framework, Zip.framework拷贝到项目工程目录下,然后添加到工程中,target为当前的工程,然后点“Add”,如下图所示:
依次找到:“Target” -> General -> Embedded Binaries,点击下面的“+”,将上述3个Framework文件添加进来,同样的,也需要添加到 ”Linked Frameworks and Libraries“,添加完应该如下图:
*如果使用Swift开发,需要添加一个Objective C BridgingHeader .h文件(此处不再赘述),并且在此文件添加:import <MTBeaconPlus/MTBeaconPlus.h>,如果使用Objective C进行开发,在需要的文件的顶端添加:import <MTBeaconPlus/MTBeaconPlus.h>
*如果使用Objective-C开发,则需要在“Target” -> Building Settings -> Always Embed Swift Standard Libraries" 设置为YES。
!!!在iOS10及以上版本,苹果对蓝牙APi添加了权限限制,你需要在工程的info.plist文件里添加一项字符串:Privacy - Bluetooth Peripheral Usage Description - "你的使用描述"。如下图所示:
- !!!在iOS13及以上版本,苹果对蓝牙APi添加了权限限制,你需要在工程的info.plist文件里添加一项字符串:Privacy - Bluetooth Always Usage Description - "你的使用描述"。
# 开始开发
# 获取管理类单例
首先开发者需要获取一个管理类单例,并且做好开发者需要的监听:
// 获取管理类单例
MTCentralManager *manager = [MTCentralManager sharedInstance];
// 如果需要监听系统蓝牙状态变化请这样做
// *** 还可以通过state属性主动获取
// *** 仅当state == PowerStatePoweredOn时开发套件才可正常工作
manager.stateBlock = ^(PowerState state) {
NSLog("当前系统蓝牙状态:%d",state);
};
2
3
4
5
6
7
8
9
# 扫描设备
需要通过扫描来发现附近的设备,这样才能获取它们的广播内容,连接并修改设备参数等。
/*
manager: MTCentralManager的单例
*/
// 执行扫描方法
[manager startScan:^(NSArray<MTPeripheral *> *peris){
// 遍历数组,获取每个设备实例
// 也可以把它们绑定到UI上,将所有数据显示出来。
for(NSInteger i = 0; i < peris.count; i ++){
MTPeripheral *peri = peris[i];
// 获取设备广播阶段实例
// 部分属性可能为空,请参见“注意事项”
MTFrameHandler *framer = peri.framer;
NSString *name = framer.name; // 设备名, 可能为空
NSInteger rssi = framer.rssi; // rssi
NSInteger battery = framer.battery; // 电池,可能为空
NSString *mac = framer.mac; // mac地址, 可能为空
NSArray *frames = framer.advFrames; // 设备广播的所有数据帧(iBeacon,UID,URL...)
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
另外,你可以在任何时候停止扫描任务。
/*
manager: MTCentralManager的单例
*/
// 通过这种方式停止扫描
[manager stopScan];
2
3
4
5
6
通过以上方式我们就可以获取到设备在广播阶段的所有相关数据,进一步的,想要从frameHandler里获取到所有的数据帧,可以参考以下代码示例:
/*
aFrameHandler: MTFrameHandler实例,
*/
NSArray *frames = aFrameHandler.advFrames;
for (NSInteger i = 0; i < frames.count; i ++){
MinewFrame *frame = frames[i];
switch(frame.frameType){
case FrameiBeacon:
{
MinewiBeacon *bea = (MinewiBeacon *)frame;
NSLog(@"iBeacon:%@, %ld, %ld, %@",bea.uuid, bea.major, bea.minor, bea.lastUpdate);
}
break;
case FrameUID:
{
MinewUID *uid = (MinewUID *)frame;
NSLog(@"UID:%@, %@, %ld, %@", uid.namespaceId, uid.instanceId, uid.txPower, uid.lastUpdate);
}
break;
case FrameDeviceInfo:
{
MinewDeviceInfo *info = (MinewDeviceInfo *)frame;
NSLog(@"DeviceInfo: %ld, %@, %@, %@", (long)info.battery, info.mac, info.name, info.lastUpdate);
}
break;
case FrameTLM:
{
MinewTLM *tlm = (MinewTLM *)frame;
NSLog(@"TLM: %ld, %f, %ld, %ld, %@", tlm.batteryVol, tlm.temperature, tlm.advCount, (long)tlm.secCount, tlm.lastUpdate);
}
break;
case FrameURL:
{
MinewURL *url = (MinewURL *)frame;
NSLog(@"URL: %ld, %@, %@", url.txPower, url.urlString, url.lastUpdate);
}
break;
case FrameLineBeacon:
{
MinewLineBeacon *lineBeacon = (MinewLineBeacon *)frame;
// 如果需要获取 vendorKey和lotKey,需要连接后进行操作,具体操作请参考“获取各通道数据”部分。
NSLog(@"LineBeacon:%@, %@, %@, %ld, %@", lineBeacon.hwId, lineBeacon.authenticationCode, lineBeacon.timestamp, lineBeacon.txPower, lineBeacon.lastUpdate);
}
break;
/*
更多类型,请自行处理
*/
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
**重要提示:**在获取所有的传感器数据时,如果值等于MTNAValue(我们定义的无效值常量,在"MTPublicHeader.h“文件中),表示这个数据是无效的。所有的传感器实例(MinewHTSensor,MinewLightSensor,MinewAccSensor,MinewForceSensor,MinewPIRSensor)都有这种情况。
请参考以下代码:
/*
aHT: MinewHTSensor实例
aLight: MinewLightSensor实例
aAcc: MinewAccSensor实例
aForce: MinewForceSensor实例
aPIR: MinewPIRSensor实例
*/
if (aHT.temperature == MTNAValue) {
NSLog(@"this value is not available.")
}
if (aLight.luxValue == MTNAValue) {
NSLog(@"this value is not available.")
}
if (aAcc.XAxis) {
NSLog(@"this value is not available.")
}
if (aForce.gramValue) {
NSLog(@"this value is not available.")
}
if (aPIR.gramValue) {
NSLog(@"this value is not available.")
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 连接设备
要对设备进一步操作(修改参数,OTA),需要先连接到设备。由于有些设备在连接时可能需要密码验证,所以验证密码的Block为必须实现,否则将引起Crash!!! 如下代码所示:
/*
manager: MTCentralManager的单例
aMTPeripheral: MTPeripheral实例
*/
// 监听设备连接状态改变
aMTPeripheral.connector.statusChangeHandler = ^(ConnectionStatus status, NSError *error) {
/*
typedef NS_ENUM(NSInteger, ConnectionStatus) {
StatusConnectFailed = -2,
StatusDisconnected = -1,
StatusUndifined = 0,
StatusConnecting,
StatusConnected,
StatusReadingInfo,
StatusDeviceValidating,
StatusPasswordValidating,
StatusSycingTime,
StatusReadingConnectable,
StatusReadingFeature,
StatusReadingFrames,
StatusReadingTriggers,
StatusReadingSensorInfo,
StatusCompleted,
};
*/
// 整个连接过程需要经过多个中间状态,如果遇到错误,会通过error抛出
// 只有当status == StatusCompleted时,才算是连接成功
};
// 连接到设备
// 需要一个MTPeripheral实例作为参数
// !!!:特别提醒:passwordRequire为必须实现的
[manager connectToPeripheral:aMTPeripheral passwordRequire:^(MTPasswordBlock passwordBlock){
// 给定一个8位长度的密码,
// !!! 实际开发中应该从UITextField读取输入的内容作为密码。
NSString *password = @"minew123";
passwordBlock(password);
}];
// 断开某个设备的连接状态
[manager disconnectFromPeriperal:aMTPeripheral];
/*
**/
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 获取基本信息
成功连接到设备后,就可以获取设备信息以及修改设备参数了。我们先来看看怎么获取各种基础数据。
/*
aMTPeripheral: MTPeripheral实例
*/
MTConnectionHandler *con = aMTPeripheral.connector;
ConnectionStatus conSte = con.status; // 当前的设备连接状态
NSDictionary *infoDict = con.infoDict; // 设备信息,例如:(Firmware Version: 0.9.1);
NSString *mac = con.macString; // mac地址;
Connectable able = con.connectable; // 标记设备是否可以连接,None未知,No不可连,Yes可连
Version version = con.version; // 固件版本枚举,方便处理版本号区分;
PasswordStatus pwdStatus = con.passwordStatus; // 连接时是否需要密码,None不需要,Require需要
MTConnectionFeature *feature = con.feature; // 设备特性;
NSInteger slotAtitude = feature.slotAtitude; // 设备的广播通道数量,可以根据此动态生成UI;
FeatureSupported feaSup = feature.featureSupported; // 可以调节参数类型:none不可调,adv可调,txpower可调,adv/txpower均可调
NSArray<NSNumber *> *supFrames = feature.supportedSlots; // 支持的广播帧类型(多种)
NSArray<NSNumber *> *supTxpower = feature.supportedTxpowers; // 支持的Txpower(多档位)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PS: MTConnectionHandler的Version属性说明:
Versoin值来自设备的固件版本号,可以通过检查Version的值来判断当前设备支持的功能:
// 初始化值
VersionUndefined
// 基础版本,仅支持基础功能
VersionBase
// 此版本及以上支持自定义连接密码 / 设备信息广播帧
Version0_9_8
// 此版本及以上支持远程关机命令
Version0_9_9
// 此版本及以上开始支持触发器
Version2_0_0
// 此版本及以上开始支持带广播设置的触发器配置
Version2_2_60
// 理想值,支持所有特性。
VersionMax = 1000
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 获取各通道数据
接下来可以获取每个通道对应的参数数据,之所以单独讲这部分,是因为所有与修改相关的内容全部在这里。
在阅读代码之前,我们先来了解通道的概念:通道相当于一个广播工具,它不管里面是什么内容,只管把内容广播出来,例如一个6通道的设备可能是这样的:
通道序号 | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
广播内容 | iBeacon | TLM | UID | URL | HTSensor | None |
广播间隔(ms) | 1000 | 2000 | 500 | 900 | 3000 | 0 |
RSSI@0/1m(dbm) | -1 | 0 | -4 | -10 | -3 | 0 |
信号强度(dbm) | 4 | 0 | -4 | 4 | 0 | 0 |
上表的意思是,第0个通道广播iBeacon数据,第1个通道广播TLM数据,…,第5个通道不广播任何数据。它们每个都有独立的广播间隔,信号强度和校准值,互相之间没有关系也不产生任何影响。
PS:校准值(RSSI@0/1m)指的是手机在设备0/1m(iBeacon为1,其它为0)处的信号强度。
接下来我们来看下怎么获取设备的通道数据。
/*
con: MTConnectionHandler实例
*/
// 当前设备每一个通道对应的数据帧
// 此数组的数量和通道数量保持一致(也就是feature.slotAtitude)
// 按照通道顺序严格排序,比如:0. -> MinewiBeacon,1. -> MinewUID ...
NSArray<MinewFrame *> *frames = con.allFrames;
/*
假如第3个通道为iBeacon数据,第4个通道数据为UID,
我们尝试解析第3个通道的数据。
*/
// 由于默认指针是MinewFrame(MinewiBeacon的父级)类型,需要做一下转换。
// 获取第3个通道的数据帧
MinewFrame *frame = frames[2];
// 确认此通道是iBeacon类型,如果类型确认,可以不需要做这一步判断
switch (frame.frameType) {
case FrameiBeacon:
{
MinewiBeacon *iBeacon = (MinewiBeacon *)frame;
// iBeacon数据
NSString *uuid = iBeacon.uuid; // 获取uuid
NSInteger major = iBeacon.major; // 获取major
NSInteger minor = iBeacon.minor; // 获取minor
// 所处通道的参数
NSInteger slotNumber = iBeacon.slotNumber; // 第几通道
NSInteger slotAdvInterval = iBeacon.slotAdvInterval; // 此通道的广播间隔
NSInteger slotAdvTxpower = iBeacon.slotAdvTxpower; // 此通道的信号校准值 iBeacon:RSSI@1m others: RSSI@0m
NSInteger slotRadioTxpower = iBeacon.slotRadioTxpower; // 此通道信号强度
}
break;
case FrameURL:
{
MinewURL *url = (MinewURL *)frame;
NSString *urlStr = url.urlString;
// 所处通道的参数获取方式均一致
}
break;
case FrameUID:
{
MinewUID *uid = (MinewUID *)frame;
NSString *namespaceId = uid.namespaceId;
NSString *instanceId = uid.instanceId;
// 所处通道的参数获取方式均一致
}
break;
case FrameLineBeacon:
{
// LineBeacon(获取方式较为特殊)
MTLineBeaconData *lineBeaconData = self.currentPeripheral.connector.slotHandler.slotFrameDataDic[FrameTypeString(FrameLineBeacon)];
NSString *hwid = lineBeaconData.hwId;
NSString *vendorKey = lineBeaconData.vendorKey;
NSString *lotKey = lineBeaconData.lotKey;
// 所处通道的参数获取方式均一致
}
break;
/*
如有需要,可自行处理其他类型的数据。
*/
default:
break;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
你可以使用同样的方式来解析其它所有通道,值得注意的是,当frameType == FrameNone 时,说明此通道没有广播数据。
# 修改通道数据
通过我们的开发套件,开发者可以自由的修改每个通道的广播数据。
我们区分了静态数据帧和动态数据帧,静态数据帧指的是广播数据不会发生变化的:iBeacon,UID,URL等等,动态数据帧指的是广播数据不定时发生变化的:TLM,各类传感器数据等。
可以通过下面的参考代码实现。
/*
aConnectionHandler: MTConnectionHandler实例
*/
// 生成一个uid实例
MinewUID *uid = [[MinewUID alloc]init];
// 配置uid的namespaceId和instanceId参数
uid.namespaceId = @"0123456789abdcdcba12";
uid.instanceId = @"0123456789dc";
// 通道相关配置
uid.slot = 1; // 设置想要配置的通道序号
uid.slotAdvInterval = 600; // 配置这个通道的广播间隔
uid.slotAdvTxpower = -3; // 配置这个通道的信号校准值 RSSI@0m
uid.slotRadioTxpower = 4; // 配置这个通道的广播功率
// 写入到设备
// 详情:1.把1通道设置为UID广播,namespaceId:0123456789abdcdcba12,instanceId:0123456789dc
// 2.设置1通道的广播间隔为600ms,RSSI@0m为-3dbm,广播功率为:4dbm
[aConnectionHandler writeFrame:uid completion:^(BOOL success, NSError *error){
if (success) {
NSLog(@"write frame to device successfully.");
}
else if(error) {
NSLog(@"Error:%@", error)
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
请注意,以下通道参数设置必须在范围内:
- 广播间隔: 100 - 5000 (ms)
- RSSI@0m: -127 - 0 (dbm)
重要提醒: 广播功率是档位值, 例如: -8, -4, 0, 4. 你可以通过"MTConnectionHandler"的feature属性里获取到当前设备支持的所有广播功率档位:
/*
feature: MTConnectionHandler实例的属性.
*/
// 获取当前设备支持的所有广播功率档位.
NSArray<NSNumber *> *supTx = feature.supportedTxpowers
2
3
4
5
6
你可以通过相同的方式修改任何一个通道的广播数据,如果需要关闭某个通道,只需要创建一个frameType=FrameNone的MinewFrame对象写入到设备即可,当然,别忘了设置通道序号。
# 设置 LineBeacon
LineBeacon 帧需要在写入帧数据的方法之后,另外调用以下两个方法设置LineBeacon的hwid,vendorKey和lotKey
// lotKey:16位, hwid:10位,vendorKey:8位,包含a-f/A-F/0-9
// 设置 LineBeacon 的 lotKey
[self.currentPeripheral.connector.slotHandler lineBeaconSetLotkey:@"0011223344556677" completion:^(BOOL success) {
if (success) {
NSLog(@"Set LineBeacon's lotKey success");
} else {
NSLog(@"Set LineBeacon's lotKey failed");
}
}];
// 设置 LineBeacon 的 hwid 和 vendorKey
[self.currentPeripheral.connector.slotHandler lineBeaconSetHWID:@"0011223344" VendorKey:@"00112233" completion:^(BOOL success) {
if (success) {
NSLog(@"Set LineBeacon's hwid and vendorKey success");
} else {
NSLog(@"Set LineBeacon's hwid and vendorKey failed");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 修改设备全局参数
设备全局参数指的是设备级的一些特性,比如:配置设备是否可连接,是否需要密码,恢复出厂等。
可以通过以下代码示例参考。
/*
aConnectionHandler: MTConnectionHandler实例
*/
// 恢复出厂设置
[aConnectionHandler resetFactorySettings:^(BOOL success, NSError *error){
if(success){
NSLog(@"Operation success!");
}
else {
NSLog(@"Opertion failed!");
}
}];
// 更新设备可连接设置
// YES为可连接,NO不可连接,
// 配置设备不可连接后,可以通过按下设备上的按钮再次连接到设备。
// !!!:如果设备上没有按钮,且把设备配置为不可连后,设备将无法再次被连接。
[aConnectionHandler updateConnectable:YES completion:^(BOOL success, NSError *error){
if(success){
NSLog(@"Operation success!");
}
else {
NSLog(@"Opertion failed!");
}
}];
// 修改/增加密码
// !!!: 只能设置8位密码,数字或英文字母;
// 设备没有密码时,会添加密码,设备有密码时,会更新密码。
[aConnectinoHandler modifyPassword:@"12345678" completion:^(BOOL success, NSError *error){
if(success){
NSLog(@"Operation success!");
}
else {
NSLog(@"Opertion failed!");
}
}];
// 移除密码
[aConnectionHandler removePassword:^(BOOL success, NSError *error){
if(success){
NSLog(@"Operation success!");
}
else {
NSLog(@"Opertion failed!");
}
}];
// 远程关闭设备
// !!!:请确认设备上有按钮,可以通过按下按钮的方式重启,否则关闭后无法重启设备。另外Model Number如果是 Beacon Plus-BL,那么关闭设备会失效,不支持该功能。
[aConnectionHandler poweroff:^(BOOL success, NSError *error){
if(success){
NSLog(@"Operation success!");
}
else {
NSLog(@"Opertion failed!");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# 设备上的传感器数据
BeaconPlus设备整合了温湿度,光感,加速度等多种传感器,目前我们提供了温湿度/六轴/磁力计/大气压力历史数据的读取接口和红外传感器参数设置接口。
请确认此设备带有温湿度传感器,否则无法正确获取数据。
可以通过以下代码示例参考。
/*
aConnectionHandler: MTConnectionHandler实例
*/
// 从设备上读取温湿度数据
[aConnectionHandler.sensorHandler readSensorHistory:^(MTSensorData *data){
NSInteger time = ((MTSensorHTData *)data).timestamp; // 此数据的Unix时间戳;
double temp = ((MTSensorHTData *)data).temperature; // 温度数据;
double humi = ((MTSensorHTData *)data).humidity; // 湿度数据;
NSInteger index = ((MTSensorHTData *)data).index; // 此数据的编号;
if (((MTSensorHTData *)data).endStatus == EndStatusNone){
NSLog(@"there is no data.");
}
else if (((MTSensorHTData *)data).endStatus == EndStatusSuccess) {
NSLog(@"sensor data sync successfully!");
}
else if (((MTSensorHTData *)data).endStatus == EndStatusError) {
NSLog(@"something wrong in syncing progress.");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
你可以用表格或者曲线的方式把这些数据生动的呈现出来。
请确认此设备带有红外传感器,否则无法正确获取数据。
可以通过以下代码示例参考。
/*
aConnectionHandler: MTConnectionHandler实例
aRepeat:是否允许重复触发
aTime:触发时间,过了触发时间后才可以再次触发红外传感器
*/
// 设置设备红外传感器数据
[aConnectionHandler.sensorHandler pirSet:aRepeat andDelayTime:aTime completion:^(MTSensorData *data){
if (data.status) {
NSLog(@"success");
}
else {
NSLog(@"failed");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 配置触发器
BeaconPlus设备加入了触发器功能,你可以给每个通道独立的配置触发器,仅当满足触发条件时设备才会开启对应通道进行广播,否则,对应通道将会一直处于关闭状态。
可以通过以下代码示例参考。
NSInteger slotAtitude = 2; // 目标通道:2
TriggerType type = TriggerTypeTempAbove; // 触发条件:温度高于
NSInteger value = 10; // 触发值:10
MTTriggerData *trigger = [[MTTriggerData alloc] initWithSlot:slotAtitude paramSupport:true triggerType:type value:value];
// 如果需要触发后持续广播
trigger.always = true; // 触发后是否持续广播
trigger.advInterval = 100; // 广播时间间隔
trigger.radioTxpower = -20; // 广播信号强度
// 写入到设备
[self.connectedPeripheral.connector writeTrigger:trigger completion:^(BOOL success) {
if(success){
NSLog(@"write trigger successfully!");
}
else {
NSLog(@"write trigger failed!");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 振动传感器的其他相关配置
设置和查询是否开启振动,开启振动才会收到振动传感器的广播帧,关闭振动则停止广播振动传感器广播帧
// MTVibrationTypeOpen,
// MTVibrationTypeClose,
// MTVibrationTypeError,
[self.currentPeripheral.connector.sensorHandler setVibrationStatus:MTVibrationTypeOpen CompletionHandler:^(BOOL isSuccess) {
}];
[self.currentPeripheral.connector.sensorHandler queryVibrationStatu:^(BOOL isSuccess, MTVibrationType type) {
}];
2
3
4
5
6
7
8
9
10
11
12
设置和查询振动传感器灵敏度
// MTSensitivityTypeSuperHigh,
// MTSensitivityTypeHigh,
// MTSensitivityTypeMiddle,
// MTSensitivityTypeLow,
// MTSensitivityTypeSuperLow,
[self.currentPeripheral.connector.sensorHandler setSensitivity:MTSensitivityTypeHigh CompletionHandler:^(BOOL isSuccess) {
}];
[self.currentPeripheral.connector.sensorHandler querySensitivity:^(BOOL isSuccess, MTSensitivityType type) {
}];
2
3
4
5
6
7
8
9
10
11
12
13
设置和查询振动传感器警告时间区间,开始时间需小于结束时间,精确到时分。 另外,参数需要进行计算,以秒为单位,比如早上六点十分到晚上十点,startTime = 6 * 3600 + 10 * 60 = 22200,endTime = 22 * 3600 + 0 * 60 = 79200.
// timeZone = hours*3600 + minutes*60
// 22200 = 6*3600 + 10*60 = 6:30
[self.currentPeripheral.connector.sensorHandler setFirstAlarmTimeIntervalWithAlarmStatus:MTVibrationTypeOpen StartTime:22200 EndTime:79200 CompletionHandler:^(BOOL isSuccess) {
}];
[self.currentPeripheral.connector.sensorHandler queryFirstAlarmTimeInterval:^(BOOL isSuccess, MTVibrationType type, uint32_t startTime, uint32_t endTime) {
NSLog(@"vibrationType:%@, startTime:%dhour %dminute, endTime:%dhour %dminute", type == MTVibrationTypeOpen ? @"Open" : @"Close or Error", startTime/3600, startTime%3600/60, endTime/3600, endTime%3600/60);
}];
[self.currentPeripheral.connector.sensorHandler setSecondAlarmTimeIntervalWithAlarmStatus:MTVibrationTypeOpen StartTime:22200 EndTime:79200 CompletionHandler:^(BOOL isSuccess) {
}];
[self.currentPeripheral.connector.sensorHandler querySecondAlarmTimeInterval:^(BOOL isSuccess, MTVibrationType type, uint32_t startTime, uint32_t endTime) {
}];
[self.currentPeripheral.connector.sensorHandler setThirdAlarmTimeIntervalWithAlarmStatus:MTVibrationTypeOpen StartTime:22200 EndTime:79200 CompletionHandler:^(BOOL isSuccess) {
}];
[self.currentPeripheral.connector.sensorHandler queryThirdAlarmTimeInterval:^(BOOL isSuccess, MTVibrationType type, uint32_t startTime, uint32_t endTime) {
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 设置广播速率
型号为 MBM01 的设备,并且固件版本为 2.5.x 时,可对帧通道设置蓝牙 4.0 1Mbps 广播速率或者蓝牙 5.0 125Kbps 广播速率。
六个广播通道每个通道占一个值, 当值设置为 0 代表蓝牙 4.2 1Mbps 的广播模式, 当值设置为 1 代表蓝牙 5.0 125Kbps 的广播模式。
需要注意的是,iOS 目前无法获取到广播频率为 125Kbps 广播速率的广播包,安卓无此问题。即 iOS 上设置蓝牙 5.0 广播速率为 125Kbps 的帧通道,设置完成后,在 iPhone 上无法扫描到该帧,但是该帧在安卓上可以扫描到。
[self.currentPeripheral.connector.sensorHandler queryBroadcastSpeed:^(BOOL isSuccess, NSArray * _Nonnull broadcastSpeedOfSlotArray) {
NSLog(@"第一个通道的广播速率是%@", [broadcastSpeedOfSlotArray[0] intValue] == 1 ? @"蓝牙5.0 125k" : @"蓝牙4.0 1M");
}];
// 设置广播速率时,传入的数组有六个值,每个值对应六个通道。 0 表示蓝牙 4.0 广播速率为 1M, 1 表示蓝牙 5.0 广播速率为 125Kbps。比如设置第一和第二通道为 125Kbps 广播,其他通道设置为 1Mbps 广播,那么设置如下:
[self.currentPeripheral.connector.sensorHandler settingBroadcastSpeed:@[@1,@1,@0,@0,@0,@0] CompletionHandler:^(BOOL isSuccess) {
}];
2
3
4
5
6
7
8
# 设置 Acc 传感器可配置固件的参数配置项
此功能属于定制固件专属配套功能,使用前请咨询相关业务人员。
Acc 传感器可配置固件,可设置的参数配置项。
ODR ( 输出速率 ) :
description | value |
---|---|
1Hz | 0 |
10Hz | 1 |
25Hz | 2 |
50Hz | 3 |
100Hz | 4 |
200Hz | 5 |
400Hz | 6 |
1600Hz(low power) | 7 |
1344HZ (HR/normal) /5000HZ(low power) | 8 |
wakeup_threshold ( 唤醒阈值 mg ) : 0 ~ 2000
wakeup_duration ( 唤醒持续时间 ms ) : 0 ~ 127000
[self.currentPeripheral.connector.sensorHandler queryAccSensorParameterWithCompletionHandler:^(BOOL isSuccess, NSInteger odr, NSInteger wakeupThreshold, NSInteger wakeupDuration) {
}];
[self.currentPeripheral.connector.sensorHandler setAccSensorParameterWithOdr:0 WakeupThreshold:200 WakeupDuration:1000 CompletionHandler:^(BOOL isSuccess) {
}];
2
3
4
5
6
7
现在,你可以参考以上示例进行开发了。
# 注意事项
在开发过程中你可能会发现,持续扫描一段时间,有些设备会出现多个MTPeripheral实例。关于这一点,我们咨询过苹果工程师。得到的答复是在目前的iOS平台下,CoreBluetooth对多通道广播(特别是广播数据在变化)设备并不友好。
iOS11中此问题已不再存在。
在扫描过程中,有些属性可能是无法获取的,特别是mac地址(iOS平台下的限制),如果当前设备广播了DeviceInfo数据帧,那么name,mac地址,电池都是可以获取到的。
当你成功连接到设备后,固件最多只保持5分钟连接。然后设备端会主动断开连接。
如果添加SDK之后,运行显示无法找到路径,可以在 General -> Frameworks,Libraries,and Embedded Content ,把包删除再重新添加一次即可。
# 其他
BeaconPlus SDK 同样运用于我司 BeaconSET+ app,如需更直观的了解我司 beaconPlus 设备以及SDK相对应的功能,也可以下载 BeaconSET+ app 进行了解。(提示:BeaconSET+ app和 BeaconPlus SDK 需要和我司生产的设备配套使用)
# 文档版本记录
- 2017.10.11 v1.0 初版;
- 2019.01.07 v1.1 第二版;
- 2019.07.11 v1.2 修改了 poweroff 方法;
- 2020.03.27 v1.10.0添加 LineBeacon;
- 2020.07.27 v1.10.1 优化 LineBeacon 帧的获取和设置
- 2020.10.27 v1.10.2 每个广播帧新增 lastUpdate 属性
- 2021.4.21 v1.11.0 新增六轴/磁力计/大气压力传感器
- 2021.4.28 v1.11.1 新增振动传感器
- 2021.09.16 v1.13.0 新增红外传感器(合并B9-X)
- 2021.10.9 v1.14.0 新增设置蓝牙5.0广播速率
- 2021.12.27 v1.14.1 新增适配加速度传感器可配置固件的参数配置项
- 2022.5.9 v1.15.0 新增防拆帧
- 2022.6.1 v1.16.0 新增 IN100 广播帧 MinewMBeaconInfo
- 2023.11.13 v1.17.0 修复WriteFrame崩溃;优化支持后台扫描