#!/usr/bin/env python

# Copyright 2016 by Andrew Laughton under the gpl ver 3.0.   http://www.gnu.org/licenses/gpl-3.0.en.html  
# This file is based on http://raspberrywebserver.com/gpio/using-python-to-control-GPIO-pins.html, but located in /var/www/html 
# It sets up the Raspberry Pi General purpose In Out (GPIO) pins to suit the wiring to the relay board.

import RPi.GPIO as GPIO
import time
import sqlite3	
import datetime
from time import localtime, strftime
import thread		


# GPIO pins that line up with zones.
pin1 = 38
pin2 = 36
pin3 = 32
pin4 = 26
pin5 = 24
pin6 = 22
pin7 = 16
pin8 = 12

On  = 0				# gpio 0 is on, 1 = off.  Swap these is yours is different.
Off = 1

timeout = 61		# Max time in minutes for water to run for watchdog timer.

    

def zone1(minutes, seconds):
	print("zone 1 on for %d seconds" % seconds)
	GPIO.output(pin1,On)
	time.sleep(seconds) 
	print("zone 1 off")
	GPIO.output(pin1,Off) 

def zone2(minutes, seconds):
	GPIO.output(pin2,On)
	time.sleep(seconds) 
	GPIO.output(pin2,Off) 

def zone3(minutes, seconds):
	GPIO.output(pin3,On)
	time.sleep(seconds) 
	GPIO.output(pin3,Off) 

def zone4(minutes, seconds):
	GPIO.output(pin4,On)
	time.sleep(seconds) 
	GPIO.output(pin4,Off) 

def zone5(minutes, seconds):
	GPIO.output(pin5,On)
	time.sleep(seconds) 
	GPIO.output(pin5,Off) 

def zone6(minutes, seconds):
	GPIO.output(pin6,On)
	time.sleep(seconds) 
	GPIO.output(pin6,Off) 

def zone7(minutes, seconds):
	GPIO.output(pin7,On)
	time.sleep(seconds) 
	GPIO.output(pin7,Off) 

def zone8(minutes, seconds):
	GPIO.output(pin8,On)
	time.sleep(seconds) 
	GPIO.output(pin8,Off) 

    

def main():

	print "executing script"

    # tell the GPIO module that we want to use the header pin numbering scheme
	GPIO.setmode(GPIO.BOARD)	#Option is BCM
	
    # setup pins as outputs
	GPIO.setup(pin1,GPIO.OUT)		#GPIO 
	GPIO.setup(pin2,GPIO.OUT)		#GPIO 
	GPIO.setup(pin3,GPIO.OUT)		#GPIO 
	GPIO.setup(pin4,GPIO.OUT)		#GPIO 
	GPIO.setup(pin5,GPIO.OUT)		#GPIO 
	GPIO.setup(pin6,GPIO.OUT)		#GPIO 
	GPIO.setup(pin7,GPIO.OUT)		#GPIO 
	GPIO.setup(pin8,GPIO.OUT)		#GPIO 

# Reset outputs to off.
	GPIO.output(pin1,Off)	
	GPIO.output(pin2,Off)
	GPIO.output(pin3,Off)
	GPIO.output(pin4,Off)
	GPIO.output(pin5,Off)
	GPIO.output(pin6,Off)
	GPIO.output(pin7,Off)
	GPIO.output(pin8,Off)
		
# Test each output in sequence.	
	zone1(0,1)
	zone2(0,1)
	zone3(0,1)
	zone4(0,1)
	zone5(0,1)
	zone6(0,1)
	zone7(0,1)
	zone8(0,1)

# Test multi-thread logic.	
#	thread.start_new_thread(zone1, (0,1))
#	thread.start_new_thread(zone2, (0,2))
#	thread.start_new_thread(zone3, (0,3))
#	thread.start_new_thread(zone4, (0,4))
#	thread.start_new_thread(zone5, (0,5))
#	thread.start_new_thread(zone6, (0,6))
#	thread.start_new_thread(zone7, (0,7))
#	thread.start_new_thread(zone8, (0,8))

	db = sqlite3.connect('/var/www/html/default.db')
	curs=db.cursor()

	timer1 = 0;
	timer2 = 0;
	timer3 = 0;
	timer4 = 0;
	timer5 = 0;
	timer6 = 0;
	timer7 = 0;
	timer8 = 0;

# http://strftime.org/

	while(True):
		now = datetime.datetime.today()
		print(now)
		now_month = int(now.strftime("%-m"))
		for row in curs.execute("SELECT percent FROM table_month where month = %d" % now_month ):		
			percent = row[0]
		print("percent = %d " % percent)		
		
		now_day = int(now.strftime("%d"))
		odd_day = (now_day % 2)
		now_hour = int(now.strftime("%H"))
		now_minute = int(now.strftime("%M"))
		for row in curs.execute("SELECT * FROM table_time"):
			zone = row[1]
			day = row[2]
			hour = row[3]
			minute = row[4]
			seconds = row[5]
			run_seconds = int(seconds * percent / 100)
#			print("zone = %d, day = %d, odd_day = %d, hour = %d, minute = %d, seconds = %d, run_seconds = %d" % (zone, day, odd_day, hour, minute, seconds, run_seconds))	
			if (day == 0 or (day == 1 and odd_day == 1) or (day == 2 and odd_day == 0)):
#				print("now_hour = %d, hour = %d.   now_minute = %d, minute = %d." % (now_hour, hour, now_minute, minute))
				if (now_hour == hour and now_minute == minute):
					if (zone == 1):
						thread.start_new_thread(zone1, (0, run_seconds))
					elif (zone == 2):
						thread.start_new_thread(zone2, (0, run_seconds))
					elif (zone == 3):	
						thread.start_new_thread(zone3, (0, run_seconds))
					elif (zone == 4):	
						thread.start_new_thread(zone4, (0, run_seconds))
					elif (zone == 5):	
						thread.start_new_thread(zone5, (0, run_seconds))
					elif (zone == 6):	
						thread.start_new_thread(zone6, (0, run_seconds))
					elif (zone == 7):	
						thread.start_new_thread(zone7, (0, run_seconds))
					elif (zone == 8):	
						thread.start_new_thread(zone8, (0, run_seconds))
#				print(row)



#  One pass per minute, watchdog timers.
		if (GPIO.input(pin1) == Off ):  timer1 = 0;
		else:
			timer1 += 1;
			if (timer1 >= timeout):  GPIO.output(pin1, Off);

		if (GPIO.input(pin2) == Off ):  timer2 = 0;
		else:
			timer2 += 1;
			if (timer2 >= timeout):  GPIO.output(pin2, Off);
				
		if (GPIO.input(pin3) == Off ):  timer3 = 0;
		else:
			timer3 += 1;
			if (timer3 >= timeout):  GPIO.output(pin3, Off);

		if (GPIO.input(pin4) == Off ):  timer4 = 0;
		else:
			timer4 += 1;
			if (timer4 >= timeout):  GPIO.output(pin4, Off);
				
		if (GPIO.input(pin5) == Off ):  timer5 = 0;
		else:
			timer5 += 1;
			if (timer5 >= timeout):  GPIO.output(pin5, Off);

		if (GPIO.input(pin6) == Off ):  timer6 = 0;
		else:
			timer6 += 1;
			if (timer6 >= timeout):  GPIO.output(pin6, Off);

		if (GPIO.input(pin7) == Off ):  timer7 = 0;
		else:
			timer7 += 1;
			if (timer7 >= timeout):  GPIO.output(pin7, Off);

		if (GPIO.input(pin8) == Off ):  timer8 = 0;
		else:
			timer8 += 1;
			if (timer8 >= timeout):  GPIO.output(pin8, Off);



		now = datetime.datetime.today()     # read time again 
		sleepTime = 60 - int(now.strftime("%S"))
		print( now.strftime("  %Y/%m/%d %H:%M:%S.%f "), " Sleep for %d seconds " % sleepTime )
		time.sleep(sleepTime)				# Wait until this minute is up before checking again.
#		print (now)


# Failed attempt to put the watchdog logic in a loop...
# Watchdog to make sure an output is not left on forever via web interface.
#		timer_on = ( 0,0,0,0,0,0,0,0,0 );		# Accumulated time in minutes that pin is on for.
#		pin_array = (pin1, pin2, pin3, pin4, pin5, pin6, pin7, pin8 );
#		for i in range(1,8): 						#for loop to read the pins.
#			if (GPIO.input(pin_array(i)) == Off ):  timer_on[i] = 0;
#			else:
#				timer_on[i] += 1;
#				if (timer_on[i] >= 3):  GPIO.output(pin_array(i), Off);




	db.close()
	GPIO.cleanup()

if __name__=="__main__":
    main() 
