# 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::

  1. Manually

    • Copy the development kit files: MTSensorKit.framework files to the project project directory, and then add them to the project.
  2. PS:

    1. !!! 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".
    2. !!! 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");
    }
}];
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

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.");
    }
}];
1
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");
        }
    }];

1
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");
        }
    }];
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
# 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");
        }
    }];
1
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");
            }
    }];
1
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");
        }
    }];
1
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");
        }
    }];
1
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.");
        }
        
    }];
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
# 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);
    }];
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

# 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");
        }
    }];
1
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");
        }
    }];
1
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");
        }
    }];
1
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");
            }
    }];
1
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");
        }
    }];
1
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");
        }
    }];
1
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

  1. 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.

  2. 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’.

  3. 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;
Last Updated:: 1/12/2024, 6:46:52 PM