commit
100eebf6d5
@ -0,0 +1,2 @@
|
|||||||
|
venv/
|
||||||
|
__pycache__/
|
||||||
@ -0,0 +1,98 @@
|
|||||||
|
import tornado.httpserver
|
||||||
|
import tornado.ioloop
|
||||||
|
import tornado.options
|
||||||
|
import tornado.web
|
||||||
|
import tornado.websocket
|
||||||
|
|
||||||
|
# To handle requests
|
||||||
|
import json
|
||||||
|
|
||||||
|
# Get the host IP
|
||||||
|
import netifaces as ni
|
||||||
|
ni.ifaddresses("wlan0")
|
||||||
|
ip = ni.ifaddresses("wlan0")[ni.AF_INET][0]["addr"]
|
||||||
|
print("Host IP address:", ip)
|
||||||
|
|
||||||
|
# Get the host port
|
||||||
|
from tornado.options import define, options
|
||||||
|
define("port", default=8080, help="run on the given port", type=int)
|
||||||
|
|
||||||
|
# Our program for reading/writing to our output
|
||||||
|
import led
|
||||||
|
|
||||||
|
class IndexHandler(tornado.web.RequestHandler):
|
||||||
|
def get(self):
|
||||||
|
# TODO: render all the controls automatically depending on what we have connected
|
||||||
|
self.render("index.html", ip = ip, port = options.port)
|
||||||
|
|
||||||
|
ws_clients = []
|
||||||
|
|
||||||
|
class WebSocketHandler(tornado.websocket.WebSocketHandler):
|
||||||
|
def open(self):
|
||||||
|
if self not in ws_clients:
|
||||||
|
print("New connection")
|
||||||
|
ws_clients.append(self)
|
||||||
|
#self.write_message("Connected")
|
||||||
|
|
||||||
|
def on_message(self, message):
|
||||||
|
print("Message received:", message)
|
||||||
|
#self.write_message("Message received: " + message)
|
||||||
|
|
||||||
|
message = json.loads(message) #load the json
|
||||||
|
|
||||||
|
if message["message_type"] == "io_request":
|
||||||
|
# We have something that we need to do
|
||||||
|
|
||||||
|
if message["io_type"] == "led":
|
||||||
|
colour = message["led_colour"]
|
||||||
|
operation = message["operation"]
|
||||||
|
|
||||||
|
if operation == "toggle":
|
||||||
|
result = led.toggle(colour)
|
||||||
|
|
||||||
|
response = {"message_type": "io_response",
|
||||||
|
"io_type": "led",
|
||||||
|
"led_colour": colour,
|
||||||
|
"led_state": result}
|
||||||
|
|
||||||
|
send_to_all(json.dumps(response))
|
||||||
|
|
||||||
|
if operation == "read":
|
||||||
|
result = led.read(colour)
|
||||||
|
|
||||||
|
response = {"message_type": "io_response",
|
||||||
|
"io_type": "led",
|
||||||
|
"led_colour": colour,
|
||||||
|
"led_state": result}
|
||||||
|
|
||||||
|
send_to_all(json.dumps(response))
|
||||||
|
|
||||||
|
# if message == "BUTTON_PRESS":
|
||||||
|
# result = led.toggle()
|
||||||
|
# send_to_all("LED_STATE " + str(result))
|
||||||
|
|
||||||
|
# if message == "GET_STATES":
|
||||||
|
# states = led.read("R")
|
||||||
|
# send_to_all("LED_STATE" + str(states))
|
||||||
|
|
||||||
|
def on_close(self):
|
||||||
|
if self in ws_clients:
|
||||||
|
ws_clients.remove(self)
|
||||||
|
print("Connection closed")
|
||||||
|
|
||||||
|
def send_to_all(message):
|
||||||
|
for c in ws_clients:
|
||||||
|
c.write_message(message)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
tornado.options.parse_command_line()
|
||||||
|
app = tornado.web.Application(
|
||||||
|
handlers=[
|
||||||
|
(r"/", IndexHandler),
|
||||||
|
(r"/ws", WebSocketHandler)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
httpServer = tornado.httpserver.HTTPServer(app)
|
||||||
|
httpServer.listen(options.port)
|
||||||
|
print("Listening on port:", options.port)
|
||||||
|
tornado.ioloop.IOLoop.instance().start()
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body { margin: 0px; padding: 0px; }
|
||||||
|
canvas { border: 1px solid #9C9898; }
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
var socket = new WebSocket("ws://{{ ip }}:{{ port }}/ws");
|
||||||
|
|
||||||
|
socket.onopen = function(){
|
||||||
|
console.log("Connected");
|
||||||
|
//get initial states
|
||||||
|
var leds = ["R", "G"];
|
||||||
|
for (var i = 0; i < leds.length; i++) {
|
||||||
|
request = {"message_type": "io_request",
|
||||||
|
"io_type": "led",
|
||||||
|
"led_colour": leds[i],
|
||||||
|
"operation": "read"};
|
||||||
|
sendMessage(request);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onmessage = function (message) {
|
||||||
|
console.log("receiving: " + message.data);
|
||||||
|
processInstruction(message.data);
|
||||||
|
};
|
||||||
|
|
||||||
|
function processInstruction(instruction) {
|
||||||
|
var instruction_json = JSON.parse(instruction);
|
||||||
|
console.log(instruction_json.message_type);
|
||||||
|
console.log(typeof instruction_json.message_type);
|
||||||
|
if (instruction_json.message_type == "io_response") {
|
||||||
|
console.log("here");
|
||||||
|
if (instruction_json.io_type == "led") {
|
||||||
|
console.log("here2");;
|
||||||
|
var colour = instruction_json.led_colour;
|
||||||
|
var state = instruction_json.led_state;
|
||||||
|
document.getElementById(colour).innerHTML = "LED state: " + state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
socket.onclose = function(){
|
||||||
|
console.log("disconnected");
|
||||||
|
};
|
||||||
|
|
||||||
|
sendMessage = function(message) {
|
||||||
|
socket.send(JSON.stringify(message));
|
||||||
|
};
|
||||||
|
|
||||||
|
function buttonPress(colour) {
|
||||||
|
var request = {"message_type": "io_request",
|
||||||
|
"io_type": "led",
|
||||||
|
"led_colour": colour,
|
||||||
|
"operation": "toggle"};
|
||||||
|
sendMessage(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="container"></div>
|
||||||
|
<h1>Controller</h1>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td><button onClick="buttonPress('R')">Toggle red LED</button></td>
|
||||||
|
<td><p id="R">LED state: ?</p></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><button onClick="buttonPress('G')">Toggle green LED</button></td>
|
||||||
|
<td><p id="G">LED state: ?</p></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
import RPi.GPIO as GPIO
|
||||||
|
GPIO.setwarnings(False)
|
||||||
|
GPIO.setmode(GPIO.BCM)
|
||||||
|
|
||||||
|
pins = [19, 26]
|
||||||
|
|
||||||
|
GPIO.setup(pins, GPIO.OUT, initial=GPIO.LOW)
|
||||||
|
|
||||||
|
def colour_to_pin(colour):
|
||||||
|
if colour == "R":
|
||||||
|
return 19
|
||||||
|
if colour == "G":
|
||||||
|
return 26
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def on(colour):
|
||||||
|
pin = colour_to_pin(colour)
|
||||||
|
GPIO.output(pin, GPIO.HIGH)
|
||||||
|
|
||||||
|
def off(colour):
|
||||||
|
pin = colour_to_pin(colour)
|
||||||
|
GPIO.output(pin, GPIO.LOW)
|
||||||
|
|
||||||
|
def read(colour):
|
||||||
|
pin = colour_to_pin(colour)
|
||||||
|
return GPIO.input(pin)
|
||||||
|
|
||||||
|
def toggle(colour):
|
||||||
|
if read(colour):
|
||||||
|
off(colour)
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
on(colour)
|
||||||
|
return 1
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
netifaces==0.10.9
|
||||||
|
pkg-resources==0.0.0
|
||||||
|
RPi.GPIO==0.6.5
|
||||||
|
tornado==6.0.1
|
||||||
Loading…
Reference in new issue