Skip to content

Instantly share code, notes, and snippets.

@dupontgu
Created November 16, 2022 14:23
Show Gist options
  • Save dupontgu/0034d9c590adac9c04b037a28f34caca to your computer and use it in GitHub Desktop.
Save dupontgu/0034d9c590adac9c04b037a28f34caca to your computer and use it in GitHub Desktop.
CircuitPython HTTP Remote (used for Android TV control)
# Tested on a Raspbery Pi Pico W running CircuitPyton 8
import socketpool
import wifi
import board
import array
import time
import usb_hid
import digitalio
# download the .mpy from https://github.com/deckerego/ampule
import ampule
# from https://circuitpython.org/libraries
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
from adafruit_hid.consumer_control import ConsumerControl
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)
cc = ConsumerControl(usb_hid.devices)
led = digitalio.DigitalInOut(board.LED)
led.direction = digitalio.Direction.OUTPUT
led.value = False
# this might fail, feel free to wrap in error handling / retry logic
wifi.radio.connect("your WiFI SSID", "your password")
# read file from CIRCUITPY drive as a string
def static_file(filename):
with open(filename) as local_file:
content = local_file.read()
return content
# send a normal key code via HTTP, "press" and release it via USB.
@ampule.route("/key_code/<code>")
def key_code(request, code):
print("code", code)
keyboard.press(int(code))
keyboard.release_all()
return (200, {}, str(code))
# send a normal consumer code (usually for media control) via HTTP, "press" and release it via USB.
@ampule.route("/consumer_code/<code>")
def consumer_code(request, code):
print("cc code", code)
cc.send(int(code))
return (200, {}, str(code))
# load the main UI
@ampule.route("/")
def index(request):
return (200, {}, static_file("remote.html"))
pool = socketpool.SocketPool(wifi.radio)
socket = pool.socket()
socket.bind(['0.0.0.0', 80])
socket.listen(1)
# turn on the LED to indicate everything is up and running.
led.value = True
print("Connected")
while True:
ampule.listen(socket)
<!DOCTYPE html>
<html>
<body>
<style>
.button {
height: 200px;
font-size: 50px;
width: 50%;
}
</style>
<script>
function sendKeyCode(code) {
console.log(`send code; ${code}`)
fetch(`key_code/${code}`)
.then((response) => console.log(response))
}
function sendConsumerCode(code) {
console.log(`send consumer code; ${code}`)
fetch(`consumer_code/${code}`)
.then((response) => console.log(response))
}
</script>
<!-- Keycode values pulled from: https://docs.circuitpython.org/projects/hid/en/latest/_modules/adafruit_hid/keycode.html -->
<div style="width: 80%;">
<div style="background-color: #4400ff; width: 100%">
<button class="button" style="width: 100%;" onclick="sendKeyCode(0x52)">UP</button>
</div>
<div>
<button class="button" style="width: 32%;" onclick="sendKeyCode(0x50)">LEFT</button>
<button class="button" style="width: 32%;" onclick="sendKeyCode(0x28)">ENTER</button>
<button class="button" style="width: 32%;" onclick="sendKeyCode(0x4F)">RIGHT</button>
</div>
<div>
<button class="button" style="width: 100%;" onclick="sendKeyCode(0x51)">DOWN</button>
</div>
<br><br>
<div>
<button class="button" onclick="sendConsumerCode(0xEA)">VOL -</button>
<button class="button" onclick="sendConsumerCode(0xE9)">VOL +</button>
</div>
<div>
<button class="button" onclick="sendKeyCode(0x2A)">BACK</button>
</div>
<div>
<!-- TODO This is not the right key code for Home, at least not on Android TV -->
<button class="button" onclick="sendKeyCode(0x5F)">HOME</button>
</div>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment