Руководство по устройству термостата для Android

Тип устройства «Термостат» может быть реализован с помощью нескольких свойств Home API, но основным является свойство Thermostat . Ниже приведены обязательные и необязательные свойства для устройств «Термостат».

API для дома Тип устройства Черты Пример приложения Kotlin Вариант использования

Термостат

Thermostat Device

home.matter.0000.types.0301

Устройство, которое может иметь встроенные или отдельные датчики температуры, влажности или присутствия людей, и позволяет устанавливать желаемую температуру. Термостат способен отправлять уведомления о необходимости нагрева и/или охлаждения на нагревательное/охлаждающее устройство (например, внутренний кондиционер) или может включать в себя механизм для непосредственного управления нагревательным/охлаждающим устройством.

Требуемые черты
вопрос Идентифицировать
дело Термостат

Термостат

Поддержка API автоматизации

В API автоматизации поддерживаются следующие характеристики и элементы термостата.

Черта Тип черты Тип элемента Элемент
Термостат иметь значение Команда SetpointRaiseLower
Термостат иметь значение Атрибут activePresetHandle
Термостат иметь значение Атрибут локальная температура
Термостат иметь значение Атрибут занятость
Термостат иметь значение Атрибут ЗанятаяУставкаОхлаждения
Термостат иметь значение Атрибут Занятая уставка нагрева
Термостат иметь значение Атрибут наружная температура
Термостат иметь значение Атрибут setpointChangeSource
Термостат иметь значение Атрибут systemMode
Термостат иметь значение Атрибут удержание заданной температуры
Термостат иметь значение Атрибут температураУставкаПродолжительностьУдержания
Термостат иметь значение Атрибут термостатRunningMode
Термостат иметь значение Атрибут термостатRunningState
Термостат иметь значение Атрибут незанятыйУставкаОхлаждения
Термостат иметь значение Атрибут незанятыйУставкаОтопления
Расширенный термостат Google Атрибут activePresetHandle
Расширенный термостат Google Атрибут activeRemoteTemperatureSensorIds
Расширенный термостат Google Атрибут средняя местная температура
Расширенный термостат Google Атрибут расширенный режим работы
Расширенный термостат Google Атрибут расширенныйсистемныйрежим

Получите температуру окружающей среды

Получите температуру окружающей среды с помощью термостата

Чтобы получить температуру окружающей среды термостата с помощью свойства Thermostat , прочитайте атрибут localTemperature .

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 }

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 .

API устройства

val temperatureTraitFlow: Flow<TemperatureMeasurement?> =
  thermostat
    .type(TemperatureSensorDevice)
    .map { it.standardTraits.temperatureMeasurement }
    .distinctUntilChanged()

val localTemp: Short? = temperatureTraitFlow.first()?.measuredValue

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 .

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

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 .

API устройства

// Get the ambient humidity

val humidityTraitFlow: Flow<RelativeHumidityMeasurement?> =
  humiditySensingThermostat
    .type(HumiditySensorDevice)
    .map { it.standardTraits.relativeHumidityMeasurement }
    .distinctUntilChanged()

val localHumidity: UShort? = humidityTraitFlow.first()?.measuredValue

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 .

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) }
}

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 .

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) }
}

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 .

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

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 .

Эта черта доступна только для использования с API автоматизации.

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 .

API устройства

// Get the controlSequenceOfOperation
val standardTraitFlow: Flow<Thermostat?> =
  thermostat.type(ThermostatDevice).map { it.standardTraits.thermostat }.distinctUntilChanged()

val controlSequenceOfOperation: ThermostatTrait.ControlSequenceOfOperationEnum? =
  standardTraitFlow.first()?.controlSequenceOfOperation

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 .

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,
        )
      )
    }
}

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 .

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)

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))
    }
  }
}

Установите приоритет заданного значения температуры

Можно сделать так, чтобы заданное значение температуры имело приоритет над предварительно запрограммированным расписанием, установив атрибут temperatureSetpointHold объекта ThermostatTrait на TemperatureSetpointHoldEnum.SetpointHoldOn или задать приоритет расписания, установив его на TemperatureSetpointHoldEnum.SetpointHoldOff .

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)
    }

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 , чтобы контролировать, как долго в минутах будет активна уставка.

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) }
}

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) }
    }
  }
}