ESP32-S3 Bench Guide
ESP32-S3 N16R8 bench guide: live pinout, lessons, simulators and the bench log.
翻译准备中
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Just a better fucking untis app
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A school timetable app for AP Hogeschool students: fetches lessons directly from the WebUntis REST API (the same source the AP-WebUntisToICS-Node server uses), stores everything offline, and stays out of your way.
• React Native + Expo SDK 57 (expo-router), bun
• React Native Reusables (RNR) components + NativeWind v4, dark theme
• Syncs once, then works fully offline (AsyncStorage)
• No server needed on mobile — Android/iOS call WebUntis directly查看完整 README ↗A school timetable app for AP Hogeschool students: fetches lessons directly from the WebUntis REST API (the same source the AP-WebUntisToICS-Node server uses), stores everything offline, and stays out of your way.
bun install
bun start # dev server (scan QR for Expo Go / dev build)
The first launch walks you through: WebUntis server → school year → class.
bun run web:build # expo export --platform web → dist/
bun run web:serve # serves dist/ on http://localhost:8080
Or run the web preview in Docker (no local bun/node needed):
docker build -f Dockerfile.web -t calendar-web .
docker run -d -p 8080:8080 calendar-web # → http://localhost:8080
Browsers require CORS preflight approval for the API's custom
anonymous-school header, which WebUntis does not grant. The web build
therefore goes through the same-origin proxy at /proxy?url=<encoded>
(which forwards that header) served by web:serve. Running under bun start
alone has no proxy — you'll get HTML instead of JSON.
Android/iOS are unaffected and hit the API directly.
Base URL (the API_BASE_URL from the reference project's .env.example):
https://ap.webuntis.com/WebUntis/api/rest/view/v1
The school tenant is selected with the anonymous-school: ap request header.
Responses are cached in memory with the reference server's TTLs: school
years / class lists for 7 days, timetable entries for 15 minutes.
| Endpoint | Used for |
|---|---|
GET /schoolyears | available school years |
GET /app/data | current school year (default date range) |
GET /timetable/filter?resourceType=CLASS&start=&end= | class list for a year |
GET /timetable/entries?resourceType=CLASS&start=&end=&resources=<id> | timetable entries |
Lessons are mapped from the raw grid entries (positions 1–7 → subject / teachers / rooms / info / classes) the same way the reference server does, including merging same-slot lessons and subject filtering (hidden subjects are excluded at sync time).
The app is distributed as a self-hosted APK: the landing page (website/index.html, plain HTML, no build step) offers the download; install once, and receive JS-only fixes silently via EAS Update
(no reinstall). Native changes require a new APK; the fingerprint
runtime-version policy guarantees devices only get compatible updates.
The landing page resolves the newest release at runtime via the GitHub API, so its download button always points at the latest APK without redeploying. Host it anywhere static files work — e.g. with the bundled Dockerfile:
docker build -t betteruntis-site .
docker run -d -p 8080:80 betteruntis-site # → http://localhost:8080
bun run site:serve # local preview without Docker
Both containers together (landing page on :5200, web preview on :5201):
docker compose up -d --build
| Pipeline | Trigger | Output |
|---|---|---|
deploy.yml | push to main | Rebuilds and redeploys both web containers on the own server via docker compose (landing page :5200, web preview :5201) |
update.yml | push to main | EAS OTA update (JS-only, typechecked first) |
release.yml | tag v*.*.* | APK built on EAS cloud, attached to a GitHub Release (= download button target) |
release.yml also carries a version failsafe: it rewrites app.json,
package.json and android.versionCode from the pushed tag (e.g. tag
v1.0.2 → version 1.0.2, versionCode 10002), commits that back to
main, and only then builds — so a release can never ship with a stale
version number or a versionCode too low to install over the previous APK.
fingerprint.config.js keeps version fields out of the update fingerprint,
so those bumps don't break in-app OTA updates for older installs.
Both need an EXPO_TOKEN repo secret (create at expo.dev/settings/access-tokens).
Manual equivalents:
eas update --auto --branch production # push an OTA update
eas build -p android --profile apk # build APK on EAS cloud (same as the release pipeline)
In-app, Settings → "Check for updates" fetches and applies OTA updates immediately; otherwise they apply on the next launch.
bun run typecheck # typecheck app + server
bunx expo run:android # native build
src/app/ — routes: setup wizard, calendar, settingssrc/components/ — week grid (3/5/7-day), agenda, now banner, lesson & add-lesson sheetssrc/lib/ — data layer: WebUntis client + mappers (webuntis.ts), sync, storage, ICS/CSV export, hidden-rule logicsrc/context/calendar-context.tsx — app state, repeat expansion, persistencesrc/components/ui/ — RNR primitivesserver/ — static web server with the CORS proxy (web only; mobile needs no server)