Do interfejsów API urządzeń można uzyskać dostęp za pomocą interfejsów API Home na Androida. Zaimportuj do aplikacji te pakiety:
import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id
Aby używać określonych typów urządzeń lub ich cech z interfejsami Device API, musisz je zaimportować osobno.
Aby na przykład używać atrybutu Matter Włączanie/wyłączanie i typu urządzenia Wtyczka, 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 API Home może wywołać błądHomeException
, dlatego zalecamy użycie bloku try-catch
do przechwytywania błęduHomeException
we wszystkich wywołaniach.
Podczas obsługi HomeException
sprawdź pola code
i message
, aby dowiedzieć się, co poszło nie tak.
Każdy nieobsługiwany wyjątek spowoduje awarię aplikacji.
Więcej informacji znajdziesz w artykule Postępowanie z błędami.
Przykładowo, aby wysłać polecenie do urządzenia, zobacz artykuł Wysyłanie polecenia do urządzenia.
Przykładowe rozmowy
Pobieranie listy urządzeń
Jeśli struktura jest dostępna, wywołanie devices()
zwraca listę urządzeń Flow dostępnych 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()
W tym miejscu można uzyskać dostęp do stanów poszczególnych urządzeń i wysłać do nich obsługiwane polecenia.
Czytanie stanu urządzenia
Zobaczmy przykład sprawdzania atrybutu OnOff
z cechy urządzenia Wł./wył. Korzystając z modelu danych cech interfejsów API Home, w którym ta cecha jest identyfikowana jako OnOff
, możesz pobierać dane cech 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()!!
Aby dowiedzieć się więcej o funkcji przepływu w Kotlinie, zapoznaj się z artykułem distinctUntilChanged
.
Unieważnianie stanu w subskrypcji cech
Interfejs TraitStateInvalidation
umożliwia unieważnienie stanu wyodrębnionego za pomocą subskrypcji na urządzeniu docelowym w przypadku, gdy stan nie jest zgłaszany prawidłowo.
Przykłady sytuacji, w których stan może nie być prawidłowo zgłaszany, to m.in. użycie atrybutów w cechach Matter o jakości „C” lub nieoczekiwane problemy spowodowane implementacją urządzenia.
Ten interfejs API powoduje wymuszone odczytanie bieżącego stanu atrybutu i zwraca wynik za pomocą istniejących przepływów atrybutów.
Pobierz cechę, a potem uruchom na niej funkcję forceRead
:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
Pobieranie listy cech typu urządzenia
Typy urządzeń powinny być używane jako punkt wejścia do odczytu cech, ponieważ dzielą urządzenie na elementy funkcjonalne (np. punkty końcowe w Matter).
Uwzględniają one też kolizje cech w przypadku, gdy urządzenie ma 2 typy urządzeń, z których każdy ma tę samą cechę. Jeśli na przykład urządzenie jest jednocześnie głośnikiem i ściemnianym światłem, ma 2 cechy włączania/wyłączania i 2 cechy kontroli poziomu.
Aby uzyskać listę dostępnych cech dla typu urządzenia „Światło z możliwością przyciemnienia”:
// 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 standardowej cechy OnOff
lub cechy zdefiniowanej przez producenta OnOff
. Aby uniknąć niejasności, która cecha jest zamierzona, instancja Trait
odwołująca się do urządzenia powinna być poprzedzona odpowiednią przestrzenią nazw. W przypadku standardowych cech, czyli takich, które są analogiczne do standardowych klastrów Matter, użyj standardTraits
. W przypadku cech 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 konkretnego producenta, odwołuj się do niej bezpośrednio:
// Accessing a custom trait on the type. val customTrait = dimmableLightDevice.trait(MyCustomTrait)
Pobieranie listy urządzeń z określonymi cechami
Funkcji filter
w Kotlinie można używać do dalszego doprecyzowania wywołań interfejsu API. Aby na przykład 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łna lista cech dostępnych w interfejsie Trait
.
Pobieranie listy urządzeń o podobnych typach
Aby zobaczyć listę urządzeń odpowiadających wszystkim lampom 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) } }
Interfejsy API Home obsługują 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, jak w poprzednim przykładzie, istnieje 4 różne typy urządzeń, które mogą reprezentować światło. Aby uzyskać kompleksowy wgląd w typ urządzenia na wyższym poziomie w domu, należy uwzględnić w przefiltrowanych przepływach wiele typów urządzeń.
Pełną listę typów urządzeń dostępnych w interfejsie DeviceType
znajdziesz w interfejsie API Home.
Pobieranie identyfikatora producenta lub identyfikatora produktu urządzenia
Cecha BasicInformation
zawiera 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}")
Identyfikowanie urządzeń w chmurze
Jeśli jesteś producentem urządzeń i tworzysz urządzenia Cloud-to-cloud, aby zidentyfikować swoje urządzenia Cloud-to-cloud za pomocą atrybutu BasicInformation
, możesz uwzględnić te pola ciągu w odpowiedzi SYNC
:
Identyfikator dostawcy wydany przez Connectivity Standards Alliance (CSA):
"matterOriginalVendorId": "0xfff1",
Identyfikator produktu, który jednoznacznie identyfikuje produkt sprzedawcy:
"matterOriginalProductId": "0x1234",
Unikalny identyfikator urządzenia, który jest tworzony w sposób specyficzny dla danego producenta:
"matterUniqueId": "matter-device-id",
Podczas wypełniania tych pól tekstowych użyj Matter
identyfikatorów dostawcy 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 i podać matterUniqueId
jako identyfikator.
Przykładowa odpowiedź SYNC pokazuje 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 dokumentacji Cloud-to-cloud SYNC
.
Metadane urządzenia i cechy
Urządzenia i cechy w interfejsach API Home są powiązane z metadanymi, które mogą ułatwiać zarządzanie wrażeniami użytkowników w aplikacji.
Każda cecha w interfejsach API Home zawiera właściwość sourceConnectivity
, która zawiera informacje o stanie online i lokalizacji cechy (przekierowanie lokalne lub zdalne).
Pobieranie głównego typu urządzenia
Niektóre urządzenia mogą wyświetlać wiele typów urządzeń za pomocą interfejsów API Home. Aby mieć pewność, że użytkownicy widzą odpowiednie opcje aplikacji (np. opcje sterowania urządzeniem i sugerowane automatyzacje) na swoich urządzeniach, warto sprawdzić, jaki jest podstawowy typ urządzenia.
Najpierw pobierz typy urządzenia za pomocą elementu type()
, a następnie określ, który z nich jest podstawowy:
val types = device.types().first() val primaryType = types.first { it.metadata.isPrimaryType }
Sprawdzanie, czy cecha jest dostępna 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 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
Możliwość połączenia urządzenia jest sprawdzana na poziomie typu urządzenia, ponieważ niektóre urządzenia obsługują wiele typów urządzeń. Zwrócony stan to kombinacja stanów połączeń wszystkich cech na danym urządzeniu.
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
Stan PARTIALLY_ONLINE
może wystąpić w przypadku mieszanych typów urządzeń, gdy nie ma połączenia z internetem. Cechy standardowe Matter mogą być nadal dostępne online z powodu routingu lokalnego, ale cechy oparte na chmurze będą offline.
Sprawdzanie kierowania sieciowego cechy
Lokalizacja atrybutu jest też dostępna w interfejsach API Home.
dataSourceLocality
wskazuje, czy cecha jest kierowana zdalnie (przez chmurę), lokalnie (przez lokalny hub) czy peer-to-peer (bezpośrednio z urządzenia na urządzenie, bez huba).
Wartość lokalizacji UNSPECIFIED
może być nieznana, np. gdy aplikacja uruchamia się i jeszcze nie połączyła się z hubem lub serwerem. Te urządzenia są niedostępne i nie będą reagować na żądania interakcji z poleceń ani zdarzeń. To klient decyduje, jak ma postępować z takimi urządzeniami.
val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality
Sprawdzanie trasowania sieci na urządzeniu
Podobnie jak w przypadku łączności, lokalizacja jest sprawdzana na poziomie typu urządzenia. Zwrócony stan to kombinacja lokalizacji wszystkich cech na danym 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.
Lista interfejsów API
Po utworzeniu instancji interfejsu Home
są dostępne te interfejsy API urządzenia:
Interfejs API | Opis |
---|---|
devices() |
Uzyskaj dostęp do wszystkich urządzeń we wszystkich strukturach na koncie Google. Zwraca HomeObjectsFlow , który zawiera dalsze opcje wyszukiwania i filtrowania. |
Po otrzymaniu tokenu HomeDevice
możesz korzystać z tych interfejsów API:
Interfejs API | Opis |
---|---|
allCandidates() |
Zwraca wszystkie kandydatury automatyzacji dla urządzenia i jego podrzędnych. |
candidates() |
Zwraca wszystkie kandydatury automatyzacji dla urządzenia. |
connectivityStateChanged |
Najnowsza data zmiany stanu urządzenia. |
events(event) |
Pobiera przepływ danych konkretnego zdarzenia. |
events(trait) |
Pobiera przepływ wszystkich zdarzeń według tej cechy. |
events(traits) |
Pobiera listę wszystkich zdarzeń według tych atrybutów. |
getSourceConnectivity(trait) |
Pobieranie metadanych określonej cechy. Zwraca wartość SourceConnectivity . |
has(trait) |
Sprawdź, czy urządzenie obsługuje aktualnie żądaną cechę. |
has(type) |
czy urządzenie obsługuje podany typ. |
id |
Unikalny identyfikator systemu urządzenia. |
isInRoom |
czy urządzenie znajduje się w pokoju. |
isInStructure |
czy urządzenie znajduje się w budynku. |
isMatterDevice |
Jeśli urządzenie jest obsługiwane przez Matter. |
name |
Nazwa urządzenia podana przez użytkownika. |
room() |
Pomieszczenie, do którego jest przypisane urządzenie. Zwraca wartość Room . |
roomId |
Identyfikator pokoju, do którego przypisana jest kamera. Zwraca wartość Id . |
sourceConnectivity |
Łączność źródłowa urządzenia, która reprezentuje zbiorcze stany łączności i lokalizację sieciową cech urządzenia. |
structure() |
Struktura, do której jest przypisane urządzenie. Zwraca wartość Structure . |
structureId |
Identyfikator struktury, do której przypisany jest dany sprzęt. Zwraca wartość Id . |
type(type) |
Pobierz definicję typu z wypełnionymi cechami (jeśli są dostępne) w celu uzyskania bezpośredniego dostępu. Zawsze zwraca aktualny zrzut cech. |
types() |
Pobierz listę wszystkich typów dostępnych na urządzeniu. |