Доступ к API устройства можно получить через Home API для Android. Импортируйте эти пакеты в своё приложение:
import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id
Чтобы использовать определенные типы устройств или характеристики с API устройств, их необходимо импортировать по отдельности.
Например, чтобы использовать свойство Matter On/Off и тип устройства On/Off Plug-in Unit, импортируйте в свое приложение следующие пакеты:
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice
Более подробную информацию см. в разделе Модель данных на Android .
Обработка ошибок
Любой метод в Home API может выдать исключение HomeException
, поэтому мы рекомендуем использовать блок try-catch
для перехвата HomeException
во всех вызовах.
При обработке HomeException
проверьте его code
и поля message
, чтобы узнать, что пошло не так.
Любые необработанные исключения приведут к сбою вашего приложения.
Более подробную информацию см. в разделе Обработка ошибок .
См. пример в разделе Отправка команды на устройство .
Примеры звонков
Получить список устройств
При наличии структуры вызов devices()
возвращает поток устройств, доступных вам из этой структуры:
// 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()
Отсюда становятся доступны состояния каждого устройства, и на устройство можно отправлять поддерживаемые команды.
Чтение состояния устройства
Рассмотрим пример проверки атрибута OnOff
из свойства On/Off устройства. Используя модель данных свойств Home API, где это свойство идентифицировано как OnOff
, вы можете получить данные свойства через класс standardTraits
типа устройства:
// 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()!!
Подробнее о функции потока Kotlin см. в разделе distinctUntilChanged
Отменить состояние в подписке на признак
Интерфейс TraitStateInvalidation
позволяет аннулировать состояние, полученное через подписки на целевое устройство, в случаях, когда состояние отображается некорректно. Примерами случаев, когда состояние может отображаться некорректно, являются использование атрибутов в трейтах Matter с качеством «C» или реализация устройства, которая неожиданно вызывает проблему.
Этот API принудительно считывает текущее состояние признака и возвращает результат через существующие потоки признаков.
Получите признак, затем запустите forceRead
для этого признака:
val generalDiagnosticsTrait = device.trait(GeneralDiagnostics).first()
generalDiagnosticsTrait.forceRead()
Получить список характеристик типа устройства
Типы устройств следует использовать в качестве точки входа для считывания характеристик, поскольку они разлагают устройство на его функциональные части (как конечные точки в Matter ).
Они также учитывают коллизии характеристик в случае, если устройство относится к двум типам устройств, у обоих из которых может быть одна и та же характеристика. Например, если устройство одновременно является динамиком и диммируемым светильником, у него будут две характеристики «Вкл./Выкл.» и две характеристики «Регулировка уровня».
Чтобы получить список доступных характеристик для типа устройства Dimmable Light:
// 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()
Другой тип конфликта трейтов может возникнуть, когда устройство имеет два трейта с одинаковым именем. Например, onOff
может ссылаться на экземпляр стандартного трейта OnOff
или на экземпляр трейта OnOff
, определённого производителем. Чтобы исключить любую потенциальную неоднозначность относительно того, какой трейт подразумевается, экземпляру Trait
, на который ссылается устройство, должно предшествовать соответствующее пространство имён. Для стандартных трейтов, то есть тех, которые аналогичны стандартным кластерам Matter , используйте standardTraits
. Для трейтов Google используйте googleTraits
:
// Accessing standard traits on the type. val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl
Чтобы получить доступ к характеристике, специфичной для производителя, сошлитесь на нее напрямую:
// Accessing a custom trait on the type. val customTrait = dimmableLightDevice.trait(MyCustomTrait)
Получить список устройств с определенной характеристикой
Функция filter
в Kotlin может использоваться для дальнейшего уточнения вызовов API. Например, чтобы получить список устройств в доме, все из которых имеют свойство «Вкл/Выкл»:
// Get all devices that support OnOff val onOffDevices: Flow<List<HomeDevice>> = home.devices().map { devices -> devices.filter { it.has(OnOff) } }
Полный список характеристик, доступных в API Home, смотрите в разделе Интерфейс Trait
.
Получить список устройств с похожими типами устройств
Чтобы получить список устройств, представляющих все источники света в доме:
// 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) } }
В API Home есть несколько типов устройств, которые могут представлять основной тип устройств. Например, отсутствует тип устройства «Светильник». Вместо него существует четыре различных типа устройств, которые могут представлять светильник, как показано в предыдущем примере. Таким образом, для получения комплексного представления о типах устройств более высокого уровня в доме необходимо включить несколько типов устройств в отфильтрованные потоки.
Полный список типов устройств, доступных в Home API, см. в интерфейсе DeviceType
Получите идентификатор поставщика или идентификатор продукта для устройства
Признак BasicInformation
включает в себя такую информацию, как идентификатор поставщика, идентификатор продукта, название продукта и серийный номер устройства:
// 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}")
Идентификация устройств в облаке для производителей устройств
Если вы являетесь производителем устройств и создаете устройства Cloud-to-cloud , то для идентификации ваших устройств Cloud-to-cloud с помощью признака BasicInformation
вы можете включить следующие строковые поля в их ответ SYNC
:
Альянс по стандартам связи (CSA) выдал идентификатор поставщика:
"matterOriginalVendorId": "0xfff1",
Идентификатор продукта, который однозначно идентифицирует продукт поставщика:
"matterOriginalProductId": "0x1234",
Уникальный идентификатор устройства, создаваемый производителем:
"matterUniqueId": "matter-device-id",
При заполнении этих строковых полей используйте идентификаторы поставщика и продукта Matter , если они у вас есть. Если вы не являетесь участником CSA и вам не присвоены эти идентификаторы, вы можете оставить поля matterOriginalVendorId
и matterOriginalProductId
пустыми и указать идентификатор matterUniqueId
.
Пример ответа SYNC показывает использование этих полей:
{
"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",
}
]
}
]
}
}
Более подробную информацию см. в документации Cloud-to-cloud SYNC
.
Метаданные устройств и характеристик
С устройствами и характеристиками в API Home связаны метаданные, которые могут помочь в управлении пользовательским интерфейсом в приложении.
Каждый признак в API Home содержит свойство sourceConnectivity
, которое содержит информацию о сетевом статусе признака и его местоположении (локальная или удаленная маршрутизация).
Получить основной тип устройства
Некоторые устройства могут поддерживать несколько типов устройств через API Home. Чтобы пользователи получали в приложении необходимые функции (например, управление устройствами и предлагаемые варианты автоматизации) для своих устройств, полезно проверить основной тип устройства.
Сначала получите тип(ы) устройства с помощью type()
, затем определите основной(ые) тип(ы):
val types = device.types().first() val primaryTypes = types.filter { it.metadata.isPrimaryType }
Проверьте, доступен ли признак в сети
Используйте метод connectivityState()
для проверки связности признака:
val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState
Некоторые характеристики, как правило, характеристики smart home Google, могут отображаться в режиме офлайн, если устройство не подключено к интернету. Это связано с тем, что эти характеристики работают в облаке и не имеют локальной маршрутизации.
Проверьте подключение к устройству
Подключённость устройства фактически проверяется на уровне типа устройства, поскольку некоторые устройства поддерживают несколько типов устройств. Возвращаемое состояние представляет собой комбинацию состояний подключения для всех характеристик этого устройства.
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
Состояние PARTIALLY_ONLINE
может наблюдаться в случае смешанных типов устройств при отсутствии подключения к Интернету. Стандартные трейты Matter могут оставаться онлайн благодаря локальной маршрутизации, но облачные трейты будут недоступны.
Проверьте сетевую маршрутизацию признака
Местоположение признака также доступно в API Home. Параметр dataSourceLocality
указывает, маршрутизируется ли признак удалённо (через облако), локально (через локальный концентратор) или одноранговым способом (напрямую с устройства на устройство, без концентратора).
Значение неизвестной локальности UNSPECIFIED
возможно, например, когда приложение загружается и ещё не достигло концентратора или сервера для подключения устройств. Эти устройства недоступны и не будут отвечать на запросы взаимодействия от команд или событий. Клиент должен самостоятельно определить, как обращаться с такими устройствами.
val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality
Проверьте сетевую маршрутизацию для устройства
Как и подключение, локальность проверяется на уровне типа устройства. Возвращаемое состояние представляет собой комбинацию локальности для всех характеристик этого устройства.
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
Состояние MIXED
может наблюдаться в аналогичном сценарии, что и PARTIALLY_ONLINE
подключение: некоторые характеристики являются облачными, а другие — локальными.
Изменить имя устройства
Вызовите метод setName()
, чтобы изменить имя устройства:
mixerDevice.setName("Grendel")
Имена будут усечены, если их длина превышает лимит в 60 кодовых точек (символов) Unicode, без каких-либо ошибок. Разработчики несут ответственность за обработку длинных имён и, например, могут решить, следует ли уведомлять пользователей о том, что имена будут усечены.
список API
После создания экземпляра Home
через него становятся доступны следующие API-интерфейсы устройств:
API | Описание |
---|---|
devices() | Получить все устройства во всех структурах учётной записи Google. Возвращает HomeObjectsFlow , предоставляющий дополнительные возможности поиска и фильтрации. |
Если у вас есть HomeDevice
, через него доступны следующие API:
API | Описание |
---|---|
allCandidates() | Возвращает всех кандидатов на автоматизацию для устройства и его дочерних элементов. |
candidates() | Возвращает всех кандидатов на автоматизацию для устройства. |
connectivityStateChanged | Последний раз, когда изменилось состояние устройства. |
events(event) | Получает поток определенного события. |
events(trait) | Получает поток всех событий по этой черте. |
events(traits) | Получает поток всех событий по этим чертам. |
getSourceConnectivity(trait) | Получить метаданные для определенного признака. Возвращает SourceConnectivity . |
has(trait) | Проверьте, поддерживается ли текущая запрошенная характеристика устройством. |
has(type) | Если устройство поддерживает предоставленный тип. |
id | Уникальный системный идентификатор устройства. |
isInRoom | Если устройство находится в помещении. |
isInStructure | Если устройство находится в конструкции. |
isMatterDevice | Если устройство поддерживается Matter . |
name | Имя устройства, указанное пользователем. |
room() | Комната, к которой относится устройство. Возвращает Room . |
roomId | Идентификатор комнаты, к которой назначено устройство. Возвращает Id . |
sourceConnectivity | Исходная связность устройства, представляющая агрегированные состояния связности и сетевую локальность характеристик устройства. |
structure() | Структура, к которой относится устройство. Возвращает Structure . |
structureId | Идентификатор структуры, к которой назначено устройство. Возвращает Id . |
type(type) | Получает определение типа с заполненными признаками (при наличии) для прямого доступа. Всегда возвращает актуальный снимок признаков. |
types() | Получите список всех типов, доступных на устройстве. |