Skip to content

Instantly share code, notes, and snippets.

@Neradoc
Last active January 27, 2023 18:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Neradoc/fd29d5ac2d5bfcf2c56b679345027930 to your computer and use it in GitHub Desktop.
Save Neradoc/fd29d5ac2d5bfcf2c56b679345027930 to your computer and use it in GitHub Desktop.
Text field demo for adafruit_httpserver with Circuitpython 8
# SPDX-FileCopyrightText: 2023 Neradoc
# SPDX-License-Identifier: MIT
"""Show text from the web page on a display"""
import board
import json
import mdns
import microcontroller
import socketpool
import time
import traceback
import wifi
import os
from adafruit_httpserver.server import HTTPServer
from adafruit_httpserver.response import HTTPResponse
from adafruit_httpserver.mime_type import MIMEType
from adafruit_httpserver.status import CommonHTTPStatus
MDNS_NAME = "text-setter"
PORT = 8080
ROOT = "/www"
# setup I2C display
I2C_ADDRESS = 0x3D
DISPLAY_WIDTH = 128
DISPLAY_HEIGHT = 64
SCALE = 1
############################################################################
# Display
############################################################################
import displayio
if hasattr(board, "DISPLAY"):
display = board.DISPLAY
else:
from adafruit_displayio_ssd1306 import SSD1306
displayio.release_displays()
try:
i2c = board.I2C()
except RuntimeError:
i2c = board.STEMMA_I2C()
display_bus = displayio.I2CDisplay(i2c, device_address=I2C_ADDRESS)
display = SSD1306(display_bus, width=DISPLAY_WIDTH, height=DISPLAY_HEIGHT)
############################################################################
# Interface on the display
############################################################################
import terminalio
from adafruit_display_text.label import Label
from adafruit_display_text import wrap_text_to_lines
FONT = terminalio.FONT
box = FONT.get_bounding_box()
LINE_WRAP = display.width // (box[0] * SCALE)
color_bitmap = displayio.Bitmap(display.width, display.height, 1)
color_palette = displayio.Palette(1)
color_palette[0] = 0xFFFFFF # White
splash = displayio.Group()
text_area = Label(
FONT,
scale=SCALE,
text="Ready to\nreceive.",
color=0xFFFF00,
anchored_position=(display.width // 2, 2),
anchor_point=(0.5, 0),
)
splash.append(text_area)
display.show(splash)
############################################################################
# MDNS
############################################################################
mdnserv = mdns.Server(wifi.radio)
mdnserv.hostname = MDNS_NAME
mdnserv.advertise_service(service_type="_http", protocol="_tcp", port=PORT)
############################################################################
# wifi
############################################################################
wifi.radio.connect(
os.getenv("CIRCUITPY_WIFI_SSID"),
os.getenv("CIRCUITPY_WIFI_PASSWORD")
)
print(f"Listening on http://{wifi.radio.ipv4_address}:{PORT}")
pool = socketpool.SocketPool(wifi.radio)
server = HTTPServer(pool)
############################################################################
# server routes and app logic
############################################################################
ERROR400 = CommonHTTPStatus.BAD_REQUEST_400
@server.route("/")
def base(request):
"""Default reponse is /index.html"""
print("/ -> index.html")
with HTTPResponse(request, content_type=MIMEType.TYPE_HTML) as response:
response.send_file(f"{ROOT}/index.html")
@server.route("/text", method="POST")
def base(request):
# receive a text in the body
body = json.loads(request.body)
try:
the_text = body.get("the_text", "")
message = "\n".join(wrap_text_to_lines(the_text, LINE_WRAP))
text_area.text = message
print(f"Received:", message)
with HTTPResponse(request) as response:
response.send("ok")
except (ValueError, AttributeError) as err:
traceback.print_exception(err, err, err.__traceback__)
with HTTPResponse(request, status=ERROR400) as response:
response.send("error")
############################################################################
# start and loop
############################################################################
IP_ADDRESS = wifi.radio.ipv4_address or wifi.radio.ipv4_address_ap
server.start(host=str(IP_ADDRESS), port=PORT, root_path=ROOT)
while True:
server.poll()
time.sleep(0.01)
<!doctype html>
<html lang="en">
<!--
SPDX-FileCopyrightText: Copyright 2023 Neradoc, https://neradoc.me
SPDX-License-Identifier: MIT
-->
<head>
<meta charset="utf-8"/>
<link rel="icon" href="/blinka.png"/>
<title>Button</title>
<style>
@keyframes pulse {
0% {opacity: 1;}
50% {opacity: 0;}
100% {opacity: 1;}
}
@keyframes spin {
0% {transform: rotate(0);}
25% {transform: rotate(90deg);}
50% {transform: rotate(180deg);}
75% {transform: rotate(270deg);}
100% {transform: rotate(360deg);}
}
#form {
width: 320px;
padding: 8px;
background: #B0E0FF;
border-radius: 16px;
margin: auto;
}
#field_text {
font-size: inherit;
padding: 2px 4px;
}
.icons {
display: none;
}
#text_sending {
animation-name: spin;
animation-duration: 1.5s;
animation-iteration-count: infinite;
}
</style>
<script>
async function send_text(field, event) {
console.log(field.value)
console.log(event)
if(event.keyCode == 13) {
const icons = document.getElementsByClassName("icons")
for(icon of icons) { icon.style.display="none" }
const sending = document.getElementById("text_sending")
const sent = document.getElementById("text_sent")
const error = document.getElementById("text_error")
var ok = false;
sending.style.display = "inline-block"
try {
const res = await fetch(`/text`, {
method: "POST",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({the_text: field.value}),
})
console.log(res)
ok = res.ok
} catch(err) {
console.log(err)
}
sending.style.display = "none"
if(ok) {
sent.style.display = "inline"
} else {
error.style.display = "inline"
}
}
}
</script>
</head>
<body>
<div id="form">
<label>Press enter to send:
<input id="field_text" type="text" onkeyup="send_text(this, event)"/>
<span class="icons" id="text_sending">💬</span>
<span class="icons" id="text_sent">☑️</span>
<span class="icons" id="text_error">❌️</span>
</label>
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment