Доступ к API устройства можно получить через Home API для iOS. Импортируйте следующие пакеты в ваше приложение:
import GoogleHomeSDK
import GoogleHomeTypes
Более подробную информацию см. в разделе Модель данных на iOS .
Обработка ошибок
Некоторые методы в Home API выдают HomeError
, поэтому мы рекомендуем использовать блок do-catch
для перехвата HomeError
при таких вызовах.
При обработке HomeError
проверьте ее code
и поля message
, чтобы узнать, что пошло не так.
Любые необработанные ошибки приведут к сбою вашего приложения.
Более подробную информацию см. в разделе Обработка ошибок .
См. пример в разделе Отправка команды на устройство .
Примеры звонков
Получить список устройств
Используя ссылку на объект Home
, вызовите devices()
, чтобы получить Query
доступных устройств. Вызовите метод batched()
объекта Query
, который возвращает набор, отражающий текущее состояние объекта 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 есть несколько типов устройств, которые могут представлять основной тип устройств. Например, отсутствует тип устройства «Светильник». Вместо него существует четыре различных типа устройств, которые могут представлять светильник, как показано в предыдущем примере. Таким образом, для получения полного представления о типах устройств более высокого уровня в доме необходимо включить несколько типов устройств.
Полный список типов устройств и их характеристик, доступных в 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
В аналогичном сценарии, как и при partiallyOnline
-подключении, можно наблюдать mixed
состояние: некоторые характеристики являются облачными, а другие — локальными.
Изменить имя устройства
Вызовите метод setName(_:)
, чтобы изменить имя устройства:
let updatedDevice = try await theDevice.setName("new device name")
При изменении имени устройства исходная структура HomeDevice
остается прежней, а изменение отражается в возвращаемом обновленном объекте HomeDevice
.
Имена будут усечены, если их длина превышает лимит в 60 кодовых точек (символов) Unicode, без каких-либо ошибок. Разработчики несут ответственность за обработку длинных имён и, например, могут решить, следует ли уведомлять пользователей о том, что имена будут усечены.
список API
После создания экземпляра Home
через него становятся доступны следующие API-интерфейсы устройств:
API | Описание |
---|---|
device(id:) | Возвращает Publisher для указанного устройства, который передает состояние устройства при каждом его изменении. |
devices() | Получить все устройства во всех структурах учётной записи Google. Возвращает запрос Query<HomeDevice> , который предоставляет дополнительные возможности поиска и фильтрации. |
Если у вас есть HomeDevice
, через него доступны следующие API:
API | Описание |
---|---|
id | Уникальный системный идентификатор устройства. |
name | Имя устройства, указанное пользователем. |
structureID | Идентификатор структуры, к которой назначено устройство. Возвращает String? . |
roomID | Идентификатор комнаты, к которой назначено устройство. Возвращает String? . |
types | Получить определенный тип или все доступные типы на устройстве. |
isMatterDevice | Если устройство поддерживается Matter . |
sourceConnectivity | Исходная связность устройства, представляющая агрегированные состояния связности и сетевую локальность характеристик устройства. |