Clock
Clock widget - big time, refreshed every second.
How to run
This app is a single Python file that talks directly to the BUSY Bar HTTP API: no libraries, no setup. Connect your bar via USB and run:
python app.py
Over USB the bar is always at 10.0.4.20. On Wi-Fi, pass the bar's IP
with --host <address>.
No bar at hand? Run the
BUSY Bar Emulator
and point the app at it: python app.py --host 127.0.0.1:8080.
Source code
app.py
#!/usr/bin/env python3
"""Clock widget: big time, refreshed every second.
python app.py # BUSY Bar over USB (always 10.0.4.20)
python app.py --host 127.0.0.1:8080 # emulator or a Wi-Fi bar
"""
import json
import sys
import time
import urllib.error
import urllib.request
APP = "clock"
# ---------------------------------------------------------------------------
# BUSY Bar HTTP API — self-contained, stdlib only.
# Over USB the bar is always at 10.0.4.20; --host targets a Wi-Fi bar or the
# emulator. Full API docs are served by the device: http://10.0.4.20/docs
# ---------------------------------------------------------------------------
def _host(default="10.0.4.20"):
if "--host" in sys.argv:
i = sys.argv.index("--host")
if i + 1 < len(sys.argv):
return sys.argv[i + 1]
return default
BASE = "http://" + _host().replace("http://", "").rstrip("/")
def draw(elements, **extra):
body = {"application_name": APP, "elements": elements, **extra}
req = urllib.request.Request(BASE + "/api/display/draw",
data=json.dumps(body).encode(), method="POST",
headers={"Content-Type": "application/json"})
with urllib.request.urlopen(req, timeout=5):
pass
def text(txt, x=0, y=0, font="normal", color="#FFFFFFFF", **kw):
# Every element needs an id, and colors are #RRGGBBAA (API 25.0.0+).
return {"id": "0", "type": "text", "text": str(txt), "x": x, "y": y, "font": font, "color": color, **kw}
# ---------------------------------------------------------------------------
# App
# ---------------------------------------------------------------------------
def tick():
hhmm = time.strftime("%H:%M:%S", time.localtime())
try:
# align lets the device place elements without measuring text width.
draw([text(hhmm, x=36, y=15, font="extra_large", align="bottom_mid")])
except urllib.error.HTTPError as e:
# A higher-priority app owns the screen: keep ticking and retry next second.
if e.code != 409:
raise
print("display busy (409), retrying...")
if __name__ == "__main__":
print(f"clock → {BASE} (Ctrl-C to stop)")
try:
while True:
tick()
time.sleep(1.0)
except KeyboardInterrupt:
print("\nstopped.")
except urllib.error.HTTPError as e:
sys.exit(f"error: HTTP {e.code} — {e.read().decode('utf-8', 'ignore')}")
except urllib.error.URLError as e:
sys.exit(f"error: cannot reach {BASE} — {e.reason}")