import time
import requests
import sys
import oauth2 as oauth
import serial
import asyncio
from kasa import SmartDimmer
from datetime import datetime, timedelta
from playsound import playsound


ser = serial.Serial('<ADD SERIAL PORT HERE (eg. COM5)>', 9600)

#To get new access token, click the tutorial link in the api - https://dev.fitbit.com/apps
access_token ='<TOKEN HERE>'
user_id = '<USER ID HERE>'

p = SmartDimmer("<PUT YOUR DIMMER'S IP ADDRESS HERE>")

minuteAdjustment = timedelta(minutes=15)
mostRecentTime = datetime.now() - minuteAdjustment #just a starting place

async def setBrightness(brightness):
    await p.update()  # Request the update
    print(p.alias)  # Print out the alias
    await p.set_brightness(brightness)

async def turnOn(isOn):
	await p.update()  # Request the update
	print(p.alias)  # Print out the alias
	if isOn:
		p.turn_on
	else:
		p.turn_off

def getFitbitData():
	try:
		date = datetime.now()
		start_time = date - minuteAdjustment
		end_time = date


		strDate = date.strftime("%Y-%m-%d")
		strStart = start_time.strftime("%H:%M")
		strEnd = end_time.strftime("%H:%M")


		hr_request = requests.get('https://api.fitbit.com/1/user/'+ user_id +'/activities/heart/date/' + strDate  + '/1d/1sec/time/' + strStart + '/' + strEnd + '.json', headers={'Authorization': 'Bearer ' + access_token})
		print("Status Code "+str(hr_request.status_code))
        #This means you're spamming fitbit and they don't like it - time to take a break
		if hr_request.status_code == 429:
			print("Retry after" + hr_request.headers["Retry-After"])
			time.sleep(int(hr_request.headers["Retry-After"]))
		# Store intraday heart data
		intraday_hr_data = hr_request.json()['activities-heart-intraday']['dataset']
		print(intraday_hr_data)
		if len(intraday_hr_data)>0:
			val = intraday_hr_data[len(intraday_hr_data)-1]['value']
			eventTime = intraday_hr_data[len(intraday_hr_data)-1]['time']	#don't trigger the same event over and over
			print(eventTime)
			global mostRecentTime
			print(mostRecentTime)
			if eventTime != mostRecentTime:
				mostRecentTime = eventTime
				print(val)
				ser.write(val)

				#Non-random - that way we also get to know the heart rate exactly for fun :)  (all higher than resting, tho)
				#Scurry sounds -
				if val >90:
					ser.write(val.encode())
				if val <80:
					asyncio.run(setBrightness(30))
					print("Option 1")
				else:
					if val <85:
						asyncio.run(setBrightness(15))
						print("Option 2")
					else:
						if val <90:
							asyncio.run(setBrightness(5))
							print("Option 3")
                #You'll obviously need to adjust this based on the sounds you've picked
				if val == 94 or val == 84 or val == 104:
					playsound('blehNoise.mp3')
					print("Option 4")
				if val == 95 or val == 85 or val == 105:
					playsound('Straw Squeak.mp3')
					print("Option 5")
				if val == 96 or val == 86 or val == 106:
					playsound('scream1.mp3')
					print("Option 6")
				if val == 97 or val == 87 or val == 107:
					playsound('scream2.mp3')
					print("Option 7")
				if val == 102 or val == 88 or val == 108:
					playsound('Swoosh.mp3')
					print("Option 8")
				if val >98 and val != 105:
					print("Option 9")
                    #Flicker the lights (this one is fun)
					asyncio.run(setBrightness(1))
					time.sleep(1)
					asyncio.run(setBrightness(100))
					time.sleep(1)
					asyncio.run(setBrightness(1))
					time.sleep(1)
					asyncio.run(setBrightness(100))
					time.sleep(1)
					asyncio.run(setBrightness(1))
				if val == 101:
					playsound('weKillU.mp3')
					print("Option 10")
				if val == 105:
					asyncio.run(turnOn(False))
					print("Option 11")
	except Exception as e: print(e)
		#nothing needs to happen - just don't want the program to stop running



#Loop indefinitely, fetching fitbit data every 30 seconds
while True:
	getFitbitData()
	time.sleep(30)