Go to file
Krzysztof Rudnicki f878d48f11
Some checks are pending
pre-commit / pre-commit (push) Waiting to run
Tests / test (3.10) (push) Waiting to run
Tests / test (3.11) (push) Waiting to run
Tests / test (3.12) (push) Waiting to run
Run the fit check as a module, so it works where nothing is installed
CI caught what a developer machine cannot: the hook died with "No module
named" its own package. The package is pip-installed locally, so running the
script by path found it anyway; a fresh checkout has no install, and
`python3 scripts/x.py` puts only `scripts/` on sys.path.
`python3 -m scripts.verify_screen_fits` puts the repo root there instead,
which is the checkout in CI and locally alike. The xvfb re-exec runs the same
way, with an explicit cwd so the child does not depend on where the parent was
invoked from.

pylint had the same blind spot for the same reason: it infers sys.path from
the files it is handed, so a script outside the package resolved its imports
only when a package file happened to be in the same batch -- passing or
failing by what else was staged. An init-hook puts the repo root on the path
unconditionally.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BsXnTHyuuCUZsqetTaajcF
2026-08-03 16:37:02 +02:00
.github/workflows Extract wake_alarm from testsAndMisc as a standalone repo 2026-06-22 12:31:40 +02:00
docs/explanations Add change explanation: phone-driven-alarm-timer 2026-07-20 09:17:12 +02:00
phone_app Let a half-awake keyboard user actually reach Submit 2026-07-30 16:27:39 +02:00
scripts Run the fit check as a module, so it works where nothing is installed 2026-08-03 16:37:02 +02:00
wake_alarm Size the alarm's type in pixels, and gate every screen on fitting 768px 2026-08-03 16:04:27 +02:00
.gitignore Add CI-mirror pre-push gate + requirements-sync check 2026-07-11 17:51:16 +02:00
.pre-commit-config.yaml Run the fit check as a module, so it works where nothing is installed 2026-08-03 16:37:02 +02:00
CLAUDE.md Fire the alarm at the phone's time via a per-minute timer 2026-07-19 20:21:17 +02:00
DESIGN_AUDIT_TODO.md Add a design-rules audit against the new safe-design-rules checklist 2026-07-21 15:25:20 +02:00
install.sh Fire the alarm at the phone's time via a per-minute timer 2026-07-19 20:21:17 +02:00
MIGRATION.md MIGRATION.md: correct the pinned crdt_sync_dart tag to v0.2.0 2026-07-20 08:59:00 +02:00
pyproject.toml Run the fit check as a module, so it works where nothing is installed 2026-08-03 16:37:02 +02:00
README.md Fire the alarm at the phone's time via a per-minute timer 2026-07-19 20:21:17 +02:00
requirements.txt Size the alarm's type in pixels, and gate every screen on fitting 768px 2026-08-03 16:04:27 +02:00
shutdown-wrapper.sh Fire the alarm at the phone's time via a per-minute timer 2026-07-19 20:21:17 +02:00
sleep-hook.sh Extract wake_alarm from testsAndMisc as a standalone repo 2026-06-22 12:31:40 +02:00
wake-alarm-fans.sh Extract wake_alarm from testsAndMisc as a standalone repo 2026-06-22 12:31:40 +02:00
wake-alarm-trigger.service Fire the alarm at the phone's time via a per-minute timer 2026-07-19 20:21:17 +02:00
wake-alarm-trigger.timer Fire the alarm at the phone's time via a per-minute timer 2026-07-19 20:21:17 +02:00
wake-alarm.service Fire the alarm at the phone's time via a per-minute timer 2026-07-19 20:21:17 +02:00

wake_alarm

A phone-driven wake alarm for an always-on PC. The alarm time is whatever the companion phone app last synced (via the shared crdt_sync transport over a private GitHub repo); a per-minute systemd user timer fires at exactly that time, showing a fullscreen, challenge-dismissed alarm with fan ramp and optional TP-Link Tapo P110 smart-plug control.

Change the alarm on the phone at any hour and the PC follows within ~5 minutes. If the PC does happen to be powered down, a shutdown wrapper hibernates with rtcwake set to the same synced time, as a fallback.

Install

bash install.sh

This installs the package + dependencies into system Python's user site-packages (the systemd units run /usr/bin/python directly, not a venv — see CLAUDE.md), installs and enables the per-minute trigger timer, the systemd-sleep resume hook, the shutdown wrapper that hibernates with rtcwake as a fallback, the fan-ramp script, and (optionally) python-kasa for smart-plug control.

Reading the phone's alarm needs a GitHub token with repo scope, at ~/.config/wake_alarm/sync.json as {"token": "..."}. If that file is absent, a sibling app's ~/.config/{diet_guard,screen_locker}/sync_token is used instead, so one token covers every app syncing through kuhyx/syncs.

Usage

python -m wake_alarm._alarm --demo     # test the alarm window (safe, closeable)
python -m wake_alarm._sync --show      # what alarm time the PC resolves
python -m wake_alarm._trigger --dry-run  # what the next tick would do
journalctl --user -fu wake-alarm-trigger.service  # watch it live

The alarm fires automatically once installed; no manual invocation is needed in normal operation.

Development

python -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/pre-commit install && .venv/bin/pre-commit install --hook-type pre-push
.venv/bin/python -m pytest wake_alarm/tests/ --cov=wake_alarm --cov-branch --cov-fail-under=100

See CLAUDE.md for scheduling details, the hibernate/rtcwake mechanism, the cross-repo workout_log.json read, and production deployment gotchas.