001:格式
<script>
const LAST_CONNECTED_DEVICE = 'last_connected_device'
import PrinterJobs from '../../common/printer/printerjobs'
import printerUtil from '../../common/printer/printerutil'
function inArray(arr, key, val) {
for (let i = 0; i < arr.length; i++) {
if (arr[i][key] === val) {
return i
}
}
return -1
}
// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join(',')
}
function str2ab(str) {
// Convert str to ArrayBuff and write to printer
let buffer = new ArrayBuffer(str.length)
let dataView = new DataView(buffer)
for (let i = 0; i < str.length; i++) {
dataView.setUint8(i, str.charAt(i).charCodeAt(0))
}
return buffer;
}
export default {
data() {
return {
devices: [],
}
},
onLoad(e) {
const lastDevice = uni.getStorageSync(LAST_CONNECTED_DEVICE);
this.lastDevice = lastDevice
// 初始化蓝牙
this.openBluetoothAdapter()
},
}
</script>
1、初始化蓝牙
// 初始化蓝牙模块
openBluetoothAdapter() {
if (!uni.openBluetoothAdapter) {
uni.showModal({
title: this.$t('wechat.w102'), //'提示',
content: this.$t('wechat.w226') //'当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
return
}
uni.openBluetoothAdapter({
success: (res) => {
console.log('openBluetoothAdapter success', res)
// 搜寻附近的蓝牙
this.startBluetoothDevicesDiscovery()
},
fail: (res) => {
console.log('openBluetoothAdapter fail', res)
if (res.errCode === 10001) {
uni.showModal({
title: this.$t('wechat.w227'), //错误
content: this.$t('wechat.w228'), //'未找到蓝牙设备, 请打开蓝牙后重试。',
showCancel: false
})
// 监听蓝牙适配器状态变化事件
uni.onBluetoothAdapterStateChange((res) => {
console.log('onBluetoothAdapterStateChange', res)
// available:蓝牙适配器是否可用
if (res.available) {
// 取消监听,否则stopBluetoothDevicesDiscovery后仍会继续触发onBluetoothAdapterStateChange,
// 导致再次调用startBluetoothDevicesDiscovery
uni.onBluetoothAdapterStateChange(() => {});
// 开始搜寻附近的蓝牙外围设备
this.startBluetoothDevicesDiscovery()
}
})
}
}
})
uni.onBLEConnectionStateChange((res) => {
// 该方法回调中可以用于处理连接意外断开等异常情况
console.log('onBLEConnectionStateChange',
`device ${res.deviceId} state has changed, connected: ${res.connected}`)
this.connected = res.connected
if (!res.connected) {
uni.showModal({
title: this.$t('wechat.w227'), //错误
content: this.$t('wechat.w229'), //蓝牙连接已断开
showCancel: false
})
}
});
},
2.搜索附近蓝牙设备
// 开始搜寻附近的蓝牙外围设备
startBluetoothDevicesDiscovery() {
if (this._discoveryStarted) {
return
}
this._discoveryStarted = true
uni.startBluetoothDevicesDiscovery({
success: (res) => {
console.log('startBluetoothDevicesDiscovery success111', res)
// 监听寻找到新设备的事件
this.onBluetoothDeviceFound()
},
fail: (res) => {
console.log('startBluetoothDevicesDiscovery fail', res)
}
})
},
3.监听寻找到新设备的事件
// 监听寻找到新设备的事件
onBluetoothDeviceFound() {
uni.onBluetoothDeviceFound((res) => {
console.log('寻找设备', res)
res.devices.forEach(device => {
if (!device.name && !device.localName) {
return
}
const foundDevices = this.devices
const idx = inArray(foundDevices, 'deviceId', device.deviceId)
const data = {}
if (idx === -1) {
this.$set(this.devices, `${foundDevices.length}`, device)
} else {
this.$set(this.devices, `${idx}`, device)
}
// console.log(this.devices)
})
})
},
4.点击连接蓝牙
// 点击链接蓝牙
createBLEConnection(e) {
console.log('点击连接蓝牙', e)
const deviceId = e.deviceId
const name = e.name
this._createBLEConnection(deviceId, name)
},
// 连接蓝牙设备
_createBLEConnection(deviceId, name) {
this.$myToast(this.$t('wechat.w224'), 'loading') //连接设备中
// 连接低功耗蓝牙设备
uni.createBLEConnection({
deviceId, // 用于区分设备的 id
success: () => {
console.log('createBLEConnection success', this.devices);
this.devices.forEach((item, index) => {
this.$set(this.devices[index], 'isShowConnect', false)
if (item.deviceId == deviceId) {
this.$set(this.devices[index], 'isShowConnect', true)
}
})
this.$myToast(this.$t('wechat.w225'), 'success') //设备连接成功
this.connected = true
this.isConnected = false
this.name = name
this.deviceId = deviceId
//延迟1.5s获取设备的services
setTimeout(() => {
// 获取蓝牙设备所有服务(service)
this.getBLEDeviceServices(deviceId)
}, 3000);
// 最后连接设备
uni.setStorage({
key: LAST_CONNECTED_DEVICE,
data: name + ':' + deviceId
})
},
complete() {
uni.hideLoading()
},
fail: (res) => {
// 连接蓝牙接口调用失败
console.log('createBLEConnection fail', res)
}
})
// 已经找到需要的蓝牙设备,停止搜寻附近的蓝牙外围设备
this.stopBluetoothDevicesDiscovery()
},
// 已经找到需要的蓝牙设备,停止搜寻附近的蓝牙外围设备
stopBluetoothDevicesDiscovery() {
uni.stopBluetoothDevicesDiscovery({
complete: () => {
// console.log('stopBluetoothDevicesDiscovery')
this._discoveryStarted = false
}
})
},
5.获取蓝牙设备所有服务
// 获取蓝牙设备所有服务(service)
getBLEDeviceServices(deviceId) {
uni.getBLEDeviceServices({
deviceId,
success: (res) => {
console.log('获取蓝牙设备所有服务getBLEDeviceServices', res)
for (let i = 0; i < res.services.length; i++) {
// #ifdef MP-WEIXIN
if (res.services[i].isPrimary) {
this.getBLEDeviceCharacteristics(deviceId,res.services[i].uuid)
return
}
// #endif
// #ifdef APP-PLUS
if (res.services[i].uuid === '0000FF00-0000-1000-8000-00805F9B34FB') {
console.log('App的服务序号', res.services[i].uuid)
this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
return
}
// #endif
}
}
})
},
6.获取特征值
/*
获取蓝牙设备某个服务中所有特征值(characteristic)
characteristic:
uuid:蓝牙设备特征值的 uuid
properties:该特征值支持的操作类型
*/
getBLEDeviceCharacteristics(deviceId, serviceId) {
uni.getBLEDeviceCharacteristics({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId,
// 这里的 serviceId(蓝牙服务 uuid) 需要在 getBLEDeviceServices 接口中获取
serviceId,
success: (res) => {
console.log('特征值getBLEDeviceCharacteristics success', deviceId, serviceId, res, res
.characteristics)
// 这里会存在特征值是支持write,写入成功但是没有任何反应的情况
// 只能一个个去试
// characteristics:设备服务列表
for (let i = 0; i < res.characteristics.length; i++) {
const item = res.characteristics[i]
if (item.properties.write) {
this.canWrite = true
this._deviceId = deviceId
this._serviceId = serviceId
this._characteristicId = item.uuid
break;
}
}
},
fail(res) {
console.error('getBLEDeviceCharacteristics', res)
}
})
},
7.点击打印写入数据
// 点击打印:写入数据
writeBLECharacteristicValue() {
this.isLoading = true
setTimeout(() => {
this.isDisabled = false
this.isLoading = false
}, 3000)
let printerJobs = new PrinterJobs();
const {
channels,
header,
dataList
} = this.printInfo
console.log('通道数据', dataList)
let title = ''
header.forEach(item => {
title = `${item.name} `
})
// 要打印的头部信息
printerJobs
.setAlign('ct')
.setSize(2, 2)
.print(this.$t('wechat.w221')) //'记录报告'
.setSize(0, 0)
.print()
.setAlign('lt')
.setSize(1, 1)
.print(`${this.$t('wechat.w51')}:${this.info.name}`) //设备名称
.print(`${this.$t('wechat.w76')}:${this.info.modelName}`) //设备型号
.print(`${this.$t('wechat.w46')}:${this.info.deviceSerial}`) //序列号
.print(`${this.$t('wechat.w100')}:${this.userInfo.relName}`) //用户名
.print(`${this.$t('wechat.w101')}:${this.remark}`) //备注
if (this.isEn) {
channels.forEach(item => {
printerJobs.print(`${item.name}(Max):${item.max}${item.unitIcon}`)
.print(`${this.$t('wechat.w148')}:${this.$timestampToTimeEn(item.maxDate)}`) //时间
.print(`${item.name}(Min):${item.min}${item.unitIcon}`)
.print(`${this.$t('wechat.w148')}:${this.$timestampToTimeEn(item.minDate)}`) //时间
})
} else {
channels.forEach(item => {
printerJobs.print(`${item.name}(Max):${item.max}${item.unitIcon}`)
.print(`${this.$t('wechat.w148')}:${this.$timestampToTime2(item.maxDate)}`) //时间
.print(`${item.name}(Min):${item.min}${item.unitIcon}`)
.print(`${this.$t('wechat.w148')}:${this.$timestampToTime2(item.minDate)}`) //时间
})
}
printerJobs.print(printerUtil.fillLine())
.setSize(1, 1)
let titleStr = ''
header.forEach((item, index) => {
titleStr = titleStr + `${index==0?'':' '}` + `${item.name}`
})
printerJobs.print(printerUtil.inline(this.$t('wechat.w222'),
`${titleStr}`)) //记录时间
// 打印'----------------'
printerJobs.print(printerUtil.fillLine())
// 要打印的内容
dataList.forEach(item => {
let str = ''
header.forEach((item2, index2) => {
// 暂无
str = str + `${index2==0?'':' '}` +
`${item[item2.columnName]?item[item2.columnName].toFixed(2):this.$t('wechat.w71empty')}`
})
if (this.isEn) {
printerJobs.print(printerUtil.inline(`${this.$timestampToTimeEn2(item.dataTime)}`,
`${str}`))
} else {
printerJobs.print(printerUtil.inline(`${this.$timestampToTime3(item.dataTime)}`,
`${str}`))
}
// console.log(`${item.dataTime}`, str);
})
// 结尾
printerJobs.println()
.print(`${this.$t('wechat.w223')}:`) //'签名
.println()
.println()
let buffer = printerJobs.buffer();
// console.log('ArrayBuffer', 'length: ' + buffer.byteLength, ' hex: ' + ab2hex(buffer));
// 1.并行调用多次会存在写失败的可能性
// 2.建议每次写入不超过20字节
// 分包处理,延时调用
const maxChunk = 20;
const delay = 40;
for (let i = 0, j = 0, length = buffer.byteLength; i < length; i += maxChunk, j++) {
let subPackage = buffer.slice(i, i + maxChunk <= length ? (i + maxChunk) : length);
// subPackage:参数
setTimeout(this._writeBLECharacteristicValue, j * delay, subPackage);
}
},
// 向低功耗蓝牙设备特征值中写入二进制数据。注意:必须设备的特征值支持 write 才可以成功调用。
_writeBLECharacteristicValue(buffer) {
uni.writeBLECharacteristicValue({
deviceId: this._deviceId, // 蓝牙设备 id
serviceId: this._serviceId, // 蓝牙特征值对应服务的 uuid
characteristicId: this._characteristicId, // 蓝牙特征值的 uuid
value: buffer, // 蓝牙设备特征值对应的二进制值
success(res) {
console.log('writeBLECharacteristicValue success', res)
},
fail(res) {
console.log('writeBLECharacteristicValue fail', res)
}
})
},
8.离开关闭蓝牙
//关闭蓝牙
onUnload() {
this.closeBluetoothAdapter()
},
closeBluetoothAdapter() {
uni.closeBluetoothAdapter()
this._discoveryStarted = false
},