Skip to content

Commit 45c6f22

Browse files
committed
miniterm: refactor key handler and extend suspend function
1 parent 591c451 commit 45c6f22

File tree

1 file changed

+138
-104
lines changed

1 file changed

+138
-104
lines changed

serial/tools/miniterm.py

Lines changed: 138 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -502,25 +502,7 @@ def handle_menu_key(self, c):
502502
if self.echo:
503503
self.console.write(c)
504504
elif c == '\x15': # CTRL+U -> upload file
505-
sys.stderr.write('\n--- File to upload: ')
506-
sys.stderr.flush()
507-
with self.console:
508-
filename = sys.stdin.readline().rstrip('\r\n')
509-
if filename:
510-
try:
511-
with open(filename, 'rb') as f:
512-
sys.stderr.write('--- Sending file {} ---\n'.format(filename))
513-
while True:
514-
block = f.read(1024)
515-
if not block:
516-
break
517-
self.serial.write(block)
518-
# Wait for output buffer to drain.
519-
self.serial.flush()
520-
sys.stderr.write('.') # Progress indicator.
521-
sys.stderr.write('\n--- File {} sent ---\n'.format(filename))
522-
except IOError as e:
523-
sys.stderr.write('--- ERROR opening file {}: {} ---\n'.format(filename, e))
505+
self.upload_file()
524506
elif c in '\x08hH?': # CTRL+H, h, H, ? -> Show help
525507
sys.stderr.write(self.get_help_text())
526508
elif c == '\x12': # CTRL+R -> Toggle RTS
@@ -536,22 +518,7 @@ def handle_menu_key(self, c):
536518
self.echo = not self.echo
537519
sys.stderr.write('--- local echo {} ---\n'.format('active' if self.echo else 'inactive'))
538520
elif c == '\x06': # CTRL+F -> edit filters
539-
sys.stderr.write('\n--- Available Filters:\n')
540-
sys.stderr.write('\n'.join(
541-
'--- {:<10} = {.__doc__}'.format(k, v)
542-
for k, v in sorted(TRANSFORMATIONS.items())))
543-
sys.stderr.write('\n--- Enter new filter name(s) [{}]: '.format(' '.join(self.filters)))
544-
with self.console:
545-
new_filters = sys.stdin.readline().lower().split()
546-
if new_filters:
547-
for f in new_filters:
548-
if f not in TRANSFORMATIONS:
549-
sys.stderr.write('--- unknown filter: {}\n'.format(repr(f)))
550-
break
551-
else:
552-
self.filters = new_filters
553-
self.update_transformations()
554-
sys.stderr.write('--- filters: {}\n'.format(' '.join(self.filters)))
521+
self.change_filter()
555522
elif c == '\x0c': # CTRL+L -> EOL mode
556523
modes = list(EOL_TRANSFORMATIONS) # keys
557524
eol = modes.index(self.eol) + 1
@@ -561,82 +528,17 @@ def handle_menu_key(self, c):
561528
sys.stderr.write('--- EOL: {} ---\n'.format(self.eol.upper()))
562529
self.update_transformations()
563530
elif c == '\x01': # CTRL+A -> set encoding
564-
sys.stderr.write('\n--- Enter new encoding name [{}]: '.format(self.input_encoding))
565-
with self.console:
566-
new_encoding = sys.stdin.readline().strip()
567-
if new_encoding:
568-
try:
569-
codecs.lookup(new_encoding)
570-
except LookupError:
571-
sys.stderr.write('--- invalid encoding name: {}\n'.format(new_encoding))
572-
else:
573-
self.set_rx_encoding(new_encoding)
574-
self.set_tx_encoding(new_encoding)
575-
sys.stderr.write('--- serial input encoding: {}\n'.format(self.input_encoding))
576-
sys.stderr.write('--- serial output encoding: {}\n'.format(self.output_encoding))
531+
self.change_encoding()
577532
elif c == '\x09': # CTRL+I -> info
578533
self.dump_port_settings()
579534
#~ elif c == '\x01': # CTRL+A -> cycle escape mode
580535
#~ elif c == '\x0c': # CTRL+L -> cycle linefeed mode
581536
elif c in 'pP': # P -> change port
582-
with self.console:
583-
try:
584-
port = ask_for_port()
585-
except KeyboardInterrupt:
586-
port = None
587-
if port and port != self.serial.port:
588-
# reader thread needs to be shut down
589-
self._stop_reader()
590-
# save settings
591-
settings = self.serial.getSettingsDict()
592-
try:
593-
new_serial = serial.serial_for_url(port, do_not_open=True)
594-
# restore settings and open
595-
new_serial.applySettingsDict(settings)
596-
new_serial.rts = self.serial.rts
597-
new_serial.dtr = self.serial.dtr
598-
new_serial.open()
599-
new_serial.break_condition = self.serial.break_condition
600-
except Exception as e:
601-
sys.stderr.write('--- ERROR opening new port: {} ---\n'.format(e))
602-
new_serial.close()
603-
else:
604-
self.serial.close()
605-
self.serial = new_serial
606-
sys.stderr.write('--- Port changed to: {} ---\n'.format(self.serial.port))
607-
# and restart the reader thread
608-
self._start_reader()
537+
self.change_port()
609538
elif c in 'sS': # S -> suspend / open port temporarily
610-
# reader thread needs to be shut down
611-
self._stop_reader()
612-
self.serial.close()
613-
sys.stderr.write('\n--- Port closed: {} ---\n'.format(self.serial.port))
614-
while not self.serial.is_open:
615-
sys.stderr.write('--- press {exit} to exit or any other key to reconnect ---\n'.format(
616-
exit=key_description(self.exit_character)))
617-
k = self.console.getkey()
618-
if k == self.exit_character:
619-
self.stop() # exit app
620-
break
621-
try:
622-
self.serial.open()
623-
except Exception as e:
624-
sys.stderr.write('--- ERROR opening port: {} ---\n'.format(e))
625-
# and restart the reader thread
626-
self._start_reader()
627-
sys.stderr.write('--- Port opened: {} ---\n'.format(self.serial.port))
539+
self.suspend_port()
628540
elif c in 'bB': # B -> change baudrate
629-
sys.stderr.write('\n--- Baudrate: ')
630-
sys.stderr.flush()
631-
with self.console:
632-
backup = self.serial.baudrate
633-
try:
634-
self.serial.baudrate = int(sys.stdin.readline().strip())
635-
except ValueError as e:
636-
sys.stderr.write('--- ERROR setting baudrate: {} ---\n'.format(e))
637-
self.serial.baudrate = backup
638-
else:
639-
self.dump_port_settings()
541+
self.change_baudrate()
640542
elif c == '8': # 8 -> change to 8 bits
641543
self.serial.bytesize = serial.EIGHTBITS
642544
self.dump_port_settings()
@@ -676,6 +578,138 @@ def handle_menu_key(self, c):
676578
else:
677579
sys.stderr.write('--- unknown menu character {} --\n'.format(key_description(c)))
678580

581+
def upload_file(self):
582+
"""Ask user for filenname and send its contents"""
583+
sys.stderr.write('\n--- File to upload: ')
584+
sys.stderr.flush()
585+
with self.console:
586+
filename = sys.stdin.readline().rstrip('\r\n')
587+
if filename:
588+
try:
589+
with open(filename, 'rb') as f:
590+
sys.stderr.write('--- Sending file {} ---\n'.format(filename))
591+
while True:
592+
block = f.read(1024)
593+
if not block:
594+
break
595+
self.serial.write(block)
596+
# Wait for output buffer to drain.
597+
self.serial.flush()
598+
sys.stderr.write('.') # Progress indicator.
599+
sys.stderr.write('\n--- File {} sent ---\n'.format(filename))
600+
except IOError as e:
601+
sys.stderr.write('--- ERROR opening file {}: {} ---\n'.format(filename, e))
602+
603+
def change_filter(self):
604+
"""change the i/o transformations"""
605+
sys.stderr.write('\n--- Available Filters:\n')
606+
sys.stderr.write('\n'.join(
607+
'--- {:<10} = {.__doc__}'.format(k, v)
608+
for k, v in sorted(TRANSFORMATIONS.items())))
609+
sys.stderr.write('\n--- Enter new filter name(s) [{}]: '.format(' '.join(self.filters)))
610+
with self.console:
611+
new_filters = sys.stdin.readline().lower().split()
612+
if new_filters:
613+
for f in new_filters:
614+
if f not in TRANSFORMATIONS:
615+
sys.stderr.write('--- unknown filter: {}\n'.format(repr(f)))
616+
break
617+
else:
618+
self.filters = new_filters
619+
self.update_transformations()
620+
sys.stderr.write('--- filters: {}\n'.format(' '.join(self.filters)))
621+
622+
def change_encoding(self):
623+
"""change encoding on the serial port"""
624+
sys.stderr.write('\n--- Enter new encoding name [{}]: '.format(self.input_encoding))
625+
with self.console:
626+
new_encoding = sys.stdin.readline().strip()
627+
if new_encoding:
628+
try:
629+
codecs.lookup(new_encoding)
630+
except LookupError:
631+
sys.stderr.write('--- invalid encoding name: {}\n'.format(new_encoding))
632+
else:
633+
self.set_rx_encoding(new_encoding)
634+
self.set_tx_encoding(new_encoding)
635+
sys.stderr.write('--- serial input encoding: {}\n'.format(self.input_encoding))
636+
sys.stderr.write('--- serial output encoding: {}\n'.format(self.output_encoding))
637+
638+
def change_baudrate(self):
639+
"""change the baudrate"""
640+
sys.stderr.write('\n--- Baudrate: ')
641+
sys.stderr.flush()
642+
with self.console:
643+
backup = self.serial.baudrate
644+
try:
645+
self.serial.baudrate = int(sys.stdin.readline().strip())
646+
except ValueError as e:
647+
sys.stderr.write('--- ERROR setting baudrate: {} ---\n'.format(e))
648+
self.serial.baudrate = backup
649+
else:
650+
self.dump_port_settings()
651+
652+
def change_port(self):
653+
"""Have a conversation with the user to change the serial port"""
654+
with self.console:
655+
try:
656+
port = ask_for_port()
657+
except KeyboardInterrupt:
658+
port = None
659+
if port and port != self.serial.port:
660+
# reader thread needs to be shut down
661+
self._stop_reader()
662+
# save settings
663+
settings = self.serial.getSettingsDict()
664+
try:
665+
new_serial = serial.serial_for_url(port, do_not_open=True)
666+
# restore settings and open
667+
new_serial.applySettingsDict(settings)
668+
new_serial.rts = self.serial.rts
669+
new_serial.dtr = self.serial.dtr
670+
new_serial.open()
671+
new_serial.break_condition = self.serial.break_condition
672+
except Exception as e:
673+
sys.stderr.write('--- ERROR opening new port: {} ---\n'.format(e))
674+
new_serial.close()
675+
else:
676+
self.serial.close()
677+
self.serial = new_serial
678+
sys.stderr.write('--- Port changed to: {} ---\n'.format(self.serial.port))
679+
# and restart the reader thread
680+
self._start_reader()
681+
682+
def suspend_port(self):
683+
"""\
684+
open port temporarily, allow reconnect, exit and port change to get
685+
out of the loop
686+
"""
687+
# reader thread needs to be shut down
688+
self._stop_reader()
689+
self.serial.close()
690+
sys.stderr.write('\n--- Port closed: {} ---\n'.format(self.serial.port))
691+
do_change_port = False
692+
while not self.serial.is_open:
693+
sys.stderr.write('--- Quit: {exit} | p: port change | any other key to reconnect ---\n'.format(
694+
exit=key_description(self.exit_character)))
695+
k = self.console.getkey()
696+
if k == self.exit_character:
697+
self.stop() # exit app
698+
break
699+
elif k in 'pP':
700+
do_change_port = True
701+
break
702+
try:
703+
self.serial.open()
704+
except Exception as e:
705+
sys.stderr.write('--- ERROR opening port: {} ---\n'.format(e))
706+
if do_change_port:
707+
self.change_port()
708+
else:
709+
# and restart the reader thread
710+
self._start_reader()
711+
sys.stderr.write('--- Port opened: {} ---\n'.format(self.serial.port))
712+
679713
def get_help_text(self):
680714
"""return the help text"""
681715
# help text, starts with blank line!

0 commit comments

Comments
 (0)