ElinkThings小程序蓝牙插件SDK集合:aifresh、ailink http://doc.elinkthings.com/web/#/36?page_id=127
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  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. for (let i = 0; i < res.services.length; i++) {
  176. if (res.services[i].isPrimary) {
  177. this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
  178. return
  179. }
  180. }
  181. }
  182. })
  183. },
  184. // 获取蓝牙设备某个服务中所有特征值(characteristic)
  185. getBLEDeviceCharacteristics(deviceId, serviceId) {
  186. this._deviceId = deviceId
  187. this._serviceId = serviceId
  188. this._device.serviceId = serviceId
  189. wx.getBLEDeviceCharacteristics({
  190. deviceId,
  191. serviceId,
  192. success: (res) => {
  193. console.log('getBLEDeviceCharacteristics success', res.characteristics)
  194. // 这部分功能在插件的 initPlugin 中已实现,如需用到其中的 uuid 也可取消注释
  195. // // let uuid1, uuid2, uuid3;
  196. // for (let i = 0; i < res.characteristics.length; i++) {
  197. // let item = res.characteristics[i]
  198. // if (item.uuid.indexOf('0000FFE1') != -1) {
  199. // this.uuid1 = item.uuid //下发数据
  200. // } else if (item.uuid.indexOf('0000FFE2') != -1) {
  201. // this.uuid2 = item.uuid //监听数据
  202. // } else if (item.uuid.indexOf('0000FFE3') != -1) {
  203. // this.uuid3 = item.uuid //写入设置
  204. // }
  205. // }
  206. // // 打开监听
  207. // wx.notifyBLECharacteristicValueChange({
  208. // deviceId,
  209. // serviceId,
  210. // characteristicId: this.uuid2,
  211. // state: true,
  212. // })
  213. // wx.notifyBLECharacteristicValueChange({
  214. // deviceId,
  215. // serviceId,
  216. // characteristicId: this.uuid3,
  217. // state: true,
  218. // })
  219. // 初始化插件
  220. plugin.initPlugin(res.characteristics, this._device)
  221. wx.onBLECharacteristicValueChange((characteristic) => {
  222. // 解析特征值,返回解密后的数据
  223. let bleData = plugin.parseBleData(characteristic.value)
  224. if (bleData.status == 0) {
  225. console.log("握手成功")
  226. } else if (bleData.status == 1) {
  227. console.log(bleData)
  228. let payload = bleData.data //对应协议中的payload数据,可以自行解析该数据
  229. console.log(ab2hex(payload, ' '))
  230. console.log(ab2hex(bleData.completeData, ' '))
  231. // 以体脂秤数据解析为例
  232. let weight, adc;
  233. switch (payload[0]) {
  234. /*
  235. * 例如: A7 00 0E 05 01 00 01 F4 10 19 7A---------50.0kg
  236. * 其中 01 00 01 F4 10 为 payload
  237. * 具体指令请根据协议解析
  238. */
  239. case 0x01:
  240. case 0x02:
  241. let weightValue = (payload[1] << 16) | (payload[2] << 8) | payload[3]
  242. let decPoint = (payload[4] & 0xf0) >> 4
  243. let unit = payload[4] & 0x0f
  244. // console.log("体重数值:" + weightValue)
  245. // console.log("小数点:" + decPoint)
  246. // console.log("单位:" + unit)
  247. if (unit == 1) { // 单位为斤
  248. weight = weightValue / 2
  249. } else {
  250. // ... 其他单位
  251. }
  252. weight = weightValue / (decPoint * 10) // 除去小数点位数
  253. break;
  254. // ...
  255. /*
  256. * 例如: A7 00 0E 03 07 02 30 4A 7A---------阻抗测量成功,阻抗 560Ω
  257. * 其中 07 02 30 为 payload
  258. * 具体指令请根据协议解析
  259. */
  260. case 0x07:
  261. adc = (payload[1] << 8) | payload[2]
  262. break;
  263. case 0x0A:
  264. //测量完成
  265. let bodyData = plugin.getBodyData(1, 20, 170, weight, adc) // 体脂秤数据解析
  266. console.log("解析后的体脂数据: ", bodyData)
  267. console.log(util.getWeightDisplay(170, weight))
  268. break;
  269. }
  270. const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
  271. const data = {}
  272. if (idx === -1) {
  273. data[`chs[${this.data.chs.length}]`] = {
  274. uuid: characteristic.characteristicId,
  275. value: ab2hex(payload, ' ')
  276. }
  277. } else {
  278. data[`chs[${idx}]`] = {
  279. uuid: characteristic.characteristicId,
  280. value: ab2hex(payload, ' ')
  281. }
  282. }
  283. this.setData(data)
  284. } else {
  285. console.log(bleData)
  286. }
  287. })
  288. },
  289. fail(res) {
  290. console.error('getBLEDeviceCharacteristics', res)
  291. }
  292. })
  293. },
  294. writeBLECharacteristicValue(buffer, uuid, deviceId, serviceId) {
  295. // 向蓝牙设备发送一个二进制流数据
  296. wx.writeBLECharacteristicValue({
  297. deviceId,
  298. serviceId,
  299. characteristicId: uuid,
  300. value: buffer,
  301. success(res) {
  302. console.log('writeBLECharacteristicValue success', res)
  303. console.log(ab2hex(buffer))
  304. }
  305. })
  306. },
  307. closeBluetoothAdapter() {
  308. wx.closeBluetoothAdapter()
  309. this._discoveryStarted = false
  310. },
  311. // 打开指令输入框
  312. showWriteInputView() {
  313. this.setData({
  314. showWriteInput: true
  315. })
  316. },
  317. // 关闭指令输入框
  318. hideWriteInputView() {
  319. this.setData({
  320. showWriteInput: false
  321. })
  322. },
  323. // 指令输入
  324. writingCmd(e) {
  325. this._cmd = e.detail.value
  326. },
  327. // 指令下发
  328. submitCmd() {
  329. if (!this._cmd) {
  330. return
  331. }
  332. let arr = []
  333. if (this._cmd.indexOf(",") == -1) {
  334. arr = this._cmd.split(" ")
  335. } else {
  336. arr = this._cmd.split(",")
  337. }
  338. for (let i in arr) {
  339. arr[i] = parseInt(arr[i], 16)
  340. }
  341. // let arr = [
  342. // 0xA6,
  343. // 0x01,
  344. // 0x28,
  345. // 0x29,
  346. // 0x6A,
  347. // //A6 01 28 29 6A
  348. // ]
  349. if (arr[0] == 0xA6) {
  350. let payload = arr.slice(2, -2)
  351. plugin.sendDataOfA6(payload)
  352. } else if (arr[0] == 0xA7) {
  353. let cid = [arr[1], arr[2]] // 001E
  354. let payload = arr.slice(4, -2)
  355. plugin.sendDataOfA7(payload)
  356. // this.writeBLECharacteristicValue(buff, this.uuid1, this._deviceId, this._serviceId)
  357. }
  358. return
  359. },
  360. });