2014-05-26 21:56:57 +02:00
|
|
|
#!/usr/bin/env python
|
2010-11-05 22:36:14 +01:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2014-05-26 21:56:57 +02:00
|
|
|
try:
|
|
|
|
import configparser
|
|
|
|
except ImportError:
|
|
|
|
import ConfigParser as configparser
|
|
|
|
|
2014-03-26 13:04:20 +01:00
|
|
|
from twisted.internet import reactor
|
|
|
|
from twisted.internet.protocol import Protocol, ReconnectingClientFactory
|
2014-04-03 16:14:38 +02:00
|
|
|
import cmd, serial, sys, threading, readline, time, logging, os, argparse, re, codecs, signal
|
2011-11-30 18:21:11 +01:00
|
|
|
|
2014-03-25 17:05:07 +01:00
|
|
|
### set some default options
|
2014-05-25 16:57:08 +02:00
|
|
|
import platform
|
|
|
|
defaulthostname = platform.node()
|
|
|
|
|
2014-03-25 17:03:14 +01:00
|
|
|
defaultport = "/dev/ttyUSB0"
|
2014-03-26 00:00:33 +01:00
|
|
|
defaultbaud = 115200
|
2014-03-25 19:18:15 +01:00
|
|
|
defaultdir = os.environ['HOME'] + os.path.sep + '.pyterm'
|
2014-05-25 16:57:08 +02:00
|
|
|
defaultfile = "pyterm-" + defaulthostname + ".conf"
|
|
|
|
defaultrunname = "default-run"
|
2010-11-05 22:36:14 +01:00
|
|
|
|
2010-11-09 18:47:19 +01:00
|
|
|
class SerCmd(cmd.Cmd):
|
|
|
|
|
2014-05-25 16:57:08 +02:00
|
|
|
def __init__(self, port=None, baudrate=None, confdir=None, conffile=None, host=None, run_name=None):
|
2011-11-30 18:21:11 +01:00
|
|
|
cmd.Cmd.__init__(self)
|
|
|
|
self.port = port
|
2014-03-26 00:00:33 +01:00
|
|
|
self.baudrate = baudrate
|
2014-03-25 19:18:15 +01:00
|
|
|
self.configdir = confdir
|
|
|
|
self.configfile = conffile
|
2014-05-25 16:57:08 +02:00
|
|
|
self.host = host
|
|
|
|
self.run_name = run_name
|
|
|
|
|
|
|
|
if not self.host:
|
|
|
|
self.host = defaulthostname
|
|
|
|
|
2014-06-05 05:40:56 +02:00
|
|
|
if not self.run_name:
|
2014-05-25 16:57:08 +02:00
|
|
|
self.run_name = defaultrunname
|
2014-03-25 19:18:15 +01:00
|
|
|
|
|
|
|
if not os.path.exists(self.configdir):
|
|
|
|
os.makedirs(self.configdir)
|
|
|
|
|
2011-11-30 18:21:11 +01:00
|
|
|
self.aliases = dict()
|
2014-06-05 06:25:34 +02:00
|
|
|
self.triggers = dict()
|
2014-03-25 19:57:18 +01:00
|
|
|
self.filters = []
|
|
|
|
self.ignores = []
|
2014-03-26 13:04:20 +01:00
|
|
|
self.json_regs = dict()
|
2014-05-25 16:57:08 +02:00
|
|
|
self.init_cmd = []
|
2011-11-30 18:21:11 +01:00
|
|
|
self.load_config()
|
2014-03-25 19:57:18 +01:00
|
|
|
|
2011-11-30 18:21:11 +01:00
|
|
|
try:
|
|
|
|
readline.read_history_file()
|
|
|
|
except IOError:
|
|
|
|
pass
|
|
|
|
|
2014-03-25 17:03:14 +01:00
|
|
|
### create Logging object
|
2014-05-26 21:56:57 +02:00
|
|
|
my_millis = "{:.4f}".format(time.time())
|
|
|
|
date_str = '{}.{}'.format(time.strftime('%Y%m%d-%H:%M:%S'), my_millis[-4:])
|
2014-05-25 16:57:08 +02:00
|
|
|
self.startup = date_str
|
2011-11-30 18:21:11 +01:00
|
|
|
# create formatter
|
|
|
|
fmt_str = '%(asctime)s - %(levelname)s # %(message)s'
|
|
|
|
formatter = logging.Formatter(fmt_str)
|
2014-05-25 16:57:08 +02:00
|
|
|
|
|
|
|
directory = self.configdir + os.path.sep + self.host
|
|
|
|
if not os.path.exists(directory):
|
|
|
|
os.makedirs(directory)
|
|
|
|
logging.basicConfig(filename=directory + os.path.sep + self.run_name + '.log', level=logging.DEBUG, format=fmt_str)
|
2011-11-30 18:21:11 +01:00
|
|
|
ch = logging.StreamHandler()
|
|
|
|
ch.setLevel(logging.DEBUG)
|
|
|
|
|
|
|
|
# create logger
|
|
|
|
self.logger = logging.getLogger('')
|
2014-06-05 06:16:19 +02:00
|
|
|
self.logger.setLevel(logging.INFO)
|
2011-11-30 18:21:11 +01:00
|
|
|
|
|
|
|
# add formatter to ch
|
|
|
|
ch.setFormatter(formatter)
|
|
|
|
# add ch to logger
|
|
|
|
self.logger.addHandler(ch)
|
|
|
|
|
|
|
|
|
|
|
|
def preloop(self):
|
|
|
|
if not self.port:
|
2014-03-25 17:03:14 +01:00
|
|
|
sys.stderr.write("No port specified, using default (%s)!\n" % (defaultport))
|
|
|
|
self.port = defaultport
|
2014-03-26 00:00:33 +01:00
|
|
|
self.ser = serial.Serial(port=self.port, baudrate=self.baudrate, dsrdtr=0, rtscts=0)
|
2011-11-30 18:21:11 +01:00
|
|
|
self.ser.setDTR(0)
|
|
|
|
self.ser.setRTS(0)
|
|
|
|
|
2014-05-25 16:57:08 +02:00
|
|
|
time.sleep(1)
|
|
|
|
for cmd in self.init_cmd:
|
2014-05-25 22:57:42 +02:00
|
|
|
self.logger.debug("WRITE ----->>>>>> '" + cmd + "'\n")
|
2014-06-05 06:22:44 +02:00
|
|
|
self.onecmd(self.precmd(cmd))
|
2014-05-25 16:57:08 +02:00
|
|
|
|
2011-11-30 18:21:11 +01:00
|
|
|
# start serial->console thread
|
2014-03-25 19:18:38 +01:00
|
|
|
receiver_thread = threading.Thread(target=self.reader)
|
2011-11-30 18:21:11 +01:00
|
|
|
receiver_thread.setDaemon(1)
|
|
|
|
receiver_thread.start()
|
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def precmd(self, line):
|
2014-06-05 06:22:44 +02:00
|
|
|
self.logger.debug("processing line #%s#" % line)
|
2014-03-25 19:58:26 +01:00
|
|
|
if (line.startswith("/")):
|
|
|
|
return "PYTERM_" + line[1:]
|
|
|
|
return line
|
|
|
|
|
2011-11-30 18:21:11 +01:00
|
|
|
def default(self, line):
|
2014-06-05 06:22:44 +02:00
|
|
|
self.logger.debug("%s is no pyterm command, sending to default out" % line)
|
2011-11-30 18:21:11 +01:00
|
|
|
for tok in line.split(';'):
|
|
|
|
tok = self.get_alias(tok)
|
2014-06-27 16:32:41 +02:00
|
|
|
self.ser.write((tok.strip() + "\n").encode("utf-8"))
|
2011-11-30 18:21:11 +01:00
|
|
|
|
|
|
|
def do_help(self, line):
|
2014-06-27 16:32:41 +02:00
|
|
|
self.ser.write("help\n".encode("utf-8"))
|
2011-11-30 18:21:11 +01:00
|
|
|
|
|
|
|
def complete_date(self, text, line, begidx, endidm):
|
|
|
|
date = time.strftime("%Y-%m-%d %H:%M:%S")
|
2014-05-26 21:56:57 +02:00
|
|
|
return ["{}".format(date)]
|
2011-11-30 18:21:11 +01:00
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def do_PYTERM_reset(self, line):
|
2011-11-30 18:21:11 +01:00
|
|
|
self.ser.setDTR(1)
|
|
|
|
self.ser.setDTR(0)
|
|
|
|
|
2014-04-03 16:14:38 +02:00
|
|
|
def do_PYTERM_exit(self, line, unused=None):
|
2014-06-05 06:32:30 +02:00
|
|
|
self.logger.info("Exiting Pyterm")
|
2011-11-30 18:21:11 +01:00
|
|
|
readline.write_history_file()
|
2014-03-26 13:04:20 +01:00
|
|
|
if reactor.running:
|
2014-04-03 16:14:38 +02:00
|
|
|
reactor.callFromThread(reactor.stop)
|
2014-03-26 13:04:20 +01:00
|
|
|
return True
|
2011-11-30 18:21:11 +01:00
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def do_PYTERM_save(self, line):
|
2011-11-30 18:21:11 +01:00
|
|
|
if not self.config.has_section("general"):
|
|
|
|
self.config.add_section("general")
|
|
|
|
self.config.set("general", "port", self.port)
|
|
|
|
if len(self.aliases):
|
|
|
|
if not self.config.has_section("aliases"):
|
|
|
|
self.config.add_section("aliases")
|
|
|
|
for alias in self.aliases:
|
|
|
|
self.config.set("aliases", alias, self.aliases[alias])
|
2014-06-05 06:25:34 +02:00
|
|
|
if len(self.triggers):
|
|
|
|
if not self.config.has_section("triggers"):
|
|
|
|
self.config.add_section("triggers")
|
|
|
|
for trigger in self.triggers:
|
|
|
|
self.config.set("triggers", trigger.pattern, self.triggers[trigger])
|
2014-03-26 13:04:20 +01:00
|
|
|
if len(self.json_regs):
|
|
|
|
if not self.config.has_section("json_regs"):
|
|
|
|
self.config.add_section("json_regs")
|
|
|
|
for j in self.json_regs:
|
|
|
|
self.config.set("json_regs", j, self.json_regs[j].pattern)
|
2014-03-25 19:57:18 +01:00
|
|
|
if len(self.filters):
|
|
|
|
if not self.config.has_section("filters"):
|
|
|
|
self.config.add_section("filters")
|
|
|
|
i = 0
|
|
|
|
for r in self.filters:
|
|
|
|
self.config.set("filters", "filter%i" % i, r.pattern)
|
|
|
|
i += 1
|
|
|
|
if len(self.ignores):
|
|
|
|
if not self.config.has_section("ignores"):
|
|
|
|
self.config.add_section("ignores")
|
|
|
|
i = 0
|
|
|
|
for r in self.ignores:
|
|
|
|
self.config.set("ignores", "ignore%i" % i, r.pattern)
|
|
|
|
i += 1
|
2014-05-25 22:57:42 +02:00
|
|
|
if len(self.init_cmd):
|
|
|
|
if not self.config.has_section("init_cmd"):
|
|
|
|
self.config.add_section("init_cmd")
|
|
|
|
i = 0
|
|
|
|
for ic in self.init_cmd:
|
|
|
|
self.config.set("init_cmd", "init_cmd%i" % i, ic)
|
|
|
|
i += 1
|
2014-03-25 19:57:18 +01:00
|
|
|
|
|
|
|
with open(self.configdir + os.path.sep + self.configfile, 'wb') as config_fd:
|
2011-11-30 18:21:11 +01:00
|
|
|
self.config.write(config_fd)
|
2014-06-05 06:32:30 +02:00
|
|
|
self.logger.info("Config saved")
|
2011-11-30 18:21:11 +01:00
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def do_PYTERM_show_config(self, line):
|
2011-11-30 18:21:11 +01:00
|
|
|
for key in self.__dict__:
|
|
|
|
print(str(key) + ": " + str(self.__dict__[key]))
|
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def do_PYTERM_alias(self, line):
|
2011-11-30 18:21:11 +01:00
|
|
|
if line.endswith("list"):
|
|
|
|
for alias in self.aliases:
|
2014-06-05 06:32:30 +02:00
|
|
|
self.logger.info("{} = {}".format(alias, self.aliases[alias]))
|
2011-11-30 18:21:11 +01:00
|
|
|
return
|
|
|
|
if not line.count("="):
|
2014-06-05 06:24:49 +02:00
|
|
|
sys.stderr.write("Usage: /alias <ALIAS> = <CMD>\n")
|
2011-11-30 18:21:11 +01:00
|
|
|
return
|
2014-06-05 07:11:34 +02:00
|
|
|
alias = line.split('=')[0].strip()
|
2014-06-05 07:12:42 +02:00
|
|
|
command = line[line.index('=')+1:].strip()
|
2014-06-05 07:11:34 +02:00
|
|
|
self.logger.info("adding command %s for alias %s" % (command, alias))
|
|
|
|
self.aliases[alias] = command
|
2011-11-30 18:21:11 +01:00
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def do_PYTERM_rmalias(self, line):
|
2011-11-30 18:21:11 +01:00
|
|
|
if not self.aliases.pop(line, None):
|
|
|
|
sys.stderr.write("Alias not found")
|
|
|
|
|
|
|
|
def get_alias(self, tok):
|
|
|
|
for alias in self.aliases:
|
|
|
|
if tok.split()[0] == alias:
|
|
|
|
return self.aliases[alias] + tok[len(alias):]
|
|
|
|
return tok
|
|
|
|
|
2014-06-05 06:25:34 +02:00
|
|
|
def do_PYTERM_trigger(self, line):
|
|
|
|
if not line.count("="):
|
|
|
|
sys.stderr.write("Usage: /trigger <regex> = <CMD>\n")
|
|
|
|
return
|
|
|
|
trigger = line.split('=')[0].strip()
|
2014-06-05 07:12:42 +02:00
|
|
|
action = line[line.index('=')+1:].strip()
|
2014-06-05 06:25:34 +02:00
|
|
|
self.logger.info("adding action %s for trigger %s" % (action, trigger))
|
|
|
|
self.triggers[re.compile(trigger)] = action
|
|
|
|
|
|
|
|
def do_PYTERM_rmtrigger(self, line):
|
|
|
|
if not self.triggers.pop(line, None):
|
|
|
|
sys.stderr.write("Trigger not found")
|
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def do_PYTERM_ignore(self, line):
|
2014-03-25 19:57:18 +01:00
|
|
|
self.ignores.append(re.compile(line.strip()))
|
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def do_PYTERM_unignore(self, line):
|
2014-03-25 19:57:18 +01:00
|
|
|
for r in self.ignores:
|
|
|
|
if (r.pattern == line.strip()):
|
2014-06-05 06:32:30 +02:00
|
|
|
self.logger.info("Remove ignore for %s" % r.pattern)
|
2014-03-25 19:57:18 +01:00
|
|
|
self.ignores.remove(r)
|
|
|
|
return
|
|
|
|
sys.stderr.write("Ignore for %s not found\n" % line.strip())
|
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def do_PYTERM_filter(self, line):
|
2014-03-25 19:57:18 +01:00
|
|
|
self.filters.append(re.compile(line.strip()))
|
2014-03-25 19:18:38 +01:00
|
|
|
|
2014-03-25 19:58:26 +01:00
|
|
|
def do_PYTERM_unfilter(self, line):
|
2014-03-25 19:57:18 +01:00
|
|
|
for r in self.filters:
|
2014-03-25 19:18:38 +01:00
|
|
|
if (r.pattern == line.strip()):
|
2014-06-05 06:32:30 +02:00
|
|
|
self.logger.info("Remove filter for %s" % r.pattern)
|
2014-03-25 19:57:18 +01:00
|
|
|
self.filters.remove(r)
|
2014-03-25 19:18:38 +01:00
|
|
|
return
|
2014-03-25 19:57:18 +01:00
|
|
|
sys.stderr.write("Filter for %s not found\n" % line.strip())
|
2014-03-25 19:18:38 +01:00
|
|
|
|
2014-03-26 13:04:20 +01:00
|
|
|
def do_PYTERM_json(self, line):
|
2014-04-03 17:09:37 +02:00
|
|
|
self.json_regs[line.split(' ')[0].strip()] = re.compile(line.partition(' ')[2].strip())
|
2014-03-26 13:04:20 +01:00
|
|
|
|
|
|
|
def do_PYTERM_unjson(self, line):
|
|
|
|
if not self.aliases.pop(line, None):
|
|
|
|
sys.stderr.write("JSON regex with ID %s not found" % line)
|
|
|
|
|
2014-05-25 22:57:42 +02:00
|
|
|
def do_PYTERM_init(self, line):
|
|
|
|
self.init_cmd.append(line.strip())
|
|
|
|
|
2011-11-30 18:21:11 +01:00
|
|
|
def load_config(self):
|
2014-05-26 21:56:57 +02:00
|
|
|
self.config = configparser.SafeConfigParser()
|
2014-03-25 19:18:15 +01:00
|
|
|
self.config.read([self.configdir + os.path.sep + self.configfile])
|
2011-11-30 18:21:11 +01:00
|
|
|
|
|
|
|
for sec in self.config.sections():
|
2014-03-25 19:57:18 +01:00
|
|
|
if sec == "filters":
|
|
|
|
for opt in self.config.options(sec):
|
|
|
|
self.filters.append(re.compile(self.config.get(sec, opt)))
|
|
|
|
if sec == "ignores":
|
|
|
|
for opt in self.config.options(sec):
|
|
|
|
self.ignores.append(re.compile(self.config.get(sec, opt)))
|
2014-03-26 13:04:20 +01:00
|
|
|
if sec == "json_regs":
|
|
|
|
for opt in self.config.options(sec):
|
2014-06-05 06:32:30 +02:00
|
|
|
self.logger.info("add json regex for %s" % self.config.get(sec, opt))
|
2014-03-26 13:04:20 +01:00
|
|
|
self.json_regs[opt] = re.compile(self.config.get(sec, opt))
|
2011-11-30 18:21:11 +01:00
|
|
|
if sec == "aliases":
|
|
|
|
for opt in self.config.options(sec):
|
|
|
|
self.aliases[opt] = self.config.get(sec, opt)
|
2014-06-05 06:25:34 +02:00
|
|
|
if sec == "triggers":
|
|
|
|
for opt in self.config.options(sec):
|
|
|
|
self.triggers[re.compile(opt)] = self.config.get(sec, opt)
|
2014-05-25 16:57:08 +02:00
|
|
|
if sec == "init_cmd":
|
|
|
|
for opt in self.config.options(sec):
|
|
|
|
self.init_cmd.append(self.config.get(sec, opt))
|
2011-11-30 18:21:11 +01:00
|
|
|
else:
|
|
|
|
for opt in self.config.options(sec):
|
2014-05-26 21:56:57 +02:00
|
|
|
if opt not in self.__dict__:
|
2011-11-30 18:21:11 +01:00
|
|
|
self.__dict__[opt] = self.config.get(sec, opt)
|
|
|
|
|
2014-06-05 06:24:04 +02:00
|
|
|
def process_line(self, line):
|
|
|
|
self.logger.info(line)
|
2014-06-05 06:25:34 +02:00
|
|
|
# check if line matches a trigger and fire the command(s)
|
|
|
|
for trigger in self.triggers:
|
|
|
|
self.logger.debug("comparing input %s to trigger %s" % (line, trigger.pattern))
|
|
|
|
m = trigger.search(line)
|
|
|
|
if m:
|
|
|
|
self.onecmd(self.precmd(self.triggers[trigger]))
|
|
|
|
|
2014-06-05 06:24:04 +02:00
|
|
|
# ckecking if the line should be sent as JSON object to a tcp server
|
|
|
|
if (len(self.json_regs)) and self.factory and self.factory.myproto:
|
|
|
|
for j in self.json_regs:
|
|
|
|
m = self.json_regs[j].search(line)
|
|
|
|
if m:
|
|
|
|
try:
|
|
|
|
json_obj = '{"jid":%d, ' % int(j)
|
|
|
|
except ValueError:
|
|
|
|
sys.stderr.write("Invalid JID: %s\n" % j)
|
|
|
|
break
|
|
|
|
json_obj += '"raw":"%s", ' % line
|
|
|
|
json_obj += '"date":%s, ' % int(time.time()*1000)
|
|
|
|
for g in m.groupdict():
|
|
|
|
try:
|
|
|
|
json_obj += '"%s":%d, ' % (g, int(m.groupdict()[g]))
|
|
|
|
except ValueError:
|
|
|
|
json_obj += '"%s":"%s", ' % (g, m.groupdict()[g])
|
|
|
|
|
|
|
|
# eliminate the superfluous last ", "
|
|
|
|
json_obj = json_obj[:-2]
|
|
|
|
|
|
|
|
json_obj += "}"
|
|
|
|
self.factory.myproto.sendMessage(json_obj)
|
|
|
|
|
|
|
|
def handle_line(self, line):
|
|
|
|
# First check if line should be ignored
|
|
|
|
ignored = False
|
|
|
|
if (len(self.ignores)):
|
|
|
|
for i in self.ignores:
|
|
|
|
if i.search(line):
|
|
|
|
ignored = True
|
|
|
|
break
|
|
|
|
# now check if filter rules should be applied
|
|
|
|
if (len(self.filters)):
|
|
|
|
for r in self.filters:
|
|
|
|
if r.search(line):
|
|
|
|
if not ignored:
|
|
|
|
self.process_line(line)
|
|
|
|
# if neither nor applies print the line
|
|
|
|
else:
|
|
|
|
if not ignored:
|
|
|
|
self.process_line(line)
|
|
|
|
|
|
|
|
|
2014-03-25 19:18:38 +01:00
|
|
|
def reader(self):
|
2014-05-26 15:12:46 +02:00
|
|
|
"""Serial or TCP reader.
|
|
|
|
"""
|
2014-03-25 19:18:38 +01:00
|
|
|
output = ""
|
|
|
|
while (1):
|
2014-05-26 15:12:46 +02:00
|
|
|
try:
|
|
|
|
sr = codecs.getreader("UTF-8")(self.ser, errors='replace')
|
|
|
|
c = sr.read(1)
|
|
|
|
except (serial.SerialException, ValueError) as se:
|
2014-06-05 06:32:30 +02:00
|
|
|
self.logger.warn("Serial port disconnected, waiting to get reconnected...")
|
2014-05-26 15:12:46 +02:00
|
|
|
self.ser.close()
|
|
|
|
time.sleep(1)
|
|
|
|
if os.path.exists(self.port):
|
2014-06-05 06:32:30 +02:00
|
|
|
self.logger.warn("Try to reconnect to %s again..." % (self.port))
|
2014-05-26 15:12:46 +02:00
|
|
|
self.ser = serial.Serial(port=self.port, baudrate=self.baudrate, dsrdtr=0, rtscts=0)
|
|
|
|
self.ser.setDTR(0)
|
|
|
|
self.ser.setRTS(0)
|
|
|
|
continue
|
2014-03-25 19:18:38 +01:00
|
|
|
if c == '\n' or c == '\r':
|
2014-06-05 06:24:04 +02:00
|
|
|
self.handle_line(output)
|
2014-03-25 19:18:38 +01:00
|
|
|
output = ""
|
|
|
|
else:
|
|
|
|
output += c
|
|
|
|
#sys.stdout.write(c)
|
|
|
|
#sys.stdout.flush()
|
2010-11-05 22:36:14 +01:00
|
|
|
|
2014-03-26 13:04:20 +01:00
|
|
|
class PytermProt(Protocol):
|
|
|
|
def dataReceived(self, data):
|
2014-04-03 16:14:38 +02:00
|
|
|
sys.stdout.write(data)
|
2014-03-26 13:04:20 +01:00
|
|
|
|
|
|
|
def sendMessage(self, msg):
|
2014-04-03 19:21:20 +02:00
|
|
|
self.transport.writeSomeData("%d#%s\n" % (len(msg), msg))
|
2014-03-26 13:04:20 +01:00
|
|
|
|
|
|
|
class PytermClientFactory(ReconnectingClientFactory):
|
|
|
|
|
|
|
|
def __init__(self):
|
|
|
|
self.myproto = None
|
|
|
|
|
|
|
|
def buildProtocol(self, addr):
|
|
|
|
print('Connected.')
|
|
|
|
self.resetDelay()
|
|
|
|
self.myproto = PytermProt()
|
|
|
|
return self.myproto
|
|
|
|
|
|
|
|
def clientConnectionLost(self, connector, reason):
|
2014-04-03 16:15:58 +02:00
|
|
|
if reactor.running:
|
|
|
|
print('Lost connection. Reason:', reason)
|
2014-03-26 13:04:20 +01:00
|
|
|
ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
|
|
|
|
|
|
|
|
def clientConnectionFailed(self, connector, reason):
|
|
|
|
print('Connection failed. Reason:', reason)
|
|
|
|
ReconnectingClientFactory.clientConnectionFailed(self, connector,
|
|
|
|
reason)
|
|
|
|
|
2014-04-03 16:14:38 +02:00
|
|
|
def __stop_reactor(signum, stackframe):
|
|
|
|
sys.stderr.write("Ctrl-C is disabled, type '/exit' instead\n")
|
|
|
|
|
2010-11-05 22:36:14 +01:00
|
|
|
if __name__ == "__main__":
|
2011-11-30 18:21:11 +01:00
|
|
|
|
2014-03-25 19:18:15 +01:00
|
|
|
parser = argparse.ArgumentParser(description="Pyterm - The Python terminal program")
|
2014-03-26 00:00:33 +01:00
|
|
|
parser.add_argument("-p", "--port",
|
|
|
|
help="Specifies the serial port to use, default is %s" % defaultport,
|
|
|
|
default=defaultport)
|
|
|
|
parser.add_argument("-b", "--baudrate",
|
|
|
|
help="Specifies baudrate for the serial port, default is %s" % defaultbaud,
|
|
|
|
default=defaultbaud)
|
|
|
|
parser.add_argument('-d', '--directory',
|
|
|
|
help="Specify the Pyterm directory, default is %s" % defaultdir,
|
|
|
|
default=defaultdir)
|
|
|
|
parser.add_argument("-c", "--config",
|
|
|
|
help="Specify the config filename, default is %s" % defaultfile,
|
|
|
|
default=defaultfile)
|
2014-03-26 13:04:20 +01:00
|
|
|
parser.add_argument("-s", "--server",
|
|
|
|
help="Connect via TCP to this server to send output as JSON")
|
|
|
|
parser.add_argument("-P", "--tcp_port", type=int,
|
|
|
|
help="Port at the JSON server")
|
2014-05-25 16:57:08 +02:00
|
|
|
parser.add_argument("-H", "--host",
|
|
|
|
help="Hostname of this maschine")
|
|
|
|
parser.add_argument("-rn", "--run-name",
|
|
|
|
help="Run name, used for logfile")
|
2014-03-25 19:18:15 +01:00
|
|
|
args = parser.parse_args()
|
2010-11-05 22:36:14 +01:00
|
|
|
|
2014-05-25 16:57:08 +02:00
|
|
|
myshell = SerCmd(args.port, args.baudrate, args.directory, args.config, args.host, args.run_name)
|
2011-11-30 18:21:11 +01:00
|
|
|
myshell.prompt = ''
|
2010-11-05 22:36:14 +01:00
|
|
|
|
2014-04-03 16:14:38 +02:00
|
|
|
if args.server and args.tcp_port:
|
|
|
|
myfactory = PytermClientFactory()
|
|
|
|
reactor.connectTCP(args.server, args.tcp_port, myfactory)
|
|
|
|
myshell.factory = myfactory
|
|
|
|
reactor.callInThread(myshell.cmdloop, "Welcome to pyterm!\nType '/exit' to exit.")
|
|
|
|
signal.signal(signal.SIGINT, __stop_reactor)
|
|
|
|
reactor.run()
|
|
|
|
else:
|
|
|
|
myshell.cmdloop("Welcome to pyterm!\nType 'exit' to exit.")
|