Skip to main content

Overview

The Nest thermostat initiates all connections. The server never dials out to the device. Instead, the device maintains a persistent long-poll connection and relies on the server to push data on it.

Device Lifecycle (Full Flow)


WoWLAN — How the Device Sleeps

The thermostat is battery-powered and aggressively manages CPU sleep. After the server sends chunked response headers, the device:
  1. Hands the open TCP socket to its WiFi hardware chipset
  2. Puts the main CPU to sleep
  3. Relies on the WiFi hardware to monitor the socket for incoming data (WoWLAN — WiFi Wake-on-LAN)
  4. When data arrives, the WiFi hardware wakes the CPU in ~100–500ms
From the server’s perspective: the connection appears idle but is very much alive. You can push data at any time and the device will wake.
TCP keep-alive must be disabled server-side. The device cannot respond to TCP keep-alive probes while its CPU is sleeping. Server-side SO_KEEPALIVE will cause the OS to close the connection after a few missed probes. The WiFi hardware keeps the connection alive independently.

Subscribe Cycle Timing

The server drives the reconnect cycle by closing the connection. The device’s X-nl-suspend-time-max timer (default 300s) is a safety net, not the primary trigger.

Two-Port Architecture

The self-hosted server runs two independent HTTP services:
The device talks exclusively to port 8000. You talk exclusively to port 8082. The server coordinates state between both ports internally.

Overlapping Subscriptions

When a device wakes early (user turns the dial), it sends a new subscribe request before the previous connection has closed. The server briefly sees two active subscriptions for the same device. The correct handling:
  1. Track each subscription with a server-generated ID (not the device’s session field)
  2. Push data to all active subscriptions when a change occurs
  3. Remove a subscription only when its specific connection closes
The device’s session field is reused across all subscribe requests during normal operation — it is not a unique connection identifier.