ElinkThings小程序蓝牙插件SDK集合:aifresh、ailink http://doc.elinkthings.com/web/#/36?page_id=127
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. const util = require("../../utils/util");
  2. const plugin = requirePlugin("sdkPlugin").AiLink;
  3. function inArray(arr, key, val) {
  4. for (let i = 0; i < arr.length; i++) {
  5. if (arr[i][key] === val) {
  6. return i;
  7. }
  8. }
  9. return -1;
  10. }
  11. // ArrayBuffer转16进度字符串示例
  12. function ab2hex(buffer, split = ',') {
  13. var hexArr = Array.prototype.map.call(
  14. new Uint8Array(buffer),
  15. function (bit) {
  16. return ('00' + bit.toString(16)).slice(-2)
  17. }
  18. )
  19. return hexArr.join(split);
  20. }
  21. Page({
  22. data: {
  23. showWriteInput: false,
  24. devices: [
  25. // {
  26. // deviceId: "02:03:04:05:06:07",
  27. // name: "elink",
  28. // localName: "elink",
  29. // mac: "02:03:04:05:06:07",
  30. // RSSI: -69,
  31. // advertisServiceUUIDs:[
  32. // "FFE0","FFC0"
  33. // ],
  34. // analyzeDataText:"0102003241123413"
  35. // }
  36. ],
  37. connected: false,
  38. chs: [],
  39. },
  40. onLoad: function () {
  41. },
  42. // 初始化蓝牙模块
  43. openBluetoothAdapter() {
  44. wx.openBluetoothAdapter({
  45. success: (res) => {
  46. console.log('openBluetoothAdapter success', res)
  47. this.startBluetoothDevicesDiscovery()
  48. },
  49. fail: (res) => {
  50. if (res.errCode === 10001) {
  51. wx.showToast({
  52. title: '请打开蓝牙',
  53. icon: "none"
  54. })
  55. wx.onBluetoothAdapterStateChange(function (res) {
  56. console.log('onBluetoothAdapterStateChange', res)
  57. if (res.available) {
  58. this.startBluetoothDevicesDiscovery()
  59. }
  60. })
  61. }
  62. }
  63. })
  64. },
  65. // 获取本机蓝牙适配器状态
  66. getBluetoothAdapterState() {
  67. wx.getBluetoothAdapterState({
  68. success: (res) => {
  69. console.log('getBluetoothAdapterState', res)
  70. if (res.discovering) {
  71. this.onBluetoothDeviceFound()
  72. } else if (res.available) {
  73. this.startBluetoothDevicesDiscovery()
  74. }
  75. }
  76. })
  77. },
  78. // 开始搜寻附近的蓝牙外围设备
  79. startBluetoothDevicesDiscovery() {
  80. if (this._discoveryStarted) {
  81. return
  82. }
  83. this._discoveryStarted = true
  84. wx.startBluetoothDevicesDiscovery({
  85. allowDuplicatesKey: true,
  86. services: [
  87. "FFE0",
  88. "F0A0",
  89. ],
  90. success: (res) => {
  91. console.log('startBluetoothDevicesDiscovery success', res)
  92. this.onBluetoothDeviceFound()
  93. },
  94. })
  95. },
  96. // 停止搜寻附近的蓝牙外围设备
  97. stopBluetoothDevicesDiscovery() {
  98. wx.stopBluetoothDevicesDiscovery()
  99. },
  100. // 监听寻找到新设备的事件
  101. onBluetoothDeviceFound() {
  102. wx.onBluetoothDeviceFound((res) => {
  103. res.devices.forEach(device => {
  104. if (!device.name && !device.localName) {
  105. return
  106. }
  107. const foundDevices = this.data.devices
  108. const idx = inArray(foundDevices, 'deviceId', device.deviceId)
  109. const data = {}
  110. // console.log(device)
  111. // console.log(ab2hex(device.advertisData))
  112. // 此处判断是否BM30广播模块,如使用连接模块请删除此 if ,只保留 else 内容
  113. if (device.advertisServiceUUIDs[0].indexOf("F0A0") !== -1) {
  114. let parseDataRes = plugin.parseBroadcastData(device.advertisData)
  115. console.log(parseDataRes)
  116. if (parseDataRes.status == 1) {
  117. let analyzeData = plugin.analyzeBroadcastScaleData(parseDataRes)
  118. console.log(analyzeData)
  119. device.analyzeDataText = analyzeData.text
  120. }
  121. } else {
  122. let buff = device.advertisData.slice(-6)
  123. device.mac = new Uint8Array(buff) // 保存广播数据中的mac地址,这是由于iOS不直接返回mac地址
  124. }
  125. if (idx === -1) {
  126. data[`devices[${foundDevices.length}]`] = device
  127. } else {
  128. data[`devices[${idx}]`] = device
  129. }
  130. this.setData(data)
  131. })
  132. })
  133. },
  134. // 连接低功耗蓝牙设备
  135. createBLEConnection(e) {
  136. const ds = e.currentTarget.dataset
  137. const index = ds.index
  138. // 保存当前连接的设备,注意不能从wxml的dataset中直接返回该对象,因为ArrarBuffer类型的数据无法保留
  139. this._device = this.data.devices[index]
  140. console.log(this._device)
  141. const deviceId = ds.deviceId
  142. const name = ds.name
  143. this.mac = ds.mac
  144. wx.createBLEConnection({
  145. deviceId,
  146. success: (res) => {
  147. this.setData({
  148. connected: true,
  149. name,
  150. deviceId,
  151. })
  152. console.log("createBLEConnection:success")
  153. wx.stopBluetoothDevicesDiscovery()
  154. this.getBLEDeviceServices(deviceId)
  155. }
  156. })
  157. // 连接上设备就可以停止蓝牙搜索,减少功耗。
  158. this.stopBluetoothDevicesDiscovery()
  159. },
  160. // 断开与低功耗蓝牙设备的连接
  161. closeBLEConnection() {
  162. wx.closeBLEConnection({
  163. deviceId: this._deviceId
  164. })
  165. this.setData({
  166. connected: false,
  167. chs: [],
  168. })
  169. },
  170. // 获取蓝牙设备的 serviceId
  171. getBLEDeviceServices(deviceId) {
  172. wx.getBLEDeviceServices({
  173. deviceId,
  174. success: (res) => {
  175. console.log(res)
  176. for (let i = 0; i < res.services.length; i++) {
  177. if (res.services[i].isPrimary && res.services[i].uuid.indexOf("FFE0")>-1) {
  178. this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
  179. return
  180. }
  181. }
  182. }
  183. })
  184. },
  185. // 获取蓝牙设备某个服务中所有特征值(characteristic)
  186. getBLEDeviceCharacteristics(deviceId, serviceId) {
  187. this._deviceId = deviceId
  188. this._serviceId = serviceId
  189. this._device.serviceId = serviceId
  190. wx.getBLEDeviceCharacteristics({
  191. deviceId,
  192. serviceId,
  193. success: (res) => {
  194. console.log('getBLEDeviceCharacteristics success', res.characteristics)
  195. // 这部分功能在插件的 initPlugin 中已实现,如需用到其中的 uuid 也可取消注释
  196. // // let uuid1, uuid2, uuid3;
  197. // for (let i = 0; i < res.characteristics.length; i++) {
  198. // let item = res.characteristics[i]
  199. // if (item.uuid.indexOf('0000FFE1') != -1) {
  200. // this.uuid1 = item.uuid //下发数据
  201. // } else if (item.uuid.indexOf('0000FFE2') != -1) {
  202. // this.uuid2 = item.uuid //监听数据
  203. // } else if (item.uuid.indexOf('0000FFE3') != -1) {
  204. // this.uuid3 = item.uuid //写入设置
  205. // }
  206. // }
  207. // // 打开监听
  208. // wx.notifyBLECharacteristicValueChange({
  209. // deviceId,
  210. // serviceId,
  211. // characteristicId: this.uuid2,
  212. // state: true,
  213. // })
  214. // wx.notifyBLECharacteristicValueChange({
  215. // deviceId,
  216. // serviceId,
  217. // characteristicId: this.uuid3,
  218. // state: true,
  219. // })
  220. // 初始化插件
  221. plugin.initPlugin(res.characteristics, this._device)
  222. wx.onBLECharacteristicValueChange((characteristic) => {
  223. // 解析特征值,返回解密后的数据
  224. console.log("===" + plugin.ab2hex(characteristic.value))
  225. let bleData = plugin.parseBleData(characteristic.value)
  226. if (bleData.status == 0) {
  227. console.log("握手成功")
  228. } else if (bleData.status == 1) {
  229. console.log(bleData)
  230. let payload = bleData.data //对应协议中的payload数据,可以自行解析该数据
  231. console.log(ab2hex(payload, ' '))
  232. console.log(ab2hex(bleData.completeData, ' '))
  233. // 以体脂秤数据解析为例
  234. let weight, adc;
  235. switch (payload[0]) {
  236. /*
  237. * 例如: A7 00 0E 05 01 00 01 F4 10 19 7A---------50.0kg
  238. * 其中 01 00 01 F4 10 为 payload
  239. * 具体指令请根据协议解析
  240. */
  241. case 0x01:
  242. case 0x02:
  243. let weightValue = (payload[1] << 16) | (payload[2] << 8) | payload[3]
  244. let decPoint = (payload[4] & 0xf0) >> 4
  245. let unit = payload[4] & 0x0f
  246. // console.log("体重数值:" + weightValue)
  247. // console.log("小数点:" + decPoint)
  248. // console.log("单位:" + unit)
  249. if (unit == 1) { // 单位为斤
  250. weight = weightValue / 2
  251. } else {
  252. // ... 其他单位
  253. }
  254. weight = weightValue / (decPoint * 10) // 除去小数点位数
  255. break;
  256. // ...
  257. /*
  258. * 例如: A7 00 0E 03 07 02 30 4A 7A---------阻抗测量成功,阻抗 560Ω
  259. * 其中 07 02 30 为 payload
  260. * 具体指令请根据协议解析
  261. */
  262. case 0x07:
  263. adc = (payload[1] << 8) | payload[2]
  264. break;
  265. case 0x0A:
  266. //测量完成
  267. let bodyData = plugin.getBodyData(1, 20, 170, weight, adc) // 体脂秤数据解析
  268. console.log("解析后的体脂数据: ", bodyData)
  269. console.log(util.getWeightDisplay(170, weight))
  270. break;
  271. }
  272. const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
  273. const data = {}
  274. if (idx === -1) {
  275. data[`chs[${this.data.chs.length}]`] = {
  276. uuid: characteristic.characteristicId,
  277. value: ab2hex(payload, ' ')
  278. }
  279. } else {
  280. data[`chs[${idx}]`] = {
  281. uuid: characteristic.characteristicId,
  282. value: ab2hex(payload, ' ')
  283. }
  284. }
  285. this.setData(data)
  286. } else {
  287. console.log(bleData)
  288. }
  289. })
  290. },
  291. fail(res) {
  292. console.error('getBLEDeviceCharacteristics', res)
  293. }
  294. })
  295. },
  296. writeBLECharacteristicValue(buffer, uuid, deviceId, serviceId) {
  297. // 向蓝牙设备发送一个二进制流数据
  298. wx.writeBLECharacteristicValue({
  299. deviceId,
  300. serviceId,
  301. characteristicId: uuid,
  302. value: buffer,
  303. success(res) {
  304. console.log('writeBLECharacteristicValue success', res)
  305. console.log(ab2hex(buffer))
  306. }
  307. })
  308. },
  309. closeBluetoothAdapter() {
  310. wx.closeBluetoothAdapter()
  311. this._discoveryStarted = false
  312. },
  313. // 打开指令输入框
  314. showWriteInputView() {
  315. this.setData({
  316. showWriteInput: true
  317. })
  318. },
  319. // 关闭指令输入框
  320. hideWriteInputView() {
  321. this.setData({
  322. showWriteInput: false
  323. })
  324. },
  325. // 指令输入
  326. writingCmd(e) {
  327. this._cmd = e.detail.value
  328. },
  329. // 指令下发
  330. submitCmd() {
  331. if (!this._cmd) {
  332. return
  333. }
  334. let arr = []
  335. if (this._cmd.indexOf(",") == -1) {
  336. arr = this._cmd.split(" ")
  337. } else {
  338. arr = this._cmd.split(",")
  339. }
  340. for (let i in arr) {
  341. arr[i] = parseInt(arr[i], 16)
  342. }
  343. // let arr = [
  344. // 0xA6,
  345. // 0x01,
  346. // 0x28,
  347. // 0x29,
  348. // 0x6A,
  349. // //A6 01 28 29 6A
  350. // ]
  351. if (arr[0] == 0xA6) {
  352. let payload = arr.slice(2, -2)
  353. plugin.sendDataOfA6(payload)
  354. } else if (arr[0] == 0xA7) {
  355. let cid = [arr[1], arr[2]] // 001E
  356. let payload = arr.slice(4, -2)
  357. plugin.sendDataOfA7(payload)
  358. // this.writeBLECharacteristicValue(buff, this.uuid1, this._deviceId, this._serviceId)
  359. }
  360. return
  361. },
  362. });