闲来没事钻研小程序开发,写了一篇关于微信小程序ble设备控制的底层api,话不多说直接上源码:
目录结构:
baseBleApi.js文件:
var currentDevice = {};
//ble设备
var notifyService = {};
//唤醒特征值
var writeService = {};
//写入服务
var writeCharacteristic = {};
//写入特征值
var notifyCharacteristic = {};
//唤醒特征值
var onSendSuccessCallBack =
undefined;
//成功回调
var onConnectCallback =
undefined;
// 链接回调
var bleUtils =
require(
'utils/strUtils.js');
var crc =
require(
'crc.js');
var isConnected =
false;
//是否已链接
module.exports = {
writeCommend: writeCommend,
closeBLEConnection: closeBLEConnection
// disConnect, disConnect,
// openBluetoothAdapter: openBluetoothAdapter
}
/**
* @param sendCommend 写入命令
* @param deviceName 锁具名称
* @param onSuccessCallBack 成功回调
* @param onFailCallBack 返回失败回调
* @param onCompleteCallBack 成功失败都会回调
*
* @param services 主服务serviceUUID
* @param writeServiceUUID 写入服务UUID
* @param notifyServiceUUID 唤醒服务UUID
*
* @param notifyCharacteristicUUID 唤醒特征值UUID
* @param writeCharacteristicUUID 写入特征值UUID
*/
function writeCommend(options) {
var params = {};
var defalt = {
adviceId:
"",
sendCommend:
"",
onSuccessCallBack:
function success(res) { },
onFailCallBack:
function success(res) { },
onCompleteCallBack:
function success(res) { },
services: [],
writeServiceUUID:
"",
notifyServiceUUID:
"",
notifyCharacteristicUUID:
"",
writeCharacteristicUUID:
""
};
params = Object.assign(defalt, options)
// setConnectionStateChange(params.onFailCallBack)
if (!setConnectionStateChange()) {
openBluetoothAdapter(params);
}
else {
// typeof str == 'string'
sendCmd(params.sendCommend, params.onSuccessCallBack, params.onFailCallBack);
}
}
/**
* 初始化蓝牙适配器
*/
function openBluetoothAdapter(params) {
wx.openBluetoothAdapter({
success:
function (res) {
console.log(
"初始化蓝牙适配器成功")
console.log(res)
startBluetoothDevicesDiscovery(params)
}, fail:
function (res) {
console.log(
"初始化蓝牙适配器失败")
params.onFailCallBack(res.errMsg)
console.log(res);
return
},
complete:
function (res) {
console.log(res);
}
})
}
/**
* 开始搜寻附近的蓝牙外围设备。注意,该操作比较耗费系统资源,请在搜索并连接到设备后调用 stop 方法停止搜索。
* @ params services:['4asdga'],根据主ServiceUUID进行搜索特定蓝牙,提高搜索效率
* 本ble设备主ServiceUUid: "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
*/
var delayTimer;
//停止循环获取tag
var isFound =
false
function startBluetoothDevicesDiscovery(params, connectCallback) {
if (
typeof connectCallback ==
'undefined') {
connectCallback =
function (errMsg) { }
}
onConnectCallback = connectCallback;
setTimeout(
function () {
if (isFound) {
return;
}
else {
console.log(
"搜索设备超时");
params.onFailCallBack(
"搜索设备超时")
stopBluetoothDevicesDiscovery();
clearInterval(delayTimer)
return
}
},
10000);
wx.startBluetoothDevicesDiscovery({
services: params.services,
success:
function (res) {
console.log(res)
console.log(
"开启搜索成功")
getBluetoothDevices(params)
}, fail:
function (res) {
console.log(
"开启搜索失败")
console.log(res)
params.onFailCallBack(res)
return
},
complete:
function (res) {
// complete
console.log(res);
}
})
//每隔一秒获取一次
delayTimer = setInterval(
function () {
getBluetoothDevices(params)
},
1000)
}
/**
* 获取所有已发现的蓝牙设备,包括已经和本机处于连接状态的设备
*/
function getBluetoothDevices(params) {
wx.getBluetoothDevices({
success:
function (res) {
console.log(
"getBluetoothDevices");
console.log(res.devices);
for (
var i =
0; i < res.devices.length; i++) {
//忽略传入的deviceName大小写
// isContains bleUtils
var lockNameFinal = bleUtils.removeBytes(params.adviceId,
":")
if (bleUtils.isContains(res.devices[i].name, lockNameFinal)) {
console.log(
"搜索到要链接的设备....")
stopBluetoothDevicesDiscovery();
isFound =
true
clearInterval(delayTimer)
currentDevice = res.devices[i]
createBLEConnection(params)
}
}
},
fail:
function (res) {
clearInterval(delayTimer)
console.log(
"没有搜索到要链接的设备....")
console.log(res)
params.onFailCallBack(res)
stopBluetoothDevicesDiscovery();
return
}
})
}
/**
* 停止搜寻附近的蓝牙外围设备。请在确保找到需要连接的设备后调用该方法停止搜索。
*/
function stopBluetoothDevicesDiscovery() {
wx.stopBluetoothDevicesDiscovery({
success:
function (res) {
console.log(res)
}
})
}
/**
* 连接低功耗蓝牙设备
*/
function createBLEConnection(params) {
// setConnectionStateChange(params.onFailCallBack);
setTimeout(
function () {
if (isConnected)
return;
console.log(
"连接设备超时");
params.onFailCallBack(
"连接设备超时")
return
},
5000)
wx.createBLEConnection({
// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
deviceId: currentDevice.deviceId +
"",
success:
function (res) {
console.log(res)
console.log(
`连接成功 : ${currentDevice.deviceId
}`)
isConnected =
true
getBLEDeviceServices(params);
}, fail:
function (res) {
console.log(res)
params.onFailCallBack(res)
console.log(
`连接失败 : ${currentDevice.deviceId
}`)
}
})
}
/**
* closeBLEConnection
* 断开与低功耗蓝牙设备的连接
*/
function closeBLEConnection(deviceId) {
wx.closeBLEConnection({
deviceId: currentDevice.deviceId +
"",
success:
function (res) {
console.log(res)
}
})
}
/**
*
* 返回蓝牙是否正处于链接状态
*/
function setConnectionStateChange(onFailCallback) {
wx.onBLEConnectionStateChange(
function (res) {
// 该方法回调中可以用于处理连接意外断开等异常情况
console.log(
`device ${res.deviceId
} state has changed, connected: ${res.connected
}`);
return res.connected;
});
}
/**
* 获取蓝牙设备所有 service(服务)
* @params writeServiceUUID:ble设备所具有的写入服务UUID
* @params notifyServiceUUID:ble设备具有的唤醒服务UUID
*/
function getBLEDeviceServices(params) {
wx.getBLEDeviceServices({
// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
deviceId: currentDevice.deviceId +
"",
success:
function (res) {
console.log(
`获取服务成功 :`)
console.log(
'device services:', res.services)
for (
var i =
0; i < res.services.length; i++) {
if (res.services[i].uuid == params.writeServiceUUID) {
writeService = res.services[i]
}
if (res.services[i].uuid == params.notifyServiceUUID) {
notifyService = res.services[i]
}
}
//获取
getNotifyBLEDeviceCharacteristics(params);
}
})
}
/**
* 获取蓝牙设备唤醒characteristic(特征值)
*/
function getNotifyBLEDeviceCharacteristics(params) {
wx.getBLEDeviceCharacteristics({
// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
deviceId: currentDevice.deviceId +
"",
// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: notifyService.uuid +
"",
success:
function (res) {
console.log(
"唤醒特征值获取成功:")
console.log(
'device getBLEDeviceCharacteristics:', res.characteristics)
for (
var i =
0; i < res.characteristics.length; i++) {
if (res.characteristics[i].uuid == params.notifyCharacteristicUUID) {
notifyCharacteristic = res.characteristics[i]
}
}
// getWriteBLEDeviceCharacteristics();
console.log(
"唤醒特征值 :", notifyCharacteristic)
getWriteBLEDeviceCharacteristics(params)
}
})
}
function getWriteBLEDeviceCharacteristics(params) {
wx.getBLEDeviceCharacteristics({
// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
deviceId: currentDevice.deviceId +
"",
// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: writeService.uuid +
"",
success:
function (res) {
console.log(
"写入特征值获取成功:")
console.log(
'device getBLEDeviceCharacteristics:', res.characteristics)
for (
var i =
0; i < res.characteristics.length; i++) {
if (res.characteristics[i].uuid == params.writeCharacteristicUUID) {
writeCharacteristic = res.characteristics[i]
}
}
console.log(
"xieru :", writeCharacteristic)
initNotifyListener(params);
}
})
}
/**
*
* 连接成功后,初始化回调监听
*
* 启用低功耗蓝牙设备特征值变化时的 notify 功能。注意:\
* 必须设备的特征值支持notify才可以成功调用,具体参照 characteristic 的 properties 属性
*/
function initNotifyListener(params) {
wx.notifyBLECharacteristicValueChanged({
deviceId: currentDevice.deviceId +
"",
serviceId: notifyService.uuid +
"",
characteristicId: notifyCharacteristic.uuid +
"",
state:
true,
success:
function (res) {
console.log(
`开启监听成功${res.errMsg
}`);
setTimeout(
function () {
onConnectCallback(
'ok');
// 连接成功后,初始化回调监听回调
sendCmd(params.sendCommend, params.onSuccessCallBack, params.onFailCallBack);
},
200);
},
fail:
function (res) {
console.log(
"开启监听失败" + res.errMsg);
params.onFailCallBack(
"开启监听失败");
}
});
onBLECharacteristicValueChange();
}
/**
* 启用低功耗蓝牙设备特征值变化时的 notify 功能。注意:
* 必须设备的特征值支持notify才可以成功调用,具体参照 characteristic 的 properties 属性
*/
function onBLECharacteristicValueChange() {
wx.onBLECharacteristicValueChange(
function (res) {
console.log(
`characteristic ${res.characteristicId
} has changed, now is ${bleUtils.arrayBuffer2HexString(res.value)
}`);
onSendSuccessCallBack(bleUtils.arrayBuffer2HexString(res.value));
})
}
/**
* 发送指令,不关心指令具体长度
* @param commond 指令
* @param onSuccess 指令执行成功回调
*/
function sendCmd(commond, onSuccess, onFailCallback) {
var sendCommonds = crc.getCRCCmd(commond);
//对commond的CRC处理必须放在这里
if (
typeof onSuccess ==
'undefined') {
onSuccess =
function (result) { }
}
onSendSuccessCallBack = onSuccess;
sendCmds(sendCommonds,
0, onFailCallback);
}
/**
*
* 逐条发送指令
*/
function sendCmds(commond, index, onFailCallback) {
var itemCmd;
var isLast =
false;
// 判断是否是最后一条
if (commond.length > index +
40) {
itemCmd = commond.substr(index,
40);
}
else {
isLast =
true;
itemCmd = commond.substr(index);
}
writeCommendToBle(itemCmd,
function (errMsg) {
if (errMsg ==
'ok' && !isLast) {
// 发送成功并且不是最后一条时,执行下一条
sendCmds(commond, index +
40);
}
}, onFailCallback)
}
// 向蓝牙中写入数据(ble蓝牙)(增加指纹)
function writeCommendToBle(commonds, onSendCallback, onFailCallback) {
var commond = commonds;
console.log(
"commond :" + commond)
let buffer = bleUtils.hexString2ArrayBuffer(commond);
console.log(
`执行指令:${bleUtils.arrayBuffer2HexString(buffer)
}`);
wx.writeBLECharacteristicValue({
deviceId: currentDevice.deviceId +
"",
serviceId: writeService.uuid +
'',
characteristicId: writeCharacteristic.uuid +
'',
// 这里的value是ArrayBuffer类型
value: buffer,
success:
function (res) {
console.log(
'发送指令成功')
console.log(
'writeBLECharacteristicValue success', res.errMsg)
onSendCallback(
'ok');
},
fail:
function (res) {
console.log(
`执行指令失败${res.errMsg
}`);
onFailCallback(
"执行指令失败");
}
})
}
crc.js文件:
function CRC16(data) {
var len = data.length;
if (len >
0) {
var crc =
0xFFFF;
for (
var i =
0; i < len; i++) {
crc = (crc ^ (data[i]));
for (
var j =
0; j <
8; j++) {
crc = (crc &
1) !=
0 ? ((crc >>
1) ^
0xA001) : (crc >>
1);
}
}
var hi = ((crc &
0xFF00) >>
8);
//高位置
var lo = (crc &
0x00FF);
//低位置
// return [hi, lo];
return [lo, hi];
// 大端模式
}
return [
0,
0];
};
function isArray(arr) {
return Object.prototype.toString.call(arr) ===
'[object Array]';
};
function ToCRC16(str, isReverse) {
return toString(CRC16(isArray(str) ? str : strToByte(str)), isReverse);
};
function strToByte(str) {
var tmp = str.split(
''), arr = [];
for (
var i =
0, c = tmp.length; i < c; i++) {
var j = encodeURI(tmp[i]);
if (j.length ==
1) {
arr.push(j.charCodeAt());
}
else {
var b = j.split(
'%');
for (
var m =
1; m < b.length; m++) {
arr.push(parseInt(
'0x' + b[m]));
}
}
}
return arr;
};
function convertChinese(str) {
var tmp = str.split(
''), arr = [];
for (
var i =
0, c = tmp.length; i < c; i++) {
var s = tmp[i].charCodeAt();
if (s <=
0 || s >=
127) {
arr.push(s.toString(
16));
}
else {
arr.push(tmp[i]);
}
}
return arr;
};
function filterChinese(str) {
var tmp = str.split(
''), arr = [];
for (
var i =
0, c = tmp.length; i < c; i++) {
var s = tmp[i].charCodeAt();
if (s >
0 && s <
127) {
arr.push(tmp[i]);
}
}
return arr;
};
function strToHex(hex, isFilterChinese) {
hex = isFilterChinese ? filterChinese(hex).join(
'') : convertChinese(hex).join(
'');
//清除所有空格
hex = hex.replace(/\s/g,
"");
//若字符个数为奇数,补一个空格
hex += hex.length %
2 !=
0 ?
" " :
"";
var c = hex.length /
2, arr = [];
for (
var i =
0; i < c; i++) {
arr.push(parseInt(hex.substr(i *
2,
2),
16));
}
return arr;
};
function padLeft(s, w, pc) {
if (pc ==
undefined) {
pc =
'0';
}
for (
var i =
0, c = w - s.length; i < c; i++) {
s = pc + s;
}
return s;
};
function toString(arr, isReverse) {
if (
typeof isReverse ==
'undefined') {
isReverse =
true;
}
var hi = arr[
0], lo = arr[
1];
return padLeft((isReverse ? hi + lo *
0x100 : hi *
0x100 + lo).toString(
16).toUpperCase(),
4,
'0');
};
function CRC16(data) {
var len = data.length;
if (len >
0) {
var crc =
0xFFFF;
for (
var i =
0; i < len; i++) {
crc = (crc ^ (data[i]));
for (
var j =
0; j <
8; j++) {
crc = (crc &
1) !=
0 ? ((crc >>
1) ^
0xA001) : (crc >>
1);
}
}
var hi = ((crc &
0xFF00) >>
8);
//高位置
var lo = (crc &
0x00FF);
//低位置
// return [hi, lo];
return [lo, hi];
// 大端模式
}
return [
0,
0];
};
function ToCRC16(str, isReverse) {
return toString(CRC16(isArray(str) ? str : strToByte(str)), isReverse);
};
function ToModbusCRC16(str, isReverse) {
return toString(CRC16(isArray(str) ? str : strToHex(str)), isReverse);
};
/**
* 给命令增加CRC 16进制
*
* @param hex
* @return 16进制
*/
function getCRCCmd(hex) {
var hexTemp = hex;
if (hex.toUpperCase().startsWith(
"0X")) {
hexTemp = hex.substr(
4);
}
else
if (hex.toUpperCase().startsWith(
"AA")) {
hexTemp = hex.substr(
2);
}
return hex + getCRCStr(hexTemp);
}
/**
* 获取CRC 16进制
*
* @param data
* @return
*/
function getCRCStr(data) {
return ToModbusCRC16(data);
}
module.exports = {
ToCRC16: ToCRC16,
ToModbusCRC16: ToModbusCRC16,
getCRCCmd: getCRCCmd
}
strUtils文件:
/**
* ArrayBuffer转16进制字符串
*/
function arrayBuffer2HexString(buf) {
var out =
"";
var u8a =
new Uint8Array(buf);
var single;
for (
var i =
0; i < u8a.length; i++) {
single = u8a[i].toString(
16)
while (single.length <
2) single =
"0".concat(single);
out += single;
}
return out;
}
/**
* 1、字符串转换为十六进制
* 主要使用 charCodeAt()方法,此方法返回一个字符的 Unicode 值,该字符位于指定索引位置。
*/
function stringToHex(str) {
var val =
"";
for (
var i =
0; i < str.length; i++) {
val += str.charCodeAt(i).toString(
16);
}
return val;
}
function filterChinese(str) {
var tmp = str.split(
''), arr = [];
for (
var i =
0, c = tmp.length; i < c; i++) {
var s = tmp[i].charCodeAt();
if (s >
0 && s <
127) {
arr.push(tmp[i]);
}
}
return arr;
};
function strToHex(hex, isFilterChinese) {
hex = isFilterChinese ? filterChinese(hex).join(
'') : convertChinese(hex).join(
'');
//清除所有空格
hex = hex.replace(/\s/g,
"");
//若字符个数为奇数,补一个空格
hex += hex.length %
2 !=
0 ?
" " :
"";
var c = hex.length /
2, arr = [];
for (
var i =
0; i < c; i++) {
arr.push(parseInt(hex.substr(i *
2,
2),
16));
}
return arr;
};
/**
* 16进制字符串转ArrayBuffer
*/
function hexString2ArrayBuffer(hexStr) {
var count = hexStr.length /
2;
let buffer =
new ArrayBuffer(count);
let dataView =
new DataView(buffer);
for (
var i =
0; i < count; i++) {
var curCharCode = parseInt(hexStr.substr(i *
2,
2),
16);
dataView.setUint8(i, curCharCode);
}
return buffer;
}
/**
* 字符串转为ArrayBuffer对象,参数为字符串
*/
function string2ArrayBuffer(str) {
var buf =
new ArrayBuffer(str.length *
2);
// 每个字符占用2个字节
var bufView =
new Uint8Array(buf);
for (
var i =
0, strLen = str.length; i < strLen; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
function isArray(arr) {
return Object.prototype.toString.call(arr) ===
'[object Array]';
};
function strToByte(str) {
var tmp = str.split(
''), arr = [];
for (
var i =
0, c = tmp.length; i < c; i++) {
var j = encodeURI(tmp[i]);
if (j.length ==
1) {
arr.push(j.charCodeAt());
}
else {
var b = j.split(
'%');
for (
var m =
1; m < b.length; m++) {
arr.push(parseInt(
'0x' + b[m]));
}
}
}
return arr;
};
function convertChinese(str) {
var tmp = str.split(
''), arr = [];
for (
var i =
0, c = tmp.length; i < c; i++) {
var s = tmp[i].charCodeAt();
if (s <=
0 || s >=
127) {
arr.push(s.toString(
16));
}
else {
arr.push(tmp[i]);
}
}
return arr;
};
function filterChinese(str) {
var tmp = str.split(
''), arr = [];
for (
var i =
0, c = tmp.length; i < c; i++) {
var s = tmp[i].charCodeAt();
if (s >
0 && s <
127) {
arr.push(tmp[i]);
}
}
return arr;
};
function strToHex(hex, isFilterChinese) {
hex = isFilterChinese ? filterChinese(hex).join(
'') : convertChinese(hex).join(
'');
//清除所有空格
hex = hex.replace(/\s/g,
"");
//若字符个数为奇数,补一个空格
hex += hex.length %
2 !=
0 ?
" " :
"";
var c = hex.length /
2, arr = [];
for (
var i =
0; i < c; i++) {
arr.push(parseInt(hex.substr(i *
2,
2),
16));
}
return arr;
};
function padLeft(s, w, pc) {
if (pc ==
undefined) {
pc =
'0';
}
for (
var i =
0, c = w - s.length; i < c; i++) {
s = pc + s;
}
return s;
};
function toString(arr, isReverse) {
if (
typeof isReverse ==
'undefined') {
isReverse =
true;
}
var hi = arr[
0], lo = arr[
1];
return padLeft((isReverse ? hi + lo *
0x100 : hi *
0x100 + lo).toString(
16).toUpperCase(),
4,
'0');
};
/**
* 16进制字符串异或处理
*
* @param str1
* @param str2
* @return
*/
function stringXor(str1, str2) {
if (!str1 && !str2) {
return
"";
}
if (!str1 && str2) {
return str2;
}
if (str1 && !str2) {
return str1;
}
var longStr;
var shortStr;
if (str1.length >= str2.length) {
longStr = str1;
shortStr = str2;
}
else {
longStr = str2;
shortStr = str1;
}
var count = parseInt(shortStr.length /
2);
var leftCount = longStr.length - shortStr.length;
var resultStr =
"";
if (leftCount >
0) {
resultStr += longStr.substr(
0, leftCount);
}
for (
var i =
0; i < count; i++) {
var shortCharCode = parseInt(shortStr.substr(i *
2,
2),
16);
var longCharCode = parseInt(longStr.substr(leftCount + i *
2,
2),
16);
var resultCode = shortCharCode ^ longCharCode;
var single = resultCode.toString(
16);
while (single.length <
2) single =
"0".concat(single);
resultStr += single;
}
return resultStr.toUpperCase();
}
/**
* 指令两个16进制字符串异或处理
*
* @param command
* @param secretKey
* @return
*/
function getSecretEncoding(command, secretKey) {
if (!command || !secretKey) {
return
"";
}
var secretLength = secretKey.length;
var length = parseInt(command.length / secretLength);
console.log(
`command(${command.length
})/secretLength(${secretLength
}) = ${length
}`);
var resultCmd =
"";
console.log(
`secretKey(${secretKey.length
}):${secretKey
}`);
for (
var i =
0; i < length; i++) {
var part = command.substr(i * secretLength, secretLength);
resultCmd += stringXor(part, secretKey);
console.log(
`part${i
}:${stringXor(part, secretKey)
}`);
}
var lastLen = command.length % secretLength;
if (lastLen >
0) {
console.log(
`lastCMD:${command.substr(command.length - lastLen, lastLen)
}`);
console.log(
`lastSecretKey:${secretKey.substr(
0, lastLen)
}`);
var lastPart = command.substr(command.length - lastLen, lastLen);
var lastCmd = stringXor(lastPart, secretKey.substr(
0, lastLen));
resultCmd += lastCmd;
console.log(
`lastPart:${lastCmd
}`);
}
return resultCmd;
}
/**
* 2、十六进制转换为字符串
*主要使用 fromCharCode()方法,此方法将 Unicode 码转换为与之对应的字符。
*/
function hexToString(str) {
var val =
"";
var arr = str.split(
",");
for (
var i =
0; i < arr.length; i++) {
val += arr[i].fromCharCode(i);
}
return val;
}
/**
* 获取随机长度16进制字符串
*/
function getRamNumber(length) {
var result =
'';
for (
var i =
0; i < length; i++) {
result += Math.floor(Math.random() *
16).toString(
16);
//获取0-15并通过toString转16进制
}
//默认字母小写,手动转大写
return result.toUpperCase();
//另toLowerCase()转小写
}
/**
* 得到BCD码时间字符串
*
* @param datetime
* @return
*/
function getBCDTime(datetime, needWeek) {
if (
typeof datetime ==
'undefined') {
datetime =
new Date();
}
if (
typeof needWeek ==
'undefined') {
needWeek =
true;
}
var year = datetime.getFullYear() -
2000;
//获取年份,从2000年开始计算
if (year <
0) year =
0;
// 不允许小于2000年的年份出现
var month = datetime.getMonth() +
1;
//获取月份 0-11 所以需要加1
var day = datetime.getDate();
//获取日
var hour = datetime.getHours();
//小时
var minute = datetime.getMinutes();
//分
var second = datetime.getSeconds();
//秒
if (needWeek) {
var dayOfWeek = datetime.getDay();
//一周的第几天 0-6
return formatNumber(year) + formatNumber(month) + formatNumber(day) + formatNumber(dayOfWeek)
+ formatNumber(hour) + formatNumber(minute) + formatNumber(second);
// 得到BCD码的时间字符串
}
else {
return formatNumber(year) + formatNumber(month) + formatNumber(day)
+ formatNumber(hour) + formatNumber(minute) + formatNumber(second);
// 得到BCD码的时间字符串
}
}
function formatNumber(n) {
n = n.toString()
return (n[
1] ? n :
'0' + n) +
"";
}
/**
* 判断一个字符串是否包含子串
*/
function isContains(str, substr) {
var strUp = str.toUpperCase();
var substrUp = substr.toUpperCase()
return
new RegExp(substrUp).test(strUp);
}
/**
* 去除字符串中特定的字符
*/
function removeBytes(str, substr) {
var items = str.split(substr)
// 会得到一个数组,数组中包括利用o分割后的多个字符串(不包括o)
var newStr = items.join(
"");
return newStr
// }
}
module.exports = {
hexString2ArrayBuffer: hexString2ArrayBuffer,
arrayBuffer2HexString: arrayBuffer2HexString,
// getCRCCmd: getCRCCmd,
getBCDTime: getBCDTime,
stringToHex: stringToHex,
stringXor: stringXor,
getSecretEncoding: getSecretEncoding,
hexToString: hexToString,
getRamNumber: getRamNumber,
isContains: isContains,
removeBytes: removeBytes
}
傻瓜式调用,
为了方便用户,这里进行了二级封装
antsBleApi.js文件时为了方便用户调用的二级接口:
var bleApi =
require(
'baseBleApi.js');
module.exports = {
sendCommand: sendCommand
}
function sendCommand(params) {
var defaults = {
adviceId:
"",
sendCommend:
"",
onSuccessCallBack:
function successCallBack(res) { },
onFailCallBack:
function failCallBack(res) { },
onCompleteCallBack:
function completeCallBack(res) { },
services: [
"xxxxx-xxxxxxxxx-xxxxx"],
writeServiceUUID:
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx",
notifyServiceUUID:
"xxxxxxxxxx-xxxx
-xxxx-xxxx-xxxxxxxxxxx",
notifyCharacteristicUUID:
"xxxxxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxx",
writeCharacteristicUUID:
"xxxx-xxxx-xxxx-xxxx-xxxx"
}
var setParams = Object.assign(defaults, params)
bleApi.writeCommend(setParams);
}
此接口中service可以不写,但是adviceId,链接时必须写,,链接标志,
writeServiceUUID,notifyServiceUUID,notifyCharacteristicUUID,writeCharacteristicUUID
这几个参数是为了进行ble设备通信所用到的
调用demo:
openDoor:
function () {
var that =
this
progressUtils.showLoding();
bleApi.sendCommand({
deviceId:
"xx:xx:xx:xx:xx:xx", sendCommend:
"xxxxxxxxx", onSuccessCallBack:
function onSuccessCallBack(result) {
wx.showToast({
title:
result,
icon:
'',
image:
'',
duration:
1500,
})
console.log(
'result:' +
result);
}
});