led.py: improve initialization logic, add interactive test
This commit is contained in:
parent
e0c93606e1
commit
fb17a3b2c9
2 changed files with 107 additions and 30 deletions
74
mmgen/led.py
74
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
|
||||
|
||||
|
|
|
|||
57
test/misc/led.py
Executable file
57
test/misc/led.py
Executable file
|
|
@ -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}]')
|
||||
Loading…
Add table
Add a link
Reference in a new issue