คู่มืออุปกรณ์ตัวควบคุมอุณหภูมิสำหรับ Android

คุณอาจใช้ประเภทอุปกรณ์ตัวควบคุมอุณหภูมิโดยใช้ลักษณะ Home API หลายอย่าง แต่ลักษณะหลักคือ Thermostat คุณลักษณะที่จำเป็นและไม่บังคับ สำหรับอุปกรณ์ตัวควบคุมอุณหภูมิมีดังนี้

ประเภทอุปกรณ์ API สำหรับ Home ลักษณะ แอปตัวอย่าง Kotlin กรณีการใช้งาน

ตัวควบคุมอุณหภูมิ

ThermostatDevice

home.matter.0000.types.0301

อุปกรณ์ที่มีเซ็นเซอร์ในตัวหรือเซ็นเซอร์แยกสำหรับอุณหภูมิ ความชื้น หรือการเข้าพัก และช่วยให้ตั้งอุณหภูมิที่ต้องการได้ ตัวควบคุมอุณหภูมิสามารถส่งการแจ้งเตือนข้อกำหนดในการทำความร้อนและ/หรือความเย็นไปยังหน่วยทำความร้อน/ความเย็น (เช่น เครื่องจัดการอากาศภายในอาคาร) หรือสามารถรวมกลไกในการควบคุมหน่วยทำความร้อนหรือความเย็นได้โดยตรง

ลักษณะที่จำเป็น
     Matter ระบุ
     Matter ตัวควบคุมอุณหภูมิ

ลักษณะที่ไม่บังคับ
     matter ThermostatUserInterfaceConfiguration
     google ExtendedThermostat
ตัวควบคุมอุณหภูมิ

การสนับสนุน Automation API

Automation API รองรับลักษณะและองค์ประกอบของตัวควบคุมอุณหภูมิต่อไปนี้

ลักษณะ ประเภทลักษณะ ประเภทองค์ประกอบ องค์ประกอบ
ตัวควบคุมอุณหภูมิ matter คำสั่ง SetpointRaiseLower
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ activePresetHandle
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ localTemperature
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ occupancy
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ occupiedCoolingSetpoint
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ occupiedHeatingSetpoint
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ outdoorTemperature
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ setpointChangeSource
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ systemMode
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ temperatureSetpointHold
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ temperatureSetpointHoldDuration
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ thermostatRunningMode
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ thermostatRunningState
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ unoccupiedCoolingSetpoint
ตัวควบคุมอุณหภูมิ matter แอตทริบิวต์ unoccupiedHeatingSetpoint
ExtendedThermostat google แอตทริบิวต์ activePresetHandle
ExtendedThermostat google แอตทริบิวต์ activeRemoteTemperatureSensorIds
ExtendedThermostat google แอตทริบิวต์ averageLocalTemperature
ExtendedThermostat google แอตทริบิวต์ extendedRunningMode
ExtendedThermostat google แอตทริบิวต์ 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 }

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

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

หากต้องการดูอุณหภูมิเฉลี่ยจากเซ็นเซอร์หลายตัว โปรดอ่านแอตทริบิวต์ ExtendedThermostat ของลักษณะ averageLocalTemperature

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

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

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

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

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

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 เท่านั้น

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

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

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)

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

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

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