Procházet zdrojové kódy

update readme

tags/v2.4
elinkthings před 4 roky
rodič
revize
5314c1260e
2 změnil soubory, kde provedl 4 přidání a 990 odebrání
  1. 4
    483
      README.md
  2. 0
    507
      README_CN.md

+ 4
- 483
README.md Zobrazit soubor

@@ -1,485 +1,6 @@
[中文文档](README_CN.md)

# Inet Body Fat Scale SDK Instructions
En:
http://doc.elinkthings.com/web/#/4?page_id=71


Note: This SDK upgrade to version 2.0 (AIFit-Demo-New) is a major version upgrade with new features and improved stability. Some class names and method names have changed. Not compatible with previous versions. The old version of AIFit-Demo is no longer maintained, please use the new version as much as possible.


## Contents

* Overview
* Conditions of Use
* SDK integration
* Get SDK version
* Get the Bluetooth status of the IOS system
* Get INBluetoothManager working status
* Get AnalysisBLEDataManager working status
* Device Type
* Scan device list
* Broadcast scale interactive process
* Connection scale interactive process
* Version history
* FAQ
* Technical Support


## Overview

* What is the Inet Body Fat Scale SDK?

> Inet Body Fat Scale SDK is a Bluetooth development tool provided to Inet partners. This SDK implements and encapsulates the Inet Bluetooth protocol and is responsible for the communication between the mobile phone App and the Bluetooth body fat scale device. It is designed to facilitate partners to customize themselves. Bluetooth Body Fat Scale Application.


* Scope

> Partners who need to personalize their own iOS Bluetooth Body Fat Scale App.


## Conditions of Use

* 1. Minimum version of iOS 8.0
* 2. The Bluetooth version used by the device needs 4.0 and above
* 3. Support armv7 / i386 / x86_64 / arm64 instruction set;

## SDK integration

* 1. Import InetBleSDK.framework into Xcode project. <br><br>
* 2. Set the following privacy permission usage description in the project's `Info.plist`, and the actual description content is set by each project.

```
<key> NSBluetoothAlwaysUsageDescription </key>
<string> Use bluetooth to connect body fat scale </string>
```

* 3. Firstly, you need config the SDK with key and secret, please see: [http://sdk.aicare.net.cn/](http://sdk.aicare.net.cn/)

```
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//apply sdk key website http://sdk.aicare.net.cn/
[INBluetoothManager configAppKey:@"885fd30a19f54fb0" secret:@"000fec8b4dadbca6a3d4e00875"];
return YES;
}

```

* 4. Import `#import <InetBleSDK/InetBleSDK.h>` in the xxx.m file that needs to use the SDK, and follow the `<INBluetoothManagerDelegate, AnalysisBLEDataManagerDelegate>` protocol, set the proxy, and implement the proxy method.



## Get SDK version

The SDK version number can be obtained by calling the method [INBluetoothManager sdkVersion], and the SDK version number will be automatically printed on the console after the app starts. Example: v2.0-20191225


## Get the Bluetooth status of the IOS system

You can get the Bluetooth state of the system through [BluetoothManagershareManager].bleState
<br>Refer to the CBCentralManagerState enumeration definition for the obtained state.

```
typedef NS_ENUM (NSInteger, CBCentralManagerState) {
CBCentralManagerStateUnknown = CBManagerStateUnknown,
CBCentralManagerStateResetting = CBManagerStateResetting,
CBCentralManagerStateUnsupported = CBManagerStateUnsupported,
CBCentralManagerStateUnauthorized = CBManagerStateUnauthorized,
CBCentralManagerStatePoweredOff = CBManagerStatePoweredOff,
CBCentralManagerStatePoweredOn = CBManagerStatePoweredOn,
}
```

## Get INBluetoothManager working status

Set the agent of the SDK Bluetooth management class [INBluetoothManager shareManager] .delegate = self; and implement the following proxy method to monitor the working status of the Bluetooth management class INBluetoothManager.

```
-(void) BluetoothManager: (INBluetoothManager *) manager updateCentralManagerState: (BluetoothManagerState) state {
}

// BluetoothManagerState enumeration is as follows:
typedef NS_ENUM (NSInteger, BluetoothManagerState) {
    BluetoothManagerState_PowerOn,
    BluetoothManagerState_PowerOff,
    BluetoothManagerState_UnknowErr,
    BluetoothManagerState_StartScan,
    BluetoothManagerState_StopScan,
    BluetoothManagerState_ConnectSuccess,
    BluetoothManagerState_ConnectFailed,
    BluetoothManagerState_Disconnect
};

```

## Get AnalysisBLEDataManager working status

Set the proxy of the data analysis class [AnalysisBLEDataManager shareManager] .infoDelegate = self; and implement the following proxy method to get the working status of the data analysis class AnalysisBLEDataManager

```
-(void) AnalysisBLEDataManager: (AnalysisBLEDataManager *) analysisManager updateBleDataAnalysisStatus: (BleDataAnalysisStatus) bleDataAnalysisStatus {
}

// BleDataAnalysisStatus enumeration is as follows:

/ **
 Note:
 linkScale has all below status, but broadcastScale just has // b1, b2, b3
 * /
typedef NS_ENUM (NSInteger, BleDataAnalysisStatus) {
    
    BleDataAnalysisStatus_SyncTimeSuccess,
    BleDataAnalysisStatus_SyncTimeFailed, // lead to error measureTime
    BleDataAnalysisStatus_SyncUserSuccess,
    BleDataAnalysisStatus_SyncUserFailed, // lead to no bodydata, just weight
    
    BleDataAnalysisStatus_UnstableWeight, // b1
    BleDataAnalysisStatus_StableWeight, // b2
    BleDataAnalysisStatus_MeasureComplete, // b3
    BleDataAnalysisStatus_AdcError,
    
    BleDataAnalysisStatus_LightOff,
};

```


## Device Type

Devices are mainly divided into the following two categories, and the device type can be obtained according to the acNumber attribute of deviceModel called by -BluetoothManager:didDiscoverDevice: proxy method callback.

1. Broadcast scale: acNumber = 0 or acNumber = 1
> * The broadcast scale uses Bluetooth broadcast to transmit data to the outside world and cannot be connected. The broadcast scale is only responsible for determining the user's weight and impedance, and does not calculate any body fat data.<br><br>
> * After the app parses the weight and impedance via Bluetooth broadcast, it calls the corresponding method in the SDK algorithm class AlgorithmSDK to calculate 10 items of body fat data.<br><br>
> * acNumber = 0 is a broadcast scale without temperature, acNumber = 1 is a broadcast scale with temperature. Currently the SDK only supports BM15 broadcast scales.


2. Link scale: acNumber = 2 or acNumber = 3
> * The connection scale is responsible for measuring the user's weight and impedance, and calculating 10 items of body fat data according to the user information issued by the App, and transmitting it to the App via Bluetooth.<br><br>
> * acNumber = 2 is the connected scale without temperature, acNumber = 3 is the connected scale with temperature. At present, the SDK only supports scales with 1 decimal place, and does not support protocols with 2 decimal places and 0xAE.

## Scan device list

```
// SearchDeviceVC.m

@interface SearchDeviceVC () <INBluetoothManagerDelegate>
@end

@implementation SearchDeviceVC

-(void) viewDidLoad
{
    [super viewDidLoad];

    if ([INBluetoothManager shareManager] .bleState == CBCentralManagerStatePoweredOn) {
        [INBluetoothManager shareManager] .delegate = self;
        [[INBluetoothManager shareManager] startBleScan];
    } else {
        NSLog (@ "--- Error: BLE not avalible, pls check.");
    }
}


#pragma mark-BluetoothManagerDelegate

-(void) BluetoothManager: (INBluetoothManager *) manager didDiscoverDevice: (DeviceModel *) deviceModel
{

    if (self.isAddPeripheraling == YES) return;
    
    self.isAddPeripheraling = YES;
    
    BOOL willAdd = YES;
    for (DeviceModel * model in self.peripheralArray) // avoid add the same device
    {
        if ([model.deviceAddress isEqualToString: deviceModel.deviceAddress]
        && [model.deviceName isEqualToString: deviceModel.deviceName])
        {
            willAdd = NO;
        }
    }
    
    if (willAdd) {
        [self.peripheralArray addObject: deviceModel];
        [self.BleTableView reloadData];
    }
    
    self.isAddPeripheraling = NO;
    
}


```

## Broadcast scale interactive process

1. Scan the device list (refer to the “Scan Device List” operation), filter out the broadcast scale model according to acNumber = 0 or acNumber = 1

2. Set the proxy of the data analysis class AnalysisBLEDataManager, follow the data analysis protocol AnalysisBLEDataManagerDelegate, and listen to the corresponding proxy method
```
-(void) AnalysisBLEDataManager: (AnalysisBLEDataManager *) analysisManager updateMeasureUserInfo: (UserInfoModel *) infoModel;
```
3. Call the SDK method [[INBluetoothManager shareManager] handleDataForBroadScale: device]; and start processing broadcast scale data.

4. After performing step 3, the proxy method in step 2 starts to call back infoModel (broadcast scale only measures weight and impedance), plus the user information obtained by the App, calls the algorithm provided by AlgorithmSDK + (AlgorithmModel *) getBodyfatWithWeight: (double ) kgWeight adc: (int) adc sex: (AlgUserSex) sex age: (int) age height: (int) height; Calculate 10 items of body fat data

```
-(void) AnalysisBLEDataManager: (AnalysisBLEDataManager *) analysisManager updateMeasureUserInfo: (UserInfoModel *) infoModel {
    NSLog (@ "--- infoModel:% @", infoModel);
    
    _currentInfoModel = infoModel;
    [self refreshTableView];
    
    if (_currentInfoModel.measureStatus == MeasureStatus_Complete && _currentInfoModel.weightsum> 0 && _currentInfoModel.newAdc> 0) {// Measure Complete
        
        float weight = _currentInfoModel.weightsum / pow (10, _currentInfoModel.weightOriPoint); // 6895-> 68.95
        float adc = _currentInfoModel.newAdc;
        _appUser.weightKg = weight;
        _appUser.adc = adc;
        _userInfoLabel.text = [NSString stringWithFormat: @ "sex:% d \ n age:% d \ n height:% d \ n weight:%. 1f \ n adc:% d", _ appUser.sex, _appUser.age, _appUser .height, _appUser.weightKg, _appUser.adc];
        
        if (_targetDeviceModel.acNumber.intValue <2) {// BroadScale BM15 mesure complete

            AlgorithmModel * algModel = [AlgorithmSDK getBodyfatWithWeight: weight adc: adc sex: _appUser.sex age: _appUser.age height: _appUser.height];
            NSLog (@ "--- BM15 AlgorithmModel:% @", algModel);
            _currentInfoModel.fatRate = algModel.bfr.floatValue;
            _currentInfoModel.BMI = algModel.bmi.floatValue;
            _currentInfoModel.moisture = algModel.vwc.floatValue;
            _currentInfoModel.muscle = algModel.rom.floatValue;
            _currentInfoModel.BMR = algModel.bmr.floatValue;
            _currentInfoModel.boneMass = algModel.bm.floatValue;
            _currentInfoModel.visceralFat = algModel.uvi.floatValue;
            _currentInfoModel.proteinRate = algModel.pp.floatValue;
            _currentInfoModel.physicalAge = algModel.physicalAge.floatValue;
            _currentInfoModel.subcutaneousFat = algModel.sfr.floatValue;
            
            // refresh
            [self refreshTableView];
            
        } else {// connect scale measure complete
            
        }

    }
    
}
```

* 5. If you need to obtain 6 additional physical indicators such as fat-free weight and weight control, please call another algorithm provided by the SDK, BfsCalculateSDK to calculate.

```
    float weight = _currentInfoModel.weightsum / pow (10, _currentInfoModel.weightOriPoint); // 6895-> 68.95
    int sex = _appUser.sex;
    int height = _appUser.height;
    NSString * bfr = [NSString stringWithFormat: @ "%. 1f", _ currentInfoModel.fatRate];
    NSString * rom = [NSString stringWithFormat: @ "%. 1f%", _ currentInfoModel.muscle];
    NSString * pp = [NSString stringWithFormat: @ "%. 1f%", _ currentInfoModel.proteinRate];
    BfsCalculateItem * item = [BfsCalculateSDK getBodyfatItemWithSex: sex height: height weight: weight bfr: bfr rom: rom pp: pp];
    
```


## Connection scale interactive process

`1`. Scan the device list (refer to “Scan Device List” operation), and select the connected scale model according to acNumber = 2 or acNumber = 3

`2`. Set the proxy of the data analysis class AnalysisBLEDataManager, follow the data analysis protocol AnalysisBLEDataManagerDelegate, and listen to the corresponding proxy method

```
-(void) AnalysisBLEDataManager: (AnalysisBLEDataManager *) analysisManager
updateBleDataAnalysisStatus: (BleDataAnalysisStatus) bleDataAnalysisStatus;

-(void) AnalysisBLEDataManager: (AnalysisBLEDataManager *) analysisManager
updateMeasureUserInfo: (UserInfoModel *) infoModel;

/// If no need offline history function, do not implement this callback
-(void) AnalysisBLEDataManager: (AnalysisBLEDataManager *) analysisManager backOfflineHistorys: (NSMutableArray <UserInfoModel *> *) historysMutableArr;

```

`3`. Invoke SDK method [[INBluetoothManager shareManager] connectToLinkScale: device]; try to connect the connected scale device.

`4`. Monitor the working status of the data analysis class BleDataAnalysisStatus_SyncTimeSuccess callback, which means that the connection to the scale is successfully connected, the initialization is completed, and the app can receive interactive instructions. At this time, you need to switch the scale unit to keep in sync with the App, synchronize the information of the user who is about to be weighed, synchronize the offline user list, and request offline history (if you don't need offline function, you can ignore it).



```
- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager
updateBleDataAnalysisStatus:(BleDataAnalysisStatus)bleDataAnalysisStatus {
switch (bleDataAnalysisStatus) {
case BleDataAnalysisStatus_SyncTimeSuccess:
{
_tipLB.text = @"sync time success";
//set unit
[self ChooseUnit:self.unitSegmentedControl];
//then sync user to be weighing
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self syncWeighingUserToBle];
});

//sync offline userlist(If no need offline history function, do not call this method)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self syncOfflineUserListToBle];
});
//request history (If no need offline history function, do not call this method)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[WriteToBLEManager shareManager] requestOfflineHistory];
});

break;
}
case BleDataAnalysisStatus_SyncTimeFailed:
{
_tipLB.text = @"sync time failed";
break;
}
case BleDataAnalysisStatus_SyncUserSuccess:
{
_tipLB.text = @"sync weighing user success";
break;
}
case BleDataAnalysisStatus_SyncUserFailed:
{
_tipLB.text = @"sync weighing user failed";
break;
}
case BleDataAnalysisStatus_UnstableWeight:
{
_tipLB.text = @"measuring...\nUnstable Weight";
break;
}
case BleDataAnalysisStatus_StableWeight:
{
_tipLB.text = @"Stable Weight";
break;
}
case BleDataAnalysisStatus_MeasureComplete:
{
_tipLB.text = @"measure complete";
break;
}
case BleDataAnalysisStatus_AdcError:
{
_tipLB.text = @"adc measure failed";
break;
}
case BleDataAnalysisStatus_LightOff:
{
_tipLB.text = @"your linkScale light off";
break;
}
default:
break;
}
}

```

`5`. After executing step 3, the proxy method set in step 2 starts to call back the weight information model infoModel. The App performs secondary processing on the received data and refreshes the UI interface. At the same time, it is necessary to determine the end of the measurement, and send instructions to update the current and offline user list information.

```
- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager updateMeasureUserInfo:(UserInfoModel *)infoModel {
NSLog(@"---infoModel:%@",infoModel);
_currentInfoModel = infoModel;
[self refreshTableView];
if (_currentInfoModel.measureStatus == MeasureStatus_Complete && _currentInfoModel.weightsum > 0 && _currentInfoModel.newAdc > 0) { //Measure Complete
float weight = _currentInfoModel.weightsum/pow(10, _currentInfoModel.weightOriPoint);//6895->68.95
float adc = _currentInfoModel.newAdc;
_appUser.weightKg = weight;
_appUser.adc = adc;
_userInfoLabel.text = [NSString stringWithFormat:@" sex:%d\n age:%d\n height:%d\n weight:%.1f\n adc:%d",_appUser.sex,_appUser.age,_appUser.height,_appUser.weightKg,_appUser.adc];
if (_targetDeviceModel.acNumber.intValue < 2) { //BroadScale BM15 mesure complete
} else { //connect scale measure complete
[self syncWeighingUserToBle];
// If no need offline history function, do not call this method
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self syncOfflineUserListToBle];
});
}

}
}

```

`6`. If you need to obtain 6 additional physical indicators such as fat-free weight and weight control, please call another algorithm provided by the SDK, BfsCalculateSDK to calculate.

```
float weight = _currentInfoModel.weightsum/pow(10, _currentInfoModel.weightOriPoint);//6895->68.95
int sex = _appUser.sex;
int height = _appUser.height;
NSString *bfr = [NSString stringWithFormat:@"%.1f",_currentInfoModel.fatRate];
NSString *rom = [NSString stringWithFormat:@"%.1f%",_currentInfoModel.muscle];
NSString *pp = [NSString stringWithFormat:@"%.1f%",_currentInfoModel.proteinRate];
BfsCalculateItem *item = [BfsCalculateSDK getBodyfatItemWithSex:sex height:height
weight:weight bfr:bfr rom:rom pp:pp];
```


## Version history

Version number | Update time | Author | Update information |
| --- | --- | --- | --- |
| v1.0 | 9/10 2018 | wz | Preliminary version |
v1.1 | 2019/02/27 | wz | Add impedance measurement failure callback and Log switch |
| v1.2 | 2019/04/25 | wz | Added BM15 algorithm interface |
| v1.3 | 2019/08/12 | wz | Optimize Bluetooth connection |
V1.4 | 2019/10/29 | wz | IOS13 compatible system |
V1.5 | 2019/12/20 | wz | Add offline history function |
V2.0 | 2019/12/25 | wz | Feature update: <br> 1. Modify the BluetoothManager class name to INBluetoothManager to avoid conflicts with the system's private APIs. <br> 2. Standardize methods and properties in AlgorithmSDK and AlgorithmModel classes. br> 3. Added BfsCalculateSDK algorithm, which can obtain additional data for calculating body fat data <br> 4. Automatically read the DID of the scale <br> 5. Fix bugs found during testing |
| V2.1 | 2020/04/20 | wz | Added support for connection scales with 2 decimal |


## FAQ

> Q: How to tell whether the currently scanned DeviceModel is a broadcast scale or a connected scale?

> A: According to the acNumber property value of DeviceModel: acNumber = 0 is a broadcast scale without temperature, acNumber = 1 is a broadcast scale with temperature. acNumber = 2 is the connected scale without temperature, acNumber = 3 is the connected scale with temperature.

> Q: How to judge the end of the measurement?

> A: According to the UserInfoModel * infoModel property.measureStatus of the data analysis class proxy method callback.
>
```
typedef NS_ENUM (NSInteger, MeasureStatus) {
    MeasureStatus_Unstable = 0,
    MeasureStatus_Stable,
    MeasureStatus_Complete,
    MeasureStatus_OfflineHistory,
};
```

> Q: Which units does the Bluetooth protocol support?
>
> A: The unit only supports up to 4 types (kg, lb, st, catty). For details about what units are supported, please refer to the factory settings of the scale.



## Technical Support

Wuz

Inet App Manager

inet_support@163.com
CN:
http://doc.elinkthings.com/web/#/4?page_id=24

+ 0
- 507
README_CN.md Zobrazit soubor

@@ -1,507 +0,0 @@
[README_EN](README.md)
# Inet体脂秤SDK使用说明


注意:本次SDK升级为2.0(AIFit-Demo-New),是大版本升级,新增功能,提升稳定性,部分类名和方法名发生了变化,将不再兼容之前的版本。旧版本AIFit-Demo不再维护,请尽量使用新版本。


## 目录

* 概述
* 使用条件
* SDK集成
* 获取SDK版本号
* 获取IOS系统蓝牙状态
* 获取INBluetoothManager工作状态
* 获取AnalysisBLEDataManager工作状态
* 设备类型
* 扫描设备列表
* 广播秤交互流程
* 连接秤交互流程
* 版本历史
* FAQ
* 技术支持


## 概述

* 什么是Inet体脂秤SDK ?

> Inet体脂秤SDK 是提供给Inet合作伙伴的蓝牙开发工具,该SDK对Inet蓝牙协议进行了实现和封装,负责手机App与蓝牙体脂秤设备之间的通信,旨在方便合作伙伴定制自己的蓝牙体脂秤应用。


* 适用范围

> 需要个性化定制自己的 iOS 蓝牙体脂秤 APP 的合作伙伴。


## 使用条件

1. 最低版本iOS 8.0
2. 设备所使用的蓝牙版本需要4.0及以上
3. 支持armv7/i386/x86_64/arm64指令集;

## SDK集成

1. 将InetBleSDK.framework导入Xcode工程。
2. 在项目的`Info.plist`中设置以下隐私权限使用描述,实际描述内容各项目自行设置

```
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Use bluetooth to connect body fat scale</string>
```
3. 首先给SDK配置key和secret,申请地址为:[http://sdk.aicare.net.cn/](http://sdk.aicare.net.cn/)

```
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//apply sdk key website http://sdk.aicare.net.cn/
[INBluetoothManager configAppKey:@"885fd30a19f54fb0" secret:@"000fec8b4dadbca6a3d4e00875"];
return YES;
}
```
4. 在需要使用SDK的类.m文件中导入#import \<InetBleSDK/InetBleSDK.h>,并遵守\<INBluetoothManagerDelegate,AnalysisBLEDataManagerDelegate>协议,设置代理,实现代理方法。


## 获取SDK版本号
通过调用方法[INBluetoothManager sdkVersion]可获取SDK版本号,同时App启动后会自动在控制台打印SDK版本号。例如:v2.0-20191225


## 获取IOS系统蓝牙状态
通过[BluetoothManagershareManager].bleState可以获取系统蓝牙状态,获取的状态参考CBCentralManagerState枚举定义。

```
typedef NS_ENUM(NSInteger, CBCentralManagerState) {
CBCentralManagerStateUnknown = CBManagerStateUnknown,
CBCentralManagerStateResetting = CBManagerStateResetting,
CBCentralManagerStateUnsupported = CBManagerStateUnsupported,
CBCentralManagerStateUnauthorized = CBManagerStateUnauthorized,
CBCentralManagerStatePoweredOff = CBManagerStatePoweredOff,
CBCentralManagerStatePoweredOn = CBManagerStatePoweredOn,
}
```

## 获取INBluetoothManager工作状态

设置SDK蓝牙管理类的代理[INBluetoothManager shareManager].delegate = self; 并实现如下代理方法,,即可监听蓝牙管理类INBluetoothManager的工作状态。

```
- (void)BluetoothManager:(INBluetoothManager *)manager updateCentralManagerState:(BluetoothManagerState)state {
}

//BluetoothManagerState枚举如下:
typedef NS_ENUM(NSInteger,BluetoothManagerState) {
BluetoothManagerState_PowerOn,
BluetoothManagerState_PowerOff,
BluetoothManagerState_UnknowErr,
BluetoothManagerState_StartScan,
BluetoothManagerState_StopScan,
BluetoothManagerState_ConnectSuccess,
BluetoothManagerState_ConnectFailed,
BluetoothManagerState_Disconnect
};

```

## 获取AnalysisBLEDataManager工作状态
设置数据解析类的代理[AnalysisBLEDataManager shareManager].infoDelegate = self; 并实现如下代理方法,即可获取数据解析类AnalysisBLEDataManager的工作状态

```
- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager updateBleDataAnalysisStatus:(BleDataAnalysisStatus)bleDataAnalysisStatus {
}

//BleDataAnalysisStatus枚举如下:

/**
Note:
linkScale has all below status, but broadcastScale just has //b1,b2,b3
*/
typedef NS_ENUM(NSInteger, BleDataAnalysisStatus) {
BleDataAnalysisStatus_SyncTimeSuccess,
BleDataAnalysisStatus_SyncTimeFailed, //lead to error measureTime
BleDataAnalysisStatus_SyncUserSuccess,
BleDataAnalysisStatus_SyncUserFailed, //lead to no bodydata, just weight
BleDataAnalysisStatus_UnstableWeight, //b1
BleDataAnalysisStatus_StableWeight, //b2
BleDataAnalysisStatus_MeasureComplete, //b3
BleDataAnalysisStatus_AdcError,
BleDataAnalysisStatus_LightOff,
};

```


## 设备类型

设备主要分为以下两大类,可根据-BluetoothManager:didDiscoverDevice:代理方法回调的deviceModel的属性acNumber来获取设备类型。

1. 广播秤(broadcast scale):acNumber=0 或 acNumber=1
> * 广播秤使用蓝牙广播对外界传输数据,不可以被连接。广播秤仅负责测定用户的体重和阻抗,不会计算任何体脂数据。
> * App通过蓝牙广播解析到体重和阻抗后,调用SDK算法类AlgorithmSDK中的对应方法,计算出10项体脂数据。。
> * acNumber=0是不带温度的广播秤,acNumber=1是有温度的广播秤。目前SDK仅支持BM15广播秤。


2. 连接秤(link scale):acNumber=2 或 acNumber=3
> * 连接秤负责测定用户的体重和阻抗,并根据App下发的用户信息计算出10项体脂数据,通过蓝牙传输给App。
> * acNumber=2是不带温度的连接秤,acNumber=3是有温度的连接秤。 目前SDK仅支持1位小数的连接秤,不支持2位小数及0xAE开头的协议。

## 扫描设备列表

```
// SearchDeviceVC.m

@interface SearchDeviceVC () <INBluetoothManagerDelegate>
@end

@implementation SearchDeviceVC

- (void)viewDidLoad
{
[super viewDidLoad];

if ([INBluetoothManager shareManager].bleState == CBCentralManagerStatePoweredOn) {
[INBluetoothManager shareManager].delegate = self;
[[INBluetoothManager shareManager] startBleScan];
} else {
NSLog(@"---Error: BLE not avalible, pls check.");
}
}


#pragma mark - BluetoothManagerDelegate

- (void)BluetoothManager:(INBluetoothManager *)manager didDiscoverDevice:(DeviceModel *)deviceModel
{

if (self.isAddPeripheraling == YES) return;
self.isAddPeripheraling = YES;
BOOL willAdd = YES;
for (DeviceModel *model in self.peripheralArray) //avoid add the same device
{
if ([model.deviceAddress isEqualToString:deviceModel.deviceAddress] && [model.deviceName isEqualToString:deviceModel.deviceName])
{
willAdd = NO;
}
}
if (willAdd) {
[self.peripheralArray addObject:deviceModel];
[self.BleTableView reloadData];
}
self.isAddPeripheraling = NO;
}


```


## 广播秤交互流程
* 1.扫描设备列表(参考“扫描设备列表”操作),根据acNumber=0或acNumber=1筛选出广播秤模型

* 2.设置数据解析类AnalysisBLEDataManager的代理,遵守数据解析协议AnalysisBLEDataManagerDelegate,监听相应的代理方法

```
- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager
updateMeasureUserInfo:(UserInfoModel *)infoModel;
```

* 3.调用SDK方法[[INBluetoothManager shareManager] handleDataForBroadScale:device];开始处理广播秤数据。

* 4.执行完步骤3操作后,步骤2中代理方法开始回调infoModel(广播秤仅测定体重和阻抗),加上App获取的用户信息,调用AlgorithmSDK提供的算法 + (AlgorithmModel *)getBodyfatWithWeight:(double)kgWeight adc:(int)adc sex:(AlgUserSex)sex age:(int)age height:(int)height; 计算出10项体脂数据

```
- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager updateMeasureUserInfo:(UserInfoModel *)infoModel {
NSLog(@"---infoModel:%@",infoModel);
_currentInfoModel = infoModel;
[self refreshTableView];
if (_currentInfoModel.measureStatus == MeasureStatus_Complete && _currentInfoModel.weightsum > 0 && _currentInfoModel.newAdc > 0) { //Measure Complete
float weight = _currentInfoModel.weightsum/pow(10, _currentInfoModel.weightOriPoint);//6895->68.95
float adc = _currentInfoModel.newAdc;
_appUser.weightKg = weight;
_appUser.adc = adc;
_userInfoLabel.text = [NSString stringWithFormat:@" sex:%d\n age:%d\n height:%d\n weight:%.1f\n adc:%d",_appUser.sex,_appUser.age,_appUser.height,_appUser.weightKg,_appUser.adc];
if (_targetDeviceModel.acNumber.intValue < 2) { //BroadScale BM15 mesure complete

AlgorithmModel *algModel = [AlgorithmSDK getBodyfatWithWeight:weight adc:adc sex:_appUser.sex age:_appUser.age height:_appUser.height];
NSLog(@"---BM15 AlgorithmModel: %@",algModel);
_currentInfoModel.fatRate = algModel.bfr.floatValue;
_currentInfoModel.BMI = algModel.bmi.floatValue;
_currentInfoModel.moisture = algModel.vwc.floatValue;
_currentInfoModel.muscle = algModel.rom.floatValue;
_currentInfoModel.BMR = algModel.bmr.floatValue;
_currentInfoModel.boneMass = algModel.bm.floatValue;
_currentInfoModel.visceralFat = algModel.uvi.floatValue;
_currentInfoModel.proteinRate = algModel.pp.floatValue;
_currentInfoModel.physicalAge = algModel.physicalAge.floatValue;
_currentInfoModel.subcutaneousFat = algModel.sfr.floatValue;
//refresh
[self refreshTableView];
} else { //connect scale measure complete
}

}
}
```

* 5.如需要获取 去脂体重、体重控制量等额外的6项身体指标,请调用SDK提供的另外一个算法BfsCalculateSDK中方法计算。

```
float weight = _currentInfoModel.weightsum/pow(10, _currentInfoModel.weightOriPoint);//6895->68.95
int sex = _appUser.sex;
int height = _appUser.height;
NSString *bfr = [NSString stringWithFormat:@"%.1f",_currentInfoModel.fatRate];
NSString *rom = [NSString stringWithFormat:@"%.1f%",_currentInfoModel.muscle];
NSString *pp = [NSString stringWithFormat:@"%.1f%",_currentInfoModel.proteinRate];
BfsCalculateItem *item = [BfsCalculateSDK getBodyfatItemWithSex:sex height:height weight:weight bfr:bfr rom:rom pp:pp];
```


## 连接秤交互流程

* 1.扫描设备列表(参考“扫描设备列表”操作),根据acNumber=2或acNumber=3筛选出连接秤模型

* 2.设置数据解析类AnalysisBLEDataManager的代理,遵守数据解析协议AnalysisBLEDataManagerDelegate,监听相应的代理方法

```
- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager
updateBleDataAnalysisStatus:(BleDataAnalysisStatus)bleDataAnalysisStatus;

- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager
updateMeasureUserInfo:(UserInfoModel *)infoModel;

///If no need offline history function, do not implement this callback
- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager backOfflineHistorys:(NSMutableArray <UserInfoModel *> *)historysMutableArr;

```

* 3.调用SDK方法[[INBluetoothManager shareManager] connectToLinkScale:device];尝试连接该连接秤设备。

* 4.监听数据解析类的工作状态BleDataAnalysisStatus_SyncTimeSuccess回调,即代表连接秤连接成功,完成初始化设置,可接收App交互指令。此时需要切换秤的单位与App保持同步,同步当前即将称重那个用户的信息,同步离线用户列表和请求离线历史记录(如无需离线功能,可忽略)。

```
- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager
updateBleDataAnalysisStatus:(BleDataAnalysisStatus)bleDataAnalysisStatus {
switch (bleDataAnalysisStatus) {
case BleDataAnalysisStatus_SyncTimeSuccess:
{
_tipLB.text = @"sync time success";
//set unit
[self ChooseUnit:self.unitSegmentedControl];
//then sync user to be weighing
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self syncWeighingUserToBle];
});

//sync offline userlist(If no need offline history function, do not call this method)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self syncOfflineUserListToBle];
});
//request history (If no need offline history function, do not call this method)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
(int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[[WriteToBLEManager shareManager] requestOfflineHistory];
});

break;
}
case BleDataAnalysisStatus_SyncTimeFailed:
{
_tipLB.text = @"sync time failed";
break;
}
case BleDataAnalysisStatus_SyncUserSuccess:
{
_tipLB.text = @"sync weighing user success";
break;
}
case BleDataAnalysisStatus_SyncUserFailed:
{
_tipLB.text = @"sync weighing user failed";
break;
}
case BleDataAnalysisStatus_UnstableWeight:
{
_tipLB.text = @"measuring...\nUnstable Weight";
break;
}
case BleDataAnalysisStatus_StableWeight:
{
_tipLB.text = @"Stable Weight";
break;
}
case BleDataAnalysisStatus_MeasureComplete:
{
_tipLB.text = @"measure complete";
break;
}
case BleDataAnalysisStatus_AdcError:
{
_tipLB.text = @"adc measure failed";
break;
}
case BleDataAnalysisStatus_LightOff:
{
_tipLB.text = @"your linkScale light off";
break;
}
default:
break;
}
}

```

* 5.执行完步骤3操作后,步骤2中设置的代理方法开始回调体重信息模型infoModel,App对接收的数据进行二次加工,并刷新UI界面。同时需判定测量结束,发送指令更新当前用户及离线用户列表信息。

```
- (void)AnalysisBLEDataManager:(AnalysisBLEDataManager *)analysisManager updateMeasureUserInfo:(UserInfoModel *)infoModel {
NSLog(@"---infoModel:%@",infoModel);
_currentInfoModel = infoModel;
[self refreshTableView];
if (_currentInfoModel.measureStatus == MeasureStatus_Complete && _currentInfoModel.weightsum > 0 && _currentInfoModel.newAdc > 0) { //Measure Complete
float weight = _currentInfoModel.weightsum/pow(10, _currentInfoModel.weightOriPoint);//6895->68.95
float adc = _currentInfoModel.newAdc;
_appUser.weightKg = weight;
_appUser.adc = adc;
_userInfoLabel.text = [NSString stringWithFormat:@" sex:%d\n age:%d\n height:%d\n weight:%.1f\n adc:%d",_appUser.sex,_appUser.age,_appUser.height,_appUser.weightKg,_appUser.adc];
if (_targetDeviceModel.acNumber.intValue < 2) { //BroadScale BM15 mesure complete
} else { //connect scale measure complete
[self syncWeighingUserToBle];
// If no need offline history function, do not call this method
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self syncOfflineUserListToBle];
});
}

}
}

```

* 6.如需要获取 去脂体重、体重控制量等额外的6项身体指标,请调用SDK提供的另外一个算法BfsCalculateSDK中方法计算。

```
float weight = _currentInfoModel.weightsum/pow(10, _currentInfoModel.weightOriPoint);//6895->68.95
int sex = _appUser.sex;
int height = _appUser.height;
NSString *bfr = [NSString stringWithFormat:@"%.1f",_currentInfoModel.fatRate];
NSString *rom = [NSString stringWithFormat:@"%.1f%",_currentInfoModel.muscle];
NSString *pp = [NSString stringWithFormat:@"%.1f%",_currentInfoModel.proteinRate];
BfsCalculateItem *item = [BfsCalculateSDK getBodyfatItemWithSex:sex height:height
weight:weight bfr:bfr rom:rom pp:pp];
```


## 版本历史

| 版本号 | 更新时间 | 作者 | 更新信息 |
| --- | --- | --- | --- |
| v1.0 | 2018/9/10 | wz | 初步版本 |
| v1.1 | 2019/02/27 | wz | 新增阻抗测量失败回调及Log开关 |
| v1.2 | 2019/04/25 | wz | 新增BM15算法接口 |
| v1.3 | 2019/08/12 | wz | 优化蓝牙连接 |
| V1.4 | 2019/10/29 | wz | 兼容IOS13系统 |
| V1.5 | 2019/12/20 | wz | 添加离线历史记录功能 |
| V2.0 | 2019/12/25 | wz | 功能更新:<br>1.修改BluetoothManager类名为INBluetoothManager,避免与系统私有API冲突 <br>2.规范AlgorithmSDK和AlgorithmModel类中方法及属性命名 <br>3.新增BfsCalculateSDK算法,可获取额外的计算体脂数据数据 <br>4.自动读取秤的DID <br>5.修复测试发现的bug |
| V2.1 | 2020/04/20 | wz | 增加对2位小数的连接秤的支持 |


## FAQ

+ 1: 如何判断区分当前扫描到的DeviceModel是广播秤还是连接秤?
答:根据DeviceModel的acNumber属性值区分:acNumber=0是不带温度的广播秤,acNumber=1是有温度的广播秤。acNumber=2是不带温度的连接秤,acNumber=3是有温度的连接秤。

+ 2: 如何判定测量结束?
答:根据数据解析类代理方法回调的 UserInfoModel *infoModel属性.measureStatus来判定
```
typedef NS_ENUM(NSInteger, MeasureStatus) {
MeasureStatus_Unstable = 0,
MeasureStatus_Stable,
MeasureStatus_Complete,
MeasureStatus_OfflineHistory,
};
```

+ 3: 蓝牙协议支持哪些单位?

答:单位最多只支持4种(kg,lb,st,斤),具体支持什么单位请参照秤的出厂设置。
+ 4: 扫描不到蓝牙设备?
答:A.拔掉电池重启秤 B.检查秤是否已被其他手机连接,要求其断开(秤未被连接时,秤盘上蓝牙图标会不断闪烁)
+ 5: 支持哪些设备?
答:支持BM系列的连接秤、BM15广播秤
+ 6: 为什么只能测到体重,没有其他体脂数据?
答:必须脱掉鞋和袜子,光脚站在体脂秤的电极片上,才能测出体脂数据。
+ 7: 称量时秤总是显示Error,app显示阻抗测量失败,是什么原因?
答:脱掉鞋和袜子,光脚站在体脂秤的电极片上测量,就不会再显示Error。
+ 8: 如何高效的向技术支持人员提供反馈?
答:1.SDK会在控制台打印log,反馈问题时请先将log保存为txt,发给技术人员
2. 反馈问题时,尽可能将问题出现时的前后操作描述清楚,最好能录制视频告知问题如何复现。
+ 9: 是否有各项体脂数据的判定标准和文案呢?
答:体脂判定标准各厂商标准都可能不一样,目前并没有行业公认的参考标准。如下是我司使用的标准,仅供参考:
《蓝牙体脂秤判定标准及小程序文案20200416》[https://shimo.im/sheets/8dGqCgyhX9P6Xpcw/GX3qk/](https://shimo.im/sheets/8dGqCgyhX9P6Xpcw/GX3qk/)



## 联系我们

深圳市易连物联网有限公司

电话:0755-81773367

官网:www.elinkthings.com

邮箱:app@elinkthings.com

Načítá se…
Zrušit
Uložit