﻿#! /usr/bin/python

import pythoncom 
import win32serviceutil 
import win32service 
import win32event 
import servicemanager 
import socket 

from xbee import XBee
import _mysql
import select 
from datetime import datetime 
from datetime import timedelta
import logging
import urllib2
import json
import rfc822
import time

			
def getOutsideTemp():
	try:
		global tempVal
		global tempTime
		global projected 
		global projectedTime 
		
		#logger.debug('Trying to get JSON from wunderground')
		wunderground = urllib2.urlopen('http://api.wunderground.com/api/myHash/conditions/hourly/q/EFTU.json')
		json_string = wunderground.read()
		parsed_json = json.loads(json_string)
		tempVal = parsed_json['current_observation']['temp_c']
		tempTime = parsed_json['current_observation']['observation_time_rfc822']
		tempTime = datetime.strptime(tempTime[:-6], '%a, %d %b %Y %H:%M:%S')
		
		projected = parsed_json['hourly_forecast'][7]['temp']['metric']
		projectedTime = tempTime +timedelta(hours=8) 
		
		wunderground.close()

	except:
		logger.error('Problem with getting outside temp in JSON. wunderground = '+str(wunderground) +' and json_string = '+str(json_string))
		logger.error(sys.exc_info()[0])
		print "Unexpected error:", sys.exc_info()[0]
		raise
		return 99
		
def writeToDatabase():
	global prevForcastTime
	global prevTempTime
	try:
		if (str(prevTempTime) != str(tempTime)):
			# Current outside temp
			insertString = 'Insert into temperatures (sensorId, temp, _timestamp, _date, _time) \
			values(99, '+str(tempVal) +', "'+str(tempTime) +'", "'+str(tempTime.strftime('%Y-%m-%d')) +'", "'+str(tempTime.strftime('%H:%M:%S')) +'")'
			#print insertString
			print 'Current temp ' +str(tempVal) +' at time ' +str(tempTime)
			logger.debug('Current temp ' +str(tempVal) +' at time ' +str(tempTime))
			mySqlCon.query(insertString)
			prevTempTime = tempTime
		if (str(prevForcastTime) != str(projectedTime)): 
			# Projected temp
			insertString = 'Insert into temperatures (sensorId, temp, _timestamp, _date, _time) \
			values(98, '+str(projected) +', "'+str(projectedTime) +'", "'+str(projectedTime.strftime('%Y-%m-%d')) +'", "'+str(projectedTime.strftime('%H:%M:%S')) +'")'
			#print insertString
			print 'Forecast 8h temp ' +str(projected) +' at time ' +str(projectedTime)
			logger.debug('Forecast 8h temp ' +str(projected) +' at time ' +str(projectedTime))
			mySqlCon.query(insertString)
			prevForcastTime = projectedTime
	except:
		logger.error('Failed to write data into database.')
		logger.error(sys.exc_info()[0])
		print "Unexpected error:", sys.exc_info()[0]
		getOutsideTemp()
		
def initLogger():
	try:
		global logger 
		logger = logging.getLogger('myapp')
		hdlr = logging.FileHandler('C:/myHomeWebsite/logs/getOutsideTemps.log')
		formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
		hdlr.setFormatter(formatter)
		logger.addHandler(hdlr) 
		logger.setLevel(logging.DEBUG)
		logger.debug('Starting getOutsideTemps')
	except:
		logger.error('Error in initLogger')
		
def initSql():
	try:
		global mySqlCon 
		mySqlCon = _mysql.connect('localhost', 'username', 'password', 'myhome')
	except:
		logger.error('Could not init SQL')
		
class AppServerSvc (win32serviceutil.ServiceFramework): 
	_svc_name_ = "myHomeGetOutsideTemps" 
	_svc_display_name_ = "myHomeGetOutsideTemps" 
 
	def __init__(self,args): 
		win32serviceutil.ServiceFramework.__init__(self,args) 
		self.hWaitStop = win32event.CreateEvent(None,0,0,None) 
		socket.setdefaulttimeout(60) 

	def SvcStop(self): 
		self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
		win32event.SetEvent(self.hWaitStop) 
		sys.stopservice = "true"
		continueRunning = 0
		sys.exit()
		
	def SvcDoRun(self): 
		servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, servicemanager.PYS_SERVICE_STARTED, (self._svc_name_,''))
		self.main() 

	def main(self): 
		global wunderground
		global prevTempTime
		global prevForcastTime
		prevTempTime = ''
		prevForcastTime = ''
		
		try:
			initLogger()	
			initSql()
		except:
			logger.error('Wierdfail inside main')
		try:
			while True:
				try:
					getOutsideTemp()
				except:
					logger.error('Failed to getOutsideTemp in main')
				try:
					writeToDatabase()
				except:
					logger.error('Failed to writeToDatabase in main')
				try:
					time.sleep(6*60)  # Delay for 3 minutes
				except KeyboardInterrupt:
					print 'Ending program at keyboard interrupt'
					logger.debug('Ending program at keyboard interrupt')
					break	
		except:
			logger.error('Failed in main')
			time.sleep(5)
			self.main() 
			
if __name__ == '__main__': 
	win32serviceutil.HandleCommandLine(AppServerSvc)
	

	