comparison server/ts.py @ 395:f0ddb75bcf04

main.c : add a delay before turning on uart server : try and improve timeouts, get rid of lightblue, don't use https, use python logging module
author Matt Johnston <matt@ucc.asn.au>
date Sun, 15 Jul 2012 21:49:59 +0800
parents b33045e7e08e
children 231662c6690c
comparison
equal deleted inserted replaced
394:2cd246ea92c6 395:f0ddb75bcf04
17 import binascii 17 import binascii
18 import hmac 18 import hmac
19 import zlib 19 import zlib
20 import urllib 20 import urllib
21 import urllib2 21 import urllib2
22 import logging
23
24 L = logging.info
25 W = logging.warning
26 E = logging.error
22 27
23 import config 28 import config
24 29
25 from utils import monotonic_time, retry, readline, crc16 30 from utils import monotonic_time, retry, readline, crc16
26 import utils 31 import utils
27 32
28 lightblue = None 33 import bluetooth
29 try:
30 import lightblue
31 except ImportError:
32 import bluetooth
33 34
34 def get_socket(addr): 35 def get_socket(addr):
35 if lightblue: 36 s = bluetooth.BluetoothSocket( bluetooth.RFCOMM )
36 s = lightblue.socket() 37 s.settimeout(1)
37 s.connect((addr, 1)) 38 s.connect((addr, 1))
38 s.settimeout(3)
39 else:
40 s = bluetooth.BluetoothSocket( bluetooth.RFCOMM )
41 s.connect((addr, 1))
42
43 s.setblocking(False)
44 39
45 return s 40 return s
46 41
47 42
48 @retry() 43 @retry()
49 def fetch(sock): 44 def fetch(sock):
50 print "fetch"
51 sock.send("fetch\n") 45 sock.send("fetch\n")
52 46
53 crc = 0 47 crc = 0
54 48
55 lines = [] 49 lines = []
56 l = readline(sock) 50 l = readline(sock)
57 if l != 'START\n': 51 if l != 'START\n':
58 print>>sys.stderr, "Bad expected START line '%s'\n" % l.rstrip('\n') 52 W("Bad expected START line '%s'\n" % l.rstrip('\n'))
59 return None 53 return None
60 crc = crc16(l, crc) 54 crc = crc16(l, crc)
61 55
62 while True: 56 while True:
63 l = readline(sock) 57 l = readline(sock)
67 if l == 'END\n': 61 if l == 'END\n':
68 break 62 break
69 63
70 lines.append(l.rstrip('\n')) 64 lines.append(l.rstrip('\n'))
71 65
72 print lines 66 for d in lines:
73 67 L("Received: %s" % d)
68
74 l = readline(sock) 69 l = readline(sock)
75 recv_crc = None 70 recv_crc = None
76 try: 71 try:
77 k, v = l.rstrip('\n').split('=') 72 k, v = l.rstrip('\n').split('=')
78 print k,v
79 if k == 'CRC': 73 if k == 'CRC':
80 recv_crc = int(v) 74 recv_crc = int(v)
81 if recv_crc < 0 or recv_crc > 0xffff: 75 if recv_crc < 0 or recv_crc > 0xffff:
82 recv_crc = None 76 recv_crc = None
83 except ValueError: 77 except ValueError:
84 pass 78 pass
85 79
86 if recv_crc is None: 80 if recv_crc is None:
87 print>>sys.stderr, "Bad expected CRC line '%s'\n" % l.rstrip('\n') 81 W("Bad expected CRC line '%s'\n" % l.rstrip('\n'))
88 return None 82 return None
89 83
90 if recv_crc != crc: 84 if recv_crc != crc:
91 print>>sys.stderr, "Bad CRC: calculated 0x%x vs received 0x%x\n" % (crc, recv_crc) 85 W("Bad CRC: calculated 0x%x vs received 0x%x\n" % (crc, recv_crc))
92 return None 86 return None
93 87
94 return lines 88 return lines
95 89
96 @retry() 90 @retry()
97 def turn_off(sock): 91 def turn_off(sock):
98 if TESTING: 92 if TESTING:
99 return 99 93 return 99
100 print>>sys.stderr, "sending btoff" 94 L("Sending btoff")
101 sock.send("btoff\n"); 95 sock.send("btoff\n");
102 # read newline 96 # read newline
103 l = readline(sock) 97 l = readline(sock)
104 if not l: 98 if not l:
105 print>>sys.stderr, "Bad response to btoff\n" 99 W("Bad response to btoff")
106 return None 100 return None
107 101
108 if not l.startswith('off:'): 102 if not l.startswith('off:'):
109 print>>sys.stderr, "Bad response to btoff '%s'\n" % l 103 W("Bad response to btoff '%s'" % l)
110 return None 104 return None
111 off, next_wake = l.rstrip().split(':') 105 off, next_wake = l.rstrip().split(':')
112 print>>sys.stderr, "Next wake %s" % next_wake 106 L("Next wake %s" % next_wake)
113 107
114 return int(next_wake) 108 return int(next_wake)
115 109
116 @retry() 110 @retry()
117 def clear_meas(sock): 111 def clear_meas(sock):
118 sock.send("clear\n"); 112 sock.send("clear\n");
119 l = readline(sock) 113 l = readline(sock)
120 if l and l.rstrip() == 'cleared': 114 if l and l.rstrip() == 'cleared':
121 return True 115 return True
122 116
123 print>>sys.stderr, "Bad response to clear %s\n" % str(l) 117 E("Bad response to clear '%s'" % str(l))
124 return False 118 return False
125 119
126 def send_results(lines): 120 def send_results(lines):
127 enc_lines = binascii.b2a_base64(zlib.compress('\n'.join(lines))) 121 enc_lines = binascii.b2a_base64(zlib.compress('\n'.join(lines)))
128 mac = hmac.new(config.HMAC_KEY, enc_lines).hexdigest() 122 mac = hmac.new(config.HMAC_KEY, enc_lines).hexdigest()
131 con = urllib2.urlopen(config.UPDATE_URL, url_data) 125 con = urllib2.urlopen(config.UPDATE_URL, url_data)
132 result = con.read(100) 126 result = con.read(100)
133 if result == 'OK': 127 if result == 'OK':
134 return True 128 return True
135 else: 129 else:
136 print>>sys.stderr, "Bad result '%s'" % result 130 W("Bad result '%s'" % result)
137 return False 131 return False
138 132
139 def do_comms(sock): 133 def do_comms(sock):
140 print "do_comms" 134 L("do_comms")
141 d = None 135 d = None
142 # serial could be unreliable, try a few times 136 # serial could be unreliable, try a few times
143 for i in range(FETCH_TRIES): 137 d = fetch(sock)
144 d = fetch(sock)
145 if d:
146 break
147 time.sleep(1)
148 if not d: 138 if not d:
149 return 139 return
150 140
151 res = send_results(d) 141 res = send_results(d)
152 if not res: 142 if not res:
166 length = until - monotonic_time() 156 length = until - monotonic_time()
167 if length <= 0: 157 if length <= 0:
168 return 158 return
169 time.sleep(length) 159 time.sleep(length)
170 160
161 def setup_logging():
162 logging.basicConfig(format='%(asctime)s %(message)s',
163 datefmt='%m/%d/%Y %I:%M:%S %p')
164
171 def main(): 165 def main():
172 next_wake_time = 0 166 setup_logging()
167
168 L("Running templog rfcomm server")
173 169
174 if '--daemon' in sys.argv: 170 if '--daemon' in sys.argv:
175 utils.cheap_daemon() 171 utils.cheap_daemon()
176 172
177 while True: 173 while True:
178 sock = None 174 sock = None
179 try: 175 try:
180 sock = get_socket(config.BTADDR) 176 sock = get_socket(config.BTADDR)
181 except Exception, e: 177 except Exception, e:
182 print>>sys.stderr, "Error connecting:" 178 pass
183 traceback.print_exc(file=sys.stderr) 179 #print>>sys.stderr, "Error connecting:"
180 #traceback.print_exc(file=sys.stderr)
181 next_wake_time = 0
182 if sock:
183 try:
184 avr_wake = do_comms(sock)
185 next_wake_time = time.time() + avr_wake
186 except Exception, e:
187 logging.exception("Error in do_comms")
188
189 next_wake_interval = next_wake_time - time.time() - EXTRA_WAKEUP
184 sleep_time = config.SLEEP_TIME 190 sleep_time = config.SLEEP_TIME
185 if sock: 191 if next_wake_interval > 0:
186 next_wake = None 192 sleep_time = min(next_wake_interval, sleep_time)
187 try: 193 L("Sleeping for %d, next wake time %f" % (sleep_time, next_wake_time))
188 next_wake_interval = do_comms(sock)
189 next_wake_time = time.time() + next_wake_interval
190 except Exception, e:
191 print>>sys.stderr, "Error in do_comms:"
192 traceback.print_exc(file=sys.stderr)
193 if next_wake_time > time.time():
194 sleep_time = min(next_wake_time - time.time() - EXTRA_WAKEUP, sleep_time)
195
196 print "Sleeping for %d" % sleep_time
197 sleep_for(sleep_time) 194 sleep_for(sleep_time)
198 195
199 if __name__ == '__main__': 196 if __name__ == '__main__':
200 main() 197 main()