- Free Sleep is a local controller for 8 Sleep Pods. The server runs on the Pod's embedded Linux system and exposes a local REST API. The app is a React/MUI web UI served by the server.
- The Pod hardware is controlled through a Unix socket called
dac.sock; this repo calls that integration "Franken" or "Franken sock". - Persistent user data lives under
/persistent/free-sleep-data/on the Pod. Local development mirrors parts of that underserver/free-sleep-data/.
app/: Vite React frontend using MUI, Zustand, React Query, and Axios.server/: Express TypeScript backend, LowDB JSON settings/schedules, Prisma SQLite metrics, node-schedule jobs, and Franken socket control.biometrics/: Python stream processing, sleep detection, vitals calculation, and SQLite writes for biometrics.scripts/: Pod install/update/reset/service helper scripts.docs/: user-facing screenshots and hardware teardown/install docs.
- App typecheck:
cd app && npx tsc -b - App lint:
cd app && npm run lint - App dev server:
cd app && VITE_POD_IP=<pod-ip> npm run dev - Server typecheck without writing
dist:cd server && npx tsc --noEmit - Server lint:
cd server && npm run lint - Server hot reload on Pod:
fs-dev-serverperserver/README_SERVER.md - Server local dev:
cd server && npm run dev:local
server/src/config.tsrequiresDATA_FOLDERandENV; Pod runtime gets these throughserver/.env.podvianpm start.server/src/jobs/jobScheduler.tsschedules jobs at import time and watches the LowDB folder for changes. Writes to settings or schedules trigger full job cancellation and recreation.- Schedule data is stored in
schedulesDB.json; settings are stored insettingsDB.json; service health is stored inservicesDB.json. - The app imports schemas directly from
server/src/db/*Schema.ts; schema changes must remain compatible with both app and server TypeScript settings.
- Client schedule state lives in
app/src/pages/SchedulePage/scheduleStore.tsx. - Schedule save payloads are assembled in
app/src/pages/SchedulePage/SchedulePage.tsx. - Server schedule writes are handled by
server/src/routes/schedules/schedules.ts. - Scheduled jobs are created in:
server/src/jobs/powerScheduler.tsserver/src/jobs/temperatureScheduler.tsserver/src/jobs/alarmScheduler.tsserver/src/jobs/primeScheduler.ts
- Socket lifecycle:
server/src/8sleep/frankenServer.ts - Socket server wrapper:
server/src/8sleep/unixSocketServer.ts - Message parsing:
server/src/8sleep/messageStream.ts - Hardware command map:
server/src/8sleep/deviceApi.ts - Device status parsing:
server/src/8sleep/loadDeviceStatus.ts - Startup initializes Franken from
server/src/server.ts; health is surfaced throughserver/src/serverStatus.ts.
- Check timezone behavior with
moment-timezone; the app sets a default timezone after settings load, and server jobs setRecurrenceRule.tz. - Prefer adding tests or small reproductions around scheduling time math before changing job timing.
- When reviewing install/update scripts, remember they run as root or through sudo on an embedded Yocto-based system.
- Any complicated functions should have concise, short comments explaining what the function does
- Do not write obscure code with abbreviated variable names <= 2 characters
- Scalability is important, don't write one off hacks. Ensure new files and code are placed in appropriate locations.