5
rpyterm - Control your RP6 robot
6
Copyright (C) 2011 Scirocco <rpyutils@t-online.de>
8
This program is free software: you can redistribute it and/or modify
9
it under the terms of the GNU General Public License as published by
10
the Free Software Foundation, either version 3 of the License, or
11
(at your option) any later version.
13
This program is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
18
You should have received a copy of the GNU General Public License
19
along with this program. If not, see <http://www.gnu.org/licenses/>.
22
"""rpyutils by Maximilian Mühlbauer <rpyutils@t-online.de>"""
34
from rpyutils.translation import _
36
def quit(signum, frame): #Strg+C abfangen. Ideen, wie man curses beenden kann?
39
signal.signal(signal.SIGINT, quit)#signal "connecten"
43
print(_("Robby pyTerm version ")+VERSION) #immer version ausgeben
45
print("rpyutils Copyright (C) 2011 Scirocco <rpyutils@t-online.de>")
46
print("This program comes with ABSOLUTELY NO WARRANTY; for details please visit http://www.gnu.org/licenses/gpl.html")
47
print("This is free software, and you are welcome to redistribute it under certain conditions; visit http://www.gnu.org/licenses/gpl.html for details.")
50
def getargs(argv): #funktion, um parameter auszulesen
51
global port #port ist global
52
port = "/dev/ttyUSB0" #standard-port
53
try: #optionen versuchen
54
opts, args = getopt.getopt(argv, "d:", ["device="]) #optionen auslesen
55
except getopt.GetoptError: #falsche option?
56
print("Wrong option.")
57
for opt, arg in opts: #wenn optionen
58
if opt in ("-d", "--device"): #device
60
port = arg #port auf device setzen
62
getargs(sys.argv[1:])#1.arg (rpyTerm.py) nicht
65
# make stdin a non-blocking file
66
fd = sys.stdin.fileno()
67
fl = fcntl.fcntl(fd, fcntl.F_GETFL)
68
fcntl.fcntl(fd, fcntl.F_SETFL, fl |os.O_NONBLOCK)
69
pipe_name = '/tmp/pypipe' #pipe zwischen robby auslesen und prog
72
pipeout = os.open(pipe_name, os.O_WRONLY)#pipe öffnen
78
parity=serial.PARITY_NONE, #keine Parität
79
stopbits=serial.STOPBITS_ONE, #ein stopbit
80
bytesize=serial.EIGHTBITS #acht bits
82
except: #Port existiert nicht
83
print(port+_(": No such a device."))
87
ser.setRTS(0) #rts aus
89
s = ser.read(1)#char von robby lesen &
90
os.write(pipeout, s)#ueber pipe weiterleiten
93
histfile = "rpyTermhistory" #history fuer session in datei speichern
94
rpyUtilsdir = ".rpyUtils"#verstecktes verzeichnis
96
histpath = os.environ['HOME']+ os.sep +rpyUtilsdir + os.sep + histfile #linux: ~/.rpyUtils/rpyTermhistory
97
if not os.path.exists(os.environ['HOME']+ os.sep+rpyUtilsdir): #verzeichnis existiert nicht?
98
os.mkdir(os.environ['HOME']+ os.sep+rpyUtilsdir)#anlegen
99
if not os.path.isfile(histpath):
100
f = open(histpath, "a")
103
hist = open(histpath, "r")
105
histcounter = histcounter + 1
107
readline.read_history_file(histpath)
108
ser = serial.Serial(#serial port zu robby oeffnen
110
baudrate=38400, #baud
112
parity=serial.PARITY_NONE, #keine
113
stopbits=serial.STOPBITS_ONE, #ein stopbit
114
bytesize=serial.EIGHTBITS #acht bits
116
ser.setRTS(0) #rts aus
118
time.sleep(0.2) #anderem prog zeit lassen
119
pipein = open(pipe_name, "r")#pipe oeffnen
120
fl = fcntl.fcntl(pipein, fcntl.F_GETFL)#pipein
121
fcntl.fcntl(pipein, fcntl.F_SETFL, fl |os.O_NONBLOCK)#nonblocking machen
123
stdscr = curses.initscr()#start
124
curses.noecho()# Keine Anzeige gedrückter Tasten
125
curses.cbreak()# Kein line-buffer -> kann eingreifen
126
stdscr.keypad(1)# Escape-Sequenzen aktivieren
130
curses.init_pair(1, curses.COLOR_GREEN, curses.COLOR_BLUE)
131
curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_WHITE)
132
curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_WHITE)
134
# Fenster und Hintergrundfarben
135
stdscr.bkgd(curses.color_pair(1))
138
termy, termx = stdscr.getmaxyx() #groesse von terminalfenster ermitteln
140
win = curses.newwin((termy-4), termx, 0, 0)#groesse: max. breite, unten 4 uebrig lassen
141
win.bkgd(curses.color_pair(2))
145
win2 = curses.newwin(4, termx, (termy-4), 0)#groesse: max. breite, vier unterste zeilen
147
win2.bkgd(curses.color_pair(3))
148
win2.keypad(1) #fuer key_up etc
151
win2.timeout(0)#non-blocking lesen: keine daten -> -1
153
win2.addstr(1, 2, _("Please Enter your command (help for a list of built-in commands): "))
154
win2.addstr(2, 2, "")
157
pad = curses.newpad(pad_height, 1000)#pad fuer term
158
maxy, maxx = win.getmaxyx()#groesse von win1 ermitteln
160
# Wir merken uns, wo wir sind -> scrollen
164
i=2 #pad bei 2.Zeile anfangen
165
zeile = ">> " #von robby : >> am anfang, z.B.( >> [RP6BOOT] )
166
line = "" #von tastatur: leerer string
167
pad.addstr(1, 2, _("Robby pyTerm version ")+str(VERSION)) #begruessung
168
pad.refresh(line_start, col_start, 1, 1, maxy-2, maxx-2) #pad updaten
170
cur_histcounter = histcounter
171
while True and exit == 0:
173
read = pipein.read(1)#IOError wenn keine Daten
174
zeile += read#Byte dem String anfügen
176
pad.addstr(i, 2, zeile)#aufs pad schreiben
177
line_start = i-maxy+4
178
pad.refresh(line_start, col_start, 1, 1, maxy-2, maxx-2)#pad, wenn noetig, verschieben
180
zeile = ">> "#zeile leeren
183
if i > pad_height -2:
186
char = win2.getch() #user-input einlesen
187
if char != -1: #char wartet!
188
if char == curses.KEY_BACKSPACE: #127:#loeschtaste
189
win2.delch()#char loeschen
190
line = line[0:(len(line)-1)]#von line letzten char loeschen
193
win2.addstr(1, 2, _("Please Enter your command (help for a list of built-in commands): "))
194
win2.addstr(2, 2, line)
195
win2.refresh() #refreshen
196
elif char == curses.KEY_UP:
197
cur_histcounter = cur_histcounter - 1
200
win2.addstr(1, 2, _("Please Enter your command (help for a list of built-in commands): "))
201
line = readline.get_history_item(cur_histcounter)
202
#print(cur_histcounter)
206
cur_histcounter = cur_histcounter + 1
207
win2.addstr(2, 2, line)
208
win2.refresh() #refreshen
209
elif char == curses.KEY_DOWN:
210
cur_histcounter = cur_histcounter + 1
213
win2.addstr(1, 2, _("Please Enter your command (help for a list of built-in commands): "))
214
line = readline.get_history_item(cur_histcounter)
215
#print(cur_histcounter)
219
cur_histcounter = cur_histcounter - 1
220
win2.addstr(2, 2, line)
221
win2.refresh() #refreshen
222
elif char == curses.KEY_NPAGE: #bild auf
229
if line_start > i-maxy+4:
230
line_start = i-maxy+4
232
pad.refresh(line_start, col_start, 1, 1, maxy-2, maxx-2)
233
elif char == curses.KEY_PPAGE: #bild ab
243
pad.refresh(line_start, col_start, 1, 1, maxy-2, maxx-2)
244
elif char == curses.KEY_END:
246
line_start = i-maxy+4
247
pad.refresh(line_start, col_start, 1, 1, maxy-2, maxx-2)
248
elif char == 10: #enter
249
histcounter = histcounter +1
250
cur_histcounter = histcounter
251
readline.add_history(line)
252
if(line == "help"):#hilfe ausgeben
253
pad.addstr(i, 2, _("+--------------------------------------------------+"))
255
pad.addstr(i, 2, _("| pyTerm help |"))
257
pad.addstr(i, 2, _("| Built-in Commands: |"))
259
pad.addstr(i, 2, _("| exit: Exit pyTerm |"))
261
pad.addstr(i, 2, _("| reset: Reset RP6 |"))
263
pad.addstr(i, 2, _("| start: Start Program on RP6 |"))
265
pad.addstr(i, 2, _("| Keys: |"))
267
pad.addstr(i, 2, _("| PageUp: Scroll up in Term |"))
269
pad.addstr(i, 2, _("| PageDown: Scroll down in Term |"))
271
pad.addstr(i, 2, _("| End: stop scrolling |"))
273
pad.addstr(i, 2, _("+--------------------------------------------------+"))
274
elif line == "exit": #ende
275
exit = 1 #endlosschleife verlassen
276
os.kill(pid, signal.SIGTERM) #child (robbytopipe) killen
277
elif line == "reset": #robby-reset
278
ser.setRTS(1) #rts ein
279
time.sleep(0.1) #kurz warten
280
ser.setRTS(0) #rts aus
281
elif line == "start":
283
ser.write(bytes('s', encoding='ascii'))#
284
ser.write(bytes("\x0A", encoding='ascii'))
285
except:#python 2.6 fallback
289
pad.addstr(i, 2, "# "+line) #befehl auf pad schreiben
291
ser.write(bytes(line, encoding='ascii'))#
292
ser.write(bytes("\x0A", encoding='ascii'))
293
except:#python 2.6 fallback
296
line_start = i-maxy+4
297
pad.refresh(line_start, col_start, 1, 1, maxy-2, maxx-2)
301
win2.addstr(1, 2, _("Please Enter your command (help for a list of built-in commands): "))
302
win2.addstr(2, 2, "")
305
elif char > 31 and char < 127:
313
readline.write_history_file(histpath)
315
if not os.path.exists(pipe_name):