import requests
import time
import datetime
import RPi.GPIO as GPIO
import os
from gpiozero import CPUTemperature
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)

top=6.4
mid=3.5
low=0.8
t0 = time.time()
t1 = time.time()
state ="Full"
oldState="Full"
consumption="N/A"

def measureTime():
    runTime=(time.time() - t0 ) / 3600
    print (runTime, "hours")
    return runTime

def measureWater():
    global state
    
    avg=0
    
    for i in range(0,5):
        
        GPIO.setup(10, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
        if GPIO.input(10):
            avg=avg + top
            print ("Full")
            GPIO.setup(10, GPIO.IN,pull_up_down = GPIO.PUD_UP)
        else:
            
            GPIO.setup(11, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
            if GPIO.input(11):
                avg= avg + mid
                print ("Mid")
                GPIO.setup(11, GPIO.IN,pull_up_down = GPIO.PUD_UP)
            else:
                GPIO.setup(9, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
                
                if GPIO.input(9):
                    avg= avg + low
                    print ("Low")
                else:
                    avg= avg
        resetPull()
        time.sleep(10)
        
    avg= avg/5
    if avg > mid:
        avg=top
        state="Full"
    else:
        if avg > low:
            avg = mid
            state="Half"
        elif avg < 0:
            avg = low
            state="Low"
        else:
            avg = 0
            state="Empty"
    avg=round(avg,2)        
    return avg

def checkConsumption(state,runTime,consumption): #If water has been consumed, calculate l/h. Else use old saved value.
    global oldState
    global t1
    
    if state is oldState and state is "Full":
        return getFromFile(consumption)
    
    elif oldState is "Full" and state is "Half":
        t1 = time.time() 
        return getFromFile(consumption)
    
    elif oldState is "Half" and state is "Low":
        # Has consumed 6.4-3.5 l, how long did it take? Save as new consump.

        consumption=top-mid/t1
        saveToFile(consumption)
        
    oldState=state
    if type(consumption) is float:
        consumption=round(consumption,2)
    return abs(getFromFile(consumption))

def guessWaterLevel(consumption, runTime):
    guessLevel=(float(top)- (float(consumption)) * float(runTime))
    guessLevel=round(guessLevel,2)
    print ("Guesslevel:",guessLevel)
    return guessLevel
    
def sendData(avg,cpu,runTime,consumption,reFill,guessLevel):
    runTime= round(runTime,2)
    payload = {'Waterlevel': avg,'Status': 'Online','Cpu': cpu.temperature, 'Run time':runTime, 'Consumption':consumption, 'Refill':reFill, 'Guesslevel':guessLevel}
    r = requests.get('https://dweet.io/dweet/for/annoyed-wilderness?', params=payload)

def resetPull():
    GPIO.setup(10, GPIO.IN,pull_up_down = GPIO.PUD_UP)
    GPIO.setup(9, GPIO.IN,pull_up_down = GPIO.PUD_UP)
    GPIO.setup(11, GPIO.IN,pull_up_down = GPIO.PUD_UP)
    time.sleep(1)
    
def getFromFile(consumption):
    with open('data.txt') as f:
        lines = f.readlines()
        lines = [line.rstrip('\n') for line in open('data.txt')]
        consumption=float(lines[-1]) #Use the last avg 
    return consumption

def saveToFile(consumption):
    textfile  = open('data.txt', 'a')
    consumption=abs(consumption)
    textfile.write('\n' + str(consumption))
    return

def calculateRefill(guessLevel,avg):
    reFill=((top-low)/consumption ) /24 #Days
    print ("Refill",reFill)
    reFill=round(reFill,2) 
    return reFill

def uploadPhoto():
    print ("Take photo")
    os.system("raspistill -o cam.jpg")
    print ("Upload photo")
    os.system("gdrive update 0B1GNVwq1vqyXTEpBSGRZSmczdDQ cam.jpg")
    print ("Current State:",state)
    
while 1:
    uploadPhoto()
    runTime=measureTime()
    avg=measureWater()    
    cpu = CPUTemperature()
    consumption=checkConsumption(state,runTime,consumption)
    guessLevel=guessWaterLevel(consumption, runTime)
    reFill=calculateRefill(consumption,guessLevel)
    sendData(avg,cpu,runTime,consumption,reFill,guessLevel)

    
    
    

