1202 lines
43 KiB
Python
1202 lines
43 KiB
Python
"""
|
||
命令处理器模块
|
||
负责处理语音命令并执行相应操作
|
||
"""
|
||
|
||
import time
|
||
import re
|
||
from typing import Dict, Any, List, Optional, Callable
|
||
import threading
|
||
|
||
class CommandProcessor:
|
||
"""
|
||
命令处理器
|
||
负责处理语音命令并执行相应操作
|
||
"""
|
||
|
||
def __init__(self, plugin):
|
||
"""
|
||
初始化命令处理器
|
||
|
||
Args:
|
||
plugin: 语音控制插件实例
|
||
"""
|
||
self.plugin = plugin
|
||
self.enabled = False
|
||
self.initialized = False
|
||
|
||
# 命令映射
|
||
self.command_mappings = {}
|
||
|
||
# 命令组
|
||
self.command_groups = {}
|
||
|
||
# 命令历史
|
||
self.command_history = []
|
||
self.max_history_size = 1000
|
||
|
||
# 命令配置
|
||
self.command_config = {
|
||
'enable_fuzzy_matching': True,
|
||
'fuzzy_threshold': 0.7,
|
||
'enable_context_commands': True,
|
||
'context_timeout': 30.0,
|
||
'enable_chained_commands': True,
|
||
'max_chain_length': 5,
|
||
'enable_confirmation': True,
|
||
'confirmation_threshold': 0.9
|
||
}
|
||
|
||
# 上下文管理
|
||
self.command_context = {
|
||
'current_context': 'default',
|
||
'context_stack': [],
|
||
'context_start_time': 0.0,
|
||
'context_variables': {}
|
||
}
|
||
|
||
# 命令链
|
||
self.command_chain = {
|
||
'is_active': False,
|
||
'commands': [],
|
||
'chain_start_time': 0.0
|
||
}
|
||
|
||
# 统计信息
|
||
self.stats = {
|
||
'commands_processed': 0,
|
||
'commands_executed': 0,
|
||
'commands_failed': 0,
|
||
'fuzzy_matches': 0,
|
||
'exact_matches': 0,
|
||
'context_commands': 0,
|
||
'chained_commands': 0
|
||
}
|
||
|
||
# 回调函数
|
||
self.command_callbacks = {
|
||
'command_received': [],
|
||
'command_processed': [],
|
||
'command_executed': [],
|
||
'command_failed': [],
|
||
'context_changed': [],
|
||
'chain_started': [],
|
||
'chain_completed': []
|
||
}
|
||
|
||
# 时间戳记录
|
||
self.last_command_time = 0.0
|
||
self.last_context_change = 0.0
|
||
|
||
print("✓ 命令处理器已创建")
|
||
|
||
def initialize(self) -> bool:
|
||
"""
|
||
初始化命令处理器
|
||
|
||
Returns:
|
||
是否初始化成功
|
||
"""
|
||
try:
|
||
# 初始化默认命令映射
|
||
self._initialize_default_commands()
|
||
|
||
# 初始化命令组
|
||
self._initialize_command_groups()
|
||
|
||
self.initialized = True
|
||
print("✓ 命令处理器初始化完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令处理器初始化失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def enable(self) -> bool:
|
||
"""
|
||
启用命令处理器
|
||
|
||
Returns:
|
||
是否启用成功
|
||
"""
|
||
try:
|
||
if not self.initialized:
|
||
print("✗ 命令处理器未初始化")
|
||
return False
|
||
|
||
self.enabled = True
|
||
print("✓ 命令处理器已启用")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令处理器启用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def disable(self):
|
||
"""禁用命令处理器"""
|
||
try:
|
||
self.enabled = False
|
||
print("✓ 命令处理器已禁用")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令处理器禁用失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def finalize(self):
|
||
"""清理命令处理器资源"""
|
||
try:
|
||
self.disable()
|
||
self.command_mappings.clear()
|
||
self.command_groups.clear()
|
||
self.command_history.clear()
|
||
self.command_callbacks.clear()
|
||
self.initialized = False
|
||
print("✓ 命令处理器资源已清理")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令处理器资源清理失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def update(self, dt: float):
|
||
"""
|
||
更新命令处理器状态
|
||
|
||
Args:
|
||
dt: 时间增量
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
return
|
||
|
||
current_time = time.time()
|
||
self.last_command_time = current_time
|
||
|
||
# 检查上下文超时
|
||
self._check_context_timeout(current_time)
|
||
|
||
# 检查命令链超时
|
||
self._check_chain_timeout(current_time)
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令处理器更新失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def _initialize_default_commands(self):
|
||
"""初始化默认命令映射"""
|
||
try:
|
||
# 基础移动命令
|
||
self.register_command('前进', self._move_forward, 'movement', '向前移动')
|
||
self.register_command('后退', self._move_backward, 'movement', '向后移动')
|
||
self.register_command('左转', self._turn_left, 'movement', '向左转')
|
||
self.register_command('右转', self._turn_right, 'movement', '向右转')
|
||
self.register_command('停止', self._stop_movement, 'movement', '停止移动')
|
||
|
||
# 系统控制命令
|
||
self.register_command('打开灯光', self._toggle_lights, 'system', '切换灯光状态')
|
||
self.register_command('关闭灯光', self._toggle_lights, 'system', '切换灯光状态')
|
||
self.register_command('增加音量', self._increase_volume, 'system', '增加系统音量')
|
||
self.register_command('减少音量', self._decrease_volume, 'system', '减少系统音量')
|
||
self.register_command('播放音乐', self._play_music, 'entertainment', '播放音乐')
|
||
self.register_command('暂停播放', self._pause_music, 'entertainment', '暂停音乐播放')
|
||
self.register_command('下一首', self._next_track, 'entertainment', '播放下一首')
|
||
self.register_command('上一首', self._previous_track, 'entertainment', '播放上一首')
|
||
|
||
# 交互命令
|
||
self.register_command('你好', self._greet_user, 'interaction', '打招呼')
|
||
self.register_command('谢谢', self._acknowledge_thanks, 'interaction', '回应感谢')
|
||
self.register_command('再见', self._say_goodbye, 'interaction', '道别')
|
||
self.register_command('帮助', self._provide_help, 'interaction', '提供帮助信息')
|
||
self.register_command('关于', self._show_about, 'interaction', '显示系统信息')
|
||
|
||
print("✓ 默认命令映射初始化完成")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 默认命令映射初始化失败: {e}")
|
||
|
||
def _initialize_command_groups(self):
|
||
"""初始化命令组"""
|
||
try:
|
||
self.command_groups = {
|
||
'movement': {
|
||
'name': '移动控制',
|
||
'description': '控制物体移动的命令',
|
||
'commands': ['前进', '后退', '左转', '右转', '停止']
|
||
},
|
||
'system': {
|
||
'name': '系统控制',
|
||
'description': '控制系统功能的命令',
|
||
'commands': ['打开灯光', '关闭灯光', '增加音量', '减少音量']
|
||
},
|
||
'entertainment': {
|
||
'name': '娱乐控制',
|
||
'description': '控制娱乐功能的命令',
|
||
'commands': ['播放音乐', '暂停播放', '下一首', '上一首']
|
||
},
|
||
'interaction': {
|
||
'name': '交互命令',
|
||
'description': '日常交互的命令',
|
||
'commands': ['你好', '谢谢', '再见', '帮助', '关于']
|
||
}
|
||
}
|
||
|
||
print("✓ 命令组初始化完成")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令组初始化失败: {e}")
|
||
|
||
def register_command(self, command_text: str, handler: Callable,
|
||
group: str = 'default', description: str = '') -> bool:
|
||
"""
|
||
注册命令
|
||
|
||
Args:
|
||
command_text: 命令文本
|
||
handler: 命令处理函数
|
||
group: 命令组
|
||
description: 命令描述
|
||
|
||
Returns:
|
||
是否注册成功
|
||
"""
|
||
try:
|
||
self.command_mappings[command_text] = {
|
||
'handler': handler,
|
||
'group': group,
|
||
'description': description,
|
||
'registered_time': time.time()
|
||
}
|
||
|
||
# 添加到命令组
|
||
if group in self.command_groups:
|
||
if command_text not in self.command_groups[group]['commands']:
|
||
self.command_groups[group]['commands'].append(command_text)
|
||
else:
|
||
self.command_groups[group] = {
|
||
'name': group,
|
||
'description': f'命令组: {group}',
|
||
'commands': [command_text]
|
||
}
|
||
|
||
print(f"✓ 命令已注册: {command_text}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令注册失败: {e}")
|
||
return False
|
||
|
||
def unregister_command(self, command_text: str) -> bool:
|
||
"""
|
||
注销命令
|
||
|
||
Args:
|
||
command_text: 命令文本
|
||
|
||
Returns:
|
||
是否注销成功
|
||
"""
|
||
try:
|
||
if command_text in self.command_mappings:
|
||
command_info = self.command_mappings[command_text]
|
||
group = command_info['group']
|
||
|
||
# 从命令组中移除
|
||
if group in self.command_groups:
|
||
if command_text in self.command_groups[group]['commands']:
|
||
self.command_groups[group]['commands'].remove(command_text)
|
||
|
||
del self.command_mappings[command_text]
|
||
print(f"✓ 命令已注销: {command_text}")
|
||
return True
|
||
else:
|
||
print(f"✗ 命令不存在: {command_text}")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令注销失败: {e}")
|
||
return False
|
||
|
||
def process_command(self, text: str, confidence: float = 1.0) -> bool:
|
||
"""
|
||
处理语音命令
|
||
|
||
Args:
|
||
text: 命令文本
|
||
confidence: 置信度(0.0-1.0)
|
||
|
||
Returns:
|
||
是否处理成功
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
print("✗ 命令处理器未启用")
|
||
return False
|
||
|
||
# 记录命令历史
|
||
command_entry = {
|
||
'text': text,
|
||
'confidence': confidence,
|
||
'timestamp': time.time(),
|
||
'context': self.command_context['current_context']
|
||
}
|
||
|
||
self.command_history.append(command_entry)
|
||
|
||
# 保持历史记录大小
|
||
if len(self.command_history) > self.max_history_size:
|
||
self.command_history.pop(0)
|
||
|
||
# 触发命令接收回调
|
||
self._trigger_command_callback('command_received', {
|
||
'text': text,
|
||
'confidence': confidence,
|
||
'command_entry': command_entry
|
||
})
|
||
|
||
# 检查是否在命令链中
|
||
if self.command_chain['is_active']:
|
||
return self._process_chained_command(text, confidence)
|
||
|
||
# 查找匹配的命令
|
||
matched_command = self._find_matching_command(text, confidence)
|
||
|
||
if matched_command:
|
||
command_text = matched_command['command']
|
||
command_info = self.command_mappings[command_text]
|
||
handler = command_info['handler']
|
||
|
||
# 更新统计信息
|
||
if matched_command['type'] == 'exact':
|
||
self.stats['exact_matches'] += 1
|
||
else:
|
||
self.stats['fuzzy_matches'] += 1
|
||
|
||
# 检查是否需要确认
|
||
if (self.command_config['enable_confirmation'] and
|
||
confidence < self.command_config['confirmation_threshold']):
|
||
return self._request_confirmation(text, command_text, handler, confidence)
|
||
|
||
# 执行命令
|
||
return self._execute_command(command_text, handler, text, confidence, matched_command)
|
||
else:
|
||
# 未找到匹配命令
|
||
print(f"✗ 未找到匹配命令: {text}")
|
||
self.stats['commands_failed'] += 1
|
||
|
||
# 触发命令失败回调
|
||
self._trigger_command_callback('command_failed', {
|
||
'text': text,
|
||
'confidence': confidence,
|
||
'reason': 'no_match'
|
||
})
|
||
|
||
# 请求帮助
|
||
if self._is_help_request(text):
|
||
self._provide_help()
|
||
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令处理失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
self.stats['commands_failed'] += 1
|
||
return False
|
||
|
||
def _find_matching_command(self, text: str, confidence: float) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
查找匹配的命令
|
||
|
||
Args:
|
||
text: 命令文本
|
||
confidence: 置信度
|
||
|
||
Returns:
|
||
匹配的命令信息或None
|
||
"""
|
||
try:
|
||
# 首先尝试精确匹配
|
||
if text in self.command_mappings:
|
||
return {
|
||
'command': text,
|
||
'type': 'exact',
|
||
'confidence': confidence
|
||
}
|
||
|
||
# 尝试上下文命令
|
||
if (self.command_config['enable_context_commands'] and
|
||
self.command_context['current_context'] != 'default'):
|
||
context_commands = self.command_context['context_variables'].get('commands', [])
|
||
for command in context_commands:
|
||
if command in self.command_mappings and text in command:
|
||
return {
|
||
'command': command,
|
||
'type': 'context',
|
||
'confidence': confidence * 0.9
|
||
}
|
||
self.stats['context_commands'] += 1
|
||
|
||
# 尝试模糊匹配
|
||
if self.command_config['enable_fuzzy_matching']:
|
||
best_match = self._fuzzy_match_command(text)
|
||
if best_match:
|
||
return best_match
|
||
|
||
return None
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令匹配失败: {e}")
|
||
return None
|
||
|
||
def _fuzzy_match_command(self, text: str) -> Optional[Dict[str, Any]]:
|
||
"""
|
||
模糊匹配命令
|
||
|
||
Args:
|
||
text: 命令文本
|
||
|
||
Returns:
|
||
匹配的命令信息或None
|
||
"""
|
||
try:
|
||
best_match = None
|
||
best_score = 0.0
|
||
|
||
for command_text in self.command_mappings:
|
||
score = self._calculate_similarity(text, command_text)
|
||
if score > best_score and score >= self.command_config['fuzzy_threshold']:
|
||
best_score = score
|
||
best_match = {
|
||
'command': command_text,
|
||
'type': 'fuzzy',
|
||
'confidence': score
|
||
}
|
||
|
||
return best_match
|
||
|
||
except Exception as e:
|
||
print(f"✗ 模糊匹配失败: {e}")
|
||
return None
|
||
|
||
def _calculate_similarity(self, text1: str, text2: str) -> float:
|
||
"""
|
||
计算文本相似度
|
||
|
||
Args:
|
||
text1: 文本1
|
||
text2: 文本2
|
||
|
||
Returns:
|
||
相似度(0.0-1.0)
|
||
"""
|
||
try:
|
||
# 简单的相似度计算(实际应用中可以使用更复杂的算法)
|
||
set1 = set(text1)
|
||
set2 = set(text2)
|
||
|
||
intersection = len(set1.intersection(set2))
|
||
union = len(set1.union(set2))
|
||
|
||
if union == 0:
|
||
return 0.0
|
||
|
||
return intersection / union
|
||
|
||
except Exception as e:
|
||
print(f"✗ 相似度计算失败: {e}")
|
||
return 0.0
|
||
|
||
def _process_chained_command(self, text: str, confidence: float) -> bool:
|
||
"""
|
||
处理命令链中的命令
|
||
|
||
Args:
|
||
text: 命令文本
|
||
confidence: 置信度
|
||
|
||
Returns:
|
||
是否处理成功
|
||
"""
|
||
try:
|
||
# 添加到命令链
|
||
self.command_chain['commands'].append({
|
||
'text': text,
|
||
'confidence': confidence,
|
||
'timestamp': time.time()
|
||
})
|
||
|
||
# 检查是否完成命令链
|
||
if self._is_chain_completion(text):
|
||
return self._execute_command_chain()
|
||
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令链处理失败: {e}")
|
||
return False
|
||
|
||
def _is_chain_completion(self, text: str) -> bool:
|
||
"""
|
||
检查是否完成命令链
|
||
|
||
Args:
|
||
text: 命令文本
|
||
|
||
Returns:
|
||
是否完成命令链
|
||
"""
|
||
try:
|
||
completion_keywords = ['完成', '结束', '执行', '确定', '确认']
|
||
return any(keyword in text for keyword in completion_keywords)
|
||
except Exception as e:
|
||
print(f"✗ 命令链完成检查失败: {e}")
|
||
return False
|
||
|
||
def _execute_command_chain(self) -> bool:
|
||
"""
|
||
执行命令链
|
||
|
||
Returns:
|
||
是否执行成功
|
||
"""
|
||
try:
|
||
# 触发命令链完成回调
|
||
self._trigger_command_callback('chain_completed', {
|
||
'commands': self.command_chain['commands']
|
||
})
|
||
|
||
# 重置命令链
|
||
self.command_chain['is_active'] = False
|
||
self.command_chain['commands'] = []
|
||
self.command_chain['chain_start_time'] = 0.0
|
||
|
||
self.stats['chained_commands'] += 1
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令链执行失败: {e}")
|
||
return False
|
||
|
||
def _request_confirmation(self, original_text: str, command_text: str,
|
||
handler: Callable, confidence: float) -> bool:
|
||
"""
|
||
请求命令确认
|
||
|
||
Args:
|
||
original_text: 原始文本
|
||
command_text: 命令文本
|
||
handler: 处理函数
|
||
confidence: 置信度
|
||
|
||
Returns:
|
||
是否请求成功
|
||
"""
|
||
try:
|
||
confirmation_text = f"您是想执行 {command_text} 吗?请确认。"
|
||
|
||
# 通过语音合成器播放确认请求
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech(confirmation_text)
|
||
|
||
# 存储待确认的命令
|
||
self.pending_confirmation = {
|
||
'original_text': original_text,
|
||
'command_text': command_text,
|
||
'handler': handler,
|
||
'confidence': confidence,
|
||
'timestamp': time.time()
|
||
}
|
||
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 确认请求失败: {e}")
|
||
return False
|
||
|
||
def _execute_command(self, command_text: str, handler: Callable,
|
||
original_text: str, confidence: float,
|
||
match_info: Dict[str, Any]) -> bool:
|
||
"""
|
||
执行命令
|
||
|
||
Args:
|
||
command_text: 命令文本
|
||
handler: 处理函数
|
||
original_text: 原始文本
|
||
confidence: 置信度
|
||
match_info: 匹配信息
|
||
|
||
Returns:
|
||
是否执行成功
|
||
"""
|
||
try:
|
||
# 触发命令处理回调
|
||
self._trigger_command_callback('command_processed', {
|
||
'command_text': command_text,
|
||
'original_text': original_text,
|
||
'confidence': confidence,
|
||
'match_type': match_info['type']
|
||
})
|
||
|
||
# 执行命令处理函数
|
||
result = handler(original_text, confidence)
|
||
|
||
if result:
|
||
self.stats['commands_executed'] += 1
|
||
|
||
# 触发命令执行回调
|
||
self._trigger_command_callback('command_executed', {
|
||
'command_text': command_text,
|
||
'original_text': original_text,
|
||
'confidence': confidence
|
||
})
|
||
|
||
# 检查是否需要进入特定上下文
|
||
self._check_context_transition(command_text)
|
||
|
||
print(f"✓ 命令执行成功: {command_text}")
|
||
return True
|
||
else:
|
||
self.stats['commands_failed'] += 1
|
||
|
||
# 触发命令失败回调
|
||
self._trigger_command_callback('command_failed', {
|
||
'command_text': command_text,
|
||
'original_text': original_text,
|
||
'confidence': confidence,
|
||
'reason': 'execution_failed'
|
||
})
|
||
|
||
print(f"✗ 命令执行失败: {command_text}")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令执行异常: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
self.stats['commands_failed'] += 1
|
||
|
||
# 触发命令失败回调
|
||
self._trigger_command_callback('command_failed', {
|
||
'command_text': command_text,
|
||
'original_text': original_text,
|
||
'confidence': confidence,
|
||
'reason': 'exception',
|
||
'exception': str(e)
|
||
})
|
||
|
||
return False
|
||
|
||
def _check_context_transition(self, command_text: str):
|
||
"""
|
||
检查上下文转换
|
||
|
||
Args:
|
||
command_text: 命令文本
|
||
"""
|
||
try:
|
||
# 根据命令类型设置上下文
|
||
context_transitions = {
|
||
'播放音乐': 'music',
|
||
'暂停播放': 'music',
|
||
'下一首': 'music',
|
||
'上一首': 'music'
|
||
}
|
||
|
||
if command_text in context_transitions:
|
||
self.set_context(context_transitions[command_text])
|
||
|
||
except Exception as e:
|
||
print(f"✗ 上下文转换检查失败: {e}")
|
||
|
||
def _check_context_timeout(self, current_time: float):
|
||
"""
|
||
检查上下文超时
|
||
|
||
Args:
|
||
current_time: 当前时间
|
||
"""
|
||
try:
|
||
if (self.command_context['current_context'] != 'default' and
|
||
current_time - self.command_context['context_start_time'] >
|
||
self.command_config['context_timeout']):
|
||
self.reset_context()
|
||
|
||
except Exception as e:
|
||
print(f"✗ 上下文超时检查失败: {e}")
|
||
|
||
def _check_chain_timeout(self, current_time: float):
|
||
"""
|
||
检查命令链超时
|
||
|
||
Args:
|
||
current_time: 当前时间
|
||
"""
|
||
try:
|
||
if (self.command_chain['is_active'] and
|
||
current_time - self.command_chain['chain_start_time'] > 10.0): # 10秒超时
|
||
self.command_chain['is_active'] = False
|
||
self.command_chain['commands'] = []
|
||
self.command_chain['chain_start_time'] = 0.0
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令链超时检查失败: {e}")
|
||
|
||
def set_context(self, context_name: str, variables: Dict[str, Any] = None) -> bool:
|
||
"""
|
||
设置命令上下文
|
||
|
||
Args:
|
||
context_name: 上下文名称
|
||
variables: 上下文变量
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
try:
|
||
# 保存当前上下文到栈中
|
||
self.command_context['context_stack'].append({
|
||
'context': self.command_context['current_context'],
|
||
'variables': self.command_context['context_variables'].copy(),
|
||
'timestamp': self.command_context['context_start_time']
|
||
})
|
||
|
||
# 设置新上下文
|
||
self.command_context['current_context'] = context_name
|
||
self.command_context['context_start_time'] = time.time()
|
||
if variables:
|
||
self.command_context['context_variables'] = variables
|
||
else:
|
||
self.command_context['context_variables'] = {}
|
||
|
||
# 触发上下文变更回调
|
||
self._trigger_command_callback('context_changed', {
|
||
'old_context': self.command_context['context_stack'][-1]['context'] if self.command_context['context_stack'] else 'default',
|
||
'new_context': context_name,
|
||
'variables': variables
|
||
})
|
||
|
||
self.last_context_change = time.time()
|
||
print(f"✓ 上下文已设置为: {context_name}")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 上下文设置失败: {e}")
|
||
return False
|
||
|
||
def reset_context(self) -> bool:
|
||
"""
|
||
重置命令上下文
|
||
|
||
Returns:
|
||
是否重置成功
|
||
"""
|
||
try:
|
||
if self.command_context['context_stack']:
|
||
# 恢复上一个上下文
|
||
previous_context = self.command_context['context_stack'].pop()
|
||
self.command_context['current_context'] = previous_context['context']
|
||
self.command_context['context_variables'] = previous_context['variables']
|
||
self.command_context['context_start_time'] = previous_context['timestamp']
|
||
else:
|
||
# 重置为默认上下文
|
||
self.command_context['current_context'] = 'default'
|
||
self.command_context['context_variables'] = {}
|
||
self.command_context['context_start_time'] = time.time()
|
||
|
||
# 触发上下文变更回调
|
||
self._trigger_command_callback('context_changed', {
|
||
'old_context': 'previous',
|
||
'new_context': self.command_context['current_context'],
|
||
'variables': self.command_context['context_variables']
|
||
})
|
||
|
||
print("✓ 上下文已重置")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 上下文重置失败: {e}")
|
||
return False
|
||
|
||
def start_command_chain(self) -> bool:
|
||
"""
|
||
开始命令链
|
||
|
||
Returns:
|
||
是否开始成功
|
||
"""
|
||
try:
|
||
self.command_chain['is_active'] = True
|
||
self.command_chain['commands'] = []
|
||
self.command_chain['chain_start_time'] = time.time()
|
||
|
||
# 触发命令链开始回调
|
||
self._trigger_command_callback('chain_started', {})
|
||
|
||
print("✓ 命令链已开始")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 命令链开始失败: {e}")
|
||
return False
|
||
|
||
def _is_help_request(self, text: str) -> bool:
|
||
"""
|
||
检查是否为帮助请求
|
||
|
||
Args:
|
||
text: 文本
|
||
|
||
Returns:
|
||
是否为帮助请求
|
||
"""
|
||
try:
|
||
help_keywords = ['帮助', 'help', '怎么用', '使用方法', '功能']
|
||
return any(keyword in text for keyword in help_keywords)
|
||
except Exception as e:
|
||
print(f"✗ 帮助请求检查失败: {e}")
|
||
return False
|
||
|
||
# 默认命令处理函数
|
||
def _move_forward(self, text: str, confidence: float) -> bool:
|
||
"""向前移动"""
|
||
try:
|
||
print("→ 执行向前移动命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("正在向前移动")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 向前移动命令执行失败: {e}")
|
||
return False
|
||
|
||
def _move_backward(self, text: str, confidence: float) -> bool:
|
||
"""向后移动"""
|
||
try:
|
||
print("← 执行向后移动命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("正在向后移动")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 向后移动命令执行失败: {e}")
|
||
return False
|
||
|
||
def _turn_left(self, text: str, confidence: float) -> bool:
|
||
"""向左转"""
|
||
try:
|
||
print("↺ 执行向左转命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("正在向左转")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 向左转命令执行失败: {e}")
|
||
return False
|
||
|
||
def _turn_right(self, text: str, confidence: float) -> bool:
|
||
"""向右转"""
|
||
try:
|
||
print("↻ 执行向右转命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("正在向右转")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 向右转命令执行失败: {e}")
|
||
return False
|
||
|
||
def _stop_movement(self, text: str, confidence: float) -> bool:
|
||
"""停止移动"""
|
||
try:
|
||
print("⏹ 执行停止移动命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("已停止移动")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 停止移动命令执行失败: {e}")
|
||
return False
|
||
|
||
def _toggle_lights(self, text: str, confidence: float) -> bool:
|
||
"""切换灯光"""
|
||
try:
|
||
action = "打开" if "打开" in text else "关闭"
|
||
print(f"💡 执行{action}灯光命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech(f"已{action}灯光")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 灯光控制命令执行失败: {e}")
|
||
return False
|
||
|
||
def _increase_volume(self, text: str, confidence: float) -> bool:
|
||
"""增加音量"""
|
||
try:
|
||
print("🔊 执行增加音量命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("音量已增加")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 增加音量命令执行失败: {e}")
|
||
return False
|
||
|
||
def _decrease_volume(self, text: str, confidence: float) -> bool:
|
||
"""减少音量"""
|
||
try:
|
||
print("🔉 执行减少音量命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("音量已减少")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 减少音量命令执行失败: {e}")
|
||
return False
|
||
|
||
def _play_music(self, text: str, confidence: float) -> bool:
|
||
"""播放音乐"""
|
||
try:
|
||
print("🎵 执行播放音乐命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("正在播放音乐")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 播放音乐命令执行失败: {e}")
|
||
return False
|
||
|
||
def _pause_music(self, text: str, confidence: float) -> bool:
|
||
"""暂停音乐"""
|
||
try:
|
||
print("⏸ 执行暂停音乐命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("音乐已暂停")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 暂停音乐命令执行失败: {e}")
|
||
return False
|
||
|
||
def _next_track(self, text: str, confidence: float) -> bool:
|
||
"""下一首"""
|
||
try:
|
||
print("⏭ 执行播放下一首命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("正在播放下一首")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 播放下一首命令执行失败: {e}")
|
||
return False
|
||
|
||
def _previous_track(self, text: str, confidence: float) -> bool:
|
||
"""上一首"""
|
||
try:
|
||
print("⏮ 执行播放上一首命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("正在播放上一首")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 播放上一首命令执行失败: {e}")
|
||
return False
|
||
|
||
def _greet_user(self, text: str, confidence: float) -> bool:
|
||
"""打招呼"""
|
||
try:
|
||
print("👋 执行打招呼命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("您好!有什么可以帮助您的吗?")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 打招呼命令执行失败: {e}")
|
||
return False
|
||
|
||
def _acknowledge_thanks(self, text: str, confidence: float) -> bool:
|
||
"""回应感谢"""
|
||
try:
|
||
print("🙏 执行回应感谢命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("不客气!")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 回应感谢命令执行失败: {e}")
|
||
return False
|
||
|
||
def _say_goodbye(self, text: str, confidence: float) -> bool:
|
||
"""道别"""
|
||
try:
|
||
print("👋 执行道别命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech("再见!")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 道别命令执行失败: {e}")
|
||
return False
|
||
|
||
def _provide_help(self, text: str = None, confidence: float = 1.0) -> bool:
|
||
"""提供帮助"""
|
||
try:
|
||
help_text = "我可以帮您控制移动、灯光、音量和音乐播放。请说'前进'、'后退'、'左转'、'右转'、'停止'来控制移动;说'打开灯光'或'关闭灯光'来控制灯光;说'增加音量'或'减少音量'来调节音量;说'播放音乐'、'暂停播放'、'下一首'、'上一首'来控制音乐。"
|
||
print("ℹ️ 执行提供帮助命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech(help_text)
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 提供帮助命令执行失败: {e}")
|
||
return False
|
||
|
||
def _show_about(self, text: str, confidence: float) -> bool:
|
||
"""显示关于信息"""
|
||
try:
|
||
about_text = "语音控制系统版本1.0.0,基于EG引擎开发。"
|
||
print("ℹ️ 执行显示关于信息命令")
|
||
if self.plugin.speech_synthesizer:
|
||
self.plugin.speech_synthesizer.synthesize_speech(about_text)
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 显示关于信息命令执行失败: {e}")
|
||
return False
|
||
|
||
def get_command_mappings(self) -> Dict[str, Dict[str, Any]]:
|
||
"""
|
||
获取命令映射
|
||
|
||
Returns:
|
||
命令映射字典
|
||
"""
|
||
return self.command_mappings.copy()
|
||
|
||
def get_command_groups(self) -> Dict[str, Dict[str, Any]]:
|
||
"""
|
||
获取命令组
|
||
|
||
Returns:
|
||
命令组字典
|
||
"""
|
||
return self.command_groups.copy()
|
||
|
||
def get_command_history(self) -> List[Dict[str, Any]]:
|
||
"""
|
||
获取命令历史
|
||
|
||
Returns:
|
||
命令历史列表
|
||
"""
|
||
return self.command_history.copy()
|
||
|
||
def clear_command_history(self):
|
||
"""清空命令历史"""
|
||
try:
|
||
self.command_history.clear()
|
||
print("✓ 命令历史已清空")
|
||
except Exception as e:
|
||
print(f"✗ 命令历史清空失败: {e}")
|
||
|
||
def set_command_config(self, config: Dict[str, Any]) -> bool:
|
||
"""
|
||
设置命令配置
|
||
|
||
Args:
|
||
config: 配置字典
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
try:
|
||
self.command_config.update(config)
|
||
print(f"✓ 命令配置已更新: {self.command_config}")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 命令配置设置失败: {e}")
|
||
return False
|
||
|
||
def get_command_config(self) -> Dict[str, Any]:
|
||
"""
|
||
获取命令配置
|
||
|
||
Returns:
|
||
配置字典
|
||
"""
|
||
return self.command_config.copy()
|
||
|
||
def get_context(self) -> Dict[str, Any]:
|
||
"""
|
||
获取当前上下文
|
||
|
||
Returns:
|
||
上下文字典
|
||
"""
|
||
return self.command_context.copy()
|
||
|
||
def _trigger_command_callback(self, callback_type: str, data: Dict[str, Any]):
|
||
"""
|
||
触发命令回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
data: 回调数据
|
||
"""
|
||
try:
|
||
if callback_type in self.command_callbacks:
|
||
for callback in self.command_callbacks[callback_type]:
|
||
try:
|
||
callback(data)
|
||
except Exception as e:
|
||
print(f"✗ 命令回调执行失败: {e}")
|
||
except Exception as e:
|
||
print(f"✗ 命令回调触发失败: {e}")
|
||
|
||
def register_command_callback(self, callback_type: str, callback: Callable):
|
||
"""
|
||
注册命令回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
callback: 回调函数
|
||
"""
|
||
try:
|
||
if callback_type in self.command_callbacks:
|
||
self.command_callbacks[callback_type].append(callback)
|
||
print(f"✓ 命令回调已注册: {callback_type}")
|
||
else:
|
||
print(f"✗ 无效的回调类型: {callback_type}")
|
||
except Exception as e:
|
||
print(f"✗ 命令回调注册失败: {e}")
|
||
|
||
def unregister_command_callback(self, callback_type: str, callback: Callable):
|
||
"""
|
||
注销命令回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
callback: 回调函数
|
||
"""
|
||
try:
|
||
if callback_type in self.command_callbacks:
|
||
if callback in self.command_callbacks[callback_type]:
|
||
self.command_callbacks[callback_type].remove(callback)
|
||
print(f"✓ 命令回调已注销: {callback_type}")
|
||
except Exception as e:
|
||
print(f"✗ 命令回调注销失败: {e}")
|
||
|
||
def get_stats(self) -> Dict[str, Any]:
|
||
"""
|
||
获取统计信息
|
||
|
||
Returns:
|
||
统计信息字典
|
||
"""
|
||
return self.stats.copy()
|
||
|
||
def reset_stats(self):
|
||
"""重置统计信息"""
|
||
try:
|
||
self.stats = {
|
||
'commands_processed': 0,
|
||
'commands_executed': 0,
|
||
'commands_failed': 0,
|
||
'fuzzy_matches': 0,
|
||
'exact_matches': 0,
|
||
'context_commands': 0,
|
||
'chained_commands': 0
|
||
}
|
||
print("✓ 命令处理器统计信息已重置")
|
||
except Exception as e:
|
||
print(f"✗ 命令处理器统计信息重置失败: {e}") |