Skip to content

Build an HVAC scheduling application

This walkthrough documents the hvac_schedules reference application. It lets a customer edit zone configuration in the cloud and projects the current records into a versioned dataset that a Linux controller can use offline.

Implementation boundary

The proof uses the real customer record API, dataset generator, Prelude Agent Product Runtime, persistent dataset store, and applied-generation reporting. The proof harness substitutes a simulator at the OEM controller boundary. It reads the active dataset but does not run a building control or safety loop.

This guide uses the shared Product Applications status vocabulary:

  • Platform-provided and proven: customer-scoped records, immutable dataset generations, agent download/activation, applied reporting, and persistence across the harness's agent restart.
  • Worked reference / test-mode: the editable HVAC starter and its minimal zone / setpoint_c projection.
  • Simulated in the proof harness: the OEM controller consumer reads the agent's active hvac_entitlements dataset.
  • Customer-supplied: calendar semantics, local control and safety loops, setpoint validation, physical HVAC integration, and fallback policy.

You finish with:

  • an HVAC Controller Device Class bound as controller
  • customer-managed schedule records
  • an hvac_entitlements offline dataset
  • a published application instance for one building
  • desired and applied generation evidence for a staging controller

The reference proves non-financial offline dataset sync. It does not implement a complete BMS, calendar engine, occupancy strategy, safety loop, or local control algorithm.

Before you start

You need:

  • Product Applications beta access on Standard+
  • a staging customer and Customer Portal
  • an HVAC Controller Device Class
  • a representative Linux controller or safe simulator
  • a controller-side consumer that can validate and atomically activate a versioned JSON dataset

Use hvac-sim for Device Class telemetry. Prelude Agent Product Runtime consumes the HVAC entitlements dataset; the controller OEM handler reads the active records over the local Unix socket.

Part 1: Define the controller product

Create or select HVAC Controller under Engineering > Device classes. Define the product values and controls independently from the schedule records:

  • current zone temperature
  • operating mode and fault state
  • customer-safe bounded override where supported
  • reported schedule generation
  • connectivity and data freshness

The customer schedule says what should be true. The controller remains responsible for local limits, frost protection, compressor protection, sensor validation, and safe fallback.

Current Device Class Software tab used to attach an HVAC simulator or release a controller-side application
Use the HVAC simulator to prove class telemetry and layout, then qualify the controller-side dataset consumer separately.

Part 2: Create and bind the application

  1. Open Developer > Product Applications.
  2. Create HVAC Schedules with key hvac_schedules.
  3. Open Build > Hardware.
  4. Connect the HVAC Controller class with role alias controller.
  5. Confirm the staging controller is eligible for that role.
HVAC Schedules Build tab showing the hvac_entitlements offline dataset projected from Schedule zone and setpoint_c fields
The reproducible proof creates this dataset, applies a base and two deltas, then restarts the agent and reopens the same active generation.
Current Customer Portal location page showing products scoped to one customer location
Verify schedule state in the customer's building context, while keeping dataset generation and controller diagnostics in the engineering boundary.

Part 3: Define schedule records

In Build > Models, add:

FieldValue
Model keyschedule
LabelSchedule
LifecycleConfiguration
Customer create/updateEnabled for authorised operators

The normative minimum fields are:

Field keyTypeMeaning
zoneStringZone identifier understood by the controller
setpoint_cIntegerTemperature target in degrees Celsius

A production schedule normally also needs:

  • a stable schedule or rule ID
  • days of week and local start/end times
  • an IANA time-zone name
  • occupied and unoccupied setpoints
  • validity dates and exception dates
  • priority and temporary override expiry
  • a controller, site, or group reference

Keep the first proof deliberately small. Adding calendar semantics without explicit time-zone and daylight-saving behavior creates an unsafe ambiguity.

Part 4: Define the offline dataset

Add an offline dataset:

SettingValue
Keyhvac_entitlements
LabelHVAC entitlements
Projectionschedule.zone, schedule.setpoint_c
FormatJSON

The name comes from the normative reference. For a customer-facing production design, use wording such as HVAC schedule dataset in the UI while retaining a stable technical key once devices depend on it.

Each generated payload is immutable and identified as a generation. The cloud tracks desired and reported applied generation separately.

Prelude Agent Product Runtime downloads each generation advertised on instance discovery, verifies it, stages it, atomically activates it, keeps last-known-good, and reports the applied generation. After a reboot the same identity volume must reopen the last applied generation without a duplicate apply. Confirm the Customer Portal sync chip shows current.

HVAC Schedules Build tab showing the hvac_entitlements offline dataset projected from Schedule zone and setpoint_c fields
The running draft projects Zone and Setpoint into the immutable hvac_entitlements dataset consumed by the local agent simulator.

Part 5: Add customer pages and permissions

In Access:

  1. add a list page for schedules
  2. add create and edit forms for the approved fields
  3. allow viewers to read but not change schedules
  4. allow only authorised operators to create or update
  5. keep dataset generation and device sync controls in the OEM or administrator surface

Show the customer:

  • zone and target
  • when the configuration was changed
  • who changed it
  • desired generation
  • applied generation and last report
  • an explicit pending, current, failed, or stale sync state

Do not present a saved cloud record as proof that the building controller applied it.

Part 6: Publish and prove the first generation

  1. Validate and publish version 1.
  2. Attach the version to the staging Customer Portal.
  3. Provision the Building A customer instance.
  4. Create a record with zone = lobby and setpoint_c = 21.
  5. In Release > Sandbox, preview hvac_entitlements.
  6. Generate the base dataset for the staging controller.
  7. Inspect the payload and record count.
  8. Have the test consumer validate and activate the generation.
  9. Report that exact generation as applied.
  10. Confirm the device sync state becomes current.

The normative acceptance proof expects one record in the first base generation and a current applied state after the report.

Part 7: Prove change and failure behavior

Update the lobby setpoint, then generate the next dataset.

Confirm:

  • a new immutable generation is created
  • the previous generation remains available as evidence
  • the controller reports pending until it applies the new generation
  • successful activation changes reported generation
  • invalid content leaves the last-known-good schedule active
  • a failed report does not claim current state
  • duplicate generation fetch or applied reports are safe
  • a second customer cannot fetch Building A's dataset

Then test:

  • controller offline during a schedule change
  • power loss while staging
  • restart after successful activation
  • unsupported schema version
  • out-of-range setpoint
  • missing zone
  • rollback to the last-known-good generation

The local agent and simulator provide real desired/applied generation reports and last-known-good restart evidence. They do not implement a BMS safety loop or prove that a compressor, valve, or fan followed the schedule. Capture that physical evidence only during controller qualification.

Part 8: Extend toward a production HVAC workflow

Add complexity one contract at a time:

  1. model time zone and recurrence explicitly
  2. add temporary overrides with expiry
  3. publish telemetry and explicit fault state through the Device Class
  4. add rules for customer-impacting conditions
  5. add operations for approved overrides
  6. add multi-controller targeting only after partial rollout and rollback are tested
  7. preserve a local fallback schedule for cloud and network failure

Do not put the safety loop or second-by-second control process in Product Applications. Keep it local to the qualified controller.

Production handover gate

  • [ ] Every schedule has explicit time-zone and daylight-saving behavior.
  • [ ] Setpoints and overrides are bounded locally.
  • [ ] The controller activates datasets atomically.
  • [ ] Last-known-good state survives restart and failed updates.
  • [ ] Desired and applied generations are shown separately.
  • [ ] Offline, stale, pending, current, and failed states differ.
  • [ ] Customer viewers cannot edit schedules.
  • [ ] Another customer cannot see records, datasets, devices, or activity.
  • [ ] Rollback and schema compatibility are tested.
  • [ ] Local safety and fallback do not depend on cloud availability.