Przewodnik po termostatach

Typ urządzenia Termostat może być implementowany za pomocą kilku atrybutów interfejsu Home API, ale głównym atrybutem jest Thermostat. Poniżej znajdziesz wymagane i opcjonalne cechy urządzeń termostatów.

Typ urządzenia w interfejsach API Home Cechy Przykładowa aplikacja Przypadek użycia

Termostat

ThermostatDevice

Urządzenie, które może mieć wbudowane lub oddzielne czujniki temperatury, wilgotności lub obecności oraz umożliwia ustawienie żądanej temperatury. Termostat może wysyłać powiadomienia o wymaganiach dotyczących ogrzewania lub chłodzenia do jednostki grzewczej/chłodniczej (np. do modułu klimatyzacji) lub może zawierać mechanizm umożliwiający bezpośrednie sterowanie jednostką grzewczą lub chłodniczą.

Wymagania dotyczące cech
     matter Identify
     matter Thermostat

Opcjonalne cechy
     matter Konfiguracja interfejsu użytkownika termostatu
     google Rozszerzony termostat
Termostat

Pomoc dotycząca interfejsu Automation API

Te cechy i elementy termostatu są obsługiwane w interfejsie Automation API:

Cecha Typ cechy Typ elementu Element
Termostat matter Polecenie SetpointRaiseLower
Termostat matter Atrybut activePresetHandle
Termostat matter Atrybut localTemperature
Termostat matter Atrybut liczba osób
Termostat matter Atrybut occupiedCoolingSetpoint
Termostat matter Atrybut occupiedHeatingSetpoint
Termostat matter Atrybut outdoorTemperature
Termostat matter Atrybut setpointChangeSource
Termostat matter Atrybut systemMode
Termostat matter Atrybut temperatureSetpointHold
Termostat matter Atrybut temperatureSetpointHoldDuration
Termostat matter Atrybut thermostatRunningMode
Termostat matter Atrybut thermostatRunningState
Termostat matter Atrybut unoccupiedCoolingSetpoint
Termostat matter Atrybut unoccupiedHeatingSetpoint
ExtendedThermostat google Atrybut activePresetHandle
ExtendedThermostat google Atrybut activeRemoteTemperatureSensorIds
ExtendedThermostat google Atrybut averageLocalTemperature
ExtendedThermostat google Atrybut extendedRunningMode
ExtendedThermostat google Atrybut extendedSystemMode
SimplifiedThermostat google Polecenie SetSystemMode
SimplifiedThermostat google Atrybut systemMode

Pobieranie temperatury otoczenia

Pobieranie temperatury otoczenia za pomocą termostatu

Aby uzyskać temperaturę otoczenia termostatu za pomocą atrybutu Thermostat, zapoznaj się z atrybutem 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...
    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."))
    }
  }
}

Pobieranie temperatury otoczenia za pomocą usługi TemperatureMeasurement

Aby uzyskać temperaturę otoczenia termostatu za pomocą atrybutu TemperatureMeasurement, zapoznaj się z atrybutem 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 35
      val expr2 = stateReaderNode.onOff equals true
      expression = expr1 and expr2
    }
    action(light, DimmableLightDevice) { command(OnOff.on()) }
  }
}

Pobieranie średniej temperatury za pomocą rozszerzonego termostatu

Aby uzyskać średnią temperaturę z kilku czujników, zapoznaj się z atrybutem averageLocalTemperaturew przypadku atrybutu 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 35
      val expr2 = stateReaderNode.onOff equals true
      expression = expr1 and expr2
    }
    // Turn on the light
    action(light, DimmableLightDevice) { command(OnOff.on()) }
  }
}

Pobieranie wilgotności otoczenia

Aby uzyskać dane dotyczące wilgotności otoczenia termostatu za pomocą cechy RelativeHumidityMeasurement, odczytaj atrybut 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()) }
  }
}

Wybierz wyświetlaną skalę temperatury

Aby zmienić jednostkę miary temperatury używaną na wyświetlaczu termostatu, ustaw atrybut ThermostatUserInterfaceConfigurationTrait na temperatureDisplayModeTemperatureDisplayModeEnum.Celsius lub 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)
      }
    }
  }
}

Zmiana trybu działania

Termostat może być ograniczony do określonych trybów działania zdefiniowanych przez parametr ThermostatTrait.SystemModeEnum, poprzez ustawienie atrybutu ThermostatTrait.Attributes.systemMode, którego wartości są zdefiniowane przez parametr 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))
    }
  }
}

Gdy termostat jest ustawiony na SystemModeEnum.Auto, dodatkowe informacje o trybie działania termostatu można odczytać z parametru ThermostatTrait.Attributes.thermostatRunningMode, który jest wypełniany wartościami z parametru 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 ma na celu usprawnienie procesu konfigurowania trybu działania automatyzacji. Aby zmienić tryb pracy termostatu za pomocą parametru SimplifiedThermostatTrait, użyj parametru SetSystemModeCommand, którego wartości są definiowane przez parametr SimplifiedThermostatTrait.SystemModeEnum.

Ta cecha jest dostępna tylko do użycia z interfejsem 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))
    }
  }
}

Aby określić tryby systemu, w których może działać termostat, zapoznaj się z parametrami 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))
      }
    }
  }
}

Zmiana trybu działania programowania

Tryb programowania termostatu można zmienić za pomocą parametru thermostatProgrammingOperationMode, którego wartości są definiowane przez parametr ProgrammingOperationModeBitmap.Thermostat

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

Zmień ustawienie temperatury

Aby zmienić wartość punktu odniesienia temperatury za pomocą interfejsu Thermostat, wywołaj funkcję 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
thermostatTrait.setpointRaiseLower(amount = 1, 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
    condition() { expression = stateReaderNode.occupiedCoolingSetpoint greaterThan 19 }

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

Nadawanie priorytetu ustawieniu temperatury

Aby wartość zadanej temperatury miała pierwszeństwo przed wstępnie zaprogramowanym harmonogramem, ustaw atrybut ThermostatTrait temperatureSetpointHold na TemperatureSetpointHoldEnum.SetpointHoldOn lub ustaw harmonogram jako priorytet, ustawiając go na 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)
        }
    }
  }

Ustaw wartość ThermostatTrait.Attributes.temperatureSetpointHoldDuration , aby określić, ile minut ma trwać utrzymywanie wartości zadanej.

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

Aby zmienić zasady utrzymywania temperatury, które określają, jak i kiedy kończy się stan utrzymywania termostatu, zadzwoń pod numer ThermostatTrait.SetTemperatureSetpointHoldPolicyCommand.

Prawidłowe wartości są określane przez TemperatureSetpointHoldPolicyBitmap.

Device API

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