Skip to main content

Overview

The schedule bucket holds the weekly temperature schedule. Unlike most buckets, the device subscribes to this bucket explicitly (it appears in the device’s subscribe request body), so you don’t need to inject it. Object key: schedule.{serial}
Direction: Bidirectional (with sync guards)
Revision type: base_object_revision (unconditional)

Schedule JSON Format

The schedule is a single JSON object with the full weekly schedule. Version is always 2.
{
  "ver": 2,
  "name": "My Schedule",
  "schedule_mode": "HEAT",
  "days": {
    "0": {
      "0": {"type": "HEAT", "time": 21600, "entry_type": "setpoint", "temp": 20.0},
      "1": {"type": "HEAT", "time": 28800, "entry_type": "setpoint", "temp": 21.5},
      "2": {"type": "HEAT", "time": 64800, "entry_type": "setpoint", "temp": 19.0}
    },
    "1": {
      "0": {"type": "HEAT", "time": 21600, "entry_type": "setpoint", "temp": 20.0}
    },
    "2": {},
    "3": {},
    "4": {},
    "5": {},
    "6": {}
  }
}

Top-Level Fields

FieldTypeRequiredDescription
verintegerYesAlways 2
namestringYesSchedule name (e.g., "Default")
schedule_modestringYes"HEAT", "COOL", or "RANGE"
daysobjectYesDay containers keyed "0" through "6"

Day Indexing

Days are integer strings starting from Monday = 0:
KeyDay
"0"Monday
"1"Tuesday
"2"Wednesday
"3"Thursday
"4"Friday
"5"Saturday
"6"Sunday
Monday = 0, not Sunday. This differs from many programming language conventions (JavaScript Date.getDay() uses Sunday = 0). Double-check your day mapping when generating schedules.
Within each day, setpoints are keyed by sequential integer strings: "0", "1", "2", etc.

Setpoint Fields

FieldTypeModesDescription
typestringAll"HEAT", "COOL", or "RANGE" — must match schedule_mode
timeintegerAllSeconds from midnight (0–86399)
entry_typestringAll"setpoint" (user-configured) or "continuation" (auto-generated filler)
tempfloatHEAT, COOLTarget temperature in °C
temp-minfloatRANGELower bound in °C
temp-maxfloatRANGEUpper bound in °C
21600 = 6:00 AM (6 × 3600)
28800 = 8:00 AM (8 × 3600)
64800 = 6:00 PM (18 × 3600)
All temperatures are Celsius floats. The device converts for display based on temperature_scale.

Schedule Modes

ModeDescriptionTemperature fields
HEATHeating onlytemp
COOLCooling onlytemp
RANGEDual heat and cooltemp-min, temp-max
The active schedule mode is stored in the shared bucket as schedule_mode — not inside the schedule itself. To switch modes, push schedule_mode to the shared bucket. The schedule_mode inside the schedule JSON and the schedule_mode in the shared bucket must match. If they differ, the device ignores the schedule.

Pushing a Schedule

Always push the complete schedule — all 7 days, all setpoints. There is no mechanism to add or remove individual setpoints. The device replaces the entire schedule on each push.
{
  "objects": [
    {
      "object_revision": 100,
      "object_timestamp": 1707148800000,
      "object_key": "schedule.09AA01AB12345678",
      "value": { ...complete schedule JSON... }
    }
  ]
}

Reading Schedules from the Device

The device sends schedule changes via PUT requests:
{
  "session": "sess_xyz789",
  "schedule.09AA01AB12345678": {
    "object_key": "schedule.09AA01AB12345678",
    "base_object_revision": 99,
    "ver": 2,
    "name": "Default",
    "schedule_mode": "HEAT",
    "days": { ... }
  }
}
Note: Schedule data is inline in the PUT (not nested in value). Store the complete schedule value. Return it on subscribe when the server’s version is newer.

Sync Guards

Three mechanisms protect schedule integrity:
GuardDescription
15-second debounceMultiple schedule pushes within 15s — only the last one takes effect. Do not retry within this window.
Timestamp rejectionIf your push has an older timestamp than the device’s current schedule, the device silently discards it. Always use a current object_timestamp.
Pending local changeIf the user is editing the schedule on-device, incoming server pushes are silently discarded. The device’s local version takes priority.

Learning Mode Warning

When learning mode is enabled, the device’s auto-schedule system may modify a schedule you pushed based on subsequent dial turns. To prevent this, disable learning before pushing:
{
  "object_key": "device.09AA01AB12345678",
  "value": { "learning_mode": false }
}
Then push your schedule. Re-enable learning afterward if desired.