Доступ к API устройства можно получить через Home API для iOS. Импортируйте следующие пакеты в свое приложение:
import GoogleHomeSDK
import GoogleHomeTypes
Дополнительные сведения см. в разделе Модель данных в iOS .
Обработка ошибок
Некоторые методы в Home API выдают 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
. Например, чтобы получить конкретную характеристику для типа устройства с регулируемой яркостью:
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) } } }
Полный список признаков, доступных в Home API, см. в разделе «Указатель признаков» на 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) }
В Home API есть несколько типов устройств, которые могут представлять основной тип устройства. Например, нет типа устройства «Легкий». Вместо этого существует четыре разных типа устройств, которые могут представлять свет, как показано в предыдущем примере. Таким образом, чтобы получить полное представление о типах устройств более высокого уровня в доме, необходимо включить несколько типов устройств.
Полный список типов устройств и их характеристик, доступных в Home API, см. в разделе « Поддерживаемые типы устройств на 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
.
Метаданные устройства и характеристик
Устройства и характеристики в Home API имеют связанные с ними метаданные, которые могут помочь в управлении взаимодействием с пользователем в приложении.
Каждый признак в Home API содержит свойство sourceConnectivity
, которое содержит информацию об онлайн-статусе и местонахождении признака (локальная или удаленная маршрутизация).
Получить основной тип устройства
Некоторые устройства могут представлять несколько типов устройств через Home API. Чтобы гарантировать, что пользователям предоставляются соответствующие параметры в приложении (например, управление устройствами и предлагаемые средства автоматизации) для их устройств, полезно проверить, является ли тип устройства основным типом устройства.
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 могут по-прежнему находиться в сети из-за локальной маршрутизации, но облачные свойства будут отключены.
Проверьте сетевую маршрутизацию признака
Местоположение признака также доступно в Home API. dataSourceLocality
указывает, маршрутизируется ли признак удаленно (через облако), локально (через локальный концентратор) или в одноранговой сети (напрямую от устройства к устройству, без концентратора).
Неизвестное unspecified
значение местоположения возможно, например, когда приложение загружается и еще не достигло концентратора или сервера для подключения устройства. Эти устройства недоступны и не смогут выполнить запросы на взаимодействие от команд или событий. Клиент сам решает, как обращаться с такими устройствами.
let levelControlLocality = levelControlTrait.metadata.sourceConnectivity .dataSourceLocality
Проверьте сетевую маршрутизацию устройства
Как и возможность подключения, локальность проверяется на уровне типа устройства. Возвращаемое состояние представляет собой комбинацию местоположения для всех признаков на этом устройстве.
let lightLocality = dimmableLightDeviceType.metadata.sourceConnectivity.dataSourceLocality
mixed
состояние можно наблюдать в сценарии, аналогичном сценарию partiallyOnline
подключения: некоторые характеристики основаны на облаке, а другие — локальны.
Список API
После создания экземпляра Home
через него становятся доступны следующие API-интерфейсы устройств:
API | Описание |
---|---|
device(id:) | Возвращает Publisher для указанного устройства, который выдает состояние устройства при каждом его изменении. |
devices() | Получите все устройства во всех структурах аккаунта Google. Возвращает Query<HomeDevice> , предоставляющий дополнительные параметры поиска и фильтрации. |
Если у вас есть HomeDevice
, через него будут доступны следующие API:
API | Описание |
---|---|
id | Уникальный системный идентификатор устройства. |
name | Имя устройства, предоставленное пользователем. |
structureID | Идентификатор структуры, которой присвоено устройство. Возвращает String? . |
roomID | Идентификатор комнаты, которой присвоено устройство. Возвращает String? . |
types | Получите определенный тип или все доступные типы на устройстве. |
isMatterDevice | Если устройство поддерживается Matter . |
sourceConnectivity | Исходное подключение устройства, представляющее совокупные состояния подключения и сетевую локальность характеристик устройства. |