Cookbook: Real-time IoT Thermostat ​
In a standard stack, building an IoT backend is a nightmare of infrastructure. You have to set up cron jobs or message brokers (like Kafka/RabbitMQ) just to poll sensor data, write complex state machines to ensure the heater doesn't fight the AC, and manage race conditions when a user tries to override the temperature from their phone.
In Carotene, time-based execution and state management are native primitives. You don't need external polling servers; you just use a loop block and let the Vapor Sandbox guarantee the state transitions.
Here is a complete, real-time smart thermostat backend.
1. The Architecture Blueprint ​
We start by defining the physical state of the device. Because an HVAC system physically cannot be heating and cooling at the exact same time, we define a strict flow state machine to prevent catastrophic hardware commands.
domain HomeAutomation {
// 1. The Hardware Guardrail
// Mathematically prevents the AC and Heater from running simultaneously.
flow HVACMode {
on Change {
Idle -> Heating
Idle -> Cooling
Heating -> Idle
Cooling -> Idle
}
}
// 2. The Device State
model Thermostat {
id: UUID
currentTemp: Float
targetTemp: Float
mode: HVACMode
lastPing: Date
}
store Thermostat {
model: Thermostat
}
}2. The Continuous Execution Loop ​
Instead of setting up external cron jobs, Carotene allows you to define background processes natively using the loopkeyword.
This loop runs every minute, reads external weather data to optimize energy usage, and adjusts the physical HVAC mode.
backend IoTGateway {
// We declare an external integration to fetch local weather
integration WeatherAPI {
GetOutsideTemp(zipcode: String) -> Float
}
// ==========================================
// AUTONOMIC LOOP (Runs every 1 minute)
// ==========================================
loop OptimizeClimate {
config {
interval: "1m"
}
reads store.Thermostat
updates store.Thermostat
calls integration.WeatherAPI
triggers store.Thermostat.mode.Change
implements {
device = store.Thermostat.find("device_1") // Assuming a single-home setup for simplicity
outsideTemp = integration.WeatherAPI.GetOutsideTemp("90210")
// The Generative Operator handles the complex thermodynamic prediction logic
// rather than us writing nested IF statements for insulation, delta-T, etc.
idealMode = @("Compare the device's currentTemp to the targetTemp, factoring in the outsideTemp. Return 'Heating', 'Cooling', or 'Idle' to reach the target most efficiently.")
// Only apply the change if a transition is needed
if (device.mode != idealMode) {
device.mode = idealMode
}
device.lastPing = Time.now()
}
}
}3. The User Override (Mobile App API) ​
We also need a standard API endpoint so the user can open their phone and change the target temperature manually.
backend MobileAPI {
// ==========================================
// MANUAL OVERRIDE
// ==========================================
function SetTargetTemperature(deviceId: store.Thermostat.id, newTarget: store.Thermostat.targetTemp) {
requires session.isAuthenticated
updates store.Thermostat
implements {
device = store.Thermostat.find(deviceId)
// Hard constraint: Don't freeze or boil the house
if (newTarget < 50.0 || newTarget > 90.0) {
throws "Target temperature out of safe bounds"
}
device.targetTemp = newTarget
return true
}
}
}4. The Proof (Testing Time and State) ​
To test this, we need to prove two things: that the AI correctly predicts the needed HVAC mode based on outside weather, and that our strict flow prevents illegal state changes.
// Test 1: AI Thermodynamic Logic
test "Turns on Heating when house is cold and outside is freezing" {
config { sandbox: EmbeddedWASM }
// 1. Mock the device currently sitting idle at 60 degrees
given mock store.Thermostat {
id: "device_1",
currentTemp: 60.0,
targetTemp: 72.0,
mode: Idle
}
// 2. Mock the Weather API returning a freezing temperature
mock integration.WeatherAPI.GetOutsideTemp -> 30.0
// 3. Manually trigger one iteration of the loop
trigger loop OptimizeClimate
// 4. Assert the AI correctly chose to trigger the Heater
asserts store.Thermostat.find("device_1").mode == Heating
}
// Test 2: Hardware Safety Guardrails
test "Rejects unsafe manual temperature overrides" {
given mock session { isAuthenticated: true }
given mock store.Thermostat { id: "device_1", targetTemp: 72.0 }
// Assert the manual override fails with our exact error message
asserts SetTargetTemperature("device_1", 100.0) throws "Target temperature out of safe bounds"
}5. Compile and Deploy ​
When you run carrot build:
- The compiler maps the
loopto a highly optimized background worker in Go or TypeScript. - It generates the REST/RPC endpoint for the mobile app.
- It uses the LLM to write the predictive logic comparing
currentTemp,targetTemp, andoutsideTemp. - It runs the Sandbox tests to mathematically guarantee the house will actually start heating when it gets cold, and that a user cannot set their app to 100 degrees.