Merge branch 'master' of estia:weathermon
[weathermon.git] / weathermon-light
1 #!/usr/bin/python
2
3 import serial
4
5 from os import system
6
7 from pprint import pprint
8
9 from termios import tcflush, TCIOFLUSH
10
11 from time import sleep
12
13 from uuid import getnode
14
15 import sys,traceback
16
17 import pycurl
18 from urllib import urlencode
19 from StringIO import StringIO
20
21 path = None
22 baud = None
23 timeout = None
24
25 import ConfigParser
26
27 import thread
28 from threading import Timer
29
30 def open_port(path):
31
32   global proc
33
34   print "Opening path "+path
35
36   ser = serial.Serial(path,1200);
37   ser.open();
38   ser.close();
39
40   ser = serial.Serial(path,baud,timeout=timeout)
41   if ser.portstr:
42     tcflush(ser,TCIOFLUSH);
43   return ser
44   
45 def read_port(ser):
46
47   try: 
48     timeout_timer = Timer(timeout, thread.interrupt_main)
49     timeout_timer.start()
50     line = ser.readline()
51     return line.strip()
52   except KeyboardInterrupt:
53     return "<<TIMEOUT>>"
54   finally:
55     timeout_timer.cancel()
56   
57 def read_loop(ser,callback):
58
59   global proc
60
61   while True:
62   
63     try:
64       line=read_port(ser)
65       if line=="<<TIMEOUT>>":
66         print "Reopening port..."
67         ser.close()
68         ser=open_port(path)
69       if line:
70         callback(line)
71     except KeyboardInterrupt:
72       break
73     finally:
74       None
75
76 def print_log(str):
77   global logging
78   print str
79   if logging == "on":
80     system("logger -t weathermon \""+str+"\"")
81
82 def submit_data(stype,sid,param,value):
83
84   global url,username,password
85
86   params = {'stype':stype, 'sid':sid, 'param':param, 'value':value}
87
88   pprint (params)
89
90   try:
91
92     response_buffer = StringIO()
93     curl = pycurl.Curl()
94
95     curl.setopt(curl.URL, url)
96     if username:
97       curl.setopt(curl.USERPWD, '%s:%s' % (username, password))
98     curl.setopt(curl.WRITEFUNCTION, response_buffer.write)
99     curl.setopt(curl.POST, 1)
100     curl.setopt(curl.POSTFIELDS, urlencode(params))
101
102     curl.perform()
103     curl.close()
104     
105     response_value = response_buffer.getvalue()
106     
107     print_log('Server response: '+response_value)
108   
109     return True
110   
111   except:
112
113     exc_type, exc_value, exc_traceback = sys.exc_info()
114     traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
115     traceback.print_exception(exc_type, exc_value, exc_traceback,
116                                   limit=2, file=sys.stdout)
117     return False  
118
119 def process_str(str):
120   print_log("Received: "+str)
121   try:
122     msg_type, msg_body = str.split(':')
123   except:
124     return
125   try:  
126     if msg_type == 'STATUS':
127       print_log('Status: '+msg_body)
128     elif msg_type == 'ERROR':
129       print_log('Error: '+ msg_body)
130     elif msg_type == 'SENSOR':
131       sens = msg_body.split(',')
132       sensor = {}
133       sensor_type = None
134       sensor_id = None
135       for rec in sens:
136         key,value = rec.split('=')
137         value=value.strip()
138         if len(value)>0:
139           if key == 'TYPE':
140             sensor_type = value
141           elif key == 'ID':
142             sensor_id = value  
143           else:  
144             sensor[key] = value
145       if sensor_type:    
146         if not sensor_id:
147           sensor_id=devid;    
148       for key in sensor:
149         if sensor[key]:
150           print_log('Type = '+sensor_type+', ID = '+sensor_id+', Param = '+key+', Value = '+sensor[key])
151           submit_data(sensor_type,sensor_id,key,sensor[key])
152         else:
153           print_log('Error: got empty parameter value for '+sensor_type+'.'+sensor_id+'.'+key)
154   except:
155     print_log('Exception processing...')
156     exc_type, exc_value, exc_traceback = sys.exc_info()
157     traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
158     traceback.print_exception(exc_type, exc_value, exc_traceback,
159                               limit=5, file=sys.stdout)  
160
161 def weather_mon():
162
163   global path
164
165   ser = open_port(path)
166   read_loop(ser,process_str)
167
168 def main():
169   weather_mon()
170
171 try:
172
173   cfg = ConfigParser.RawConfigParser(allow_no_value=True)
174   cfg.readfp(open('/etc/weathermon.conf'))
175   url = cfg.get("web","url")
176   path = cfg.get("serial","port");
177   try:
178     username = cfg.get("web","user");
179     password = cfg.get("web","password");
180   except:
181     username = None
182     password = None
183   try:
184     logging = cfg.get("logging","enabled")
185   except:
186     logging = None
187   try:
188     timeout = int(cfg.get("serial","timeout"))
189   except:
190     timeout = 120
191   try:
192     baud = int(cfg.get("serial","baud"))
193   except:
194     baud = 57600
195   try:
196     devid = cfg.get("web","devid")
197   except:
198     devid = "{:0>12X}".format(getnode())   
199  
200 except:
201
202   print_log("Cannot intialize system")
203   exit() 
204   
205 if __name__ == "__main__":
206   import sys
207   reload(sys)
208   sys.setdefaultencoding('utf-8')
209   main()