import Common from '@/utils/Common.js' class BleReceive { constructor() { this.StorageKey = "linkedDevices"; this.HandlerMap = { '/pages/6155/deviceDetail': this.Receive_6155.bind(this), '/pages/6155/BJQ6155': this.Receive_6155_XH.bind(this), '/pages/7305/BJQ7305': this.Receive_6155.bind(this), '/pages/650/HBY650': this.Receive_650.bind(this), '/pages/670/HBY670': this.Receive_670.bind(this), '/pages/4877/BJQ4877': this.Receive_4877.bind(this), '/pages/100/HBY100': this.Receive_100.bind(this), '/pages/102/HBY102': this.Receive_102.bind(this) }; } setBleFormData(data, f) { if (data) { let linkedList = uni.getStorageSync(this.StorageKey); if (!linkedList) { return; } linkedList.find((v) => { if (f.deviceId == v.deviceId) { let keys = Object.keys(data); keys.forEach((key) => { if (!v.formData) { v.formData = {}; } if (!f.formData) { f.formData = {}; } v.formData[key] = data[key]; f.formData[key] = data[key]; }); uni.setStorageSync(this.StorageKey, linkedList); return true; } }); } } ReceiveData(receive, f, path, recArr) { if (f && f.macAddress && f.device && f.device.id) { let handler = null; let keys = Object.keys(this.HandlerMap); let devKey = f.device.detailPageUrl ? f.device.detailPageUrl.replace(/\//g, '').toLowerCase() : ''; for (let index = 0; index < keys.length; index++) { let devKey = f.device.detailPageUrl ? f.device.detailPageUrl.replace(/\//g, "").toLowerCase() : ''; let key = keys[index].replace(/\//g, '').toLowerCase(); if (key == devKey) { handler = this.HandlerMap[keys[index]]; break; } } if (handler) { let data = handler(receive, f, path, recArr); this.setBleFormData(data, f); return data; } else { console.error("已收到消息,但无指定处理程序, deviceUrl:", f.device.detailPageUrl, "可用handlers:", keys); } } else { console.log("已收到该消息,但无法处理", receive, "f:", f); } return receive; } Receive_650(receive, f, path, recArr) { console.log("通用程序正在处理650的数据", receive); var parseData = () => { let bytes = receive.bytes; if (bytes[0] == 0x55) { try { let staticLevelByte = bytes[1]; let staticLevelText = '未知'; let modeCurr = ""; switch (staticLevelByte) { case 0x65: staticLevelText = '高档'; modeCurr = "hight"; break; case 0x66: staticLevelText = '中档'; modeCurr = "center"; break; case 0x67: staticLevelText = '低档'; modeCurr = "low"; break; case 0x68: staticLevelText = '前置'; modeCurr = "smalllow"; break; case 0x64: staticLevelText = '关闭'; modeCurr = "close"; break; } // 解析照明档位 let lightingLevelByte = bytes[2]; let lightingLevelText = lightingLevelByte === 0x6e ? '开启' : '关闭'; // 解析剩余照明时间(第三和第四字节,大端序) let lightingTime = (bytes[3] << 8) | bytes[4]; let hours = Math.floor(lightingTime / 60); let remainingMinutes = lightingTime % 60; let xuhang = '0分'; // 处理不同情况的显示 if (hours === 0) { xuhang = `${remainingMinutes}分`; } else if (remainingMinutes === 0) { xuhang = `${hours}小时`; } else { xuhang = `${hours}小时${remainingMinutes}分`; } // 解析剩余电量 let batteryLevelByte = bytes[5]; // 电量百分比范围检查 let batteryLevel = Math.max(0, Math.min(100, batteryLevelByte)); let iswarn = false; let warn = bytes[6]; if (warn == 0x00) { warn = '无预警'; } else if (warn == 0x01) { warn = '弱预警'; } else if (warn == 0x02) { iswarn = true; warn = '中预警'; } else if (warn == 0x03) { iswarn = true; warn = '强预警'; } else if (warn == 0x04) { iswarn = true; warn = '非常强预警'; } let formData = {}; formData.battary = batteryLevel; formData.xuhang = xuhang; formData.cMode = lightingLevelByte === 0x6e; formData.modeCurr = modeCurr; formData.warnLevel = warn; formData.iswarn = iswarn; let recCnt = recArr.find(v => { return v.key.replace(/\//g, "").toLowerCase() == f.device.detailPageUrl .replace(/\//g, "").toLowerCase(); }); if (!recCnt) { if (iswarn) { uni.showModal({ content: "'" + f.device.deviceName + "'环境存在漏电电源", title: "警告", success(res) { if (res.confirm) { if (f) { uni.navigateTo({ url: f.detailPageUrl, events: { ack: function(data) {} }, success: (res) => { res.eventChannel.emit('detailData', { data: f, deviceType: '', apiType: 'listA' }); } }); } } } }) } } return formData; } catch (error) { return null; } } if (receive.str) { try { let str = receive.str; if (str.indexOf('mac address:') == 0) { let formData = {}; formData.macAddress = str.split(':')[1]; return formData; } else { let receiveData = { a: 1 }; try { let json = JSON.parse(str); if ("staBlue_picture" in json) { //重发图片 console.log("收到重新发送图片的命令"); receiveData = json; } else if ("staBlue_text" in json) { //重发文本 console.log("收到重新发送文本的命令"); receiveData = json; } else if ("staBlue_vidio" in json) { //重发视频 console.log("收到重新发送视频的命令"); receiveData = json; } else if ("staBlue" in json) { if (json.staBlue == "finish") { console.log("收到设备回复,全部传输完成"); receiveData = json; } } else { receiveData = {}; console.log("无法解析该文本"); } } catch (error) { receiveData = {}; console.log("文本解析失败") } return receiveData; } return null; } catch (ex) { return null; } } } let data = parseData(receive.bytes); console.log("data=", data); return data; } Receive_670(receive, f, path, recArr) { // console.log("pagh=", path); var todo = (bytes) => { console.log("todo", receive); let receiveData = {}; if (bytes[0] == 0x55) { try { // console.log("todo"); // 跳过帧头(第一个字节),从第二个字节开始解析 let staticLevelByte = bytes[1]; let staticLevelText = ''; switch (staticLevelByte) { case 0x65: staticLevelText = 'hight'; break case 0x66: staticLevelText = 'center'; break case 0x67: staticLevelText = 'low'; break case 0x64: staticLevelText = 'close'; break } // console.log("todo"); // 解析照明档位 let lightingLevelByte = bytes[2]; let lightingLevelText = lightingLevelByte === 0x6d ? 'qiang' : lightingLevelByte === 0x6e ? 'ruo' : 'close'; // 解析剩余照明时间(第三和第四字节,小端序) let lightingTime = (bytes[3] << 8) | bytes[4]; // 解析剩余电量 // 电量百分比范围检查 let batteryLevelByte = bytes[5]; let batteryLevel = Math.max(0, Math.min(100, batteryLevelByte)); // console.log("todo"); let warn = bytes[6]; if (warn == 0x00) { warn = 'none'; } else if (warn == 0x01) { warn = 'ruo'; } else if (warn == 0x02) { warn = 'center'; } else if (warn == 0x03) { warn = 'hight'; } else if (warn == 0x04) { warn = 'veryhight'; } let staticWarn = bytes[7] == 0x01; //静止报警 let fourGStrenth = bytes[8]; //4g信号强度 let sosTxt = bytes[9] == 0x00 ? 'close' : bytes[9] == 0x01 ? 'sg' : 'rb'; // console.log("todo"); receiveData.modeCurr = staticLevelText; receiveData.lightCurr = lightingLevelText; receiveData.xuhang = lightingTime; receiveData.battary = batteryLevel; receiveData.warnLevel = warn; receiveData.staticWarn = staticWarn; receiveData.fourGStrenth = fourGStrenth; receiveData.SOS = sosTxt; receiveData.qzwarn = sosTxt === 'sg'; console.log("recArr=", recArr); let recCnt = recArr.find(v => { return v.key.replace(/\//g, "").toLowerCase() == f.device.detailPageUrl .replace(/\//g, "").toLowerCase(); }); if (!recCnt) { let msgs = []; if (receiveData.qzwarn) { msgs.push("声光报警中"); } if (staticWarn) { //有静止报警 msgs.push("静止报警中"); } if (msgs.length > 0) { msgs = "设备'" + f.device.deviceName + msgs.join(";"); uni.showModal({ title: "警告", content: msgs, showCancel: false }); } } } catch (error) { console.error('数据解析错误:', error); } // console.log("todo"); } else { try { let uint8Array = new Uint8Array(receive.value); let str = ''; for (let i = 0; i < uint8Array.length; i++) { // 将每个字节转换为对应的字符 str += String.fromCharCode(uint8Array[i]); } if (str.indexOf('mac address:') == 0) { receiveData.macAddress = str.split(':').slice(1).join(":"); console.log('收到mac地址:', +this.receiveData.macAddress); } else if (str.indexOf('imei:') == 0) { receiveData.imei = str.split(':')[1]; console.log('收到IEMI:', +this.receiveData.macAddress); } else if (str.indexOf('longitude:') == 0) { receiveData.Lon = str.split(':')[1]; console.log('收到经度:', +this.receiveData.macAddress); } else if (str.indexOf('latitude:') == 0) { receiveData.Lat = str.split(':')[1]; console.log('收到纬度:', +this.receiveData.macAddress); } else { try { // console.log("str=",str); let json = JSON.parse(str); if ("staBlue_picture" in json) { //重发图片 console.log("收到重新发送图片的命令"); receiveData = json; } else if ("staBlue_text" in json) { //重发文本 console.log("收到重新发送文本的命令"); receiveData = json; } else if ("staBlue_vidio" in json) { //重发视频 console.log("收到重新发送视频的命令"); receiveData = json; } else if ("staBlue" in json) { if (json.staBlue == "finish") { console.log("收到设备回复,全部传输完成"); receiveData = json; } } else { receiveData = {}; console.log("无法解析该文本"); } } catch (error) { receiveData = {}; // console.log("文本解析失败",error) } } } catch (ex) { receiveData = {}; console.log('将数据转文本失败', ex); } } return receiveData; } let data = todo(receive.bytes); return data; } Receive_6155_XH(receive, f, path, recArr) { let bytes = receive.bytes; if (bytes[0] == 0xFB && bytes[1] == 0x64 && bytes.length >= 8) { try { let light = null; let mode = null; if (bytes[2] === 0x01 && bytes[3] === 0x00) { light = 0; mode = 'main'; } else if (bytes[2] === 0x02 && bytes[3] === 0x00) { light = 1; mode = 'main'; } else if (bytes[2] === 0x00 && bytes[3] === 0x01) { light = 2; mode = 'main'; } else if (bytes[2] === 0x03 && bytes[3] === 0x00) { light = 0; mode = 'fu'; } else if (bytes[2] === 0x04 && bytes[3] === 0x00) { light = 1; mode = 'fu'; } if (bytes[2] === 0x05 && bytes[3] === 0x00) { light = 3; } // 解析剩余电量 let batteryLevelByte = bytes[4]; // 电量百分比范围检查 let batteryLevel = Math.max(0, Math.min(100, batteryLevelByte)); //充电状态 let warn = bytes[5]; if (warn == 0x00) { warn = '未充电'; } else if (warn == 0x01) { warn = '充电中'; } // 解析剩余照明时间(第三和第四字节,小端序) let lightingTime = ""; let HH = Math.max(0, Math.min(100, bytes[6])); let mm = Math.max(0, Math.min(100, bytes[7])); lightingTime = HH + "小时" + mm + "分钟"; let formData = {}; formData.mode = mode; formData.light = light; formData.battary = batteryLevel; formData.statu = warn; formData.xuhang = lightingTime; let recCnt = recArr.find(v => { return v.key.replace(/\//g, "").toLowerCase() === f.device.detailPageUrl.replace(/\//g, '').toLowerCase(); }); if (!recCnt) { if (batteryLevel <= 20) { // 会弹出两个框,暂且注释掉这段代码 uni.showModal({ content: "设备'" + f.device.deviceName + "'电量低", title: "提示" }); } } return formData; } catch (error) { console.log('7305数据解析错误:', error); return null; } } return null; } Receive_6155(receive, f, path, recArr) { let bytes = receive.bytes; if (bytes[0] == 0xFB && bytes[1] == 0x64 && bytes.length >= 8) { try { let getName = function(type, ) { let name = ""; switch (type) { case 0x01: // name = '强光'; name = 0; break; case 0x02: // name = '弱光'; name = 1; break; case 0x03: // name = '爆闪'; name = 2; break; case 0x04: name = 0; //泛光 break; case 0x0A: name = 1; //强光&泛光 break; default: // name = '关闭'; name = null; break; } return name; } let staticLevelText = getName(bytes[2]); // 解析照明档位 let lightingLevelText = getName(bytes[3]); // 解析剩余电量 let batteryLevelByte = bytes[4]; // 电量百分比范围检查 let batteryLevel = Math.max(0, Math.min(100, batteryLevelByte)); //充电状态 let warn = bytes[5]; if (warn == 0x00) { warn = '未充电'; } else if (warn == 0x01) { warn = '充电中'; } // 解析剩余照明时间(第三和第四字节,小端序) let lightingTime = ""; let HH = Math.max(0, Math.min(100, bytes[6])); let mm = Math.max(0, Math.min(100, bytes[7])); lightingTime = HH + "小时" + mm + "分钟"; let formData = {}; formData.mode = (bytes[2] === 0x00 || bytes[2] === 0x0B) ? 'fu' : 'main'; formData.light = formData.mode == 'fu' ? lightingLevelText : staticLevelText; formData.battary = batteryLevel; formData.statu = warn; formData.xuhang = lightingTime; let recCnt = recArr.find(v => { return v.key.replace(/\//g, "").toLowerCase() === f.device.detailPageUrl.replace(/\//g, '').toLowerCase(); }); if (!recCnt) { if (batteryLevel <= 20) { // 会弹出两个框,暂且注释掉这段代码 uni.showModal({ content: "设备'" + f.device.deviceName + "'电量低", title: "提示" }); } } return formData; } catch (error) { console.log('7305数据解析错误:', error); return null; } } return null; } Receive_4877(receive, f, path, recArr) { let receiveData = {}; try { // console.log("str=",receive.str); receiveData = JSON.parse(receive.str); let recCnt = recArr.find(v => { return v.key.replace(/\//g, "").toLowerCase() == f.device.detailPageUrl .replace(/\//g, "").toLowerCase(); }); if (!recCnt) { if (receiveData.sta_PowerPercent <= 20) { uni.showModal({ title: "提示", content: "设备'" + f.device.deviceName + "'电量低", showCancel: false }); } } } catch (error) { receiveData = {}; console.log("文本解析失败", error) } return receiveData; } Receive_100(receive, f, path, recArr) { let receiveData = {}; try { // console.log("str=",receive.str); receiveData = JSON.parse(receive.str); let recCnt = recArr.find(v => { return v.key.replace(/\//g, "").toLowerCase() == f.device.detailPageUrl .replace(/\//g, "").toLowerCase(); }); if (!recCnt) { if (receiveData.sta_battery <= 20) { uni.showModal({ title: "提示", content: "设备'" + f.device.deviceName + "'电量低", showCancel: false }); } } } catch (error) { receiveData = {}; console.log("文本解析失败", error) } return receiveData; } Receive_102(receive, f, path, recArr) { let receiveData = {}; try { console.log("订阅消息者:", path); console.log("设备收到消息:", f); console.log("消息内容:", receive); receiveData = JSON.parse(receive.str); let recCnt = recArr.find(v => { return v.key.replace(/\//g, "").toLowerCase() == f.device.detailPageUrl .replace(/\//g, "").toLowerCase(); }); if (!recCnt) { if (receiveData.sta_PowerPercent <= 20) { uni.showModal({ title: "提示", content: "设备'" + f.device.deviceName + "'电量低", showCancel: false }); } if (receiveData.sta_Intrusion === 1) { uni.showModal({ title: "提示", content: "闯入报警中", showCancel: false }); } } if (f.device && path === "pages/common/index") { //仅在首页订阅此操作 console.error("1111111111"); let linkKey = "102_" + f.device.id + "_linked"; let warnKey = "102_" + f.device.id + "_warning"; let time = new Date(); //Common.DateFormat(new Date(),'yyyy-MM-dd HH:mmss'); if (receiveData.sta_tomac) { //某个设备上线了 if (receiveData.sta_tomac.indexOf(':') == -1) { receiveData.sta_tomac = receiveData.sta_tomac.replace(/(.{2})/g, '$1:').slice(0, - 1); //mac地址自动补: } uni.getStorageInfo({ success: function(res) { let arr = []; let linked = { linkId: f.linkId, read: false, linkEqs: [{ linkTime: time, linkMac: f.macAddress }, { linkTime: time, linkMac: receiveData.sta_tomac }] }; if (res.keys.includes(linkKey)) { arr = uni.getStorageSync(linkKey); } if (arr.length == 0) { arr.unshift(linked); } else { let dev = arr.find(v => { if (v.linkId == f.linkId) { let vl = v.linkEqs.find(cvl => { if(cvl.linkMac === receiveData.sta_tomac){ v.read=false; cvl.linkTime=time; return true; } return false; }); if (!vl) { v.linkEqs.push({ linkTime: time, linkMac: receiveData.sta_tomac }); } return vl; } return false; }); if (!dev) { arr.unshift(linked); } } console.error("某个设备上线了", arr) uni.setStorage({ key: linkKey, data: arr }); } }); } let warnArrs = []; let guid = Common.guid(); if (receiveData.sta_sosadd) { //某个设备闯入报警 console.error("某个设备闯入报警"); if (receiveData.sta_sosadd.indexOf(':') == -1) { receiveData.sta_sosadd = receiveData.sta_sosadd.replace(/(.{2})/g, '$1:').slice(0, - 1); //mac地址自动补: } warnArrs.push({ linkId: f.linkId, read: false, key: guid, warnType: "闯入报警", warnMac: receiveData.sta_sosadd, warnTime: time, warnName: "" }); } if (receiveData.sta_LedType === 'led_alarm' || receiveData.ins_LedType === 'led_alarm') { //强制报警 console.error("强制报警了", f); warnArrs.push({ linkId: f.linkId, read: false, key: guid, warnType: "强制报警", warnMac: f.macAddress, warnTime: time, warnName: "" }); } if (warnArrs.length > 0) { uni.getStorageInfo({ success: function(res) { let arr = []; if (res.keys.includes(warnKey)) { arr = uni.getStorageSync(warnKey); arr = warnArrs.concat(arr); } else { arr = warnArrs } uni.setStorage({ key: warnKey, data: arr }); } }); } } } catch (error) { receiveData = {}; console.log("文本解析失败", error) } return receiveData; } } let receiveInstance = null; export default { getBleReceive: function(found, receive) { if (!receiveInstance) { receiveInstance = new BleReceive(); } return receiveInstance; } }