5 from os import listdir,system
 
   6 from os.path import isfile, join
 
   8 from pprint import pprint
 
  10 from termios import tcflush, TCIOFLUSH
 
  12 from time import sleep,time
 
  14 from uuid import getnode
 
  16 from hashlib import md5
 
  23 from urllib import urlencode
 
  24 from StringIO import StringIO
 
  26 searchpath = '/dev/serial/by-id/'
 
  31 external_submit_interval = 320
 
  32 owm_submit_interval = 320
 
  33 expire_interval = 1200
 
  35 submit_time_owm = time()
 
  46   files = listdir(searchpath)
 
  49       return join(searchpath,f)
 
  54   ser = serial.Serial(path,baud,timeout)
 
  56     tcflush(ser,TCIOFLUSH);
 
  64 def read_loop(ser,callback):
 
  72     except KeyboardInterrupt:
 
  81     system("logger -t weathermon \""+str+"\"")
 
  83 def submit_narodmon(queue):
 
  85   param = { 'ID':"{:X}".format(getnode())}
 
  90     value = submit_queue[sensor]['val']
 
  91     timestamp = submit_queue[sensor]['timestamp']
 
  92     digest = md5(sensor).hexdigest()[:18]
 
  93     param[digest] = value;
 
  97   url = "http://narodmon.ru/post.php"
 
 101     response_buffer = StringIO()
 
 104     curl.setopt(curl.URL, url)
 
 105     curl.setopt(curl.WRITEFUNCTION, response_buffer.write)   
 
 106     curl.setopt(curl.POST, 1)
 
 107     curl.setopt(curl.POSTFIELDS, urlencode(param))
 
 112     response_value = response_buffer.getvalue()
 
 114     print_log('Narodmon response: '+response_value)
 
 120     exc_type, exc_value, exc_traceback = sys.exc_info()
 
 121     traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
 
 122     traceback.print_exception(exc_type, exc_value, exc_traceback,
 
 123                               limit=2, file=sys.stdout)  
 
 126 def submit_owm(queue):
 
 128   url = "http://openweathermap.org/data/post"
 
 129   params = {'name':owm_station, 'lat':owm_lat, 'long':owm_lon}
 
 134       params['temp'] = queue[owm_temp]['val']
 
 135       params['pressure'] = queue[owm_pres]['val']
 
 136       params['humidity'] = queue[owm_humi]['val']
 
 140     response_buffer = StringIO()
 
 143     curl.setopt(curl.URL, url)
 
 144     curl.setopt(curl.USERPWD, '%s:%s' % (owmuser, owmpasswd))
 
 145     curl.setopt(curl.WRITEFUNCTION, response_buffer.write)
 
 146     curl.setopt(curl.POST, 1)
 
 147     curl.setopt(curl.POSTFIELDS, urlencode(params))
 
 152     response_value = response_buffer.getvalue()
 
 154     print_log('Openweathermap response: '+response_value)
 
 160     exc_type, exc_value, exc_traceback = sys.exc_info()
 
 161     traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
 
 162     traceback.print_exception(exc_type, exc_value, exc_traceback,
 
 163                                   limit=2, file=sys.stdout)
 
 169   for key in submit_queue:
 
 170     if submit_queue[key]['timestamp'] < time()-expire_interval:
 
 171       print_log("Expired value for "+key)
 
 176 def submit_data(sensor_type,sensor_id,sensor_param,param_value):
 
 178   global submit_time_owm
 
 179   global external_submit_interval
 
 180   global owm_submit_interval
 
 182   c = database.cursor()
 
 183   c.execute('CALL meteo.submit_value(%s,%s,%s,%s,NULL)', (sensor_type,sensor_id,sensor_param,param_value))
 
 185   submit_queue[sensor_type+'.'+sensor_id+'.'+sensor_param]={'val':param_value,'timestamp':time()}
 
 186   if time()>submit_time+external_submit_interval:
 
 187     submit_narodmon(submit_queue)
 
 189   if owmuser and time()>submit_time_owm+owm_submit_interval:
 
 190     submit_owm(submit_queue)
 
 191     submit_time_owm=time()
 
 195 def process_str(str):
 
 196   print_log("Received: "+str)
 
 198     msg_type, msg_body = str.split(':')
 
 202     if msg_type == 'STATUS':
 
 203       print_log('Status: '+msg_body)
 
 204     elif msg_type == 'ERROR':
 
 205       print_log('Error: '+ msg_body)
 
 206     elif msg_type == 'SENSOR':
 
 207       sens = msg_body.split(',')
 
 212         key,value = rec.split('=')
 
 223         if sensor[key] is not None:
 
 224           print_log('Type = '+sensor_type+', ID = '+sensor_id+', Param = '+key+', Value = '+sensor[key])
 
 225           submit_data(sensor_type,sensor_id,key,sensor[key])
 
 227           print_log('Error: got empty parameter value for '+sensor_type+'.'+sensor_id+'.'+key)
 
 229     print_log('Exception processing...')
 
 230     exc_type, exc_value, exc_traceback = sys.exc_info()
 
 231     traceback.print_tb(exc_traceback, limit=1, file=sys.stdout)
 
 232     traceback.print_exception(exc_type, exc_value, exc_traceback,
 
 233                               limit=5, file=sys.stdout)  
 
 246   ser = open_port(path)
 
 247   read_loop(ser,process_str)
 
 258       database = MySQLdb.connect(host=dbhost,user=dbuser,passwd=dbpasswd,use_unicode=True,connect_timeout=10)
 
 259       database.set_character_set('utf8')
 
 260       c = database.cursor()
 
 261       c.execute('SET NAMES utf8;')
 
 262       print_log("Database connected...")
 
 267       print_log("Error connecting database")
 
 275   cfg = ConfigParser.RawConfigParser(allow_no_value=True)
 
 276   cfg.readfp(open('/etc/weathermon.conf'))
 
 277   dbhost = cfg.get("mysql","host")
 
 278   dbuser = cfg.get("mysql","user")
 
 279   dbpasswd = cfg.get("mysql","passwd")
 
 281     path = cfg.get("serial","port");
 
 285     serialnum = cfg.get("serial","id")
 
 289     logging = cfg.get("logging","enabled")
 
 292   owmuser = cfg.get("openweathermap","user")
 
 293   owmpasswd = cfg.get("openweathermap",'passwd')
 
 295     owm_temp = cfg.get("openweathermap",'temp')
 
 296     owm_pres = cfg.get("openweathermap",'pres')
 
 297     owm_humi = cfg.get("openweathermap",'humi')
 
 298     owm_lat = cfg.get("openweathermap",'lat')
 
 299     owm_lon = cfg.get("openweathermap",'lon')
 
 300     owm_station = cfg.get("openweathermap",'station')
 
 305   print_log("Cannot intialize system")
 
 308 if __name__ == "__main__":
 
 311   sys.setdefaultencoding('utf-8')