Skip to content

feat(cmd): add away mode (vacation) command#26

Merged
omarshahine merged 1 commit intosteipete:mainfrom
omarshahine:feat/away-mode
Apr 16, 2026
Merged

feat(cmd): add away mode (vacation) command#26
omarshahine merged 1 commit intosteipete:mainfrom
omarshahine:feat/away-mode

Conversation

@omarshahine
Copy link
Copy Markdown
Collaborator

@omarshahine omarshahine commented Mar 15, 2026

Depends on #24 — this PR is rebased on top of the auth/gzip/retry fix. Merge #24 first.

Summary

  • Adds eightctl away on and eightctl away off commands
  • Supports --both flag to toggle both sides of the pod at once
  • Adds doURL() to support the separate app API host (app-api.8slp.net)

Details

Away mode tells the pod to stop heating/cooling for a given side, useful when traveling. The API lives on app-api.8slp.net (separate from client-api.8slp.net), which required adding doURL() for absolute-URL requests.

API contract (reverse-engineered from Eight Sleep Home Assistant integration):

PUT https://app-api.8slp.net/v1/users/{userId}/away-mode

# Activate:  {"awayPeriod": {"start": "2024-03-12T08:15:30.123Z"}}
# Deactivate: {"awayPeriod": {"end": "2024-03-12T08:15:30.123Z"}}

Timestamps are set 24h in the past to trigger immediately (same pattern as pyEight and the official app).

Usage

eightctl away on               # your side only
eightctl away on --both        # both sides
eightctl away off --both       # resume both sides
eightctl away on --user-id ID  # specific side

Changes

File Change
internal/client/eightsleep.go Add appAPIBaseURL (var, testable), refactor do()doURL()doURLRetry(), add SetAwayMode()
internal/client/device.go Add DeviceSides type and Sides() method
internal/client/eightsleep_test.go Tests for SetAwayMode (activate/deactivate payloads) and DeviceSides
internal/cmd/away.go New away command with on/off subcommands, --both flag, --quiet support
internal/cmd/root.go Register awayCmd

Changes since original submission

Add `eightctl away on` and `eightctl away off` to activate/deactivate
away mode. When away, the pod stops heating/cooling.

Supports per-side and whole-pod control:
- Default: authenticated user's side only
- --both: both sides of the pod
- --user-id: specific user/side

Changes:
- Add appAPIBaseURL constant (app-api.8slp.net, used by away mode)
- Refactor do() into do() + doURL() to support requests to different
  base URLs
- Add Device().Sides() to fetch left/right user ID assignments
- Add Client.SetAwayMode(ctx, userID, away) method
- Add away command with on/off subcommands and --both flag

API details reverse-engineered from the Eight Sleep Home Assistant
integration (pyEight):
- PUT https://app-api.8slp.net/v1/users/{userId}/away-mode
- Payload: {"awayPeriod": {"start"|"end": "<ISO 8601 timestamp>"}}
- Timestamps set 24h in the past to trigger immediately

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@omarshahine omarshahine merged commit 0e32c4c into steipete:main Apr 16, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant