Dieser Leitfaden baut auf Auf Geräte und Gerätemetadaten unter iOS zugreifen auf und enthält weitere Beispiele für die Gerätesteuerung und den Gerätezugriff.
Wenn du bestimmte Gerätetypen oder Attribute verwenden möchtest, z. B. den in vielen Beispielen verwendeten Matter
OnOffTrait, musst du sie importieren:
import GoogleHomeSDK
import GoogleHomeTypes
Prüfen, ob ein Attribut einen Befehl unterstützt
Mit der Funktion supports auf Trait-Ebene kannst du prüfen, ob ein Befehl für ein bestimmtes Gerät unterstützt wird.
So kannst du beispielsweise prüfen, ob ein Gerät den Befehl toggle des Attributs „An/Aus“ unterstützt:
// Check if the OnOff trait supports the toggle command. if onOffTraitTest.supportsToggleCommand { print("onOffTrait supports toggle command") } else { print("onOffTrait does not support stateful toggle command") }
Befehl an Geräte senden
Das Senden eines Befehls ähnelt dem Lesen eines Statusattributs aus einem Trait. Wenn du das Gerät ein- oder ausschalten möchtest, verwende den Toggle-Befehl OnOffTrait, der im Datenmodell des Google Home-Ökosystems als toggle() definiert ist. Mit dieser Methode wird onOff in false geändert, wenn der Wert true ist, oder in true, wenn der Wert false ist:
// Calling a command on a trait. do { try await onOffTraitTest.toggle() } catch let _ as HomeError { // Code for handling the exception }
Befehle können eine Ausnahme zurückgeben, wenn ein Problem mit dem Ausführungsablauf erkannt wird. Als Entwickler sollten Sie einen do-catch-Block verwenden, um diese Ausnahmen ordnungsgemäß zu verarbeiten und Nutzern detaillierte Informationen zu Fällen zu liefern, in denen die Fehler behoben werden können. Unbehandelte Ausnahmen stoppen die App-Laufzeit und können zu Abstürzen in Ihrer App führen.
Alternativ können Sie den Status mit den Befehlen off() oder on() explizit festlegen:
do { try await onOffTraitTest.off() try await onOffTraitTest.on() } catch let _ as HomeError { // Code for handling the exception }
Nachdem du einen Befehl zum Ändern des Status gesendet hast, kannst du den Status wie unter Gerätestatus lesen beschrieben auslesen, um ihn in deiner App zu verarbeiten.
Befehl mit Parametern senden
Einige Befehle können Parameter verwenden, z. B. die auf der OnOffTrait oder LevelControlTrait:
offWithEffect
// Turn off the light using the DyingLight effect. do { try await onOffTraitTest.offWithEffect( effectIdentifier: Matter.OnOffTrait.EffectIdentifierEnum.dyingLight, effectVariant: 0 ) } catch let _ as HomeError { // Code for handling the exception }
moveToLevel
// Change the brightness of the light to 50% do { try await levelControlTraitTest.moveToLevel( level: UInt8(127), transitionTime: 0, optionsMask: Matter.LevelControlTrait.OptionsBitmap(), optionsOverride: Matter.LevelControlTrait.OptionsBitmap() ) } catch let _ as HomeError { // Code for handling the exception }
Prüfen, ob ein Attribut von einer Eigenschaft unterstützt wird
Einige Geräte unterstützen möglicherweise ein Matter-Trait, aber kein bestimmtes Attribut. Beispielsweise unterstützt ein Cloud-to-cloud-Gerät, das Matter zugeordnet wurde, möglicherweise nicht alle Matter-Attribute. Verwende in solchen Fällen das Attribut isSupported auf Trait-Ebene, um zu prüfen, ob das Attribut für ein bestimmtes Gerät unterstützt wird.
So kannst du beispielsweise prüfen, ob ein Gerät das Attribut onOff des Merkmals „An/Aus“ unterstützt:
// Check if the OnOff trait supports the onOff attribute. if onOffTrait.attributes.$onOff.isSupported { print("onOffTrait supports onOff state") } else { print("onOffTrait is for a command only device!") }
Einige Attribute können in der Matter-Spezifikation oder im Cloud-to-cloud-smart home-Schema null sein. Bei diesen Attributen können Sie feststellen, ob ein vom Attribut zurückgegebener nil-Wert darauf zurückzuführen ist, dass das Gerät diesen Wert nicht meldet, oder ob der Wert des Attributs tatsächlich nil ist. Verwenden Sie dazu zusätzlich zu isSupported den Wert isNullable:
// Check if a nullable attribute is set or is not supported. if let deviceType = await device.types.get(OnOffLightDeviceType.self) { if let onOffTrait = deviceType.traits[Matter.OnOffTrait.self] { if onOffTrait.attributes.startUpOnOff == nil { if onOffTrait.attributes.$startUpOnOff.isSupported { print( "onOffTrait supports startUpOnOff and it is nil. Check the spec for the contextual meaning." ) } else { print("onOffTrait does not support startUpOnOff!") } } else { print( "onOffTrait supports startUpOnOff and it is set to \(String(describing: onOffTrait.attributes.startUpOnOff))" ) } } }
Eigenschaftsattribute aktualisieren
Wenn du den Wert eines bestimmten Attributs ändern möchtest und keiner der Befehle des Attributs dies tut, kann der Wert des Attributs möglicherweise explizit festgelegt werden.
Ob der Wert eines Attributs geändert werden kann, hängt von zwei Faktoren ab:
- Ist das Attribut beschreibbar?
- Kann sich der Wert des Attributs als Nebenwirkung des Sendens eines Attributbefehls ändern?
Diese Informationen finden Sie in der Referenzdokumentation für Eigenschaften und ihre Attribute.
Daher sind die Kombinationen von Attributen, die bestimmen, wie der Wert eines Attributs geändert werden kann, folgende:
Schreibgeschützt und nicht von anderen Befehlen betroffen. Das bedeutet, dass sich der Wert des Attributs nicht ändert. Beispiel: das Attribut
currentPositiondesSwitchTrait.Schreibgeschützt und von anderen Befehlen betroffen. Das bedeutet, dass der Wert des Attributs nur durch das Senden eines Befehls geändert werden kann. Das Attribut
currentLeveldesLevelControlTraitist beispielsweise schreibgeschützt, sein Wert kann jedoch durch Befehle wiemoveToLevelgeändert werden.Beschreibbar und nicht von anderen Befehlen betroffen. Das bedeutet, dass du den Wert des Attributs direkt mit der Funktion
updatedes Merkmals ändern kannst, es aber keine Befehle gibt, die sich auf den Wert des Attributs auswirken. Beispiel: das AttributWrongCodeEntryLimitdesDoorLockTrait.Beschreibbar und von anderen Befehlen betroffen. Das bedeutet, dass du den Wert des Attributs direkt mit der Funktion
updatedes Merkmals ändern kannst. Außerdem kann sich der Wert des Attributs ändern, wenn ein Befehl gesendet wird. Beispielsweise kann das AttributoccupiedCoolingSetpointvonThermostatTraitbeschrieben, aber auch mit dem BefehlsetpointRaiseLoweraktualisiert werden.
Beispiel für die Verwendung der Update-Funktion zum Ändern des Werts eines Attributs
In diesem Beispiel wird gezeigt, wie Sie den Wert des Attributs DoorLockTrait.wrongCodeEntryLimit explizit festlegen.
Wenn du einen Attributwert festlegen möchtest, rufe die update-Funktion des Merkmals auf und übergib ihr eine Aktualisierungsfunktion, die den neuen Wert festlegt. Es empfiehlt sich, zuerst zu prüfen, ob das Attribut vom Merkmal unterstützt wird.
Beispiel:
if doorLockTraitTest.attributes.$wrongCodeEntryLimit.isSupported { let _ = try await doorLockTraitTest.update { $0.setWrongCodeEntryLimit(3) } }
Gerätegruppe steuern
Zusätzlich zur detaillierten Steuerung jedes Mitglieds einer Gruppe durch Iterieren durch die Mitgliedsgeräte können Sie eine DeviceGroup als einzelne Entität steuern. DeviceGroup entspricht dem Protokoll HasParts und stellt die DeviceType-Teile bereit, die von den Geräten in der Gruppe unterstützt werden:
await group.part(_:)gibt die erste Instanz des angegebenenDeviceTypezurück, wenn die Gruppe dies unterstützt, andernfallsnil.try await group.parts(_:)gibt ein Array aller Teile der obersten Ebene zurück, die mit dem angegebenenDeviceTypeübereinstimmen.
Wenn du einen Trait-Befehl für einen Gerätetyp aufrufst, der Teil einer DeviceGroup ist, leitet das SDK den Befehl an alle zugehörigen Mitgliedsgeräte in der Gruppe weiter, die diese Funktion unterstützen, unabhängig von ihrer zugrunde liegenden Verbindung oder ihrem Transport (z. B. Matter oder Cloud-to-cloud).
Gruppenattribute für Teileigenschaften und Fehlerbehandlung
Die Ausrichtung auf einen Gruppenteil vereinfacht gängige Fälle, in denen Sie einen idempotenten Befehl (z. B. das Ein- oder Ausschalten von Lichtern oder das Festlegen einer Helligkeitsstufe) an eine Gruppe senden möchten. Beachte bei der Arbeit mit Attributen und Befehlen für einen DeviceGroup-Teil Folgendes:
- Dynamische Statusattribute (z. B. das Attribut
onOffvonOnOffTraitoder das AttributcurrentLevelvonLevelControlTrait) werden im Allgemeinen nicht für die Eigenschaft eines Gruppenmitglieds ausgefüllt, da sich die Mitgliedsgeräte in einer Gruppe in unterschiedlichen Zuständen befinden können, die nicht zu einem einzigen Wert kombiniert werden können. Unterstützte Befehle (mitsupports(_:)geprüft, z. B..moveToLevelWithOnOffbei einer dimmbaren Lampe) und ausgewählte Funktionsattribute (z. B.colorTempPhysicalMinMiredsundcolorTempPhysicalMaxMiredsbeiColorControlTraitfür farbige Lampen) werden jedoch ausgefüllt, damit deine App die UI-Steuerelemente entsprechend konfigurieren kann. - Nicht alle Befehle für Eigenschaften von Gruppenmitgliedern sind für einen Gruppenteil verfügbar. Insbesondere sind Befehle, die Werte zurückgeben, nicht verfügbar.
- Ein Befehl für einen Gruppenteil gibt keine einzelnen Ergebnisse für jeden zugrunde liegenden Befehl für ein Mitgliedsgerät zurück. Wenn Sie einzelne Befehlsergebnisse prüfen oder Befehle aufrufen möchten, die Werte zurückgeben, iterieren Sie direkt durch die Mitgliedsgeräte der Gruppe.
- Befehle, die an einen Teil eines
DeviceGroupgesendet werden, werden abgeschlossen, sobald das gesamte Fanout auf den Mitgliedsgeräten abgeschlossen ist und alle zugrunde liegenden Befehlserfolge oder -fehler erfasst wurden. Ein Befehl schlägt nur dann fehl (löst einenHomeErroraus), wenn er für jedes verknüpfte Mitgliedsgerät fehlschlägt oder wenn alle Zielgeräte nicht verfügbar sind. Dies wird als einzelner Befehlsfehler angezeigt, der der Syntax für den Aufruf eines einzelnen Befehls entspricht. Wenn mindestens ein Mitgliedsgerät den Befehl ausführt, wird der Gruppenbefehl ohne Fehler abgeschlossen.
Befehle an einen Teil einer Gruppe senden
So schaltest du alle OnOffLightDeviceType-Lampen in einer Gerätegruppe ein:
if let lightPart = await group.part(OnOffLightDeviceType.self),
let onOffTrait = lightPart.matterTraits.onOffTrait,
onOffTrait.supports(.on) {
try await onOffTrait.on()
}
Du kannst auch mehrere verwandte Gerätetypen prüfen, z. B. alle Lichtgerätetypen in der Gruppe, die OnOffTrait unterstützen, ausschalten:
func onOffTrait(in group: DeviceGroup) async -> Matter.OnOffTrait? {
if let light = await group.part(OnOffLightDeviceType.self) {
return light.matterTraits.onOffTrait
}
if let light = await group.part(DimmableLightDeviceType.self) {
return light.matterTraits.onOffTrait
}
if let light = await group.part(ColorTemperatureLightDeviceType.self) {
return light.matterTraits.onOffTrait
}
if let light = await group.part(ExtendedColorLightDeviceType.self) {
return light.matterTraits.onOffTrait
}
return nil
}
if let trait = await onOffTrait(in: group) {
try await trait.off()
}
Du kannst die Befehlsunterstützung prüfen oder die Funktionsgrenzen eines Gruppenparts abrufen, bevor du einen Befehl sendest. Du kannst beispielsweise .moveToLevelWithOnOff für einen dimmbaren Lichtpart prüfen oder colorTempPhysicalMinMireds und colorTempPhysicalMaxMireds für einen Farbtemperatur-Lichtpart abrufen:
if let dimmableLight = await group.part(DimmableLightDeviceType.self),
let levelTrait = dimmableLight.matterTraits.levelControlTrait,
levelTrait.supports(.moveToLevelWithOnOff) {
try await levelTrait.moveToLevelWithOnOff(
level: 127,
transitionTime: nil,
optionsMask: [],
optionsOverride: []
)
}
if let colorLight = await group.part(ColorTemperatureLightDeviceType.self),
let colorTrait = colorLight.matterTraits.colorControlTrait,
let minMireds = colorTrait.attributes.colorTempPhysicalMinMireds,
let maxMireds = colorTrait.attributes.colorTempPhysicalMaxMireds {
let midMireds = UInt16((UInt32(minMireds) + UInt32(maxMireds)) / 2)
try await colorTrait.moveToColorTemperature(
colorTemperatureMireds: midMireds,
transitionTime: 0,
optionsMask: [],
optionsOverride: []
)
}