瀏覽代碼

增加: 广播身高仪 食物探针 食物探针盒子 支持

tags/v1.6.1^0
larryzhang 1 年之前
父節點
當前提交
7ee3347a60
共有 38 個檔案被更改,包括 1776 行新增619 行删除
  1. 80
    4
      AILinkBleSDKDemo.xcodeproj/project.pbxproj
  2. 二進制
      AILinkBleSDKDemo/AILinkBleSDK.framework/AILinkBleSDK
  3. 1
    6
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/AILinkBleSDK-umbrella.h
  4. 1
    1
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/AILinkBleSDK_Version.h
  5. 0
    136
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAILinkBleManager+AirDetector.h
  6. 3
    7
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAILinkBleManager+MeatProbe.h
  7. 0
    5
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAILinkBleManager+WIFI.h
  8. 5
    9
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAILinkBleManager.h
  9. 0
    126
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleFunctionModel.h
  10. 0
    63
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleHeader.h
  11. 0
    32
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleParser.h
  12. 0
    113
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleSettingModel.h
  13. 0
    117
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleStatusModel.h
  14. 49
    0
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBfsOKOKDataModel.h
  15. 2
    0
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBleDisposeDataTool.h
  16. 3
    0
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBluetoothManager+Settings_Callback.h
  17. 1
    0
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBluetoothManager.h
  18. 2
    0
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBroadcastScaleDataModel.h
  19. 6
    0
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELExSupportDeviceType.h
  20. 45
    0
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELSDKHeader.h
  21. 3
    0
      AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ElBloodBleWifiManager.h
  22. 二進制
      AILinkBleSDKDemo/AILinkBleSDK.framework/Info.plist
  23. 17
    0
      AILinkBleSDKDemo/DeviceDemo/06B_BroadcastHeightGuage/BroadcastHeightGuage.h
  24. 127
    0
      AILinkBleSDKDemo/DeviceDemo/06B_BroadcastHeightGuage/BroadcastHeightGuage.m
  25. 101
    0
      AILinkBleSDKDemo/DeviceDemo/06B_BroadcastHeightGuage/BroadcastHeightGuage.xib
  26. 21
    0
      AILinkBleSDKDemo/DeviceDemo/26_MeatProbe/MeatProbeVC.h
  27. 261
    0
      AILinkBleSDKDemo/DeviceDemo/26_MeatProbe/MeatProbeVC.m
  28. 145
    0
      AILinkBleSDKDemo/DeviceDemo/26_MeatProbe/MeatProbeVC.xib
  29. 27
    0
      AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELAILinkBleManager+MeatProbeBox.h
  30. 55
    0
      AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELAILinkBleManager+MeatProbeBox.m
  31. 23
    0
      AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELMeatProbeBoxBleHeader.h
  32. 102
    0
      AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELMeatProbeBoxBleParser.h
  33. 228
    0
      AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELMeatProbeBoxBleParser.m
  34. 21
    0
      AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/MeatProbeBoxVC.h
  35. 292
    0
      AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/MeatProbeBoxVC.m
  36. 145
    0
      AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/MeatProbeBoxVC.xib
  37. 9
    0
      AILinkBleSDKDemo/Others/ViewController.m
  38. 1
    0
      README.md

+ 80
- 4
AILinkBleSDKDemo.xcodeproj/project.pbxproj 查看文件

@@ -22,6 +22,14 @@
78DC4DF62990FB40006C6911 /* ELDeviceScanCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 78DC4DF02990FB40006C6911 /* ELDeviceScanCell.xib */; };
78DC4DFB2990FC10006C6911 /* HeightBodyFatScaleVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 78DC4DF82990FC10006C6911 /* HeightBodyFatScaleVC.m */; };
78DC4DFC2990FC10006C6911 /* HeightBodyFatScaleVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 78DC4DF92990FC10006C6911 /* HeightBodyFatScaleVC.xib */; };
78E07B6A2A49664000E68200 /* BroadcastHeightGuage.m in Sources */ = {isa = PBXBuildFile; fileRef = 78E07B672A49663F00E68200 /* BroadcastHeightGuage.m */; };
78E07B6B2A49664000E68200 /* BroadcastHeightGuage.xib in Resources */ = {isa = PBXBuildFile; fileRef = 78E07B682A49663F00E68200 /* BroadcastHeightGuage.xib */; };
78E07B7A2A49664E00E68200 /* MeatProbeVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 78E07B6D2A49664D00E68200 /* MeatProbeVC.m */; };
78E07B7B2A49664E00E68200 /* MeatProbeVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 78E07B6E2A49664D00E68200 /* MeatProbeVC.xib */; };
78E07B7C2A49664E00E68200 /* ELAILinkBleManager+MeatProbeBox.m in Sources */ = {isa = PBXBuildFile; fileRef = 78E07B742A49664E00E68200 /* ELAILinkBleManager+MeatProbeBox.m */; };
78E07B7D2A49664E00E68200 /* ELMeatProbeBoxBleParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 78E07B752A49664E00E68200 /* ELMeatProbeBoxBleParser.m */; };
78E07B7E2A49664E00E68200 /* MeatProbeBoxVC.xib in Resources */ = {isa = PBXBuildFile; fileRef = 78E07B782A49664E00E68200 /* MeatProbeBoxVC.xib */; };
78E07B7F2A49664E00E68200 /* MeatProbeBoxVC.m in Sources */ = {isa = PBXBuildFile; fileRef = 78E07B792A49664E00E68200 /* MeatProbeBoxVC.m */; };
952D19A1276DE80000ED3A0C /* AILinkBleSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 952D19A0276DE80000ED3A0C /* AILinkBleSDK.framework */; };
95565B792786EA3B000265EA /* SkipConnectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 95565B752786EA3B000265EA /* SkipConnectionViewController.m */; };
95565B7A2786EA3B000265EA /* SkipScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 95565B782786EA3B000265EA /* SkipScanViewController.m */; };
@@ -133,6 +141,20 @@
78DC4DF82990FC10006C6911 /* HeightBodyFatScaleVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HeightBodyFatScaleVC.m; sourceTree = "<group>"; };
78DC4DF92990FC10006C6911 /* HeightBodyFatScaleVC.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = HeightBodyFatScaleVC.xib; sourceTree = "<group>"; };
78DC4DFA2990FC10006C6911 /* HeightBodyFatScaleVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeightBodyFatScaleVC.h; sourceTree = "<group>"; };
78E07B672A49663F00E68200 /* BroadcastHeightGuage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BroadcastHeightGuage.m; sourceTree = "<group>"; };
78E07B682A49663F00E68200 /* BroadcastHeightGuage.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = BroadcastHeightGuage.xib; sourceTree = "<group>"; };
78E07B692A49663F00E68200 /* BroadcastHeightGuage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BroadcastHeightGuage.h; sourceTree = "<group>"; };
78E07B6D2A49664D00E68200 /* MeatProbeVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MeatProbeVC.m; sourceTree = "<group>"; };
78E07B6E2A49664D00E68200 /* MeatProbeVC.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MeatProbeVC.xib; sourceTree = "<group>"; };
78E07B6F2A49664D00E68200 /* MeatProbeVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MeatProbeVC.h; sourceTree = "<group>"; };
78E07B722A49664E00E68200 /* ELMeatProbeBoxBleParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ELMeatProbeBoxBleParser.h; sourceTree = "<group>"; };
78E07B732A49664E00E68200 /* ELMeatProbeBoxBleHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ELMeatProbeBoxBleHeader.h; sourceTree = "<group>"; };
78E07B742A49664E00E68200 /* ELAILinkBleManager+MeatProbeBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ELAILinkBleManager+MeatProbeBox.m"; sourceTree = "<group>"; };
78E07B752A49664E00E68200 /* ELMeatProbeBoxBleParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ELMeatProbeBoxBleParser.m; sourceTree = "<group>"; };
78E07B762A49664E00E68200 /* ELAILinkBleManager+MeatProbeBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ELAILinkBleManager+MeatProbeBox.h"; sourceTree = "<group>"; };
78E07B772A49664E00E68200 /* MeatProbeBoxVC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MeatProbeBoxVC.h; sourceTree = "<group>"; };
78E07B782A49664E00E68200 /* MeatProbeBoxVC.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MeatProbeBoxVC.xib; sourceTree = "<group>"; };
78E07B792A49664E00E68200 /* MeatProbeBoxVC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MeatProbeBoxVC.m; sourceTree = "<group>"; };
952D19A0276DE80000ED3A0C /* AILinkBleSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = AILinkBleSDK.framework; sourceTree = "<group>"; };
95565B752786EA3B000265EA /* SkipConnectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SkipConnectionViewController.m; sourceTree = "<group>"; };
95565B762786EA3B000265EA /* SkipScanViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SkipScanViewController.h; sourceTree = "<group>"; };
@@ -309,6 +331,7 @@
955725E0276C38CC003BFBAC /* 04_BabyScale */,
955725BA276C38CC003BFBAC /* 05_BloodPressure */,
955725E5276C38CC003BFBAC /* 06_HeightGuage */,
78E07B662A49663F00E68200 /* 06B_BroadcastHeightGuage */,
9557261E276C38CD003BFBAC /* 07_RemoteControl */,
95572614276C38CD003BFBAC /* 08_Forehead */,
955725F9276C38CD003BFBAC /* 09_Thermometer */,
@@ -329,6 +352,8 @@
955725F4276C38CD003BFBAC /* 23_FaceMask */,
95565B742786EA3B000265EA /* 24_Skip */,
78DC4DF72990FC10006C6911 /* 25_HeightBodyFatScale */,
78E07B6C2A49664D00E68200 /* 26_MeatProbe */,
78E07B702A49664E00E68200 /* 27_MeatProbeBox */,
);
path = DeviceDemo;
sourceTree = "<group>";
@@ -395,6 +420,49 @@
path = AILinkBleSDKDemo/DeviceDemo/25_HeightBodyFatScale;
sourceTree = SOURCE_ROOT;
};
78E07B662A49663F00E68200 /* 06B_BroadcastHeightGuage */ = {
isa = PBXGroup;
children = (
78E07B692A49663F00E68200 /* BroadcastHeightGuage.h */,
78E07B672A49663F00E68200 /* BroadcastHeightGuage.m */,
78E07B682A49663F00E68200 /* BroadcastHeightGuage.xib */,
);
path = 06B_BroadcastHeightGuage;
sourceTree = "<group>";
};
78E07B6C2A49664D00E68200 /* 26_MeatProbe */ = {
isa = PBXGroup;
children = (
78E07B6F2A49664D00E68200 /* MeatProbeVC.h */,
78E07B6D2A49664D00E68200 /* MeatProbeVC.m */,
78E07B6E2A49664D00E68200 /* MeatProbeVC.xib */,
);
path = 26_MeatProbe;
sourceTree = "<group>";
};
78E07B702A49664E00E68200 /* 27_MeatProbeBox */ = {
isa = PBXGroup;
children = (
78E07B712A49664E00E68200 /* Ble */,
78E07B772A49664E00E68200 /* MeatProbeBoxVC.h */,
78E07B792A49664E00E68200 /* MeatProbeBoxVC.m */,
78E07B782A49664E00E68200 /* MeatProbeBoxVC.xib */,
);
path = 27_MeatProbeBox;
sourceTree = "<group>";
};
78E07B712A49664E00E68200 /* Ble */ = {
isa = PBXGroup;
children = (
78E07B762A49664E00E68200 /* ELAILinkBleManager+MeatProbeBox.h */,
78E07B742A49664E00E68200 /* ELAILinkBleManager+MeatProbeBox.m */,
78E07B732A49664E00E68200 /* ELMeatProbeBoxBleHeader.h */,
78E07B722A49664E00E68200 /* ELMeatProbeBoxBleParser.h */,
78E07B752A49664E00E68200 /* ELMeatProbeBoxBleParser.m */,
);
path = Ble;
sourceTree = "<group>";
};
95565B742786EA3B000265EA /* 24_Skip */ = {
isa = PBXGroup;
children = (
@@ -869,11 +937,14 @@
files = (
78DC4DF42990FB40006C6911 /* ELDeviceTypeCell.xib in Resources */,
E622E287243F1D41003C319D /* Main.storyboard in Resources */,
78E07B7E2A49664E00E68200 /* MeatProbeBoxVC.xib in Resources */,
78DC4DE32990FB2E006C6911 /* ELDemoScanVC.xib in Resources */,
E622E26E243F1CA6003C319D /* LaunchScreen.storyboard in Resources */,
E622E26B243F1CA6003C319D /* Assets.xcassets in Resources */,
78DC4DF62990FB40006C6911 /* ELDeviceScanCell.xib in Resources */,
78E07B7B2A49664E00E68200 /* MeatProbeVC.xib in Resources */,
78350BBD29D28C1200456695 /* README.md in Resources */,
78E07B6B2A49664000E68200 /* BroadcastHeightGuage.xib in Resources */,
78DC4DFC2990FC10006C6911 /* HeightBodyFatScaleVC.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -930,16 +1001,19 @@
95572641276C38CD003BFBAC /* ELEightScaleRecordModel.m in Sources */,
95572634276C38CD003BFBAC /* HeightGuageScanViewController.m in Sources */,
958B4EA7263C08E800476BAE /* UIButton+WZAdd.m in Sources */,
78E07B7C2A49664E00E68200 /* ELAILinkBleManager+MeatProbeBox.m in Sources */,
958B4EA9263C08E800476BAE /* ELSelectView.m in Sources */,
95572635276C38CD003BFBAC /* HeightGuageConnectViewController.m in Sources */,
95572639276C38CD003BFBAC /* NutritionScaleConnectionViewController.m in Sources */,
95572647276C38CD003BFBAC /* ForeheadConnectViewController.m in Sources */,
E622E271243F1CA6003C319D /* main.m in Sources */,
78E07B7F2A49664E00E68200 /* MeatProbeBoxVC.m in Sources */,
95572646276C38CD003BFBAC /* FoodThermometerConnectionViewController.m in Sources */,
958B4EB3263C08E800476BAE /* View+MASAdditions.m in Sources */,
958B4EB1263C08E800476BAE /* MASLayoutConstraint.m in Sources */,
9557263A276C38CD003BFBAC /* FaceMaskConnectionViewController.m in Sources */,
95572636276C38CD003BFBAC /* OximeterScanViewController.m in Sources */,
78E07B7D2A49664E00E68200 /* ELMeatProbeBoxBleParser.m in Sources */,
958B4EA4263C08E800476BAE /* ELInputAlertView.m in Sources */,
958B4EB6263C08E800476BAE /* MASViewAttribute.m in Sources */,
958B4EBB263C08E800476BAE /* InheritConnectViewController.m in Sources */,
@@ -949,6 +1023,7 @@
78DC4DF32990FB40006C6911 /* ELDemoButton.m in Sources */,
958B4EA5263C08E800476BAE /* UILabel+WZAdd.m in Sources */,
95572633276C38CD003BFBAC /* BabyScaleConnectViewController.m in Sources */,
78E07B7A2A49664E00E68200 /* MeatProbeVC.m in Sources */,
95572644276C38CD003BFBAC /* BodyFatScaleConnectViewController.m in Sources */,
958B4EBD263C08E800476BAE /* AppDelegate.m in Sources */,
95565B792786EA3B000265EA /* SkipConnectionViewController.m in Sources */,
@@ -962,6 +1037,7 @@
95572645276C38CD003BFBAC /* FoodThermometerScanViewController.m in Sources */,
958B4EA6263C08E800476BAE /* UIView+Category.m in Sources */,
9557262E276C38CD003BFBAC /* ELBfsWifiConnectVC.m in Sources */,
78E07B6A2A49664000E68200 /* BroadcastHeightGuage.m in Sources */,
95572637276C38CD003BFBAC /* OximeterConnectionViewController.m in Sources */,
95572648276C38CD003BFBAC /* ForeheadScanViewController.m in Sources */,
78DC4DE42990FB2E006C6911 /* ELDemoDeviceModel.m in Sources */,
@@ -1117,7 +1193,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20230427;
CURRENT_PROJECT_VERSION = 20230626;
DEVELOPMENT_TEAM = YEU77XR292;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -1139,7 +1215,7 @@
"$(PROJECT_DIR)/AILinkBleSDKDemo/DeviceDemo/13_EightScale/HTBodyfat_SDK",
"$(PROJECT_DIR)/AILinkBleSDKDemo/DeviceDemo/13_EightScale/BhBodyComposition120",
);
MARKETING_VERSION = 1.5.15;
MARKETING_VERSION = 1.6.1;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = com.pingwang.AILinkBleSDKDemo;
PRODUCT_NAME = "$(TARGET_NAME)";
@@ -1152,7 +1228,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20230427;
CURRENT_PROJECT_VERSION = 20230626;
DEVELOPMENT_TEAM = YEU77XR292;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
@@ -1174,7 +1250,7 @@
"$(PROJECT_DIR)/AILinkBleSDKDemo/DeviceDemo/13_EightScale/HTBodyfat_SDK",
"$(PROJECT_DIR)/AILinkBleSDKDemo/DeviceDemo/13_EightScale/BhBodyComposition120",
);
MARKETING_VERSION = 1.5.15;
MARKETING_VERSION = 1.6.1;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = com.pingwang.AILinkBleSDKDemo;
PRODUCT_NAME = "$(TARGET_NAME)";

二進制
AILinkBleSDKDemo/AILinkBleSDK.framework/AILinkBleSDK 查看文件


+ 1
- 6
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/AILinkBleSDK-umbrella.h 查看文件

@@ -18,12 +18,6 @@
#import "NELBleManagerHeader.h"
#import "NELMacAddressModel.h"
#import "NSData+AILinkBle.h"
#import "ELAILinkBleManager+AirDetector.h"
#import "ELAirDetectorBleFunctionModel.h"
#import "ELAirDetectorBleHeader.h"
#import "ELAirDetectorBleParser.h"
#import "ELAirDetectorBleSettingModel.h"
#import "ELAirDetectorBleStatusModel.h"
#import "ELAILinkBleManager+MeatProbe.h"
#import "ELMeatProbeBleTool.h"
#import "ELAILinkBleManager+NoiseMeter.h"
@@ -71,6 +65,7 @@
#import "ELBroadcastNutritionFoodScaleBleManager.h"
#import "ELBroadcastNutritionFoodScaleDataModel.h"
#import "ELBfsLeaOneDataModel.h"
#import "ELBfsOKOKDataModel.h"
#import "ELBroadcastScaleBleHeader.h"
#import "ELBroadcastScaleBleManager.h"
#import "ELBroadcastScaleDataModel.h"

+ 1
- 1
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/AILinkBleSDK_Version.h 查看文件

@@ -9,6 +9,6 @@
#define AILinkBleSDK_Version_h

//版本号 SDK Version
#define AiLinkBleSDKVersion @"1.5.15" //20230427 增加 蓝牙牙刷防飞溅
#define AiLinkBleSDKVersion @"1.6.1" //20230626 增加 广播身高仪 食物探针 食物探针盒子 支持

#endif /* AILinkBleSDK_Version_h */

+ 0
- 136
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAILinkBleManager+AirDetector.h 查看文件

@@ -1,136 +0,0 @@
//
// ELAILinkBleManager+AirDetector.h
// AILinkBleSDK
//
// Created by LarryZhang on 2022/12/12.
//

#import "ELAILinkBleManager.h"
#import "ELTLVModel.h"
#import "ELAirDetectorBleHeader.h"
#import "ELAirDetectorBleParser.h"


NS_ASSUME_NONNULL_BEGIN

@interface ELAILinkBleManager (AirDetector)

- (NSData *)xxx;

//APP获取设备功能列表 //0x01 CMD:获取设备支持的功能列表
- (void)airDetectorRequestDeviceFunctions;
- (NSData *)airDetectorRequestDeviceFunctionsPacketWithMac:(NSData *)mac withCid:(UInt16)cid;

//APP获取设备状态 //0x03 CMD:获取设备状态
- (void)airDetectorRequestDeviceStatus;
- (NSData *)airDetectorRequestDeviceStatusPacketWithMac:(NSData *)mac withCid:(UInt16)cid;

//APP设置/获取参数 //0x05 CMD:设置/获取参数功能
- (void)airDetectorRequestDeviceSettings;
- (NSData *)airDetectorRequestDeviceSettingsPacketWithMac:(NSData *)mac withCid:(UInt16)cid;
- (void)airDetectorSendDeviceSettings:(NSArray<ELTLVModel *> *)tlvs;
- (NSData *)airDetectorSendDeviceSettingsData:(NSArray<ELTLVModel *> *)tlvs;

//APP与模块心跳 //0x07 CMD:定时心跳包
- (void)airDetectorSendHeartbeat;
- (NSData *)airDetectorSendHeartbeatPacketWithMac:(NSData *)mac withCid:(UInt16)cid;


@end

@interface ELAILinkBleManager (AirDetectorTLV)

//0x01:甲醛
+ (ELTLVModel *)tlvHCHOAlarmOn:(BOOL)on value:(NSInteger)value;

//0x02:温度 //参数: scale(标度) 表示小数点位数
+ (ELTLVModel *)tlvTemperatureMinValue:(NSInteger)minValue maxValue:(NSInteger)maxValue uint:(ELDeviceTemperatureUnit)unit scale:(NSInteger)scale;

//0x03:湿度
+ (ELTLVModel *)tlvHumidityMinValue:(NSInteger)minValue maxValue:(NSInteger)maxValue;

//0x04:PM2.5
+ (ELTLVModel *)tlvPM2_5AlarmOn:(BOOL)on value:(NSInteger)value;

//0x05:PM1.0
+ (ELTLVModel *)tlvPM1AlarmOn:(BOOL)on value:(NSInteger)value;

//0x06:PM10
+ (ELTLVModel *)tlvPM10AlarmOn:(BOOL)on value:(NSInteger)value;

//0x07:VOC
+ (ELTLVModel *)tlvVOCAlarmOn:(BOOL)on value:(NSInteger)value;

//0x08:CO2
+ (ELTLVModel *)tlvCO2AlarmOn:(BOOL)on value:(NSInteger)value;

//0x09:AQI
+ (ELTLVModel *)tlvAQIAlarmOn:(BOOL)on value:(NSInteger)value;

//0x0B:音量状态
+ (ELTLVModel *)tlvVolumeOn:(BOOL)on value:(NSInteger)value;

//0x0C:报警时长
+ (ELTLVModel *)tlvAlertDuration:(NSInteger)duration;

//0x0D:报警铃声
+ (ELTLVModel *)tlvAlertRing:(NSInteger)ringValue;

//0x0F:设备自检 ??
+ (ELTLVModel *)tlvSelf:(NSInteger)ringValue;

//0x10:TVOC
+ (ELTLVModel *)tlvTVOCAlarmOn:(BOOL)on value:(NSInteger)value;

//0x11:单位切换
+ (ELTLVModel *)tlvTemperatureUint:(ELDeviceTemperatureUnit)unit;

//0x13:设备绑定
+ (ELTLVModel *)tlvBindDeviceRequest;
+ (ELTLVModel *)tlvBindDeviceCancel;

//0x15:CO
+ (ELTLVModel *)tlvCOAlarmOn:(BOOL)on value:(NSInteger)value;

//0x16:闹钟设置
+ (ELTLVModel *)tlvSetupAlarms:(NSArray *)alarms;

//0x17:恢复出厂设置
+ (ELTLVModel *)tlvRestoreFactory;

//0x18:参数校准设置
+ (ELTLVModel *)tlvCalibrationUp:(ELAirDetectorTLVType)type;
+ (ELTLVModel *)tlvCalibrationDown:(ELAirDetectorTLVType)type;
+ (ELTLVModel *)tlvCalibrationReset:(ELAirDetectorTLVType)type;

//0x19:时间格式设置
+ (ELTLVModel *)tlvTimeFormat12H;
+ (ELTLVModel *)tlvTimeFormat24H;

//0x1A:设备亮度设置
+ (ELTLVModel *)tlvDeviceBrightnessOn:(BOOL)on value:(NSInteger)value;

//0x1B:按键音效设置
+ (ELTLVModel *)tlvKeySoundOn;
+ (ELTLVModel *)tlvKeySoundOff;

//0x1C:报警音效设置
+ (ELTLVModel *)tlvAlertSoundOn;
+ (ELTLVModel *)tlvAlertSoundOff;

//0x1D:图标显示设置
+ (ELTLVModel *)tlvIconDisplayOn;
+ (ELTLVModel *)tlvIconDisplayOff;

//0x1E:监控显示数据
+ (ELTLVModel *)tlvMonitoringDisplayDataOn;
+ (ELTLVModel *)tlvMonitoringDisplayDataOff;

//0x1F:数据显示模式设置
+ (ELTLVModel *)tlvDataDisplayMode:(NSInteger)mode;


@end

NS_ASSUME_NONNULL_END


+ 3
- 7
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAILinkBleManager+MeatProbe.h 查看文件

@@ -13,17 +13,13 @@ NS_ASSUME_NONNULL_BEGIN


//MeatProbe 设置设备信息 0x35
- (void)meatProbeSendCustomData:(NSData *_Nonnull)customData;
- (NSData *)meatProbeSendCustomData:(NSData *)customData;

//MeatProbe 设置设备信息 0x35 请求
- (void)meatProbeRequestCustomData;
- (NSData *)meatProbeRequestCustomData;

//切换温度单位 A7
- (void)meatProbeSwitchUint:(ELDeviceTemperatureUnit)unit;


//关闭自动关机指令 A7 **调试阶段使用
//- (void)meatProbeCloseAutoOff;
- (NSData *)meatProbeSwitchUint:(ELDeviceTemperatureUnit)unit;


@end

+ 0
- 5
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAILinkBleManager+WIFI.h 查看文件

@@ -11,11 +11,6 @@ NS_ASSUME_NONNULL_BEGIN

@interface ELAILinkBleManager (WIFI)

//============ wifi 分包数据 ==============
@property(nonatomic, strong) ELBleWifiDetailModel *_Nullable wifiDetailModel;
@property(nonatomic, strong) NSMutableData *_Nullable urlBuffData;
@property(nonatomic, strong) NSMutableData *_Nullable pathBuffData;

//============ Bluetooth WIFI calling method(蓝牙WIFI 设置命令) ==============

/**

+ 5
- 9
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAILinkBleManager.h 查看文件

@@ -31,9 +31,13 @@ NS_ASSUME_NONNULL_BEGIN
- (NSString *)sdkVersion;
+ (NSString *)sdkVersion;

//扫描状态
@property(nonatomic, assign, readonly, getter=isScanning) BOOL scanning;

@property(nonatomic, assign, readonly) CBCentralManager *central;
//BLE设备连接状态
@property(nonatomic, assign, readonly) NELBleManagerConnectState connectState;

@property(nonatomic, strong, readonly) CBCentralManager *central;

@property (nonatomic, weak) id<ELAILinkBleManagerDelegate> delegate DEPRECATED_MSG_ATTRIBUTE("use 'ailinkDelegate' only");

@@ -150,12 +154,4 @@ NS_ASSUME_NONNULL_BEGIN

@end

#pragma mark - specialMethod
@interface ELAILinkBleManager (specialMethod)

- (BOOL)specialMethodWithCid:(UInt16)cid vid:(UInt16)vid pid:(UInt16)pid secret:(NSString *)secret;

@end


NS_ASSUME_NONNULL_END

+ 0
- 126
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleFunctionModel.h 查看文件

@@ -1,126 +0,0 @@
//
// ELAirDetectorBleFunctionModel.h
// AILinkBleSDK
//
// Created by LarryZhang on 2022/12/13.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface ELAirDetectorBleFunctionModel : NSObject

//0x01:甲醛
@property (nonatomic, assign) NSInteger HCHOScale;
@property (nonatomic, assign) NSInteger HCHOMin;
@property (nonatomic, assign) NSInteger HCHOMax;

//0x02:温度
@property (nonatomic, assign) NSInteger temperatureScale;
@property (nonatomic, assign) NSInteger temperatureMin;
@property (nonatomic, assign) NSInteger temperatureMax;

//0x03:湿度
@property (nonatomic, assign) NSInteger humidityScale;
@property (nonatomic, assign) NSInteger humidityMin;
@property (nonatomic, assign) NSInteger humidityMax;

//0x04:PM2.5
@property (nonatomic, assign) NSInteger PM2_5Scale;
@property (nonatomic, assign) NSInteger PM2_5Min;
@property (nonatomic, assign) NSInteger PM2_5Max;

//0x05:PM1.0
@property (nonatomic, assign) NSInteger PM1Scale;
@property (nonatomic, assign) NSInteger PM1Min;
@property (nonatomic, assign) NSInteger PM1Max;

//0x06:PM10
@property (nonatomic, assign) NSInteger PM10Scale;
@property (nonatomic, assign) NSInteger PM10Min;
@property (nonatomic, assign) NSInteger PM10Max;

//0x07:VOC
@property (nonatomic, assign) NSInteger VOCScale;
@property (nonatomic, assign) NSInteger VOCMin;
@property (nonatomic, assign) NSInteger VOCMax;

//0x08:CO2
@property (nonatomic, assign) NSInteger CO2Scale;
@property (nonatomic, assign) NSInteger CO2Min;
@property (nonatomic, assign) NSInteger CO2Max;

//0x09:AQI
@property (nonatomic, assign) NSInteger AQIScale;
@property (nonatomic, assign) NSInteger AQIMin;
@property (nonatomic, assign) NSInteger AQIMax;

//0x0A:报警功能
@property (nonatomic, assign) BOOL alertSupport;

//0x0B:音量
@property (nonatomic, assign) NSInteger volumeMax;

//0x0C:报警时长
@property (nonatomic, assign) NSInteger alertDurationMax;

//0x0D:报警铃声
@property (nonatomic, assign) NSInteger alertRingCount;

//0x0E:设备故障
@property (nonatomic, assign) BOOL deviceErrorSupport;

//0x0F:设备自检
@property (nonatomic, assign) BOOL deviceSelfTestSupport;

//0x10:TVOC
@property (nonatomic, assign) NSInteger TVOCScale;
@property (nonatomic, assign) NSInteger TVOCMin;
@property (nonatomic, assign) NSInteger TVOCMax;

//0x15:CO(一氧化碳)
@property (nonatomic, assign) NSInteger COScale;
@property (nonatomic, assign) NSInteger COMin;
@property (nonatomic, assign) NSInteger COMax;

//0x16:闹钟功能声明
@property (nonatomic, assign) BOOL alarmAllSupport;
@property (nonatomic, assign) NSInteger alarmCount;
@property (nonatomic, assign) NSInteger alarmMode;

//0x17:恢复出厂设置声明
@property (nonatomic, assign) BOOL restoreFactorySupport;

//0x18:参数校准声明
@property (nonatomic, strong) NSArray<NSNumber *> *_Nullable calibrationSupportArray;

//0x19:时间格式声明
@property (nonatomic, assign) BOOL timeFormat12HSupport;
@property (nonatomic, assign) BOOL timeFormat24HSupport;

//0x1A:设备亮度声明
@property (nonatomic, assign) BOOL deviceBrightnessAuto;
@property (nonatomic, assign) BOOL deviceBrightnessManual;
@property (nonatomic, assign) BOOL deviceBrightnessGearMode;
@property (nonatomic, assign) BOOL deviceBrightnessGearMax;

//0x1B:按键音效声明
@property (nonatomic, assign) BOOL keySoundSupport;

//0x1C:报警音效声明
@property (nonatomic, assign) BOOL alertSoundSupport;

//0x1D:图标显示声明
@property (nonatomic, assign) BOOL iconDisplaySupport;

//0x1E:监控显示数据声明
@property (nonatomic, assign) BOOL monitoringDisplayDataSupport;

//0x1F:数据显示模式声明
@property (nonatomic, assign) NSInteger dataDisplayModeCount;


@end

NS_ASSUME_NONNULL_END

+ 0
- 63
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleHeader.h 查看文件

@@ -1,63 +0,0 @@
//
// ELAirDetectorBleHeader.h
// Pods
//
// Created by LarryZhang on 2022/12/13.
//

#ifndef ELAirDetectorBleHeader_h
#define ELAirDetectorBleHeader_h


typedef NS_ENUM(NSUInteger, ELAirDetectorBleCMD) {
ELAirDetectorBleCMD01 = 0x01, //CMD:获取设备支持的功能列表
ELAirDetectorBleCMD02 = 0x02, //CMD:设备返回功能
ELAirDetectorBleCMD03 = 0x03, //CMD:获取设备状态
ELAirDetectorBleCMD04 = 0x04, //CMD:设备返回状态
ELAirDetectorBleCMD05 = 0x05, //CMD:设置/获取参数功能
ELAirDetectorBleCMD06 = 0x06, //CMD:MCU返回参数功能
ELAirDetectorBleCMD07 = 0x07, //CMD:定时心跳包
ELAirDetectorBleCMD08 = 0x08, //CMD:模块返回心跳包
ELAirDetectorBleCMDF1 = 0xF1, //CMD:上发保存数据
};

typedef NS_ENUM(NSUInteger, ELAirDetectorTLVType) {
ELAirDetectorTLVTypeHCHO = 0x01, //甲醛
ELAirDetectorTLVTypeTemperature = 0x02, //温度
ELAirDetectorTLVTypeHumidity = 0x03, //湿度
ELAirDetectorTLVTypePM2_5 = 0x04, //PM2.5
ELAirDetectorTLVTypePM1 = 0x05, //PM1
ELAirDetectorTLVTypePM10 = 0x06, //PM10
ELAirDetectorTLVTypeVOC = 0x07,
ELAirDetectorTLVTypeCO2 = 0x08,
ELAirDetectorTLVTypeAQI = 0x09,
ELAirDetectorTLVTypeSettingAlert = 0x0A, //报警功能
ELAirDetectorTLVTypeSettingVolume = 0x0B, //音量
ELAirDetectorTLVTypeSettingAlertDuration = 0x0C, //报警时长
ELAirDetectorTLVTypeSettingAlertRing = 0x0D, //报警铃声
ELAirDetectorTLVTypeSettingDeviceError = 0x0E, //设备故障
ELAirDetectorTLVTypeSettingDeviceSelfTest = 0x0F, //设备自检
ELAirDetectorTLVTypeTVOC = 0x10, //TVOC
ELAirDetectorTLVTypeSwitchTemperatureUnit = 0x11, //单位切换
ELAirDetectorTLVTypeBatteryState = 0x12, //电池状态
ELAirDetectorTLVTypeBindDevice = 0x13, //设备绑定
ELAirDetectorTLVTypeHeartbeat = 0x14, //心跳包(用以模块和APP通信)

ELAirDetectorTLVTypeCO = 0x15, //CO(一氧化碳)
ELAirDetectorTLVTypeAlarm = 0x16, //闹钟功能
ELAirDetectorTLVTypeRestoreFactorySetting = 0x17, //恢复出厂设置
ELAirDetectorTLVTypeCalibrationParameter = 0x18, //参数校准
ELAirDetectorTLVTypeTimeFormat = 0x19, //时间格式
ELAirDetectorTLVTypeDeviceBrightness = 0x1A, //设备亮度
ELAirDetectorTLVTypeKeySound = 0x1B, //按键音效
ELAirDetectorTLVTypeAlertSound = 0x1C, //报警音效
ELAirDetectorTLVTypeIconDisplay = 0x1D, //图标显示
ELAirDetectorTLVTypeMonitoringDisplayData = 0x1E, //监控显示数据
ELAirDetectorTLVTypeDataDisplayMode = 0x1F, //数据显示模式
};

#endif /* ELAirDetectorBleHeader_h */

+ 0
- 32
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleParser.h 查看文件

@@ -1,32 +0,0 @@
//
// ELAirDetectorBleParser.h
// AILinkBleSDK
//
// Created by LarryZhang on 2022/12/12.
//

#import <Foundation/Foundation.h>
#import "ELSDKHeader.h"
#import "ELAirDetectorBleHeader.h"
#import "ELAirDetectorBleFunctionModel.h"
#import "ELAirDetectorBleStatusModel.h"
#import "ELAirDetectorBleSettingModel.h"

NS_ASSUME_NONNULL_BEGIN

@interface ELAirDetectorBleParser : NSObject

typedef void(^airDetectorDidUpdateDataBlock)(ELAirDetectorBleCMD cmd, ELAirDetectorTLVType type);

@property (nonatomic, strong) ELAirDetectorBleFunctionModel *functionModel;

@property (nonatomic, strong) ELAirDetectorBleStatusModel *statusModel;

@property (nonatomic, strong) ELAirDetectorBleSettingModel *settingModel;


- (void)parseData:(NSData *)payload callback:(airDetectorDidUpdateDataBlock)calllback;

@end

NS_ASSUME_NONNULL_END

+ 0
- 113
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleSettingModel.h 查看文件

@@ -1,113 +0,0 @@
//
// ELAirDetectorBleSettingModel.h
// AILinkBleSDK
//
// Created by LarryZhang on 2022/12/14.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface ELAirDetectorBleSettingModel : NSObject

//0x01:甲醛
@property (nonatomic, assign) BOOL HCHOAlertOn;
@property (nonatomic, assign) NSInteger HCHOAlertValue;

//0x02:温度
@property (nonatomic, assign) NSInteger temperatureScale;
@property (nonatomic, assign) NSInteger temperatureUint;
@property (nonatomic, assign) NSInteger temperatureAlertMinValue;
@property (nonatomic, assign) NSInteger temperatureAlertMaxValue;

//0x03:湿度
@property (nonatomic, assign) NSInteger humidityAlertMinValue;
@property (nonatomic, assign) NSInteger humidityAlertMaxValue;

//0x04:PM2.5
@property (nonatomic, assign) BOOL PM2_5AlertOn;
@property (nonatomic, assign) NSInteger PM2_5AlertValue;

//0x05:PM1.0
@property (nonatomic, assign) BOOL PM1AlertOn;
@property (nonatomic, assign) NSInteger PM1AlertValue;

//0x06:PM10
@property (nonatomic, assign) BOOL PM10AlertOn;
@property (nonatomic, assign) NSInteger PM10AlertValue;

//0x07:VOC
@property (nonatomic, assign) BOOL VOCAlertOn;
@property (nonatomic, assign) NSInteger VOCAlertValue;

//0x08:CO2
@property (nonatomic, assign) BOOL CO2AlertOn;
@property (nonatomic, assign) NSInteger CO2AlertValue;

//0x09:AQI
@property (nonatomic, assign) BOOL AQIAlertOn;
@property (nonatomic, assign) NSInteger AQIAlertValue;

//0x0B:音量状态
@property (nonatomic, assign) BOOL volumeAlertOn;
@property (nonatomic, assign) NSInteger volumeValue;

//0x0C:报警时长
@property (nonatomic, assign) NSInteger alertDurationValue;

//0x0D:报警铃声
@property (nonatomic, assign) NSInteger alertRingValue;

//0x0F:设备自检
@property (nonatomic, assign) BOOL deviceSelfTesting;

//0x10:TVOC
@property (nonatomic, assign) BOOL TVOCAlertOn;
@property (nonatomic, assign) NSInteger TVOCAlertValue;

//0x11:单位切换
@property (nonatomic, assign) NSInteger switchTemperatureUint;

//0x13:设备绑定
@property (nonatomic, assign) NSInteger bandState;

//0x15:CO
@property (nonatomic, assign) BOOL COAlertOn;
@property (nonatomic, assign) NSInteger COAlertValue;

//0x16:闹钟设置 //原始数据未解析
@property (nonatomic, strong) NSData *alarmSettingData;

//0x17:恢复出厂设置
@property (nonatomic, assign) NSInteger restoreFactoryState;

//0x18:参数校准设置 //原始数据未解析
@property (nonatomic, strong) NSData *calibrationSettingData;

//0x19:时间格式设置
@property (nonatomic, assign) NSInteger timeFormatValue;

//0x1A:设备亮度状态
@property (nonatomic, assign) BOOL deviceBrightnessOn;
@property (nonatomic, assign) NSInteger deviceBrightnessValue;

//按键音效设置
@property (nonatomic, assign) BOOL keySoundOn;

//0x1C:报警音效设置
@property (nonatomic, assign) BOOL alertSoundOn;

//0x1D:图标显示设置
@property (nonatomic, assign) BOOL iconDisplayOn;

//0x1E:监控显示数据
@property (nonatomic, assign) BOOL monitoringDisplayDataOn;

//0x1F:数据显示模式设置
@property (nonatomic, assign) NSInteger dataDisplayModeValue;


@end

NS_ASSUME_NONNULL_END

+ 0
- 117
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELAirDetectorBleStatusModel.h 查看文件

@@ -1,117 +0,0 @@
//
// ELAirDetectorBleStatusModel.h
// AILinkBleSDK
//
// Created by LarryZhang on 2022/12/13.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface ELAirDetectorBleStatusModel : NSObject

//0x01:甲醛
@property (nonatomic, assign) NSInteger HCHOValue;

//0x02:温度
@property (nonatomic, assign) NSInteger temperatureScale;
@property (nonatomic, assign) NSInteger temperatureValue;
@property (nonatomic, assign) NSInteger temperatureUint;

//0x03:湿度
@property (nonatomic, assign) NSInteger humidityValue;

//0x04:PM2.5
@property (nonatomic, assign) NSInteger PM2_5Value;

//0x05:PM1.0
@property (nonatomic, assign) NSInteger PM1Value;

//0x06:PM10
@property (nonatomic, assign) NSInteger PM10Value;

//0x07:VOC
@property (nonatomic, assign) NSInteger VOCValue;

//0x08:CO2
@property (nonatomic, assign) NSInteger CO2Value;

//0x09:AQI
@property (nonatomic, assign) NSInteger AQIValue;

//0x0A:报警状态
@property (nonatomic, assign) BOOL alertOn;
@property (nonatomic, assign) BOOL alertHCHOHigh;
@property (nonatomic, assign) BOOL alertTemperatureLow;
@property (nonatomic, assign) BOOL alertTemperatureHigh;
@property (nonatomic, assign) BOOL alertHumidityLow;
@property (nonatomic, assign) BOOL alertHumidityHigh;
@property (nonatomic, assign) BOOL alertPM2_5;
@property (nonatomic, assign) BOOL alertPM1;
@property (nonatomic, assign) BOOL alertPM10;
@property (nonatomic, assign) BOOL alertVOC;
@property (nonatomic, assign) BOOL alertCO2;
@property (nonatomic, assign) BOOL alertAQI;
@property (nonatomic, assign) BOOL alertTVOC;

//0x0B:音量状态
@property (nonatomic, assign) BOOL volumeOn;
@property (nonatomic, assign) NSInteger volumeValue;

//0x0C:报警时长
@property (nonatomic, assign) NSInteger alertDurationValue;

//0x0D:报警铃声
@property (nonatomic, assign) NSInteger alertRingValue;

//0x0E:设备故障
@property (nonatomic, assign) BOOL deviceError;

//0x0F:设备自检
@property (nonatomic, assign) BOOL deviceSelfTesting;

//0x10:TVOC
@property (nonatomic, assign) NSInteger TVOCValue;

//0x12:电池状态
@property (nonatomic, assign) NSInteger batteryState;
@property (nonatomic, assign) NSInteger batteryPercentValue;

//0x15:CO
@property (nonatomic, assign) NSInteger COValue;

//0x16:闹钟状态 //原始数据未解析
@property (nonatomic, strong) NSData *alarmStatusData;

//0x17:恢复出厂设置
@property (nonatomic, assign) NSInteger restoreFactoryState;

//0x18:参数校准状态 //原始数据未解析
@property (nonatomic, strong) NSData *calibrationStatusData;

//0x19:时间格式状态
@property (nonatomic, assign) NSInteger timeFormatValue;

//0x1A:设备亮度状态
@property (nonatomic, assign) BOOL deviceBrightnessOn;
@property (nonatomic, assign) NSInteger deviceBrightnessValue;

//0x1B:按键音效状态
@property (nonatomic, assign) BOOL keySoundOn;

//0x1C:报警音效状态
@property (nonatomic, assign) BOOL alertSoundOn;

//0x1D:图标显示状态
@property (nonatomic, assign) BOOL iconDisplayOn;

//0x1E:监控显示数据状态
@property (nonatomic, assign) BOOL monitoringDisplayDataOn;

//0x1F:数据显示模式
@property (nonatomic, assign) NSInteger dataDisplayModeValue;

@end

NS_ASSUME_NONNULL_END

+ 49
- 0
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBfsOKOKDataModel.h 查看文件

@@ -0,0 +1,49 @@
//
// ELBfsOKOKDataModel.h
// Elink
//

#import <Foundation/Foundation.h>
#import "ELBroadcastScaleBleHeader.h"

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, OKOKDevType) {
/** 体重秤 */
OKOKDevType_Weight = 0 ,
/** 体脂秤 */
OKOKDevType_Bfr ,
};

/** lea one 秤返回的数据对象模型 */
@interface ELBfsOKOKDataModel : NSObject

/** 流水号 */
@property (nonatomic, assign) NSInteger serialNumber;

/** 设备返回的原始体重 */
@property (nonatomic, assign) NSInteger rawWeight;

/** 电阻 */
@property (nonatomic, assign) NSInteger adc;

/** mac地址 */
@property (nonatomic, copy) NSString *mac;

/** 设备类型 */
@property (nonatomic, assign) OKOKDevType devType;

/** 单位 (仅支持 kg,斤,lb和st:lb) */
@property (nonatomic, assign) ELDeviceWeightUnit unit;

/** 小数位 */
@property (nonatomic, assign) NSInteger weightPoint;

/** 是否为锁定数据 */
@property (nonatomic, assign) BOOL isLockData;

+ (instancetype)initWithDevBleData:(NSData *)data;

@end

NS_ASSUME_NONNULL_END

+ 2
- 0
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBleDisposeDataTool.h 查看文件

@@ -73,6 +73,8 @@ NS_ASSUME_NONNULL_BEGIN
@return 结构体
*/
+(struct ELMCUStateStruct)analysisBluetoothConnectState:(NSData *)data;
//重构
+ (ELWMStateStruct)analysisWMState:(NSData *)data;

/**
解析模块通信模式

+ 3
- 0
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBluetoothManager+Settings_Callback.h 查看文件

@@ -72,6 +72,9 @@ NS_ASSUME_NONNULL_BEGIN
@param stateStrct 结构体
*/
-(void)bluetoothManagerReceiveMCUConnectedState:(struct ELMCUStateStruct)stateStrct;
//重构
-(void)bluetoothManagerReceiveWMState:(ELWMStateStruct)stateStrct;
-(void)bluetoothManagerReceiveWMStateFailCode:(WMWorkStateFailCode)failCode;

/**
Query the callback of the communication mode(查询通信模式的回调)

+ 1
- 0
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBluetoothManager.h 查看文件

@@ -68,6 +68,7 @@ static NSString *GET_A7_DECRYPT_BLE_PAYLOAD_DATA_CONTENT = @"GET_A7_DECRYPT_BLE_

//Start scanning(开始扫描)- 过滤 cid 列表
-(void)startScanFilterCids:(NSArray<NSNumber *> *)cids;
-(void)startScanAllFilterCids:(NSArray<NSNumber *> *)cids;

//Start scanning all (开始扫描附近所有设备)
- (void)startScanAll;

+ 2
- 0
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELBroadcastScaleDataModel.h 查看文件

@@ -41,6 +41,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, assign) long long createTime;


@property (nonatomic, assign) BOOL weightNegative;
@property (nonatomic, assign) UInt16 weightValue;

@end


+ 6
- 0
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELExSupportDeviceType.h 查看文件

@@ -106,10 +106,16 @@ typedef NS_ENUM(NSUInteger, ELSupportDeviceType) {
ELSupportDeviceTypeBroadcastScale = (0xffff +0x01) , //655536 Broadcast body fat scale(AILink广播体脂秤)
ELSupportDeviceTypeBroadcastHeightGauge = (0xffff + 0x03) , //65538 广播身高仪
ELSupportDeviceTypeBroadcastScale_Lingyang = (0xffff +0x16) , //65557 凌阳广播体脂秤
ELSupportDeviceTypeBroadcastBodyScale = (0xFFFF + 0x07) , //Broadcast body scale AILink广播体重秤(无体脂)
ELSupportDeviceTypeBroadcastNutritionFoodScale = (0xffff + 0x04) , //65539 广播营养秤
ELSupportDeviceTypeBroadcastHygrothermograph = (0xffff + 0x06) , //65541 广播温湿度计
ELSupportDeviceTypeBroadcastScale_OKOK = (0xffff + 0x08) , //65543 OKOK广播体脂秤
ELSupportDeviceTypeBroadcastScale_T6 = (0xffff + 0x09) , //65544 T6广播体脂秤

};

#endif /* ELExSupportDeviceType_h */

+ 45
- 0
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ELSDKHeader.h 查看文件

@@ -37,6 +37,7 @@ typedef NS_ENUM(NSUInteger, ELInetGetCmdType) {
ELInetGetCmdTypeGetC_V_P_ID = 0x1E, //-Read CID, VID, PID(读取CID、VID、PID)
ELInetGetCmdTypeGetCommunicationMode = 0x20, //-Get module communication mode(获取模块通信模式)
ELInetGetCmdTypeGetConnectState = 0x26, //-Get Bluetooth and WiFi connection status(获取蓝牙和WiFi连接状态)
ELInetGetCmdTypeGetConnectStateFailCode = 0xAB, //- WiFi connection error 连接失败原因
ELInetGetCmdTypeGetBatteryState = 0x28, //-Get MCU battery status(获取MCU电池状态)
ELInetGetCmdTypeGetHandshake = 0x24, //-Encrypted handshake data returned by Bluetooth(蓝牙返回的加密的握手数据)
ELInetGetCmdTypeGetBodyFatScaleA6Data = 0x2B, //-Body fat scale 0x2B stands for A6 protocol (see the second level instructions for details)(体脂秤0x2B代表A6协议(具体见二级指令))
@@ -195,6 +196,50 @@ struct ELMCUStateStruct {
BleWiFiConnectServerFaildState faildState;
};

//重构
//BLE状态
typedef NS_ENUM(Byte, WMBleState) {
WMBleStateNoConnection = 0,//无连接
WMBleStateConnected = 1,//已连接
WMBleStatePaired = 2,//配对完成
WMBleStateMax = 0xFF
};
//wifi状态
typedef NS_ENUM(Byte, WMWiFiState) {
WMWiFiStateNotSetAP = 0, //未配置AP
WMWiFiStateConnectAPFail = 1, //连接AP失败,连接时密码错误、AP信号不好、主动断开都会是这个状态
WMWiFiStateConnectServerFail = 2, //与服务器通讯失败
WMWiFiStateConnectedAP = 3, //成功连接上AP
WMWiFiStateConnectingAP = 4, //正在连接AP
WMWiFiStateMax = 0xFF
};
//工作状态
typedef NS_ENUM(Byte, WMWorkState) {
WMWorkStateWakeup = 0,//唤醒
WMWorkStateSleep = 1,//进入休眠
WMWorkStateReady = 2,//模块准备就绪
WMWorkStateMax = 0xFF
};
//WiFi连接失败原因
typedef NS_ENUM(Byte, WMWorkStateFailCode) {
WMWorkStateFailCodeUnknow = 0,//未知原因
WMWorkStateFailCodeAPSignalBad = 1,//AP信号差
WMWorkStateFailCodeWrongPassword = 2,//密码错误
WMWorkStateFailCodeNoIP = 3,//获取不到IP
WMWorkStateFailCodeMax = 0xFF
};
typedef struct {
WMBleState bleState;
WMWiFiState wifiState;
WMWorkState workState;
WMWorkStateFailCode failCode;
} ELWMStateStruct, ELWMStateStruct;


#pragma mark - AiLink unit

/** Type key of unit string(单位字符串的type key) */

+ 3
- 0
AILinkBleSDKDemo/AILinkBleSDK.framework/Headers/ElBloodBleWifiManager.h 查看文件

@@ -120,6 +120,9 @@ NS_ASSUME_NONNULL_BEGIN
///获取设备连接的wifi名称
- (void)getBleLinkWifiName;

/** 设置设备的IP地址,端口号和访问路径 */
- (void)setDevAccessIpAddress:(NSString *)address portNumber:(NSUInteger)portNum path:(NSString *)path;


@property (nonatomic,assign) ELBluetoothState bleWifiBloodStatus;


二進制
AILinkBleSDKDemo/AILinkBleSDK.framework/Info.plist 查看文件


+ 17
- 0
AILinkBleSDKDemo/DeviceDemo/06B_BroadcastHeightGuage/BroadcastHeightGuage.h 查看文件

@@ -0,0 +1,17 @@
//
// BroadcastHeightGuage.h
// AILinkBleSDK_Example
//
// Created by LarryZhang on 2023/6/26.
// Copyright © 2023 zhengzida. All rights reserved.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface BroadcastHeightGuage : UIViewController

@end

NS_ASSUME_NONNULL_END

+ 127
- 0
AILinkBleSDKDemo/DeviceDemo/06B_BroadcastHeightGuage/BroadcastHeightGuage.m 查看文件

@@ -0,0 +1,127 @@
//
// BroadcastHeightGuage.m
// AILinkBleSDK_Example
//
// Created by LarryZhang on 2023/6/26.
// Copyright © 2023 zhengzida. All rights reserved.
//

#import "BroadcastHeightGuage.h"
#import <AILinkBleSDK/ELBroadcastHeightGaugeBleManager.h>

@interface BroadcastHeightGuage ()

@property (weak, nonatomic) IBOutlet UILabel *bleStatusLabel;

@property (weak, nonatomic) IBOutlet UITextView *logTextView;

@end


@interface BroadcastHeightGuage () <ELBroadcastHeightGaugeBleDelegate>

@end


@implementation BroadcastHeightGuage

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self initBle];
[self scanBle];
}

- (void)dealloc {
[self deinitBle];
}

#pragma mark - Action

- (IBAction)clearAction:(id)sender {
self.logTextView.text = @"";
}

- (IBAction)shareLogAction:(id)sender {
}


#pragma mark - BLE

- (void)initBle {
[ELBroadcastHeightGaugeBleManager shareManager].heightGaugeDelegate = self;
}

- (void)scanBle {
[[ELBroadcastHeightGaugeBleManager shareManager] startScanAll];
}

- (void)deinitBle {
[[ELBroadcastHeightGaugeBleManager shareManager] stopScan];
[ELBroadcastHeightGaugeBleManager shareManager].heightGaugeDelegate = nil;
}

/**Callback Bluetooth status(回调蓝牙状态) */
- (void)broadcastHeightGaugeUpdateState:(ELBluetoothState)state {
if (state == ELBluetoothStateAvailable) {
self.bleStatusLabel.text = @"Connecting";
} else if (state == ELBluetoothStateUnavailable) {
self.bleStatusLabel.text = @"Bluetooth is disconnected";
}

}

/** 回调身高数据 */
- (void)broadcastHeightGaugeDeviceDataModel:(ELBroadcastHeightGaugeBleDataModel *)model {
static NSInteger serialNumber = 0;
if (serialNumber == model.serialNumber) {
return;
}
serialNumber = model.serialNumber;
switch (model.testState) {
case BroadcastHeightGuage_TestState_Measuring: {
self.bleStatusLabel.text = @"Measuring";
break;
}
case BroadcastHeightGuage_TestState_Stable: {
self.bleStatusLabel.text = @"Stabl";
break;
}
case BroadcastHeightGuage_TestState_Failed: {
self.bleStatusLabel.text = @"Failed";
break;
}
}

NSString *log = [NSString stringWithFormat:@"MAC:%@ cid = %d--vid=%d--pid=%d\n Height = %@%@", model.mac, model.cid - 0xFFFF, model.vid, model.pid, @(model.height), AiLinkBleHeightUnitDic[@(model.heightUnit)]];
[self addLog:log];

}

#pragma mark - Log

- (void)addLog:(NSString *)log {
[self addLog:log newline:YES];
}

- (void)addWithoutNewlineLog:(NSString *)log {
[self addLog:log newline:NO];
}

- (void)addLog:(NSString *)log newline:(BOOL)newline {
NSDateFormatter *format = [[NSDateFormatter alloc] init];
format.dateFormat = @"HH:mm:ss.SSS";
NSString *time = [format stringFromDate:[NSDate date]];
if (newline) {
self.logTextView.text = [self.logTextView.text stringByAppendingFormat:@"%@ %@\n", time, log];
} else {
self.logTextView.text = [self.logTextView.text stringByAppendingFormat:@"%@ %@", time, log];
}
[self.logTextView scrollRangeToVisible:NSMakeRange(self.logTextView.text.length, 1)];
}


@end

+ 101
- 0
AILinkBleSDKDemo/DeviceDemo/06B_BroadcastHeightGuage/BroadcastHeightGuage.xib 查看文件

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="BroadcastHeightGuage">
<connections>
<outlet property="bleStatusLabel" destination="0xz-aS-XmR" id="M4X-Dn-08b"/>
<outlet property="logTextView" destination="7mG-7x-9xa" id="8Vr-ji-Eql"/>
<outlet property="view" destination="Cra-or-dGB" id="NoP-us-drS"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="Cra-or-dGB">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="y1w-g7-Gwh">
<rect key="frame" x="16" y="346" width="31" height="30"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="清空"/>
<connections>
<action selector="clearAction:" destination="-1" eventType="touchUpInside" id="k92-gw-3vb"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PGm-jo-Ko3">
<rect key="frame" x="346" y="346" width="31" height="30"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="分享"/>
<connections>
<action selector="shareLogAction:" destination="-1" eventType="touchUpInside" id="jj3-ON-0lh"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stauts" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0xz-aS-XmR">
<rect key="frame" x="0.0" y="63" width="393" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="itb-kd-JGo">
<rect key="frame" x="8" y="384" width="377" height="434"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" indicatorStyle="white" editable="NO" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7mG-7x-9xa">
<rect key="frame" x="0.0" y="0.0" width="377" height="434"/>
<color key="backgroundColor" systemColor="labelColor"/>
<color key="textColor" systemColor="opaqueSeparatorColor"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="10"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="7mG-7x-9xa" firstAttribute="leading" secondItem="itb-kd-JGo" secondAttribute="leading" id="0NM-af-zvv"/>
<constraint firstAttribute="trailing" secondItem="7mG-7x-9xa" secondAttribute="trailing" id="Q09-hB-QcZ"/>
<constraint firstItem="7mG-7x-9xa" firstAttribute="top" secondItem="itb-kd-JGo" secondAttribute="top" id="kkV-Sm-BVr"/>
<constraint firstAttribute="bottom" secondItem="7mG-7x-9xa" secondAttribute="bottom" id="nqD-ZR-BY0"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<real key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="k4u-s9-7Su"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="k4u-s9-7Su" firstAttribute="bottom" secondItem="itb-kd-JGo" secondAttribute="bottom" id="031-Ze-0Uo"/>
<constraint firstItem="itb-kd-JGo" firstAttribute="top" secondItem="PGm-jo-Ko3" secondAttribute="bottom" constant="8" symbolic="YES" id="49Z-8f-jcF"/>
<constraint firstItem="itb-kd-JGo" firstAttribute="top" secondItem="0xz-aS-XmR" secondAttribute="bottom" constant="300" id="6aU-tq-ex8"/>
<constraint firstItem="itb-kd-JGo" firstAttribute="top" secondItem="y1w-g7-Gwh" secondAttribute="bottom" constant="8" symbolic="YES" id="MZu-VN-DtI"/>
<constraint firstItem="y1w-g7-Gwh" firstAttribute="leading" secondItem="k4u-s9-7Su" secondAttribute="leading" constant="16" id="O7j-eL-y7n"/>
<constraint firstItem="k4u-s9-7Su" firstAttribute="trailing" secondItem="itb-kd-JGo" secondAttribute="trailing" constant="8" id="Spc-n1-4dx"/>
<constraint firstItem="k4u-s9-7Su" firstAttribute="trailing" secondItem="0xz-aS-XmR" secondAttribute="trailing" id="bLk-Ca-9bf"/>
<constraint firstItem="k4u-s9-7Su" firstAttribute="trailing" secondItem="PGm-jo-Ko3" secondAttribute="trailing" constant="16" id="h1Q-kO-zCq"/>
<constraint firstItem="itb-kd-JGo" firstAttribute="leading" secondItem="k4u-s9-7Su" secondAttribute="leading" constant="8" id="mGb-E5-W9q"/>
<constraint firstItem="0xz-aS-XmR" firstAttribute="leading" secondItem="k4u-s9-7Su" secondAttribute="leading" id="qzH-Hp-bXE"/>
<constraint firstItem="0xz-aS-XmR" firstAttribute="top" secondItem="k4u-s9-7Su" secondAttribute="top" constant="4" id="sdm-yW-Wjg"/>
<constraint firstItem="0xz-aS-XmR" firstAttribute="centerX" secondItem="Cra-or-dGB" secondAttribute="centerX" id="zhi-rs-RXG"/>
</constraints>
<point key="canvasLocation" x="53" y="20"/>
</view>
</objects>
<resources>
<systemColor name="labelColor">
<color red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="opaqueSeparatorColor">
<color red="0.77647058823529413" green="0.77647058823529413" blue="0.78431372549019607" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

+ 21
- 0
AILinkBleSDKDemo/DeviceDemo/26_MeatProbe/MeatProbeVC.h 查看文件

@@ -0,0 +1,21 @@
//
// MeatProbeVC.h
// AILinkBleSDK_Example
//
// Created by LarryZhang on 2023/3/7.
// Copyright © 2023 zhengzida. All rights reserved.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@class ELAILinkPeripheral;

@interface MeatProbeVC : UIViewController

@property (nonatomic, strong) ELAILinkPeripheral *per;

@end

NS_ASSUME_NONNULL_END

+ 261
- 0
AILinkBleSDKDemo/DeviceDemo/26_MeatProbe/MeatProbeVC.m 查看文件

@@ -0,0 +1,261 @@
//
// MeatProbeVC.m
// AILinkBleSDK_Example
//
// Created by LarryZhang on 2023/3/7.
// Copyright © 2023 zhengzida. All rights reserved.
//

#import "MeatProbeVC.h"
#import <AILinkBleSDK/ELAILinkBleManager+MeatProbe.h>
#import <AILinkBleSDK/ELMeatProbeBleTool.h>
#import "ELDemoButton.h"

@interface MeatProbeVC () <ELAILinkBleManagerDelegate>

@property (weak, nonatomic) IBOutlet UILabel *bleStatusLabel;

@property (weak, nonatomic) IBOutlet UITextView *logTextView;

@property (nonatomic, strong) ELAILinkBleManager *bleManager;

@end


@implementation MeatProbeVC

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self initBle];
}

- (void)dealloc {
[self deinitBle];
}

#pragma mark - Action

- (IBAction)customDataRequestAction:(id)sender {
NSData *payload = [self.bleManager meatProbeRequestCustomData];
NSString *log = [NSString stringWithFormat:@"发: payload: %@", payload];
[self addLog:log];
}

- (IBAction)customDataSendAction:(id)sender {
NSData *payload = [self.bleManager meatProbeSendCustomData:[self coustumData]];
NSString *log = [NSString stringWithFormat:@"发: payload: %@", payload];
[self addLog:log];
}

- (IBAction)customDataClearAction:(id)sender {
NSData *payload = [self.bleManager meatProbeSendCustomData:[NSData data]];
NSString *log = [NSString stringWithFormat:@"发: payload: %@", payload];
[self addLog:log];
}

- (IBAction)switchUnitAction:(id)sender {
static BOOL flag = NO;
if (flag) {
NSData *payload = [self.bleManager meatProbeSwitchUint:0];
NSString *log = [NSString stringWithFormat:@"发: payload: %@ -- 切换单位 to C", payload];
[self addLog:log];
} else {
NSData *payload = [self.bleManager meatProbeSwitchUint:1];
NSString *log = [NSString stringWithFormat:@"发: payload: %@ -- 切换单位 to F", payload];
[self addLog:log];
}
flag = !flag;
}

- (IBAction)clearAction:(id)sender {
self.logTextView.text = @"";
}

- (IBAction)shareLogAction:(id)sender {
}

- (NSData *)coustumData {
//自定义数据
//*******要验证设备必须支持128字节payload
Byte bytes[128];
memset(bytes, 0, sizeof(bytes));
for (int i=0; i<sizeof(bytes); i++) {
bytes[i] = 0x80 + i;
}
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
NSLog(@"meatProbeAction() data:%@", data);
return data;
}

#pragma mark - ELAILinkBleManagerDelegate

- (void)initBle {
self.bleManager = [[ELAILinkBleManager alloc] init];
self.bleManager.ailinkDelegate = self;
}

- (void)scanBle {
[self.bleManager scanFilterWithCidArray:@[@(self.per.cid)]];
}

- (void)connect {
[self.bleManager connectAILinkPeripheral:self.per];
[self updateBleStatusView:NELBleManagerConnectStateConnecting];
}

- (void)deinitBle {
[self.bleManager stopScan];
self.bleManager.ailinkDelegate = nil;
[self.bleManager disconnectPeripheral];
}

- (void)updateBleStatusView:(NELBleManagerConnectState)state {
if (self.bleManager.central.state == CBManagerStatePoweredOff) {
self.bleStatusLabel.text = @"蓝牙关闭";
return;
}
switch (state) {
case NELBleManagerConnectStateDisconnected:
self.bleStatusLabel.text = @"断开连接";
break;
case NELBleManagerConnectStateFailed:
case NELBleManagerConnectStateFailedValidation:
self.bleStatusLabel.text = @"连接失败";
break;
case NELBleManagerConnectStateConnecting:
self.bleStatusLabel.text = @"正在连接...";
break;
case NELBleManagerConnectStatePassed:
self.bleStatusLabel.text = @"连接成功";
//获取电量
[self.bleManager getBluetoothInfoWithELInetGetCmdType:ELInetGetCmdTypeGetBatteryState];
//获取 设置设备信息
// [self requestDeviceData];
break;
case NELBleManagerConnectStateCentralScanning:
self.bleStatusLabel.text = @"正在扫描...";
break;

default:
break;
}
}

- (void)requestDeviceData {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0), dispatch_get_main_queue(), ^{
//获取 设置设备信息
[self.bleManager meatProbeRequestCustomData];
});
}

// 设备状态变更
- (void)managerDidUpdateState:(CBCentralManager *)central {
NSLog(@"%s state:%@", __func__, @(central.state));
if (central.state == CBManagerStatePoweredOn) {
[self scanBle];
} else if (central.state == CBManagerStatePoweredOff) {
[self updateBleStatusView:NELBleManagerConnectStateCentralPowerOff];
}
}

- (void)managerScanState:(BOOL)scanning {
NSLog(@"%s scanning:%@", __func__, @(scanning));
if (scanning) {
[self updateBleStatusView:NELBleManagerConnectStateCentralScanning];
}
}

// 扫描到设备
- (void)managerDidDiscoverPeripheral:(ELAILinkPeripheral *)peripheral {
NSLog(@"managerDidDiscoverPeripheral cid:%02x vid:%02x pid:%02x mac:%@", peripheral.cid, peripheral.vid, peripheral.pid, peripheral.macAddressString);
if ([peripheral.macAddressString isEqualToString:self.per.macAddressString]) {
[self.bleManager stopScan];
[self.bleManager connectAILinkPeripheral:peripheral];
}
}

- (void)managerDidUpdateConnect:(NELBleManagerConnectState)state {
NSLog(@"%s NELBleManagerConnectState:%@", __func__, @(state));
[self updateBleStatusView:state];
}

//A7数据
- (void)aiLinkBleReceiveA7Data:(NSData *)payload {
NSLog(@"%s #### payload:%@", __func__, payload);
ELMeatProbeBleTemperatureStruct temperatureInfo = [ELMeatProbeBleTool parseTemperature:payload];
if (temperatureInfo.createTime == 0) {
return;
}
NSString *log = [NSString stringWithFormat:@"internalTemprature:%@%@ (%@%@) ambientTemperature:%@%@ (%@%@)", @(temperatureInfo.internalTemperature_C), @"℃", @(temperatureInfo.internalTemperature_F), @"℉", @(temperatureInfo.ambientTemperature_C), @"℃", @(temperatureInfo.ambientTemperature_F), @"℉"];
[self addLog:log];
}

//A6数据
- (void)aiLinkBleReceiveA6Data:(NSData *)packet {
NSLog(@"%s ##### packet:%@", __func__, packet);
Byte *bytes = (Byte *)packet.bytes;
Byte cmd = bytes[2];
if (cmd == ELInetGetCmdTypeGetBatteryState) {
int power = self.bleManager.battery.power;
ELBatteryChargingState state = self.bleManager.battery.state;
NSLog(@"##### state: %lu power: %d", (unsigned long)state, power);
NSString *log = [NSString stringWithFormat:@"battery state:%@ power:%@", @(state), @(power)];
[self addLog:log];
return;
}
if (cmd == ELInetGetCmdTypeGetBMVersion) {
NSString *bmVersion = self.bleManager.bmVersion;
NSLog(@"##### bmVersion: %@", bmVersion);
return;
}
if (cmd == ELInetGetCmdTypeGetBMVersionPro) {
NSString *bmVersionPro = self.bleManager.bmVersionPro;
NSLog(@"##### bmVersionPro: %@", bmVersionPro);
return;
}
if (cmd == ELInetGetCmdTypeGetBasicInfoData) {
NSLog(@"##### ELInetGetCmdTypeGetBasicInfoData: %@", packet);
Byte state = bytes[3];
if (state == 0x01) {
NSData *custom = [packet subdataWithRange:NSMakeRange(4, 128)];
NSString *log = [NSString stringWithFormat:@"custom:%@", custom];
[self addLog:log];
} else {
NSString *log = [NSString stringWithFormat:@"custom:nil"];
[self addLog:log];
}
return;
}
}

#pragma mark - addLog

- (void)addLog:(NSString *)log {
[self addLog:log newline:YES];
}

- (void)addWithoutNewlineLog:(NSString *)log {
[self addLog:log newline:NO];
}

- (void)addLog:(NSString *)log newline:(BOOL)newline {
NSDateFormatter *format = [[NSDateFormatter alloc] init];
format.dateFormat = @"HH:mm:ss.SSS";
NSString *time = [format stringFromDate:[NSDate date]];
if (newline) {
self.logTextView.text = [self.logTextView.text stringByAppendingFormat:@"%@ %@\n", time, log];
} else {
self.logTextView.text = [self.logTextView.text stringByAppendingFormat:@"%@ %@", time, log];
}
[self.logTextView scrollRangeToVisible:NSMakeRange(self.logTextView.text.length, 1)];
}


@end

+ 145
- 0
AILinkBleSDKDemo/DeviceDemo/26_MeatProbe/MeatProbeVC.xib 查看文件

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21679"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MeatProbeVC">
<connections>
<outlet property="bleStatusLabel" destination="7bY-Ib-xgF" id="obS-2C-ezt"/>
<outlet property="logTextView" destination="aWC-up-Yoe" id="Gad-hB-MrW"/>
<outlet property="view" destination="thx-ue-KPs" id="ozx-bW-w8j"/>
</connections>
</placeholder>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="thx-ue-KPs">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LZQ-xA-pA3">
<rect key="frame" x="16" y="346" width="31" height="30"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="清空"/>
<connections>
<action selector="clearAction:" destination="-1" eventType="touchUpInside" id="P6P-KV-phg"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Wia-UQ-8Ld">
<rect key="frame" x="346" y="346" width="31" height="30"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="分享"/>
<connections>
<action selector="shareLogAction:" destination="-1" eventType="touchUpInside" id="e5W-ic-RSS"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stauts" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7bY-Ib-xgF">
<rect key="frame" x="0.0" y="63" width="393" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2cp-J6-wNZ">
<rect key="frame" x="8" y="384" width="377" height="434"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" indicatorStyle="white" editable="NO" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aWC-up-Yoe">
<rect key="frame" x="0.0" y="0.0" width="377" height="434"/>
<color key="backgroundColor" systemColor="labelColor"/>
<color key="textColor" systemColor="opaqueSeparatorColor"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="10"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="aWC-up-Yoe" firstAttribute="leading" secondItem="2cp-J6-wNZ" secondAttribute="leading" id="IA2-sg-ktX"/>
<constraint firstAttribute="bottom" secondItem="aWC-up-Yoe" secondAttribute="bottom" id="NbF-DQ-HWh"/>
<constraint firstItem="aWC-up-Yoe" firstAttribute="top" secondItem="2cp-J6-wNZ" secondAttribute="top" id="UvG-mE-0OI"/>
<constraint firstAttribute="trailing" secondItem="aWC-up-Yoe" secondAttribute="trailing" id="YF8-Au-gGR"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<real key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="RjY-Pb-1ZL">
<rect key="frame" x="24" y="108" width="145.33333333333334" height="35"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="请求自定义数据"/>
<connections>
<action selector="customDataRequestAction:" destination="-1" eventType="touchUpInside" id="4HT-gK-erD"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6wU-4y-kXJ">
<rect key="frame" x="201.33333333333337" y="108" width="146" height="35"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="发送自定义数据"/>
<connections>
<action selector="customDataSendAction:" destination="-1" eventType="touchUpInside" id="Tgn-0e-wxU"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Vm8-VU-scN">
<rect key="frame" x="202" y="159" width="93.333333333333314" height="35"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="单位切换"/>
<connections>
<action selector="switchUnitAction:" destination="-1" eventType="touchUpInside" id="Gkc-6R-oeG"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ttt-Hs-Tk9">
<rect key="frame" x="24" y="159" width="146" height="35"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="清除自定义数据"/>
<connections>
<action selector="customDataClearAction:" destination="-1" eventType="touchUpInside" id="VKf-Yq-l4b"/>
</connections>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="5ya-cg-e71"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="Vm8-VU-scN" firstAttribute="top" secondItem="RjY-Pb-1ZL" secondAttribute="bottom" constant="16" id="3fa-3k-CsR"/>
<constraint firstItem="7bY-Ib-xgF" firstAttribute="leading" secondItem="5ya-cg-e71" secondAttribute="leading" id="5iU-uI-ukE"/>
<constraint firstItem="5ya-cg-e71" firstAttribute="trailing" secondItem="Wia-UQ-8Ld" secondAttribute="trailing" constant="16" id="GYI-zv-QJU"/>
<constraint firstItem="7bY-Ib-xgF" firstAttribute="top" secondItem="5ya-cg-e71" secondAttribute="top" constant="4" id="KNZ-xZ-Kvy"/>
<constraint firstItem="ttt-Hs-Tk9" firstAttribute="top" secondItem="RjY-Pb-1ZL" secondAttribute="bottom" constant="16" id="Lji-qd-u0z"/>
<constraint firstItem="6wU-4y-kXJ" firstAttribute="leading" secondItem="RjY-Pb-1ZL" secondAttribute="trailing" constant="32" id="M6a-6u-DWR"/>
<constraint firstItem="RjY-Pb-1ZL" firstAttribute="leading" secondItem="5ya-cg-e71" secondAttribute="leading" constant="24" id="NYf-r3-SxK"/>
<constraint firstItem="2cp-J6-wNZ" firstAttribute="top" secondItem="7bY-Ib-xgF" secondAttribute="bottom" constant="300" id="P0n-PG-LvG"/>
<constraint firstItem="2cp-J6-wNZ" firstAttribute="top" secondItem="Wia-UQ-8Ld" secondAttribute="bottom" constant="8" symbolic="YES" id="SWO-jj-7Mh"/>
<constraint firstItem="RjY-Pb-1ZL" firstAttribute="top" secondItem="7bY-Ib-xgF" secondAttribute="bottom" constant="24" id="TRo-Mu-UVA"/>
<constraint firstItem="6wU-4y-kXJ" firstAttribute="top" secondItem="7bY-Ib-xgF" secondAttribute="bottom" constant="24" id="Uqf-4D-Cl0"/>
<constraint firstItem="2cp-J6-wNZ" firstAttribute="leading" secondItem="5ya-cg-e71" secondAttribute="leading" constant="8" id="Z3M-US-a9v"/>
<constraint firstItem="5ya-cg-e71" firstAttribute="trailing" secondItem="2cp-J6-wNZ" secondAttribute="trailing" constant="8" id="ZSu-l2-kID"/>
<constraint firstItem="Vm8-VU-scN" firstAttribute="leading" secondItem="ttt-Hs-Tk9" secondAttribute="trailing" constant="32" id="gT6-xc-gTY"/>
<constraint firstItem="ttt-Hs-Tk9" firstAttribute="leading" secondItem="5ya-cg-e71" secondAttribute="leading" constant="24" id="hNT-dX-rsK"/>
<constraint firstItem="LZQ-xA-pA3" firstAttribute="leading" secondItem="5ya-cg-e71" secondAttribute="leading" constant="16" id="kW2-mg-yKj"/>
<constraint firstItem="5ya-cg-e71" firstAttribute="bottom" secondItem="2cp-J6-wNZ" secondAttribute="bottom" id="ms3-vm-VMQ"/>
<constraint firstItem="5ya-cg-e71" firstAttribute="trailing" secondItem="7bY-Ib-xgF" secondAttribute="trailing" id="qVb-2b-hVU"/>
<constraint firstItem="2cp-J6-wNZ" firstAttribute="top" secondItem="LZQ-xA-pA3" secondAttribute="bottom" constant="8" symbolic="YES" id="tY0-Fc-dAj"/>
<constraint firstItem="7bY-Ib-xgF" firstAttribute="centerX" secondItem="thx-ue-KPs" secondAttribute="centerX" id="yRU-ks-IeE"/>
</constraints>
<point key="canvasLocation" x="53" y="20"/>
</view>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
</objects>
<resources>
<systemColor name="labelColor">
<color red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="opaqueSeparatorColor">
<color red="0.77647058823529413" green="0.77647058823529413" blue="0.78431372549019607" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

+ 27
- 0
AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELAILinkBleManager+MeatProbeBox.h 查看文件

@@ -0,0 +1,27 @@
//
// ELAILinkBleManager+MeatProbeBox.h
// AILinkBleSDK
//
// Created by LarryZhang on 2023/2/16.
//

#import <AILinkBleSDK/ELAILinkBleManager.h>

NS_ASSUME_NONNULL_BEGIN

@interface ELAILinkBleManager (MeatProbeBox)

//APP 获取设备状态数据(Type:01)
- (NSData *)meatProbeBoxGetStatus;

//设置、获取设备参数数据(Type:03)
- (NSData *)meatProbeBoxSendCustomData:(NSData *)customData withMac:(NSData *)macData;
- (NSData *)meatProbeBoxRequestCustomDataWithMac:(NSData *)macData;
- (NSData *)meatProbeBoxClearCustomDataWithMac:(NSData *)macData;

//切换单位(Type:04)
- (NSData *)meatProbeBoxSwitchUint:(ELDeviceTemperatureUnit)unit;

@end

NS_ASSUME_NONNULL_END

+ 55
- 0
AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELAILinkBleManager+MeatProbeBox.m 查看文件

@@ -0,0 +1,55 @@
//
// ELAILinkBleManager+MeatProbeBox.m
// AILinkBleSDK
//
// Created by LarryZhang on 2023/2/16.
//

#import "ELAILinkBleManager+MeatProbeBox.h"
#import "ELMeatProbeBoxBleHeader.h"

@implementation ELAILinkBleManager (MeatProbeBox)

//APP 获取设备状态数据(Type:01)
- (NSData *)meatProbeBoxGetStatus {
Byte bytes[] = { ELMeatProbeBoxCMDAppGetStatus_Type01, 0x01 };
NSData *payload = [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];
[self sendA7PayloadNoEncryption:payload];
return payload;
}

//设置、获取设备参数数据(Type:03)
- (NSData *)meatProbeBoxSendCustomData:(NSData *)customData withMac:(NSData *)macData {
Byte bytes[] = { ELMeatProbeBoxCMDCustomData_Type03, 0x01 };
NSMutableData *payload = [[NSMutableData alloc] initWithBytes:bytes length:sizeof(bytes)];
[payload appendData:macData];
[payload appendData:customData];
[self sendA7PayloadNoEncryption:payload.copy];
return payload.copy;
}

- (NSData *)meatProbeBoxRequestCustomDataWithMac:(NSData *)macData {
Byte bytes[] = { ELMeatProbeBoxCMDCustomData_Type03, 0x02 };
NSMutableData *payload = [[NSMutableData alloc] initWithBytes:bytes length:sizeof(bytes)];
[payload appendData:macData];
[self sendA7PayloadNoEncryption:payload.copy];
return payload.copy;
}

- (NSData *)meatProbeBoxClearCustomDataWithMac:(NSData *)macData {
Byte bytes[] = { ELMeatProbeBoxCMDCustomData_Type03, 0x00 };
NSMutableData *payload = [[NSMutableData alloc] initWithBytes:bytes length:sizeof(bytes)];
[payload appendData:macData];
[self sendA7PayloadNoEncryption:payload.copy];
return payload.copy;
}

//切换单位(Type:04)
- (NSData *)meatProbeBoxSwitchUint:(ELDeviceTemperatureUnit)unit {
Byte bytes[] = { ELMeatProbeBoxCMDAppSwitchUnit_Type04, unit };
NSData *payload = [[NSData alloc] initWithBytes:bytes length:sizeof(bytes)];
[self sendA7PayloadNoEncryption:payload];
return payload;
}

@end

+ 23
- 0
AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELMeatProbeBoxBleHeader.h 查看文件

@@ -0,0 +1,23 @@
//
// ELMeatProbeBoxBleHeader.h
// Pods
//
// Created by LarryZhang on 2023/3/30.
//

#ifndef ELMeatProbeBoxBleHeader_h
#define ELMeatProbeBoxBleHeader_h

typedef NS_ENUM(UInt8, ELMeatProbeBoxCMD) {
ELMeatProbeBoxCMDAppGetStatus_Type01 = 0x01, //0x01:Type:APP 获取设备状态
ELMeatProbeBoxCMDMcuUploadStatus_Type02 = 0x02, //0x02:Type:设备上报设备数据
ELMeatProbeBoxCMDCustomData_Type03 = 0x03, //0x03:Type:APP 设置、获取设备相关信息
ELMeatProbeBoxCMDAppSwitchUnit_Type04 = 0x04, //0x04:Type:切换单位
};

#endif /* ELMeatProbeBoxBleHeader_h */

+ 102
- 0
AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELMeatProbeBoxBleParser.h 查看文件

@@ -0,0 +1,102 @@
//
// ELMeatProbeBoxBleParser.h
// AILinkBleSDK
//
// Created by LarryZhang on 2023/2/16.
//

#import <Foundation/Foundation.h>
#import <AILinkBleSDK/ELSDKHeader.h>

NS_ASSUME_NONNULL_BEGIN

@class ELMeatProbeBoxBleBoxStatusModel, ELMeatProbeBoxBleProbeStatusModel;

@protocol ELMeatProbeBoxBleParserDelegate;

@interface ELMeatProbeBoxBleParser : NSObject

@property (nonatomic, copy) NSString *mac;

@property (nonatomic, weak) id<ELMeatProbeBoxBleParserDelegate> delegate;

- (void)parseA7Payload:(NSData *)payloadData;

@end


@protocol ELMeatProbeBoxBleParserDelegate <NSObject>

@optional

//MCU 上报设备状态数据(Type:02)
- (void)meatProbeBoxBleParser:(ELMeatProbeBoxBleParser *)bleParser boxStatus:(ELMeatProbeBoxBleBoxStatusModel *)boxStatus probeStatus:(ELMeatProbeBoxBleProbeStatusModel *)probeStatus offline:(BOOL)offline;

//设置、获取设备参数数据(Type:03)
- (void)meatProbeBoxBleParser:(ELMeatProbeBoxBleParser *)bleParser state:(BOOL)state mac:(NSString *)mac customData:(NSData *)customData;

//切换单位(Type:04)
- (void)meatProbeBoxBleParser:(ELMeatProbeBoxBleParser *)bleParser unit:(ELDeviceTemperatureUnit)unit;

@end

@interface ELMeatProbeBoxBleBoxStatusModel : NSObject

//设备状态数据协议版本:0x01
@property (nonatomic, assign) UInt8 version;

//支持的探针数量 M
@property (nonatomic, assign) UInt8 probeMaxCount;

//当前连接的探针数量 N
@property (nonatomic, assign) UInt8 probeCount;

//充电盒电池状态
@property (nonatomic, assign) UInt8 batteryStatus;
@property (nonatomic, assign) UInt8 batteryPercent;

//温度单位
@property (nonatomic, assign) ELDeviceTemperatureUnit unit;

//生成时间
@property (nonatomic, assign) double timestamp;

@end

@interface ELMeatProbeBoxBleProbeStatusModel : NSObject

//探针编号(1-M) 无法确定可连 接探针的编号,上报 0xFF
@property (nonatomic, assign) UInt8 index;
@property (nonatomic, assign) UInt8 dataIndex;

//探针 mac 地址
@property (nonatomic, strong) NSData *macData;
@property (nonatomic, copy) NSString *macString;

//食物温度
@property (nonatomic, assign) NSInteger internalTemperature;
@property (nonatomic, assign) ELDeviceTemperatureUnit internalTemperatureUnit;
@property (nonatomic, assign) UInt16 internalTemperatureRaw;

//环境温度
@property (nonatomic, assign) NSInteger ambientTemperature;
@property (nonatomic, assign) ELDeviceTemperatureUnit ambientTemperatureUnit;
@property (nonatomic, assign) UInt16 ambientTemperatureRaw;

//探针电池状态
@property (nonatomic, assign) UInt8 batteryStatus;
@property (nonatomic, assign) UInt8 batteryPercent;
@property (nonatomic, assign) UInt8 batteryRaw;

//探针插入食物状态
@property (nonatomic, assign) UInt8 insertStatusRaw;

//生成时间
@property (nonatomic, assign) double timestamp;

//数据无效
- (void)makeInvalid;

@end

NS_ASSUME_NONNULL_END

+ 228
- 0
AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/Ble/ELMeatProbeBoxBleParser.m 查看文件

@@ -0,0 +1,228 @@
//
// ELMeatProbeBoxBleParser.m
// AILinkBleSDK
//
// Created by LarryZhang on 2023/2/16.
//

#import "ELMeatProbeBoxBleParser.h"
#import "ELMeatProbeBoxBleHeader.h"
#import <objc/runtime.h>

@interface ELMeatProbeBoxBleParser ()

@property (nonatomic, strong) ELMeatProbeBoxBleBoxStatusModel *boxStatusModel;

@property (nonatomic, strong) ELMeatProbeBoxBleProbeStatusModel *probeStatusModel;

@end

@implementation ELMeatProbeBoxBleParser

- (instancetype)init {
if (self = [super init]) {
_boxStatusModel = [[ELMeatProbeBoxBleBoxStatusModel alloc] init];
_probeStatusModel = [[ELMeatProbeBoxBleProbeStatusModel alloc] init];
}
return self;
}

#pragma mark - 解析包

- (void)parseA7Payload:(NSData *)payloadData {
UInt8 *bytes = (Byte *)payloadData.bytes;
// UInt8 len = payloadData.length;
UInt8 cmd = bytes[0];

switch (cmd) {
case ELMeatProbeBoxCMDMcuUploadStatus_Type02:
[self handelMcuUploadStatus:payloadData];
break;
case ELMeatProbeBoxCMDCustomData_Type03:
[self handelCustomData:payloadData];
break;
case ELMeatProbeBoxCMDAppSwitchUnit_Type04:
[self handelSwitchUnit:payloadData];
break;
default:
break;
}
}

- (void)handelCustomData:(NSData *)payloadData {
UInt8 *bytes = (Byte *)payloadData.bytes;
UInt8 len = payloadData.length;
BOOL state = bytes[1];
NSData *mac = [payloadData subdataWithRange:NSMakeRange(2, 6)];
Byte *bytesMac = (Byte *)mac.bytes;
NSString *macString = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", bytesMac[5], bytesMac[4], bytesMac[3], bytesMac[2], bytesMac[1], bytesMac[0]];
NSData *customData = [payloadData subdataWithRange:NSMakeRange(8, len - 8)];
if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeBoxBleParser:state:mac:customData:)]) {
[self.delegate meatProbeBoxBleParser:self state:state mac:macString customData:customData];
}
}

- (void)handelSwitchUnit:(NSData *)payloadData {
UInt8 *bytes = (Byte *)payloadData.bytes;
//UInt8 len = payloadData.length;
ELDeviceTemperatureUnit unit = bytes[1];
if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeBoxBleParser:unit:)]) {
[self.delegate meatProbeBoxBleParser:self unit:unit];
}
}

- (void)handelMcuUploadStatus:(NSData *)payloadData {
UInt8 *bytes = (Byte *)payloadData.bytes;
UInt8 len = payloadData.length;
_boxStatusModel.version = bytes[1];
UInt8 probeMaxCount = bytes[2];
if (probeMaxCount < 1) {
return;//探针数排错
}
_boxStatusModel.probeMaxCount = probeMaxCount;
UInt8 probeCount = bytes[3];
if (probeCount > probeMaxCount) {
return;//探针数排错
}
if (len < 1 + 8 + 16 * probeCount) {
return;//数据长度排错
}
_boxStatusModel.probeCount = probeCount;
_boxStatusModel.batteryStatus = bytes[4] >> 7;
_boxStatusModel.batteryPercent = bytes[4] & 0x7F;
_boxStatusModel.unit = bytes[5];
UInt8 reserved = bytes[6];
reserved = bytes[7];
reserved = bytes[8];
double timestamp = [[NSDate date] timeIntervalSince1970];
_boxStatusModel.timestamp = timestamp;
// for (int i=0, j=9+16*i; i<probeCount; i++) {
for (int i=0, j=9+16*i; i<probeMaxCount; i++) {
_probeStatusModel.index = bytes[j+0];
_probeStatusModel.dataIndex = i;
_probeStatusModel.macData = [payloadData subdataWithRange:NSMakeRange(j+1, 6)];
_probeStatusModel.macString = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X", bytes[j+6], bytes[j+5], bytes[j+4], bytes[j+3], bytes[j+2], bytes[j+1]];
if ([_probeStatusModel.macString isEqualToString:@"00:00:00:00:00:00"] || [_probeStatusModel.macString isEqualToString:@"FF:FF:FF:FF:FF:FF"]) {
continue;
}
if (i >= probeCount) {
[_probeStatusModel makeInvalid];
_probeStatusModel.timestamp = timestamp;
if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeBoxBleParser:boxStatus:probeStatus:offline:)]) {
[self.delegate meatProbeBoxBleParser:self boxStatus:_boxStatusModel probeStatus:_probeStatusModel offline:YES];
}
continue;
}
UInt16 temp = (bytes[j+7] << 8) | bytes[j+8];
_probeStatusModel.internalTemperatureRaw = temp;
_probeStatusModel.internalTemperatureUnit = (temp & 0x8000) ? ELDeviceTemperatureUnit_F : ELDeviceTemperatureUnit_C;
_probeStatusModel.internalTemperature = (temp & 0x4000) ? -(temp & 0x3FFF) : (temp & 0x3FFF);
temp = (bytes[j+9] << 8) | bytes[j+10];
_probeStatusModel.ambientTemperatureRaw = temp;
_probeStatusModel.ambientTemperatureUnit = (temp & 0x8000) ? ELDeviceTemperatureUnit_F : ELDeviceTemperatureUnit_C;
_probeStatusModel.ambientTemperature = (temp & 0x4000) ? -(temp & 0x3FFF) : (temp & 0x3FFF);
#if DEBUG
// _probeStatusModel.ambientTemperature += 40;
#endif
UInt8 battery = bytes[j+11];
_probeStatusModel.batteryRaw = battery;
_probeStatusModel.batteryStatus = battery >> 7;
_probeStatusModel.batteryPercent = battery & 0x7F;
_probeStatusModel.insertStatusRaw = bytes[j+12];
_probeStatusModel.timestamp = timestamp;
if (self.delegate && [self.delegate respondsToSelector:@selector(meatProbeBoxBleParser:boxStatus:probeStatus:offline:)]) {
[self.delegate meatProbeBoxBleParser:self boxStatus:_boxStatusModel probeStatus:_probeStatusModel offline:NO];
}
}
}

@end

@implementation ELMeatProbeBoxBleBoxStatusModel

#pragma mark ---- description

- (NSString *)description {
NSMutableString *desc = [NSStringFromClass([self class]) stringByAppendingString:@": {\n"].mutableCopy;
unsigned int count;
Ivar *ivar = class_copyIvarList([self class], &count);
for (int i = 0 ; i < count ; i++) {
Ivar iv = ivar[i];
const char *name = ivar_getName(iv);
NSString *strName = [NSString stringWithUTF8String:name];
//利用KVC取值
id value = [self valueForKey:strName];
[desc appendString:[NSString stringWithFormat:@" %@: %@,\n", strName, value]];
}
free(ivar);
[desc appendString:@"}"];
return desc;
}

- (NSString *)debugDescription {
return [self description];
}

@end

@implementation ELMeatProbeBoxBleProbeStatusModel

//数据无效
- (void)makeInvalid {
self.internalTemperatureRaw = 0xFFFF;
self.internalTemperatureUnit = 0;
self.internalTemperature = 0;
self.ambientTemperatureRaw = 0xFFFF;
self.ambientTemperatureUnit = 0;
self.ambientTemperature = 0;
self.batteryRaw = 0xFF;
self.batteryStatus = 0;
self.batteryPercent = 0;
self.insertStatusRaw = 0;
}

#pragma mark ---- description

- (NSString *)description {
NSMutableString *desc = [NSStringFromClass([self class]) stringByAppendingString:@": {\n"].mutableCopy;
unsigned int count;
Ivar *ivar = class_copyIvarList([self class], &count);
for (int i = 0 ; i < count ; i++) {
Ivar iv = ivar[i];
const char *name = ivar_getName(iv);
NSString *strName = [NSString stringWithUTF8String:name];
//利用KVC取值
id value = [self valueForKey:strName];
[desc appendString:[NSString stringWithFormat:@" %@: %@,\n", strName, value]];
}
free(ivar);
[desc appendString:@"}"];
return desc;
}

- (NSString *)debugDescription {
return [self description];
}

@end


+ 21
- 0
AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/MeatProbeBoxVC.h 查看文件

@@ -0,0 +1,21 @@
//
// MeatProbeBoxVC.h
// AILinkBleSDK_Example
//
// Created by LarryZhang on 2023/3/7.
// Copyright © 2023 zhengzida. All rights reserved.
//

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@class ELAILinkPeripheral;

@interface MeatProbeBoxVC : UIViewController

@property (nonatomic, strong) ELAILinkPeripheral *per;

@end

NS_ASSUME_NONNULL_END

+ 292
- 0
AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/MeatProbeBoxVC.m 查看文件

@@ -0,0 +1,292 @@
//
// MeatProbeBoxVC.m
// AILinkBleSDK_Example
//
// Created by LarryZhang on 2023/3/7.
// Copyright © 2023 zhengzida. All rights reserved.
//

#import "MeatProbeBoxVC.h"
#import <AILinkBleSDK/ELAILinkBleManager.h>
#import <AILinkBleSDK/NSData+AILinkBle.h>

#import "ELAILinkBleManager+MeatProbeBox.h"
#import "ELMeatProbeBoxBleParser.h"


@interface MeatProbeBoxVC () <ELAILinkBleManagerDelegate, ELMeatProbeBoxBleParserDelegate>

@property (weak, nonatomic) IBOutlet UILabel *bleStatusLabel;

@property (weak, nonatomic) IBOutlet UITextView *logTextView;


@property (nonatomic, strong) ELAILinkBleManager *bleManager;

@property (nonatomic, assign) NELBleManagerConnectState bleConnectState;

@property (nonatomic, strong) ELMeatProbeBoxBleParser *bleParser;

@property (nonatomic, strong) NSMutableSet *probeList;

@property (nonatomic, strong) ELMeatProbeBoxBleBoxStatusModel *boxStatus;

@end

@implementation MeatProbeBoxVC

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
self.probeList = [NSMutableSet set];
[self initBle];
}

- (void)dealloc {
[self deinitBle];
}

#pragma mark - Action

- (IBAction)customDataRequestAction:(id)sender {
for (NSData *mac in self.probeList) {
NSData *payload = [self.bleManager meatProbeBoxRequestCustomDataWithMac:mac];
NSString *log = [NSString stringWithFormat:@"发: payload: %@", payload];
[self addLog:log];
}
}

- (IBAction)customDataSendAction:(id)sender {
for (NSData *mac in self.probeList) {
NSData *payload = [self.bleManager meatProbeBoxSendCustomData:[self coustumData] withMac:mac];
NSString *log = [NSString stringWithFormat:@"发: payload: %@", payload];
[self addLog:log];
}
}

- (IBAction)customDataClearAction:(id)sender {
for (NSData *mac in self.probeList) {
NSData *payload = [self.bleManager meatProbeBoxClearCustomDataWithMac:mac];
NSString *log = [NSString stringWithFormat:@"发: payload: %@", payload];
[self addLog:log];
}
}

- (IBAction)switchUnitAction:(id)sender {
if (self.boxStatus.unit == 1) {
NSData *payload = [self.bleManager meatProbeBoxSwitchUint:0];
NSString *log = [NSString stringWithFormat:@"发: payload: %@ -- 切换单位 to C", payload];
[self addLog:log];
} else {
NSData *payload = [self.bleManager meatProbeBoxSwitchUint:1];
NSString *log = [NSString stringWithFormat:@"发: payload: %@ -- 切换单位 to F", payload];
[self addLog:log];
}
}

- (IBAction)clearAction:(id)sender {
self.logTextView.text = @"";
}

- (IBAction)shareLogAction:(id)sender {
}

- (NSData *)coustumData {
//自定义数据
//*******要验证设备必须支持128字节payload
Byte bytes[128];
memset(bytes, 0, sizeof(bytes));
for (int i=0; i<sizeof(bytes); i++) {
bytes[i] = 0x80 + i;
}
NSData *data = [NSData dataWithBytes:bytes length:sizeof(bytes)];
NSLog(@"meatProbeAction() data:%@", data);
return data;
}

#pragma mark - ELAILinkBleManagerDelegate

- (void)initBle {
self.bleManager = [[ELAILinkBleManager alloc] init];
self.bleManager.ailinkDelegate = self;
self.bleParser = [ELMeatProbeBoxBleParser new];
self.bleParser.delegate = self;
}

- (void)scanBle {
[self.bleManager scanFilterWithCidArray:@[@(self.per.cid)]];
}

- (void)connect:(ELAILinkPeripheral *)peripheral {
[self.bleManager connectAILinkPeripheral:peripheral];
[self updateBleStatusView:NELBleManagerConnectStateConnecting];
}

- (void)deinitBle {
[self.bleManager stopScan];
self.bleManager.ailinkDelegate = nil;
[self.bleManager disconnectPeripheral];
}

- (void)updateBleStatusView:(NELBleManagerConnectState)state {
if (self.bleManager.central.state == CBManagerStatePoweredOff) {
self.bleStatusLabel.text = @"蓝牙关闭";
[self addLog:self.bleStatusLabel.text];
return;
}
switch (state) {
case NELBleManagerConnectStateDisconnected:
self.bleStatusLabel.text = @"断开连接";
break;
case NELBleManagerConnectStateFailed:
case NELBleManagerConnectStateFailedValidation:
self.bleStatusLabel.text = @"连接失败";
break;
case NELBleManagerConnectStateConnecting:
self.bleStatusLabel.text = @"正在连接...";
break;
case NELBleManagerConnectStatePassed:
self.bleStatusLabel.text = @"连接成功";

[self requestDeviceData];
break;
case NELBleManagerConnectStateCentralScanning:
self.bleStatusLabel.text = @"正在扫描...";
break;

default:
break;
}
[self addLog:self.bleStatusLabel.text];
}

- (void)requestDeviceData {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.0), dispatch_get_main_queue(), ^{
// //APP获取设备功能列表
// [self.bleManager airDetectorRequestDeviceFunctions];
// //APP获取设备状态 //0x03 CMD:获取设备状态
// [self.bleManager airDetectorRequestDeviceStatus];
});
}

// 设备状态变更
- (void)managerDidUpdateState:(CBCentralManager *)central {
NSLog(@"%s state:%@", __func__, @(central.state));
if (central.state == CBManagerStatePoweredOn) {
[self scanBle];
} else if (central.state == CBManagerStatePoweredOff) {
self.bleConnectState = NELBleManagerConnectStateCentralPowerOff;
[self updateBleStatusView:NELBleManagerConnectStateCentralPowerOff];
}
}

- (void)managerScanState:(BOOL)scanning {
NSLog(@"%s scanning:%@", __func__, @(scanning));
if (scanning) {
[self updateBleStatusView:NELBleManagerConnectStateCentralScanning];
}
}

// 扫描到设备
- (void)managerDidDiscoverPeripheral:(ELAILinkPeripheral *)peripheral {
NSLog(@"managerDidDiscoverPeripheral cid:%02x vid:%02x pid:%02x mac:%@", peripheral.cid, peripheral.vid, peripheral.pid, peripheral.macAddressString);
if ([peripheral.macAddressString isEqualToString:self.per.macAddressString]) {
[self.bleManager stopScan];
[self connect:peripheral];
}
}

- (void)managerDidUpdateConnect:(NELBleManagerConnectState)state {
NSLog(@"%s NELBleManagerConnectState:%@", __func__, @(state));
[self updateBleStatusView:state];
}

//A7数据
- (void)aiLinkBleReceiveA7Data:(NSData *)payload {
NSLog(@"%s #### payload:%@", __func__, payload.elHexString);
NSString *log = [NSString stringWithFormat:@"收: payload: %@", payload.elHexString];
[self addLog:log];
[self.bleParser parseA7Payload:payload];
}

//A6数据
- (void)aiLinkBleReceiveA6Data:(NSData *)packet {
NSLog(@"%s ##### packet:%@", __func__, packet.elHexString);
Byte *bytes = (Byte *)packet.bytes;
Byte cmd = bytes[2];
if (cmd == ELInetGetCmdTypeGetBatteryState) {
int power = self.bleManager.battery.power;
ELBatteryChargingState state = self.bleManager.battery.state;
NSLog(@"##### state: %lu power: %d", (unsigned long)state, power);
}
if (cmd == ELInetGetCmdTypeGetBMVersion) {
NSString *bmVersion = self.bleManager.bmVersion;
NSLog(@"##### bmVersion: %@", bmVersion);
}
if (cmd == ELInetGetCmdTypeGetBMVersionPro) {
NSString *bmVersionPro = self.bleManager.bmVersionPro;
NSLog(@"##### bmVersionPro: %@", bmVersionPro);
}
}

#pragma mark - ELMeatProbeBoxBleParserDelegate

//MCU 上报设备状态数据(Type:02)
- (void)meatProbeBoxBleParser:(ELMeatProbeBoxBleParser *)bleParser boxStatus:(ELMeatProbeBoxBleBoxStatusModel *)boxStatus probeStatus:(ELMeatProbeBoxBleProbeStatusModel *)probeStatus offline:(BOOL)offline {
NSLog(@"##### boxStatus(): %@ probeStatus(): %@", boxStatus, probeStatus);
self.boxStatus = boxStatus;
NSString *log = [NSString stringWithFormat:@"boxStatus: { probeMaxCount:%hhu, probeCount:%hhu, batteryStatus:%hhu batteryPercent:%hhu, unit:%ld }", boxStatus.probeMaxCount, boxStatus.probeCount, boxStatus.batteryStatus, boxStatus.batteryPercent, boxStatus.unit];
[self addLog:log];
NSString *log2 = [NSString stringWithFormat:@"probeStatus: { index:%hhu, macString:%@, internalTemperature:%ld, ambientTemperature:%ld, batteryPercent:%hhu }", probeStatus.index, probeStatus.macString, probeStatus.internalTemperature, probeStatus.ambientTemperature, probeStatus.batteryPercent];
[self addLog:log2];
if (![self.probeList containsObject:probeStatus.macData]) {
[self.probeList addObject:probeStatus.macData];
NSData *payload = [self.bleManager meatProbeBoxRequestCustomDataWithMac:probeStatus.macData];
NSString *log = [NSString stringWithFormat:@"发: payload: %@", payload];
[self addLog:log];
}
}

//设置、获取设备参数数据(Type:03)
- (void)meatProbeBoxBleParser:(ELMeatProbeBoxBleParser *)bleParser state:(BOOL)state mac:(NSData *)mac customData:(NSData *)customData {
NSLog(@"##### state:%d mac:%@ customData():%@", state, mac, customData);
NSLog(@"");
}

//切换单位(Type:04)
- (void)meatProbeBoxBleParser:(ELMeatProbeBoxBleParser *)bleParser unit:(ELDeviceTemperatureUnit)unit {
NSLog(@"##### unit(): %@", @(unit));
NSLog(@"");
}

#pragma mark - addLog

- (void)addLog:(NSString *)log {
[self addLog:log newline:YES];
}

- (void)addWithoutNewlineLog:(NSString *)log {
[self addLog:log newline:NO];
}

- (void)addLog:(NSString *)log newline:(BOOL)newline {
NSDateFormatter *format = [[NSDateFormatter alloc] init];
format.dateFormat = @"HH:mm:ss.SSS";
NSString *time = [format stringFromDate:[NSDate date]];
if (newline) {
self.logTextView.text = [self.logTextView.text stringByAppendingFormat:@"%@ %@\n", time, log];
} else {
self.logTextView.text = [self.logTextView.text stringByAppendingFormat:@"%@ %@", time, log];
}
[self.logTextView scrollRangeToVisible:NSMakeRange(self.logTextView.text.length, 1)];
}


@end

+ 145
- 0
AILinkBleSDKDemo/DeviceDemo/27_MeatProbeBox/MeatProbeBoxVC.xib 查看文件

@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MeatProbeBoxVC">
<connections>
<outlet property="bleStatusLabel" destination="Rgz-Ge-utp" id="h2s-vl-sLn"/>
<outlet property="logTextView" destination="Txf-5E-hsN" id="Azk-gu-Gls"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="K5I-eH-HGA">
<rect key="frame" x="16" y="346" width="31" height="30"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="清空"/>
<connections>
<action selector="clearAction:" destination="-1" eventType="touchUpInside" id="o2p-MO-8pL"/>
</connections>
</button>
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="lwE-Xr-Dac">
<rect key="frame" x="346" y="346" width="31" height="30"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="分享"/>
<connections>
<action selector="shareLogAction:" destination="-1" eventType="touchUpInside" id="aLe-00-nz6"/>
</connections>
</button>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stauts" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Rgz-Ge-utp">
<rect key="frame" x="0.0" y="63" width="393" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="I1h-EM-UuI">
<rect key="frame" x="8" y="384" width="377" height="434"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" indicatorStyle="white" editable="NO" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Txf-5E-hsN">
<rect key="frame" x="0.0" y="0.0" width="377" height="434"/>
<color key="backgroundColor" systemColor="labelColor"/>
<color key="textColor" systemColor="opaqueSeparatorColor"/>
<fontDescription key="fontDescription" name="HelveticaNeue-Light" family="Helvetica Neue" pointSize="10"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
</subviews>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="Txf-5E-hsN" secondAttribute="bottom" id="CLf-PD-bjv"/>
<constraint firstItem="Txf-5E-hsN" firstAttribute="top" secondItem="I1h-EM-UuI" secondAttribute="top" id="RHZ-uy-ZqR"/>
<constraint firstItem="Txf-5E-hsN" firstAttribute="leading" secondItem="I1h-EM-UuI" secondAttribute="leading" id="vQ7-WS-tPk"/>
<constraint firstAttribute="trailing" secondItem="Txf-5E-hsN" secondAttribute="trailing" id="wsr-Tq-aYp"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
<real key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="U2W-tX-U1Z">
<rect key="frame" x="24" y="108" width="145.33333333333334" height="35"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="请求自定义数据"/>
<connections>
<action selector="customDataRequestAction:" destination="-1" eventType="touchUpInside" id="EbK-Xt-NEO"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MNm-EU-G2q">
<rect key="frame" x="201.33333333333337" y="108" width="146" height="35"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="发送自定义数据"/>
<connections>
<action selector="customDataSendAction:" destination="-1" eventType="touchUpInside" id="Bgd-AX-0sf"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="AXK-mu-b6T">
<rect key="frame" x="202" y="159" width="93.333333333333314" height="35"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="单位切换"/>
<connections>
<action selector="switchUnitAction:" destination="-1" eventType="touchUpInside" id="qmW-aP-fla"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7tV-LN-Ahy">
<rect key="frame" x="24" y="159" width="146" height="35"/>
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="清除自定义数据"/>
<connections>
<action selector="customDataClearAction:" destination="-1" eventType="touchUpInside" id="ZWX-NO-7e6"/>
</connections>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="Q5M-cg-NOt"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="Rgz-Ge-utp" firstAttribute="leading" secondItem="Q5M-cg-NOt" secondAttribute="leading" id="26n-ac-URx"/>
<constraint firstItem="K5I-eH-HGA" firstAttribute="leading" secondItem="Q5M-cg-NOt" secondAttribute="leading" constant="16" id="43e-FM-L00"/>
<constraint firstItem="U2W-tX-U1Z" firstAttribute="top" secondItem="Rgz-Ge-utp" secondAttribute="bottom" constant="24" id="76S-le-4CY"/>
<constraint firstItem="Rgz-Ge-utp" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="Cuz-sL-8PR"/>
<constraint firstItem="7tV-LN-Ahy" firstAttribute="leading" secondItem="Q5M-cg-NOt" secondAttribute="leading" constant="24" id="DGY-hw-cQW"/>
<constraint firstItem="Q5M-cg-NOt" firstAttribute="bottom" secondItem="I1h-EM-UuI" secondAttribute="bottom" id="Dfj-32-bLS"/>
<constraint firstItem="I1h-EM-UuI" firstAttribute="top" secondItem="K5I-eH-HGA" secondAttribute="bottom" constant="8" symbolic="YES" id="EN4-TU-LIY"/>
<constraint firstItem="Rgz-Ge-utp" firstAttribute="top" secondItem="Q5M-cg-NOt" secondAttribute="top" constant="4" id="NV7-q2-a68"/>
<constraint firstItem="AXK-mu-b6T" firstAttribute="top" secondItem="U2W-tX-U1Z" secondAttribute="bottom" constant="16" id="Nnq-dz-fTJ"/>
<constraint firstItem="7tV-LN-Ahy" firstAttribute="top" secondItem="U2W-tX-U1Z" secondAttribute="bottom" constant="16" id="RA0-gL-Ljv"/>
<constraint firstItem="AXK-mu-b6T" firstAttribute="leading" secondItem="7tV-LN-Ahy" secondAttribute="trailing" constant="32" id="RAL-eu-lGT"/>
<constraint firstItem="MNm-EU-G2q" firstAttribute="leading" secondItem="U2W-tX-U1Z" secondAttribute="trailing" constant="32" id="Su5-Ls-bvw"/>
<constraint firstItem="Q5M-cg-NOt" firstAttribute="trailing" secondItem="I1h-EM-UuI" secondAttribute="trailing" constant="8" id="Ulp-Zv-w68"/>
<constraint firstItem="Q5M-cg-NOt" firstAttribute="trailing" secondItem="lwE-Xr-Dac" secondAttribute="trailing" constant="16" id="aZt-4V-Vkm"/>
<constraint firstItem="I1h-EM-UuI" firstAttribute="top" secondItem="Rgz-Ge-utp" secondAttribute="bottom" constant="300" id="gWj-B6-gld"/>
<constraint firstItem="I1h-EM-UuI" firstAttribute="leading" secondItem="Q5M-cg-NOt" secondAttribute="leading" constant="8" id="mGL-Xz-QuQ"/>
<constraint firstItem="Q5M-cg-NOt" firstAttribute="trailing" secondItem="Rgz-Ge-utp" secondAttribute="trailing" id="myT-ol-sQQ"/>
<constraint firstItem="U2W-tX-U1Z" firstAttribute="leading" secondItem="Q5M-cg-NOt" secondAttribute="leading" constant="24" id="onE-X9-raT"/>
<constraint firstItem="MNm-EU-G2q" firstAttribute="top" secondItem="Rgz-Ge-utp" secondAttribute="bottom" constant="24" id="vx8-hV-lTa"/>
<constraint firstItem="I1h-EM-UuI" firstAttribute="top" secondItem="lwE-Xr-Dac" secondAttribute="bottom" constant="8" symbolic="YES" id="zvN-yN-K2g"/>
</constraints>
<point key="canvasLocation" x="53" y="20"/>
</view>
</objects>
<resources>
<systemColor name="labelColor">
<color red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="opaqueSeparatorColor">
<color red="0.77647058823529413" green="0.77647058823529413" blue="0.78431372549019607" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

+ 9
- 0
AILinkBleSDKDemo/Others/ViewController.m 查看文件

@@ -20,6 +20,7 @@
#import "BabyScaleViewController.h"
#import "BloodScanViewController.h"
#import "HeightGuageScanViewController.h"
#import "BroadcastHeightGuage.h"
#import "RemoteControlScanViewController.h"
#import "ForeheadScanViewController.h"
#import "ThermometerScanViewController.h"
@@ -42,6 +43,8 @@
#import "HeightBodyFatScaleVC.h"


#import "MeatProbeVC.h"
#import "MeatProbeBoxVC.h"



@@ -69,6 +72,9 @@
[ELDemoDeviceModel modelWithIndex:@"04" imageName:@"type_baby_scale_ic" title:@"Baby Scale" subtitle:@"婴儿秤" entryVCName:NSStringFromClass(BabyScaleViewController.class)],
[ELDemoDeviceModel modelWithIndex:@"05" imageName:@"type_sphygmomanometer_ic" title:@"Sphygmomanometer" subtitle:@"血压计" entryVCName:NSStringFromClass(BloodScanViewController.class)],
[ELDemoDeviceModel modelWithIndex:@"06" imageName:@"type_height_measuring_instrument" title:@"Height Guage" subtitle:@"身高仪" entryVCName:NSStringFromClass(HeightGuageScanViewController.class)],
[ELDemoDeviceModel modelWithIndex:@"06B" imageName:@"type_height_measuring_instrument" title:@"Broadcast Height Guage" subtitle:@"广播身高仪" entryVCName:NSStringFromClass(BroadcastHeightGuage.class)],
[ELDemoDeviceModel modelWithIndex:@"07" imageName:@"type_control_vision_ic" title:@"Remote Control" subtitle:@"遥控器" entryVCName:NSStringFromClass(RemoteControlScanViewController.class)],
[ELDemoDeviceModel modelWithIndex:@"08" imageName:@"type_temperature_gun_ic" title:@"Forehead thermometer" subtitle:@"额温枪" entryVCName:NSStringFromClass(ForeheadScanViewController.class)],
[ELDemoDeviceModel modelWithIndex:@"09" imageName:@"type_thermometer_ic" title:@"Digital thermometer" subtitle:@"温度计" entryVCName:NSStringFromClass(ThermometerScanViewController.class)],
@@ -93,6 +99,9 @@
[ELDemoDeviceModel modelWithIndex:@"25" imageName:@"height_body_fat_scale_type_ic" title:@"HeightBodyFatScale" subtitle:@"身高体脂秤" entryVCName:NSStringFromClass(HeightBodyFatScaleVC.class) cids:@[@(ELSupportDeviceTypeHeightBodyFatScale)]],
[ELDemoDeviceModel modelWithIndex:@"26" imageName:@"meat_probe_type_ic" title:@"MeatProbe" subtitle:@"食物探针" entryVCName:NSStringFromClass(MeatProbeVC.class) cids:@[@(ELSupportDeviceTypeMeatProbe)]],
[ELDemoDeviceModel modelWithIndex:@"27" imageName:@"ailink_cid85_type_ic" title:@"MeatProbeBox" subtitle:@"食物探针盒子" entryVCName:NSStringFromClass(MeatProbeBoxVC.class) cids:@[@(ELSupportDeviceTypeMeatProbeBox)]],
];
}


+ 1
- 0
README.md 查看文件

@@ -10,4 +10,5 @@
| 1.5.9| 20230206 | larry | 增加 身高体脂秤,优化 Demo UI |
| 1.5.11 | 20230327 | larry | 增加 蓝牙体重秤 |
| 1.5.15 | 20230427 | larry | 修改 增加 蓝牙牙刷防飞溅 |
| 1.6.1 | 20230626 | larry | 修改 增加 广播身高仪 食物探针 食物探针盒子 支持 |


Loading…
取消
儲存