<template>
	<view style="width: 100%;">
		<button @click="getBluetoothDevices">获取设备</button>
		<view class="device-item" v-if="item.name=='FAYA'" @click="connectBlue(item)" v-for="item in deviceList" :key="item.name">
			<text>{{item.name}}</text>
			<text>点击连接</text>
		</view>
		<view>
			状态：{{statusStr}}
		</view>
		<view>
			结果：{{balanceData}}
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				deviceList:[], // 设备列表
				deviceId: '',
				connectedDeviceId: '',
				services: [],
				notifyCharacteristicsId:'',
				notifyServicweId: '',
				writeDatas: '',
				balanceData: '',
				hexstr: '',
				statusStr: ''
			};
		},
		onShow() {
			let _this = this
			// this.closeConnect()
			const res = uni.getSystemInfoSync();
			// 初始化蓝牙模块
			uni.openBluetoothAdapter({
			  success(res) {
			    console.log(res)
				_this.statusStr = '初始化蓝牙模块成功'
				/* 获取本机的蓝牙状态 */
				setTimeout(() => {
					_this.init()
				}, 1000)
			  }
			})
			// 监听蓝牙适配器状态变化事件
			uni.onBluetoothAdapterStateChange(function (res) {
			  console.log(res,'适配器变化')
			})
			
			if(!res.bluetoothEnabled){
				uni.showModal({
					title:'提示',
					content:'请开启手机蓝牙',
					complete(e) {
						console.log(e)
						_this.statusStr = '请开启手机蓝牙'
					}
				})
			} 
		},
		methods: {
			// 初始化蓝牙
			init(){
				let _this = this
				uni.getBluetoothAdapterState({
				  success(res) {
				    console.log(res)
					_this.statusStr = 'adapterState changed, now is'
					// 开始搜寻附近的蓝牙外围设备
					_this.startBluetoothDevicesDiscovery()
				  },
				  fail(res) {
					  console.log(res)
				  }
				})
			},
			startBluetoothDevicesDiscovery(){
				let _this = this
				uni.startBluetoothDevicesDiscovery({
				  services: [],
				  success(res) {
				    console.log(res)
					// 监听寻找到新设备的事件
					uni.onBluetoothDeviceFound(function (res) {
					  _this.statusStr = '发现新设备'
					  console.dir(res.devices)
					  if(res.devices[0].name == 'FAYA'){
						  _this.deviceId = res.devices[0].deviceId
						  _this.deviceList = res.devices
						  // _this.createBLEConnection()
					  }
					})
				  }
				})
			},
			// 获取在蓝牙模块生效期间所有已发现的蓝牙设备
			getBluetoothDevices() {
				let _this = this
				uni.getBluetoothDevices({
				  success(res) {
				    console.log(res)
				    if (res.devices.length) {
					  _this.deviceList = res.devices
				    }
				  }
				})
			},
			connectBlue(item){
				this.deviceId = item.deviceId
				this.createBLEConnection()
			},
			// 连接指定设备
			createBLEConnection(){
				let _this = this
				uni.createBLEConnection({
				  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
				  deviceId:this.deviceId,
				  success(res) {
				    console.log(res)
					_this.statusStr = '连接设备成功'
					_this.connectedDeviceId = _this.deviceId
					// 获取连接设备的service服务
					setTimeout(()=>{
						_this.getBLEDeviceServices()						  
					},1000)
				  }
				})
			},
			// 获取连接设备的service服务
			getBLEDeviceServices(){
				let _this = this
				uni.getBLEDeviceServices({
				  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
				  deviceId: _this.deviceId,
				  success(res) {
				    console.log('device services:', res.services)
					_this.statusStr = '获取连接设备的service服务成功'
					_this.services = res.services
					/* 获取连接设备的所有特征值 */
					setTimeout(()=>{
						_this.getBLEDeviceCharacteristics()
					},500)
					// 停止搜索
					uni.stopBluetoothDevicesDiscovery({
						success: function(res) {
							console.log(res, '停止搜索')
						},
						fail(res) {
						}
					})
				  }
				})
			},
			// 获取连接设备的所有特征值
			getBLEDeviceCharacteristics(){
				let _this = this
				this.notifyServicweId = this.services[1].uuid
				uni.getBLEDeviceCharacteristics({
					deviceId: this.connectedDeviceId,
					serviceId: this.notifyServicweId,
					success: function(res) {
						console.log(res)
						_this.statusStr = '获取连接设备的所有特征值成功'
						for (let i = 0; i < res.characteristics.length; i++) {
							if ((res.characteristics[i].properties.notify || res.characteristics[i].properties.indicate) &&
								(res.characteristics[i].properties.read && res.characteristics[i].properties.write)) {
								console.log(res.characteristics[i].uuid, '蓝牙特征值 ==========')
								/* 获取蓝牙特征值 */
								_this.notifyCharacteristicsId = res.characteristics[i].uuid
								// 启用低功耗蓝牙设备特征值变化时的 notify 功能
								setTimeout(()=>{
									_this.notifyBLECharacteristicValueChange()
								},500)
							}
						}
					},
					fail: function(res) {
						console.log(res)
					}
				})
			},
			// 启用低功耗蓝牙设备特征值变化时的 notify 功能
			 notifyBLECharacteristicValueChange() { 
				let that = this;
				console.log(that.connectedDeviceId,that.notifyServicweId,that.notifyCharacteristicsId)
				uni.notifyBLECharacteristicValueChange({
					state: true,
					deviceId: that.connectedDeviceId,
					serviceId: that.notifyServicweId,
					// characteristicId: that.notifyCharacteristicsId,
					characteristicId: '49535343-1E4D-4BD9-BA61-23C647249616',
					success(res) {
						console.log(res,'notifyBLECharacteristicValueChange')
						that.statusStr = '启用低功耗蓝牙设备特征值变化成功'
						/*用来监听手机蓝牙设备的数据变化*/
						uni.onBLECharacteristicValueChange(function(res) {
							console.log(res,'read data')
							that.balanceData = that.buf2string(res.value)
							// that.hexstr = that.receiveData(res.value)
						})
					},
					fail(res) {
						console.log(res, '启用低功耗蓝牙设备监听失败')
					}
				})
			},
			/*转换成需要的格式*/
		    buf2string(buffer) {
				let arr = Array.prototype.map.call(new Uint8Array(buffer), x => x)
				return arr.map((char, i) => {
					return String.fromCharCode(char);
				}).join('');
			},
			receiveData(buf) {
					return this.hexCharCodeToStr(this.ab2hex(buf))
			},
			/*转成二进制*/
			ab2hex (buffer) {
			  let hexArr = Array.prototype.map.call(
				  new Uint8Array(buffer), function (bit) {
					  return ('00' + bit.toString(16)).slice(-2)
				  }
			  )
			  return hexArr.join('')
			},
			/*转成可展会的文字*/
			hexCharCodeToStr(hexCharCodeStr) {
			  let trimedStr = hexCharCodeStr.trim();
			  let rawStr = trimedStr.substr(0, 2).toLowerCase() === '0x' ? trimedStr.substr(2) : trimedStr;
			  let len = rawStr.length;
			  let curCharCode;
			  let resultStr = [];
			  for (let i = 0; i < len; i = i + 2) {
				  curCharCode = parseInt(rawStr.substr(i, 2), 16);
				  resultStr.push(String.fromCharCode(curCharCode));
			  }
			  return resultStr.join('');
			},
			// 发送数据
			sendData(str) {
			    let that = this;
			    let dataBuffer = new ArrayBuffer(3)
			    let dataView = new DataView(dataBuffer)
			    // for (let i = 0; i < str.length; i++) {
			    //     dataView.setUint8(i, str.charAt(i).charCodeAt())
			    // }
				dataView.setUint8(0, 0x02)
				dataView.setUint8(1, 0x42)
				dataView.setUint8(2, 0x03)
			    let dataHex = that.ab2hex(dataBuffer);
			    this.writeDatas = that.hexCharCodeToStr(dataHex);
			    uni.writeBLECharacteristicValue({
			        deviceId: that.connectedDeviceId,
			        serviceId: that.notifyServicweId,
			        characteristicId: that.notifyCharacteristicsId,
					// characteristicId: '49535343-1E4D-4BD9-BA61-23C647249616',
			        value: dataBuffer,
			        success: function (res) {
			            console.log('发送的数据：' + that.writeDatas)
			            console.log('message发送成功')
			        },
			        fail: function (res) {
						console.log('发送失败：' + res)
			        },
			        complete: function (res) {
			        }
			    })
			},
			 // 断开设备连接
			closeConnect() {
				let that = this;
			    if (that.connectedDeviceId) {
			        uni.closeBLEConnection({
			            deviceId: that.connectedDeviceId,
			            success: function(res) {
			                that.closeBluetoothAdapter()
			            },
			            fail(res) {
			            }
			        })
			    } else {
			        that.closeBluetoothAdapter()
			    }
			},
			// 关闭蓝牙模块
			closeBluetoothAdapter() {
				let that = this;
			    uni.closeBluetoothAdapter({
			        success: function(res) {
						that.statusStr = '关闭蓝牙模块'
						that.balanceData = ''
						console.log(res,'closeBluetoothAdapter')
			        },
			        fail: function(err) {
			        }
			    })
			},
		},
		onUnload() {
			this.closeConnect()
		}
	}
</script>

<style lang="scss">
	.device-item{
		width: 100%;
		padding: 20upx;
		border-bottom: 2upx solid #eee;
		display: flex;
		align-items: center;
		justify-content: space-between;
	}
</style>
