دليل جهاز الترموستات لأجهزة Android

يمكن تنفيذ نوع الجهاز "الترموستات" باستخدام عدة سمات من Home API، ولكن السمة الأساسية هي Thermostat. في ما يلي السمات المطلوبة والاختيارية لأجهزة الترموستات.

نوع الجهاز في Home APIs السمات نموذج تطبيق Kotlin حالة الاستخدام

ترموستات

ThermostatDevice

home.matter.0000.types.0301

جهاز يمكن أن يتضمّن أجهزة استشعار مدمجة أو منفصلة لدرجة الحرارة أو الرطوبة أو الإشغال، ويتيح ضبط درجة الحرارة المطلوبة. جهاز الترموستات قادر على إرسال إشعارات بمتطلبات التدفئة و/أو التبريد إلى وحدة تدفئة/تبريد (مثل جهاز معالجة الهواء الداخلي) أو قادر على تضمين آلية للتحكّم في وحدة تدفئة أو تبريد مباشرةً.

السمات المطلوبة
     matter التعرّف
     matter الترموستات

السمات الاختيارية
     matter ThermostatUserInterfaceConfiguration
     google ExtendedThermostat
الترموستات

دعم Automation API

تتوفّر سمات وعناصر الترموستات التالية في واجهة برمجة التطبيقات الخاصة بالأتمتة.

السمة نوع السمة نوع العنصر العنصر
الترموستات matter Command SetpointRaiseLower
الترموستات matter السمة activePresetHandle
الترموستات matter السمة localTemperature
الترموستات matter السمة الإشغال
الترموستات 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 }

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

تحديد درجة حرارة مثلى

يمكنك منح الأولوية لنقطة ضبط درجة الحرارة على الجدول الزمني المبرمَج مسبقًا من خلال ضبط السمة ThermostatTraittemperatureSetpointHold على 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) }
    }
  }
}