Google Home Device Integration into Mobile IoT App
Google Home SDK became publicly available in 2023 after years of closed beta. Before that only path — Google Home API via REST, limiting control and requiring OAuth per user via Google account. Now two paths: Google Home SDK for Android (native integration) and Device Access API (REST/gRPC, works with Android and iOS).
Device Access API: REST Integration for iOS and Flutter
Device Access works with Nest devices (thermostats, cameras, doorbell cameras). Authorization via OAuth 2.0, after which app gets access to Structures, Rooms and Devices:
GET https://smartdevicemanagement.googleapis.com/v1/enterprises/{projectId}/devices
Authorization: Bearer {access_token}
Response contains device list with traits. Nest Learning 3rd gen thermostat returns:
{
"name": "enterprises/project-id/devices/device-id",
"type": "sdm.devices.types.THERMOSTAT",
"traits": {
"sdm.devices.traits.ThermostatMode": {
"mode": "HEAT",
"availableModes": ["HEAT", "COOL", "HEATCOOL", "OFF"]
},
"sdm.devices.traits.ThermostatTemperatureSetpoint": {
"heatCelsius": 21.5
},
"sdm.devices.traits.Temperature": {
"ambientTemperatureCelsius": 19.8
}
}
}
Control — via ExecuteCommand:
// iOS, Alamofire
func setThermostatMode(_ mode: String, deviceName: String) async throws {
let url = "https://smartdevicemanagement.googleapis.com/v1/\(deviceName):executeCommand"
let body: [String: Any] = [
"command": "sdm.devices.commands.ThermostatMode.SetMode",
"params": ["mode": mode]
]
_ = try await AF.request(url, method: .post, parameters: body,
encoding: JSONEncoding.default,
headers: authHeaders)
.serializingDecodable(CommandResponse.self)
.value
}
Authorization via Google Sign-In SDK with scope https://www.googleapis.com/auth/sdm.service. Store refresh token in Keychain — DeviceAccess tokens live 1 hour.
Android: Google Home SDK
Android Google Home SDK provides native ecosystem access, including Matter devices:
// build.gradle.kts
implementation("com.google.home:google-home-sdk:1.1.0")
Initialization:
val homeClient = HomeManager.getHomeClient(context)
homeClient.getHomes()
.flowOn(Dispatchers.IO)
.collect { homes ->
homes.forEach { home ->
home.devices().collect { devices ->
devices.forEach { device ->
processDevice(device)
}
}
}
}
Interesting SDK feature — reactive model based on Kotlin Flow. Device state is Flow, automatically emits new values on change:
suspend fun observeThermostat(device: HomeDevice) {
device.trait(ThermostatMode)
?.changes()
?.collect { mode ->
updateUI(mode.mode)
}
}
Execute commands via same trait objects:
val thermostatTrait = device.trait(ThermostatMode) ?: return
thermostatTrait.setMode(ThermostatMode.Mode.COOL)
Nest Cameras: WebRTC Streaming
Camera Access trait returns rtspUrl or WebRTC offer, depending on camera model. New Nest Cam (2021+) work only via WebRTC:
val cameraLiveStream = device.trait(CameraLiveStream)
val streamResponse = cameraLiveStream?.generateWebRtcStream(
offerSdp = localPeerConnection.localDescription?.description ?: ""
)
// Pass streamResponse.answerSdp to RTCPeerConnection
peerConnection.setRemoteDescription(
RTCSessionDescription(RTCSessionDescription.Type.ANSWER, streamResponse.answerSdp)
)
Common mistake: don't update stream token. WebRTC session lives 5 minutes, then Nest closes connection. Need background timer calling extendWebRtcStream() 30 seconds before expiry.
Ecosystem Limitations
Device Access API requires Google approval for each project — submit request via console, response 1-5 business days. Fee: $5 project registration. Cameras don't work in Device Access without Nest Aware subscription on user account — must explicitly mention in UX.
Google Home SDK Android still Developer Preview in 2024, API may change. For production solutions with cameras, Device Access API more reliable.
Integration timeline: Device Access API for iOS — 2-3 weeks; Android Google Home SDK with Matter — 3-4 weeks; Flutter with both — 5-6 weeks. Cost calculated individually after analyzing requirements.







