# MTIndustrialSensorKit Documentation
This set of SDK only supports the Bluetooth Sensor device produced by Minew, and is currently a industrial temperature and humidity 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: MTICentralManager is a device management class, which is always a singleton when the APP is running. MTIPeripheral is a device instance class. This suite will generate a MTIPeripheral instance for each device to facilitate monitoring and operating devices.
MTICentralManager : Device management class, which can scan the surrounding Sensor devices, and can connect them, verify them, etc.
MTIPeripheral : Device instance class. When MTICentralManager discovers a physical device, MTICentralManager will generate a MTIPeripheral instance, which corresponds to a physical device.
MTIFrameHandler : Device broadcast class, which can get the data when the device broadcasts.
MTConnectionHandler : Device connection class for receiving and sending data from the device.
MTISensorHandler:传感器操作类,进行设备的读写数据。
# 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: MTIndustrialSensorKit.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 MTICentralManager, then check the current Bluetooth status of the phone, and then you can scan the device.
// Get Manager singleton
MTICentralManagerV3 *manager = [MTICentralManagerV3 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<MTIPeripheral *> *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
MTIPeripheralV3 *device = deviceAry[0];
// Connect the device
[manager connectToPeriperal:device SecretKey:@"Device's secretKey"];
// 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
# Other command operations
Continuing from the previous step, when the device successfully verifies that the written secretKey is correct, other command operations can be performed.
The following operations are in no particular order and can be selected by yourself.
# Get the broadcast parameters for the device information frame
/// Get the device information frame broadcast parameters
/// @param completionHandler the receive block.
[device.connector.sensorHandler getDeviceInfoFrameAdvertisingParameters:^(BOOL success, MTIAdvertisingParametersData * _Nonnull data) {
if (success) {
NSLog(@"Information Frame Type: %@, Broadcast Interval: %ld, Broadcast Power: %d, Continuous Broadcast: %@", data.frameType == MTIFrameDeviceInfo ? @"Device Information Frame": @"Temperature and humidity frame", data.advertisingInterval, data.txPower, data.isAlwaysAdvertising == YES ? @"Yes":@"No");
}
}];
2
3
4
5
6
7
8
# Set the broadcast parameters for device information frames
Note that the value of broadcast power can only be set -40, -20, -16, -12, -8, -4, 0, 4。
int interval = 100; // unit is ms.
int txpower = 4;
/// Set device information frame broadcast parameters
/// @param advertisingInterval Broadcast interval in milliseconds
/// @param txPower -40 -20 -16 -12 -8 -4 0 4dBm
/// @param completionHandler the receive block.
[device.connector.sensorHandler setDeviceInfoFrameAdvertisingParametersConfiguration:interval TxPower:txpower CompletionHandle:^(BOOL success) {
if (success) {
NSLog(@"Setting deviceInfo frame configuration parameters successfully");
} else {
NSLog(@"Setting deviceInfo frame configuration parameters failed");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Get the broadcast parameters of the humidity and temperature broadcast frame
/// Get the industrial temperature and humidity frame broadcast parameters
/// @param completionHandler the receive block.
[device.connector.sensorHandler getIndustryHTFrameAdvertisingParameters:^(BOOL success, MTIAdvertisingParametersData *data) {
if (success) {
NSLog(@"Information Frame Type: %@, Broadcast Interval: %ld, Broadcast Power: %d, Continuous Broadcast: %@, Device Name: %@", data.frameType == MTIFrameDeviceInfo ? @"Device Information Frame": @"Temperature and humidity frame", data.advertisingInterval, data.txPower, data.isAlwaysAdvertising == YES ? @"Yes":@"No", data.deviceName);
}
}];
2
3
4
5
6
7
8
# Set the broadcast parameters of the humidity and temperature broadcast frame
Note that the value of broadcast power can only be set -40, -20, -16, -12, -8, -4, 0, 4。
// Set the device name to no more than eight digits/letters, and types other than numbers/letters are not supported.
NSString *deviceName = @"MST01";
int interval = 2000; // unit is ms.
int txpower = 0;
/// Set industrial temperature and humidity frame broadcast parameters
/// @param advertisingInterval Broadcast interval in milliseconds
/// @param txPower -40 -20 -16 -12 -8 -4 0 4dBm
/// @param deviceName device name
/// @param completionHandler the receive block.
[device.connector.sensorHandler setIndustryHTFrameAdvertisingParametersConfiguration:interval TxPower:txpower DeveceName:deviceName CompletionHandle:^(BOOL success) {
if (success) {
NSLog(@"Setting temperature and humidity broadcast frame configuration parameters successfully");
} else {
NSLog(@"Setting temperature and humidity broadcast frame configuration parameters failed");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Get the configuration parameters of industrial temperature and humidity sensors
/// Get industrial humidity and temperature sensor configurations
/// @param completionHandler the receive block.
[device.connector.sensorHandler getIndustryHTSensorConfiguration:^(BOOL success, MTIHTSensorConfigParm * _Nonnull data) {
if (success) {
NSLog(@"get htSensor configuration success");
NSArray<MTIHTSensorWarmingSettingModel *> *MTIHTSensorWarmingSettingModels = data.MTIHTSensorWarmingSettingModels;
MTIHTSensorWarmingSettingModel *model1 = MTIHTSensorWarmingSettingModels.firstObject;
MTIHTSensorWarmingSettingModel *model2 = MTIHTSensorWarmingSettingModels.lastObject;
NSLog(@"The first set of trigger thresholds High temperature-low temperature: %f-%f, high humidity-low humidity: %f-%f, temperature switch: %@, humidity switch:%@ \n", model1.highTemperature, model1.lowTemperature, model1.highHumidity, model1.lowHumidity, model1.isOpenTempAlarmSwitch == YES ? @"Yes" : @"NO", model1.isOpenHumiAlarmSwitch == YES ? @"Yes" : @"NO");
NSLog(@"The second set of trigger thresholds High temperature-low temperature: %f-%f, high humidity-low humidity: %f-%f, temperature switch: %@, humidity switch:%@ \n", model2.highTemperature, model2.lowTemperature, model2.highHumidity, model2.lowHumidity, model2.isOpenTempAlarmSwitch == YES ? @"Yes" : @"NO", model2.isOpenHumiAlarmSwitch == YES ? @"Yes" : @"NO");
NSLog(@"Sampling interval:%ld", data.samplingInterval);
} else {
NSLog(@"get htSensorConfigation failed");
}
}];
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# Set the configuration parameters of the industrial temperature and humidity sensor
Note that in degrees Celsius units, the temperature is up to 85°C and the minimum is -40°C, and at Fahrenheit, the temperature is up to 185°F and the minimum is -40°F; The maximum humidity is 100 and the minimum is 0. In addition, the upper bound value of the warning interval needs to be greater than or equal to the lower bound value.
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);
/// Set the industrial humidity and temperature sensor configuration
/// @param htSettingDatas Trigger threshold list fixed length 2
/// @param samplingInterval The sampling interval is in milliseconds
/// @param completionHandler the receive block.
[device.connector.sensorHandler setIndustryHTSensorConfiguration:@[model1, model2] SamplingInterval:samplingInterval CompletionHandle:^(BOOL success) {
if (success) {
NSLog(@"setHTWarning success");
}
else {
NSLog(@"setHTWarning 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
# Get the temperature unit
Temperature units are divided into Celsius and Fahrenheit.
/// Device getting temperature unit.
/// @param completionHandler the receive block.
[device.connector.sensorHandler getTemperatureUnit:^(BOOL success, MTITemperatureUnitType unitType) {
if (success) {
NSLog(@"getUnit success");
} else {
NSLog(@"getUnit failed");
}
}];
2
3
4
5
6
7
8
9
# Set the temperature unit
Temperature units are divided into Celsius and Fahrenheit.
Unit conversion: When Celsius is 20, the conversion value to Fahrenheit is 20*1.8+32.
/// Device setting temperature unit.
/// @param temperatureUnitType the device temperature unit type of temperature, MTICelsius 和 MTIFahrenheit
/// @param completionHandler the receive block.
[device.connector.sensorHandler setTemperatureUnit:MTICelsius completionHandler:^(BOOL success) {
if (success) {
NSLog(@"setUnit success");
}
else {
NSLog(@"setUnit failed");
}
}];
2
3
4
5
6
7
8
9
10
11
# Read historical temperature and humidity data
// formatter
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
[formatter setTimeStyle:NSDateFormatterShortStyle];
[formatter setDateFormat:@"YYYY/MM/dd HH:mm:ss"];
//timeZone
NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];
[formatter setTimeZone:timeZone];
// system time
NSDate *currentDate = [NSDate new];
NSTimeInterval currentTimeInterval =[currentDate timeIntervalSince1970];
NSTimeInterval startTimeInterval, endTimeInterval;
// start time
NSString *startTime = @"2023/3/22 9:00:00";
NSDate *startDate = [formatter dateFromString:startTime];
startTimeInterval = [startDate timeIntervalSince1970];
// endTime
NSString *endTime = @"2023/3/31 17:36:00";
NSDate *endDate = [formatter dateFromString:endTime];
endTimeInterval = [endDate timeIntervalSince1970];
// get all history data
// startTimeInterval = 0;
// endTimeInterval = currentTimeInterval;
if (startTimeInterval > endTimeInterval) {
NSLog(@"The end time needs to be greater than the start time, please try again");
return;
}
if (device.connector.connection == Disconnected) {
NSLog(@"IndustrialHistoryVC device disconnected in HTViewController");
return;
}
/// Read historical temperature and humidity data
/// @param formatter the time format you want
/// @param unit temperature unit
/// @param startTimeInterval the start timestamp
/// @param endTimeInterval the end timestamp
/// @param systemTimeInterval the real-time timestamp
/// @param htModel For the device type, only MST01 can be selected for the current version
/// @param completionHandler the receive block
[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(@"Success to read ht history.");
for (int i = 0; i < data.count; i++) {
MTIHistoryData *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
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
# ##### Fireware update
// ⚠️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
Schedule
# MTICentralManager property description
Name | Type | Remark |
---|---|---|
state | PowerState | current iphone bluetooth state |
scannedPeris | NSArray | current scanned devices |
# MTIPeripheral property description
Name | Type | Remark |
---|---|---|
identifier | NSString | Uniquely identifier like "MAC address" |
frameHandler | MTIFrameHandler | advertising stage handler |
connector | MTConnectionHandler | connection stage handler |
# MTIFrameHandler property description
Name | Type | Remark |
---|---|---|
mac | NSString | mac string, sometimes available |
name | NSString | name string, sometimes available |
rssi | NSInteger | current rssi value |
identifier | NSString | unique device identification |
advFrames | NSArray<MTIFrame *> | frame array |
# MTIDeviceInfoFrame property description
Name | Type | Remark |
---|---|---|
firmVersion | NSString | firmware version |
mac | NSString | mac string |
battery | NSInteger | battery |
# MTITempHumiFrame property description
Name | Type | Remark |
---|---|---|
name | NSString | name |
temp | double | Temperature |
humi | double | Humidity |
isMarkStatus | BOOL | Whether the device is marked or not |
temperatureUnit | MTITemperatureUnitType | Temperature unit |
deviceType | MTIDeviceType | HT ;SingleTemp |
deviceWarningStatus | MTIWarningType | Temperature and humidity sensor status, normal/abnormal |
screenStatus | MTIWarningType | seceen status, normal/abnormal |
htModel | MTIHTModel | Device model, currently only MST01 |
# MTConnectionHandler property description
Name | Type | Remark |
---|---|---|
macString | NSString | macString of device |
connection | Connection | current connection status. |
sensorHandler | MTISensorHandler | sensor read and write operation handler |
# MTIHTSensorConfigParm property description
Name | Type | Remark |
---|---|---|
MTIHTSensorWarmingSettingModels | NSString | MTIHTSensorWarmingSettingModel array |
samplingInterval | NSInteger | sampling Interval,ms |
# MTIHTSensorWarmingSettingModel property description
Name | Type | Remark |
---|---|---|
deviceType | MTIDeviceType | device type |
isOpenTempAlarmSwitch | BOOL | temperature alarm switch |
isOpenHumiAlarmSwitch | BOOL | humidity alarm switch |
highTemperature | double | temperature warning upper bound |
lowTemperature | double | temperature warning lower bound |
highHumidity | double | humidity warning upper bound |
lowHumidity | double | humidity warning lower bound |
# MTIAdvertisingParametersData property description
Name | Type | Remark |
---|---|---|
frameType | MTIFrameType | frame type |
advertisingInterval | NSInteger | advertising interval,ms |
advTxpower | NSInteger | txpower,only -40, -20, -16, -12, -8, -4, 0, 4dBm |
isAlwaysAdvertising | BOOL | Whether the broadcast is continuous |
deviceName | BOOL | device name(Only temperature and humidity broadcast frames have this property) |
# 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
- 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
- 2023.04.01 v1.0 first version;