אפשר להטמיע את סוג המכשיר Thermostat (תרמוסטט) באמצעות כמה מאפיינים של Home API, אבל המאפיין העיקרי הוא Thermostat
. בהמשך מפורטים המאפיינים הנדרשים והאופציונליים של מכשירי תרמוסטט.
Home APIs Device Type | תכונות | אפליקציה לדוגמה ב-Kotlin | תרחיש לדוגמה |
---|---|---|---|
תרמוסטט
מכשיר שיש בו חיישנים מובנים או נפרדים לטמפרטורה, ללחות או לנוכחות, ואפשר להגדיר בו את הטמפרטורה הרצויה. תרמוסטט יכול לשלוח התראות על הצורך בחימום או בקירור ליחידת חימום או קירור (לדוגמה, יחידה לטיפול באוויר בתוך הבית) או לכלול מנגנון לשליטה ישירה ביחידת חימום או קירור. |
מאפיינים נדרשים matter זיהוי matter תרמוסטט |
תרמוסטט |
תמיכה ב-Automation API
התכונות והרכיבים הבאים של התרמוסטט נתמכים ב-Automation API.
תכונה | סוג המאפיין | סוג הרכיב | רכיב |
---|---|---|---|
Thermostat | matter | פקודה | SetpointRaiseLower |
Thermostat | matter | מאפיין | activePresetHandle |
Thermostat | matter | מאפיין | localTemperature |
Thermostat | matter | מאפיין | תפוסה |
Thermostat | matter | מאפיין | occupiedCoolingSetpoint |
Thermostat | matter | מאפיין | occupiedHeatingSetpoint |
Thermostat | matter | מאפיין | outdoorTemperature |
Thermostat | matter | מאפיין | setpointChangeSource |
Thermostat | matter | מאפיין | systemMode |
Thermostat | matter | מאפיין | temperatureSetpointHold |
Thermostat | matter | מאפיין | temperatureSetpointHoldDuration |
Thermostat | matter | מאפיין | thermostatRunningMode |
Thermostat | matter | מאפיין | thermostatRunningState |
Thermostat | matter | מאפיין | unoccupiedCoolingSetpoint |
Thermostat | matter | מאפיין | unoccupiedHeatingSetpoint |
ExtendedThermostat | מאפיין | activePresetHandle | |
ExtendedThermostat | מאפיין | activeRemoteTemperatureSensorIds | |
ExtendedThermostat | מאפיין | averageLocalTemperature | |
ExtendedThermostat | מאפיין | extendedRunningMode | |
ExtendedThermostat | מאפיין | extendedSystemMode |
קבלת טמפרטורת הסביבה
קבלת טמפרטורת החדר באמצעות תרמוסטט
כדי לקבל את טמפרטורת הסביבה של התרמוסטט באמצעות מאפיין המאפיינים Thermostat
, קוראים את המאפיין localTemperature
.
Device API
// Get the ambient temperature val thermostat = home.devices().list().first { device -> device.has(Thermostat) } val thermostatTraitFlow: Flow<Thermostat?> = thermostat .type(ThermostatDevice) .mapNotNull { it.standardTraits.thermostat } .distinctUntilChanged() val localTempFlow = thermostatTraitFlow.mapNotNull { it?.localTemperature }
Automation API
val automation = automation { sequential { val starterNode = starter<_>(thermostat, ThermostatDevice, Thermostat) // If the temperature is higher than 35C... // `localTemperature` is in one hundredth of a degree Celsius. condition { expression = starterNode.localTemperature greaterThan 3500 } // ...and the automation hasn't been run for at least an hour... suppressFor(Duration.ofHours(1)) // ...broadcast a message action(speaker, SpeakerDevice) { command(AssistantBroadcast.broadcast("It's very hot outside.")) } } }
קבלת טמפרטורת החדר באמצעות TemperatureMeasurement
כדי לקבל את טמפרטורת הסביבה של התרמוסטט באמצעות מאפיין המאפיינים TemperatureMeasurement
, קוראים את המאפיין measuredValue
.
Device API
val temperatureTraitFlow: Flow<TemperatureMeasurement?> = thermostat .type(TemperatureSensorDevice) .map { it.standardTraits.temperatureMeasurement } .distinctUntilChanged() val localTemp: Short? = temperatureTraitFlow.first()?.measuredValue
Automation API
val automation = automation { sequential { val temperature = starter<_>(thermostat, ThermostatDevice, TemperatureMeasurement) val stateReaderNode = stateReader<_>(light, DimmableLightDevice, OnOff) condition() { val expr1 = temperature.measuredValue greaterThanOrEquals 3500 val expr2 = stateReaderNode.onOff equals true expression = expr1 and expr2 } action(light, DimmableLightDevice) { command(OnOff.on()) } } }
קבלת הטמפרטורה הממוצעת באמצעות ExtendedThermostat
כדי לקבל את הטמפרטורה הממוצעת מכמה חיישנים, קוראים את המאפיין averageLocalTemperature
של מאפיין ExtendedThermostat
.
Device API
// Get the average temperature val thermostat = home.devices().list().first { device -> device.has(TemperatureSensorDevice) } val temperatureTraitFlow: Flow<TemperatureMeasurement?> = thermostat .type(TemperatureSensorDevice) .map { it.standardTraits.temperatureMeasurement } .distinctUntilChanged() val localTemp: Short? = temperatureTraitFlow.first()?.measuredValue
Automation API
val automation = automation { sequential { val temperature = starter<_>(thermostat, ThermostatDevice, ExtendedThermostat) val stateReaderNode = stateReader<_>(light, DimmableLightDevice, OnOff) // if the average temperature is >= 35C condition() { val expr1 = temperature.averageLocalTemperature greaterThanOrEquals 3500 val expr2 = stateReaderNode.onOff equals true expression = expr1 and expr2 } // Turn on the light action(light, DimmableLightDevice) { command(OnOff.on()) } } }
קבלת הלחות בסביבה
כדי לקבל את הלחות הסביבתית של התרמוסטט באמצעות מאפיין RelativeHumidityMeasurement
, קוראים את מאפיין measuredValue
.
Device API
// Get the ambient humidity val humidityTraitFlow: Flow<RelativeHumidityMeasurement?> = humiditySensingThermostat .type(HumiditySensorDevice) .map { it.standardTraits.relativeHumidityMeasurement } .distinctUntilChanged() val localHumidity: UShort? = humidityTraitFlow.first()?.measuredValue
Automation API
val automation = automation { sequential { val humidity = starter<_>(thermostat, HumiditySensorDevice, RelativeHumidityMeasurement) val stateReaderNode = stateReader<_>(light, DimmableLightDevice, OnOff) // if the ambient humidity is >= 80% condition() { val expr1 = (humidity.measuredValue greaterThanOrEquals 80u) val expr2 = (stateReaderNode.onOff equals true) expression = expr1 and expr2 } // Turn on the light action(light, DimmableLightDevice) { command(OnOff.on()) } } }
בחירת סולם הטמפרטורה שיוצג
כדי לשנות את יחידת המידה של הטמפרטורה שמוצגת בתרמוסטט, צריך להגדיר את המאפיין temperatureDisplayMode
של ThermostatUserInterfaceConfigurationTrait
לערך TemperatureDisplayModeEnum.Celsius
או TemperatureDisplayModeEnum.Fahrenheit
.
Device API
// Set the displayed temperature scale to Fahrenheit val uiConfig = home .devices() .list() .filter { device -> device.has(ThermostatUserInterfaceConfiguration) } .first() val uiConfigTraitFlow: Flow<ThermostatUserInterfaceConfiguration?> = uiConfig .type(ThermostatDevice) .map { it.standardTraits.thermostatUserInterfaceConfiguration } .distinctUntilChanged() val uiConfigTrait: ThermostatUserInterfaceConfiguration = uiConfigTraitFlow.first()!! if ( uiConfigTrait.supports(ThermostatUserInterfaceConfiguration.Attribute.temperatureDisplayMode) ) { val unused = uiConfigTrait.update { setTemperatureDisplayMode(TemperatureDisplayModeEnum.Fahrenheit) } }
Automation API
val automation = automation { isActive = true sequential { val stateReaderNode = stateReader<_>(thermostat, ThermostatDevice, ThermostatUserInterfaceConfiguration) // When someone says "Show the temperature in Fahrenheit", val unused = starter<_>(structure, VoiceStarter.OkGoogleEvent) { parameter(VoiceStarter.OkGoogleEvent.query("Show the temperature in Fahrenheit")) } // if the temperature isn't being shown in Fahrenheit condition() { expression = stateReaderNode.temperatureDisplayMode notEquals TemperatureDisplayModeEnum.Fahrenheit } // display the current temperature using Fahrenheit action(thermostat, ThermostatDevice) { update(ThermostatUserInterfaceConfiguration) { setTemperatureDisplayMode(TemperatureDisplayModeEnum.Fahrenheit) } } } }
שינוי מצב ההפעלה
אפשר להגביל את התרמוסטט למצבי הפעלה מסוימים, שמוגדרים על ידי ThermostatTrait.SystemModeEnum
, על ידי הגדרת המאפיין ThermostatTrait.Attributes.systemMode
, שהערכים שלו מוגדרים על ידי ThermostatTrait.Attributes.SystemModeEnum
.
Device API
val thermostatDevice = structure.devices().list().first { device -> device.has(Thermostat) } val thermostatTraitFlow: Flow<Thermostat?> = thermostat.type(ThermostatDevice).map { it.standardTraits.thermostat }.distinctUntilChanged() val thermostatTrait: Thermostat = thermostatTraitFlow.first()!! // Set the system mode to Auto if (thermostatTrait.supports(Thermostat.Attribute.systemMode)) { val unused = thermostatTrait.update { setSystemMode(SystemModeEnum.Auto) } }
Automation API
val automation = automation { isActive = true // When the door lock state changes sequential { val doorLockEvent = starter<_>(doorLock, DoorLockDevice, LockOperationEvent) val stateReaderNode = stateReader<_>(thermostat, ThermostatDevice, SimplifiedThermostat) // if the door is unlocked and the thermostat is in Eco mode condition() { val expr1 = (doorLockEvent.lockOperationType equals LockOperationTypeEnum.Unlock) val expr2 = (stateReaderNode.systemMode equals SimplifiedThermostatSystemModeEnum.Eco) expression = expr1 and expr2 } // Set the thermostat to Auto mode action(thermostat, ThermostatDevice) { command(SimplifiedThermostat.setSystemMode(SimplifiedThermostatSystemModeEnum.Auto)) } } }
כשהתרמוסטט מוגדר ל-SystemModeEnum.Auto
, אפשר לקרוא מידע נוסף על מצב הפעולה של התרמוסטט מ-ThermostatTrait.Attributes.thermostatRunningMode
, שמאוכלס בערכים מ-ThermostatRunningModeEnum
.
Device API
// Get the current thermostat running mode val runningModeTraitFlow: Flow<Thermostat?> = thermostat.type(ThermostatDevice).map { it.standardTraits.thermostat }.distinctUntilChanged() val runningMode: ThermostatTrait.ThermostatRunningModeEnum? = runningModeTraitFlow.first()?.thermostatRunningMode
Automation API
val automation = automation { isActive = true sequential { val stateReaderNode = stateReader<_>(thermostat, ThermostatDevice, Thermostat) // at 10:00am val unused = starter<_>(structure, Time.ScheduledTimeEvent) { parameter(Time.ScheduledTimeEvent.clockTime(LocalTime.of(10, 0, 0, 0))) } // if the thermostat is in Auto mode and is currently cooling condition() { val expr1 = (stateReaderNode.systemMode equals ThermostatTrait.SystemModeEnum.Auto) val expr2 = (stateReaderNode.thermostatRunningMode equals ThermostatTrait.ThermostatRunningModeEnum.Cool) expression = expr1 and expr2 } // announce that it's in Cool mode action(structure) { command(AssistantBroadcast.broadcast("The thermostat is currently running in Cool mode.")) } } }
התכונה
SimplifiedThermostatTrait
נועדה לייעל את תהליך ההגדרה של מצב ההפעלה באוטומציות. כדי לשנות את מצב הפעולה של התרמוסטט באמצעות SimplifiedThermostatTrait
, משתמשים ב-SetSystemModeCommand
, שהערכים שלו מוגדרים על ידי SimplifiedThermostatTrait.SystemModeEnum
.
התכונה הזו זמינה לשימוש רק עם Automation API.
Automation API
val automation = automation { isActive = true sequential { // When the presence state changes... val starterNode = starter<_>(structure, AreaPresenceState) // ...and if the area is unoccupied... condition() { expression = starterNode.presenceState equals PresenceState.PresenceStateVacant } // Set the thermostat to Eco mode action(thermostat, ThermostatDevice) { command(SimplifiedThermostat.setSystemMode(SimplifiedThermostatSystemModeEnum.Eco)) } } }
כדי לקבוע את מצבי המערכת שבהם התרמוסטט יכול לפעול, קוראים את
ThermostatTrait.Attributes.controlSequenceOfOperation
, שהערכים שלו נקבעים על ידי
ThermostatTrait.ControlSequenceOfOperationEnum
.
Device API
// Get the controlSequenceOfOperation val standardTraitFlow: Flow<Thermostat?> = thermostat.type(ThermostatDevice).map { it.standardTraits.thermostat }.distinctUntilChanged() val controlSequenceOfOperation: ThermostatTrait.ControlSequenceOfOperationEnum? = standardTraitFlow.first()?.controlSequenceOfOperation
Automation API
val automation = automation { isActive = true sequential { val stateReaderNode = stateReader<_>(thermostat, ThermostatDevice, Thermostat) // When someone says "Switch to cool mode", val unused = starter<_>(structure, VoiceStarter.OkGoogleEvent) { parameter(VoiceStarter.OkGoogleEvent.query("Switch to cool mode")) } // if the thermostat is capable of operating in Cool mode, condition() { val expr1 = stateReaderNode.controlSequenceOfOperation notEquals ControlSequenceOfOperationEnum.HeatingOnly val expr2 = stateReaderNode.controlSequenceOfOperation notEquals ControlSequenceOfOperationEnum.HeatingWithReheat expression = expr1 and expr2 } action(thermostat, ThermostatDevice) { // switch to Cool mode update(SimplifiedThermostat) { command(SimplifiedThermostat.setSystemMode(SimplifiedThermostatSystemModeEnum.Cool)) } } } }
שינוי מצב הפעולה של התכנות
אפשר לשנות את מצב הפעולה של התרמוסטט באמצעות Thermostat
של thermostatProgrammingOperationMode
, שהערכים שלו מוגדרים על ידי ProgrammingOperationModeBitmap
.
Device API
val thermostatTraitFlow: Flow<Thermostat?> = thermostat.type(ThermostatDevice).map { it.standardTraits.thermostat }.distinctUntilChanged() val thermostatTrait: Thermostat = thermostatTraitFlow.first()!! if (thermostatTrait.supports(Thermostat.Attribute.thermostatProgrammingOperationMode)) { val programmingOperationMode = thermostatTrait.thermostatProgrammingOperationMode!! // Enable autoRecovery on the thermostatProgrammingOperationMode val unused = thermostatTrait.update { setThermostatProgrammingOperationMode( ThermostatTrait.ProgrammingOperationModeBitmap( programmingOperationMode.scheduleActive, true, programmingOperationMode.economy, ) ) } }
Automation API
// When someone says "Reset programming operation mode" val automation = automation { isActive = true sequential { val unused = starter<_>(structure, VoiceStarter.OkGoogleEvent) { parameter(VoiceStarter.OkGoogleEvent.query("Reset programming operation mode")) } // Set all the flags on the programming operation mode action(thermostat, ThermostatDevice) { update(Thermostat) { setThermostatProgrammingOperationMode(ProgrammingOperationModeBitmap(true, true, true)) } } } }
שינוי הטמפרטורה לשמירה
כדי לשנות את נקודת הטמפרטורה שנקבעה באמצעות Thermostat
, צריך להתקשר אל ThermostatTrait.SetpointRaiseLowerCommand
.
Device API
val thermostatTraitFlow: Flow<Thermostat?> = thermostat.type(ThermostatDevice).map { it.standardTraits.thermostat }.distinctUntilChanged() val thermostatTrait: Thermostat = thermostatTraitFlow.first()!! // lower the temperature setpoint by 1 degree C. // `amount` is in one tenth of a degree Celsius. thermostatTrait.setpointRaiseLower(amount = -10, mode = SetpointRaiseLowerModeEnum.Cool)
Automation API
val automation = automation { isActive = true sequential { val stateReaderNode = stateReader<_>(thermostat, ThermostatDevice, Thermostat) // At 10:00pm val unused = starter<_>(structure, Time.ScheduledTimeEvent) { parameter(Time.ScheduledTimeEvent.clockTime(LocalTime.of(22, 0, 0, 0))) } // if the setpoint is warmer than 19C // `occupiedCoolingSetpoint` is in one hundredth of a degree C. condition() { expression = stateReaderNode.occupiedCoolingSetpoint greaterThan 1900 } // lower the temperature setpoint by 5 degrees C // Setpoint amount here is in one tenth of a degree Celsius. action(thermostat, ThermostatDevice) { command(Thermostat.setpointRaiseLower(SetpointRaiseLowerModeEnum.Cool, -50)) } } }
קביעת עדיפות לטמפרטורה לשמירה
כדי להגדיר שטמפרטורת היעד תהיה בעדיפות גבוהה יותר מלוח זמנים מתוכנת מראש, צריך להגדיר את מאפיין ThermostatTrait
temperatureSetpointHold
לערך TemperatureSetpointHoldEnum.SetpointHoldOn
. כדי להגדיר שלוח הזמנים תהיה עדיפות גבוהה יותר, צריך להגדיר את המאפיין לערך TemperatureSetpointHoldEnum.SetpointHoldOff
.
Device API
val thermostatTraitFlow: Flow<Thermostat?> = thermostat.type(ThermostatDevice).map { it.standardTraits.thermostat }.distinctUntilChanged() val thermostatTrait: Thermostat = thermostatTraitFlow.first()!! if (thermostatTrait.supports(Thermostat.Attribute.temperatureSetpointHold)) { // Set temperatureSetpointHold to SetpointHoldOn // allowing temperature setpoints to override any preprogrammed schedules. val unused = thermostatTrait.update { setTemperatureSetpointHold(TemperatureSetpointHoldEnum.SetpointHoldOn) }
Automation API
val automation = automation { isActive = true sequential { // When someone says "Prioritize thermostat setpoint" val unused = starter<_>(structure, VoiceStarter.OkGoogleEvent) { parameter(VoiceStarter.OkGoogleEvent.query("Prioritize thermostat setpoint")) } // make temperature setpoints override any preprogrammed schedules. action(thermostat, ThermostatDevice) { val unused2 = update(Thermostat) { setTemperatureSetpointHold(TemperatureSetpointHoldEnum.SetpointHoldOn) } } }
מגדירים את ThermostatTrait.Attributes.temperatureSetpointHoldDuration
כדי לשלוט במספר הדקות שבהן נקודת ההגדרה פעילה.
Device API
val thermostatTraitFlow: Flow<Thermostat?> = thermostat.type(ThermostatDevice).map { it.standardTraits.thermostat }.distinctUntilChanged() val thermostatTrait: Thermostat = thermostatTraitFlow.first()!! if (thermostatTrait.supports(Thermostat.Attribute.temperatureSetpointHoldDuration)) { // Set the setpoint hold duration to 60 minutes val unused = thermostatTrait.update { setTemperatureSetpointHoldDuration(60u) } }
Automation API
val automation = automation { isActive = true sequential { val stateReaderNode = stateReader<_>(thermostat, ThermostatDevice, Thermostat) val unused = starter<_>(thermostat, ThermostatDevice, Thermostat) // if the temperature setpoint hold duration is less than 60 minutes... condition() { expression = stateReaderNode.temperatureSetpointHoldDuration.lessThan(60u) } // ...and the automation hasn't been run for at least 24 hours... suppressFor(Duration.ofHours(24)) // ...set the temperature setpoint hold duration to 60 minutes action(thermostat, ThermostatDevice) { val unused2 = update(Thermostat) { setTemperatureSetpointHoldDuration(60u) } } } }