RED_PIN   = 17
GREEN_PIN = 22
BLUE_PIN  = 24

# Number of color changes per step (more is faster, less is slower).
# You also can use 0.X floats.
#STEPS     = 1

###### END ######




import os
import subprocess
import sys
import termios
import tty
import pigpio
import time
from thread import start_new_thread

bright = 255
r = 255.0
g = 0.0
b = 0.0
steps = 0.003

brightChanged = False
abort = False
state = True	#boolean if light show is on or paused

try:
	pid = subprocess.check_output(["pgrep", "pigpio"])
	print("pid:", pid)

except:
	print('Error --> Start pipiod process')
	os.system('sudo pigpiod')
	time.sleep(1)
	#if pid < 1000:
	#print('Start pigiod process')
	#os.system('sudo pigpiod') #start pigpiod process if pi got restarted

pi = pigpio.pi()

def updateColor(color, step): #For changing the light power
	color += step
	
	if color > 255: #max and min values for setting the stength of the LEDs
		return 255
	if color < 0:
		return 0
		
	return color


def setLights(pin, brightness):
	realBrightness = int(int(brightness) * (float(bright) / 255.0))
	pi.set_PWM_dutycycle(pin, realBrightness) #Set value of the port --> e.g. pigpio pigs p 17 255


def getCh(): #get user input in terminal
	fd = sys.stdin.fileno()
	old_settings = termios.tcgetattr(fd)
	
	try:
		tty.setraw(fd)
		ch = sys.stdin.read(1)
	finally:
		termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
		
	return ch


def checkKey():
	global bright
	global brightChanged
	global state
	global abort
	global steps
	
	while True:
		c = getCh()
		
		if c == '+' and bright < 255 and not brightChanged:
			brightChanged = True
			time.sleep(0.01)
			brightChanged = False
			
			bright = bright + 1
			print ("Current brightness: %d" % bright)

		if c == 's':
			steps *= 0.8
			print ("Current Steps: ", round(steps,5)) # Round Value to 5 digits after comma

		if c == 'f':
			steps *= 1.2
			print ("Current Steps: ", round(steps,5))

		if c == '-' and bright > 0 and not brightChanged:
			brightChanged = True
			time.sleep(0.01)
			brightChanged = False
			
			bright = bright - 1
			print ("Current brightness: %d" % bright)
			
		if c == 'p' and state:
			state = False
			print ("Pausing...")
			
			time.sleep(0.1)
			
			setLights(RED_PIN, 0)
			setLights(GREEN_PIN, 0)
			setLights(BLUE_PIN, 0)
			
		if c == 'r' and not state:
			state = True
			print ("Resuming...")
			
		if c == 'c' and not abort:
			abort = True
			break

#new thread to have 2 endless loops in the script
start_new_thread(checkKey, ()) # Start a thread and execute funtion --> loop with waiting for user input in terminal


print ("+ / - = Increase / Decrease brightness")
print ("f / s = Increase / Decrease fading speed")
print ("p / r = Pause / Resume")
print ("c = Abort Program")

#set init values for LEDs
setLights(RED_PIN, r)
setLights(GREEN_PIN, g)
setLights(BLUE_PIN, b)

#Main Endless Loop with Color Fading
while abort == False:
	if state and not brightChanged:
		if r == 255 and b == 0 and g < 255:
			g = updateColor(g, steps)
			setLights(GREEN_PIN, g)
		
		elif g == 255 and b == 0 and r > 0:
			r = updateColor(r, -steps)
			setLights(RED_PIN, r)
		
		elif r == 0 and g == 255 and b < 255:
			b = updateColor(b, steps)
			setLights(BLUE_PIN, b)
		
		elif r == 0 and b == 255 and g > 0:
			g = updateColor(g, -steps)
			setLights(GREEN_PIN, g)
		
		elif g == 0 and b == 255 and r < 255:
			r = updateColor(r, steps)
			setLights(RED_PIN, r)
		
		elif r == 255 and g == 0 and b > 0:
			b = updateColor(b, -steps)
			setLights(BLUE_PIN, b)
	
print ("Aborting...")

setLights(RED_PIN, 0)
setLights(GREEN_PIN, 0)
setLights(BLUE_PIN, 0)

time.sleep(0.5)

pi.stop()#Stop "pigpio.pi()" - Process
