820 lines
23 KiB
JavaScript
820 lines
23 KiB
JavaScript
Page({
|
||
data: {
|
||
// 传感器数据
|
||
temperature: '--',
|
||
humidity: '--',
|
||
tvoc: '--',
|
||
co2: '--',
|
||
pm1: '--',
|
||
pm25: '--',
|
||
pm10: '--',
|
||
|
||
// 数据状态
|
||
temperatureStatus: 'normal',
|
||
humidityStatus: 'normal',
|
||
tvocStatus: 'normal',
|
||
co2Status: 'normal',
|
||
pmStatus: 'normal',
|
||
|
||
// 蓝牙连接状态
|
||
deviceId: '',
|
||
deviceName: '',
|
||
serviceId: '',
|
||
notifyCharId: '',
|
||
writeCharId: '',
|
||
connected: false,
|
||
refreshing: false,
|
||
lastConnectedTime: '',
|
||
|
||
// WiFi配置
|
||
showWifiModalFlag: false,
|
||
wifiName: '',
|
||
wifiPassword: '',
|
||
|
||
// 历史记录
|
||
showHistoryFlag: false,
|
||
historyData: []
|
||
},
|
||
|
||
/**
|
||
* 页面加载
|
||
*/
|
||
onLoad() {
|
||
console.log('页面加载完成')
|
||
// 初始化蓝牙监听器
|
||
this.initBLEListener()
|
||
// 启动自动刷新
|
||
this.startAutoRefresh()
|
||
// 加载历史数据
|
||
this.loadHistoryData()
|
||
// 记录系统日志
|
||
this.addLog('system', '页面加载完成,初始化蓝牙监听器')
|
||
},
|
||
|
||
/**
|
||
* 添加日志
|
||
* @param {string} type 日志类型:data或system
|
||
* @param {string} content 日志内容
|
||
* @param {string} details 日志详情
|
||
*/
|
||
addLog(type, content, details = '') {
|
||
const app = getApp()
|
||
app.globalData = app.globalData || {}
|
||
app.globalData.logs = app.globalData.logs || []
|
||
|
||
const log = {
|
||
time: this.getFormattedTime(),
|
||
type,
|
||
data: type === 'data' ? content : '',
|
||
message: type === 'system' ? content : '',
|
||
details
|
||
}
|
||
|
||
app.globalData.logs.unshift(log)
|
||
|
||
// 限制日志数量
|
||
if (app.globalData.logs.length > 100) {
|
||
app.globalData.logs = app.globalData.logs.slice(0, 100)
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 页面卸载
|
||
*/
|
||
onUnload() {
|
||
console.log('页面卸载')
|
||
// 移除蓝牙监听器
|
||
wx.offBLECharacteristicValueChange()
|
||
// 停止自动刷新
|
||
this.stopAutoRefresh()
|
||
// 断开蓝牙连接
|
||
this.disconnectBluetooth()
|
||
},
|
||
|
||
|
||
/**
|
||
* 初始化蓝牙数据接收监听器
|
||
*/
|
||
initBLEListener() {
|
||
console.log('========== 初始化蓝牙数据接收监听器 ==========')
|
||
|
||
// 移除之前的监听器,避免重复
|
||
console.log('移除之前的监听器')
|
||
wx.offBLECharacteristicValueChange()
|
||
|
||
// 设置新的监听器
|
||
console.log('设置新的蓝牙数据接收监听器')
|
||
const listener = (res) => {
|
||
console.log('========== 接收到蓝牙数据 ==========')
|
||
console.log('接收到蓝牙数据事件:', res)
|
||
|
||
// 检查数据是否存在
|
||
if (!res || !res.value) {
|
||
console.error('接收到的数据为空:', res)
|
||
return
|
||
}
|
||
|
||
// 处理接收到的数据
|
||
const data = new Uint8Array(res.value)
|
||
console.log('接收到的原始数据:', Array.from(data))
|
||
|
||
// 转换为十六进制字符串,便于调试
|
||
const hexString = Array.from(data).map(byte => byte.toString(16).padStart(2, '0')).join('')
|
||
console.log('接收到的十六进制数据:', hexString)
|
||
console.log('数据长度:', data.length)
|
||
|
||
// 立即记录所有蓝牙数据,无论格式是否正确
|
||
console.log('记录蓝牙数据到日志')
|
||
this.addLog('data', hexString, `长度: ${data.length}字节`)
|
||
|
||
// 解析传感器数据
|
||
console.log('解析传感器数据')
|
||
this.parseSensorData(data)
|
||
}
|
||
|
||
wx.onBLECharacteristicValueChange(listener)
|
||
|
||
console.log('蓝牙数据接收监听器初始化完成,等待数据...')
|
||
},
|
||
|
||
/**
|
||
* 解析传感器数据
|
||
* @param {Uint8Array} data 接收到的原始数据
|
||
*/
|
||
parseSensorData(data) {
|
||
console.log('解析传感器数据')
|
||
|
||
// 隐藏加载提示
|
||
wx.hideLoading()
|
||
this.setData({ refreshing: false })
|
||
|
||
// 转换为十六进制字符串,便于调试
|
||
const hexString = Array.from(data).map(byte => byte.toString(16).padStart(2, '0')).join('')
|
||
console.log('接收到的完整数据:', hexString)
|
||
console.log('数据长度:', data.length)
|
||
console.log('原始数据数组:', Array.from(data))
|
||
|
||
// 检查数据长度
|
||
if (data.length < 18) {
|
||
console.error('数据长度错误:', data.length, ',期望至少18字节')
|
||
wx.showToast({ title: `数据长度错误: ${data.length}字节`, icon: 'none' })
|
||
return
|
||
}
|
||
|
||
// 检查帧头
|
||
if (data[0] !== 0xAA || data[1] !== 0x55) {
|
||
console.error('数据格式错误,帧头不匹配:',
|
||
`0x${data[0].toString(16).padStart(2, '0')} 0x${data[1].toString(16).padStart(2, '0')}`,
|
||
',期望 AA 55'
|
||
)
|
||
wx.showToast({ title: '数据格式错误', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
try {
|
||
// 解析数据 - 根据用户提供的数据格式AA550000FF025B007801C20005000C000F00调整索引(小端模式)
|
||
// 数据格式:AA 55 00 00 FF 02 5B 00 78 01 C2 00 05 00 0C 00 0F 00
|
||
// 解析:温度=78 01 → 0178=376→37.6℃,湿度=C2 00→00C2=194→19.4%,TVOC=05 00=5,CO2=0C 00=12,PM1=0F 00=15
|
||
|
||
console.log('开始解析各传感器数据:')
|
||
|
||
// 温度数据解析
|
||
const tempRaw = (data[9] << 8) | data[8]
|
||
const temperature = tempRaw / 10
|
||
console.log(`温度原始值: 0x${tempRaw.toString(16).padStart(4, '0')} = ${tempRaw} → ${temperature}℃`)
|
||
|
||
// 湿度数据解析
|
||
const humRaw = (data[11] << 8) | data[10]
|
||
const humidity = humRaw / 10
|
||
console.log(`湿度原始值: 0x${humRaw.toString(16).padStart(4, '0')} = ${humRaw} → ${humidity}%`)
|
||
|
||
// TVOC数据解析
|
||
const tvoc = (data[13] << 8) | data[12]
|
||
console.log(`TVOC原始值: 0x${tvoc.toString(16).padStart(4, '0')} = ${tvoc}`)
|
||
|
||
// CO2数据解析
|
||
const co2 = (data[15] << 8) | data[14]
|
||
console.log(`CO2原始值: 0x${co2.toString(16).padStart(4, '0')} = ${co2}`)
|
||
|
||
// PM1数据解析
|
||
const pm1 = (data[17] << 8) | data[16]
|
||
console.log(`PM1原始值: 0x${pm1.toString(16).padStart(4, '0')} = ${pm1}`)
|
||
|
||
// 固定值
|
||
const pm25 = 0
|
||
const pm10 = 0
|
||
|
||
console.log('解析结果:', {
|
||
temperature,
|
||
humidity,
|
||
tvoc,
|
||
co2,
|
||
pm1,
|
||
pm25,
|
||
pm10
|
||
})
|
||
|
||
// 计算数据状态
|
||
const temperatureStatus = this.calculateStatus(temperature, 18, 26)
|
||
const humidityStatus = this.calculateStatus(humidity, 40, 60)
|
||
const tvocStatus = this.calculateStatus(tvoc, 0, 50)
|
||
const co2Status = this.calculateStatus(co2, 0, 1000)
|
||
const pmStatus = this.calculateStatus(pm1, 0, 35)
|
||
|
||
console.log('数据状态:', {
|
||
temperatureStatus,
|
||
humidityStatus,
|
||
tvocStatus,
|
||
co2Status,
|
||
pmStatus
|
||
})
|
||
|
||
// 更新页面数据
|
||
const newData = {
|
||
temperature: temperature.toFixed(1),
|
||
humidity: humidity.toFixed(1),
|
||
tvoc,
|
||
co2,
|
||
pm1,
|
||
pm25,
|
||
pm10,
|
||
temperatureStatus,
|
||
humidityStatus,
|
||
tvocStatus,
|
||
co2Status,
|
||
pmStatus
|
||
}
|
||
|
||
this.setData(newData)
|
||
console.log('页面数据更新成功')
|
||
|
||
// 保存历史数据
|
||
this.saveHistoryData(newData)
|
||
console.log('历史数据保存成功')
|
||
|
||
// 不显示解析成功提示,避免频繁弹窗干扰用户体验
|
||
// 只在控制台记录解析成功
|
||
console.log('数据解析成功,已更新到页面')
|
||
console.log('数据解析完成')
|
||
} catch (error) {
|
||
console.error('数据解析错误:', error)
|
||
console.error('错误堆栈:', error.stack)
|
||
wx.showToast({ title: `解析错误: ${error.message}`, icon: 'none' })
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 计算数据状态
|
||
* @param {number} value 数据值
|
||
* @param {number} min 正常最小值
|
||
* @param {number} max 正常最大值
|
||
* @returns {string} 状态
|
||
*/
|
||
calculateStatus(value, min, max) {
|
||
if (value < min || value > max) {
|
||
return 'warning'
|
||
}
|
||
return 'normal'
|
||
},
|
||
|
||
/**
|
||
* 手动刷新数据
|
||
*/
|
||
onRefresh() {
|
||
console.log('手动刷新数据')
|
||
|
||
// 检查蓝牙连接状态
|
||
if (!this.data.connected) {
|
||
console.warn('蓝牙未连接,无法刷新数据')
|
||
wx.showToast({ title: '请先连接蓝牙', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
// 检查蓝牙初始化状态
|
||
if (!this.data.writeCharId) {
|
||
console.warn('蓝牙初始化未完成,无法刷新数据')
|
||
wx.showToast({ title: '蓝牙初始化未完成', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
console.log('发送数据读取指令')
|
||
this.setData({ refreshing: true })
|
||
wx.showLoading({ title: '读取数据中...' })
|
||
this.sendReadCmd()
|
||
},
|
||
|
||
/**
|
||
* 发送读取数据指令
|
||
*/
|
||
sendReadCmd() {
|
||
console.log('开始发送读取数据指令')
|
||
|
||
// 构建读取指令
|
||
const cmd = new Uint8Array([0xA5, 0x01, 0x00, 0x5A])
|
||
console.log('发送的指令数据:', Array.from(cmd))
|
||
console.log('指令十六进制:', Array.from(cmd).map(byte => byte.toString(16).padStart(2, '0')).join(''))
|
||
|
||
// 发送指令
|
||
wx.writeBLECharacteristicValue({
|
||
deviceId: this.data.deviceId,
|
||
serviceId: this.data.serviceId,
|
||
characteristicId: this.data.writeCharId,
|
||
value: cmd.buffer,
|
||
success: (res) => {
|
||
console.log('发送指令成功:', res)
|
||
// 取消指令发送成功的提示,因为蓝牙模块会自动发送数据
|
||
},
|
||
fail: (err) => {
|
||
console.error('发送指令失败:', err)
|
||
wx.hideLoading()
|
||
this.setData({ refreshing: false })
|
||
wx.showToast({ title: '发送指令失败', icon: 'none' })
|
||
}
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 启动自动刷新(已移除,因为传感器主动上报数据)
|
||
*/
|
||
startAutoRefresh() {
|
||
console.log('传感器数据由设备主动上报,无需自动刷新')
|
||
},
|
||
|
||
/**
|
||
* 停止自动刷新
|
||
*/
|
||
stopAutoRefresh() {
|
||
console.log('停止自动刷新')
|
||
},
|
||
|
||
/**
|
||
* 跳转到蓝牙搜索页面
|
||
*/
|
||
connectBluetooth() {
|
||
console.log('准备跳转到蓝牙搜索页面')
|
||
|
||
wx.navigateTo({
|
||
url: '/pages/bluetooth/bluetooth',
|
||
success: () => {
|
||
console.log('跳转到蓝牙搜索页面成功')
|
||
},
|
||
fail: (err) => {
|
||
console.error('跳转到蓝牙搜索页面失败:', err)
|
||
wx.showToast({ title: '打开蓝牙搜索页面失败', icon: 'none' })
|
||
}
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 断开蓝牙连接
|
||
*/
|
||
disconnectBluetooth() {
|
||
if (!this.data.connected || !this.data.deviceId) {
|
||
return
|
||
}
|
||
|
||
console.log('断开蓝牙连接')
|
||
|
||
wx.closeBLEConnection({
|
||
deviceId: this.data.deviceId,
|
||
success: () => {
|
||
console.log('断开连接成功')
|
||
this.resetConnectionState()
|
||
wx.showToast({ title: '已断开连接', icon: 'success' })
|
||
},
|
||
fail: (err) => {
|
||
console.error('断开连接失败:', err)
|
||
this.resetConnectionState()
|
||
}
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 重置连接状态
|
||
*/
|
||
resetConnectionState() {
|
||
const app = getApp()
|
||
app.globalData.connectedDevice = null
|
||
|
||
this.setData({
|
||
deviceId: '',
|
||
deviceName: '',
|
||
serviceId: '',
|
||
notifyCharId: '',
|
||
writeCharId: '',
|
||
connected: false,
|
||
lastConnectedTime: '',
|
||
temperature: '--',
|
||
humidity: '--',
|
||
tvoc: '--',
|
||
co2: '--',
|
||
pm1: '--',
|
||
pm25: '--',
|
||
pm10: '--'
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 页面显示时检查连接状态
|
||
*/
|
||
onShow() {
|
||
console.log('========== 页面显示,检查连接状态 ==========')
|
||
|
||
// 获取全局数据
|
||
const app = getApp()
|
||
const connectedDevice = app.globalData.connectedDevice
|
||
|
||
// 检查是否有连接的设备
|
||
if (connectedDevice) {
|
||
console.log('检测到已连接的设备:', connectedDevice)
|
||
|
||
// 更新页面状态
|
||
this.setData({
|
||
deviceId: connectedDevice.deviceId,
|
||
deviceName: connectedDevice.name,
|
||
connected: true,
|
||
lastConnectedTime: this.getFormattedTime()
|
||
})
|
||
|
||
// 记录系统日志
|
||
this.addLog('system', `蓝牙设备已连接: ${connectedDevice.name}`, `设备ID: ${connectedDevice.deviceId}`)
|
||
|
||
// 先初始化监听器,确保能接收到数据
|
||
console.log('先初始化蓝牙监听器')
|
||
this.initBLEListener()
|
||
|
||
// 然后获取设备服务和特征值
|
||
console.log('然后获取设备服务和特征值')
|
||
this.getBLEServices()
|
||
} else {
|
||
console.log('未检测到已连接的设备')
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 获取格式化时间
|
||
* @returns {string} 格式化后的时间
|
||
*/
|
||
getFormattedTime() {
|
||
const now = new Date()
|
||
return now.toLocaleTimeString('zh-CN', {
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
second: '2-digit'
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 获取蓝牙设备服务
|
||
*/
|
||
getBLEServices() {
|
||
console.log('开始获取蓝牙设备服务')
|
||
console.log('设备ID:', this.data.deviceId)
|
||
|
||
wx.getBLEDeviceServices({
|
||
deviceId: this.data.deviceId,
|
||
success: (res) => {
|
||
console.log('获取设备服务成功,共找到', res.services.length, '个服务')
|
||
console.log('服务列表:', JSON.stringify(res.services))
|
||
|
||
// 检查服务数量
|
||
if (res.services.length === 0) {
|
||
console.error('未找到设备服务')
|
||
wx.showToast({ title: '未找到设备服务', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
// 遍历所有服务,打印详细信息
|
||
for (let i = 0; i < res.services.length; i++) {
|
||
console.log(`服务 ${i}:`, res.services[i].uuid, '是否为主服务:', res.services[i].isPrimary)
|
||
}
|
||
|
||
// 尝试每个服务,直到找到具有通知和写入特征的服务
|
||
// 优先尝试第二个服务,因为第一个服务可能不是数据服务
|
||
let serviceIndex = 1
|
||
let triedIndexes = new Set()
|
||
const tryNextService = () => {
|
||
if (triedIndexes.size >= res.services.length) {
|
||
console.error('所有服务都没有找到完整的特征值')
|
||
wx.showToast({ title: '未找到合适的服务', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
// 确保不重复尝试同一个服务
|
||
while (triedIndexes.has(serviceIndex)) {
|
||
serviceIndex = (serviceIndex + 1) % res.services.length
|
||
}
|
||
triedIndexes.add(serviceIndex)
|
||
|
||
const serviceId = res.services[serviceIndex].uuid
|
||
console.log(`尝试服务 ${serviceIndex}:`, serviceId)
|
||
|
||
// 获取当前服务的特征值
|
||
wx.getBLEDeviceCharacteristics({
|
||
deviceId: this.data.deviceId,
|
||
serviceId: serviceId,
|
||
success: (charRes) => {
|
||
console.log(`服务 ${serviceId} 的特征值:`, JSON.stringify(charRes.characteristics))
|
||
|
||
let hasNotify = false
|
||
let hasWrite = false
|
||
let notifyCharId = ''
|
||
let writeCharId = ''
|
||
|
||
for (const char of charRes.characteristics) {
|
||
if (char.properties.notify) {
|
||
hasNotify = true
|
||
notifyCharId = char.uuid
|
||
}
|
||
if (char.properties.write) {
|
||
hasWrite = true
|
||
writeCharId = char.uuid
|
||
}
|
||
}
|
||
|
||
if (hasNotify && hasWrite) {
|
||
console.log('========== 找到合适的服务 ==========')
|
||
console.log('找到合适的服务,同时具有通知和写入特征')
|
||
this.setData({
|
||
serviceId,
|
||
notifyCharId,
|
||
writeCharId
|
||
})
|
||
console.log('使用服务:', serviceId)
|
||
console.log('通知特征值:', notifyCharId)
|
||
console.log('写入特征值:', writeCharId)
|
||
|
||
// 记录系统日志
|
||
this.addLog('system', `使用蓝牙服务: ${serviceId}`, `通知特征: ${notifyCharId}, 写入特征: ${writeCharId}`)
|
||
|
||
// 再次确认监听器已设置
|
||
console.log('再次确认监听器已设置')
|
||
this.initBLEListener()
|
||
|
||
// 启用通知
|
||
console.log('准备启用通知')
|
||
this.enableNotification(notifyCharId)
|
||
} else {
|
||
console.log(`服务 ${serviceId} 缺少必要的特征值,通知:${hasNotify}, 写入:${hasWrite}`)
|
||
// 尝试下一个服务
|
||
tryNextService()
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error(`获取服务 ${serviceId} 的特征值失败:`, err)
|
||
// 尝试下一个服务
|
||
tryNextService()
|
||
}
|
||
})
|
||
}
|
||
|
||
// 开始尝试服务
|
||
tryNextService()
|
||
},
|
||
fail: (err) => {
|
||
console.error('获取服务失败:', err)
|
||
wx.showToast({ title: '获取服务失败', icon: 'none' })
|
||
// 记录系统日志
|
||
this.addLog('system', '获取蓝牙服务失败', err.errMsg)
|
||
}
|
||
})
|
||
},
|
||
|
||
|
||
|
||
/**
|
||
* 启用蓝牙通知
|
||
* @param {string} notifyCharId 通知特征值ID
|
||
*/
|
||
enableNotification(notifyCharId) {
|
||
console.log('========== 开始启用蓝牙通知 ==========')
|
||
console.log('设备ID:', this.data.deviceId)
|
||
console.log('服务ID:', this.data.serviceId)
|
||
console.log('通知特征值ID:', notifyCharId)
|
||
|
||
wx.notifyBLECharacteristicValueChange({
|
||
deviceId: this.data.deviceId,
|
||
serviceId: this.data.serviceId,
|
||
characteristicId: notifyCharId,
|
||
state: true,
|
||
success: (res) => {
|
||
console.log('========== 启用通知成功 ==========')
|
||
console.log('启用通知成功:', res)
|
||
wx.showToast({ title: '通知已启用,开始接收数据', icon: 'success' })
|
||
// 记录系统日志
|
||
this.addLog('system', '蓝牙通知已启用', `特征值: ${notifyCharId}`)
|
||
|
||
// 发送触发命令,让传感器开始发送数据
|
||
console.log('发送触发命令,让传感器开始发送数据')
|
||
wx.writeBLECharacteristicValue({
|
||
deviceId: this.data.deviceId,
|
||
serviceId: this.data.serviceId,
|
||
characteristicId: this.data.writeCharId,
|
||
value: new Uint8Array([0xA5, 0x01, 0x00, 0x5A]).buffer,
|
||
success: (res) => {
|
||
console.log('发送触发命令成功:', res)
|
||
wx.showToast({ title: '已触发数据发送', icon: 'success' })
|
||
},
|
||
fail: (err) => {
|
||
console.error('发送触发命令失败:', err)
|
||
wx.showToast({ title: '触发数据发送失败', icon: 'none' })
|
||
}
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.error('========== 启用通知失败 ==========')
|
||
console.error('启用通知失败:', err)
|
||
wx.showToast({ title: '启用通知失败', icon: 'none' })
|
||
// 记录系统日志
|
||
this.addLog('system', '蓝牙通知启用失败', err.errMsg)
|
||
}
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 显示WiFi配置模态框
|
||
*/
|
||
showWifiModal() {
|
||
console.log('显示WiFi配置模态框')
|
||
this.setData({ showWifiModalFlag: true })
|
||
},
|
||
|
||
/**
|
||
* 处理WiFi名称输入
|
||
* @param {Event} e 输入事件
|
||
*/
|
||
onWifiNameInput(e) {
|
||
this.setData({ wifiName: e.detail.value })
|
||
},
|
||
|
||
/**
|
||
* 处理WiFi密码输入
|
||
* @param {Event} e 输入事件
|
||
*/
|
||
onWifiPasswordInput(e) {
|
||
this.setData({ wifiPassword: e.detail.value })
|
||
},
|
||
|
||
/**
|
||
* 取消WiFi配置
|
||
*/
|
||
onWifiCancel() {
|
||
console.log('取消WiFi配置')
|
||
this.setData({
|
||
showWifiModalFlag: false,
|
||
wifiName: '',
|
||
wifiPassword: ''
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 确认WiFi配置
|
||
*/
|
||
onWifiConfirm() {
|
||
console.log('确认WiFi配置')
|
||
|
||
// 检查输入
|
||
if (!this.data.wifiName || !this.data.wifiPassword) {
|
||
console.warn('WiFi名称或密码为空')
|
||
wx.showToast({ title: 'WiFi名称和密码不能为空', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
console.log('发送WiFi配置信息')
|
||
wx.showLoading({ title: '发送WiFi信息...' })
|
||
|
||
// 构建WiFi配置指令
|
||
const wifiNameBytes = this.stringToUint8Array(this.data.wifiName)
|
||
const wifiPasswordBytes = this.stringToUint8Array(this.data.wifiPassword)
|
||
|
||
// 指令格式:0xAA 0x55 0x02 [name_length] [name_bytes] [password_length] [password_bytes]
|
||
const cmd = new Uint8Array([
|
||
0xAA, 0x55, 0x02,
|
||
wifiNameBytes.length,
|
||
...wifiNameBytes,
|
||
wifiPasswordBytes.length,
|
||
...wifiPasswordBytes
|
||
])
|
||
|
||
// 发送指令
|
||
wx.writeBLECharacteristicValue({
|
||
deviceId: this.data.deviceId,
|
||
serviceId: this.data.serviceId,
|
||
characteristicId: this.data.writeCharId,
|
||
value: cmd.buffer,
|
||
success: () => {
|
||
console.log('WiFi配置发送成功')
|
||
wx.hideLoading()
|
||
wx.showToast({ title: 'WiFi信息已发送', icon: 'success' })
|
||
this.setData({
|
||
showWifiModalFlag: false,
|
||
wifiName: '',
|
||
wifiPassword: ''
|
||
})
|
||
},
|
||
fail: (err) => {
|
||
console.error('WiFi配置发送失败:', err)
|
||
wx.hideLoading()
|
||
wx.showToast({ title: '发送失败', icon: 'none' })
|
||
}
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 显示历史记录
|
||
*/
|
||
showHistory() {
|
||
console.log('显示历史记录')
|
||
this.setData({ showHistoryFlag: true })
|
||
},
|
||
|
||
/**
|
||
* 隐藏历史记录
|
||
*/
|
||
hideHistory() {
|
||
console.log('隐藏历史记录')
|
||
this.setData({ showHistoryFlag: false })
|
||
},
|
||
|
||
/**
|
||
* 导航到日志页面
|
||
*/
|
||
navigateToLogs() {
|
||
console.log('导航到日志页面')
|
||
wx.navigateTo({
|
||
url: '/pages/logs/logs',
|
||
success: () => {
|
||
console.log('跳转到日志页面成功')
|
||
this.addLog('system', '导航到日志页面')
|
||
},
|
||
fail: (err) => {
|
||
console.error('跳转到日志页面失败:', err)
|
||
this.addLog('system', '导航到日志页面失败', err.errMsg)
|
||
}
|
||
})
|
||
},
|
||
|
||
/**
|
||
* 保存历史数据
|
||
* @param {Object} data 传感器数据
|
||
*/
|
||
saveHistoryData(data) {
|
||
try {
|
||
// 获取现有历史数据
|
||
let historyData = wx.getStorageSync('historyData') || []
|
||
|
||
// 添加新数据
|
||
const newRecord = {
|
||
time: this.getFormattedTime(),
|
||
temperature: data.temperature,
|
||
humidity: data.humidity,
|
||
tvoc: data.tvoc,
|
||
co2: data.co2,
|
||
pm1: data.pm1
|
||
}
|
||
|
||
historyData.unshift(newRecord)
|
||
|
||
// 限制历史记录数量
|
||
if (historyData.length > 50) {
|
||
historyData = historyData.slice(0, 50)
|
||
}
|
||
|
||
// 保存到本地存储
|
||
wx.setStorageSync('historyData', historyData)
|
||
|
||
// 更新页面数据
|
||
this.setData({ historyData })
|
||
} catch (error) {
|
||
console.error('保存历史数据失败:', error)
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 加载历史数据
|
||
*/
|
||
loadHistoryData() {
|
||
try {
|
||
const historyData = wx.getStorageSync('historyData') || []
|
||
this.setData({ historyData })
|
||
} catch (error) {
|
||
console.error('加载历史数据失败:', error)
|
||
this.setData({ historyData: [] })
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 将字符串转换为Uint8Array
|
||
* @param {string} str 要转换的字符串
|
||
* @returns {Array} 转换后的Uint8Array
|
||
*/
|
||
stringToUint8Array(str) {
|
||
// 在小程序环境中,TextEncoder不可用,使用兼容的字符串转换方法
|
||
const result = []
|
||
for (let i = 0; i < str.length; i++) {
|
||
result.push(str.charCodeAt(i))
|
||
}
|
||
return result
|
||
}
|
||
})
|