# MTIndustrialSensorKit说明文档

本套SDK仅支持Minew公司出品的蓝牙Sensor设备,目前是工业温湿度传感器。通过SDK可以帮助开发者处理手机和Sensor之间的一切工作,包括:扫描设备,连接设备,向设备写入数据,从设备接收数据等。

# 前期工作

整体框架:MTICentralManager为设备管理类,在APP运行时始终是单例。MTIPeripheral是设备实例类,此套件会为每一个设备生成一个MTIPeripheral实例以便于对监听设备和操作设备。

MTICentralManager:设备管理类,可以扫描周围的Sensor设备,并且可以连接它们,校验它们等。

MTIPeripheral:设备实例类,当MTICentralManager发现一个物理设备时,MTICentralManager会生成一个MTIPeripheral实例,这个实例就对应一个物理设备。

MTIFrameHandler:设备广播类,可以获取设备广播时的数据。

MTConnectionHandler:设备连接类,进行设备的接发数据。

MTISensorHandler:传感器操作类,进行设备的读写数据。

# 开始上手

# 开发环境:

  • Xcode10+,当前SDK使用Xcode11编译,请使用Xcode10及以上版本进行开发;
  • iOS12.0,限制最低系统版本为iOS12;

# 导入到工程:

  1. 手动导入

    • 将开发套件的文件:MTIndustrialSensorKit.framework文件拷贝到项目工程目录下,然后添加到项目中。

PS:

  1. !!!在iOS10及以上版本,苹果对蓝牙APi添加了权限限制,你需要在工程的info.plist文件里添加一项字符串:Privacy - Bluetooth Peripheral Usage Description - "你的使用描述"。
  2. !!!在iOS13及以上版本,苹果对蓝牙APi添加了权限限制,你需要在工程的info.plist文件里添加一项字符串:Privacy - Bluetooth Always Usage Description - "你的使用描述"。

# 开始开发

# 扫描设备

首先需要获取到MTICentralManager的单例,然后检查手机当前的蓝牙状态,接着就可以进行设备扫描了。

// 获取Manager单例
MTICentralManager *manager = [MTICentralManager sharedInstance];

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    // 手机端当前的蓝牙开关状态
    if(self->manager.status == PowerStatePoweredOn) {
        // 开始进行设备扫描
        [manager startScan:^(NSArray<MTIPeripheral *> *peripherals) {
          //可根据broadcast属性的type筛选所需要的传感器种类
        	self->deviceAry = peripherals;
    	}];
    }
});
//扫描到的设备也可以使用manager.scannedPeris获得

// 如果你需要对手机的蓝牙状态作出响应。请监听回调。
[manager didChangesBluetoothStatus:^(PowerState status){
    
    switch(status) {
        case PowerStatePoweredOn:
            NSLog(@"bluetooth status change to poweron");
            break;
        case PowerStatePoweredOff:
            NSLog(@"bluetooth status change to poweroff");
            break;
        case PowerStateUnknown:
            NSLog(@"bluetooth status change to unknown");
    }
}];
1
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

PS: 只有手机蓝牙状态处于Poweron时,整个SDK才能够正常工作。

# 连接到设备

// 从上一步能够获取到扫描到的设备
MTIPeripheral *device = deviceAry[0];
//连接设备
[manager connectToPeriperal:device SecretKey:@"Device's secretKey"];
// 监听设备连接状态。
[device.connector didChangeConnection:^(Connection connection) {
    if (connection == Vaildated) {
      	//验证成功,成功连接设备
        NSLog(@"vaildated");
      	//需要写入密码,密码验证成功后进行其他的操作
    }
    if (connection == Disconnected) {
        NSLog(@"device has disconnected.");
    }
}];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 其他指令操作

接上一步,当设备成功验证写入的密钥正确后,方可进行其他指令操作。

以下操作不分先后顺序,可自行选择。

# 获取设备信息帧的广播参数
    /// 获取设备信息帧的广播参数
    /// @param completionHandler 结果回调
    [device.connector.sensorHandler getDeviceInfoFrameAdvertisingParameters:^(BOOL success, MTIAdvertisingParametersData * _Nonnull data) {

        if (success) {
            NSLog(@"信息帧类型:%@,广播间隔:%ld, 广播功率:%d,持续广播:%@", data.frameType == MTIFrameDeviceInfo ? @"设备信息帧":@"温湿度帧", data.advertisingInterval, data.txPower, data.isAlwaysAdvertising == YES ? @"是的":@"不是");
        }
    }];
1
2
3
4
5
6
7
8
# 设置设备信息帧的广播参数

请注意,广播功率的值只能设置 -40, -20, -16, -12, -8, -4, 0, 4。

    int interval = 100; // unit is ms.
    int txpower = 4;
    
    /// 设置设备信息帧的广播参数
    /// @param advertisingInterval 广播间隔,单位为毫秒
    /// @param txPower -40 -20 -16 -12 -8 -4 0 4dBm
    /// @param completionHandler 结果回调
    [device.connector.sensorHandler setDeviceInfoFrameAdvertisingParametersConfiguration:interval TxPower:txpower CompletionHandle:^(BOOL success) {
        if (success) {
            NSLog(@"设置设备信息帧配置参数:成功");
        } else {
            NSLog(@"设置设备信息帧配置参数:失败");
        }
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 获取温湿度广播帧的广播参数
    /// 获取温湿度广播帧的广播参数
    /// @param completionHandler 结果回调
    [device.connector.sensorHandler getIndustryHTFrameAdvertisingParameters:^(BOOL success, MTIAdvertisingParametersData *data) {
        
        if (success) {
            NSLog(@"信息帧类型:%@,广播间隔:%ld, 广播功率:%d,持续广播:%@,设备名称:%@", data.frameType == MTIFrameDeviceInfo ? @"设备信息帧":@"温湿度帧", data.advertisingInterval, data.txPower, data.isAlwaysAdvertising == YES ? @"是的":@"不是", data.deviceName);
        }
    }];
1
2
3
4
5
6
7
8
# 设置温湿度广播帧的广播参数

请注意,广播功率的值只能设置 -40, -20, -16, -12, -8, -4, 0, 4。

    // ⚠️ 设置设备名称不得超过八位的数字/字母,不支持除数字/字母之外的类型。
    NSString *deviceName = @"MST01";
    
    int interval = 2000; // unit is ms.
    int txpower = 0;
    
    /// 设置温湿度广播帧的广播参数
    /// @param advertisingInterval 广播间隔,单位是毫秒
    /// @param txPower -40 -20 -16 -12 -8 -4 0 4dBm
    /// @param deviceName 设备名称
    /// @param completionHandler 结果回调
    [device.connector.sensorHandler setIndustryHTFrameAdvertisingParametersConfiguration:interval TxPower:txpower DeveceName:deviceName CompletionHandle:^(BOOL success) {
        
        if (success) {
            NSLog(@"设置温湿度广播帧配置参数成功");
        } else {
            NSLog(@"设置温湿度广播帧配置参数失败");
        }

    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 获取工业温湿度传感器的配置参数
    /// 获取工业温湿度传感器的配置参数
    /// @param completionHandler 结果回调
    [device.connector.sensorHandler getIndustryHTSensorConfiguration:^(BOOL success, MTIHTSensorConfigParm * _Nonnull data) {
        if (success) {
            NSLog(@"获取工业温湿度传感器的配置参数成功");
            
            NSArray<MTIHTSensorWarmingSettingModel *> *MTIHTSensorWarmingSettingModels = data.MTIHTSensorWarmingSettingModels;
            MTIHTSensorWarmingSettingModel *model1 = MTIHTSensorWarmingSettingModels.firstObject;
            MTIHTSensorWarmingSettingModel *model2 = MTIHTSensorWarmingSettingModels.lastObject;
            
            NSLog(@"第一组触发阈值 高温-低温:%f-%f,高湿-低湿:%f-%f,温度开关:%@,湿度开关:%@ \n", model1.highTemperature, model1.lowTemperature, model1.highHumidity, model1.lowHumidity, model1.isOpenTempAlarmSwitch == YES ? @"Yes" : @"NO", model1.isOpenHumiAlarmSwitch == YES ? @"Yes" : @"NO");
            NSLog(@"第二组触发阈值 高温-低温:%f-%f,高湿-低湿:%f-%f ,温度开关:%@,湿度开关:%@ \n", model2.highTemperature, model2.lowTemperature, model2.highHumidity, model2.lowHumidity, model2.isOpenTempAlarmSwitch == YES ? @"Yes" : @"NO", model2.isOpenHumiAlarmSwitch == YES ? @"Yes" : @"NO");

            NSLog(@"采样间隔:%ld", data.collectIntervalForHTFrame);
        } else {
            NSLog(@"获取工业温湿度传感器的配置参数失败");
        }
    }];
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 设置工业温湿度传感器的配置参数

请注意,摄氏度单位下,温度最大为85°C,最小为-40°C,华氏度下,温度最大为185°F,最小为-40°F;湿度最大为100,最小为0。另外,警告区间上界值需要大于或等于下界值。

    MTIHTSensorWarmingSettingModel *model1 = [[MTIHTSensorWarmingSettingModel alloc] init];
    model1.highTemperature = 30;
    model1.lowTemperature = 20;
    model1.highHumidity = 60;
    model1.lowHumidity = 40;
    model1.deviceType = HT;
    model1.isOpenTempAlarmSwitch = YES;
    model1.isOpenHumiAlarmSwitch = YES;
    
    MTIHTSensorWarmingSettingModel *model2 = [[MTIHTSensorWarmingSettingModel alloc] init];
    model2.highTemperature = 35;
    model2.lowTemperature = 25;
//    model2.highTemperature = 50;
//    model2.lowTemperature = 20;
    model2.deviceType = SingleTemp;
    model2.isOpenTempAlarmSwitch = YES;
    
    int samplingInterval = 100;
    
    NSLog(@"Sampling interval:%d", samplingInterval);
    
    /// 设置工业温湿度传感器的配置参数
    /// @param htSettingDatas 温湿度传感器告警参数配置
    /// @param samplingInterval 采集间隔,1s到24h,单位为毫秒
    /// @param completionHandler 结果回调
    [device.connector.sensorHandler setIndustryHTSensorConfiguration:@[model1, model2] SamplingInterval:samplingInterval CompletionHandle:^(BOOL success) {

        if (success) {
            NSLog(@"设置温湿度传感器告警参数成功");
        }
        else {
            NSLog(@"设置温湿度传感器告警参数失败");
        }
    }];
1
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
# 获取温度单位

温度单位分为摄氏温标(Celsius)和华氏温标(Fahrenheit)。

		/// 获取温度单位
		/// @param completionHandler 回调结果 
    [device.connector.sensorHandler getTemperatureUnit:^(BOOL success, MTITemperatureUnitType unitType) {
        if (success) {
            NSLog(@"获取温度单位成功");
        } else {
            NSLog(@"获取温度单位失败");
        }
    }];
1
2
3
4
5
6
7
8
9
# 设置温度单位

温度单位分为摄氏温标(Celsius)和华氏温标(Fahrenheit)。

单位转换:摄氏度为 20 时,转换为华氏度值为 20*1.8+32 。

		/// 设置温湿度传感器温度单位
    /// @param temperatureUnitType 温度单位类型,MTICelsius 和 MTIFahrenheit
    /// @param completionHandler 回调结果
    [device.connector.sensorHandler setTemperatureUnit:MTICelsius completionHandler:^(BOOL success) {
    if (success) {
        NSLog(@"设置温度单位成功");
    }
    else {
        NSLog(@"设置温度单位失败");
    }
}];
1
2
3
4
5
6
7
8
9
10
11
# 读取温湿度历史数据
    // 时间格式
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"YYYY/MM/dd HH:mm:ss"];
    
    // 时区
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];
    [formatter setTimeZone:timeZone];
    

    // 当前系统时间
    NSDate *currentDate = [NSDate new];
    NSTimeInterval currentTimeInterval =[currentDate timeIntervalSince1970];
    
    NSTimeInterval startTimeInterval, endTimeInterval;
    
    // 开始时间
    NSString *startTime = @"2023/3/22 9:00:00";
    NSDate *startDate = [formatter dateFromString:startTime];
    startTimeInterval = [startDate timeIntervalSince1970];
    
    // 结束时间
    NSString *endTime = @"2023/3/31 17:36:00";
    NSDate *endDate = [formatter dateFromString:endTime];
    endTimeInterval = [endDate timeIntervalSince1970];
    
    // 如果你想获取所有历史数据,开始时间和结束时间按照这样设置
//    startTimeInterval = 0;
//    endTimeInterval = currentTimeInterval;
        
    if (startTimeInterval > endTimeInterval) {
        NSLog(@"结束时间不能大于开始时间");
        return;
    }
    
    /// 获取历史数据
    /// @param formatter 时间格式
    /// @param unit 温度单位
    /// @param startTimeInterval 开始时间的时间戳
    /// @param endTimeInterval 结束时间的时间戳
    /// @param systemTimeInterval 当前系统时间
    /// @param htModel 设备类型, 当前版本只有MST01
    /// @param completionHandler 结果回调
    [device.connector.sensorHandler readHTHistoryWithDateFormatter:formatter Unit:MTICelsius StartTimeInterval:startTimeInterval EndTimeInterval:endTimeInterval SystemTimeInterval:currentTimeInterval DeviceHTModelType:MST01 completionHandler:^(BOOL success, NSInteger totalNum, NSArray<MTIHistoryData *> * _Nonnull data) {
        
        if (success) {
            NSLog(@"成功读取历史数据");
            for (int i = 0; i < data.count; i++) {
                MTIHistoryData *historyData = data[i];
                NSLog(@"原始数据:%@, 时间戳:%f 时间字符串:%@, 温度:%f, 湿度:%f", historyData.historyOriginData, historyData.timeInterval, historyData.timeStr, historyData.temp, historyData.humi);                
            }
        } else {
            NSLog(@"读取历史数据失败");
        }
    }];
1
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
# 固件升级

请注意,需要使用匹配的固件升级包,否则可能导致设备无法正常使用。

    // ⚠️注意:demo 附带的ota升级包未必与当前设备匹配,请根据自己手头设备的硬件及固件信息,跟业务沟通后,使用匹配的固件升级包进行 ota 升级。如果使用了错误的固件升级包,这可能会让你的设备无法正常使用。
		// 只看s3 s4 关键词来区分固件升级包是否与设备匹配是不可行的,因为不同出厂设置的设备,固件版本和硬件版本也不一定匹配,所以一定要确认固件升级包的正确。
   
    NSData *otaPacketData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"S3V2_NV900_20210312_s3_ota_v1_0_23" ofType:@".bin"]];
    

    /// 固件升级
    /// @param originOtaData 固件升级包数据
    /// @param stateHandler 监听升级状态的改变,“完成”表示升级成功。
    /// @param progressHandler 监听升级包发送进度
    /// @param errorHandler 监听升级失败原因
    [device.connector startOTAWithOTAData:otaPacketData stateHandler:^(OTAState state) {
        if (state == OTAStateStarting) {
            NSLog(@"ota start");
        } else if(state == OTAStateUploading) {
            NSLog(@"ota uploading");
        } else if(state == OTAStateAborted) {
            NSLog(@"ota aborted");
        } else if(state == OTAStateDisconnecting) {
            NSLog(@"ota disconnect");
        } else if (state == OTAStateCompleted) {
            NSLog(@"ota successfully");
        } else if(state == OTAStateFailed) {
            NSLog(@"ota failed");
        }
    } progressHandler:^(float progress) {
        NSLog(@"ota progress:%f", progress);
    } errorHandler:^(NSError * _Nonnull error) {
        NSLog(@"ota  failed,error:%@",error);
    }];
1
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

附表

# MTICentralManager 属性说明
名称 类型 备注
state PowerState 当前的手机蓝牙状态
scannedPeris NSArray 扫描到的设备
# MTIPeripheral属性说明
名称 类型 备注
identifier NSString 设备的Identifier
broadcast MTIFrameHandler 广播类实例对象
connector MTConnectionHandler 连接类实例对象
# MTIFrameHandler属性说明
名称 类型 说明
mac NSString 设备mac
name NSString 设备名称,可自定义。工业温湿度传感器初始化名称为“MST01”
rssi NSInteger 信号强度
identifier NSString 设备唯一标识
advFrames NSArray<MTIFrame *> 扫描到的广播数组
# MTIDeviceInfoFrame属性说明
名称 类型 备注
firmVersion NSString 设备的固件版本
mac NSString 设备的Mac地址
battery NSInteger 设备的电池电量
# MTITempHumiFrame属性说明
名称 类型 备注
name NSString 设备的蓝牙名称
temp double 设备温度
humi double 设备湿度
isMarkStatus BOOL 设备是否被标记
temperatureUnit MTITemperatureUnitType 温度单位
deviceType MTIDeviceType HT ;SingleTemp
deviceWarningStatus MTIWarningType 温湿度传感器状态,正常/异常
screenStatus MTIWarningType 屏幕状态, 正常/异常
htModel MTIHTModel 设备模型,目前只有MST01
# MTConnectionHandler属性说明
名称 类型 备注
macString NSString 设备Mac地址
connection Connection 设备连接状态
sensorHandler MTISensorHandler 传感器读写操作管理
# MTIHTSensorConfigParm属性说明
名称 类型 备注
MTIHTSensorWarmingSettingModels NSString MTIHTSensorWarmingSettingModel数组
samplingInterval NSInteger 采集间隔,ms
# MTIHTSensorWarmingSettingModel属性说明
名称 类型 备注
deviceType MTIDeviceType 设备类型
isOpenTempAlarmSwitch BOOL 温度告警开关
isOpenHumiAlarmSwitch BOOL 湿度告警开关
highTemperature double 温度告警上界
lowTemperature double 温度告警下界
highHumidity double 湿度告警上界
lowHumidity double 湿度告警下界
# MTIAdvertisingParametersData属性说明
名称 类型 备注
frameType MTIFrameType 帧类型
advertisingInterval NSInteger 广播间隔,ms
advTxpower NSInteger 广播功率,只能是-40, -20, -16, -12, -8, -4, 0, 4dBm
isAlwaysAdvertising BOOL 是否持续广播
deviceName BOOL 设备名称(温湿度广播帧才有该属性)
# MTHistoryData属性说明
名称 类型 备注
historyOriginData NSData 未解析的历史数据
humi double 湿度数值
temp double 湿度数值
timeStr NSString 格式化的时间字符串
timeInterval NSTimeInterval 未格式化的时间

# 注意事项

  1. 同时写入多条指令可能会导致异常,建议每条指令完成后,再写入新的指令。

# 文档版本记录

  • 2023.04.01 v1.0 初版;
上次更新:: 2024/1/12 14:37:29