beep when GPS ready
[protos/xbee-avr.git] / dump_stats.py
1 #! /usr/bin/env python
2
3 import os,sys,termios,atexit
4 import serial
5 from select import select
6 import cmd
7 #import pylab
8 from  matplotlib import pylab
9 from math import *
10
11 import struct
12 import numpy
13 import shlex
14 import time
15 import math
16 import warnings
17 warnings.filterwarnings("ignore","tempnam",RuntimeWarning, __name__)
18
19 import logging
20 log = logging.getLogger("XbeeShell")
21 _handler = logging.StreamHandler()
22 _handler.setFormatter(logging.Formatter("%(levelname)s: %(message)s"))
23 log.addHandler(_handler)
24 log.setLevel(1)
25
26 class SerialLogger:
27     def __init__(self, ser, filein, fileout=None):
28         self.ser = ser
29         self.filein = filein
30         self.fin = open(filein, "a", 0)
31         if fileout:
32             self.fileout = fileout
33             self.fout = open(fileout, "a", 0)
34         else:
35             self.fileout = filein
36             self.fout = self.fin
37     def fileno(self):
38         return self.ser.fileno()
39     def read(self, *args):
40         res = self.ser.read(*args)
41         self.fin.write(res)
42         return res
43     def write(self, s):
44         self.fout.write(s)
45         self.ser.write(s)
46     def readline(self, *args):
47         res = self.ser.readline(*args)
48         self.fin.write(res)
49         return res
50
51 class Interp(cmd.Cmd):
52     prompt = "Xbee> "
53     def __init__(self, tty, baudrate=57600):
54         cmd.Cmd.__init__(self)
55         self.ser = serial.Serial(tty,baudrate=baudrate,timeout=0.1)
56         self.escape  = "\x01" # C-a
57         self.quitraw = "\x02" # C-b
58         self.serial_logging = False
59         self.default_in_log_file = "/tmp/xbee.in.log"
60         self.default_out_log_file = "/tmp/xbee.out.log"
61
62     def do_log(self, args):
63         """Activate serial logs.
64         log <filename>           logs input and output to <filename>
65         log <filein> <fileout>   logs input to <filein> and output to <fileout>
66         log                      logs to /tmp/microb.log or the last used file"""
67
68         if self.serial_logging:
69             log.error("Already logging to %s and %s" % (self.ser.filein,
70                                                         self.ser.fileout))
71         else:
72             self.serial_logging = True
73             files = [os.path.expanduser(x) for x in args.split()]
74             if len(files) == 0:
75                 files = [self.default_in_log_file, self.default_out_log_file]
76             elif len(files) == 1:
77                 self.default_in_log_file = files[0]
78                 self.default_out_log_file = None
79             elif len(files) == 2:
80                 self.default_in_log_file = files[0]
81                 self.default_out_log_file = files[1]
82             else:
83                 print "Can't parse arguments"
84
85             self.ser = SerialLogger(self.ser, *files)
86             log.info("Starting serial logging to %s and %s" % (self.ser.filein,
87                                                                self.ser.fileout))
88
89
90     def do_unlog(self, args):
91         if self.serial_logging:
92             log.info("Stopping serial logging to %s and %s" % (self.ser.filein,
93                                                                self.ser.fileout))
94             self.ser = self.ser.ser
95             self.serial_logging = False
96         else:
97             log.error("No log to stop")
98
99     def do_raw(self, args):
100         "Switch to RAW mode"
101         stdin = os.open("/dev/stdin",os.O_RDONLY)
102         stdout = os.open("/dev/stdout",os.O_WRONLY)
103
104         stdin_termios = termios.tcgetattr(stdin)
105         raw_termios = stdin_termios[:]
106
107         try:
108             log.info("Switching to RAW mode")
109
110             # iflag
111             raw_termios[0] &= ~(termios.IGNBRK | termios.BRKINT |
112                                 termios.PARMRK | termios.ISTRIP |
113                                 termios.INLCR | termios.IGNCR |
114                                 termios.ICRNL | termios.IXON)
115             # oflag
116             raw_termios[1] &= ~termios.OPOST;
117             # cflag
118             raw_termios[2] &= ~(termios.CSIZE | termios.PARENB);
119             raw_termios[2] |= termios.CS8;
120             # lflag
121             raw_termios[3] &= ~(termios.ECHO | termios.ECHONL |
122                                 termios.ICANON | termios.ISIG |
123                                 termios.IEXTEN);
124
125             termios.tcsetattr(stdin, termios.TCSADRAIN, raw_termios)
126
127             mode = "normal"
128             while True:
129                 ins,outs,errs=select([stdin,self.ser],[],[])
130                 for x in ins:
131                     if x == stdin:
132                         c = os.read(stdin,1)
133                         if mode  == "escape":
134                             mode =="normal"
135                             if c == self.escape:
136                                 self.ser.write(self.escape)
137                             elif c == self.quitraw:
138                                 return
139                             else:
140                                 self.ser.write(self.escape)
141                                 self.ser.write(c)
142                         else:
143                             if c == self.escape:
144                                 mode = "escape"
145                             else:
146                                 self.ser.write(c)
147                     elif x == self.ser:
148                         os.write(stdout,self.ser.read())
149         finally:
150             termios.tcsetattr(stdin, termios.TCSADRAIN, stdin_termios)
151             log.info("Back to normal mode")
152
153     def do_dump_stats(self, args):
154         """send hello at power 4 and dump stats regulary"""
155
156         self.ser.write("write power-level 4\n")
157         prev_reset = time.time()
158         try:
159             while True:
160                 # send hellos during 1 s
161                 self.ser.write("rc_proto_hello wing 30 30 tototiti\n")
162                 time.sleep(1.5)
163
164                 # send a reset every 60 s
165                 t = time.time()
166                 if t - prev_reset > 60:
167                     self.ser.write("write soft-reset\n")
168                     prev_reset = t
169
170                 # display time & stats
171                 self.ser.fin.write("\nTIME:%s\n"%(time.time()))
172                 self.ser.write("rc_proto_stats show\n")
173                 while True:
174                     l = self.ser.readline()
175                     sys.stdout.write(l)
176                     if l == "":
177                         break
178         except KeyboardInterrupt:
179             pass
180
181
182 if __name__ == "__main__":
183     try:
184         import readline,atexit
185     except ImportError:
186         pass
187     else:
188         histfile = os.path.join(os.environ["HOME"], ".xbee")
189         atexit.register(readline.write_history_file, histfile)
190         try:
191             readline.read_history_file(histfile)
192         except IOError:
193             pass
194
195     device = "/dev/ttyS0"
196     if len(sys.argv) > 1:
197         device = sys.argv[1]
198     interp = Interp(device)
199     interp.do_log("")
200     while 1:
201         try:
202             interp.cmdloop()
203         except KeyboardInterrupt:
204             print
205         except Exception,e:
206             l = str(e).strip()
207             if l:
208                 log.exception("%s" % l.splitlines()[-1])
209             continue
210         break