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.

511 lines
14 KiB

1 year ago
  1. import errToString from "./error";
  2. var util = require('../util');
  3. const app =getApp()
  4. let PRINT_SHOW = true //是否开启蓝牙调试
  5. let SYSTEM_INFO = {}
  6. let MTU_SIZE = 512
  7. function toPlatformString(systemInfo, str) {
  8. if (systemInfo.platform == 'android')
  9. return str.toLowerCase();
  10. else if (systemInfo.platform == 'ios')
  11. return str.toUpperCase();
  12. else
  13. return str;
  14. }
  15. function _openAdapter() {
  16. print(`准备初始化蓝牙适配器...`);
  17. wx.getSystemInfo({
  18. success: function (res) {
  19. print(`model: ${res.model}`);
  20. print(`pixelRatio: ${res.pixelRatio}`);
  21. print(`windowWidth: ${res.windowWidth}`);
  22. print(`windowHeight: ${res.windowHeight}`);
  23. print(`language: ${res.language}`);
  24. print(`version: ${res.version}`);
  25. print(`platform: ${res.platform}`);
  26. print(`environment: ${res.environment}`);
  27. SYSTEM_INFO = res;
  28. }
  29. })
  30. return wx.openBluetoothAdapter().then(
  31. (res) => {
  32. print(`✔ 适配器初始化成功!`);
  33. return [null, res]
  34. },
  35. (err) => {
  36. print(`✘ 初始化失败!${errToString(err)}`);
  37. return [errToString(err), null]
  38. }
  39. );
  40. }
  41. /**
  42. * @param {Array<string>} services
  43. * @param { Int } interval
  44. */
  45. function _startSearch() {
  46. print(`准备搜寻附近的蓝牙外围设备...`);
  47. return promisify(wx.startBluetoothDevicesDiscovery, {
  48. services: [this.serviceId], //如果填写了此UUID,那么只会搜索出含有这个UUID的设备
  49. allowDuplicatesKey: false,
  50. interval: 1000
  51. }).then(
  52. (res) => {
  53. print(`✔ 搜索成功!`);
  54. return [null, res]
  55. },
  56. (err) => {
  57. print(`✘ 搜索蓝牙设备失败!${errToString(err)}`);
  58. return [errToString(err), null]
  59. }
  60. );
  61. }
  62. /**
  63. *@param {Array<string>} devices
  64. *@deviceId 设备ID
  65. */
  66. function _onBluetoothFound() {
  67. print(`监听搜寻新设备事件...`);
  68. return _onBluetoothFound_promise.call(this).then(res => { //_getBluetoothDevices_promise _onBluetoothFound_promise
  69. print(`✔ 设备 ${this.blename} 查找成功!`);
  70. return [null, res]
  71. }, err => {
  72. print(`✘ 设备 ${this.blename} 查找失败!`);
  73. return [errToString(err), null]
  74. })
  75. }
  76. /**
  77. * @param {Array} devices 查找到设备数组
  78. * @param {int} count 计数器-嗅探2次
  79. */
  80. function _onBluetoothFound_promise() {
  81. let devices = []
  82. let count = 0
  83. return new Promise((resolve, reject) => {
  84. wx.onBluetoothDeviceFound(res => {
  85. devices.push(...res.devices)
  86. print(`已嗅探设备数:${devices.length}...`)
  87. print(`已嗅探设备信息:${JSON.stringify(devices)}`)
  88. count++
  89. print(`已嗅探次数:${count}`)
  90. //if (count > 1)
  91. if (devices.length > 0) {
  92. devices.forEach(element => {
  93. if ((element.name && element.name == this.blename) || (element.localName && element.localName == this.blename)) {
  94. this.deviceId = element.deviceId
  95. print(`我的设备Mac:${this.deviceId} `)
  96. print(`我的设备名:${element.name}, ${element.localName}`)
  97. resolve(res)
  98. }
  99. });
  100. } else {
  101. reject('device not found')
  102. }
  103. }, err => {
  104. // reject(err)
  105. })
  106. })
  107. }
  108. /**
  109. *@param {Array<string>} devices
  110. *@deviceId 设备ID
  111. */
  112. function _getBluetoothDevices() {
  113. print(`监听搜寻新设备事件...`);
  114. let devices = []
  115. return wx.getBluetoothDevices({
  116. success: function (res) {
  117. console.log(res)
  118. devices.push(res.devices)
  119. print(`已嗅探设备数:${res.devices.length}...`)
  120. print(`已嗅探设备信息:${JSON.stringify(res.devices)}`)
  121. if (devices.length > 0) {
  122. devices.forEach(element => {
  123. if ((element.name && element.name == this.blename) || (element.localName && element.localName == this.blename)) {
  124. this.deviceId = element.deviceId
  125. print(`我的设备Mac:${this.deviceId} `)
  126. print(`我的设备名:${element.name}, ${element.localName}`)
  127. print(`✔ 设备 ${this.blename} 查找成功!`);
  128. return [null, res]
  129. }
  130. });
  131. } else {
  132. return [`暂时没有嗅探到设备 ${this.blename}, 继续嗅探...`, null]
  133. }
  134. },
  135. fail: function (res) {
  136. print(`✘ 设备 ${this.blename} 查找失败!`);
  137. return [errToString(err), null]
  138. }
  139. })
  140. }
  141. function _getBluetoothDevices_1() {
  142. print(`监听搜寻新设备事件...`);
  143. return _getBluetoothDevices_promise.call(this).then(res => {
  144. print(`✔ 设备 ${this.blename} 查找成功!`);
  145. return [null, res]
  146. }, err => {
  147. print(`✘ 设备 ${this.blename} 查找失败!`);
  148. return [errToString(err), null]
  149. })
  150. }
  151. /**
  152. * @param {Array} devices 查找到设备数组
  153. * @param {int} count 计数器-嗅探2次
  154. */
  155. function _getBluetoothDevices_promise() {
  156. let devices = []
  157. print(`1111`)
  158. return new Promise((resolve, reject) => {
  159. print(`2222`)
  160. wx.getBluetoothDevices(res => {
  161. print(`3333`)
  162. devices.push(...res.devices)
  163. print(`已嗅探设备数:${devices.length}...`)
  164. print(`已嗅探设备信息:${JSON.stringify(devices)}`)
  165. if (devices.length > 0) {
  166. devices.forEach(element => {
  167. if ((element.name && element.name == this.blename) || (element.localName && element.localName == this.blename)) {
  168. this.deviceId = element.deviceId
  169. print(`我的设备Mac:${this.deviceId} `)
  170. print(`我的设备名:${element.name}, ${element.localName}`)
  171. resolve(res)
  172. }
  173. });
  174. }
  175. reject('device not found')
  176. }, err => {
  177. print(`4444`)
  178. reject(err)
  179. })
  180. })
  181. }
  182. function _stopSearchBluetooth() {
  183. print(`停止查找新设备...`);
  184. return wx.stopBluetoothDevicesDiscovery().then(
  185. (res) => {
  186. print(`✔ 停止查找设备成功!`);
  187. return [null, res]
  188. },
  189. (err) => {
  190. print(`✘ 停止查询设备失败!${errToString(err)}`);
  191. return [errToString(err), null]
  192. }
  193. );
  194. }
  195. function _connectBlue() {
  196. print(`准备连接设备...`);
  197. return promisify(wx.createBLEConnection, {
  198. deviceId: this.deviceId,
  199. }).then(
  200. (res) => {
  201. print(`✔ 连接蓝牙成功!`);
  202. return [null, res]
  203. },
  204. (err) => {
  205. print(`✘ 连接蓝牙失败!${errToString(err)}`);
  206. return [errToString(err), null]
  207. }
  208. );
  209. }
  210. function _setBLEMTU() {
  211. if (SYSTEM_INFO.platform != 'android') {
  212. print(`仅安卓手机需要设置MTU Size`);
  213. return ["仅安卓手机需要设置MTU Size", null];
  214. }
  215. print(`准备设置 MTU Size...`);
  216. return promisify(wx.setBLEMTU, {
  217. deviceId: this.deviceId,
  218. mtu: MTU_SIZE
  219. }).then(
  220. (res) => {
  221. //console.log("setBLEMTU success >> " + JSON.stringify(res))
  222. print(`✔ 设置MTU Size = ${MTU_SIZE} 成功!`);
  223. return [null, res]
  224. },
  225. (err) => {
  226. //console.log("setBLEMTU fail >> " + JSON.stringify(res))
  227. print(`✘ 设置MTU Size 失败!`);
  228. return [errToString(err), null]
  229. }
  230. );
  231. }
  232. function _closeBLEConnection() {
  233. print(`断开蓝牙连接...`)
  234. return promisify(wx.closeBLEConnection, {
  235. deviceId: this.deviceId,
  236. }).then(
  237. (res) => {
  238. print(`✔ 断开蓝牙成功!`);
  239. return [null, res]
  240. },
  241. (err) => {
  242. print(`✘ 断开蓝牙连接失败!${errToString(err)}`);
  243. return [errToString(err), null]
  244. }
  245. );
  246. }
  247. function _closeBLEAdapter() {
  248. print(`释放蓝牙适配器...`)
  249. return wx.closeBluetoothAdapter().then(res => {
  250. print(`✔ 释放适配器成功!`)
  251. getApp().globalData.bleStatus = ''
  252. return [null, res]
  253. }, err => {
  254. print(`✘ 释放适配器失败!${errToString(err)}`)
  255. return [errToString(err), null]
  256. })
  257. }
  258. function _getBLEServices() {
  259. print(`获取蓝牙设备所有服务...`)
  260. return promisify(wx.getBLEDeviceServices, {
  261. deviceId: this.deviceId
  262. }).then(res => {
  263. print(`✔ 获取service成功!`)
  264. console.log('services UUID:\n', JSON.stringify(res.services));
  265. for (var i = 0; i < res.services.length; i++) {
  266. console.log("第" + (i + 1) + "个UUID:" + res.services[i].uuid + "\n")
  267. }
  268. return [null, res]
  269. }, err => {
  270. print(`✘ 获取service失败!${errToString(err)}`)
  271. return [errToString(err), null]
  272. })
  273. }
  274. function _getCharacteristics() {
  275. print(`开始获取特征值...`);
  276. return promisify(wx.getBLEDeviceCharacteristics, {
  277. deviceId: this.deviceId,
  278. serviceId: toPlatformString(SYSTEM_INFO, this.serviceId), //具有写、通知属性的服务uuid
  279. }).then(
  280. (res) => {
  281. print(`✔ 获取特征值成功!`);
  282. for (let i = 0; i < res.characteristics.length; i++) {
  283. let item = res.characteristics[i];
  284. if (item.properties.read) {
  285. this.readCharacteristicId = item.uuid;
  286. print(`readCharacteristicId:${item.uuid}`)
  287. }
  288. if (item.properties.write && !item.properties.read) {
  289. this.writeCharacteristicId = item.uuid;
  290. print(`writeCharacteristicId:${item.uuid}`)
  291. }
  292. if (item.properties.notify || item.properties.indicate) {
  293. this.notifyCharacteristicId = item.uuid;
  294. print(`notifyCharacteristicId:${item.uuid}`)
  295. }
  296. }
  297. return [null, res]
  298. },
  299. (err) => {
  300. print(`✘ 获取特征值失败!${errToString(err)}`);
  301. return [errToString(err), null]
  302. }
  303. );
  304. }
  305. // 订阅特征值
  306. function _notifyBLECharacteristicValueChange() {
  307. return promisify(wx.notifyBLECharacteristicValueChange, {
  308. deviceId: this.deviceId,
  309. serviceId: toPlatformString(SYSTEM_INFO, this.serviceId),
  310. characteristicId: toPlatformString(SYSTEM_INFO, this.notifyCharacteristicId),
  311. state: true
  312. }).then(res => {
  313. wx.hideLoading()
  314. wx.showToast({
  315. title: "连接成功",
  316. duration: 2000,
  317. icon: "none"
  318. })
  319. print(`✔ 订阅notify成功!`)
  320. return [null, res]
  321. }, err => {
  322. wx.hideLoading()
  323. wx.showToast({
  324. title: `连接失败!${errToString(err)}`,
  325. duration: 2000,
  326. icon: "none"
  327. })
  328. print(`✘ 订阅notify失败!${errToString(err)}`)
  329. return [errToString(err), null]
  330. })
  331. }
  332. /**
  333. * 指令封装
  334. * @param {Array} data
  335. */
  336. function _sentOrder(cmd, payload, timestamp1) {
  337. print(`开始封装指令...`)
  338. console.log(payload)
  339. let data = payload
  340. let payloadLength = data.length;
  341. let length = 13 + payload.length
  342. let b = new Uint8Array(length);
  343. b[0] = 0x89;
  344. b[1] = 0x89;
  345. b[2] = cmd;
  346. console.log(timestamp1)
  347. // let timestamp = timestamp1 //new Date().getTime();
  348. //let ts = timestamp.toString(16)
  349. // let t = util.IntToBytesLittleEndian(timestamp, 6)
  350. /*
  351. b[4] = (byte)((timestamp >> 40) & 0x00000000000000ff);
  352. b[5] = (byte)((timestamp >> 32) & 0x00000000000000ff);
  353. b[6] = (byte)((timestamp >> 24) & 0x00000000000000ff);
  354. b[7] = (byte)((timestamp >> 16) & 0x00000000000000ff);
  355. b[8] = (byte)((timestamp >> 8) & 0x00000000000000ff);
  356. b[9] = (byte)(timestamp & 0x00000000000000ff);
  357. */
  358. let timestamp = timestamp1 //new Date().getTime();
  359. let t = new Uint8Array(6);
  360. for (let i = 0; i < 6; i++) {
  361. t[5 - i] = timestamp & 255;
  362. timestamp = timestamp >> 8;
  363. }
  364. console.log(t)
  365. b.set(t, 4)
  366. console.log(t)
  367. // b.set(t, 4)
  368. b[3] = b[9];
  369. b[10] = (payloadLength >> 8) & 0xff;
  370. b[11] = payloadLength & 0xff;
  371. let key = b[3];
  372. for (let i = 0; i < payloadLength; i++) {
  373. data[i] -= (payloadLength - i) ^ key;
  374. data[i] = (data[i] ^ (key ^ i));
  375. }
  376. b.set(data, 12)
  377. let xor = b[0];
  378. for (let i = 1; i < length - 1; i++)
  379. xor ^= b[i];
  380. b[length - 1] = xor;
  381. print(`✔ 封装成功! ${b}`)
  382. return b;
  383. }
  384. function _writeBLECharacteristicValue(data) {
  385. return promisify(wx.writeBLECharacteristicValue, {
  386. deviceId: this.deviceId,
  387. serviceId: toPlatformString(SYSTEM_INFO, this.serviceId),
  388. characteristicId: toPlatformString(SYSTEM_INFO, this.writeCharacteristicId),
  389. value: data,
  390. }).then(res => {
  391. print(`✔ 写入数据成功!`)
  392. return [null, res]
  393. }, err => {
  394. print(`✘ 写入数据失败!${errToString(err)}`)
  395. return [errToString(err), null]
  396. })
  397. }
  398. /**
  399. * 对微信接口的promise封装
  400. * @param {function} fn
  401. * @param {object} args
  402. */
  403. function promisify(fn, args) {
  404. return new Promise((resolve, reject) => {
  405. fn({
  406. ...(args || {}),
  407. success: (res) => resolve(res),
  408. fail: (err) => reject(err),
  409. });
  410. });
  411. }
  412. /**
  413. * 对微信接口回调函数的封装
  414. * @param {function} fn
  415. */
  416. function promisify_callback(fn) {
  417. return new Promise((resolve, reject) => {
  418. fn(
  419. (res) => {
  420. resolve(res);
  421. },
  422. (rej) => {
  423. reject(rej);
  424. }
  425. );
  426. });
  427. }
  428. function print(str) {
  429. PRINT_SHOW ? console.log(str) : null;
  430. }
  431. export {
  432. print,
  433. _getCharacteristics,
  434. _connectBlue,
  435. _setBLEMTU,
  436. _getBLEServices,
  437. _closeBLEConnection,
  438. _closeBLEAdapter,
  439. _stopSearchBluetooth,
  440. _notifyBLECharacteristicValueChange,
  441. _onBluetoothFound,
  442. _getBluetoothDevices,
  443. _startSearch,
  444. _openAdapter,
  445. _sentOrder,
  446. _writeBLECharacteristicValue,
  447. promisify,
  448. promisify_callback,
  449. };