Bạn có thể truy cập vào API thiết bị thông qua các API cho Home dành cho Android. Nhập các gói này vào ứng dụng của bạn:
import com.google.home.Home
import com.google.home.HomeDevice
import com.google.home.Id
Để sử dụng các loại thiết bị hoặc đặc điểm cụ thể với Device API, bạn phải nhập riêng từng loại thiết bị hoặc đặc điểm.
Ví dụ: để sử dụng đặc điểm Matter Bật/Tắt và loại thiết bị Bộ phích cắm Bật/Tắt, hãy nhập các gói sau vào ứng dụng của bạn:
import com.google.home.matter.standard.OnOff
import com.google.home.matter.standard.OnOffPluginUnitDevice
Để biết thêm thông tin, hãy xem bài viết Mô hình dữ liệu trên Android.
Xử lý lỗi
Bất kỳ phương thức nào trong Home API đều có thể gửi một
HomeException, vì vậy, bạn nên sử dụng khối try-catch để
bắt HomeException trên tất cả lệnh gọi.
Khi xử lý HomeException, hãy kiểm tra các trường
error.code và
error.message để tìm hiểu xem đã xảy ra lỗi gì. Cũng có thể có mã lỗi phụ, vì vậy, hãy gọi phương thức
getSubErrorCodes() và kiểm tra kết quả.
Mọi ngoại lệ không được xử lý sẽ khiến ứng dụng của bạn gặp sự cố.
Để biết thêm thông tin, hãy xem phần Xử lý lỗi.
Hãy xem phần Gửi lệnh đến thiết bị để biết ví dụ.
Cuộc gọi mẫu
Lấy danh sách thiết bị
Sau khi bạn có tệp đối chiếu với thực thể Structure, lệnh gọi devices() sẽ trả về một Flow của các thiết bị mà bạn có thể truy cập từ cấu trúc đó:
// 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()
Tại đây, bạn có thể truy cập vào trạng thái của từng thiết bị và gửi lệnh đến thiết bị.
Với bản phát hành 1.8 của các API cho Home, bạn có thể yêu cầu API biểu thị từng thiết bị nhiều phần dưới dạng một thiết bị bằng cách đặt tham số enableMultipartDevices của phương thức devices() thành true. Hãy xem bài viết Thiết bị nhiều phần trên Android để biết thêm thông tin.
Đọc trạng thái thiết bị
Hãy xem ví dụ về cách kiểm tra thuộc tính OnOff từ đặc điểm Bật/Tắt của thiết bị. Khi sử dụng mô hình dữ liệu đặc điểm của các API cho Home, trong đó đặc điểm này được xác định là OnOff, bạn có thể truy xuất dữ liệu đặc điểm thông qua lớp standardTraits của loại thiết bị:
// 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()!!
Hãy xem distinctUntilChanged để tìm hiểu thêm về hàm flow trong Kotlin.
Vô hiệu hoá trạng thái trong gói thuê bao đặc điểm
Giao diện TraitStateInvalidation cung cấp khả năng vô hiệu hoá trạng thái được truy xuất thông qua gói thuê bao cho thiết bị mục tiêu trong trường hợp trạng thái không được báo cáo chính xác.
Ví dụ về trường hợp trạng thái có thể không được báo cáo chính xác bao gồm việc sử dụng các thuộc tính trong đặc điểm Matter có chất lượng "C" hoặc do việc triển khai thiết bị gây ra vấn đề ngoài dự kiến.
API này đưa ra lệnh đọc bắt buộc đối với trạng thái đặc điểm hiện tại và trả về kết quả thông qua các luồng đặc điểm hiện có.
Lấy đặc điểm, sau đó chạy forceRead trên đặc điểm đó:
val onOffTrait = device.?type(DimmableLightDevice)?.map{it.trait(OnOff)}.first()
onOffTrait.forceRead()
Lấy danh sách các đặc điểm của loại thiết bị
Bạn nên sử dụng các loại thiết bị làm điểm truy cập để đọc các đặc điểm, vì các loại thiết bị này phân tách một thiết bị thành các phần chức năng (như các điểm cuối trong Matter).
Các loại thiết bị này cũng tính đến xung đột đặc điểm trong trường hợp một thiết bị có hai loại thiết bị, cả hai loại thiết bị này đều có thể có cùng một đặc điểm. Ví dụ: nếu một thiết bị vừa là Loa vừa là Đèn điều chỉnh độ sáng, thì thiết bị đó sẽ có hai đặc điểm Bật/Tắt và hai đặc điểm Điều khiển mức độ.
Cách lấy danh sách các đặc điểm có sẵn cho loại thiết bị Đèn có thể điều chỉnh độ sáng:
// 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()
Một loại xung đột đặc điểm khác có thể xảy ra khi một thiết bị có hai đặc điểm có cùng tên. Ví dụ: onOff có thể tham chiếu đến một thực thể của đặc điểm OnOff tiêu chuẩn hoặc có thể tham chiếu đến một thực thể của đặc điểm OnOff do nhà sản xuất xác định. Để loại bỏ mọi sự mơ hồ có thể xảy ra về đặc điểm dự kiến, một thực thể Trait được tham chiếu thông qua một thiết bị phải đứng trước một không gian tên đủ điều kiện. Đối với các đặc điểm tiêu chuẩn, tức là những đặc điểm tương tự như các cụm tiêu chuẩn Matter, hãy sử dụng standardTraits. Đối với các đặc điểm của Google, hãy sử dụng googleTraits:
// Accessing standard traits on the type. val onOffTrait: OnOff? = dimmableLightDevice.standardTraits.onOff val levelControlTrait: LevelControl? = dimmableLightDevice.standardTraits.levelControl
Để truy cập vào một đặc điểm dành riêng cho nhà sản xuất, hãy tham chiếu trực tiếp đến đặc điểm đó:
// Accessing a custom trait on the type. val customTrait = dimmableLightDevice.trait(MyCustomTrait)
Lấy danh sách thiết bị có một đặc điểm cụ thể
Bạn có thể dùng hàm filter trong Kotlin để tinh chỉnh thêm các lệnh gọi API. Ví dụ: để lấy danh sách các thiết bị trong nhà đều có đặc điểm Bật/Tắt:
// Get all devices that support OnOff val onOffDevices: Flow<List<HomeDevice>> = home.devices().map { devices -> devices.filter { it.has(OnOff) } }
Hãy xem giao diện Trait để biết danh sách đầy đủ các đặc điểm có trong các API cho Home.
Lấy danh sách các thiết bị có loại thiết bị tương tự
Cách lấy danh sách các thiết bị đại diện cho tất cả đèn trong nhà:
// 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) } }
Có nhiều loại thiết bị trong các API cho Home có thể đại diện cho một loại thiết bị chính. Ví dụ: không có loại thiết bị "Đèn". Thay vào đó, có 4 loại thiết bị khác nhau có thể đại diện cho một đèn, như trong ví dụ trước. Do đó, để có được thông tin toàn diện về loại thiết bị cấp cao hơn trong nhà, bạn phải đưa nhiều loại thiết bị vào các luồng đã lọc.
Hãy xem giao diện DeviceType để biết danh sách đầy đủ các loại thiết bị có trong các API cho Home.
Lấy Mã nhà cung cấp hoặc Mã sản phẩm cho một thiết bị
Đặc điểm BasicInformation bao gồm thông tin như Mã nhà cung cấp, Mã sản phẩm, Tên sản phẩm và Số sê-ri của thiết bị:
// 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}")
Nhận dạng thiết bị từ đám mây đến đám mây cho nhà sản xuất thiết bị
Nếu bạn là nhà sản xuất thiết bị và chế tạo thiết bị Cloud-to-cloud,
để xác định
thiết bị Cloud-to-cloud thông qua
đặc điểm BasicInformation, bạn có thể đưa các trường chuỗi này vào
phản hồi SYNC của thiết bị:
Mã nhà cung cấp do Connectivity Standards Alliance (Alliance) cấp:
"matterOriginalVendorId": "0xfff1",Mã nhận dạng sản phẩm giúp xác định duy nhất một sản phẩm của nhà cung cấp:
"matterOriginalProductId": "0x1234",Giá trị nhận dạng riêng biệt của thiết bị, được tạo theo cách thức riêng của nhà sản xuất:
"matterUniqueId": "matter-device-id",
Khi nhập các trường chuỗi này, hãy sử dụng Matter
Mã nhà cung cấp và mã sản phẩm nếu bạn có. Nếu bạn không phải là thành viên của Alliance và chưa được chỉ định các mã nhận dạng này, bạn có thể để trống các trường matterOriginalVendorId và matterOriginalProductId, đồng thời cung cấp matterUniqueId làm giá trị nhận dạng.
Ví dụ về phản hồi SYNC cho thấy cách sử dụng các trường này:
{
"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",
}
]
}
]
}
}
Để biết thêm thông tin, hãy xem
tài liệu về Cloud-to-cloud SYNC.
Siêu dữ liệu về thiết bị và đặc điểm
Các thiết bị và đặc điểm trong các API cho Home có siêu dữ liệu liên kết với chúng, có thể giúp quản lý trải nghiệm người dùng trong một ứng dụng.
Mỗi đặc điểm trong các API cho Home đều chứa một thuộc tính sourceConnectivity, trong đó có thông tin về trạng thái trực tuyến và vị trí của một đặc điểm (định tuyến cục bộ hoặc từ xa).
Lấy loại chính của thiết bị
Một số thiết bị có thể hiển thị nhiều loại thiết bị thông qua các API cho Home. Để đảm bảo người dùng được cung cấp các lựa chọn phù hợp trong một ứng dụng (chẳng hạn như chế độ điều khiển thiết bị và các quy trình tự động hoá được đề xuất) cho thiết bị của họ, bạn nên kiểm tra xem loại thiết bị chính của một thiết bị là gì.
Trước tiên, hãy lấy(các) loại thiết bị bằng cách sử dụng type(), sau đó xác định(các) loại chính:
val types = device.types().first() val primaryTypes = types.filter { it.metadata.isPrimaryType }
Kiểm tra xem một đặc điểm có đang trực tuyến hay không
Sử dụng phương thức connectivityState() để kiểm tra khả năng kết nối của một đặc điểm:
val onOffConnectivity = onOffTrait?.metadata?.sourceConnectivity?.connectivityState
Một số đặc điểm, thường là các đặc điểm của Google smart home, có thể hiển thị ngoại tuyến nếu thiết bị không có kết nối Internet. Điều này là do các đặc điểm này dựa trên đám mây và không có định tuyến cục bộ.
Kiểm tra khả năng kết nối của thiết bị
Khả năng kết nối của một thiết bị thực sự được kiểm tra ở cấp loại thiết bị vì một số thiết bị hỗ trợ nhiều loại thiết bị. Trạng thái được trả về là sự kết hợp của các trạng thái kết nối cho tất cả các đặc điểm trên thiết bị đó.
val lightConnectivity = dimmableLightDevice.metadata.sourceConnectivity.connectivityState
Bạn có thể thấy trạng thái PARTIALLY_ONLINE trong trường hợp có nhiều loại thiết bị khi không có kết nối Internet.
Matter đặc điểm tiêu chuẩn vẫn có thể hoạt động do định tuyến cục bộ, nhưng các đặc điểm dựa trên đám mây sẽ không hoạt động.
Lấy địa chỉ IP của thiết bị
Để tìm địa chỉ IP của thiết bị, hãy sử dụng thuộc tính networkInterfaces của đặc điểm GeneralDiagnostics. Địa chỉ được trả về dưới dạng mảng byte mà bạn có thể định dạng thành chuỗi IPv4 hoặc IPv6 chuẩn:
val ipAddresses =
trait.networkInterfaces?.flatMap { networkInterface ->
(networkInterface.ipv4Addresses + networkInterface.ipv6Addresses).mapNotNull { bytes ->
try {
java.net.InetAddress.getByAddress(bytes).hostAddress
} catch (e: java.net.UnknownHostException) {
null
}
}
} ?: emptyList()
Kiểm tra định tuyến mạng của một đặc điểm
Vị trí của một đặc điểm cũng có trong các API cho Home. dataSourceLocality cho biết liệu đặc điểm này được định tuyến từ xa (thông qua đám mây), cục bộ (thông qua trung tâm cục bộ) hay ngang hàng (trực tiếp từ thiết bị đến thiết bị, không có trung tâm).
Giá trị vị trí không xác định UNSPECIFIED có thể xảy ra, chẳng hạn như khi một ứng dụng đang khởi động và chưa kết nối được với trung tâm hoặc máy chủ để kết nối thiết bị. Các thiết bị này không kết nối được và sẽ không thực hiện được yêu cầu tương tác từ các lệnh hoặc sự kiện. Ứng dụng khách sẽ quyết định cách xử lý các thiết bị như vậy.
val onOffLocality = onOffTrait?.metadata?.sourceConnectivity?.dataSourceLocality
Kiểm tra định tuyến mạng cho thiết bị
Tương tự như khả năng kết nối, tính cục bộ được kiểm tra ở cấp loại thiết bị. Trạng thái được trả về là sự kết hợp của vị trí cho tất cả các đặc điểm trên thiết bị đó.
val lightLocality = dimmableLightDevice.metadata.sourceConnectivity.dataSourceLocality
Bạn có thể quan sát thấy trạng thái MIXED trong một trường hợp tương tự như trường hợp kết nối PARTIALLY_ONLINE: một số đặc điểm dựa trên đám mây trong khi một số đặc điểm khác là cục bộ.
Thay đổi tên thiết bị
Gọi phương thức setName() để thay đổi tên của một thiết bị:
mixerDevice.setName("Grendel")
Tên sẽ bị cắt bớt nếu vượt quá giới hạn 60 điểm mã Unicode (ký tự) và không có lỗi nào được gửi. Nhà phát triển chịu trách nhiệm xử lý tên dài và có thể quyết định xem họ có muốn thông báo cho người dùng rằng tên sẽ bị cắt bớt hay không.
Kiểm tra tư cách thành viên nhóm của một thiết bị
Một thiết bị thực có thể thuộc về một hoặc nhiều nhóm thiết bị. Để xem một thiết bị thuộc nhóm nào, hãy kiểm tra đặc điểm GroupMembership trên thiết bị:
val groupIds = device.trait(GroupMembershipTrait)?.groupObjectIds.orEmpty()
for (groupId in groupIds) {
println("HomeAPI", "Device belongs to group: $groupId")
}
Ngược lại, bạn có thể quan sát tất cả thiết bị thành viên thuộc một DeviceGroup bằng cách gọi quy trình devices() trên một DeviceGroup:
group.devices(enableMultipartDevices = true).collect { members ->
println("HomeAPI", "Group contains ${members.size} devices")
}
Để kiểm tra các loại thiết bị được DeviceGroup hỗ trợ và gửi lệnh đến nhóm dưới dạng một thực thể, hãy xem phần Điều khiển nhóm thiết bị.