#!/usr/bin/python
import time
import RPi.GPIO as GPIO
from datetime import datetime
from Tkinter import *
import sys
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)


root = Tk()
root.minsize(300,150)
root.title("16 Input Data Logger")
#root.geometry('340x670')

GPIO.setup(4, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(17, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(18, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(27, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(22, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(23, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(25, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(5, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(6, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(12, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(13, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(16, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(20, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(19, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(26, GPIO.IN, pull_up_down = GPIO.PUD_UP)
GPIO.setup(21, GPIO.IN, pull_up_down = GPIO.PUD_UP)


name_1 = StringVar()
name_2 = StringVar()
name_3 = StringVar()
name_4 = StringVar()
name_5 = StringVar()
name_6 = StringVar()
name_7 = StringVar()
name_8 = StringVar()
name_9 = StringVar()
name_10 = StringVar()
name_11 = StringVar()
name_12 = StringVar()
name_13 = StringVar()
name_14 = StringVar()
name_15 = StringVar()
name_16 = StringVar()
state_on = StringVar()
state_off = StringVar()

#This is where you can describe the Input function. i.e. replace "AA1" with "Heating valve"
name_1.set("OFFICE OUTPUT 01")
name_2.set("OFFICE OUTPUT 02")
name_3.set("OFFICE OUTPUT 03")
name_4.set("OFFICE OUTPUT 04")
name_5.set("OFFICE OUTPUT 05")
name_6.set("OFFICE OUTPUT 06")
name_7.set("OFFICE OUTPUT 07")
name_8.set("OFFICE OUTPUT 08")
name_9.set("FIELD OUTPUT 01")
name_10.set("FIELD OUTPUT 02")
name_11.set("FIELD OUTPUT 03")
name_12.set("FIELD OUTPUT 04")
name_13.set("FIELD OUTPUT 05")
name_14.set("FIELD OUTPUT 06")
name_15.set("FIELD OUTPUT 07")
name_16.set("FIELD OUTPUT 08")

#This is where you can describe the input state. i.e. ON/OFF, UP/DOWN, 0/1, Running/Stopped etc. 
state_on.set("DN")
state_off.set("UP")


f=open('logger.log', 'a')
f.write("\n")
f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
f.write(" : Logger Started \n\nStartup: Input Status... \n\n")    
f.close()

def tail_lines(filename,linesback=30,returnlist=0):

    avgcharsperline=75

    file = open('logger.log','r')
    while 1:
        try: file.seek(-1 * avgcharsperline * linesback,2)
        except IOError: file.seek(0)
        if file.tell() == 0: atstart=1
        else: atstart=0

        lines=file.read().split("\n")
        if (len(lines) > (linesback+1)) or atstart: break
        #The lines are bigger than we thought
        avgcharsperline=avgcharsperline * 1.3 #Inc avg for retry
    file.close()

    if len(lines) > linesback: start=len(lines)-linesback -1
    else: start=0
    if returnlist: return lines[start:len(lines)-1]

    out=""
    for l in lines[start:len(lines)-1]: out=out + l + "\n"
    return out


def write_1_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_1.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")    
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

def write_1_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_1.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

def write_2_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_2.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))


def write_2_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_2.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_3_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_3.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))    

    
def write_3_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_3.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

   
def write_4_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_4.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_4_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_4.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")
    f.close()    
    thirtylines.set(tail_lines('logger',30,0))

    
def write_5_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_5.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_5_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_5.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_6_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_6.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_6_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_6.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_7_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_7.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_7_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_7.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_8_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_8.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_8_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_8.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

def write_9_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_9.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")    
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

def write_9_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_9.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

def write_10_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_10.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))


def write_10_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_10.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_11_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_11.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))    

    
def write_11_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_11.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

   
def write_12_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_12.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")
    f.close()    
    thirtylines.set(tail_lines('logger',30,0))

    
def write_12_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_12.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_13_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_13.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_13_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_13.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_14_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_14.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_14_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_14.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_15_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_15.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_15_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_15.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_16_up():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_16.get())
    f.write(" : ")
    f.write(state_on.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))

    
def write_16_dn():
# write data to file
    f=open('logger.log', 'a')
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write("  ")
    f.write(name_16.get())
    f.write(" : ")
    f.write(state_off.get())
    f.write("\n")  
    f.close()
    thirtylines.set(tail_lines('logger',30,0))   


def input_1(input_pin):
    time.sleep(0.01)
    if GPIO.input(4):
        write_1_up()
    else:
        write_1_dn()

def input_2(input_pin):
    time.sleep(.1)    
    if GPIO.input(17):
        write_2_up()
    else:
        write_2_dn()
        
def input_3(input_pin):
    time.sleep(.1)    
    if GPIO.input(18):
        write_3_up()
    else:
        write_3_dn()
        
def input_4(input_pin):
    time.sleep(.1)    
    if GPIO.input(27):
        write_4_up()
    else:
        write_4_dn()
        
def input_5(input_pin):
    time.sleep(.1)    
    if GPIO.input(22):
        write_5_up()
    else:
        write_5_dn()
        
def input_6(input_pin):
    time.sleep(.1)    
    if GPIO.input(23):
        write_6_up()
    else:
        write_6_dn()
        
def input_7(input_pin):
    time.sleep(.1)     
    if GPIO.input(25):
        write_7_up()
    else:
        write_7_dn()
        
def input_8(input_pin):
    time.sleep(.1)    
    if GPIO.input(5):
        write_8_up()
    else:
        write_8_dn()

def input_9(input_pin):
    time.sleep(.1)
    if GPIO.input(6):
        write_9_up()
    else:
        write_9_dn()
        
def input_10(input_pin):
    time.sleep(.1)    
    if GPIO.input(12):
        write_10_up()
    else:
        write_10_dn()
        
def input_11(input_pin):
    time.sleep(.1)    
    if GPIO.input(13):
        write_11_up()
    else:
        write_11_dn()
        
def input_12(input_pin):
    time.sleep(.1)    
    if GPIO.input(16):
        write_12_up()
    else:
        write_12_dn()
        
def input_13(input_pin):
    time.sleep(.1)    
    if GPIO.input(20):
        write_13_up()
    else:
        write_13_dn()
        
def input_14(input_pin):
    time.sleep(.1)    
    if GPIO.input(19):
        write_14_up()
    else:
        write_14_dn()
        
def input_15(input_pin):
    time.sleep(.1)     
    if GPIO.input(26):
        write_15_up()
    else:
        write_15_dn()
        
def input_16(input_pin):
    time.sleep(.1)    
    if GPIO.input(21):
        write_16_up()
    else:
        write_16_dn()

def current_state():
    time.sleep(.1) 
    if GPIO.input(4):
        write_1_up()
    else:
        write_1_dn()
        
    if GPIO.input(17):
        write_2_up()
    else:
        write_2_dn()        

    if GPIO.input(18):
        write_3_up()
    else:
        write_3_dn()

    if GPIO.input(27):
        write_4_up()
    else:
        write_4_dn()

    if GPIO.input(22):
        write_5_up()
    else:
        write_5_dn()

    if GPIO.input(23):
        write_6_up()
    else:
        write_6_dn()

    if GPIO.input(25):
        write_7_up()
    else:
        write_7_dn()

    if GPIO.input(5):
        write_8_up()
    else:
        write_8_dn()

    if GPIO.input(6):
        write_9_up()
    else:
        write_9_dn()

    if GPIO.input(12):
        write_10_up()
    else:
        write_10_dn()

    if GPIO.input(13):
        write_11_up()
    else:
        write_11_dn()

    if GPIO.input(16):
        write_12_up()
    else:
        write_12_dn()

    if GPIO.input(20):
        write_13_up()
    else:
        write_13_dn()

    if GPIO.input(19):
        write_14_up()
    else:
        write_14_dn()

    if GPIO.input(26):
        write_15_up()
    else:
        write_15_dn()
        
    if GPIO.input(21):
        write_16_up()
    else:
        write_16_dn()

    f=open('logger.log', 'a')
    f.write("\n")
    f.write(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')[:-3])
    f.write(" : Logging Started... \n\n")    
    f.close()
    thirtylines.set(tail_lines('logger',30,0))
    
        
GPIO.add_event_detect(4, GPIO.BOTH, bouncetime=300, callback=input_1)
GPIO.add_event_detect(17, GPIO.BOTH, bouncetime=300, callback=input_2)
GPIO.add_event_detect(18, GPIO.BOTH, bouncetime=300, callback=input_3)
GPIO.add_event_detect(27, GPIO.BOTH, bouncetime=300, callback=input_4)
GPIO.add_event_detect(22, GPIO.BOTH, bouncetime=300, callback=input_5)
GPIO.add_event_detect(23, GPIO.BOTH, bouncetime=300, callback=input_6)
GPIO.add_event_detect(25, GPIO.BOTH, bouncetime=300, callback=input_7)
GPIO.add_event_detect(5, GPIO.BOTH, bouncetime=300, callback=input_8)
GPIO.add_event_detect(6, GPIO.BOTH, bouncetime=300, callback=input_9)
GPIO.add_event_detect(12, GPIO.BOTH, bouncetime=300, callback=input_10)
GPIO.add_event_detect(13, GPIO.BOTH, bouncetime=300, callback=input_11)
GPIO.add_event_detect(16, GPIO.BOTH, bouncetime=300, callback=input_12)
GPIO.add_event_detect(20, GPIO.BOTH, bouncetime=300, callback=input_13)
GPIO.add_event_detect(19, GPIO.BOTH, bouncetime=300, callback=input_14)
GPIO.add_event_detect(26, GPIO.BOTH, bouncetime=300, callback=input_15)
GPIO.add_event_detect(21, GPIO.BOTH, bouncetime=300, callback=input_16)


# LabelFrame text could also include Site Name
labelframe = LabelFrame(root, text="Recent Events - Site Name")
labelframe.pack(fill="both", expand="yes")

thirtylines=StringVar()
thirtylines.set(tail_lines('logger',30,0))

left = Label(labelframe, textvariable=thirtylines, justify=LEFT, font=('helvetica', 12))
left.pack()
current_state()
root.mainloop()