# MTSensorKit Documentation
This set of SDK only supports the Bluetooth Sensor device produced by Minew, and is currently a temperature and humidity sensor and a door sensor. The SDK can help developers handle all the work between mobile phones and Sensors, including: scanning devices, connecting devices, writing data to devices, receiving data from devices, etc.
# Preliminary work
Overall framework: MTCentralManager is a device management class, which is always a singleton when the APP is running. MTPeripheral is a device instance class. This suite will generate a MTPeripheral instance for each device to facilitate monitoring and operating devices.
MTCentralManager : Device management class, which can scan the surrounding Sensor devices, and can connect them, verify them, etc.
MTPeripheral : Device instance class. When MTCentralManager discovers a physical device, MTCentralManager will generate a MTPeripheral instance, which corresponds to a physical device.
MTBroadcastHandler : Device broadcast class, which can get the data when the device broadcasts.
MTConnectionHandler : Device connection class for receiving and sending data from the device.
MTSensorHandler:传感器操作类,进行设备的读写数据。
# Get started
# Development environment:
-Xcode10 +, the current SDK is compiled with Xcode11, please use Xcode10 and above for development; -iOS12.0, the minimum system version is iOS12;
# Import into the project::
Manually
- Copy the development kit files: MTSensorKit.framework files to the project project directory, and then add them to the project.
PS:
- !!! In iOS10 and above, Apple added permission restrictions on Bluetooth APi. You need to add a string to the project's info.plist file: Privacy-Bluetooth Peripheral Usage Description-"Your usage description".
- !!! In iOS13 and above, Apple added permission restrictions on Bluetooth APi. You need to add a string to the project's info.plist file: Privacy-Bluetooth Always Usage Description-"Your usage description".
# Start development
# Scanning equipment
First you need to get the singleton of MTCentralManager, then check the current Bluetooth status of the phone, and then you can scan the device.
// Get Manager singleton
MTCentralManagerV3 *manager = [MTCentralManagerV3 sharedInstance];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// The current state of the Bluetooth switch on the mobile phone
if(self->manager.status == PowerStatePoweredOn) {
// start device scan
[manager startScan:^(NSArray<MTPeripheral *> *peripherals) {
//According to the type of broadcast attribute, the required sensor type can be filtered.
self->deviceAry = peripherals;
}];
}
});
// Scanned devices can also be obtained using manager.scannedPeris
// If you need to respond to the Bluetooth status of your phone. Please listen for the callback.
[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");
}
}];
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
PS: The entire SDK works only when the Bluetooth state of the phone is in Poweron.
# Connect to device
// The scanned device can be obtained from the previous step
MTPeripheralV3 *device = deviceAry[0];
// Connect the device
[manager connectToPeriperal:device];
// Listen for device connection status.
[p.connector didChangeConnection:^(Connection connection) {
if (connection == Vaildated) {
// Successful verification, successfully connected to the device
NSLog(@"vaildated");
//Need to write a password, perform other operations after the password is verified successfully
}
if (connection == Disconnected) {
NSLog(@"device has disconnected.");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Write password to device
Continuing from the previous step, when the mobile phone successfully establishes a connection with a certain device and the verification is successful, you need to write a password to the device for password verification.
[device.connector.sensorHandler writePassword:@"minew123" completionHandler:^(BOOL success, MTRecieveErrorType errorType) {
if (success) {
NSLog(@"password is right");
//then do what you want for example:
} else {
NSLog(@"password is error");
}
}];
2
3
4
5
6
7
8
9
# Other command operations
Continuing from the previous step, when the device successfully verifies that the written password is correct, other command operations can be performed.
The following operations are in no particular order and can be selected by yourself.
# Get device information
The specific properties of the device information can be found in the attached table.
/// Get deveice info.
/// @param completionHandler the receive block.
[device.connector.sensorHandler readDeviceInfo:^(BOOL success, MTDeviceInfoData * _Nonnull data) {
if (success) {
NSLog(@"readDeviceData successfully");
NSString *firVersion = data.firmVersion;
NSInteger advInterval = data.advInterval;
NSInteger advTxpower = data.advTxpower;
BOOL isOpenTempAlarmSwitch = data.isOpenTempAlarmSwitch;
BOOL isOpenHumiAlarmSwitch = data.isOpenHumiAlarmSwitch;
double highTempAlarm = data.highTempAlarm;
double lowTempAlarm = data.lowTempAlarm;
double highHumiAlarm = data.highHumiAlarm;
double lowHumiAlarm = data.lowHumiAlarm;
double temperatureResolution = data.temperatureResolution;
double humidityResolution = data.humidityResolution;
double currentTemperature = data.currentTemperature;
double currentHumidity = data.currentHumidity;
MTTemperatureUnitType unitType = data.unitType;
BOOL isStorageSomethine = data.isStorageSomethine;
NSString *deviceName = data.deviceName;
NSLog(@"firVersion:%@, advTxpower:%ld, isOpenTempAlarmSwitch:%@, isOpenHumiAlarmSwitch:%@, highTempAlarm:%f, lowTempAlarm:%f, highHumiAlarm:%f, lowHumiAlarm:%f, temperatureResolution:%f, humidityResolution:%f, currentTemperature:%f, currentHumidity:%f, TemperatureUnitType:%@, isOpenStorageSwitch:%@, deviceName:%@", firVersion, advTxpower, isOpenTempAlarmSwitch==YES?@"Yes":@"No", isOpenHumiAlarmSwitch==YES?@"Yes":@"No", highTempAlarm, lowTempAlarm, highHumiAlarm, lowHumiAlarm, temperatureResolution, humidityResolution, currentTemperature, currentHumidity, unitType==Celsius?@"Celsius":@"Fahrenheit", isStorageSomethine==YES?@"Yes":@"No", deviceName);
if (data.deviceInfoType == MST01InfoOfHighVersion) {
NSInteger advIntervalForHTFrame = data.advIntervalForHTFrame;
NSInteger advIntervalForInfoFrame = data.advIntervalForInfoFrame;
NSLog(@"advIntervalForHTFrame:%ld, advIntervalForInfoFrame:%ld", advIntervalForHTFrame, advIntervalForInfoFrame);
} else {
NSInteger advInterval = data.advInterval;
NSLog(@"advInterval:%ld", advInterval);
}
} else {
NSLog(@"readDeviceData 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
# Set device name
The device name must not exceed eight digits/letters, and types other than numbers/letters are not supported.
/// Set device name.
/// @param deviceName the device name.
/// @param completionHandler the receive block.
[device.connector.sensorHandler setDeviceName:@"minew123" completionHandler:^(BOOL success, MTRecieveErrorType errorType) {
if (success) {
NSLog(@"setDeviceName successfully");
}
else {
NSLog(@"setDeviceName failed");
}
}];
2
3
4
5
6
7
8
9
10
11
# Set device storage switch
Set YES to start storing data, set NO to stop storing data.
/// Device setting storageData.
/// @param storageStatus the device whether to store data.
/// @param completionHandler the receive block.
[device..connector.sensorHandler setStorageStatusOfHistoricalData:isStorage completionHandler:^(BOOL success) {
if (success) {
NSLog(@"setIsStorageData successfully");
}
else {
NSLog(@"setIsStorageData failed");
}
}];
2
3
4
5
6
7
8
9
10
11
# Set temperature and humidity sensor temperature unit
Temperature units are divided into Celsius and Fahrenheit.
Unit conversion: When Celsius is 20, the conversion to Fahrenheit is 20*1.8+32 .
/// Device setting temperature unit.
/// @param temperatureUnitType the device temperature unit type of temperature.
/// @param completionHandler the receive block.
[device.connector.sensorHandler setTemperatureUnit:Celsius completionHandler:^(BOOL success, MTRecieveErrorType errorType) {
if (success) {
NSLog(@"setTemperatureUnit successfully");
}
else {
NSLog(@"setTemperatureUnit failed");
}
}];
2
3
4
5
6
7
8
9
10
11
# Set temperature and humidity sensor warning upper and lower bounds and warning switch
Note that in Celsius units, the maximum temperature is 85°C and the minimum is -40°C, in Fahrenheit, the maximum temperature is 185°F and the minimum is -40°F; the humidity is 100 maximum and 0 minimum. In addition, the upper bound value of the warning interval needs to be greater than or equal to the lower bound value.
/// Set alarm temperature and humidity for normal v3 device
/// @param maxTemp the hightest temperature of the device.
/// @param minTemp the low temperature of the device.
/// @param maxHumi the hightest humidity of the device.
/// @param minHumi the low humidity of the device.
/// @param isTempWarn Whether to turn on the switch of the temperature alarm function.
/// @param isHumiWarn Whether to turn on the switch of the humidity alarm function.
[device.connector.sensorHandler setHTWarningWithMaxTemp:hTemp minTemp:lTemp maxHumi:hHumi minHumi:lHumi isTempWarn:YES isHumiWarn:YES completionHandler:^(BOOL success) {
if (success) {
NSLog(@"setHTWarning successfully");
}
else {
NSLog(@"setHTWarning failed");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Read temperature and humidity historical data
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];
/// Get device HTSensor history.
/// @param formatter the date formatter.
/// @param unit the device temperature units.
[device.connector.sensorHandler readHTHistoryWithDateFormatter:formatter Unit:Celsius completionHandler:^(BOOL success, NSInteger totalNum, NSArray<MTHistoryData *> * _Nonnull data) {
if (success) {
NSLog(@"Success to read ht history.");
for (int i = 0; i < data.count; i++) {
MTHistoryData *historyData = data[i];
NSLog(@"originData:%@, timeInterval:%f timeStr:%@, temp:%f, humi:%f", historyData.historyOriginData, historyData.timeInterval, historyData.timeStr, historyData.temp, historyData.humi);
// Historical data has been parsed within the SDK, but if you want to get the raw data and parse the data yourself, you can refer to the code.
}
} else {
NSLog(@"Failed to read ht history.");
}
}];
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
# Firmware upgrade
// ⚠️Note: The ota upgrade package that comes with the demo may not match the current device. Please use the matching firmware upgrade package to perform the ota upgrade after communicating with the business according to the hardware and firmware information of the device at hand. If you use the wrong firmware update package, this may make your device unusable.
// It is not feasible to distinguish whether the firmware upgrade package matches the device only by looking at the s3 s4 keywords, because the firmware version and hardware version of the device with different factory settings may not match, so be sure to confirm that the firmware upgrade package is correct.
NSData *otaPacketData = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"S3V2_NV900_20210312_s3_ota_v1_0_23" ofType:@".bin"]];
/// ota device by using this method, input firmware data, then start ota, get statusChange in stateHandler, get firmware file upload progress in progressHandler, get error in errorHandler
/// @param originOtaData data of ota
/// @param stateHandler listen status change, only "Completed" means ota successfully.
/// @param progressHandler listen file uploading progress
/// @param errorHandler listen errors in ota stage
[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);
}];
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
# Special configuration of industrial device
# Set delay recording time
/// Set delay record Time for industrial device
/// @param delayTime the recording delay time range is 0 minutes to 18 hours, set in seconds.
/// @param completionHandler the receive block.
[device.connector.sensorHandler setIndustrialHTWarningWithMaxTemp1:hTemp1 minTemp1:lTemp1 maxTemp2:hTemp2 minTemp2:lTemp2 maxHumi:hHumi minHumi:lHumi isTempWarn:YES isTempWarnSecond:YES isHumiWarn:YES completionHandler:^(BOOL success) {
if (success) {
NSLog(@"setIndustrialHTWarning successfully");
}
else {
NSLog(@"setIndustrialHTWarning failed");
}
}];
2
3
4
5
6
7
8
9
10
11
# Set broadcast power
/// Set broadcast power
/// @param broadcastPower the value of broadcast power can only be set to -40, -20, -16, -12, -8, -4, 0, 4 dbm
/// @param completionHandler the receive block.
[device.connector.sensorHandler setBroadcastPower:-40 CompletionHandle:^(BOOL success) {
if (success) {
NSLog(@"setBroadcastPower successfully");
}
else {
NSLog(@"setBroadcastPower failed");
}
}];
2
3
4
5
6
7
8
9
10
11
# Set broadcast interval
Please note that the industrial temperature and humidity firmware version number is below 3.1.0 for devices, and S3-V3 devices can use this directive.
/// Set broadcast interval for industrial device
/// @param broadcastInterval the broadcast interval range is 100-5000ms.
/// @param completionHandler the receive block.
[device.connector.sensorHandler setBroadcastInterval:1000 CompletionHandle:^(BOOL success) {
if (success) {
NSLog(@"setBroadcastInterval successfully");
}
else {
NSLog(@"setBroadcsetBroadcastIntervalastPower failed");
}
}];
2
3
4
5
6
7
8
9
10
11
Please note that for industrial temperature and humidity, firmware version 3.1.0 and above devices, use this command to set the broadcast interval.
/// Set the broadcast interval, only for industrial temperature and humidity. This command is used by devices with firmware version 3.1.0 and above.
/// @param broadcastIntervalForHTFrame the broadcast interval of the temperature and humidity broadcast frame, the range is 1000-60000ms.
/// @param broadcastIntervalForDeviceInfoFrame the broadcast interval for device info frame range is 100-5000ms.
[device.connector.sensorHandler setBroadcastIntervalForHTFrame:1000 BroadcastIntervalForDeviceInfoFrame:500 CompletionHandle:^(BOOL success) {
if (success) {
NSLog(@"setBroadcastIntervalForMST01HighFirmVersion successfully");
}
else {
NSLog(@"setBroadcsetIntervalForMST01HighFirmVersion failed");
}
}];
2
3
4
5
6
7
8
9
10
11
# set collection interval
Please note that for industrial temperature and humidity, firmware version 3.1.0 and above devices, use this command to set the collection interval. The collection interval range is 1s--24h. Unit is second.
/// set collect interval
/// @param collectInterval the collection interval range is 1s--24h. Unit is second.
[device.connector.sensorHandler setCollectInterval:30 CompletionHandle:^(BOOL success) {
if (success) {
NSLog(@"setCollectIntervalForMST01HighFirmVersion successfully");
}
else {
NSLog(@"setCollectIntervalForMST01HighFirmVersion failed");
}
}];
2
3
4
5
6
7
8
9
10
# Set alarm temperature and humidity for industrial device
/// Set alarm temperature and humidity for industrial device
/// @param maxTemp1 the hightest temperature of the device.
/// @param minTemp1 the low temperature of the device.
/// @param maxTemp2 the second hightest temperature of the device.
/// @param minTemp2 the second low temperature of the device.
/// @param maxHumi the hightest humidity of the device.
/// @param minHumi the low humidity of the device.
/// @param isTempWarn Whether to turn on the switch of the temperature alarm function.
/// @param isTempWarnSecond Whether to turn on the switch of the second temperature alarm function.
/// @param isHumiWarn Whether to turn on the switch of the humidity alarm function.
[device.connector.sensorHandler setIndustrialHTWarningWithMaxTemp1:hTemp1 minTemp1:lTemp1 maxTemp2:hTemp2 minTemp2:lTemp2 maxHumi:hHumi minHumi:lHumi isTempWarn:YES isTempWarnSecond:YES isHumiWarn:YES completionHandler:^(BOOL success) {
if (success) {
NSLog(@"setIndustrialHTWarning successfully");
}
else {
NSLog(@"setIndustrialHTWarning failed");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Schedule
# MTCentralManager property description
Name | Type | Remark |
---|---|---|
state | PowerState | current iphone bluetooth state |
scannedPeris | NSArray | current scanned devices |
# MTPeripheral property description
Name | Type | Remark |
---|---|---|
identifier | NSString | Uniquely identifier like "MAC address" |
broadcast | MTBroadcastHandler | advertising stage handler |
connector | MTConnectionHandler | connection stage handler |
# MTBroadcastHanler property description
Name | Type | Remark |
---|---|---|
name | NSString | name of device |
rssi | NSInteger | current rssi value |
battery | NSString | battery left, sometimes available |
mac | NSString | mac string, sometimes available |
identifier | NSString | identifier string, sometimes available |
temp | double | Temperature |
humi | double | Humidity |
reseInfo | uint8_t | Temperature unit |
type | SensorType | broadcast frame type |
doorStatus | NSString | 门磁设备门磁状态 |
warningStatus | uint8_t | 设备报警状态 |
# MTConnectionHandler property description
Name | Type | Remark |
---|---|---|
macString | NSString | macString of device |
connection | Connection | current connection status. |
sensorHandler | MTSensorHandlerV3 | sensor read and write operation handler |
# MTDeviceInfo property description
Name | Type | Remark |
---|---|---|
firmVersion | NSString | firm version |
advInterval | NSInteger | broadcast interval, ms |
advTxpower | NSInteger | broadcast power, dam |
isOpenTempAlarmSwitch | BOOL | temperature alarm switch |
isOpenHumiAlarmSwitch | BOOL | humidity alarm switch |
highTempAlarm | double | temperature warning upper bound |
lowTempAlarm | double | temperature warning lower bound |
highHumiAlarm | double | humidity warning upper bound |
lowHumiAlarm | double | humidity warning upper bound |
temperatureResolution | double | temperature resolution, Only V3 devices are available |
humidityResolution | double | humidity resolution, Only V3 devices are available |
realTimeTemperature | double | real-time temperature |
realTimeHumidity | double | real-time humidity |
temperatureUnitType | MTTemperatureUnitType | temperature unit, Celsius/Fahrenheit |
isStorage | BOOL | whether to store history date |
deviceName | NSString | device name |
delayRecordTime | int | delay record time |
isOpenTempAlarmSwitchSecond | BOOL | the second temperature alarm switch |
secondHighTempAlarm | double | the second temperature warning upper bound, Only MST01 devices are available |
secondLowTempAlarm | double | the second temperature warning lower bound, Only MST01 devices are available |
advIntervalForHTFrame | NSInteger | broadcast interval for htFrame, ms, only when firmware version 3.1.0 and above industrial temperature and humidity equipment |
advIntervalForInfoFrame | NSInteger | broadcast interval for info frame, ms, only when firmware version 3.1.0 and above industrial temperature and humidity equipment |
deviceInfoType | MTDeviceInfoType | MST01Info, PR2122Info, MST01InfoOfHighVersion |
# MTHistoryData property description
Name | Type | Remark |
---|---|---|
historyOriginData | NSData | origin history data |
humi | double | humidity of device |
temp | double | temperature of device |
timeStr | NSString | Formatted time string |
timeInterval | NSTimeInterval | The original value of the time. |
# Precautions
During the development process, you may find that if you continue to scan for a period of time, there will be multiple instances of MTPeripheral on some devices. We consulted with Apple engineers about this. The answer is that under the current iOS platform, CoreBluetooth is not friendly to multi-channel broadcast (especially when the broadcast data is changing) devices.
This problem no longer exists in iOS11.
If after adding the SDK, the operation shows that the path cannot be found, you can go to General -> Frameworks, Libraries, and Embedded Content, and change MSensorV3Kit.framework -> Embed , from ‘Do Not Embed’ to ‘Embed& Sign’.
Writing multiple instructions at the same time may cause an exception. It is recommended to write a new instruction after each instruction is completed.
# Documentation version record
- 2022.05.12 v1.0 first version;
- 2022.08.31 v1.0.1 second version;