import serial, time, datetime, struct
import sys
import datetime
import requests
import os
import RPi.GPIO as GPIO
from time import sleep

ser = serial.Serial("/dev/ttyS0", baudrate = 57600, timeout = 2) #serial.Serial('/dev/ttyUSB0',57600)     port =  # serial communication in Linux

pack = [0xef01, 0xffffffff, 0x1]

def readPacket():
        time.sleep(1)
        w = ser.inWaiting()
        ret = []
        if w >= 9:
                s = ser.read(9)         #partial read to get length
                ret.extend(struct.unpack('!HIBH', s))
                ln = ret[-1]

                time.sleep(1)
                w = ser.inWaiting()
                if w >= ln:
                        s = ser.read(ln)
                        form = '!' + 'B' * (ln - 2) + 'H'
                        ret.extend(struct.unpack(form, s))
        return ret


def writePacket(data):
        pack2 = pack + [(len(data) + 2)]
        a = sum(pack2[-2:] + data)
        pack_str = '!HIBH' + 'B' * len(data) + 'H'
        l = pack2 + data + [a]
        s = struct.pack(pack_str, *l)
        ser.write(s)


def verifyFinger():
        data = [0x13, 0x0, 0, 0, 0]
        writePacket(data)
        s = readPacket()
        return s[4]

def genImg():
        data = [0x1]
        writePacket(data)
        s = readPacket()
        return s[4]

def img2Tz(buf):
        data = [0x2, buf]
        writePacket(data)
        s = readPacket()
        return s[4]

def search():   # search the whole finger library for the template that matches the one in CharBuffer1 or CharBuffer2
        data = [0x4, 0x1, 0x0, 0x0, 0x0, 0xff]
        writePacket(data)
        s = readPacket()
        return s[4:-1]

d=open("classreg.dat","r")
classID=(d.readline())
classID=classID[0:6]
lecturer=(d.readline())
lecturer=lecturer[0:len(lecturer)-1]
day=(d.readline())
day=day[0:len(day)-1]
ctime=(d.readline())
ctime=ctime[0:len(ctime)-1]
venue=(d.readline())
venue=venue[0:len(venue)-1]
d.close()
currentDT = datetime.datetime.now()

print(currentDT.strftime("%c"))
print("\n") 
print("Attendance taking for class: " + classID +"\n")
print("lecturer: "+ lecturer+"\n")
print("Day: "+ day +"\n")
print("Time: "+ctime+"\n")
print("Venue: "+venue+"\n")

while True:


    if verifyFinger():
            print 'Verification Error'
            sys.exit(-1)

    print 'Put finger',
    sys.stdout.flush()

    time.sleep(1)
    for _ in range(5):
            g = genImg()
          
            if g == 0:
                    break

            print '.',
            sys.stdout.flush()

    print ''
    sys.stdout.flush()
    if g != 0:
            continue #sys.exit(-1)
    z= img2Tz(1)
    if z:
            print 'Conversion Error'
            continue   #sys.exit(-1)
       
    r = search()
    print 'Search result', r
    if r[0] == 0 :
            currentDT = datetime.datetime.now()
            print (str(currentDT) + ' studentid: '+ str(r[2]))
            b=str(currentDT)   
            b = b[0:10]
            print(b)
            f = open("Att_" + str(b)+".txt", "a")
            f.write("\n"+ currentDT.strftime("%c") +","+ classID + "," + str(r[2]))
            f.close()
            print 'Authentication Successful'
            
            classID=str(classID)
            fingerid=str(r[2])
            response=requests.get("http://192.168.43.36/finger/opmode.php?stdclass="+classID+"&finger_id="+fingerid+"")
            f = open("Att_" + str(b)+".txt", "r")
            for x in f:
                print(x)
            f.close()
            continue   #sys.exit(0)

    else:
            print 'Authentication fail'
            #Disable warnings (optional)
            GPIO.setwarnings(False)
            #Select GPIO mode
            GPIO.setmode(GPIO.BCM)
            #Set buzzer - pin 23 as output
            buzzer=23
            GPIO.setup(buzzer,GPIO.OUT)
            GPIO.output(buzzer,GPIO.HIGH)
            sleep(0.5) # Delay in seconds
            GPIO.output(buzzer,GPIO.LOW)
            sleep(0.5)
            continue   #sys.exit(1)
    f = open("Att_" + str(b)+".txt", "r")
    for x in f:
        print(x)
    f.close()
