fastbee/yack-mini/miniprogram/services/command-manager.js

179 lines
4.0 KiB
JavaScript
Raw Permalink 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.

/**
* 命令管理服务
*/
const { bleService } = require('./ble.js');
const cmdStorage = require('../utils/command-storage.js');
const { LIMITS } = require('../utils/constants.js');
class CommandManager {
constructor() {
this._lastSendTime = 0;
this._minSendInterval = 500; // 最小发送间隔(毫秒)
}
/**
* 发送命令(固定使用BLE)
* @param {string} hex - 十六进制命令
* @param {string} method - 发送方式:'BLE'(保留参数兼容性)
* @param {Object} device - 设备信息
* @param {Object} options - 可选参数
* @returns {Promise}
*/
async sendCommand(hex, method, device, options = {}) {
// 1. 验证命令格式
if (!this._validateHex(hex)) {
throw new Error('命令格式错误:必须是有效的十六进制字符串');
}
// 2. 发送频率限制
const now = Date.now();
if (now - this._lastSendTime < this._minSendInterval) {
throw new Error('发送频率过快,请稍后再试');
}
this._lastSendTime = now;
// 3. 使用BLE发送
let result;
try {
result = await this._sendViaBle(hex, device);
// 4. 记录发送历史
this._recordHistory(hex, 'BLE', device, 'success', options.name);
return result;
} catch (err) {
// 记录失败历史
this._recordHistory(hex, 'BLE', device, 'failed', options.name, err.message);
throw err;
}
}
/**
* 通过 BLE 发送
* @param {string} hex
* @param {Object} device
* @returns {Promise}
*/
async _sendViaBle(hex, device) {
// 检查 BLE 连接状态
if (!bleService.isReady()) {
throw new Error('BLE 未连接,请先连接设备');
}
// 检查是否连接的是目标设备
if (bleService.deviceId !== device.deviceId) {
throw new Error('BLE 连接的设备不匹配');
}
// 发送命令
await bleService.writeCommand(hex);
return {
success: true,
method: 'BLE',
message: 'BLE 发送成功',
};
}
/**
* 验证十六进制格式
* @param {string} hex
* @returns {boolean}
*/
_validateHex(hex) {
if (!hex || typeof hex !== 'string') {
return false;
}
// 移除空格
hex = hex.replace(/\s+/g, '');
// 检查是否只包含 0-9, A-F, a-f
return /^[0-9A-Fa-f]+$/.test(hex) && hex.length % 2 === 0;
}
/**
* 记录发送历史
*/
_recordHistory(hex, method, device, status, name, error) {
cmdStorage.addHistory({
hex,
method,
deviceId: device.serialNumber,
deviceName: device.name,
name: name || '自定义命令',
status,
error: error || null,
});
}
/**
* 获取预设命令列表
* @param {string} deviceId
* @returns {Array}
*/
getCommands(deviceId) {
return cmdStorage.getCommands(deviceId);
}
/**
* 添加预设命令
* @param {Object} command
* @returns {boolean}
*/
addCommand(command) {
return cmdStorage.addCommand(command);
}
/**
* 更新预设命令
* @param {Object} command
* @returns {boolean}
*/
updateCommand(command) {
return cmdStorage.updateCommand(command);
}
/**
* 删除预设命令
* @param {string} id
*/
removeCommand(id) {
cmdStorage.removeCommand(id);
}
/**
* 获取发送历史(只返回当天的)
* @param {string} deviceId
* @returns {Array}
*/
getHistory(deviceId) {
return cmdStorage.getHistory(deviceId);
}
/**
* 清空发送历史
*/
clearHistory() {
cmdStorage.clearHistory();
}
/**
* 更新命令使用次数
* @param {string} id
*/
incrementUseCount(id) {
const commands = cmdStorage.getCommands();
const command = commands.find(c => c.id === id);
if (command) {
command.useCount = (command.useCount || 0) + 1;
command.lastUsedTime = Date.now();
cmdStorage.saveCommands(commands);
}
}
}
// 导出单例
const commandManager = new CommandManager();
module.exports = {
CommandManager,
commandManager,
};