Dreo — Printing Press CLI
Prerequisites: Install the CLI
This skill drives the dreo-pp-cli binary. You must verify the CLI is installed before invoking any command from this skill. If it is missing, install it first:
- Install via the Printing Press installer. It defaults binaries to
$HOME/.local/binon macOS/Linux and%LOCALAPPDATA%\Programs\PrintingPress\binon Windows:npx -y @mvanhorn/printing-press-library install dreo --cli-only - Verify:
dreo-pp-cli --version - Ensure the reported install directory is on
$PATHfor the agent/runtime that will invoke this skill.
If the npx install fails (no Node, offline, etc.), fall back to a direct Go install (requires Go 1.26.6 or newer):
go install github.com/mvanhorn/printing-press-library/library/devices/dreo/cmd/dreo-pp-cli@latest
If --version reports "command not found" after install, the runtime cannot see the binary directory on $PATH. Do not proceed with skill commands until verification succeeds.
When to Use This CLI
Reach for this CLI whenever an agent or script needs to read or control Dreo devices without Home Assistant in the loop. It is ideal for one-shot bulk commands (turn everything off at bedtime), whole-house sensor reads, live state streaming for automation debugging, and any cron-driven Dreo automation. The agent-callable MCP surface mirrors every Cobra command so AI agents can drive your home without a custom integration.
Unique Capabilities
These capabilities aren't available in any other tool for this API.
Multi-device control
bulk— Power, mode, or speed across every device matching a type/room filter in one command.Replaces the #1 user pain — tapping each device in the Dreo app at bedtime — with one cron-callable line.
dreo-pp-cli bulk --action off --type tower-fan --dry-runscene save— Capture the current state across selected devices as a named scene and replay it later as parallel WebSocket frames.Sam's nightly bedtime routine becomes one command; survives app updates.
dreo-pp-cli scene save bedtime --all && dreo-pp-cli scene apply bedtime --dry-run
Cross-device intelligence
sensors— Aggregated temperature, humidity, and PM2.5 across every sensor-bearing device in one ranked table.Answers the agent question 'what's the air quality across my house?' in one tool call.
dreo-pp-cli sensors --jsonsensors record— Persist WebSocket state events to a local sensor_readings table and query temperature/humidity/PM2.5 over arbitrary time windows.Answers 'when did the bedroom fan last go to sleep mode' and similar historical questions agents and users actually ask.
dreo-pp-cli sensors query --metric temperature --since 1h --jsonalerts— Report devices with low filter life, empty water tank, offline heartbeat, or sensor readings past a threshold.Surfaces actionable problems (filter, water, dead devices) without manually inspecting each device.
dreo-pp-cli alerts --pm25-above 50 --jsonrooms— Group devices by room with on-count, average temperature, and average humidity per room.Answers 'what's happening in my bedroom right now' in one query.
dreo-pp-cli rooms --jsondevices search— Full-text search over cached device name, room, model, and serial.Fast device lookup for scripts and agents without round-tripping the cloud.
dreo-pp-cli devices search Fan
Realtime observability
watch— Tail-f for Dreo device state — every WebSocket update as a JSON line on stdout.Enables automation debugging without running Home Assistant, and feeds agent stream-processing pipelines.
dreo-pp-cli watch --all --json
Command Reference
devices — Discover and inspect Dreo devices on your account
dreo-pp-cli devices list— List every Dreo device on your accountdreo-pp-cli devices state— Read the current state snapshot for one device
firmware — Read firmware metadata and check for updates
dreo-pp-cli firmware— Check whether a firmware update is available for a device
settings — Read and write persistent per-device settings
dreo-pp-cli settings get— Get persistent settings for a devicedreo-pp-cli settings update— Update persistent settings for a device
Finding the right command
When you know what you want to do but not which command does it, ask the CLI directly:
dreo-pp-cli which "<capability in your own words>"
which resolves a natural-language capability query to the best matching command from this CLI's curated feature index. Exit code 0 means at least one match; exit code 2 means no confident match — fall back to --help or use a narrower query.
Hand-written Extensions
These commands are declared by the spec author and require separate hand-written wiring; the generator does not emit Cobra registration for them. They are listed here for discoverability and are intentionally outside ## Command Reference so the verify-skill unknown-command check does not treat them as generator-owned paths.
dreo-pp-cli set <device>— Set state on a device (power, speed, mode, oscillation, timer) over WebSocketdreo-pp-cli bulk— Fan-out a control command across every device matching a filter (--type, --room)dreo-pp-cli watch— Tail-f for Dreo device state — every WebSocket update as a JSON line on stdoutdreo-pp-cli sensors— Whole-house temperature, humidity, and PM2.5 across every sensor-bearing devicedreo-pp-cli sensors record— Record WebSocket state events to a local sensor_readings table for timeseries historydreo-pp-cli sensors query— Query the local sensor_readings table over arbitrary time windowsdreo-pp-cli alerts— Report devices with low filter life, empty water tank, offline heartbeat, or sensor thresholdsdreo-pp-cli scene save <name>— Snapshot the current state across selected devices as a named scenedreo-pp-cli scene apply <name>— Replay a saved scene as parallel WebSocket control framesdreo-pp-cli rooms— Per-room aggregates (device count, on-count, avg temperature, avg humidity)dreo-pp-cli auth login— Exchange Dreo email and password for an access token; caches token for subsequent callsdreo-pp-cli auth logout— Clear cached Dreo access token from local configdreo-pp-cli auth status— Show current Dreo auth status (cached token age, region, last login)
Recipes
Bedtime bulk-off
dreo-pp-cli bulk --action off --type tower-fan && dreo-pp-cli bulk --action sleep --type air-purifier
One line replaces ten taps in the Dreo app; cron-friendly.
Whole-house sensor read (agent-friendly with --select)
dreo-pp-cli sensors --json --select 'devices.name,devices.room,devices.temperature_c,devices.humidity,devices.pm25'
Returns only the sensor columns an agent needs, dropping the verbose device metadata.
Capture a bedtime scene
dreo-pp-cli scene save bedtime --all && dreo-pp-cli scene apply bedtime --dry-run
Snapshot all device state under a named scene, then replay it any night.
Filter and water-tank alert sweep
dreo-pp-cli alerts --json
Reports purifiers with filter life < 10% and humidifiers with empty water tanks across your whole account.
Sensor history query
dreo-pp-cli sensors query --device Fan --metric temperature --since 24h --json
Run the recorder in the background, then query the local timeseries — no other Dreo tool keeps history.
Auth Setup
Dreo has no public developer API. Authentication uses your Dreo account email and password against the same OAuth endpoint the Dreo iOS app calls. The password is MD5-hashed before the wire; the bearer token returned is cached locally and reused.
Env vars (only — no --password flag):
export DREO_USERNAME='your-dreo-account-email'
export DREO_PASSWORD='your-dreo-password'
Then run any command. The CLI exchanges credentials for an access token on first use, caches both the credentials and the bearer token to ~/.config/dreo-pp-cli/config.toml (mode 0600), and reuses them. When the bearer expires (Dreo issues no refresh token), the CLI mints a new one transparently using the cached credentials — cron jobs and unattended runs don't need env vars re-exported. Optional: pin DREO_REGION=us (or eu) to skip region discovery on first login.
Three ways to supply credentials, in order of preference:
- Env vars (recommended):
DREO_USERNAME/DREO_PASSWORDexported in your shell or set by your secret-loading wrapper. --password-stdin(scriptable, no leak): pipe the password from a secret store. Docker-style:op read 'op://Personal/Dreo/password' | dreo-pp-cli auth login --username me@example.com --password-stdin--password <value>(insecure, prints a stderr warning): mysql/curl-style. Supported for ergonomics but prints a warning every time because the plaintext value lands inps,/proc/<pid>/cmdline, audit logs, and shell history.
Security contract:
- Flag-supplied passwords (
--password <value>) are accepted but warned against on stderr. - Credentials and the bearer token are persisted to
~/.config/dreo-pp-cli/config.tomlat mode0600. This matches AWS CLI's~/.aws/credentialspattern and is necessary because Dreo's OAuth flow has no refresh token — without persistence, expired bearer tokens would require manual re-login. Treat the config file as sensitive: don't commit it, don't share it, don't sync it to cloud-storage providers without encryption. dreo-pp-cli auth logoutwipes both the cached token and the persisted credentials.dreo-pp-cli auth statusshows current authentication state without revealing the token or password.
Run dreo-pp-cli doctor to verify end-to-end.
Agent Mode
Add --agent to any command. Expands to: --json --compact --no-input --no-color --yes.
Pipeable — JSON on stdout, errors on stderr
Filterable —
--selectkeeps a subset of fields. Dotted paths descend into nested structures; arrays traverse element-wise. Critical for keeping context small on verbose APIs:dreo-pp-cli devices list --agent --select id,name,statusPreviewable —
--dry-runshows the request without sendingNon-interactive — never prompts, every input is a flag
Explicit retries — use
--idempotentonly when an already-existing create should count as success
Agent Feedback
When you (or the agent) notice something off about this CLI, record it:
dreo-pp-cli feedback "the --since flag is inclusive but docs say exclusive"
dreo-pp-cli feedback --stdin < notes.txt
dreo-pp-cli feedback list --json --limit 10
Entries are stored locally at ~/.dreo-pp-cli/feedback.jsonl. They are never POSTed unless DREO_FEEDBACK_ENDPOINT is set AND either --send is passed or DREO_FEEDBACK_AUTO_SEND=true. Default behavior is local-only.
Write what surprised you, not a bug report. Short, specific, one line: that is the part that compounds.
Output Delivery
Every command accepts --deliver <sink>. The output goes to the named sink in addition to (or instead of) stdout, so agents can route command results without hand-piping. Three sinks are supported:
| Sink | Effect |
|---|---|
stdout |
Default; write to stdout only |
file:<path> |
Atomically write output to <path> (tmp + rename) |
webhook:<url> |
POST the output body to the URL (application/json or application/x-ndjson when --compact) |
Unknown schemes are refused with a structured error naming the supported set. Webhook failures return non-zero and log the URL + HTTP status on stderr.
Named Profiles
A profile is a saved set of flag values, reused across invocations. Use it when a scheduled agent calls the same command every run with the same configuration - HeyGen's "Beacon" pattern.
dreo-pp-cli profile save briefing --json
dreo-pp-cli --profile briefing devices list
dreo-pp-cli profile list --json
dreo-pp-cli profile show briefing
dreo-pp-cli profile delete briefing --yes
Explicit flags always win over profile values; profile values win over defaults. agent-context lists all available profiles under available_profiles so introspecting agents discover them at runtime.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 2 | Usage error (wrong arguments) |
| 3 | Resource not found |
| 4 | Authentication required |
| 5 | API error (upstream issue) |
| 7 | Rate limited (wait and retry) |
| 10 | Config error |
Argument Parsing
Parse $ARGUMENTS:
- Empty,
help, or--help→ showdreo-pp-cli --helpoutput - Starts with
install→ ends withmcp→ MCP installation; otherwise → see Prerequisites above - Anything else → Direct Use (execute as CLI command with
--agent)
MCP Server Installation
Install the MCP binary from this CLI's published public-library entry or pre-built release, then register it:
claude mcp add dreo-pp-mcp -- dreo-pp-mcp
Verify: claude mcp list
Direct Use
- Check if installed:
which dreo-pp-cliIf not found, offer to install (see Prerequisites at the top of this skill). - Match the user query to the best command from the Unique Capabilities and Command Reference above.
- Execute with the
--agentflag:dreo-pp-cli <command> [subcommand] [args] --agent - If ambiguous, drill into subcommand help:
dreo-pp-cli <command> --help.