import datetime
import time
import os
#import RPi.GPIO as GPIO
import spidev

fh = open("/home/pi/Logging.txt", "w")
#GPIO.setwarnings(False)
# GPIO.setmode(GPIO.BOARD)
# GPIO.setup(11, GPIO.IN)				#Read output from PIR motion sensor
#GPIO.setmode(GPIO.BCM)
#TRIG = 23
#ECHO = 24
#Echo from sensor TO 1kOhm, then to echo on Raspberry AND via 2kOhm to ground.
print ("Waiting for sensor to settle")
fh.write("Waiting for sensor to settle\n")
#GPIO.setup(TRIG,GPIO.OUT)
#GPIO.setup(ECHO,GPIO.IN)
#GPIO.output(TRIG, False)
spi = spidev.SpiDev()
spi.open(0,0)

time.sleep(2)
CallOutTime = 120 # Time in seconds to wait before we attract victims
Delaytime = 1 # Time in seconds we wait for the second distance measurement
MirrorMsgTime = time.time() # Time variable when the last movie was started
StartTime = time.time()
BackoffTime = 30 # Time in seconds to wait after the scary movie is played
ExitTime = 0 # Time in seconds after which the program is stopped (set to 0 to run forever)
DistanceToVictim = 100 # Distance in cm. to the victim
movielist = ["10","26","42","58"]	# Different filenames
movie = 0 				# First of the four files
print ("Starting the magic mirror!")
fh.write("Starting the magic mirror!\n")
fh.flush()
os.system('setterm -cursor off')
os.system('clear')

def VictimDetect_Ping():
    # fh.write("Distance Measurement In Progress\n")
    # print ("Distance measurement in progress")
    GPIO.output(TRIG, True)
    time.sleep(0.00001)
    GPIO.output(TRIG, False)
    while GPIO.input(ECHO)==0:
        pulse_start = time.time()
    while GPIO.input(ECHO)==1:
        pulse_end = time.time()
    pulse_duration = pulse_end - pulse_start
    distance = pulse_duration * 17150 # Correct value!!!
    distance = round(distance, 2)
    fh.write("Distance: " + str(distance) + " cm, running time: " + str(int(TempTime - MirrorMsgTime)) + "\n")
    fh.flush()
    print ("Distance: " + str(distance) + " cm, running time: " + str(int(TempTime - MirrorMsgTime)))
    fulltime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')
    if distance > DistanceToVictim: #When output from motion sensor is LOW
        fh.write(fulltime + ": No intruders\n")
        fh.flush()
        #print (str(fulltime) + ": No intruders")
        time.sleep(1)
        return False
    else: #When output from motion sensor is HIGH
        fh.write(fulltime + ": Found a willing victim, Let's see if he stays\n")
        fh.flush()
        #print (str(fulltime) + ": Found a willing victim, Let's see if he stays")
        time.sleep(Delaytime)
        GPIO.output(TRIG, True)
        time.sleep(0.00001)
        GPIO.output(TRIG, False)
        while GPIO.input(ECHO)==0:
            pulse_start = time.time()
        while GPIO.input(ECHO)==1:
            pulse_end = time.time()
        pulse_duration = pulse_end - pulse_start
        distance = pulse_duration * 17150
        distance = round(distance, 2)
        fh.write("Second distance: " + str(distance) + " cm\n")
        fh.flush()
        print ("Second distance: " + str(distance) + " cm")
        if distance > DistanceToVictim: #When output from motion sensor is LOW
            fh.write(fulltime + ": false alarm.\n")
            fh.flush()
            #print (str(fulltime) + ": false alarm.")
            time.sleep(2)
            return False
        else:
            return True

def read_spi(channel):
    spidata = spi.xfer2([1,(8+channel)<<4,0])
    # print("Raw ADC:      {}".format(spidata))
    data = ((spidata[1] & 3) << 8) + spidata[2]
    return data

def VictimDetect_IR():
    global TempTime
    v = (read_spi(0)/1023.0)*3.3
    dist = 16.2537 * v**4 - 129.893 * v**3 + 382.268 * v**2 - 512.611 * v + 301.439
    dist1 = round (dist, 2)
    v = (read_spi(0)/1023.0)*3.3
    dist = 16.2537 * v**4 - 129.893 * v**3 + 382.268 * v**2 - 512.611 * v + 301.439
    dist2 = round (dist, 2)
    v = (read_spi(0)/1023.0)*3.3
    dist = 16.2537 * v**4 - 129.893 * v**3 + 382.268 * v**2 - 512.611 * v + 301.439
    dist3 = round (dist, 2)
    dist = round ((dist1 + dist2 + dist3)/3,0)
    # print ("Distances: " + str(dist1) + ", " + str(dist2) + ", " + str(dist3) + ", average: " + str(dist))
    # time.sleep(1)
    fh.write("Distance: " + str(dist) + " cm, running time: " + str(int(TempTime - MirrorMsgTime)) + "\n")
    fh.flush()
    # print (Distance: " + str(dist) + " cm, running time: " + str(int(TempTime - MirrorMsgTime)))
    fulltime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')
    if dist > DistanceToVictim: #When output from motion sensor is LOW
        fh.write(fulltime + ": No intruders\n")
        fh.flush()
        #print (str(fulltime) + ": No intruders")
        time.sleep(1)
        return False
    else: #When output from motion sensor is HIGH
        fh.write(fulltime + ": Found a willing victim, Let's see if he stays\n")
        fh.flush()
        #print (str(fulltime) + ": Found a willing victim, Let's see if he stays")
        time.sleep(Delaytime)
        v = (read_spi(0)/1023.0)*3.3
        dist = 16.2537 * v**4 - 129.893 * v**3 + 382.268 * v**2 - 512.611 * v + 301.439
        dist1 = round (dist, 2)
        v = (read_spi(0)/1023.0)*3.3
        dist = 16.2537 * v**4 - 129.893 * v**3 + 382.268 * v**2 - 512.611 * v + 301.439
        dist2 = round (dist, 2)
        v = (read_spi(0)/1023.0)*3.3
        dist = 16.2537 * v**4 - 129.893 * v**3 + 382.268 * v**2 - 512.611 * v + 301.439
        dist3 = round (dist, 2)
        dist = round ((dist1 + dist2 + dist3)/3,2)
        fh.write("Second distance: " + str(dist) + " cm\n")
        fh.flush()
        # print ("Second distance: " + str(dist) + " cm")
        if dist > DistanceToVictim: #When output from motion sensor is LOW
            fh.write(fulltime + ": false alarm.\n")
            fh.flush()
            #print (str(fulltime) + ": false alarm.")
            time.sleep(1)
            return False
        else:
            return True	

def playmovie():
    global movie
    global MirrorMsgTime
    global TempTime
    playtime = datetime.datetime.strftime(datetime.datetime.now(), '%Y-%m-%d %H:%M:%S')
    fh.write(playtime + ": Playing the movie VTS_" + movielist[movie] + "_1.mp4\n")
    fh.flush()
    # print (playtime + ": Playing the movie VTS_" + movielist[movie] + "_1.mp4")
    # os.system('amixer set PCM -- 100% > /dev/null')
    os.system('omxplayer -o hdmi /home/pi/VTS_' + movielist[movie] + '_1.mp4 > /dev/null')
    MirrorMsgTime = TempTime
    # print("/")
    if movie < 3:
        movie = movie + 1
    else:
        movie = 0
		
while True:
    #Main loop, interrupted by visitors
    global MirrorMsgTime
    global BackoffTime
    TempTime = time.time()
    # if VictimDetect_Ping() or VictimDetect_IR():
    if VictimDetect_IR():
        playmovie()
        fh.write("Backing off for "+ str(BackoffTime) + " seconds\n")
        fh.flush()
        time.sleep(BackoffTime)
    TempTime = time.time()
    # print("*")
    if (TempTime - MirrorMsgTime) > CallOutTime: # Every CallOutTime seconds we call out for a victim!!!
        fh.write("Calling out to victim\n")
        # print ("Calling out to victim")
        MirrorMsgTime = TempTime
        # os.system('amixer set PCM -- 80% > /dev/null')
        os.system('omxplayer -o hdmi /home/pi/Mirror.mp3 > /dev/null')
    if ExitTime > 0:
        if (TempTime - StartTime) > ExitTime:
            fh.flush()
            fh.close
            os.system('setterm -cursor on')
            sys.exit()

fh.flush()
fh.close
os.system('setterm -cursor on')
