Last active
August 29, 2015 14:07
-
-
Save BennettRand/6c45ff7e898b49ad79ba to your computer and use it in GitHub Desktop.
jQuery Mobile Fan Control for RPi
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RPi.GPIO as GPIO | |
import time | |
import random | |
import signal | |
from multiprocessing import Pool | |
from paste import httpserver | |
import paste.request | |
import threading | |
import pywapi | |
fans = [] | |
GPIO.setmode(GPIO.BOARD) | |
GPIO.setwarnings(False) | |
current_weather = {} | |
speed = 50 | |
page = '''<!DOCTYPE html> | |
<html> | |
<head> | |
<title>Fan Control</title> | |
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=3"> | |
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.4/jquery.mobile-1.4.4.min.css" /> | |
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script> | |
<script src="https://code.jquery.com/mobile/1.4.4/jquery.mobile-1.4.4.min.js"></script> | |
<script> | |
function handle(dat){{ | |
location.reload(); | |
}} | |
</script> | |
<style> | |
.ui-block-a, .ui-block-b, .ui-block-c {{ | |
vertical-align: middle; | |
text-align: center; | |
}} | |
</style> | |
</head> | |
<body> | |
<div data-role="page"> | |
<div data-role="header"> | |
<h1>Fan Control</h1> | |
</div><!-- /header --> | |
<div role="main" class="ui-content"> | |
<div class="ui-grid-c"> | |
<div class="ui-block-a"><div class="ui-bar ui-bar-a" style="height:60px"><h3></h3></div></div> | |
<div class="ui-block-b"><div class="ui-bar ui-bar-a" style="height:60px"><h3>Status</h3></div></div> | |
<div class="ui-block-c"><div class="ui-bar ui-bar-a" style="height:60px"><h3>Temp.</h3></div></div> | |
<div class="ui-block-d"><div class="ui-bar ui-bar-a" style="height:60px"><h3>Speed</h3></div></div> | |
<div class="ui-block-a"><div class="ui-bar ui-bar-a" style="height:60px"><img src="{icon}"/></div></div> | |
<div class="ui-block-b"><div class="ui-bar ui-bar-a" style="height:60px">{status}</div></div> | |
<div class="ui-block-c"><div class="ui-bar ui-bar-a" style="height:60px">{temp}</div></div> | |
<div class="ui-block-d"><div class="ui-bar ui-bar-a" style="height:60px">{speed}%</div></div> | |
</div><!-- /grid-c --> | |
<input type="button" value="High" onclick="$.post( '#' , {{speed: 100}}, handle);"> | |
<input type="button" value="Med" onclick="$.post( '#' , {{speed: 70}}, handle);"> | |
<input type="button" value="Low" onclick="$.post( '#' , {{speed: 40}}, handle);"> | |
<input type="button" value="Breeze" onclick="$.post( '#' , {{speed: 10}}, handle);"> | |
<input type="button" value="Off" onclick="$.post( '#' , {{speed: 0}}, handle);"> | |
</div><!-- /content --> | |
<div data-role="footer"> | |
<h4></h4> | |
</div><!-- /footer --> | |
</div><!-- /page --> | |
</body> | |
</html> | |
''' | |
def init_worker(): | |
signal.signal(signal.SIGINT, signal.SIG_IGN) | |
def rule_set(temp): | |
ret = 0 | |
if temp > 50 and temp <= 55: | |
ret = 20 | |
elif temp > 55 and temp <= 60: | |
ret = 50 | |
elif temp > 60 and temp <= 70: | |
ret = 100 | |
elif temp > 70 and temp <= 75: | |
ret = 50 | |
elif temp > 75 and temp <= 80: | |
ret = 20 | |
hr = time.localtime()[3] | |
if hr < 7 or hr >= 11: | |
ret /=2 | |
return ret | |
def weather_callback(weather): | |
global fans | |
global current_weather | |
current_weather = weather | |
print "Currently", weather['temperature_string'] | |
print weather['weather'] | |
return | |
def setup_fans(fan_list = [3,5], frq = 50): | |
fs = [] | |
for f in fan_list: | |
GPIO.setup(f, GPIO.OUT) | |
fs += [GPIO.PWM(f, frq)] | |
return fs | |
def app(environ, start_response): | |
global current_weather | |
global speed | |
fields = paste.request.parse_formvars(environ) | |
start_response('200 OK', [('content-type', 'text/html')]) | |
if environ['REQUEST_METHOD'] == 'POST': | |
try: | |
speed = int(fields['speed']) | |
print "Speed set to", speed | |
return [] | |
except: | |
pass | |
return [page.format(status = current_weather['weather'], | |
temp = current_weather['temperature_string'], | |
icon = current_weather['icon_url_base']+current_weather['icon_url_name'], | |
speed = str(speed))] | |
def main(): | |
global fans | |
global current_weather | |
global speed | |
pool = Pool(2, init_worker) | |
fans = setup_fans(frq = 20) | |
for f in fans: | |
f.start(50) | |
count = 0 | |
while True: | |
if count == 0: | |
print "Getting weather" | |
pool.apply_async(pywapi.get_weather_from_noaa, args = ('KSFO',), callback = weather_callback) | |
time.sleep(1) | |
print ".", | |
for f in fans: | |
f.ChangeDutyCycle(speed) | |
count = (count+1)%600 | |
return | |
if __name__ == "__main__": | |
try: | |
serve = threading.Thread(target=httpserver.serve, args=(app,), kwargs={"host":'0.0.0.0', "port":'8888'}) | |
serve.daemon = True | |
serve.start() | |
main() | |
except KeyboardInterrupt as e: | |
# GPIO.cleanup() | |
print "Quitting" | |
exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment