Home Automation with
Android Things and the
Google Assistant
Android is everywhere
Google Assistant Shoebox Robot(01)
(01)
http://nilhcem.com/android-things/create-your-google-assistant-robots
In your Home?
OK Google,
Philips Hue Bridge
https://developers.google.com/actions/
OAuth2 server
Device Actions
• SYNC
• EXECUTE
• QUERY
SYNC Request:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"inputs": [{
"intent": "action.devices.SYNC"
}]
}
SYNC Response:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"devices": [{
"id": "1",
"type": "action.devices.types.LIGHT",
"traits": [
"action.devices.traits.OnOff",
"action.devices.traits.ColorSpectrum"
],
"name": {
"name": "Lightbulb"
},
"willReportState": true
}]
}
}
Device types:
Camera Refrigerator
Dishwasher Switch
Dryer Thermostat
Light Vacuum
Outlet Washer
Device traits:
Brightness OnOff
CameraStream RunCycle
ColorSpectrum Scene
ColorTemperature StartStop
Dock TemperatureSetting
Modes Toggles
"Ok Google,
"
Smart Home Device Traits(03)
(03)
https://developers.google.com/actions/smarthome/traits/
https://cloud.google.com/functions/?hl=ja
exports.ha = function(req, res) {
if (!isAuthTokenValid(req)) return;
let intent = req.body.inputs[0].intent;
switch (intent) {
case 'action.devices.SYNC':
sync(req, res);
break;
case 'action.devices.EXECUTE':
execute(req, res);
break;
case 'action.devices.QUERY':
query(req, res);
break;
}
};
function sync(req, res) {
res.status(200).json({
requestId: req.body.requestId,
payload: {
devices: [{
id: 'lightbulb',
type: 'action.devices.types.LIGHT',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.ColorSpectrum'
],
name: {
name: 'Lightbulb'
},
willReportState: true
}]
}
});
}
$ gcloud beta functions deploy ha --trigger-http
https://us-central1-your-id.cloudfunctions.net/ha
Device Actions
• SYNC
• EXECUTE
• QUERY
EXECUTE Request:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"inputs": [{
"intent": "action.devices.EXECUTE",
"payload": {
"commands": [{
"devices": [{
"id": "lightbulb"
}],
"execution": [{
"command": "action.devices.commands.OnOff",
"params": {
"on": true
}
}]
}]
}
}]
}
EXECUTE Response:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"commands": [{
"ids": ["lightbulb"],
"status": "SUCCESS",
}]
}
}
Device Actions
• SYNC
• EXECUTE
• QUERY
QUERY Request:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"inputs": [{
"intent": "action.devices.QUERY",
"payload": {
"devices": [{
"id": "lightbulb"
}]
}
}]
}
QUERY Response:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"devices": {
"lightbulb": {
"on": false,
"online": true,
"color": {
"spectrumRGB": 16777215
}
}
}
}
}
Raspberry Pi 3
FirestoreLiveData.kt
class FirestoreLiveData : LiveData<Device>() {
override fun onActive() {
authenticateWithFirebase { user ->
listenForFirestoreChanges("users/${user.uid}/devices") { change ->
postValue(change)
}
}
}
}
const admin = require('firebase-admin');
admin.initializeApp({
credential: admin.credential.applicationDefault()
});
var db = admin.firestore();
var docRef = db.doc(`users/${userId}/devices/lightbulb`);
docRef.set({ on: true, spectrumRGB: 255 });
Lightbulbs
Bluetooth lightbulbs
Reverse engineering
Bluetooth Low Energy devices(04)
(04)
http://nilhcem.com/iot/reverse-engineering-simple-bluetooth-devices
Capture Bluetooth packets
$ adb pull /sdcard/Android/data/btsnoop_hci.log
• Value: 56RRGGBB00f0aa
• Characteristic: ffe9
• Service: ffe5
Android Things app
Converting a color to a ByteArray
private fun colorToByteArray(color: Int): ByteArray {
val red = Color.red(color)
val green = Color.green(color)
val blue = Color.blue(color)
return byteArrayOf(0x56, red, green, blue, 0x00, 0xf0, 0xaa)
}
Send the color data to the lightbulb
private fun writeCharacteristic(gatt: BluetoothGatt, color: Int) {
val service = gatt.getService(SERVICE_UUID) // 0xFFE5
val characteristic = service.getCharacteristic(CHARACTERISTIC_UUID) // 0xFFE9
characteristic.value = colorToByteArray(color)
gatt.writeCharacteristic(characteristic)
}
MainActivity.kt
firestoreLiveData.observe({ lifecycle }) { device ->
when (device) {
is Lightbulb -> lightbulb.updateState(device)
}
}
Update Firestore
Fan + Relay module
Android Things GPIO API
viewModel.firestoreLiveData.observe({ lifecycle }) { device ->
when (device) {
is Lightbulb -> lightbulb.onStateChanged(device)
is Fan -> relay.value = device.isOn
}
}
Radio-controlled Power Outlets
Radio Frequency Emitter / Receiver(05)
(05)
https://github.com/Nilhcem/home-automation-talk-resources/tree/master/radio-power-outlet
Android Things UART API
private fun on() = sendUart('1')
private fun off() = sendUart('0')
private fun sendUart(char: Char) {
uartDevice?.write(byteArrayOf(char.toByte()), 1)
}
private fun openUart() {
uartDevice = PeripheralManagerService().openUartDevice(UART_NAME).apply {
setBaudrate(9600)
setDataSize(8)
setParity(UartDevice.PARITY_NONE)
setStopBits(1)
}
}
Infrared blaster
Infrared Receiver (VS1838B)(06)
(06)
https://github.com/Nilhcem/home-automation-talk-resources/tree/master/infrared-lamp/01-arduino_receiver
Infrared Receiver (VS1838B)
Infrared dump
Encoding : UNKNOWN
Code : E318261B (32 bits)
Timing[67]:
+8950, -4550 + 500, - 650 + 500, - 650 + 500, - 650
+ 500, - 650 + 500, - 650 + 500, - 650 + 500, - 650
+ 500, - 650 + 500, -1750 + 500, -1700 + 500, -1800
+ 450, -1750 + 450, -1800 + 450, -1750 + 450, -1750
+ 500, -1750 + 450, -1750 + 500, - 650 + 500, -1750
+ 500, - 650 + 500, - 650 + 500, - 650 + 500, -1750
+ 450, - 700 + 450, - 700 + 450, -1750 + 500, - 700
+ 450, -1750 + 500, -1700 + 500, -1750 + 500, - 650
+ 500, -1750 + 450
unsigned int rawData[67] = {8950,4550, 500,650, 500,650, 500,650, 500,650,
500,650, 500,650, 500,650, 500,650, 500,1750, 500,1700, 500,1800, 450,1750,
450,1800, 450,1750, 450,1750, 500,1750, 450,1750, 500,650, 500,1750, 500,650,
500,650, 500,650, 500,1750, 450,700, 450,700, 450,1750, 500,700, 450,1750,
500,1700, 500,1750, 500,650, 500,1750, 450}; // UNKNOWN E318261B
ESP8266(07)
(07)
https://github.com/Nilhcem/home-automation-talk-resources/tree/master/infrared-lamp/03-
esp8266_transmitter
Retrofit call
@GET("color/{code}")
fun setBulbColor(@Path("code") code: Char): Call<Any>
Takeaway
• Actions on Google for chatbots & smart home apps. For
companies & individuals
• Android Things simplifies building secured & advanced IoT
devices
• Create your own devices, or hack existing ones for
interoperability
• Easier than it seems
Additional information
• Source code for all the projects:
https://github.com/Nilhcem/home-automation-talk-resources
• Home automation with the Google Assistant:
http://nilhcem.com/android-things/google-assistant-smart-home
• Actions on Google Smart Home documentation:
https://developers.google.com/actions/smarthome/
• Reverse engineering BLE devices:
http://nilhcem.com/iot/reverse-engineering-simple-bluetooth-devices
• Reverse engineering IR devices:
http://nilhcem.com/iot/reverse-engineering-ir-rgb-bulb
Home Automation with
Android Things and the
Google Assistant
• Twitter: @Nilhcem

Home Automation with Android Things and the Google Assistant