diff --git a/mmgen/led.py b/mmgen/led.py index bbb24411..c3ea5cdb 100755 --- a/mmgen/led.py +++ b/mmgen/led.py @@ -80,47 +80,67 @@ class LEDControl: continue try: os.stat(board.control) - except: - pass - else: break + except FileNotFoundError: + pass else: die('NoLEDSupport', 'Control files not found! LED control not supported on this system') msg(f'{board.name} board detected') if self.debug: - msg(f'\n Control file: {board.control}\n Trigger file: {board.trigger}') + msg(f'\n Status file: {board.control}\n Trigger file: {board.trigger}') - def check_access(fn, desc, init_val=None): + def write_init_val(fn, init_val): + if not init_val: + with open(fn) as fp: + init_val = fp.read().strip() + with open(fn, 'w') as fp: + fp.write(f'{init_val}\n') - def write_init_val(init_val): - if not init_val: - with open(fn) as fp: - init_val = fp.read().strip() - with open(fn, 'w') as fp: - fp.write(f'{init_val}\n') + def permission_error_action(fn, desc): + cmd = f'sudo chmod 0666 {fn}' + if have_sudo(): + msg(orange(f'Running ‘{cmd}’')) + run(cmd.split(), check=True) + else: + msg('\n{}\n{}\n{}'.format( + blue(f'You do not have write access to the {desc}'), + blue(f'To allow access, run the following command:\n\n {cmd}'), + orange('[To prevent this message in the future, enable sudo without a password]') + )) + sys.exit(1) + def init_state(fn, desc, init_val=None): try: - write_init_val(init_val) + write_init_val(fn, init_val) except PermissionError: - cmd = f'sudo chmod 0666 {fn}' - if have_sudo(): - msg(orange(f'Running ‘{cmd}’')) - run(cmd.split(), check=True) - write_init_val(init_val) - else: - msg('\n{}\n{}\n{}'.format( - blue(f'You do not have access to the {desc} file'), - blue(f'To allow access, run the following command:\n\n {cmd}'), - orange('[To prevent this message in the future, enable sudo without a password]') - )) - sys.exit(1) - - check_access(board.control, desc='status LED control') + permission_error_action(fn, desc) + write_init_val(fn, init_val) + # Writing to control file can alter trigger file, so read and initialize trigger file first: if board.trigger: - check_access(board.trigger, desc='LED trigger', init_val=board.trigger_states[0]) + def get_cur_state(): + try: + with open(board.trigger) as fh: + states = fh.read() + except PermissionError: + permission_error_action(board.trigger, 'status LED trigger file') + with open(board.trigger) as fh: + states = fh.read() + + res = [a for a in states.split() if a.startswith('[') and a.endswith(']')] + return res[0][1:-1] if len(res) == 1 else None + + if cur_state := get_cur_state(): + msg(f'Saving current LED trigger state: [{cur_state}]') + board.trigger_reset = cur_state + else: + msg('Unable to determine current LED trigger state') + + init_state(board.trigger, desc='status LED trigger file', init_val=board.trigger_disable) + + init_state(board.control, desc='status LED control file') self.board = board diff --git a/test/misc/led.py b/test/misc/led.py new file mode 100755 index 00000000..25dbfa2f --- /dev/null +++ b/test/misc/led.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 + +import sys, os, atexit +pn = os.path.abspath(os.path.dirname(sys.argv[0])) +parpar = os.path.dirname(os.path.dirname(pn)) +os.chdir(parpar) +sys.path[0] = os.curdir + +from mmgen.cfg import Config +from mmgen.util import msg +from mmgen.ui import keypress_confirm +from mmgen.led import LEDControl + +opts_data = { + 'text': { + 'desc': 'Interactively test LED functionality', + 'usage': 'command', + 'options': """ +-h, --help Print this help message +""", + } +} + +cfg = Config(opts_data=opts_data) + +def confirm_or_exit(prompt): + if not keypress_confirm(cfg, f'{prompt}. OK?', default_yes=True): + msg('Exiting at user request') + sys.exit(1) + +confirm_or_exit('This script will interactively test LED functionality') + +led = LEDControl(enabled=True) + +atexit.register(led.stop) + +confirm_or_exit('LED should now be turned off') + +led.set('busy') + +confirm_or_exit('LED should now be signaling busy (rapid flashing)') + +led.set('standby') + +confirm_or_exit('LED should now be signaling standby (slow flashing)') + +led.set('error') + +confirm_or_exit('LED should now be signaling error (insistent flashing)') + +led.set('off') + +confirm_or_exit('LED should now be turned off') + +led.stop() + +confirm_or_exit(f'LED should now be in its original state [trigger={led.board.trigger_reset}]')