index.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. // index.js
  2. // 获取应用实例
  3. const getBle = require("../../utils/ble");
  4. const handle = require('../../utils/handle.js');
  5. const sleep = require("../../utils/sleep");
  6. const TimeClock = require('../../utils/timer');
  7. const app = getApp();
  8. const ble = getBle();
  9. let services = [];
  10. const timeClock = new TimeClock();
  11. const connectStateMap = {
  12. 0: {text:'未连接',color:"red"},
  13. 1: {text:'扫描中',color:"greenYellow"},
  14. 2: {text:'连接中',color:"#d8e84d"},
  15. 3: {text:'已连接',color:"#00ff00"}
  16. }
  17. const bleStateEnum = {
  18. notConnect: 0,
  19. searching: 1,
  20. connecting: 2,
  21. connected: 3,
  22. }
  23. const bleServerMap = {
  24. control: {
  25. uuid:'8000CC00-CC00-FFFF-FFFF-FFFFFFFFFFFF',
  26. text: '摄像控制服务',
  27. listen: {
  28. controlTip: '0000CC01',
  29. controlType: '0000CC02',
  30. },
  31. code:{
  32. }
  33. },
  34. location : {
  35. uuid:'8000DD00-DD00-FFFF-FFFF-FFFFFFFFFFFF',
  36. text: '相机定位服务'
  37. },
  38. remote : {
  39. uuid:'8000FF00-FF00-FFFF-FFFF-FFFFFFFFFFFF',
  40. text: '摄像机远程控制服务',
  41. code:{
  42. hold:{
  43. firstUuid: '0000FF01',
  44. command: {
  45. cmd1:'0107',//Focus Down
  46. shutterDown:'0109',//PRESS_TO_FOCUS
  47. shutterUp:'0108',//HOLD_FOCUS
  48. cmd4:'0106',//Focus Up
  49. }
  50. }
  51. }
  52. },
  53. pariring : {
  54. uuid:'8000EE00-EE00-FFFF-FFFF-FFFFFFFFFFFF',
  55. text: '相机配对服务',
  56. code: {
  57. pariring: {
  58. firstUuid: '0000EE01',
  59. command: {
  60. // 配对
  61. connect: '06 08 01 00 00 00',
  62. // 取消配对
  63. disConnect: '06 08 02 00 00 00',
  64. // 关机
  65. poweroff:'03 08 13'
  66. }
  67. }
  68. }
  69. },
  70. }
  71. let isOnceTimer = null;
  72. let isLongClick = false;// 是否为长按
  73. let isBulbState = false;// 是否处于b门模式下
  74. Page({
  75. data: {
  76. connectStateMap,
  77. bleStateEnum,
  78. isDebug: false,
  79. ble:{
  80. state: 0,
  81. init: false,
  82. },
  83. remoteDev:{
  84. connect: false,
  85. devName: "",
  86. devId: '',
  87. shutter: false,
  88. },
  89. bleDevs:[],// 搜索到的蓝牙设备列表
  90. motto: 'Hello World',
  91. userInfo: {},
  92. hasUserInfo: false,
  93. shutterBtnY1: 0,
  94. isHolder: false,
  95. time_minute: 0,// 分
  96. time_second: 0,// 秒
  97. time_ms: 0,// 毫秒
  98. canIUse: wx.canIUse('button.open-type.getUserInfo'),
  99. canIUseGetUserProfile: false,
  100. canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false
  101. },
  102. async onShow(){
  103. timeClock.setHook((msNum)=>{
  104. // console.log(msNum);
  105. let res = timeClock.parse(msNum)
  106. // console.log(res);
  107. this.setData({
  108. time_minute:res.minute,
  109. time_second:res.second,
  110. time_ms:res.ms,
  111. })
  112. });
  113. // 初始化蓝牙
  114. try {
  115. console.log("init ble");
  116. console.log(handle);
  117. console.log(handle);
  118. console.log(handle);
  119. console.log(handle);
  120. console.log(handle);
  121. let [err,res] = await handle(ble.initBle());
  122. if(err){throw err}
  123. ble.onSearch = this.onSearchHandle;
  124. this.setData({
  125. ble: {...this.data.ble,init: true},
  126. })
  127. } catch (error) {
  128. console.log(error);
  129. wx.showModal({
  130. title: '初始化蓝牙失败',
  131. content: error.errMsg,
  132. success (res) {
  133. if (res.confirm) {
  134. console.log('用户点击确定')
  135. } else if (res.cancel) {
  136. console.log('用户点击取消')
  137. }
  138. }
  139. })
  140. this.setData({
  141. ble: {...this.data.ble,init: false},
  142. })
  143. }
  144. },
  145. async holdFoucus(){
  146. console.log("发送对焦命令");
  147. },
  148. /**
  149. *
  150. * @param {*} isDown 按下或者抬起快门
  151. * @param {*} isBulb 是否为b门模式下释放快门
  152. */
  153. async devControlShutter(isDown = true,isBulb = false){
  154. let cmds,waitTime=10;
  155. let code = bleServerMap.remote.code.hold;
  156. let dev = this.data.bleDevs.find(dev=>this.data.remoteDev.devId===dev.deviceId);
  157. let server = services.find(s=>s.uuid === bleServerMap.remote.uuid);
  158. if(!server){console.log('无法找到远程控制服务')}
  159. let characteristic = server.characteristics.find(c=>c.uuid.startsWith(code.firstUuid));
  160. if(!characteristic){return console.log('无法匹配到特征')}
  161. if(isDown){
  162. console.log('快门抬起')
  163. // 发送抬起快门
  164. cmds =[
  165. code.command.shutterUp,
  166. ]
  167. if(isBulb){
  168. // b 门模式下需要再次按下快门在进行释放
  169. cmds.push(code.command.shutterDown);
  170. cmds.push(code.command.shutterUp);
  171. }
  172. }else{
  173. console.log('快门按下')
  174. cmds = [code.command.shutterDown]
  175. }
  176. for (let index = 0; index < cmds.length; index++) {
  177. const cmd = cmds[index];
  178. let [_err,_res] = await handle(ble.sendData(
  179. dev.deviceId,
  180. server.uuid,
  181. characteristic.uuid,
  182. cmd.replace(/\s/g,'')
  183. ));
  184. if(_err){
  185. // console.log('发送命令失败');
  186. console.error(_err);
  187. }
  188. // console.log('发送命令成功');
  189. await sleep(waitTime);
  190. }
  191. },
  192. async touchStartHandle(e){
  193. // console.log("按钮按下");
  194. // console.log(e);
  195. // todo 获取当前的y信息
  196. let touche = e.touches[0];
  197. let y1 = 0;
  198. if(touche){
  199. y1 = touche.clientY;
  200. }
  201. this.data.shutterBtnY1 = y1;
  202. isLongClick = false;
  203. // 按住700毫秒后视作长按
  204. isOnceTimer = setTimeout(()=>{
  205. isLongClick = true;
  206. isOnceTimer = null;
  207. },
  208. 700);
  209. if(this.data.isHolder){
  210. // 已经按下,视作已经发送按下快门的操作
  211. return false;
  212. }else{
  213. // todo 未按下,发送按下快门的操作
  214. this.devControlShutter(false);
  215. timeClock.start();
  216. }
  217. // 记录当前时间. 等抬起时再次获取
  218. },
  219. async touchEndHandle(e){
  220. console.log("按钮抬起");
  221. clearTimeout(isOnceTimer);
  222. isOnceTimer = null;
  223. if(this.data.isHolder){
  224. // 按住,not do sth
  225. isBulbState = true;
  226. }else{
  227. // 抬起按钮
  228. timeClock.stop();
  229. if(isBulbState){
  230. // 处于b门模式
  231. console.log(`[b门长曝光结束] 曝光时长 ${this.data.time_minute}:${this.data.time_second}:${this.data.time_ms}`);
  232. this.devControlShutter(true,true);
  233. isBulbState = false;
  234. return false;
  235. }
  236. if(isLongClick){
  237. // 长按
  238. this.devControlShutter(true);
  239. }else{
  240. // 短按,等待500ms 后发送抬起的命令
  241. setTimeout(()=>{
  242. console.log("短按,自动跟发一条抬起快门命令");
  243. this.devControlShutter(true);
  244. },500)
  245. }
  246. }
  247. },
  248. async touchMoveHandle(e){
  249. // console.log("按钮移动");
  250. let touche = e.touches[0];
  251. let y1 = this.data.shutterBtnY1;
  252. let y2 = 0;
  253. if(touche){
  254. y2 = touche.clientY;
  255. }
  256. let endY = y2 - y1;
  257. if(Math.abs(endY)<15){
  258. // console.log("移动范围太小")
  259. return false;
  260. }
  261. this.data.shutterBtnY1 = y2;
  262. if(endY < 0){
  263. console.log('+');
  264. this.setData({
  265. isHolder:true
  266. })
  267. }else{
  268. console.log('-');
  269. this.setData({
  270. isHolder:false
  271. })
  272. }
  273. },
  274. async connectDev(e){
  275. let devId = e.currentTarget.dataset.dev;
  276. let dev = this.data.bleDevs.find(dev=>devId===dev.deviceId);
  277. let err,res;
  278. if(!dev){
  279. return wx.showToast({
  280. title: '数据库异常,无法找寻设备',
  281. })
  282. }
  283. console.log(dev);
  284. // 连接设备
  285. this.setData({
  286. ble: {...this.data.ble,state: bleStateEnum.connecting},
  287. });
  288. [err,res] = await handle(ble.stopSearch());
  289. if(err){return wx.showToast({ title: '关闭微信失败', })}
  290. wx.showToast({
  291. title: `尝试${dev.name}中...`,
  292. })
  293. [err,res] = await handle(ble.connectDev(devId));
  294. if(err){
  295. return wx.showToast({
  296. title: '连接失败'+err.errMsg,
  297. })
  298. }
  299. console.log('设备连接成功');
  300. this.setData({
  301. remoteDev: {
  302. ...this.data.remoteDev,
  303. devId: devId,
  304. devName: dev.name
  305. }
  306. });
  307. console.log(res);
  308. // 然后呢?
  309. this.setData({
  310. ble:{...this.data.ble,state:bleStateEnum.connected}
  311. });
  312. // 获取服务与特征
  313. [err,res] = await handle(ble.getBleServices(devId));
  314. if(err){
  315. wx.showToast({
  316. title: '搜索蓝牙服务失败',
  317. });
  318. return console.log(err);
  319. }
  320. res.forEach(async val=>{
  321. console.log('******');
  322. console.log(val.uuid);
  323. let _err,_res;
  324. if(val.uuid === bleServerMap.pariring.uuid ){
  325. // 尝试直接向设备发起连接
  326. console.log('设备配对服务');
  327. // 获取特征值id
  328. let code_pariring = bleServerMap.pariring.code.pariring
  329. let characteristic = val.characteristics.find(c=>c.uuid.startsWith(code_pariring.firstUuid));
  330. if(!characteristic){return console.log('无法配对')}
  331. [_err,_res] = await handle(ble.sendData(
  332. devId,
  333. val.uuid,
  334. characteristic.uuid,
  335. code_pariring.command.connect.replace(/\s/g,'')
  336. ));
  337. if(_err){
  338. wx.showToast({
  339. title: 'Err:发送蓝牙数据失败??',
  340. })
  341. // 尝试关闭设备
  342. setTimeout(async ()=>{
  343. console.log('发送关机命令');
  344. [_err,_res] = await handle(ble.sendData(
  345. devId,
  346. val.uuid,
  347. characteristic.uuid,
  348. code_pariring.command.disConnect.replace(/\s/g,'')
  349. ));
  350. if(_err){
  351. console.error(_err)
  352. wx.showToast({
  353. title: 'Err:发送设备关机命令失败??',
  354. })
  355. } else{
  356. wx.showToast({
  357. title: '发送关机命令成功??',
  358. });
  359. }
  360. },10000);
  361. console.log(_err);
  362. }
  363. console.log(res);
  364. wx.showToast({
  365. title: '发送配对指令成功',
  366. })
  367. }else if(val.uuid === bleServerMap.control.uuid){
  368. let listenCode = bleServerMap.control.listen;
  369. // [_err,_res] = await handle(ble.listenData(devId,val.uuid,listenCode.controlTip));
  370. // console.log(_res);
  371. // [_err,_res] = await handle(ble.listenData(devId,val.uuid,listenCode.controlTip));
  372. // console.log(_res);
  373. // if(_err){
  374. // console.log('控制端口监听失败');
  375. // console.error(_err);
  376. // console.log('控制端口监听失败');
  377. // }
  378. // console.log('控制端口监听完成')
  379. }else if(val.uuid === bleServerMap.pariring.uuid ){
  380. // 尝试直接向设备发起连接
  381. console.log('设备配对服务');
  382. // 获取特征值id
  383. let code = bleServerMap.remote.code.hold
  384. let characteristic = val.characteristics.find(c=>c.uuid.startsWith(code.firstUuid));
  385. if(!characteristic){return console.log('无法配对')}
  386. if(_err){
  387. wx.showToast({
  388. title: 'Err:发送快门控制命令失败',
  389. })
  390. // 尝试关闭设备
  391. console.log(_err);
  392. }
  393. console.log(res);
  394. wx.showToast({
  395. title: '发送按住快门指令成功',
  396. })
  397. }
  398. console.log('******');
  399. console.log(val.uuid);
  400. val.characteristics.forEach(c=>{
  401. console.log(c);
  402. });
  403. // 查看是否会有对应特征值
  404. console.log('******');
  405. })
  406. wx.showToast({
  407. title: '蓝牙服务搜索成功',
  408. });
  409. services = res;
  410. },
  411. // 事件处理函数
  412. bindViewTap() {
  413. wx.navigateTo({
  414. url: '../logs/logs'
  415. })
  416. },
  417. async searchDevice(){
  418. console.log("搜索 蓝牙设备");
  419. if(!this.data.ble.init){
  420. return wx.showModal({
  421. title: '蓝牙错误',
  422. content: "无法启用蓝牙!!!",
  423. success (res) { }
  424. })
  425. }
  426. this.setData({
  427. ble: {...this.data.ble,state: bleStateEnum.searching},
  428. });
  429. ble.search(this.onSearchHandle);
  430. },
  431. onSearchHandle(device){
  432. console.log('搜索到设备');
  433. if(this.data.bleDevs.find(dev=>dev.deviceId === device.deviceId )){
  434. return console.log('设备再次被搜索到');
  435. }
  436. console.log(device);
  437. let arr = this.data.bleDevs;
  438. arr.push(device);
  439. this.setData({
  440. bleDevs: arr
  441. })
  442. },
  443. tapState(){
  444. switch(this.data.ble.state){
  445. case bleStateEnum.notConnect:
  446. this.searchDevice();
  447. break;
  448. case bleStateEnum.searching:
  449. break;
  450. case bleStateEnum.connecting:
  451. break;
  452. case bleStateEnum.connected:
  453. break;
  454. }
  455. },
  456. onLoad() {
  457. if (wx.getUserProfile) {
  458. this.setData({
  459. canIUseGetUserProfile: true
  460. })
  461. }
  462. },
  463. })