232 lines
5.8 KiB
JavaScript
232 lines
5.8 KiB
JavaScript
/**
|
|
* 扫描设备页面
|
|
*/
|
|
const ble = require('../../../services/ble.js');
|
|
const storage = require('../../../utils/storage.js');
|
|
const { gateway } = require('../../../services/gateway.js');
|
|
|
|
Page({
|
|
data: {
|
|
scanning: false,
|
|
scannedDevices: [],
|
|
statusText: '准备扫描',
|
|
statusHint: '点击下方按钮开始扫描 BLE 设备',
|
|
|
|
// 配置弹窗
|
|
showConfigModal: false,
|
|
configuring: false,
|
|
selectedDevice: null,
|
|
configForm: {
|
|
name: '',
|
|
serialNumber: '',
|
|
productId: '',
|
|
productSecret: '',
|
|
serviceUUID: '',
|
|
},
|
|
},
|
|
|
|
onLoad() {
|
|
// 暂停正在跑的网关,避免常驻会话与扫描/校验连接抢占同一 BLE 目标;
|
|
// 返回首页后 index.onShow → gateway.ensureStarted() 会自动恢复。
|
|
gateway.stop().then(() => this._initBluetooth());
|
|
},
|
|
|
|
onUnload() {
|
|
// 停止扫描
|
|
if (this.data.scanning) {
|
|
ble.bleService.stopScan();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 初始化蓝牙
|
|
*/
|
|
async _initBluetooth() {
|
|
try {
|
|
await ble.bleService.initBluetooth();
|
|
this.setData({
|
|
statusText: '蓝牙已就绪',
|
|
statusHint: '点击下方按钮开始扫描 BLE 设备',
|
|
});
|
|
} catch (err) {
|
|
console.error('[Scan] 初始化蓝牙失败:', err);
|
|
this.setData({
|
|
statusText: '蓝牙初始化失败',
|
|
statusHint: err.message || '请确保已开启蓝牙',
|
|
});
|
|
wx.showModal({
|
|
title: '蓝牙错误',
|
|
content: err.message || '请确保已开启蓝牙权限',
|
|
showCancel: false,
|
|
success: () => {
|
|
wx.navigateBack();
|
|
},
|
|
});
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 开始扫描
|
|
*/
|
|
async handleScan() {
|
|
if (this.data.scanning) return;
|
|
|
|
this.setData({
|
|
scanning: true,
|
|
scannedDevices: [],
|
|
statusText: '正在扫描...',
|
|
statusHint: '请确保设备已开机且在附近',
|
|
});
|
|
|
|
try {
|
|
const devices = await ble.bleService.scanDevices();
|
|
this.setData({
|
|
scanning: false,
|
|
scannedDevices: devices,
|
|
statusText: devices.length > 0 ? `发现 ${devices.length} 个设备` : '扫描完成',
|
|
statusHint: devices.length > 0 ? '点击设备进行连接配置' : '未发现设备,请确保设备已开机',
|
|
});
|
|
} catch (err) {
|
|
console.error('[Scan] 扫描失败:', err);
|
|
this.setData({
|
|
scanning: false,
|
|
statusText: '扫描失败',
|
|
statusHint: err.message || '请重试',
|
|
});
|
|
}
|
|
},
|
|
|
|
/**
|
|
* 停止扫描
|
|
*/
|
|
async handleStopScan() {
|
|
await ble.bleService.stopScan();
|
|
this.setData({
|
|
scanning: false,
|
|
statusText: '已停止扫描',
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 选择设备 - 显示配置弹窗
|
|
*/
|
|
handleSelectDevice(e) {
|
|
const index = e.currentTarget.dataset.index;
|
|
const device = this.data.scannedDevices[index];
|
|
if (!device) return;
|
|
|
|
this.setData({
|
|
selectedDevice: device,
|
|
showConfigModal: true,
|
|
configForm: {
|
|
name: device.name || '',
|
|
serialNumber: '',
|
|
productId: '',
|
|
productSecret: '',
|
|
serviceUUID: '',
|
|
},
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 配置输入
|
|
*/
|
|
onConfigInput(e) {
|
|
const field = e.currentTarget.dataset.field;
|
|
const value = e.detail.value;
|
|
this.setData({
|
|
[`configForm.${field}`]: value,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 取消配置
|
|
*/
|
|
handleCancelConfig() {
|
|
this.setData({
|
|
showConfigModal: false,
|
|
selectedDevice: null,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* 确认配置 - 连接设备并保存
|
|
*/
|
|
async handleConfirmConfig() {
|
|
const { selectedDevice, configForm } = this.data;
|
|
|
|
// 验证配置
|
|
if (!configForm.serialNumber) {
|
|
wx.showToast({ title: '请输入设备编号', icon: 'none' });
|
|
return;
|
|
}
|
|
if (!configForm.productId) {
|
|
wx.showToast({ title: '请输入产品ID', icon: 'none' });
|
|
return;
|
|
}
|
|
if (!configForm.productSecret) {
|
|
wx.showToast({ title: '请输入产品密钥', icon: 'none' });
|
|
return;
|
|
}
|
|
|
|
this.setData({ configuring: true });
|
|
|
|
try {
|
|
// 连接设备
|
|
wx.showLoading({ title: '正在连接...', mask: true });
|
|
|
|
const serviceId = configForm.serviceUUID || null;
|
|
await ble.bleService.connectDevice(selectedDevice.deviceId, serviceId);
|
|
|
|
wx.hideLoading();
|
|
|
|
// 保存设备配置
|
|
const deviceConfig = {
|
|
deviceId: selectedDevice.deviceId,
|
|
serialNumber: configForm.serialNumber,
|
|
name: configForm.name || selectedDevice.name || configForm.serialNumber,
|
|
productId: parseInt(configForm.productId),
|
|
productSecret: configForm.productSecret,
|
|
serviceUUID: configForm.serviceUUID,
|
|
bleName: selectedDevice.name,
|
|
RSSI: selectedDevice.RSSI,
|
|
enabled: true,
|
|
connected: true,
|
|
createTime: Date.now(),
|
|
};
|
|
|
|
storage.addDevice(deviceConfig);
|
|
// 新设备成为唯一启用(单 enabled 不变量,兼修历史多启用数据)
|
|
storage.activateDevice(deviceConfig.serialNumber);
|
|
|
|
wx.showToast({ title: '保存成功', icon: 'success' });
|
|
|
|
// 延迟返回(先断开连接再返回,让详情页重新连接)
|
|
setTimeout(async () => {
|
|
try {
|
|
await ble.bleService.disconnect();
|
|
} catch (e) {
|
|
console.warn('[Scan] 断开连接失败:', e);
|
|
}
|
|
this.setData({ showConfigModal: false });
|
|
wx.navigateBack();
|
|
}, 500);
|
|
|
|
} catch (err) {
|
|
wx.hideLoading();
|
|
console.error('[Scan] 连接失败:', err);
|
|
wx.showToast({
|
|
title: err.message || '连接失败',
|
|
icon: 'none',
|
|
});
|
|
// 连接失败时确保断开,避免残留连接
|
|
try {
|
|
await ble.bleService.disconnect();
|
|
} catch (e) {
|
|
console.warn('[Scan] 断开连接失败:', e);
|
|
}
|
|
} finally {
|
|
this.setData({ configuring: false });
|
|
}
|
|
},
|
|
}); |