Dostęp do interfejsów API urządzeń można uzyskać za pomocą interfejsów Home API na Androida. Zaimportuj te pakiety do aplikacji:
import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id
Aby używać określonych typów lub cech urządzeń z interfejsami Device API, musisz je zaimportować osobno.
Aby na przykład użyć cechy Matter Włączanie/wyłączanie i typu urządzenia Włącznik/wyłącznik, zaimportuj do aplikacji te pakiety:
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice
Więcej informacji znajdziesz w artykule Model danych na Androidzie.
Obsługa błędów
Każda metoda w interfejsach Home API może zgłosić wyjątek HomeException
, dlatego zalecamy używanie bloku try-catch
do przechwytywania wyjątku HomeException
we wszystkich wywołaniach.
Podczas obsługi HomeException
sprawdź pola code
i message
, aby dowiedzieć się, co poszło nie tak.
Wszelkie nieobsłużone wyjątki spowodują awarię aplikacji.
Więcej informacji znajdziesz w sekcji Obsługa błędów.
Przykład znajdziesz w artykule Wysyłanie polecenia do urządzenia.
Przykładowe połączenia
Pobieranie listy urządzeń
Gdy struktura jest dostępna, wywołanie devices()
zwraca strumień urządzeń, do których masz dostęp w ramach tej struktury:
// Get a flow of all devices accessible to the user val allDevicesFlow: HomeObjectsFlow<HomeDevice> = home.devices() // Calling list() on a HomeObjectsFlow returns the first Set of elements. val allDevices: Set<HomeDevice> = allDevicesFlow.list()
Możesz tam sprawdzić stany poszczególnych urządzeń i wysyłać do nich obsługiwane polecenia.
Odczytywanie stanu urządzenia
Spójrzmy na przykład sprawdzania atrybutu OnOff
z cechy włączania i wyłączania urządzenia. Korzystając z modelu danych cech interfejsów Home API, w którym ta cecha jest oznaczona jako OnOff
, możesz pobrać dane cechy za pomocą klasy standardTraits
typu urządzenia:
// Assuming we have a device. val deviceFlow = home.devices().itemFlow(myDeviceId) val device = deviceFlow.first() // Get a flow of a standard trait on the type. distinctUntilChanged() is needed to only trigger // on the specific trait changes and not the whole type. val onOffTraitFlow: Flow<OnOff?> = device.type(DimmableLightDevice).map { it.standardTraits.onOff }.distinctUntilChanged() val onOffTrait: OnOff = onOffTraitFlow.first()!!
Więcej informacji o funkcji przepływu Kotlin znajdziesz w sekcji
distinctUntilChanged
.
Unieważnianie stanu w subskrypcji cechy
TraitStateInvalidation
Interfejs
umożliwia unieważnienie stanu pobranego za pomocą subskrypcji
na urządzeniu docelowym w przypadkach, gdy stan nie jest zgłaszany prawidłowo.
Przykłady sytuacji, w których stan może nie być zgłaszany prawidłowo: używanie atrybutów w Matter cechach o jakości „C” lub implementacja na urządzeniu, która nieoczekiwanie powoduje problem.
Ten interfejs API wymusza odczyt bieżącego stanu cechy i zwraca wynik za pomocą istniejących przepływów cech.
Pobierz cechę, a następnie uruchom na niej funkcję forceRead
:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
Pobieranie listy cech typu urządzenia
Typy urządzeń powinny być punktem wyjścia do odczytywania cech, ponieważ dzielą urządzenie na jego funkcjonalne części (np. punkty końcowe w Matter).
Uwzględniają one też kolizje cech w przypadku, gdy urządzenie ma 2 typy, z których każdy może mieć tę samą cechę. Jeśli na przykład urządzenie jest zarówno głośnikiem, jak i ściemnianym oświetleniem, będzie miało 2 cechy włączania/wyłączania i 2 cechy sterowania poziomem.
Aby uzyskać listę dostępnych cech dla typu urządzenia Dimmable Light (Światło z możliwością ściemniania):
// Get all types available on this device. Requires the types to be part of the registry during // SDK initialization. val typesFlow: Flow<Set<DeviceType>> = device.types() // Get a snapshot of all types. val types: Set<DeviceType> = typesFlow.first() // Get the DimmableLightDevice instance from the set of types. val dimmableLightDevice = types.filterIsInstance<DimmableLightDevice>().firstOrNull() // Get all traits in the type + traits registered val allTraits: Set<Trait> = dimmableLightDevice!!.traits()
Inny rodzaj kolizji cech może wystąpić, gdy urządzenie ma 2 cechy o tej samej nazwie. Na przykład onOff
może odnosić się do instancji standardowego atrybutuOnOff
lub do instancji atrybutu zdefiniowanego przez producentaOnOff
. Aby wyeliminować wszelkie potencjalne niejasności co do tego, która cecha jest zamierzona, przed instancją Trait
, do której odwołuje się urządzenie, powinna znajdować się kwalifikująca przestrzeń nazw. W przypadku cech standardowych, czyli tych, które są analogiczne do klastrów standardowych, użyj standardTraits
.Matter W przypadku atrybutów Google użyj googleTraits
:
// Accessing standard traits on the type. val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl
Aby uzyskać dostęp do cechy specyficznej dla producenta, odwołaj się do niej bezpośrednio:
// Accessing a custom trait on the type. val customTrait = dimmableLightDevice.trait(MyCustomTrait)
Pobieranie listy urządzeń o określonej cesze
Funkcja filter
w Kotlinie może służyć do dalszego doprecyzowywania wywołań interfejsu API. Na przykład, aby uzyskać listę urządzeń w domu, które mają cechę Włączanie/wyłączanie:
// Get all devices that support OnOff val onOffDevices: Flow<List<HomeDevice>> = home.devices().map { devices -> devices.filter { it.has(OnOff) } }
Pełną listę cech dostępnych w interfejsach Home API znajdziesz w Trait
interfejsie.
Wyświetlanie listy urządzeń o podobnych typach
Aby uzyskać listę urządzeń reprezentujących wszystkie światła w domu:
// Get a list of devices with similar device types (lights) val lightDevices = home.devices().map { devices -> devices.filter { it.has(DimmableLightDevice) || it.has(OnOffLightDevice) || it.has(ColorTemperatureLightDevice) || it.has(ExtendedColorLightDevice) } }
W interfejsach Home API jest wiele typów urządzeń, które mogą reprezentować podstawowy typ urządzenia. Na przykład nie ma typu urządzenia „Światło”. Zamiast tego istnieją 4 różne typy urządzeń, które mogą reprezentować światło, jak pokazano w poprzednim przykładzie. Aby uzyskać pełny obraz urządzeń wyższego poziomu w domu, w przefiltrowanych przepływach należy uwzględnić wiele typów urządzeń.
Pełną listę typów urządzeń dostępnych w interfejsach Home API znajdziesz w DeviceType
interfejsie.
Pobieranie identyfikatora dostawcy lub identyfikatora produktu dla urządzenia
Cechy BasicInformation
zawierają informacje takie jak identyfikator dostawcy, identyfikator produktu, nazwa produktu i numer seryjny urządzenia:
// Get device basic information. All general information traits are on the RootNodeDevice type. val basicInformation = device.type(RootNodeDevice).first().standardTraits.basicInformation!! println("vendorName ${basicInformation.vendorName}") println("vendorId ${basicInformation.vendorId}") println("productId ${basicInformation.productId}")
Identyfikacja urządzeń w chmurze dla producentów urządzeń
Jeśli jesteś producentem urządzeń i tworzysz Cloud-to-cloud urządzenia, aby identyfikować swoje Cloud-to-cloud urządzenia za pomocą cechy BasicInformation
, możesz uwzględnić te pola tekstowe w odpowiedzi SYNC
:
The Connectivity Standards Alliance (CSA) wydało identyfikator dostawcy:
"matterOriginalVendorId": "0xfff1",
Identyfikator produktu, który jednoznacznie identyfikuje produkt sprzedawcy:
"matterOriginalProductId": "0x1234",
unikalny identyfikator urządzenia, który jest tworzony w sposób określony przez producenta:
"matterUniqueId": "matter-device-id",
Podczas wpisywania tych pól tekstowych użyj identyfikatorów Matterdostawcy i produktu, jeśli je masz. Jeśli nie jesteś członkiem CSA i nie masz przypisanych tych identyfikatorów, możesz pozostawić pola matterOriginalVendorId
i matterOriginalProductId
puste, a jako identyfikator podać matterUniqueId
.
W przykładowej odpowiedzi SYNC widać użycie tych pól:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"agentUserId": "1836.15267389",
"devices": [
{
"id": "456",
"type": "action.devices.types.LIGHT",
"traits": [
"action.devices.traits.OnOff",
"action.devices.traits.Brightness",
"action.devices.traits.ColorSetting",
],
"willReportState": true,
"deviceInfo": { ... },
"matterOriginalVendorId": "0xfff1",
"matterOriginalProductId": "0x1234",
"matterUniqueId": "matter-device-id",
"otherDeviceIds": [
{
"deviceId": "local-device-id",
}
]
}
]
}
}
Więcej informacji znajdziesz w Cloud-to-cloud SYNC
dokumentacji.
Metadane urządzenia i cech
Urządzenia i cechy w interfejsach Home API mają powiązane z nimi metadane, które mogą ułatwiać zarządzanie wrażeniami użytkowników w aplikacji.
Każda cecha w interfejsach Home API zawiera właściwość
sourceConnectivity
z informacjami o stanie online i lokalizacji cechy (routing lokalny lub zdalny).
Pobieranie głównego typu urządzenia
Niektóre urządzenia mogą prezentować wiele typów urządzeń za pomocą interfejsów Home API. Aby mieć pewność, że użytkownicy widzą w aplikacji odpowiednie opcje (np. sterowanie urządzeniem i sugerowane automatyzacje) dla swoich urządzeń, warto sprawdzić, jaki jest główny typ urządzenia.
Najpierw pobierz typy urządzenia za pomocą funkcji type()
, a potem określ typy podstawowe:
val types = device.types().first() val primaryTypes = types.filter { it.metadata.isPrimaryType }
Sprawdzanie, czy atrybut jest online
Aby sprawdzić łączność cechy, użyj metody connectivityState()
:
val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState
Niektóre cechy, zwykle cechy Google smart home, mogą być wyświetlane w trybie offline, jeśli urządzenie nie ma połączenia z internetem. Dzieje się tak, ponieważ te cechy są oparte na chmurze i nie mają routingu lokalnego.
Sprawdzanie połączenia urządzenia
Połączenie urządzenia jest sprawdzane na poziomie typu urządzenia, ponieważ niektóre urządzenia obsługują wiele typów. Zwracany stan jest kombinacją stanów łączności wszystkich cech na tym urządzeniu.
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
Stan PARTIALLY_ONLINE
może wystąpić w przypadku różnych typów urządzeń, gdy nie ma połączenia z internetem.
Matter standardowe sygnały mogą być nadal online ze względu na lokalne przekierowywanie, ale sygnały oparte na chmurze będą offline.
Sprawdzanie routingu sieciowego cechy
Lokalizacja cechy jest też dostępna w interfejsach Home API. Symbol
dataSourceLocality
wskazuje, czy cecha jest przekazywana zdalnie (przez chmurę), lokalnie (przez lokalny hub) czy w trybie peer-to-peer (bezpośrednio z urządzenia na urządzenie, bez huba).
Nieznana wartość lokalizacji UNSPECIFIED
może wystąpić na przykład podczas uruchamiania aplikacji, która nie nawiązała jeszcze połączenia z centrum lub serwerem. Te urządzenia są niedostępne i nie będą odpowiadać na żądania interakcji z poleceń ani zdarzeń. To klient decyduje, jak obsługiwać takie urządzenia.
val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality
Sprawdzanie routingu sieciowego urządzenia
Podobnie jak łączność, lokalizacja jest sprawdzana na poziomie typu urządzenia. Zwracany stan jest kombinacją lokalizacji wszystkich cech na tym urządzeniu.
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
Stan MIXED
może być obserwowany w podobnym scenariuszu jak w przypadku łączności PARTIALLY_ONLINE
: niektóre cechy są oparte na chmurze, a inne są lokalne.
Zmienianie nazwy urządzenia
Wywołaj metodę setName()
, aby zmienić nazwę urządzenia:
mixerDevice.setName("Grendel")
Nazwy zostaną obcięte, jeśli przekroczą limit 60 punktów kodowych Unicode (znaków), i nie zostaną zgłoszone żadne błędy. Deweloperzy odpowiadają za obsługę długich nazw i mogą na przykład zdecydować, czy chcą informować użytkowników o tym, że nazwy będą skracane.
Lista interfejsów API
Po utworzeniu instancji Home
można uzyskać dostęp do tych interfejsów API urządzenia:
Interfejs API | Opis |
---|---|
devices() |
Uzyskaj dostęp do wszystkich urządzeń we wszystkich strukturach na koncie Google. Zwraca obiekt HomeObjectsFlow , który udostępnia dodatkowe opcje pobierania i filtrowania. |
Po otrzymaniu HomeDevice
możesz uzyskać dostęp do tych interfejsów API:
Interfejs API | Opis |
---|---|
allCandidates() |
Zwraca wszystkie kandydatów do automatyzacji na urządzeniu i jego urządzeniach podrzędnych. |
candidates() |
Zwraca wszystkie kandydatów do automatyzacji na urządzeniu. |
connectivityStateChanged |
Ostatnia zmiana stanu urządzenia. |
events(event) |
Pobiera przepływ określonego zdarzenia. |
events(trait) |
Pobiera strumień wszystkich zdarzeń według tego atrybutu. |
events(traits) |
Pobiera strumień wszystkich zdarzeń według tych cech. |
getSourceConnectivity(trait) |
Pobierz metadane konkretnej cechy. Zwraca wartość SourceConnectivity . |
has(trait) |
Sprawdź, czy bieżąca żądana cecha jest obsługiwana przez urządzenie. |
has(type) |
Jeśli urządzenie obsługuje podany typ. |
id |
Unikalny identyfikator systemowy urządzenia. |
isInRoom |
Czy urządzenie znajduje się w pomieszczeniu. |
isInStructure |
Jeśli urządzenie znajduje się w budynku. |
isMatterDevice |
Jeśli urządzenie jest objęte ochroną Matter. |
name |
Nazwa urządzenia podana przez użytkownika. |
room() |
Pomieszczenie, do którego przypisane jest urządzenie. Zwraca wartość Room . |
roomId |
Identyfikator pomieszczenia, do którego przypisane jest urządzenie. Zwraca wartość Id . |
sourceConnectivity |
Łączność źródłowa urządzenia, która reprezentuje zagregowane stany łączności i lokalizację sieciową cech urządzenia. |
structure() |
Struktura, do której przypisane jest urządzenie. Zwraca wartość Structure . |
structureId |
Identyfikator struktury, do której przypisane jest urządzenie. Zwraca wartość Id . |
type(type) |
Pobierz definicję typu z wypełnionymi cechami (jeśli są dostępne), aby uzyskać bezpośredni dostęp. Zawsze zwraca aktualny zrzut cech. |
types() |
Pobierz listę wszystkich typów dostępnych na urządzeniu. |