Hướng dẫn sử dụng thiết bị máy điều nhiệt

Bạn có thể triển khai loại thiết bị Máy điều nhiệt bằng một số đặc điểm Home API, nhưng đặc điểm chính là Thermostat. Sau đây là các đặc điểm bắt buộc và không bắt buộc cho thiết bị Máy điều nhiệt.

Loại thiết bị API Home Đặc điểm Ứng dụng mẫu Trường hợp sử dụng

Máy điều nhiệt

ThermostatDevice

Thiết bị có thể có cảm biến tích hợp hoặc riêng biệt cho nhiệt độ, độ ẩm hoặc số người và cho phép đặt nhiệt độ mong muốn. Máy điều nhiệt có thể gửi thông báo yêu cầu sưởi ấm và/hoặc làm mát đến thiết bị sưởi ấm/làm mát (ví dụ: bộ xử lý không khí trong nhà) hoặc có thể bao gồm cơ chế để trực tiếp điều khiển thiết bị sưởi ấm hoặc làm mát.

Thuộc tính bắt buộc
     matter Xác định
     matter Máy điều nhiệt

Thuộc tính không bắt buộc
     matter Cấu hình giao diện người dùng của Thermostat
     google Thermostat mở rộng
Máy điều nhiệt

Hỗ trợ API tự động hoá

Các đặc điểm và phần tử của Máy điều nhiệt sau đây được hỗ trợ trong Automation API.

Đặc điểm Loại đặc điểm Loại phần tử Phần tử
Máy điều nhiệt vấn đề Lệnh SetpointRaiseLower
Máy điều nhiệt vấn đề Thuộc tính activePresetHandle
Máy điều nhiệt vấn đề Thuộc tính localTemperature
Máy điều nhiệt vấn đề Thuộc tính số người lưu trú
Máy điều nhiệt vấn đề Thuộc tính occupiedCoolingSetpoint
Máy điều nhiệt vấn đề Thuộc tính occupiedHeatingSetpoint
Máy điều nhiệt vấn đề Thuộc tính outdoorTemperature
Máy điều nhiệt vấn đề Thuộc tính setpointChangeSource
Máy điều nhiệt vấn đề Thuộc tính systemMode
Máy điều nhiệt vấn đề Thuộc tính temperatureSetpointHold
Máy điều nhiệt vấn đề Thuộc tính temperatureSetpointHoldDuration
Máy điều nhiệt vấn đề Thuộc tính thermostatRunningMode
Máy điều nhiệt vấn đề Thuộc tính thermostatRunningState
Máy điều nhiệt vấn đề Thuộc tính unoccupiedCoolingSetpoint
Máy điều nhiệt vấn đề Thuộc tính unoccupiedHeatingSetpoint
ExtendedThermostat google Thuộc tính activePresetHandle
ExtendedThermostat google Thuộc tính activeRemoteTemperatureSensorIds
ExtendedThermostat google Thuộc tính averageLocalTemperature
ExtendedThermostat google Thuộc tính extendedRunningMode
ExtendedThermostat google Thuộc tính extendedSystemMode
SimplifiedThermostat google Lệnh SetSystemMode
SimplifiedThermostat google Thuộc tính systemMode

Lấy nhiệt độ môi trường xung quanh

Lấy nhiệt độ môi trường xung quanh bằng Máy điều nhiệt

Để lấy nhiệt độ môi trường của máy điều nhiệt bằng thuộc tính Thermostat, hãy đọc thuộc tính localTemperature.

API thiết bị

// 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 tự động hoá

val automation = automation {
  sequential {
    val starterNode = starter<_>(thermostat, ThermostatDevice, Thermostat)

    // If the temperature is higher than 35C...
    condition { expression = starterNode.localTemperature greaterThan 35 }

    // ...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."))
    }
  }
}

Lấy nhiệt độ môi trường xung quanh bằng TemperatureMeasurement

Để lấy nhiệt độ môi trường của máy điều nhiệt bằng thuộc tính TemperatureMeasurement, hãy đọc thuộc tính measuredValue.

API thiết bị

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

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

API tự động hoá

val automation = automation {
  sequential {
    val temperature = starter<_>(thermostat, ThermostatDevice, TemperatureMeasurement)
    val stateReaderNode = stateReader<_>(light, DimmableLightDevice, OnOff)
    condition() {
      val expr1 = temperature.measuredValue greaterThanOrEquals 35
      val expr2 = stateReaderNode.onOff equals true
      expression = expr1 and expr2
    }
    action(light, DimmableLightDevice) { command(OnOff.on()) }
  }
}

Lấy nhiệt độ trung bình bằng ExtendedThermostat

Để lấy nhiệt độ trung bình trên nhiều cảm biến, hãy đọc thuộc tính averageLocalTemperature của đặc điểm ExtendedThermostat.

API thiết bị

// 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 tự động hoá

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 35
      val expr2 = stateReaderNode.onOff equals true
      expression = expr1 and expr2
    }
    // Turn on the light
    action(light, DimmableLightDevice) { command(OnOff.on()) }
  }
}

Nhận độ ẩm môi trường xung quanh

Để lấy độ ẩm môi trường của máy điều nhiệt bằng thuộc tính RelativeHumidityMeasurement, hãy đọc thuộc tính measuredValue.

API thiết bị

// Get the ambient humidity

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

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

API tự động hoá

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

Chọn thang nhiệt độ hiển thị

Để thay đổi đơn vị đo nhiệt độ dùng cho màn hình máy điều nhiệt, hãy đặt thuộc tính temperatureDisplayMode của ThermostatUserInterfaceConfigurationTrait thành TemperatureDisplayModeEnum.Celsius hoặc TemperatureDisplayModeEnum.Fahrenheit.

API thiết bị

// 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 tự động hoá

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

Thay đổi chế độ hoạt động

Bạn có thể giới hạn Máy điều nhiệt ở một số chế độ hoạt động nhất định do ThermostatTrait.SystemModeEnum xác định bằng cách đặt thuộc tính ThermostatTrait.Attributes.systemMode, giá trị của thuộc tính này do ThermostatTrait.Attributes.SystemModeEnum xác định.

API thiết bị

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 tự động hoá

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

Khi máy điều nhiệt được đặt thành SystemModeEnum.Auto, bạn có thể đọc thêm thông tin về chế độ chạy của máy điều nhiệt từ ThermostatTrait.Attributes.thermostatRunningMode được điền sẵn bằng các giá trị từ ThermostatRunningModeEnum.

API thiết bị

// 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 tự động hoá

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 được thiết kế để đơn giản hoá quy trình thiết lập chế độ hoạt động trong các quy trình tự động hoá. Để thay đổi chế độ hoạt động của bộ điều nhiệt bằng SimplifiedThermostatTrait, hãy sử dụng SetSystemModeCommand, giá trị của chế độ này được xác định bằng SimplifiedThermostatTrait.SystemModeEnum.

Bạn chỉ có thể sử dụng đặc điểm này với Automation API.

API tự động hoá

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

Để xác định các chế độ hệ thống mà máy điều nhiệt có thể hoạt động, hãy đọc ThermostatTrait.Attributes.controlSequenceOfOperation, giá trị của chế độ này do ThermostatTrait.ControlSequenceOfOperationEnum xác định.

API thiết bị

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

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

API tự động hoá

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

Thay đổi chế độ hoạt động lập trình

Bạn có thể thay đổi chế độ hoạt động lập trình của bộ điều nhiệt bằng cách sử dụng thermostatProgrammingOperationMode của Thermostat, giá trị của chế độ này được xác định bởi ProgrammingOperationModeBitmap.

API thiết bị

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 tự động hoá

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

Thay đổi nhiệt độ đặt

Để thay đổi điểm đặt nhiệt độ bằng Thermostat, hãy gọi ThermostatTrait.SetpointRaiseLowerCommand.

API thiết bị

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
thermostatTrait.setpointRaiseLower(amount = 1, mode = SetpointRaiseLowerModeEnum.Cool)

API tự động hoá

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
    condition() { expression = stateReaderNode.occupiedCoolingSetpoint greaterThan 19 }

    // lower the temperature setpoint by 5 degrees
    action(thermostat, ThermostatDevice) {
      command(Thermostat.setpointRaiseLower(SetpointRaiseLowerModeEnum.Cool, 5))
    }
  }
}

Ưu tiên điểm đặt nhiệt độ

Bạn có thể đặt điểm đặt nhiệt độ được ưu tiên hơn lịch biểu được lập trình trước bằng cách đặt thuộc tính temperatureSetpointHold của ThermostatTrait thành TemperatureSetpointHoldEnum.SetpointHoldOn hoặc đặt lịch biểu được ưu tiên bằng cách đặt thành TemperatureSetpointHoldEnum.SetpointHoldOff.

API thiết bị

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 tự động hoá

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

Đặt ThermostatTrait.Attributes.temperatureSetpointHoldDuration để kiểm soát số phút mà chế độ giữ điểm đặt hoạt động.

API thiết bị

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 tự động hoá

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

Để thay đổi chính sách duy trì điểm đặt nhiệt độ, chính sách này xác định cách thức và thời điểm kết thúc trạng thái Duy trì của máy điều nhiệt, hãy gọi ThermostatTrait.SetTemperatureSetpointHoldPolicyCommand.

Các giá trị hợp lệ được xác định bằng TemperatureSetpointHoldPolicyBitmap.

API thiết bị

val thermostatTraitFlow: Flow<Thermostat?> =
  thermostat.type(ThermostatDevice).map { it.standardTraits.thermostat }.distinctUntilChanged()

val thermostatTrait: Thermostat = thermostatTraitFlow.first()!!
if (thermostatTrait.supports(Thermostat.Attribute.temperatureSetpointHoldPolicy)) {

  // Set the temperature setpoint hold policy to holdDurationElapsedOrPresetChanged
  val unused =
    thermostatTrait.setTemperatureSetpointHoldPolicy(
      ThermostatTrait.TemperatureSetpointHoldPolicyBitmap(
        holdDurationElapsed = false,
        holdDurationElapsedOrPresetChanged = true,
      )
    )
}

val automation = automation {
  isActive = true
  sequential {

    // When someone says "Set my preferred hold duration",
    val unused =
      starter<_>(structure, VoiceStarter.OkGoogleEvent) {
        parameter(VoiceStarter.OkGoogleEvent.query("Set my preferred hold duration"))
      }

    // set the temperature setpoint hold policy to holdDurationElapsedOrPresetChanged
    action(thermostat, ThermostatDevice) {
      command(
        Thermostat.setTemperatureSetpointHoldPolicy(
          TemperatureSetpointHoldPolicyBitmap(
            holdDurationElapsed = false,
            holdDurationElapsedOrPresetChanged = true,
          )
        )
      )
    }
  }
}