Доступ к API устройств можно получить через API Home для iOS. Импортируйте следующие пакеты в свое приложение:
import GoogleHomeSDK
import GoogleHomeTypes
Более подробную информацию см. в разделе Модель данных на iOS .
Обработка ошибок
Некоторые методы в API Home выдают HomeError
, поэтому мы рекомендуем использовать блок do-catch
для перехвата HomeError
при таких вызовах.
При обработке HomeError
проверьте поля code
и message
, чтобы узнать, что пошло не так.
Любые необработанные ошибки приведут к сбою вашего приложения.
Более подробную информацию см. в разделе Обработка ошибок .
Пример см. в разделе Отправка команды на устройство .
Примеры звонков
Получить список устройств
Ссылаясь на объект Home
, вызовите devices()
, чтобы получить Query
доступных устройств. Вызовите метод batched()
Query
, который выдает Set, отражающий текущее состояние Home при каждом изменении метаданных устройства. Или вызовите Query.list()
, чтобы получить снимок доступных устройств. Это удобный метод, который подписывается на поток batched()
и возвращает первое выданное значение. Query.stream()
создает поток, который выдает новые значения при изменении метаданных устройства, таких как его имя, комната или структура. Внутренне это использует batched()
и выдает только измененные свойства.
// Get a list of all devices accessible to the user let homeDevices = try await self.home.devices().list()
Отсюда доступны состояния каждого устройства и на устройство можно отправлять поддерживаемые команды.
Получить типы устройств
Чтобы получить типы устройств, связанные с устройством, прочитайте свойство types
устройства, которое возвращает DeviceTypeController
.
Вызовите DeviceTypeController.subscribe(_:)
чтобы подписаться на обновления для определенного типа устройства:
let devices = try await self.home.devices().list() if let device = devices.first(where: { $0.id == myDeviceId }) { var receivedUpdate1 = false var receivedUpdate2 = false device.types.subscribe(OnOffLightDeviceType.self) .assertNoFailure() .sink { device in if !receivedUpdate1 { receivedUpdate1 = true Task { try await device.matterTraits.onOffTrait?.on() } return } if !receivedUpdate2 { receivedUpdate2 = true return } fatalError("Received unexpected update") } }
Если устройство не поддерживает указанный тип устройства, возвращается Empty Publisher
, который немедленно завершается.
Если устройство поддерживает определенный тип устройства, вы можете получить дескриптор этого типа, вызвав get()
:
if let device = devices.first(where: { $0.id == myDeviceId }) { let deviceType = await device.types.get(OnOffLightDeviceType.self) }
Если устройство не поддерживает указанный тип, возвращается nil
.
Вызовите DeviceTypeController.subscribeAll()
для получения Publisher
для DeviceTypeCollection
. Этот класс позволяет вам проверить, имеет ли устройство определенный тип устройства:
if let device = devices.first(where: { $0.id == myDeviceId }) { device.types.subscribeAll() .assertNoFailure() .sink { types in let lightDeviceType = types[OnOffLightDeviceType.self] let fanDeviceType = types[FanDeviceType.self] } }
Получить характеристику типа устройства
Типы устройств являются точкой входа для считывания характеристик, поскольку они разлагают устройство на его функциональные части (подобно конечным точкам в Matter ).
Они также учитывают столкновения признаков в случае, если устройство имеет два типа устройств, оба из которых могут иметь один и тот же признак. Например, если устройство является одновременно динамиком и регулируемым светом, у него будет два признака включения/выключения и два признака управления уровнем.
Другой вид коллизии черт может возникнуть, когда устройство имеет две черты с одинаковым именем. Например, onOff
может ссылаться на экземпляр стандартной черты OnOff
или на экземпляр черты OnOff
, определенной производителем. Чтобы исключить любую потенциальную двусмысленность относительно того, какая черта подразумевается, ссылайтесь на черту через одну из двух коллекций черт для каждого типа устройства.
Для стандартных черт, то есть тех, которые аналогичны стандартным кластерам Matter , используйте matterTraits
. Например, чтобы получить определенную черту для типа устройства Dimmable Light:
if let dimmableLightDeviceType = await device.types.get(DimmableLightDeviceType.self) { // Accessing standard trait on the type. let levelControlTrait = dimmableLightDeviceType.matterTraits.levelControlTrait.self }
Для характеристик Google используйте googleTraits
:
if let doorbellDeviceType = await device.types.get(GoogleDoorbellDeviceType.self) { // Accessing Google trait on the type. let doorbellPressTrait = doorbellDeviceType.googleTraits.doorbellPressTrait.self }
Чтобы получить доступ к свойству, специфичному для производителя, сошлитесь на него через свойство traits
, но предварите его именем пакета производителя:
let deviceType = await device1?.types.get(OnOffLightDeviceType.self) // Accessing custom trait on the type. if let spinnerTrait = deviceType?.traits[ExampleOrganization.SpinnerTrait.self] { let rpmVal = spinnerTrait.attributes.rpm }
Прочитать состояние устройства
Посмотрите на этот пример проверки атрибута OnOff
из свойства On/Off устройства:
let lightDevices = devices.filter { $0.types.contains(OnOffLightDeviceType.self) } let light1 = lightDevices.first let lightDeviceTypeOptional = await light1?.types.get(OnOffLightDeviceType.self) if let onOffTrait = lightDeviceTypeOptional?.matterTraits.onOffTrait { let onOffVal = onOffTrait.attributes.onOff }
Получить список устройств с определенной характеристикой
Чтобы получить список устройств, имеющих определенную черту, вам нужно перебрать устройства, типы устройств каждого устройства и черты каждого типа устройства. Например, чтобы получить список устройств в доме, которые все имеют черту Вкл/Выкл:
// Get all light devices that support levelControl var levelControlDevices: [HomeDevice] = [] var allDevices = try await home.devices().list() for device in allDevices { if let deviceType = await device.types.get(OnOffLightDeviceType.self) { if deviceType.traits.contains(Matter.LevelControlTrait.self) { levelControlDevices.append(device) } } }
Полный список характеристик, доступных в API Home, см. в разделе «Индекс характеристик» на iOS.
Получите список устройств с похожими типами устройств
Чтобы получить список устройств, представляющих все источники света в доме:
// Get a list of devices with similar device types (lights) let lightDevices = try await self.home.devices().list().compactMap { $0.types.contains(DimmableLightDeviceType.self) || $0.types.contains(OnOffLightDeviceType.self) || $0.types.contains(ColorTemperatureLightDeviceType.self) || $0.types.contains(ExtendedColorLightDeviceType.self) }
В API Home есть несколько типов устройств, которые могут представлять основной тип устройства. Например, нет типа устройства "Light". Вместо этого есть четыре разных типа устройств, которые могут представлять свет, как показано в предыдущем примере. Таким образом, чтобы получить полное представление о типе устройства более высокого уровня в доме, необходимо включить несколько типов устройств.
Полный список типов устройств и их характеристик, доступных в API Home, см. в разделе Поддерживаемые типы устройств на iOS.
Получите имя поставщика, идентификатор поставщика или идентификатор продукта для устройства.
Черта BasicInformationTrait
включает в себя такую информацию, как идентификатор поставщика, идентификатор продукта, название продукта и серийный номер устройства:
guard let vendorName = basicInfoTrait.attributes.vendorName else { fatalError("Failed to get vendorName") } guard let vendorID = basicInfoTrait.attributes.vendorID else { fatalError("Failed to get vendorID") } guard let productID = basicInfoTrait.attributes.productID else { fatalError("Failed to get 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. Чтобы убедиться, что пользователям представлены соответствующие параметры в приложении (например, управление устройством и предлагаемые автоматизации) для их устройств, полезно проверить, является ли тип устройства основным типом устройства.
if let deviceType = await device?.types.get(HumiditySensorDeviceType.self) { if deviceType.metadata.isPrimaryType { print("Humidity Sensor is the primary type on this device.") } else { print("Humidity Sensor isn't the primary type on this device.") } }
Проверьте, есть ли черта в сети
Прочитайте свойство connectivityState
, чтобы проверить связность признака:
let levelControlConnectivity = levelControlTrait.metadata.sourceConnectivity .connectivityState
Некоторые характеристики, как правило, характеристики smart home Google, могут отображаться в автономном режиме, если устройство не имеет подключения к Интернету. Это связано с тем, что эти характеристики основаны на облаке и не имеют локальной маршрутизации.
Проверьте подключение устройства
Подключенность устройства фактически проверяется на уровне типа устройства, поскольку некоторые устройства поддерживают несколько типов устройств. Возвращаемое состояние представляет собой комбинацию состояний подключения для всех признаков на этом устройстве.
let lightConnectivity = dimmableLightDeviceType.metadata.sourceConnectivity .connectivityState
Состояние partiallyOnline
может наблюдаться в случае смешанных типов устройств, когда нет подключения к Интернету. Стандартные черты Matter могут быть все еще онлайн из-за локальной маршрутизации, но облачные черты будут офлайн.
Проверьте сетевую маршрутизацию признака
Локальность для признака также доступна в API Home. dataSourceLocality
указывает, маршрутизируется ли признак удаленно (через облако), локально (через локальный концентратор) или однорангово (напрямую с устройства на устройство, без концентратора).
Значение unknown locality unspecified
возможно, например, когда приложение загружается и еще не достигло концентратора или сервера для подключения устройства. Эти устройства недоступны и не будут отвечать на запросы взаимодействия от команд или событий. Клиент должен определить, как обращаться с такими устройствами.
let levelControlLocality = levelControlTrait.metadata.sourceConnectivity .dataSourceLocality
Проверьте сетевую маршрутизацию для устройства
Как и подключение, локальность проверяется на уровне типа устройства. Возвращаемое состояние представляет собой комбинацию локальности для всех признаков на этом устройстве.
let lightLocality = dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality
Состояние mixed
может наблюдаться в аналогичном сценарии, что и при partiallyOnline
подключении к Интернету: некоторые характеристики являются облачными, а другие — локальными.
Изменить имя устройства
Вызовите метод setName(_:)
, чтобы изменить имя устройства:
let updatedDevice = try await theDevice.setName("new device name")
При изменении имени устройства исходная структура HomeDevice
остается прежней, а изменение отражается в возвращаемом обновленном объекте HomeDevice
.
список API
После создания экземпляра Home
через него становятся доступны следующие API устройств:
API | Описание |
---|---|
device(id:) | Возвращает Publisher для указанного устройства, который передает состояние устройства при каждом его изменении. |
devices() | Получить все устройства во всех структурах в аккаунте Google. Возвращает Query<HomeDevice> , который предоставляет дополнительные параметры поиска и фильтрации. |
Если у вас есть HomeDevice
, через него доступны следующие API:
API | Описание |
---|---|
id | Уникальный системный идентификатор устройства. |
name | Имя устройства, указанное пользователем. |
structureID | Идентификатор структуры, к которой назначено устройство. Возвращает String? . |
roomID | Идентификатор комнаты, к которой назначено устройство. Возвращает String? . |
types | Получите определенный тип или все доступные типы на устройстве. |
isMatterDevice | Если устройство поддерживается Matter . |
sourceConnectivity | Исходная связность устройства, представляющая собой агрегированные состояния связности и сетевую локальность характеристик устройства. |