Nest SDM Skill
Control and monitor Google Nest devices via the Smart Device Management REST API.
Setup
Prerequisites
- Device Access Console — Register at https://console.nest.google.com/device-access ($5 one-time fee)
- GCP Project — Create at https://console.cloud.google.com with SDM API enabled
- OAuth Client — Web application type with
https://www.google.comas redirect URI - SDM scope — Add
https://www.googleapis.com/auth/sdm.serviceto OAuth consent screen
First-time Authorization
- Build the authorization URL:
https://nestservices.google.com/partnerconnections/<PROJECT_ID>/auth?redirect_uri=https://www.google.com&access_type=offline&prompt=consent&client_id=<CLIENT_ID>&response_type=code&scope=https://www.googleapis.com/auth/sdm.service
- Open in browser, sign in as the device owner Google account
- Enable ALL device permissions, click Next, then Continue through consent
- Copy the
code=parameter from the redirect URL - Exchange for tokens:
curl -s -X POST https://oauth2.googleapis.com/token \
-d "client_id=<CLIENT_ID>" \
-d "client_secret=<CLIENT_SECRET>" \
-d "code=<AUTH_CODE>" \
-d "grant_type=authorization_code" \
-d "redirect_uri=https://www.google.com"
- Save tokens to the config file (see Configuration below)
Configuration
Create ~/.openclaw/workspace/.nest-sdm-tokens.json:
{
"client_id": "<your-client-id>",
"client_secret": "<your-client-secret>",
"project_id": "<device-access-project-id>",
"refresh_token": "<your-refresh-token>",
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/sdm.service"
}
Secure it: chmod 600 ~/.openclaw/workspace/.nest-sdm-tokens.json
CLI Usage
# Alias for convenience
alias nest="<skill-dir>/nest-sdm.sh"
Device Discovery
nest devices # List all devices (JSON)
nest structures # List structures/rooms
Thermostat
nest thermostat # Current status (temp, humidity, mode, setpoints)
nest set-cool <°F> # Set to COOL mode at temperature
nest set-heat <°F> # Set to HEAT mode at temperature
nest set-range <low°F> <high°F> # Set HEATCOOL range
nest set-mode <MODE> # HEAT | COOL | HEATCOOL | OFF
nest set-eco <MODE> # MANUAL_ECO | OFF
nest fan-on [duration_seconds] # Turn fan on (default: 900s / 15min)
nest fan-off # Turn fan off
Doorbell & Cameras
nest doorbell # Doorbell info & capabilities
nest display # Kitchen display info
nest camera-stream <DEVICE_ID> # Generate WebRTC live stream (returns SDP answer)
nest camera-image <EVENT_ID> # Get event snapshot URL
Raw API
nest api GET devices # Raw device list
nest api GET devices/<DEVICE_ID> # Single device
nest api POST devices/<DEVICE_ID>:executeCommand '{"command":"...","params":{...}}'
Supported Devices
| Type | Traits | Control |
|---|---|---|
| THERMOSTAT | Temperature, Humidity, Mode, Eco, Fan, HVAC, Setpoint, Connectivity | Full read/write |
| DOORBELL | LiveStream, CameraImage, Person, Motion, Chime, EventImage, ClipPreview | Read + stream |
| DISPLAY | LiveStream, CameraImage, Person, Sound, Motion, EventImage | Read + stream |
SDM API Commands Reference
Thermostat Commands
| Command | Params |
|---|---|
ThermostatMode.SetMode | {"mode": "HEAT|COOL|HEATCOOL|OFF"} |
ThermostatTemperatureSetpoint.SetHeat | {"heatCelsius": <float>} |
ThermostatTemperatureSetpoint.SetCool | {"coolCelsius": <float>} |
ThermostatTemperatureSetpoint.SetRange | {"heatCelsius": <float>, "coolCelsius": <float>} |
ThermostatEco.SetMode | {"mode": "MANUAL_ECO|OFF"} |
Fan.SetTimer | {"timerMode": "ON", "duration": "<seconds>s"} |
Camera Commands
| Command | Params |
|---|---|
CameraLiveStream.GenerateWebRtcStream | {"offerSdp": "<SDP offer>"} |
CameraLiveStream.StopWebRtcStream | {"mediaSessionId": "<id>"} |
CameraLiveStream.ExtendWebRtcStream | {"mediaSessionId": "<id>"} |
CameraEventImage.GenerateImage | {"eventId": "<event-id>"} |
Pub/Sub Real-Time Events
Get instant alerts for doorbell presses, motion, person detection, and device state changes.
CLI: nest-events
nest-events setup-check # Verify Pub/Sub config is ready
nest-events create-topic # Create GCP Pub/Sub topic
nest-events grant-permissions # Grant SDM publisher role
nest-events create-subscription # Create pull subscription
nest-events poll # Pull events once
nest-events listen # Poll continuously (daemon)
Setup Steps
- OAuth with Pub/Sub scope — Run OAuth flow as your-email@example.com with
pubsub+cloud-platformscopes. Save tokens to.nest-pubsub-tokens.json. - Create topic —
nest-events create-topic(createsprojects/YOUR_GCP_PROJECT/topics/nest-sdm-events) - Grant permissions —
nest-events grant-permissions(addssdm-publisher@googlegroups.com) - Create subscription —
nest-events create-subscription - Enable in Device Access Console — https://console.nest.google.com/device-access → Enable Pub/Sub → Enter topic ID
- Trigger initial events —
nest devices(one-time API call) - Start listener —
nest-events listen
Event Types Supported
| Event | Alert |
|---|---|
DoorbellChime.Chime | 🔔 DOORBELL — Someone rang! |
CameraPerson.Person | 👤 Person detected at device |
CameraMotion.Motion | 🏃 Motion at device |
CameraSound.Sound | 🔊 Sound at device |
ThermostatHvac status change | ❄️/🔥 HVAC now COOLING/HEATING |
ThermostatTemperatureSetpoint | 🌡️ Setpoint changed |
Temperature trait | 🌡️ Ambient temperature change |
Configuration
Environment Variables:
| Variable | Description | Default |
|---|---|---|
NEST_PUBSUB_TOKENS | Path to Pub/Sub OAuth tokens | ~/.openclaw/workspace/.nest-pubsub-tokens.json |
TELEGRAM_BOT_TOKEN | Bot token for alerts | from ~/.zshenv |
TELEGRAM_CHAT_ID | User/chat ID for alerts | from ~/.zshenv |
POLL_INTERVAL | Seconds between polls | 10 |
GCP_PROJECT | GCP project ID | YOUR_GCP_PROJECT |
PUBSUB_TOPIC | Topic name | nest-sdm-events |
PUBSUB_SUBSCRIPTION | Subscription name | nest-sdm-events-sub |
Event Logs
Raw events are logged to data/nest-events/events-YYYY-MM-DD.jsonl.
Alert Dedup
Same event type won't re-alert within 60 seconds to prevent alert fatigue.
Important Notes
- Token expiry: If the GCP app is in "testing" mode, refresh tokens expire in 7 days. Publish the app to avoid re-auth.
- Temperature: API uses Celsius internally. The CLI handles F↔C conversion.
- Setpoint constraints: HEATCOOL range must have at least 1.5°C (2.7°F) gap between heat and cool setpoints.
- Camera streams: WebRTC only (no RTSP). Requires SDP offer/answer exchange.
- Rate limits: 10 queries/min per device, 10 commands/min per device.
- Events: Use
nest-events listenfor real-time alerts. Requires Pub/Sub setup (see above).