Rahulsharma0810/steplock

Locks your Mac with a full-screen overlay, dismissable only by walking (iPhone steps → Home Assistant → MQTT)

★ 0Forks 0PythonGitHub ↗Compare

README

Steplock

Locks your Mac with a full-screen overlay at intervals. The overlay is only dismissable by walking — it tracks your real step count (iPhone + Health Auto Export, via Home Assistant/MQTT) and unlocks once you've taken enough new steps since the lock started.

Built for people who sit too long. If you have a Home Assistant instance already ingesting iPhone step data, this closes the loop: no steps, no Mac.

How it works

iPhone Companion app  ─┐
                       ├─► HA sensor.* ──► MQTT discovery/state ──► steplock/steps
Health Auto Export    ─┘        (or REST fallback poll)                │
                                                                        ▼
                                                        Mac daemon (enforcer.py)
                                                             │
                                                   every N minutes (adaptive)
                                                             ▼
                                                       Overlay (overlay.py)
                                                        unlocks when
                                                  steps_now ≥ baseline + goal

Two ways to feed step data in:

  1. MQTT (recommended) — ha_setup.py publishes MQTT-discovery configs so Home Assistant creates a device with sensors/controls automatically, and the enforcer subscribes for live updates.
  2. REST fallback — polls two HA entities directly (e.g. an iPhone Companion sensor and a Health Auto Export sensor) and picks whichever is freshest.

Features

  • Full-screen overlay across all displays, dismissable only by steps
  • Adaptive lock interval based on daily step pace (behind pace → locks more often)
  • Optional "compute budget": earn seconds of unlocked time per step, lock when it runs out
  • Optional calendar-aware skip (don't lock during meetings)
  • MQTT remote control: pause, skip, trigger-now, resume — controllable from Home Assistant
  • Idle-aware timer (won't burn your interval while you're away)
  • Terminal dashboard (cli.py, built with Textual) to watch status/logs and control the service
  • Home Assistant dashboard auto-provisioned via ha_setup.py

Requirements

  • macOS (uses PyObjC/AppKit/Quartz for the overlay and idle detection)
  • Python 3.11+, uv
  • A Home Assistant instance with an MQTT broker (e.g. the Mosquitto add-on)
  • A step-count entity in HA — from the iOS Home Assistant Companion app, Health Auto Export, or similar

Setup

git clone https://github.com/Rahulsharma0810/steplock.git ~/.config/steplock
cd ~/.config/steplock
uv venv
uv pip install -e .
cp config.example.toml config.toml
cp .env.example .env   # fill in MQTT_PASSWORD and (optionally) HA_TOKEN
chmod 600 .env

Edit config.toml — set your HA host, MQTT username, and step-sensor entity IDs (see the [mqtt] and [fallback] sections).

Home Assistant side

Run the provisioning script once to create the MQTT-discovered device, entities, and a dashboard view in HA:

.venv/bin/python src/ha_setup.py

Make sure MQTT auth is set up (a dedicated broker login is recommended) and the password matches .env.

Run it

# foreground smoke test
.venv/bin/python src/enforcer.py

# terminal dashboard
.venv/bin/python src/cli.py

Install as a background service:

cp launchd/com.steplock.enforcer.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.steplock.enforcer.plist

Logs land in logs/ (rotating, 1MB x 3).

Configuration reference

See config.example.toml for all options and inline comments: [timer], [goal], [daily], [mqtt], [fallback], [overlay], [compute_throttle], [calendar].

.env holds secrets only: MQTT_PASSWORD and optional HA_TOKEN (long-lived access token, used for REST fallback polling and by ha_setup.py).

Uninstall

launchctl bootout gui/$(id -u)/com.steplock.enforcer
rm ~/Library/LaunchAgents/com.steplock.enforcer.plist

Then remove the MQTT-discovered device/entities and dashboard view from Home Assistant if you provisioned them.

License

MIT

Contributors

Rahulsharma0810

Issues