Membuat Aplikasi Web Akses Perangkat

1. Pengantar

Program Akses Perangkat menyediakan Smart Device Management API, sebuah REST API bagi developer untuk mengontrol perangkat Google Nest dari aplikasi mereka. Pengguna harus memberikan izin agar pihak ketiga dapat mengakses perangkat Nest-nya.

52f77aa38cda13a6.png

Ada tiga langkah utama untuk keberhasilan integrasi Akses Perangkat:

  1. Pembuatan Project - Membuat project di Google Cloud Platform dan mendaftar sebagai developer di Konsol Akses Perangkat.
  2. Penautan Akun - Mendapatkan pengguna melalui alur penautan akun dan ambil kode akses. Tukarkan kode ini dengan token akses.
  3. Kontrol Perangkat - Membuat permintaan Smart Device Management API untuk mengontrol perangkat dengan mengirim perintah menggunakan token akses.

Dalam Codelab ini, kita akan membahas cara kerja Akses Perangkat dengan membuat aplikasi web yang menangani autentikasi dan membuat panggilan Smart Device Management API. Kita juga akan menjelajahi cara men-deploy server proxy sederhana menggunakan Node.js dan Express untuk mengirimkan permintaan Akses Perangkat.

Sebelum memulai, akan lebih baik jika Anda mempelajari teknologi web umum yang akan kami gunakan di Codelab ini, seperti mengautentikasi dengan OAuth 2.0 atau membuat aplikasi web dengan Node.js, meskipun bukan prasyarat.

Yang Akan Anda Perlukan

  • Node.js 8 atau yang lebih baru
  • Akun Google dengan Nest Thermostat yang terhubung

Yang Akan Anda Pelajari

  • Menyiapkan project Firebase yang menghosting halaman web statis dan cloud functions
  • Mengajukan permintaan akses perangkat melalui aplikasi web berbasis browser
  • Membuat server proxy dengan Node.js dan Express untuk mengirimkan permintaan Anda

2. Pembuatan Project

Developer perlu membuat project Google Cloud Platform (GCP) untuk menyiapkan integrasi Akses Perangkat. Client ID dan Client Secret yang dibuat dalam project GCP akan digunakan sebagai bagian dari alur OAuth antara aplikasi developer dan Google Cloud. Developer juga perlu mengunjungi Konsol Akses Perangkat untuk membuat project guna mengakses Smart Device Management API.

Google Cloud Platform

Buka Google Cloud Platform. Klik buat project baru dan berikan nama project. Project ID [GCP-Project-Id] untuk Google Cloud juga akan ditampilkan, harap catat karena kami akan menggunakannya selama penyiapan Firebase. (Kami menyebut ID ini sebagai [GCP-Project-Id] di seluruh Codelab ini.)

585e926b21994ac9.png

Langkah pertama adalah mengaktifkan Library API yang diperlukan pada project kita. Buka APIs & Services > Library, lalu telusuri Smart Device Management API. Anda harus mengaktifkan API ini untuk memberi otorisasi project guna membuat permintaan ke panggilan API Akses Perangkat.

14e7eabc422c7fda.png

Sebelum melanjutkan untuk membuat kredensial OAuth, kita perlu mengonfigurasi layar persetujuan OAuth untuk project kita. Buka APIs & Services > OAuth consent screen. Untuk User Type, pilih external. Berikan nama dan email dukungan untuk aplikasi Anda, serta informasi kontak developer untuk menyelesaikan layar pertama. Saat dimintai Test Users, pastikan untuk memberikan alamat email dengan perangkat yang tertaut pada langkah ini.

Setelah Anda mengonfigurasi layar persetujuan OAuth, buka APIs & Services > Credentials. Klik +Create Credentials, lalu pilih OAuth client ID. Untuk jenis aplikasi, pilih Web application.

5de534212d44fce7.png

Berikan nama untuk klien Anda dan klik CREATE. Kita akan menambahkan asal JavaScript yang Diotorisasi dan URI Pengalihan yang Diotorisasi nanti. Menyelesaikan proses ini akan memunculkan [Client-Id] dan [Client-Secret] yang terkait dengan Klien OAuth 2.0 ini.

e6a670da18952f08.png

Konsol Akses Perangkat

Buka Konsol Akses Perangkat. Jika belum pernah menggunakan Konsol Akses Perangkat sebelumnya, Anda akan disambut dengan perjanjian Persyaratan Layanan, dan biaya pendaftaran sebesar $5.

Buat project baru, lalu beri nama project. Di jendela berikutnya, berikan [Client-Id] yang Anda terima dari GCP pada langkah sebelumnya.

f8a3f27354bc2625.png

Mengaktifkan peristiwa dan menyelesaikan langkah-langkah pembuatan project akan mengarahkan Anda ke halaman beranda project. [Project-Id] Anda akan dicantumkan dengan nama yang telah Anda berikan pada project.

db7ba33d8b707148.png

Harap perhatikan [Project-Id] Anda karena kita akan menggunakannya saat mengirim permintaan ke Smart Device Management API.

3. Penyiapan Firebase

Firebase memberikan cara yang cepat dan mudah bagi developer untuk men-deploy aplikasi web. Kita akan mengembangkan aplikasi web sisi klien untuk integrasi Akses Perangkat menggunakan Firebase.

Membuat Project Firebase

Buka Firebase Console. Klik Add Project, lalu pilih project yang telah Anda buat di langkah Pembuatan Project. Hal ini akan membuat project Firebase, yang akan ditautkan ke project GCP [GCP-Project-Id] Anda.

Setelah project Firebase berhasil dibuat, Anda akan melihat layar berikut:

dbb02bbacac093f5.png

Menginstal Alat Firebase

Firebase menyediakan serangkaian alat CLI untuk membuat dan men-deploy aplikasi Anda. Untuk menginstal alat ini, buka jendela terminal baru dan jalankan perintah berikut. Tindakan ini akan menginstal alat Firebase secara global.

$ npm i -g firebase-tools

Untuk memastikan bahwa alat firebase sudah diinstal dengan benar, periksa info versi.

$ firebase --version

Anda dapat login ke alat Firebase CLI menggunakan Akun Google dengan perintah login.

$ firebase login

Melakukan Inisialisasi Project Hosting

Setelah Anda berhasil login, langkah selanjutnya adalah melakukan inisialisasi project hosting untuk aplikasi web Anda. Dari terminal, buka folder tempat Anda ingin membuat project dan jalankan perintah berikut:

$ firebase init hosting

Firebase akan mengajukan serangkaian pertanyaan untuk membantu Anda memulai project hosting:

  1. Pilih salah satu opsi — Gunakan project yang ada
  2. Pilih project Firebase default untuk direktori ini — Pilih ***[GCP-Project-Id]***
  3. Apa yang ingin Anda gunakan sebagai direktori publik? — Publik
  4. Konfigurasikan sebagai aplikasi halaman tunggal? — Ya
  5. Siapkan build dan deployment otomatis dengan GitHub? — Tidak

Setelah project diinisialisasi, Anda dapat men-deploy ke firebase dengan perintah berikut:

$ firebase deploy

Firebase akan memindai project Anda dan men-deploy file yang diperlukan ke hosting cloud.

fe15cf75e985e9a1.png

Saat membuka URL Hosting di browser, Anda akan melihat halaman yang baru saja di-deploy:

e40871238c22ebe2.png

Setelah Anda mengetahui dasar-dasar tentang cara men-deploy halaman web dengan Firebase, mari kita mulai men-deploy contoh Codelab.

4. Contoh Codelab

Anda dapat meng-clone repositori codelab yang di-hosting di GitHub, menggunakan perintah berikut:

$ git clone https://github.com/google/device-access-codelab-web-app.git

Dalam repositori ini, kami menyediakan contoh dalam dua folder terpisah. Folder codelab-start memiliki file yang diperlukan untuk membantu Anda memulai dari titik saat ini di Codelab ini. Folder codelab-done berisi versi lengkap Codelab ini, dengan klien yang berfungsi penuh dan server node.js.

Kami akan menggunakan file dari folder codelab-start di seluruh codelab ini, kapan pun Anda merasa ada hambatan, Anda juga dapat merujuk ke versi yang telah diselesaikan dengan codelab.

File Sampel Codelab

Struktur file folder codelab-start adalah sebagai berikut:

public
├───index.html
├───scripts.js
├───style.css
firebase.json

Folder publik berisi halaman statis aplikasi. firebase.json bertanggung jawab memilihkan rute permintaan web ke aplikasi kami. Pada versi codelab-done, Anda juga akan melihat direktori functions, yang berisi logika untuk server proxy kami (express) untuk di-deploy di fungsi Google Cloud.

Men-deploy Sampel Codelab

Salin file dari codelab-start ke direktori project Anda.

$ firebase deploy

Setelah Firebase selesai men-deploy, Anda akan dapat melihat aplikasi Codelab:

e84c1049eb4cca92.png

Memulai alur autentikasi memerlukan kredensial partner, yang akan kita bahas di bagian berikutnya.

5. Menangani OAuth

OAuth adalah standar web untuk delegasi akses, yang biasanya digunakan oleh pengguna untuk memberikan akses ke informasi akun kepada aplikasi pihak ketiga tanpa berbagi sandi. Kami menggunakan OAuth 2.0 untuk memungkinkan developer mengakses perangkat pengguna melalui Akses Perangkat.

7ee31f5d9c37f699.png

Menentukan URI Pengalihan

Langkah pertama alur OAuth melibatkan penerusan serangkaian parameter ke endpoint Google OAuth 2.0. Setelah mendapatkan izin pengguna, server Google OAuth akan mengirimkan permintaan dengan kode otorisasi ke URI Pengalihan Anda.

Perbarui konstanta SERVER_URI (baris 19) dengan URL Hosting Anda di scripts.js:

const SERVER_URI = "https://[GCP-Project-Id].web.app";

Men-deploy ulang aplikasi dengan perubahan ini akan memperbarui URI Pengalihan yang digunakan untuk project Anda.

$ firebase deploy

Mengaktifkan URI Pengalihan

Setelah mengupdate URI Pengalihan dalam file skrip, Anda juga harus menambahkannya ke daftar URI Pengalihan yang diizinkan untuk Client ID yang telah Anda buat untuk project Anda. Buka Credentials Page di Google Cloud Platform, yang akan mencantumkan semua kredensial yang dibuat untuk project Anda:

1a07b624b5e548da.png

Di bagian daftar Client ID OAuth 2.0, pilih Client ID yang telah Anda buat pada langkah Pembuatan Project. Tambahkan URI pengalihan aplikasi ke daftar Authorized Redirect URIs untuk project Anda.

6d65b298e1f005e2.png

Coba Login.

Buka URL Hosting yang disiapkan dengan Firebase, masukkan kredensial partner, lalu klik tombol SIGN IN. Client ID dan Rahasia Klien adalah kredensial yang Anda peroleh dari Google Cloud Platform, Project ID berasal dari Konsol Akses Perangkat.

78b48906a2dd7c05.png

Tombol SIGN IN akan mengarahkan pengguna melalui alur OAuth untuk perusahaan Anda, dimulai dengan layar login ke Akun Google mereka. Setelah login, pengguna akan diminta untuk memberikan izin bagi project Anda untuk mengakses perangkat Nest.

e9b7887c4ca420.png

Karena ini adalah aplikasi tiruan, Google akan mengeluarkan peringatan sebelum mengeluarkan pengalihan!

b227d510cb1df073.png

Klik "Advanced", lalu pilih "Buka web.app (tidak aman)" untuk menyelesaikan pengalihan ke aplikasi Anda.

673a4fd217e24dad.png

Tindakan ini akan menyediakan Kode OAuth sebagai bagian dari permintaan GET yang masuk, yang kemudian akan ditukarkan untuk Token Akses dan Token Refresh.

6. Kontrol Perangkat

Aplikasi sampel Akses Perangkat menggunakan panggilan REST API Smart Device Management untuk mengontrol perangkat Google Nest. Panggilan ini melibatkan penerusan token akses di header permintaan GET atau POST, di samping payload yang diperlukan untuk perintah tertentu.

Kami menulis fungsi permintaan akses umum untuk menangani panggilan ini. Namun, Anda harus menyediakan endpoint yang benar, serta objek payload jika diperlukan, untuk fungsi ini.

function deviceAccessRequest(method, call, localpath, payload = null) {...}
  • metode — Jenis permintaan HTTP (GET atau POST)
  • call — String yang mewakili panggilan API kami, digunakan untuk mengirimkan rute respons (listDevices, thermostatMode, temperatureSetpoint)
  • localpath — Endpoint yang dibuat permintaan, berisi Project ID dan ID Perangkat (ditambahkan setelah https://smartdevicemanagement.googleapis.com/v1)
  • payload (*) — Data tambahan yang diperlukan untuk panggilan API (misalnya, nilai numerik yang mewakili suhu untuk titik penyetelan)

Kita akan membuat contoh kontrol UI (List Device, Set Mode, Set Temp) untuk mengontrol Nest Thermostat:

86f8a193aa397421.png

Kontrol UI ini akan memanggil fungsi yang sesuai (listDevices(), postThermostatMode(), postTemperatureSetpoint()) dari scripts.js. UI tersebut dibiarkan kosong untuk diterapkan. Tujuannya adalah memilih metode/jalur yang benar dan meneruskan payload ke fungsi deviceAccessRequest(...).

Mencantumkan Perangkat

Panggilan Akses Perangkat yang paling sederhana adalah listDevices. Metode ini menggunakan permintaan GET dan tidak memerlukan payload. Endpoint harus disusun menggunakan projectId. Selesaikan fungsi listDevices() Anda sebagai berikut:

function listDevices() {
  var endpoint = "/enterprises/" + projectId + "/devices";
  deviceAccessRequest('GET', 'listDevices', endpoint);
}

Simpan perubahan dan deploy project Firebase Anda lagi dengan perintah berikut:

$ firebase deploy

Setelah versi baru aplikasi di-deploy, coba muat ulang halaman dan klik LIST DEVICES. Tindakan ini akan mengisi daftar pada Kontrol Perangkat, yang ID termostat-nya harus Anda lihat:

b64a198673ed289f.png

Memilih perangkat dari daftar akan memperbarui kolom deviceId di file scripts.js. Untuk dua kontrol berikutnya, kita perlu menentukan deviceId untuk perangkat tertentu yang ingin kita kontrol.

Mengontrol Termostat

Ada dua ciri untuk kontrol dasar Nest Thermostat di Smart Device Management API. ThermostatMode dan TemperatureSetpoint. ThermostatMode menyetel mode untuk Nest Thermostat Anda ke salah satu dari empat kemungkinan mode yang berbeda: {Off, Heat, Keren, Cool, HeatCool}. Selanjutnya, kita perlu menyediakan mode yang dipilih sebagai bagian dari payload.

Ganti fungsi postThermostatMode() di scripts.js dengan yang berikut:

function postThermostatMode() {
  var endpoint = "/enterprises/" + projectId + "/devices/" + deviceId + ":executeCommand";
  var tempMode = id("tempMode").value;
  var payload = {
    "command": "sdm.devices.commands.ThermostatMode.SetMode",
    "params": {
      "mode": tempMode
    }
  };
  deviceAccessRequest('POST', 'thermostatMode', endpoint, payload);
}

Fungsi berikutnya, postTemperatureSetpoint(), menangani penyetelan suhu (dalam Celsius) untuk Nest Thermostat Anda. Ada dua parameter yang dapat disetel dalam payload, heatCelsius dan coolCelsius, bergantung pada mode termostat yang dipilih.

function postTemperatureSetpoint() {
  var endpoint = "/enterprises/" + projectId + "/devices/" + deviceId + ":executeCommand";
  var heatCelsius = parseFloat(id("heatCelsius").value);
  var coolCelsius = parseFloat(id("coolCelsius").value);

  var payload = {
    "command": "",
    "params": {}
  };
  
  if ("HEAT" === id("tempMode").value) {
    payload.command = "sdm.devices.commands.ThermostatTemperatureSetpoint.SetHeat";
    payload.params["heatCelsius"] = heatCelsius;
  }
  else if ("COOL" === id("tempMode").value) {
    payload.command = "sdm.devices.commands.ThermostatTemperatureSetpoint.SetCool";
    payload.params["coolCelsius"] = coolCelsius;
  }
  else if ("HEATCOOL" === id("tempMode").value) {
    payload.command = "sdm.devices.commands.ThermostatTemperatureSetpoint.SetRange";
    payload.params["heatCelsius"] = heatCelsius;
    payload.params["coolCelsius"] = coolCelsius;
  } else {
    console.log("Off and Eco mode don't allow this function");
    return;
  }
  deviceAccessRequest('POST', 'temperatureSetpoint', endpoint, payload);
}

7. Server Node.js (Opsional)

Selamat! Anda telah membuat aplikasi web sisi klien yang dapat membuat permintaan Smart Device Management API dari browser. Bagi Anda yang ingin membangun di sisi server, kami ingin memulai upaya Anda dengan server proxy yang dapat mengalihkan permintaan Anda dari browser.

Untuk server proxy ini, kita akan menggunakan fungsi cloud Firebase, Node.js dan Express.

Melakukan Inisialisasi Cloud Functions

Buka jendela terminal baru, buka direktori project Anda dan jalankan perintah berikut:

$ firebase init functions

Firebase akan mengajukan serangkaian pertanyaan untuk melakukan inisialisasi cloud functions:

  1. Bahasa apa yang ingin Anda gunakan untuk menulis Cloud Functions? — JavaScript
  2. Apakah Anda ingin menggunakan ESLint untuk menangkap kemungkinan bug dan menerapkan gaya? — Tidak
  3. Apakah Anda ingin menginstal dependensi dengan npm sekarang? — Ya

Tindakan ini akan melakukan inisialisasi folder functions dalam project Anda, serta menginstal dependensi yang diperlukan. Anda akan melihat bahwa folder project berisi direktori fungsi, dengan file index.js untuk menentukan cloud function, package.json untuk menentukan setelan dan direktori node_modules untuk menampung dependensi.

Kita akan menggunakan dua library npm untuk membuat fungsionalitas sisi server: express dan xmlhttprequest. Anda perlu menambahkan entri berikut ke daftar dependensi dalam file package.json:

"xmlhttprequest": "^1.8.0",
"express": "^4.17.0"

Selanjutnya, menjalankan instal npm dari direktori fungsi akan menginstal dependensi untuk project Anda:

$ npm install

Jika npm mengalami masalah saat mendownload paket, Anda dapat mencoba menyimpan xmlhttprequest dan mengekspresikannya secara eksplisit dengan perintah berikut:

$ npm install express xmlhttprequest --save

Mengupgrade ke Paket Blaze

Untuk menggunakan perintah firebase deploy, Anda harus mengupgrade ke paket Blaze yang mengharuskan Anda menambahkan metode pembayaran ke akun Anda. Buka Project Overview > Usage and billing dan pastikan untuk memilih paket Blaze untuk project Anda.

c6a5e5a21397bef6.png

Membuat Server Express

Server express mengikuti framework sederhana untuk merespons permintaan GET dan POST yang masuk. Kami telah membuat servlet yang memproses permintaan POST, mengirimkannya ke URL tujuan yang ditentukan dalam payload, dan menanggapi dengan respons yang diterima dari transfer.

Ubah file index.js Anda di direktori fungsi agar terlihat seperti ini:

const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const functions = require('firebase-functions');
const express = require('express');
const http = require('http');

const app = express();
app.use(express.json());


//***** Device Access - Proxy Server *****//

// Serving Get Requests (Not used) 
app.get('*', (request, response) => {
  response.status(200).send("Hello World!");
});
// Serving Post Requests
app.post('*', (request, response) => {
  
  setTimeout(() => {
    // Read the destination address from payload:
    var destination = request.body.address;
    
    // Create a new proxy post request:
    var xhr = new XMLHttpRequest();
    xhr.open('POST', destination);
    
    // Add original headers to proxy request:
    for (var key in request.headers) {
            var value = request.headers[key];
      xhr.setRequestHeader(key, value);
    }
    
    // Add command/parameters to proxy request:
    var newBody = {};
    newBody.command = request.body.command;
    newBody.params = request.body.params;
    
    // Respond to original request with the response coming
    // back from proxy request (to Device Access Endpoint)
    xhr.onload = function () {
      response.status(200).send(xhr.responseText);
    };
    
    // Send the proxy request!
    xhr.send(JSON.stringify(newBody));
  }, 1000);
});

// Export our app to firebase functions:
exports.app = functions.https.onRequest(app);

Untuk mengarahkan permintaan ke server, kami perlu menyesuaikan penulisan ulang dari firebase.json sebagai berikut:

{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [{
        "source": "/proxy**",
        "function": "app"
      },{
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

Ini akan mengarahkan rute URL yang dimulai dengan /proxy ke server Express kami, dan sisanya akan berlanjut ke index.html kami.

Panggilan API Proxy

Karena sekarang server kita sudah siap, mari tentukan URI proxy di scripts.js agar browser dapat mengirim permintaan ke alamat ini:

const PROXY_URI = SERVER_URI + "/proxy";

Kemudian, tambahkan fungsi proxyRequest yaitu scripts.js, yang memiliki tanda tangan yang sama dengan fungsi deviceAccessRequest(...), untuk panggilan Akses Perangkat tidak langsung.

function proxyRequest(method, call, localpath, payload = null) {
    var xhr = new XMLHttpRequest();
    
    // We are doing our post request to our proxy server:
    xhr.open(method, PROXY_URI);
    xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
    xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
    xhr.onload = function () {
      // Response is passed to deviceAccessResponse function:
      deviceAccessResponse(call, xhr.response);
    };
    
    // We are passing the device access endpoint in address field of the payload:
    payload.address = "https://smartdevicemanagement.googleapis.com/v1" + localpath;
    if ('POST' === method && payload)
        xhr.send(JSON.stringify(payload));
    else
        xhr.send();
}

Langkah terakhir adalah mengganti panggilan deviceAccessRequest(...) dengan fungsi proxyRequest(...), di fungsi postThermostatMode() dan postTemperatureSetpoint() dalam scripts.js.

Jalankan firebase deploy untuk mengupdate aplikasi.

$ firebase deploy

Dengan ini, Anda sekarang memiliki server proxy Node.js yang berjalan menggunakan Express di Cloud Functions.

Memberikan Izin Cloud Function

Langkah terakhir adalah meninjau izin akses untuk fungsi cloud Anda dan memastikan bahwa aplikasi sisi klien Anda dapat memanggil izin tersebut.

Dari Google Cloud Platform, buka tab Cloud Functions dari menu, lalu pilih cloud function Anda:

461e9bae74227fc1.png

Klik Permissions, lalu Add Member. Tulis allUsers di kolom anggota baru, lalu pilih Cloud Functions > Cloud Functions Invoker sebagai peran. Mengklik Save akan menampilkan pesan peringatan:

3adb01644217578c.png

Memilih Allow Public Access akan membuat aplikasi sisi klien Anda dapat menggunakan fungsi cloud.

Selamat – Anda telah menyelesaikan semua langkahnya. Sekarang Anda dapat membuka aplikasi web dan memberikan kontrol perangkat yang diarahkan melalui server proxy.

Langkah Berikutnya

Mencari cara untuk mengembangkan keahlian Anda di Akses Perangkat? Lihat dokumentasi ciri untuk mengetahui lebih lanjut tentang cara mengontrol perangkat Nest lainnya, dan proses sertifikasi untuk mempelajari langkah-langkah dalam meluncurkan produk Anda ke seluruh dunia.

Tingkatkan keterampilan Anda dengan aplikasi contoh aplikasi web Akses Perangkat. Di sini, Anda akan mengembangkan pengalaman Codelab dan men-deploy aplikasi web yang berfungsi untuk mengontrol kamera, bel pintu, dan termostat Nest.