Mercurial > templog
comparison server/ts.py @ 89:51d889ad39a3
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 | 0f7c005b3f87 |
children | 231662c6690c |
comparison
equal
deleted
inserted
replaced
88:6f4497a448e8 | 89:51d889ad39a3 |
---|---|
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() |