bluetooth.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. function inArray(arr, key, val) {
  2. for (let i = 0; i < arr.length; i++) {
  3. if (arr[i][key] === val) {
  4. return i
  5. }
  6. }
  7. return -1
  8. }
  9. // ArrayBuffer转16进度字符串示例
  10. function ab2hex(buffer) {
  11. const hexArr = Array.prototype.map.call(
  12. new Uint8Array(buffer),
  13. function (bit) {
  14. return (`00${bit.toString(16)}`).slice(-2)
  15. }
  16. )
  17. return hexArr.join('')
  18. }
  19. Page({
  20. onShareAppMessage() {
  21. return {
  22. title: '蓝牙',
  23. path: 'packageAPI/pages/device/bluetooth/bluetooth'
  24. }
  25. },
  26. data: {
  27. theme: 'light',
  28. devices: [],
  29. connected: false,
  30. chs: [],
  31. },
  32. onUnload() {
  33. this.closeBluetoothAdapter()
  34. },
  35. openBluetoothAdapter() {
  36. const that = this
  37. wx.openBluetoothAdapter({
  38. success: (res) => {
  39. console.log('openBluetoothAdapter success', res)
  40. that.startBluetoothDevicesDiscovery()
  41. },
  42. fail: (res) => {
  43. if (res.errCode === 10001) {
  44. wx.showModal({
  45. title: '错误',
  46. content: '未找到蓝牙设备, 请打开蓝牙后重试。',
  47. showCancel: false
  48. })
  49. wx.onBluetoothAdapterStateChange(function (res) {
  50. if (res && res.available) {
  51. that.startBluetoothDevicesDiscovery()
  52. }
  53. })
  54. }
  55. }
  56. })
  57. },
  58. getBluetoothAdapterState() {
  59. wx.getBluetoothAdapterState({
  60. success: (res) => {
  61. console.log('getBluetoothAdapterState', res)
  62. if (res.discovering) {
  63. this.onBluetoothDeviceFound()
  64. } else if (res.available) {
  65. this.startBluetoothDevicesDiscovery()
  66. }
  67. }
  68. })
  69. },
  70. startBluetoothDevicesDiscovery() {
  71. if (this._discoveryStarted) {
  72. return
  73. }
  74. this._discoveryStarted = true
  75. wx.startBluetoothDevicesDiscovery({
  76. allowDuplicatesKey: true,
  77. success: (res) => {
  78. console.log('startBluetoothDevicesDiscovery success', res)
  79. this.onBluetoothDeviceFound()
  80. },
  81. })
  82. },
  83. stopBluetoothDevicesDiscovery() {
  84. wx.stopBluetoothDevicesDiscovery({
  85. complete: () => {
  86. this._discoveryStarted = false
  87. }
  88. })
  89. },
  90. onBluetoothDeviceFound() {
  91. wx.onBluetoothDeviceFound((res) => {
  92. res.devices.forEach(device => {
  93. if (!device.name && !device.localName) {
  94. return
  95. }
  96. const foundDevices = this.data.devices
  97. const idx = inArray(foundDevices, 'deviceId', device.deviceId)
  98. const data = {}
  99. if (idx === -1) {
  100. data[`devices[${foundDevices.length}]`] = device
  101. } else {
  102. data[`devices[${idx}]`] = device
  103. }
  104. this.setData(data)
  105. })
  106. })
  107. },
  108. createBLEConnection(e) {
  109. const ds = e.currentTarget.dataset
  110. const deviceId = ds.deviceId
  111. const name = ds.name
  112. wx.showLoading()
  113. wx.createBLEConnection({
  114. deviceId,
  115. success: () => {
  116. this.setData({
  117. connected: true,
  118. name,
  119. deviceId,
  120. })
  121. this.getBLEDeviceServices(deviceId)
  122. },
  123. complete() {
  124. wx.hideLoading()
  125. }
  126. })
  127. this.stopBluetoothDevicesDiscovery()
  128. },
  129. closeBLEConnection() {
  130. wx.closeBLEConnection({
  131. deviceId: this.data.deviceId
  132. })
  133. this.setData({
  134. connected: false,
  135. chs: [],
  136. canWrite: false,
  137. })
  138. },
  139. changeMode() {
  140. wx.navigateTo({
  141. url: './slave/slave',
  142. })
  143. },
  144. getBLEDeviceServices(deviceId) {
  145. wx.getBLEDeviceServices({
  146. deviceId,
  147. success: (res) => {
  148. for (let i = 0; i < res.services.length; i++) {
  149. if (res.services[i].isPrimary) {
  150. this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
  151. return
  152. }
  153. }
  154. }
  155. })
  156. },
  157. getBLEDeviceCharacteristics(deviceId, serviceId) {
  158. wx.getBLEDeviceCharacteristics({
  159. deviceId,
  160. serviceId,
  161. success: (res) => {
  162. console.log('getBLEDeviceCharacteristics success', res.characteristics)
  163. for (let i = 0; i < res.characteristics.length; i++) {
  164. const item = res.characteristics[i]
  165. if (item.properties.read) {
  166. wx.readBLECharacteristicValue({
  167. deviceId,
  168. serviceId,
  169. characteristicId: item.uuid,
  170. })
  171. }
  172. if (item.properties.write) {
  173. this.setData({
  174. canWrite: true
  175. })
  176. this._deviceId = deviceId
  177. this._serviceId = serviceId
  178. this._characteristicId = item.uuid
  179. console.log('write')
  180. this.writeBLECharacteristicValue()
  181. }
  182. if (item.properties.notify || item.properties.indicate) {
  183. wx.notifyBLECharacteristicValueChange({
  184. deviceId,
  185. serviceId,
  186. characteristicId: item.uuid,
  187. state: true,
  188. })
  189. }
  190. }
  191. },
  192. fail(res) {
  193. console.error('getBLEDeviceCharacteristics', res)
  194. }
  195. })
  196. // 操作之前先监听,保证第一时间获取数据
  197. wx.onBLECharacteristicValueChange((characteristic) => {
  198. const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
  199. const data = {}
  200. if (idx === -1) {
  201. data[`chs[${this.data.chs.length}]`] = {
  202. uuid: characteristic.characteristicId,
  203. value: ab2hex(characteristic.value)
  204. }
  205. } else {
  206. data[`chs[${idx}]`] = {
  207. uuid: characteristic.characteristicId,
  208. value: ab2hex(characteristic.value)
  209. }
  210. }
  211. wx.showToast({
  212. title: '收到从机数据',
  213. })
  214. // data[`chs[${this.data.chs.length}]`] = {
  215. // uuid: characteristic.characteristicId,
  216. // value: ab2hex(characteristic.value)
  217. // }
  218. this.setData(data)
  219. })
  220. },
  221. writeBLECharacteristicValue() {
  222. // 向蓝牙设备发送一个0x00的16进制数据
  223. const buffer = new ArrayBuffer(1)
  224. const dataView = new DataView(buffer)
  225. // eslint-disable-next-line
  226. dataView.setUint8(0, Math.random() * 19| 0)
  227. wx.writeBLECharacteristicValue({
  228. deviceId: this._deviceId,
  229. serviceId: this._serviceId,
  230. characteristicId: this._characteristicId,
  231. value: buffer,
  232. success() {
  233. console.log('writeBLECharacteristicValue: 成功')
  234. },
  235. fail() {
  236. console.log('writeBLECharacteristicValue: 失败')
  237. },
  238. complete() {
  239. console.log('writeBLECharacteristicValue: 结束')
  240. }
  241. })
  242. },
  243. closeBluetoothAdapter() {
  244. wx.closeBluetoothAdapter()
  245. this._discoveryStarted = false
  246. },
  247. onLoad() {
  248. this.setData({
  249. theme: wx.getSystemInfoSync().theme || 'light'
  250. })
  251. if (wx.onThemeChange) {
  252. wx.onThemeChange(({theme}) => {
  253. this.setData({theme})
  254. })
  255. }
  256. }
  257. })