The Thermostat device type may be implemented using several Home API traits, but
the primary trait is Thermostat
. Following are the required and optional
traits for Thermostat devices.
Home APIs Device Type | Traits | Swift Sample App | Use Case |
---|---|---|---|
Thermostat
A device that is capable of having either built-in or separate sensors for temperature, humidity or occupancy, and allows the desired temperature to be set. A Thermostat is capable of sending heating and/or cooling requirement notifications to a heating/cooling unit (for example, an indoor air handler) or is capable of including a mechanism to control a heating or cooling unit directly. |
Required Traits matter IdentifyTrait matter ThermostatTrait |
Thermostat |
Automation API support
The following Thermostat traits and elements are supported in the Automation API.
Trait | Trait type | Element type | Element |
---|---|---|---|
ThermostatTrait | matter | Attribute | activePresetHandle |
ThermostatTrait | matter | Attribute | localTemperature |
ThermostatTrait | matter | Attribute | occupancy |
ThermostatTrait | matter | Attribute | occupiedCoolingSetpoint |
ThermostatTrait | matter | Attribute | occupiedHeatingSetpoint |
ThermostatTrait | matter | Attribute | outdoorTemperature |
ThermostatTrait | matter | Attribute | temperatureSetpointHoldDuration |
ThermostatTrait | matter | Attribute | unoccupiedCoolingSetpoint |
ThermostatTrait | matter | Attribute | unoccupiedHeatingSetpoint |
Get the ambient temperature
To get the thermostat's ambient temperature using the
ThermostatTrait
,
read the
localTemperature
attribute.
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(ThermostatDeviceType.self), let trait = thermostat.matterTraits.thermostatTrait else { return } let temperature = trait.attributes.localTemperature
Automation API
let starterNode = starter( device1, ThermostatDeviceType.self, Matter.ThermostatTrait.self ) let stateReaderNode = stateReader(device2, OnOffLightDeviceType.self, Matter.OnOffTrait.self) let _ = automation( name: "Turn on a device", description: "Turn on a device when the temperature is too high" ) { starterNode stateReaderNode condition { // When the temperature is greater than 35 degrees C and the light is off. // `localTemperature` is in one hundredth of a degree Celsius. starterNode.localTemperature.greaterThan(3500) .and(stateReaderNode.onOff.equals(false)) } // Turn on device 2 action(device2, OnOffLightDeviceType.self) { Matter.OnOffTrait.on() } }
Get the ambient temperature using TemperatureMeasurement
To get the thermostat's ambient temperature using the
TemperatureMeasurement
trait, read the
measuredValue
attribute.
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(TemperatureSensorDeviceType.self), let trait = thermostat.matterTraits.temperatureMeasurementTrait else { return } let temperature = trait?.attributes.measuredValue
Automation API
let starterNode = starter( device1, TemperatureSensorDeviceType.self, Matter.TemperatureMeasurementTrait.self ) let stateReaderNode = stateReader( device2, OnOffLightDeviceType.self, Matter.OnOffTrait.self ) let _ = automation( name: "Turn on a device", description: "Turn on a device when the temperature is too high" ) { starterNode stateReaderNode condition { // When the temperature is greater than 35 degrees C and the light is off. // `measuredValue` is in one hundredth of a degree Celsius. starterNode.measuredValue.greaterThan(3500) .and(stateReaderNode.onOff.equals(false)) } // Turn on device 2 action(device2, OnOffLightDeviceType.self) { Matter.OnOffTrait.on() } }
Get the ambient humidity
To get the thermostat's ambient humidity using the
RelativeHumidityMeasurementTrait
,
read the
measuredValue
attribute.
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(HumiditySensorDeviceType.self), let trait = thermostat.matterTraits.relativeHumidityMeasurementTrait else { return } let humidity = trait.attributes.measuredValue
Automation API
let starterNode = starter( device1, HumiditySensorDeviceType.self, Matter.RelativeHumidityMeasurementTrait.self ) let stateReaderNode = stateReader(device2, OnOffLightDeviceType.self, Matter.OnOffTrait.self) let _ = automation( name: "Turn on a device", description: "Turn on a device when the temperature is too high" ) { starterNode stateReaderNode condition { // When the humidity is greater than 50% and the light is off. starterNode.measuredValue.greaterThan(50) .and(stateReaderNode.onOff.equals(false)) } // Turn on device 2 action(device2, OnOffLightDeviceType.self) { Matter.OnOffTrait.on() } }
Select the displayed temperature scale
To change the temperature unit of measurement that's used for the thermostat
display, set the
ThermostatUserInterfaceConfigurationTrait
's
temperatureDisplayMode
attribute to either
TemperatureDisplayModeEnum.Celsius
or
TemperatureDisplayModeEnum.Fahrenheit
.
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(ThermostatDeviceType.self), let trait = thermostat.matterTraits.thermostatUserInterfaceConfigurationTrait else { return } let updatedTrait = try await trait.update { $0.setTemperatureDisplayMode(.celsius) // or .fahrenheit }
Automation API
let starterNode = starter(structure, Google.VoiceStarterTrait.OkGoogleEvent.self) { Google.VoiceStarterTrait.OkGoogleEvent .query("Show the temperature in Fahrenheit") } let stateReaderNode = stateReader( device1, ThermostatDeviceType.self, Matter.ThermostatUserInterfaceConfigurationTrait.self ) let _ = automation( name: "Change temperature unit", description: "Change temperature unit to fahrenheit" ) { starterNode stateReaderNode condition { stateReaderNode.temperatureDisplayMode.notEquals(.fahrenheit) } action(device1, ThermostatDeviceType.self) { update(Matter.ThermostatUserInterfaceConfigurationTrait.self) { $0.setTemperatureDisplayMode(.fahrenheit) } } }
Change the operating mode
The Thermostat can be limited to certain operating modes, defined by
ThermostatTrait.SystemModeEnum
,
by setting the
ThermostatTrait.Attributes.systemMode
attribute, whose values are defined by
ThermostatTrait.Attributes.SystemModeEnum
.
Set system mode to auto
When the thermostat is set to
SystemModeEnum.Auto
,
additional information about the running mode of the thermostat can be read from
ThermostatTrait.Attributes.thermostatRunningMode
which is populated with values from
ThermostatRunningModeEnum
.
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(ThermostatDeviceType.self), let trait = thermostat.matterTraits.thermostatTrait else { return } let updatedTrait = try await trait.update { $0.setSystemMode(.auto) // or .cool, .heat, .dry, etc. }
Automation API
let starterNode = starter( device1, HumiditySensorDeviceType.self, Matter.RelativeHumidityMeasurementTrait.self ) let stateReaderNode = stateReader( device1, ThermostatDeviceType.self, Matter.ThermostatTrait.self ) let _ = automation( name: "Change mode to dry", description: "Change mode to dry when it's too humid" ) { starterNode stateReaderNode condition { // When the humidity is greater than 80%. starterNode.measuredValue.greaterThan(80) .and(stateReaderNode.systemMode.notEquals(.dry)) } action(device1, ThermostatDeviceType.self) { update(Matter.ThermostatTrait.self) { $0.setSystemMode(.dry) } } }
Get the running mode
The
SimplifiedThermostatTrait
is designed to streamline the process of setting the operating mode in
automations. To change the thermostat's operating mode using the
SimplifiedThermostatTrait
,
use the
supportsSetSystemModeCommand
,
whose values are defined by
SimplifiedThermostatTrait.SystemModeEnum
.
This trait is only available for use with the Automation API.
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(ThermostatDeviceType.self), let trait = thermostat.matterTraits.thermostatTrait else { return } let thermostatRunningMode = trait.attributes.thermostatRunningMode
Automation API
let scheduledTime = TimeOfDay(hours: 10, minutes: 0, seconds: 0) let timeStarter = starter(structure, Google.TimeTrait.ScheduledEvent.self) { Google.TimeTrait.ScheduledEvent.clockTime(scheduledTime) } let stateReaderNode = stateReader( device1, ThermostatDeviceType.self, Matter.ThermostatTrait.self ) let _ = automation( name: "Announce cooling", description: "Announce cooling at 10am every day when in auto mode" ) { timeStarter stateReaderNode condition { stateReaderNode.systemMode.equals(.auto) .and(stateReaderNode.thermostatRunningMode.equals(.cool)) } action(structure) { Google.AssistantBroadcastTrait.broadcast(msg: "Cooling is on.") } }
Get system mode with SimplifiedThermostat in an Automation
To determine the system modes that a thermostat can operate in, read the
ThermostatTrait.Attributes.controlSequenceOfOperation
,
whose values are determined by the
ThermostatTrait.ControlSequenceOfOperationEnum
.
Automation API
let starterNode = starter( structure, Google.AreaPresenceStateTrait.self ) let _ = automation( name: "Eco mode", description: "Change mode to eco when no one is around" ) { starterNode condition { starterNode.presenceState.equals(.presenceStateVacant) } action(device1, ThermostatDeviceType.self) { Google.SimplifiedThermostatTrait.setSystemMode(systemMode: .eco) } }
Get the system modes the thermostat can operate in
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(ThermostatDeviceType.self), let trait = thermostat.matterTraits.thermostatTrait else { return } let controlSequenceOfOperation = trait.attributes.controlSequenceOfOperation
Automation API
let starterNode = starter(structure, Google.VoiceStarterTrait.OkGoogleEvent.self) { Google.VoiceStarterTrait.OkGoogleEvent.query("Switch to cool mode") } let stateReaderNode = stateReader( device1, ThermostatDeviceType.self, Matter.ThermostatTrait.self ) let _ = automation( name: "Cool mode", description: "Change mode to cool at user's request" ) { starterNode condition { stateReaderNode.controlSequenceOfOperation.notEquals(.heatingOnly) .and(stateReaderNode.controlSequenceOfOperation.notEquals(.heatingWithReheat)) } action(device1, ThermostatDeviceType.self) { Google.SimplifiedThermostatTrait.setSystemMode(systemMode: .cool) } }
Change the programming operation mode
The programming operation mode of the thermostat may be changed using the
ThermostatTrait
's
thermostatProgrammingOperationMode
,
whose values are defined by the
ProgrammingOperationModeBitmap
.
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(ThermostatDeviceType.self), let trait = thermostat.matterTraits.thermostatTrait else { return } let updatedTrait = try await trait.update { $0.setThermostatProgrammingOperationMode(.economy) }
Automation API
let starterNode = starter(structure, Google.VoiceStarterTrait.OkGoogleEvent.self) { Google.VoiceStarterTrait.OkGoogleEvent .query("Activate thermostat schedule") } let _ = automation( name: "Activate thermostat schedule", description: "Activate thermostat schedule at user's request" ) { starterNode action(device1, ThermostatDeviceType.self) { update { // Note that this sets the .autoRecovery and .economy bits to 0. // Future API updates will make it possible to preserve other bits. $0.setThermostatProgrammingOperationMode(.scheduleActive) } } }
Change the temperature setpoint
To change the temperature setpoint using the
ThermostatTrait
,
call the
ThermostatTrait.setpointRaiseLower(mode:amount:)
.
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(ThermostatDeviceType.self), let trait = thermostat.matterTraits.thermostatTrait else { return } // Lower the setpoint by 10 steps (i.e. 1 degree celsius) let response = try await trait.setpointRaiseLower(mode: .cool, amount: -10)
Automation API
let scheduledTime = TimeOfDay(hours: 22, minutes: 0, seconds: 0) let timeStarter = starter(structure, Google.TimeTrait.ScheduledEvent.self) { Google.TimeTrait.ScheduledEvent.clockTime(scheduledTime) } let stateReaderNode = stateReader( device1, ThermostatDeviceType.self, Matter.ThermostatTrait.self ) let _ = automation( name: "Raise cooling setpoint", description: "Raise cooling setpoint by 4 degrees at 10pm every day" ) { timeStarter stateReaderNode condition { // Less than 18 degrees Celsius. // The unit is 100th of a degree Celsius. stateReaderNode.occupiedCoolingSetpoint.lessThan(1800) } action(device1, ThermostatDeviceType.self) { // Raise the cooling setpoint by 4 degrees Celsius. // The amount is in 10th of a degree Celsius. Matter.ThermostatTrait.setpointRaiseLower(mode: .cool, amount: 40) } }
Prioritize a temperature setpoint
You can make a temperature setpoint take precedence over a preprogrammed
schedule by setting the
ThermostatTrait
's temperatureSetpointHold
attribute to
TemperatureSetpointHoldEnum.SetpointHoldOn
,
or have the schedule take precedence by setting it to
TemperatureSetpointHoldEnum.SetpointHoldOff
.
Set
ThermostatTrait.Attributes.temperatureSetpointHoldDuration
to control how many minutes a setpoint hold is active.
Device API
let device: HomeDevice = ... guard let thermostat = await device.types.get(ThermostatDeviceType.self), let trait = thermostat.matterTraits.thermostatTrait else { return } let updatedTrait = try await trait.update { $0.setTemperatureSetpointHold(.setpointHoldOn) // Hold for 120 minutes $0.setTemperatureSetpointHoldDuration(120) }
Automation API
let starterNode = starter(structure,Google.VoiceStarterTrait.OkGoogleEvent.self) { Google.VoiceStarterTrait.OkGoogleEvent .query("Prioritize thermostat setpoint") } let stateReaderNode = stateReader( device1, ThermostatDeviceType.self, Matter.ThermostatTrait.self ) let _ = automation( name: "Prioritize setpoint", description: "Prioritize thermostat setpoint at user's request" ) { starterNode action(device1, ThermostatDeviceType.self) { update { $0.setTemperatureSetpointHold(.setpointHoldOn) } } }