Automate with the CLI¶
The quilt CLI exposes the library's read and control operations as subcommands. info,
devices, values and diagnostics take --output json, so you can pipe them into jq, use
them in shell scripts, or call them from CI pipelines.
Authenticate from the command line¶
To log in and cache tokens:
The CLI emails you a one-time code and prompts for it. Tokens are cached in tokens.json in the
user config directory (~/.config/quilt-hp/ on Linux, ~/Library/Application Support/quilt-hp/
on macOS) with permissions 0o600. Later commands reuse the cache without prompting. To log out,
delete that file.
To avoid passing --email on every command, set the environment variable:
Get a system snapshot as JSON¶
info returns every entity: spaces, indoor_units, outdoor_units, controllers (Dials),
quilt_smart_modules, remote_sensors, plus timezone and version_at. The spaces list
includes the home itself; rooms have "is_room": true.
Pipe to jq for filtering:
# Every room with its temperature
quilt info --output json \
| jq '.spaces[] | select(.is_room) | {name, temp_c: .state.ambient_temperature_c}'
# Rooms currently in COOL mode
quilt info --output json \
| jq '[.spaces[] | select(.is_room and .controls.hvac_mode == "COOL") | .name]'
# Dials that are offline
quilt info --output json | jq '[.controllers[] | select(.is_online == false) | .name]'
quilt values --output json is a smaller payload with only setpoints and sensor readings.
Read Dial presence and display state¶
Each Dial reports what its screen is doing and whether its own radar sees someone:
quilt info --output json | jq '.controllers[] | {
room: .space_name,
display: .view_state, # SLEEP, GLANCE or ACTIVE
brightness: .screen_brightness,
presence: .presence_detected, # Dial radar: target or phase detection
light_lx: .ambient_light_lux
}'
Detect configuration changes¶
version_at is the time of the last write to any control, setting or configuration in the
system. It doesn't change on sensor telemetry. Poll it to re-sync only when something changed:
#!/usr/bin/env bash
set -euo pipefail
STATE=/var/tmp/quilt-version
now=$(quilt info --output json | jq -r '.version_at')
if [[ "$now" != "$(cat "$STATE" 2>/dev/null)" ]]; then
echo "$now" > "$STATE"
echo "Quilt configuration changed at $now"
fi
Check diagnostics¶
# Human-readable: per-IDU fault conditions, refrigerant temps, dew point and power
quilt diagnostics
# Only indoor units with an active fault
quilt diagnostics --faults-only
# JSON for scripting: every active fault system-wide
quilt diagnostics --output json \
| jq '.indoor_units[] | select(.active_faults | length > 0) | {name, active_faults}'
# Indoor units running a health check or commissioning test
quilt diagnostics --output json | jq '[.indoor_units[] | select(.under_test) | {name, test}]'
The outdoor unit's own raw sensors (compressor Hz, pressures, discharge temp) are withheld from the cloud plane; the diagnostic conditions and refrigerant pipe temperatures for each ODU circuit are surfaced through its indoor units.
Control rooms from the shell¶
quilt set takes the room's exact name (case-insensitive) and at least one of --mode,
--heat, --cool or --fan. Setpoints are in °C.
# Cool the living room to 22°C
quilt set "Living Room" --mode COOL --cool 22
# Auto with a heating/cooling range
quilt set "Bedroom" --mode AUTO --heat 19 --cool 24
# Turn a room off
quilt set "Guest Room" --mode STANDBY
# Change the fan speed on every indoor unit in the room
quilt set "Office" --fan QUIET
Modes: COOL, HEAT, AUTO, FAN, DRY, STANDBY. Fan speeds: AUTO, QUIET, LOW,
MEDIUM, HIGH, BLAST.
Write a bash script to set all rooms to a setpoint¶
#!/usr/bin/env bash
set -euo pipefail
SETPOINT="${1:-22}"
quilt info --output json \
| jq -r '.spaces[] | select(.is_room) | .name' \
| while IFS= read -r room; do
echo "Setting $room to ${SETPOINT}°C"
quilt set "$room" --mode COOL --cool "$SETPOINT"
done
Process snapshot output in Python without importing the library¶
When you want Python's expressiveness but don't need to import the library directly:
#!/usr/bin/env python3
import json
import subprocess
result = subprocess.run(
["quilt", "info", "--output", "json"],
capture_output=True,
text=True,
check=True,
)
data = json.loads(result.stdout)
for space in data["spaces"]:
if not space["is_room"]:
continue
temp = space["state"]["ambient_temperature_c"]
mode = space["controls"]["hvac_mode"]
temp_str = f"{temp:.1f}°C" if temp is not None else "unknown"
print(f" {space['name']:<20} {mode:<8} {temp_str}")
Set up a cron job for nightly standby¶
Put every room in STANDBY at midnight with a small script:
#!/usr/bin/env bash
# /usr/local/bin/quilt-standby
set -euo pipefail
quilt info --output json \
| jq -r '.spaces[] | select(.is_room) | .name' \
| while IFS= read -r room; do
quilt set "$room" --mode STANDBY
done
Write snapshot metrics to a Prometheus textfile¶
#!/usr/bin/env bash
# Runs every minute via cron
OUTFILE="/var/lib/node_exporter/quilt.prom"
TMPFILE="${OUTFILE}.tmp"
# The program goes in a variable: `python3 - <<EOF` would read the script from
# stdin and lose the piped JSON.
read -r -d '' PROG << 'PYEOF' || true
import sys, json
data = json.load(sys.stdin)
for space in data["spaces"]:
if not space["is_room"]:
continue
name = space["name"].lower().replace(" ", "_")
mode = space["controls"]["hvac_mode"]
temp = space["state"]["ambient_temperature_c"]
print(f'quilt_room_temp_celsius{{room="{name}"}} {"NaN" if temp is None else temp}')
print(f'quilt_room_mode{{room="{name}",mode="{mode}"}} 1')
for dial in data["controllers"]:
room = (dial["space_name"] or dial["id"]).lower().replace(" ", "_")
print(f'quilt_dial_presence{{room="{room}"}} {int(bool(dial["presence_detected"]))}')
print(f'quilt_dial_online{{room="{room}"}} {int(dial["is_online"])}')
PYEOF
quilt info --output json | python3 -c "$PROG" > "$TMPFILE"
mv "$TMPFILE" "$OUTFILE"
Query energy usage¶
# Today, per room (kWh)
quilt energy --period day
# This week or this month
quilt energy --period week
quilt energy --period month
energy prints a human-readable table only. For per-bucket data in scripts, use
QuiltClient.get_energy() from Python.
CLI exit codes¶
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Any error: authentication failure (re-run quilt login), room not found, invalid mode or fan speed, nothing to update, or a gRPC/network failure. The message is printed in red. |
| 2 | Invalid command-line usage (unknown option, out-of-range setpoint), reported by the argument parser |