//
// LeDiscovery.h
// JK_xuXuKou
//
// Created by vita on 15/8/25.
// Copyright (c) 2015年 ZZ_Macpro. All rights reserved.
//
#import
#import
#import
#import "FMDB.h"
@interface LeDiscovery :NSObject
typedef enum {
temperatureWarning,
peeWarning,
} warningStyle;
- (void)countData;
// 周边设备群
@property (nonatomic,strong) NSMutableArray *peripheralArray;
@property (nonatomic,strong) CBPeripheral *connectPeripheral;
// 发现的周边设备
@property (nonatomic,strong) CBPeripheral *discoveredPeripheral;
// 中央设备管理者
@property (nonatomic,strong) CBCentralManager *manager;
@property (nonatomic,strong) NSString *reciveString;
@property (nonatomic,strong) NSMutableArray *peripheralModelArray;
/**当前温度*/
@property (nonatomic,strong) NSNumber *temperature;
/**当前湿度*/
@property (nonatomic,strong) NSNumber *humidity;
/**当前电量*/
@property (nonatomic,strong) NSNumber *battery;
/**当前时间*/
@property (nonatomic,strong) NSNumber *time;
@property (nonatomic,strong) NSDate *disConnectBluetoothTime; //断开蓝牙的时间
@property (nonatomic,assign) NSInteger clickTimes; //点击蓝牙连接的次数
@property (nonatomic,assign) BOOL isLine; //判断蓝牙是否连接(设备成功)
@property (nonatomic,assign) BOOL preChangePeripheral; //判断是否手动更换连接设备
@property (nonatomic,assign) NSInteger count; //通知的数量
+ (LeDiscovery *) sharedInstance;
/****************************************************************************/
/* Actions */
/****************************************************************************/
- (CBCentralManagerState) startScanningForUUIDString:(NSString *)uuidString;
- (void) stopScanning;
- (void) connectPeripheral:(CBPeripheral*)peripheral;
- (void) disconnectPeripheral:(CBPeripheral*)peripheral;
- (void) centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral;
@end
//
// LeDiscovery.m
// JK_xuXuKou
//
// Created by vita on 15/8/25.
// Copyright (c) 2015年 ZZ_Macpro. All rights reserved.
//
#import
#import "LeDiscovery.h"
#import "MBProgressHUD+MJ.h"
@interface LeDiscovery () <CBCentralManagerDelegate,CBPeripheralDelegate>
@end
@implementation LeDiscovery
#pragma mark --------------------------- 蓝牙设备 ---------------------------
+ (LeDiscovery*) sharedInstance
{
static LeDiscovery *helper;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (helper == nil) {
helper = [[LeDiscoveryalloc] init];
}
});
return helper;;
}
- (LeDiscovery*) init
{
self = [superinit];
if (self) {
/**
B-1.创建中央设备
*/
_manager =[[CBCentralManageralloc]initWithDelegate:selfqueue:nil];
/**
B-2.实例化周边设备群(数组)
*/
_peripheralArray = [[NSMutableArrayalloc] init];
[selfcreatSQLite];
}
return self;
}
#pragma mark --------------------------- 蓝牙操作 ---------------------------
/****************************************************************************/
/* 扫描设备 scan/disscan */
/****************************************************************************/
/**
* 检查蓝牙状态
*/
- (void)centralManagerDidUpdateState:(CBCentralManager *)central
{
if (central.state !=CBCentralManagerStatePoweredOn)
{
// NSLog(@"请打开蓝牙!");
_disConnectBluetoothTime = [NSDatedate];
return;
}
if (_connectPeripheral) {
[self.managerconnectPeripheral:_connectPeripheraloptions:[NSDictionarydictionaryWithObject:[NSNumbernumberWithBool:NO]forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
return;
}
//扫描指定设备
[selfstartScanningForUUIDString:SERVICE_UUID];
}
/**
* 检测到蓝牙开启,扫描设备
*/
- (CBCentralManagerState) startScanningForUUIDString:(NSString *)uuidString;
{
[_manager scanForPeripheralsWithServices:@[[CBUUIDUUIDWithString:uuidString]]options:nil];
CBCentralManagerState currentState = [_managerstate];
return currentState;
}
/**
* 停止扫描设备
*/
- (void)stopScanning
{
[self.managerstopScan];
// NSLog(@"关闭扫描");
}
/****************************************************************************/
/* 发现设备 Discovery */
/****************************************************************************/
/**
* 3.发现外设
*
* @param central 中央设备
* @param peripheral 周边设备
* @param advertisementData 响应数据
* @param RSSI 信号强度
*/
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI
{
NSUserDefaults *perialUUIDString = [NSUserDefaultsstandardUserDefaults];
NSString *str = [perialUUIDString objectForKey:@"UUIDString"];
if ([strisEqualToString:peripheral.identifier.UUIDString]) {
[self.managerconnectPeripheral:peripheral options:nil];
}
//保存搜索到的设备到 周边设备数组
if ([_peripheralArraycontainsObject:peripheral]) {
return;
}else {
[_peripheralArrayaddObject:peripheral];
}
}
/****************************************************************************/
/* 连接设备 Connection/Disconnection */
/****************************************************************************/
- (void)connectPeripheral:(CBPeripheral*)peripheral
{
if (_connectPeripheral) {
[self.managercancelPeripheralConnection:_connectPeripheral];
}
[self.managerconnectPeripheral:peripheral options:[NSDictionarydictionaryWithObject:[NSNumbernumberWithBool:NO]forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
}
- (void)disconnectPeripheral:(CBPeripheral*)peripheral
{
[self.managercancelPeripheralConnection:peripheral];
}
#pragma mark --------------------------- 连接设备后的操作 ---------------------------
/**
* 5.连接外设成功调用
*/
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral
{
// 停止扫描
_disConnectBluetoothTime =nil;
[_manager stopScan];
_connectPeripheral = peripheral;
// 设置代理
_connectPeripheral.delegate =self;
// 扫描服务
[_connectPeripheraldiscoverServices:@[[CBUUIDUUIDWithString:SERVICE_UUID]]];
// NSLog(@"连接成功");
self.isLine =YES;
NSUserDefaults *perialUUIDString = [NSUserDefaultsstandardUserDefaults];
[perialUUIDStringsetObject:peripheral.identifier.UUIDStringforKey:@"UUIDString"];
[perialUUIDStringsynchronize];
}
/**
* 5-1.当已经与peripheral建立的连接断开时调用
*/
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
// NSLog(@"重连中!!!");
self.isLine =NO;
_preChangePeripheral =NO;
NSLog(@"断线重连接!!!");
[self.managerconnectPeripheral:_connectPeripheraloptions:[NSDictionarydictionaryWithObject:[NSNumbernumberWithBool:NO]forKey:CBConnectPeripheralOptionNotifyOnDisconnectionKey]];
}
/**
* 5-2.当central管理者与peripheral建立连接失败时调用
*/
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error
{
// NSLog(@"连接失败,正在重试");
// _disConnectBluetoothTime = [NSDate date];
// [self countDisConnectTime];
self.isLine =NO;
[selfstartScanningForUUIDString:SERVICE_UUID];
}
/****************************************************************************/
/* 发现设备的服务和特征 Discover Services、Characteristics */
/****************************************************************************/
/**
* 6.发现服务
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error
{
for (CBService *servicein peripheral.services)
{
// NSLog(@"服务 UUID: %@", service.UUID);
[_connectPeripheraldiscoverCharacteristics:nilforService:service];
}
}
/**
* 7.发现特征
*
* @param peripheral 周边设备
* @param service 发现的服务
* @param error 错误信息
*/
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error
{
// 服务UUID匹配
if ([service.UUIDisEqual:[CBUUIDUUIDWithString:SERVICE_UUID]]) {
for (CBCharacteristic *characteristicin service.characteristics)
{
// 特征UUID匹配
// NSLog(@"特征 UUID: %@", characteristic.UUID);
// 开启监听 开启了才能执行下面的接受数据
if ([characteristic.UUIDisEqual:[CBUUIDUUIDWithString:CHARACTERISTIC02_UUID]]) {
uint8_t value[] = {0x55,0x03};
[_connectPeripheralwriteValue:[NSDatadataWithBytes:&value length:sizeof(value)]forCharacteristic:characteristic type:CBCharacteristicWriteWithResponse];
}
if ([characteristic.UUIDisEqual:[CBUUIDUUIDWithString:CHARACTERISTIC01_UUID]]) {
[_connectPeripheralsetNotifyValue:YESforCharacteristic:characteristic];
}
}
}
}
/****************************************************************************/
/* 接收数据 */
/****************************************************************************/
- (void)peripheral:(CBPeripheral *)peripheral didWriteValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error) {
// NSLog(@"didWriteValueForCharacteristic error:%@",error.description);
}
}
/**
* 8.接收数据
*
* @param peripheral 外部设备
* @param characteristic 外设特征
* @param error 错误信息
*/
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
{
if (error)
{
NSLog(@"didUpdateValueForCharacteristic error : %@", error.localizedDescription);
return;
}
// NSLog(@"设备 :%@ %@",self.connectPeripheral.identifier.UUIDString,peripheral.identifier.UUIDString);
if([characteristic.UUIDisEqual:[CBUUIDUUIDWithString:CHARACTERISTIC01_UUID]]){
if (characteristic.value.length >7) {
//将接收到的十六进制数据转成 十六进制字符串
NSString *reciveString = [NSStringstringWithFormat:@"%@", [selfhexadecimalString:characteristic.value]];
NSUserDefaults *productDefault = [NSUserDefaultsstandardUserDefaults];
NSString *productNumber = [reciveString substringWithRange:NSMakeRange(7,17)];
[productDefaultsetObject:productNumber forKey:@"productNumber"];
[productDefaultsynchronize];
}else{
//将接收到的十六进制数据转成 十六进制字符串
NSString *reciveString = [NSStringstringWithFormat:@"%@", [selfhexadecimalString:characteristic.value]];
if (characteristic.value) {
self.isLine =YES;
}else {
self.isLine =NO;
}
// NSLog(@"%@",reciveString);
//转成十进制数字并 打印
[selftransformDataWithString:reciveString];
}
}
}
/**
* 8-1.十六进制Data 转成 十六进制字符串
*/
- (NSString *)hexadecimalString :(NSData *)data
{
/* Returns hexadecimal string of NSData. Empty string if data is empty. */
const unsignedchar *dataBuffer = (constunsigned char *)[databytes];
if (!dataBuffer)
return [NSStringstring];
NSUInteger dataLength = [data length];
NSMutableString *hexString = [NSMutableStringstringWithCapacity:(dataLength * 2)];
for (int i =0; i < dataLength; ++i)
[hexStringappendString:[NSStringstringWithFormat:@"%02lx", (unsignedlong)dataBuffer[i]]];
return [NSStringstringWithString:hexString];
}
/**
* 8-2.十六进制字符串转成数字
*
* @param str 十六进制字符串
*/
- (void)transformDataWithString: (NSString*)str
{
//记录当前时间
_time = [NSNumbernumberWithLongLong:[selfcountCurrentDay]];
//接收的数据长度为 14(温度、湿度)或者 8(电池电量),数据发送顺序为 14、14、8、14、14、8......
if (str.length >8) {
//当前温度数据
_temperature = [NSNumbernumberWithInteger: strtoul([[strsubstringWithRange:NSMakeRange(4,4)] UTF8String],0,16)];
//当前湿度数据
_humidity = [NSNumbernumberWithInteger: strtoul([[strsubstringWithRange:NSMakeRange(8,4)] UTF8String],0,16) ];
[selfinsertSQLite:_temperature :_humidity :_battery :_time];
}else{
//电池电量数据
_battery = [NSNumbernumberWithInteger: strtoul([[strsubstringWithRange:NSMakeRange(4,2)] UTF8String],0,16)];
}
}
#pragma mark --------------------------- 将NSDate 直接转成 yyyyMMddHHmmss ---------------------------
//计算当前日期
- (longlong) countCurrentDay
{
NSDateFormatter *dateformatter=[[NSDateFormatteralloc] init];
[dateformattersetDateFormat:@"yyyyMMddHHmmss"];
NSString *today = [NSStringstringWithFormat:@"%lld",[[dateformatterstringFromDate:[NSDatedate]] longLongValue]];
long long now = [todaylongLongValue];
return now;
}
//计算断开连接时间
- (NSInteger)countDisConnectTime
{
if (!_disConnectBluetoothTime)
return 0;
else{
NSCalendar *calendar = [NSCalendarcurrentCalendar];
NSDateFormatter *dateFormatter = [[NSDateFormatteralloc] init];
[dateFormattersetDateFormat:@"yyyy-MM-dd HH:mm:ss"];
NSCalendarUnit unitFlags = NSMinuteCalendarUnit;
NSDateComponents *time = [calendarcomponents:unitFlags fromDate:_disConnectBluetoothTimetoDate:[NSDatedate] options:0];
if(_connectPeripheral.state ==CBPeripheralStateDisconnected)
return [time minute];
else
return 0;
}
}
@end