refactor: drive execute_cmd from commands.yaml action schema

Replaces the 100-line elif chain with a small dispatcher. Each entry in
commands.yaml now carries both 'phrases' (existing trigger list) and
'action' describing how to run it. Action types: exe, play_sound,
system (volume_mute/unmute/exit), sleep, multi.

The data migration lives in the next commit; the dispatcher in this
commit assumes the new schema.
This commit is contained in:
Bossiara13 2026-04-22 19:34:00 +03:00
parent 794d923bf9
commit a1a2be309b

138
main.py
View file

@ -180,8 +180,7 @@ def filter_cmd(raw_voice: str):
def recognize_cmd(cmd: str): def recognize_cmd(cmd: str):
rc = {'cmd': '', 'percent': 0} rc = {'cmd': '', 'percent': 0}
for c, v in VA_CMD_LIST.items(): for c, v in VA_CMD_LIST.items():
for x in v['phrases']:
for x in v:
vrt = fuzz.ratio(cmd, x) vrt = fuzz.ratio(cmd, x)
if vrt > rc['percent']: if vrt > rc['percent']:
rc['cmd'] = c rc['cmd'] = c
@ -190,90 +189,59 @@ def recognize_cmd(cmd: str):
return rc return rc
def _set_mute(state: int):
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
volume.SetMute(state, None)
def _shutdown():
try:
recorder.stop()
recorder.delete()
finally:
sys.exit(0)
def run_action(action):
t = action['type']
if t == 'exe':
path = f"{CDIR}\\custom-commands\\{action['file']}"
if action.get('wait'):
subprocess.check_call([path])
else:
subprocess.Popen([path])
if 'delay_ms' in action:
time.sleep(action['delay_ms'] / 1000)
elif t == 'play_sound':
play(action['name'])
elif t == 'system':
op = action['op']
if op == 'volume_mute':
_set_mute(1)
elif op == 'volume_unmute':
_set_mute(0)
elif op == 'exit':
_shutdown()
elif t == 'sleep':
time.sleep(action['ms'] / 1000)
elif t == 'multi':
for step in action['steps']:
run_action(step)
def execute_cmd(cmd: str, voice: str): def execute_cmd(cmd: str, voice: str):
if cmd == 'open_browser': spec = VA_CMD_LIST.get(cmd)
subprocess.Popen([f'{CDIR}\\custom-commands\\Run browser.exe']) if not spec:
play("ok") return
action = spec['action']
elif cmd == 'open_youtube': run_action(action)
subprocess.Popen([f'{CDIR}\\custom-commands\\Run youtube.exe']) confirm = spec.get('confirm_sound')
play("ok") if confirm is None and action['type'] == 'exe':
confirm = 'ok'
elif cmd == 'open_google': if confirm:
subprocess.Popen([f'{CDIR}\\custom-commands\\Run google.exe']) play(confirm)
play("ok")
elif cmd == 'music':
subprocess.Popen([f'{CDIR}\\custom-commands\\Run music.exe'])
play("ok")
elif cmd == 'music_off':
subprocess.Popen([f'{CDIR}\\custom-commands\\Stop music.exe'])
time.sleep(0.2)
play("ok")
elif cmd == 'music_save':
subprocess.Popen([f'{CDIR}\\custom-commands\\Save music.exe'])
time.sleep(0.2)
play("ok")
elif cmd == 'music_next':
subprocess.Popen([f'{CDIR}\\custom-commands\\Next music.exe'])
time.sleep(0.2)
play("ok")
elif cmd == 'music_prev':
subprocess.Popen([f'{CDIR}\\custom-commands\\Prev music.exe'])
time.sleep(0.2)
play("ok")
elif cmd == 'sound_off':
play("ok", True)
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
volume.SetMute(1, None)
elif cmd == 'sound_on':
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = cast(interface, POINTER(IAudioEndpointVolume))
volume.SetMute(0, None)
play("ok")
elif cmd == 'thanks':
play("thanks")
elif cmd == 'stupid':
play("stupid")
elif cmd == 'gaming_mode_on':
play("ok")
subprocess.check_call([f'{CDIR}\\custom-commands\\Switch to gaming mode.exe'])
play("ready")
elif cmd == 'gaming_mode_off':
play("ok")
subprocess.check_call([f'{CDIR}\\custom-commands\\Switch back to workspace.exe'])
play("ready")
elif cmd == 'switch_to_headphones':
play("ok")
subprocess.check_call([f'{CDIR}\\custom-commands\\Switch to headphones.exe'])
time.sleep(0.5)
play("ready")
elif cmd == 'switch_to_dynamics':
play("ok")
subprocess.check_call([f'{CDIR}\\custom-commands\\Switch to dynamics.exe'])
time.sleep(0.5)
play("ready")
elif cmd == 'off':
play("off", True)
exit(0)
recorder = PvRecorder(device_index=config.MICROPHONE_INDEX, frame_length=512) recorder = PvRecorder(device_index=config.MICROPHONE_INDEX, frame_length=512)