Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python3 -u
- #Copyright 2017 Michael Kirsch
- #Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
- #to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
- # and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- #The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
- #Fan and LED portions by @ThisSteveGuy (June 12, 2018)
- import http.server
- import configparser
- import time
- import os
- import RPi.GPIO as GPIO
- import subprocess
- from configparser import SafeConfigParser
- from enum import Enum
- pcb_components={"LED":7,"FAN":8,"RESET":3,"POWER":5,"CHECK_PCB":10}
- class path():
- kintaro_folder = "/opt/kintaro/"
- start_folder = "start/"
- intro_video = kintaro_folder + start_folder + "intro.mp4"
- config_file = kintaro_folder + start_folder + "kintaro.config"
- temp_command = 'vcgencmd measure_temp'
- class vars():
- fan_hysteresis = 5
- # The fan curve has three points: high mid low. Each has a temperature (celsius) and a fan speed (percent).
- temp_high = 70 # fan curve
- fan_high = 100 # o
- temp_mid = 65 # /
- fan_mid = 75 # o
- temp_low = 60 # /
- fan_low = 60 # o
- led_max_bright = 35
- reset_hold_short = 100
- reset_hold_long = 500
- debounce_time = 0.1
- counter_time = 0.01
- GPIO.setmode(GPIO.BOARD) #Use the same layout as the pins
- GPIO.setup(pcb_components["LED"], GPIO.OUT) #LED Output
- pled = GPIO.PWM(pcb_components["LED"], 60) #For LED dimming. This number is in Hz. Adjust "led_max_bright" above instead of this.
- GPIO.setup(pcb_components["FAN"], GPIO.OUT) #FAN Output
- pfan = GPIO.PWM(pcb_components["FAN"], 30) #Fan PWM. This is in Hz. I've had no issues with 30.
- GPIO.setup(pcb_components["POWER"], GPIO.IN) #set pin as input
- GPIO.setup(pcb_components["RESET"], GPIO.IN, pull_up_down=GPIO.PUD_UP) #set pin as input and switch on internal pull up resistor
- GPIO.setup(pcb_components["CHECK_PCB"], GPIO.IN, pull_up_down=GPIO.PUD_UP)
- def temp(): #returns the gpu temoperature
- res = os.popen(path.temp_command).readline()
- return float((res.replace("temp=", "").replace("'C\n", "")))
- curLED = 100 #for keeping track of current LED brightness, edit "led_max_bright" above instead
- def ledChange(newLED,speed):
- global curLED
- while (newLED != curLED):
- #speed is a decimal which describes how long it takes the LED to go from one brightness level to the next.
- if speed == 0: speed = 1 #a speed of 0 would mean the LED never changes, so we turn it to a 1 (an instant change).
- curLED = curLED * (1-speed) + newLED * speed #this makes for a smooth transition between brightness levels.
- if (abs(curLED-newLED) <= 1): curLED = newLED #close enough to desired brightness level? Then switch over to it.
- pled.start(curLED) #this is when the change to the actual LED brightness is applied. 0-100, & decimals are okay.
- if speed < 1: time.sleep(0.02) #tiny pause between changing brightness levels, otherwise it'd be too quick.
- class led: #class to control the led
- #I should just overhaul this whole part. For now, toggle and blink are used to keep things similar
- # with the code from before. I've made it so one can customize the speed and brightness of blinks if they want.
- def toggle(status,speed):
- #a status of 0 or 1 behaves like an on/off switch. Any other value, and it gets passed on as a brightness value.
- if status == 0:
- ledChange(0,speed)
- elif status == 1:
- #This is where the max brightness setting is actually applied.
- ledChange(vars.led_max_bright,speed)
- else:
- #we could ignore the max brightness here if we wanted.
- ledChange(status,speed)
- def blink(amount,interval,speed,brightness): #blink the led
- #amount = number of blinks; interval = time between blinks; speed = slowness of blinks; brightness = optional (2-100)
- for x in range(amount):
- if brightness > 0:
- led.toggle(brightness,speed)
- else:
- led.toggle(0,speed)
- time.sleep(interval)
- led.toggle(1,speed)
- time.sleep(interval)
- def return_config_bool(searchterm):
- Config = configparser.ConfigParser()
- Config.read(path.config_file) # read the configfile
- return Config.getboolean("Boot", searchterm)
- def fan(speed):
- pfan.start(speed)
- #this is just initializing variables. Change the fan curve above instead.
- curTemp = 50 #Current Temperature. We hold onto this value because we're using it in a filter.
- topTemp = 0 #Top Temperature. Keeps track of temp increases, used to apply hysteresis.
- botTemp = 100 #Bottom Temperature. As the fan cools things down, this keeps track of how cool it's gotten.
- oldFan = 0 #keeps track of what the fan speed was after the last time we ran this function
- def fancontrol():
- global curTemp
- global topTemp
- global botTemp
- global oldFan
- curTemp = curTemp * .4 + temp() * .6 #Applies a slight low pass filter to temperature readings, minimizes errors
- if botTemp >= curTemp:
- #if the temperature has been going down, then record it...
- botTemp = curTemp
- #...and lower the point at which the fan will speed up again.
- topTemp = curTemp + vars.fan_hysteresis
- elif topTemp <= curTemp:
- #if the temp's been getting hot, then record it...
- topTemp = curTemp
- #...and raise the level at which we will decrease the fan speed again.
- botTemp = curTemp - vars.fan_hysteresis
- #This applies the "fan curve". You could do several if elif lines like this to make more points on the curve.
- if topTemp > vars.temp_mid: #"topTemp" here means the current temp after hysteresis has been applied to it.
- #maps the range of temperatures to the range of fan speeds from the "fan curve". This part is from mid to high.
- newFAN = (topTemp-vars.temp_mid+.01)/(vars.temp_high-vars.temp_mid) * (vars.fan_high-vars.fan_mid) + vars.fan_mid
- elif topTemp > vars.temp_low:
- #and this part is from low to mid.
- newFAN = (topTemp-vars.temp_low+.01)/(vars.temp_mid-vars.temp_low) * (vars.fan_mid-vars.fan_low) + vars.fan_low
- else:
- newFAN = 0 #if we're below the fan curve, then turn off the fan
- if oldFan != 0: led.blink(3,0,.1,0) #if the fan's going off, we'll do 3 long, slow blinks.
- fan(newFAN) #this is the line that actually changes the fan speed. 0-100 only, decimals are okay.
- if (oldFan == 0) and (newFAN > 0): led.blink(5,.15,1,100) #we'll do 5 quick blinks if the fan is going on.
- oldFan = newFAN #keep track of how this function ended so we can do the blinks (that's all oldFan is used for)
- if return_config_bool("video"):
- os.system("omxplayer " + path.intro_video + " &") #start the bootvideo on start
- def toggle(toggle_this): #change one of the values in the config file
- parser = configparser.ConfigParser()
- parser.read(path.config_file)
- if return_config_bool(toggle_this):
- parser.set('Boot', toggle_this, "False")
- fan(0)
- else:
- parser.set('Boot', toggle_this, "True")
- with open(path.config_file, "w+") as configfile:
- parser.write(configfile)
- def Falling_Power(channel):
- time.sleep(vars.debounce_time) #debounce
- if (GPIO.input(pcb_components["POWER"]) == GPIO.HIGH) and GPIO.input(pcb_components["CHECK_PCB"]) == GPIO.LOW: # shutdown funktion if the powerswitch is toggled
- led.toggle(0,1)
- fan(0)
- os.system("sudo shutdown -h now")
- def Falling_Reset(channel):
- if (GPIO.input(pcb_components["RESET"]) == GPIO.LOW): # reset function
- reset_counter = 0 # counter for the time funktion
- time.sleep(vars.debounce_time) # debounce time
- while (GPIO.input(pcb_components["RESET"]) == GPIO.LOW): # while the button is hold the counter counts up
- reset_counter = reset_counter + 1
- time.sleep(vars.counter_time)
- if reset_counter > vars.reset_hold_short: # check if its hold more that one second
- if reset_counter <= vars.reset_hold_long: # if you hold it less than 5 sec it will toggle the fan
- toggle("fan")
- led.blink(1,.333,.2,0)
- if reset_counter > vars.reset_hold_long: # if you hold it more than 5 seconds if will toggle the bootupvideo
- toggle("video")
- led.blink(5,.1,0,0)
- else:
- os.system("killall emulationstation")
- time.sleep(5)
- os.system("sudo reboot")
- def PCB_Pull(channel):
- GPIO.cleanup()
- if (GPIO.input(pcb_components["POWER"]) == GPIO.HIGH) and GPIO.input(pcb_components["CHECK_PCB"]) == GPIO.LOW:
- os.system("sudo shutdown -h now")
- GPIO.add_event_detect(pcb_components["CHECK_PCB"],GPIO.RISING,callback=PCB_Pull)
- time.sleep(1)
- if return_config_bool("pcb") and GPIO.input(pcb_components["CHECK_PCB"])==GPIO.LOW: #check if there is an pcb and if there is then attach the interrupts
- led.toggle(1,1)
- GPIO.add_event_detect(pcb_components["RESET"], GPIO.FALLING, callback=Falling_Reset)
- GPIO.add_event_detect(pcb_components["POWER"], GPIO.FALLING, callback=Falling_Power)
- #check for interrupts :D
- while True:
- time.sleep(5)
- led.toggle(1,1)
- if return_config_bool("fan"): #check if the fan is activated in the config
- fancontrol()
Advertisement
Add Comment
Please, Sign In to add comment