TMRAppBle/script/ble.js

605 lines
24 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
/*初始化蓝牙适配器*/
function initManager(param) {
ble.initManager(param, function (ret) {
if (ret.state === "poweredOn") {
// console.log("初始化成功");
scan({clean: true});
} else if (ret.state === 'poweredOff') {
api.hideProgress();
mui.alert('检查蓝牙是否打开');
document.getElementById('text').innerHTML = '检查蓝牙是否打开';
}
});
}
var times = 5;
var sta = true;
var scanInter;
/*开始扫描*/
function scan(param) {
if (!uuid){
uuid = api.getPrefs({
sync: true,
key: 'uuid'
});
}
if (uuid){
isConnected({peripheralUUID: uuid},function(ret){
console.log("isConnected"+ret);
if(ret){
disconnect({peripheralUUID: uuid});
}
})
}
clearInterval(scanInter)
times = 5;
ble.scan(param, function (ret) {
if (ret.status) {
scanInter = setInterval(function (){
if (times>0){
times --;
var wifiDom = document.getElementById('wifiDom');
wifiDom.innerHTML = "扫描中"+times;
api.showProgress({
title: '扫描中'+times+'...',
modal: true
});
}else {
clearInterval(scanInter)
getPeripheral();
}
},1000)
}
});
}
/*获取扫描结果*/
function getPeripheral() {
ble.getPeripheral(function (ret) {
bleData = []
var ret2 = {};
var wifiDom = document.getElementById('wifiDom');
if (ret.peripherals.length > 0) {
ret.peripherals.forEach(function (p) {
if (undefined !== p.name) {
console.log(p.name);
if (p.name.indexOf("TMR_BLE") === -1){
return false
}else{
mui.toast("已扫描到" +p.name,{duration:3500,type:'div'});
wifiDom.innerHTML = p.name+'(未连接)';
document.getElementById('showBlePicker').setAttribute("class", 'btnc mui-btn-inline mui-btn-primary');
var json = { value: p.uuid, text: p.name };
bleData.push(json);
if (!uuid){
uuid = api.getPrefs({
sync: true,
key: 'uuid'
});
}
if (uuid && uuid === p.uuid){
document.getElementById('showBlePicker').innerHTML = p.name
isConnected({peripheralUUID: uuid},function(ret){
console.log("isConnected"+ret);
if(ret){
disconnect({peripheralUUID: uuid});
connect({peripheralUUID: uuid});
}else{
connect({peripheralUUID: uuid});
}
})
}
}
}
});
if(!bleData.length>0){
mui.toast("暂未扫描到蓝牙设备",{duration:3500,type:'div'});
document.getElementById('showBlePicker').setAttribute("class", 'btnc mui-btn-inline mui-btn-primary dis');
wifiDom.innerHTML = "重新扫描";
}else{
bleInit()
}
}
api.hideProgress();
});
}
// 连接失败次数
var connectTimes=0;
/*开始连接*/
function connect(param) {
var wifiDom = document.getElementById('wifiDom');
wifiDom.innerHTML = "";
api.showProgress({
title: '蓝牙连接中...',
modal: true
});
ble.connect(param, function (ret, err) {
if (ret.status) {
connetcedStatus = true
// 缓存蓝牙设备uuid方便自动连接
api.setPrefs({
key: 'uuid',
value: param.peripheralUUID
});
wifiDom.innerHTML = '已连接';
connectTimes = 0;
document.getElementById('text').innerHTML = '设备已连接';
text = '设备已连接';
console.log('主机端连接成功')
initWeight();
discoverService({peripheralUUID: param.peripheralUUID});
}else {
connetcedStatus = false
connectTimes ++;
console.log('主机端连接失败'+connectTimes+' '+uuid)
wifiDom.innerHTML = '连接失败';
api.hideProgress();
setTimeout(function (){
if (!connetcedStatus && uuid){
console.log("连接失败!尝试重连" + uuid);
wifiDom.innerHTML = '尝试重连';
connect({peripheralUUID: uuid});
}
},3000)
}
});
}
/*断开连接*/
function disconnect(param) {
ble.disconnect(param, function (ret, err) {
if (ret.status) {
console.log("断开连接成功!");
} else {
console.log("断开连接失败!");
}
});
}
/*判断是否已连接*/
function isConnected(param,callback){
ble.isConnected(param, function(ret) {
if (ret.status) {
console.log('已连接');
}
callback(ret.status)
});
}
var i;
// 蓝牙uuid
var peripheralUUID =''
// 蓝牙服务id
var serviceUUID =''
// 蓝牙特征id
var characteristicUUID =''
// 蓝牙待发送消息列表
var msgList = [];
// 清除消息定时任务
clearInterval(timerMsgList)
/*蓝牙消息发送定时任务150ms*/
var timerMsgList = setInterval(function(){
// console.log(new Date().getSeconds()+ ' ' + new Date().getMilliseconds() +' ' + msgList.length)
if (msgList.length > 0) {
// 发送报文
var msg = msgList[0];
msgList.splice(0, 1);
var param1 = {
peripheralUUID: peripheralUUID,
serviceUUID: serviceUUID,
characteristicUUID: characteristicUUID,
value: msg
};
if(connetcedStatus && peripheralUUID && serviceUUID && characteristicUUID){
writeValueForCharacteristic(param1, function (ret) {
// console.log(ret.status)
});
}
}
},150)
// 未装料状态计数采集达到10次发送一次停止蜂鸣指令
var bleConunt=0;
// 默认不自动跳转
var allowAuto = false;
/*扫描蓝牙服务*/
function discoverService(param) {
ble.discoverService(param, function (ret) {
if (ret.services.length > 0) {
// console.log("发现服务成功!");
ret.services.forEach(function (ret4) {
if (ret4.indexOf("0000ffe") !== -1) {
if (ret4 && ret4.length > 0) {
//发现特征
discoverCharacteristics({
serviceUUID: ret4,
peripheralUUID: param.peripheralUUID
}, function (ret5) {
peripheralUUID = param.peripheralUUID;
serviceUUID =ret4;
characteristicUUID =ret5;
//监听消息
setNotify({
peripheralUUID: param.peripheralUUID,
serviceUUID: ret4,
characteristicUUID: ret5
}, function (ret6) {
if (ret6 !== undefined) {
if (isNaN(ret6)) {
return false
}
nowWeight = ret6;
// 装料状态
if(feedStatus){
if (first) {
first = false;
beforeWeight = nowWeight;
}
if (load) {
_feedNum = nowWeight - beforeWeight;
} else {
_feedNum = beforeWeight - nowWeight;
}
text = feedName + _planSum;
if (!isNaN(nowWeight)) {
// 实时重量保存
totalList.push({
time: currTimeFn(new Date()),
nowWeight: nowWeight
});
}
document.getElementById('feedNum').innerHTML = '<font style="color:blue">:' + _planSum + '</font>/<font style="color:green">已装:' + _feedNum + '</font>';
}
serviceUUID = ret4;
characteristicUUID = ret5;
// 组装led报文
if (ledStatus && !isNaN(nowWeight)) {
getMess({
peripheralUUID: param.peripheralUUID,
serviceUUID: ret4,
characteristicUUID: ret5,
value: ret6
}, function (ret7) {
});
}
// 装料状态
if(feedStatus){
// 计划-饲喂
var feedErr = _planSum-_feedNum;
if (isNaN(feedErr)) {
return false
}
// 蜂鸣器校验基础值大于500的饲料取500为标准
var count;
if (_planSum >= 500) {
count = 500
} else {
count = _planSum
}
// 计算饲料装料量与基础值的误差比例
var ration = feedErr / count;
// console.log("ration" + ration.toFixed(2));
// 误差分为100%-20%(停止蜂鸣)10%-20%(间隔05)5%-10%(间隔03),2%-5%(间隔01),-100%-2%(长鸣)
if (ration > 0.2) {
bleConunt ++;
if (statusEle || (bleConunt >= 10)) {
bleConunt=0;
ledStatus = false;
status = '';
statusEle = false;
msgList = [];
control("00", "00");
setTimeout(function () {
ledStatus = true;
}, 500);
}
} else if (0.1 < ration && ration <= 0.2) {
time = "05";
if (!statusEle || lastTime !== time) {
console.log(feedErr + ' ' + allow + ' ' + _feedNum + ' ' + _planSum);
lastTime = time;
ledStatus = false;
status = '间隔';
statusEle = true;
msgList = [];
console.log("开始蜂鸣" + time);
control("60", time);
setTimeout(function () {
ledStatus = true;
}, 500);
}
} else if (0.05 < ration && ration <= 0.1) {
time = "03";
if (!statusEle || lastTime !== time) {
console.log(feedErr + ' ' + allow + ' ' + _feedNum + ' ' + _planSum);
lastTime = time;
ledStatus = false;
status = '间隔';
statusEle = true;
msgList = [];
console.log("开始蜂鸣" + time);
control("60", time);
setTimeout(function () {
ledStatus = true;
}, 500);
}
} else if (0.02 < ration && ration <= 0.05) {
time = "01";
if (!statusEle || lastTime !== time) {
console.log(feedErr + ' ' + allow + ' ' + _feedNum + ' ' + _planSum);
lastTime = time;
ledStatus = false;
status = '间隔';
statusEle = true;
msgList = [];
console.log("开始蜂鸣" + time);
control("60", time);
setTimeout(function () {
ledStatus = true;
}, 500);
}
} else {
if (status === '间隔' || status === '') {
console.log(feedErr + ' ' + allow + ' ' + _feedNum + ' ' + _planSum);
ledStatus = false;
status = '长鸣';
statusEle = true;
msgList = [];
console.log("开始长鸣");
control("40", "02");
setTimeout(function () {
ledStatus = true;
}, 500);
setTimeout(function() {
console.log("开始长鸣")
control("40", "02");
setTimeout(function() {
ledStatus = true;
}, 500)
}, 500)
}
}
// console.log(weightStabilization("weightStabilization"+nowWeight))
// 在误差范围内
if (feedErr <= allow && allowAuto) {
// 重量稳定计数
var filteredValue = weightDataFilter.filter(nowWeight);
// 重量稳定自动跳转
if (weightDataFilter.dataBuffer.length === 40) {
console.log("重量稳定", currTimeFn(new Date()));
weightDataFilter.dataBuffer = []
document.getElementById('submitData').click();
}
}
}
}
});
});
}
}
});
} else {
console.log("发现服务失败!");
}
});
}
/*扫描特征*/
function discoverCharacteristics(param, callback) {
ble.discoverCharacteristics(param, function (ret) {
var res = '';
if (ret.characteristics.length > 0) {
// console.log("发现特征成功!");
ret.characteristics.forEach(function (s) {
if (s.serviceUUID === param.serviceUUID) {
callback(s.uuid);
}
});
} else {
console.log("发现特征失败!");
callback(res);
}
});
}
/*适配两种称数据解析*/
function StringToNum(hexx){
var hex = hexx.toString(); //force conversion
var str = '';
var num = '';
for (var i = 0; i < hex.length; i += 2) {
num = String.fromCharCode(parseInt(hex.substr(i, 2), 16));
if((num >= '0' && num <= '9') || (num === '-'))
{
str += num;
}
else
{
if(str.length !== 0)
{
return str
}
}
}return str;
}
/*监听蓝牙数据,转换重量数据*/
function setNotify(param, callback) {
ble.setNotify(param, function (ret) {
// console.log(JSON.stringify(ret))
var value = ret.characteristic.value;
// if (ret && value.indexOf('ff01') !== -1) {
if (ret && value.substr(0,4) === 'ff01') {
var wei = value.substr(8, value.length-8);
// var wei = value.substr(12, 12);
// wei = Math.round(Number(hex2a(wei)));
wei = Math.round(Number(StringToNum(wei)));
}
callback(wei);
});
}
/*发送消息到蓝牙*/
function writeValueForCharacteristic(param, callback) {
if (param.value && connetcedStatus){
ble.writeValueForCharacteristic(param, function (ret) {
// console.log(JSON.stringify(ret));
if (ret.status) {
// console.log("发送成功");
} else {
console.log("发送失败:"+param.value);
}
callback(ret);
});
}
}
var lastTime = new Date().getSeconds()*1000+ new Date().getMilliseconds();
// 接收重量数据计数
var count = 0;
/*组装报文并发数*/
function getMess(param, callback) {
var param1 = {
SF: "AA A5 ",
LEN: '1A 00 ',
DES: 'FF FF ',
SRC: '12 34 ',
TID: 'B0 A1 ',
CMD1: '38 02 ',
X: '00 00 ',
Y: '00 00 ',
WIDTH: '40 00 ',
HEIGHT: '20 00 ',
FORMAT: '00 00 01 00 ',
CNT: '04 00 ',
CRC: '00 00 ',
EF: '5A 55 ',
msg: ''
};
var newmsg = feedName;
if(!newmsg.length>0){
return false
}
var msglen = newmsg.getByteLen();
var ttr = '';
if (Number(_planSum - _feedNum) >= 0) {
ttr = '少';
echartsType = '少';
} else {
ttr = '多';
echartsType = '多';
}
if (msglen < 8) {
for (var i = 0; i < 8 - msglen; i++) {
newmsg = newmsg + ' ';
}
newmsg = newmsg + ttr;
} else {
newmsg = feedName + ttr;
}
// 不是装料状态班次饲喂完成显示
if(!feedStatus){
var newmsg = batchName+'次';
var msglen = newmsg.getByteLen();
var ttr = '';
if (msglen < 8) {
for (var i = 0; i < 8 - msglen; i++) {
newmsg = newmsg + ' ';
}
newmsg = newmsg + ttr;
} else {
newmsg = feedName + ttr;
}
param1.msg = newmsg + '饲喂完成';
}else{
param1.msg = newmsg + Math.abs(Number(_planSum - _feedNum)).toFixed(0) + 'kg';
}
// param1.msg = newmsg + Math.abs(Number(param.value)).toFixed(0) + 'kg'
console.log(param1.msg)
//组装字符卡LED报文
zfk.getMsg(param1, function (ret, err) {
var str = ret.sendMsg;
str = str.replace(/\s+/g, "");
var num = str.length / 2;
param.value = "FF0500" + num.toString(16) + str;
count ++;
// 称重量数据3包取1包
if (count >= 3){
msgList.push(param.value);
// var ms = strToHex(sbId,4)+strToHex(classCode,2)+strToHex(trainNumber,2)+strToHex(feedIndex,2)+strToHex(_planSum,4)+strToHex(_feedNum,4)+strToHex(nowWeight,4);
// var num1 = ms.length / 2;
// 同步刷新图表
// 饲喂状态刷新实时状态,否则不刷新装料信息
if(feedStatus){
renderUnload();
feedMyChart.setOption({
dataset: {
source: [[1, _feedNum]]
}
});
}
renderLoad();
weightMyChart.setOption({
dataset: {
source: [[1, nowWeight]]
}
});
count = 0 ;
}
});
}
/*字符串转16进制hex*/
function strToHex(str,length){
var hex = Number(str).toString(16);
var append = '';
if (hex.length < length){
for (var i=0;i<length-hex.length;i++){
append = append + '0';
}
}
return append+hex;
}
/*初始化重量图表*/
function initWeight() {
api.showProgress({
title: '图表数据加装中...',
modal: true
});
weightStatus = true;
weightDataFilter = new WeightDataFilter(40, _weightSum);
renderUnload();
renderLoad();
feedMyChart.setOption({
dataset: {
source: [[1, _feedNum]]
}
});
weightMyChart.setOption({
dataset: {
source: [[1, nowWeight]]
}
});
api.hideProgress();
clearInterval(totalInterval);
totalAjax = true;
canUpload = true;
totalList = [];
totalInterval = setInterval(function () {
totalWeightUpload();
}, 3000);
document.getElementById('startLoad').setAttribute("class", 'btnc mui-btn-success dis');
document.getElementById('submitData').setAttribute("class", 'btnc mui-btn-success');
document.getElementById('text').innerHTML = 'V' + api.appVersion;
api.setGlobalData({key: 'startTime', value: currTimeFn(new Date())});
}
var lastWeight = 0;
function weightStabilization(weight) {
// 计算当前重量与上一次记录的重量之间的差值
var diff = weight - lastWeight;
// 如果差值在一定范围内,则认为重量是稳定的
if (Math.abs(diff) < 2) {
weight = weight;
lastWeight = weight;
return true;
} else {
// 如果差值超过一定范围,则认为重量是不稳定的,重新开始计算
weight = 0;
lastWeight = weight;
return false;
}
}