1. บทนำ
โปรแกรมการเข้าถึงอุปกรณ์มี Smart Device Management API ซึ่งเป็น REST API สำหรับนักพัฒนาซอฟต์แวร์ในการควบคุมอุปกรณ์ Google Nest จากแอปพลิเคชันของตน ผู้ใช้ต้องให้ความยินยอมเพื่อให้บุคคลที่สามเข้าถึงอุปกรณ์ Nest ของตนได้

ขั้นตอนสำคัญ 3 ขั้นตอนในการผสานรวม Device Access ให้สำเร็จมีดังนี้
- การสร้างโปรเจ็กต์ - สร้างโปรเจ็กต์ใน Google Cloud Platform และลงชื่อสมัครใช้เป็นนักพัฒนาแอปใน Device Access Console
- การลิงก์บัญชี - ดึงดูดผู้ใช้ผ่านขั้นตอนการลิงก์บัญชีและเรียกข้อมูลรหัสการเข้าถึง แลกรหัสเป็นโทเค็นเพื่อการเข้าถึง
- การควบคุมอุปกรณ์ - ส่งคำขอ Smart Device Management API เพื่อควบคุมอุปกรณ์โดยการส่งคำสั่งพร้อมโทเค็นการเข้าถึง
ใน Codelab นี้ เราจะเจาะลึกวิธีการทำงานของการเข้าถึงอุปกรณ์โดยการสร้างเว็บแอปพลิเคชันที่จัดการการตรวจสอบสิทธิ์และทำการเรียก Smart Device Management API นอกจากนี้ เราจะมาดูการติดตั้งใช้งานพร็อกซีเซิร์ฟเวอร์อย่างง่ายโดยใช้ Node.js และ Express เพื่อกำหนดเส้นทางการเข้าถึงอุปกรณ์
ก่อนที่จะเริ่ม เราขอแนะนำให้คุณทบทวนเทคโนโลยีเว็บทั่วไปที่เราจะใช้ใน Codelab นี้ เช่น การตรวจสอบสิทธิ์ด้วย OAuth 2.0 หรือการสร้างเว็บแอปด้วย Node.js แม้ว่าสิ่งเหล่านี้จะไม่ใช่ข้อกำหนดเบื้องต้นก็ตาม
สิ่งที่คุณต้องมี
- Node.js 8 ขึ้นไป
- บัญชี Google ที่ลิงก์กับ Nest Thermostat
สิ่งที่คุณจะได้เรียนรู้
- การตั้งค่าโปรเจ็กต์ Firebase ที่โฮสต์หน้าเว็บแบบคงที่และ Cloud Functions
- ส่งคำขอสิทธิ์เข้าถึงอุปกรณ์ผ่านเว็บแอปพลิเคชันที่ใช้เบราว์เซอร์
- การสร้างพร็อกซีเซิร์ฟเวอร์ด้วย Node.js และ Express เพื่อกำหนดเส้นทางคำขอ
2. การสร้างโปรเจ็กต์
นักพัฒนาแอปต้องสร้างโปรเจ็กต์ Google Cloud Platform (GCP) เพื่อตั้งค่าการผสานรวมการเข้าถึงอุปกรณ์ ระบบจะใช้รหัสไคลเอ็นต์และรหัสลับไคลเอ็นต์ที่สร้างขึ้นภายในโปรเจ็กต์ GCP เป็นส่วนหนึ่งของโฟลว์ OAuth ระหว่างแอปพลิเคชันของนักพัฒนาแอปกับ Google Cloud นอกจากนี้ นักพัฒนาแอปยังต้องไปที่ Device Access Console เพื่อสร้างโปรเจ็กต์เพื่อเข้าถึง Smart Device Management API ด้วย
Google Cloud Platform
ไปที่ Google Cloud Platform คลิกสร้างโปรเจ็กต์ใหม่ แล้วระบุชื่อโปรเจ็กต์ ระบบจะแสดงรหัสโปรเจ็กต์ [GCP-Project-Id] สำหรับ Google Cloud ด้วย โปรดบันทึกรหัสนี้ไว้เนื่องจากเราจะใช้รหัสนี้ในระหว่างการตั้งค่า Firebase (เราจะเรียก ID นี้ว่า [GCP-Project-Id] ตลอดทั้ง Codelab นี้)

ขั้นตอนแรกคือการเปิดใช้ไลบรารี API ที่จำเป็นในโปรเจ็กต์ ไปที่ API และบริการ > คลัง แล้วค้นหา Smart Device Management API คุณต้องเปิดใช้ API นี้เพื่อให้สิทธิ์โปรเจ็กต์ของคุณในการส่งคำขอไปยังการเรียก Device Access API

ก่อนที่จะไปสร้างข้อมูลเข้าสู่ระบบ OAuth เราต้องกำหนดค่าหน้าจอคำยินยอม OAuth สำหรับโปรเจ็กต์ของเรา ไปที่ API และบริการ > หน้าจอขอความยินยอม OAuth เลือกภายนอกสำหรับประเภทผู้ใช้ ระบุชื่อและอีเมลสนับสนุนสำหรับแอป รวมถึงข้อมูลติดต่อของนักพัฒนาแอปเพื่อกรอกข้อมูลในหน้าจอแรกให้เสร็จสมบูรณ์ เมื่อระบบขอให้ระบุผู้ใช้ทดสอบ โปรดระบุอีเมลที่มีอุปกรณ์ที่ลิงก์ไว้ในขั้นตอนนี้
เมื่อกำหนดค่าหน้าจอขอความยินยอม OAuth แล้ว ให้ไปที่ API และบริการ > ข้อมูลเข้าสู่ระบบ คลิก +สร้างข้อมูลเข้าสู่ระบบ แล้วเลือกรหัสไคลเอ็นต์ OAuth เลือกเว็บแอปพลิเคชันเป็นประเภทแอปพลิเคชัน

ตั้งชื่อไคลเอ็นต์ แล้วคลิกสร้าง เราจะเพิ่มต้นทาง JavaScript ที่ได้รับอนุญาตและ URI การเปลี่ยนเส้นทางที่ได้รับอนุญาตในภายหลัง การทำกระบวนการนี้ให้เสร็จสมบูรณ์จะแสดง [Client-Id] และ [Client-Secret] ที่เชื่อมโยงกับไคลเอ็นต์ OAuth 2.0 นี้

คอนโซลการเข้าถึงอุปกรณ์
ไปที่คอนโซลการเข้าถึงอุปกรณ์ หากไม่เคยใช้คอนโซลการเข้าถึงอุปกรณ์มาก่อน คุณจะเห็นข้อตกลงในข้อกำหนดในการให้บริการและค่าธรรมเนียมการลงทะเบียน 5 ดอลลาร์สหรัฐ
สร้างโปรเจ็กต์ใหม่และตั้งชื่อโปรเจ็กต์ ในหน้าต่างถัดไป ให้ระบุ [Client-Id] ที่คุณได้รับจาก GCP ในขั้นตอนก่อนหน้า

การเปิดใช้เหตุการณ์และการทำขั้นตอนการสร้างโปรเจ็กต์ให้เสร็จสมบูรณ์จะนำคุณไปยังหน้าแรกของโปรเจ็กต์ [Project-Id] จะแสดงอยู่ใต้ชื่อที่คุณตั้งให้กับโปรเจ็กต์

โปรดจด [Project-Id] ไว้ เนื่องจากเราจะใช้รหัสดังกล่าวเมื่อส่งคำขอไปยัง Smart Device Management API
3. การตั้งค่า Firebase
Firebase ช่วยให้นักพัฒนาแอปสามารถทำให้เว็บแอปพลิเคชันใช้งานได้ง่ายและรวดเร็ว เราจะพัฒนาเว็บแอปพลิเคชันฝั่งไคลเอ็นต์สำหรับการผสานรวมการเข้าถึงอุปกรณ์โดยใช้ Firebase
สร้างโปรเจ็กต์ Firebase
ไปที่ Firebase Console คลิกเพิ่มโปรเจ็กต์ แล้วเลือกโปรเจ็กต์ที่คุณสร้างในขั้นตอนการสร้างโปรเจ็กต์ ซึ่งจะเป็นการสร้างโปรเจ็กต์ Firebase ที่จะลิงก์กับโปรเจ็กต์ GCP [GCP-Project-Id]
เมื่อสร้างโปรเจ็กต์ Firebase สำเร็จแล้ว คุณควรเห็นหน้าจอดังต่อไปนี้

ติดตั้งเครื่องมือ Firebase
Firebase มีชุดเครื่องมือ CLI สำหรับสร้างและทำให้แอปใช้งานได้ หากต้องการติดตั้งเครื่องมือเหล่านี้ ให้เปิดหน้าต่างเทอร์มินัลใหม่แล้วเรียกใช้คำสั่งต่อไปนี้ การดำเนินการนี้จะติดตั้งเครื่องมือ Firebase ทั่วโลก
$ npm i -g firebase-tools
หากต้องการยืนยันว่าติดตั้งเครื่องมือ Firebase อย่างถูกต้อง ให้ตรวจสอบข้อมูลเวอร์ชัน
$ firebase --version
คุณเข้าสู่ระบบเครื่องมือ Firebase CLI ด้วยบัญชี Google ได้โดยใช้คำสั่งเข้าสู่ระบบ
$ firebase login
เริ่มต้นโปรเจ็กต์ Hosting
เมื่อเข้าสู่ระบบได้แล้ว ขั้นตอนถัดไปคือการเริ่มต้นโปรเจ็กต์โฮสติ้งสำหรับเว็บแอปพลิเคชัน จากเทอร์มินัล ให้ไปที่โฟลเดอร์ที่คุณต้องการสร้างโปรเจ็กต์ แล้วเรียกใช้คำสั่งต่อไปนี้
$ firebase init hosting
Firebase จะถามคำถามชุดหนึ่งเพื่อช่วยให้คุณเริ่มต้นใช้งานโปรเจ็กต์โฮสติ้งได้
- โปรดเลือกตัวเลือก ใช้โปรเจ็กต์ที่มีอยู่
- เลือกโปรเจ็กต์ Firebase เริ่มต้นสำหรับไดเรกทอรีนี้ - เลือก ***[GCP-Project-Id]***
- คุณต้องการใช้ไดเรกทอรีสาธารณะใด — สาธารณะ
- กำหนดค่าเป็นแอปหน้าเว็บเดียวไหม — ใช่
- ตั้งค่าการบิลด์และการติดตั้งใช้งานอัตโนมัติด้วย GitHub — ไม่
เมื่อเริ่มต้นโปรเจ็กต์แล้ว คุณจะสามารถนำไปใช้งานกับ Firebase ได้ด้วยคำสั่งต่อไปนี้
$ firebase deploy
Firebase จะสแกนโปรเจ็กต์และติดตั้งไฟล์ที่จำเป็นไปยังโฮสติ้งระบบคลาวด์

เมื่อเปิด URL การโฮสต์ในเบราว์เซอร์ คุณควรเห็นหน้าเว็บที่เพิ่งติดตั้งใช้งาน

ตอนนี้คุณทราบข้อมูลเบื้องต้นเกี่ยวกับวิธีทําให้หน้าเว็บใช้งานได้ด้วย Firebase แล้ว มาทําให้ตัวอย่าง Codelab ใช้งานได้กันเลย
4. ตัวอย่าง Codelab
คุณสามารถโคลนที่เก็บ Codelab ที่โฮสต์ใน GitHub ได้โดยใช้คำสั่งด้านล่าง
$ git clone https://github.com/google/device-access-codelab-web-app.git
ในที่เก็บนี้ เราจะจัดเตรียมตัวอย่างไว้ใน 2 โฟลเดอร์แยกกัน โฟลเดอร์ codelab-start มีไฟล์ที่จำเป็นเพื่อให้คุณเริ่มต้นจากจุดปัจจุบันใน Codelab นี้ codelab-done มี Codelab เวอร์ชันสมบูรณ์พร้อมไคลเอ็นต์และเซิร์ฟเวอร์ node.js ที่ทำงานได้อย่างเต็มรูปแบบ
เราจะใช้ไฟล์จากโฟลเดอร์ codelab-start ตลอดทั้งโค้ดแล็บนี้ แต่หากคุณรู้สึกว่าติดขัดเมื่อใดก็ตาม โปรดดูเวอร์ชันที่ทำเสร็จแล้วของโค้ดแล็บด้วย
ไฟล์ตัวอย่าง Codelab
โครงสร้างไฟล์ของโฟลเดอร์ codelab-start มีดังนี้
public ├───index.html ├───scripts.js ├───style.css firebase.json
โฟลเดอร์สาธารณะมีหน้าแบบคงที่ของแอปพลิเคชัน firebase.json มีหน้าที่กำหนดเส้นทางคำขอเว็บไปยังแอปของเรา ในเวอร์ชัน codelab-done คุณจะเห็นไดเรกทอรี functions ซึ่งมีตรรกะสำหรับพร็อกซีเซิร์ฟเวอร์ (express) ของเราที่จะนำไปใช้ในฟังก์ชัน Google Cloud
ติดตั้งใช้งานตัวอย่าง Codelab
คัดลอกไฟล์จาก codelab-start ไปยังไดเรกทอรีของโปรเจ็กต์
$ firebase deploy
เมื่อ Firebase ทำให้ใช้งานได้เรียบร้อยแล้ว คุณควรจะเห็นแอปพลิเคชัน Codelab ดังนี้

การเริ่มโฟลว์การให้สิทธิ์ต้องใช้ข้อมูลเข้าสู่ระบบของพาร์ทเนอร์ ซึ่งเราจะกล่าวถึงในส่วนถัดไป
5. การจัดการ OAuth
OAuth เป็นมาตรฐานเว็บสำหรับการมอบสิทธิ์เข้าถึง ซึ่งโดยทั่วไปจะใช้เพื่อให้ผู้ใช้ให้สิทธิ์แอปพลิเคชันของบุคคลที่สามเข้าถึงข้อมูลบัญชีของตนได้โดยไม่ต้องแชร์รหัสผ่าน เราใช้ OAuth 2.0 เพื่อให้สิทธิ์นักพัฒนาแอปในการเข้าถึงอุปกรณ์ของผู้ใช้ผ่าน Device Access

ระบุ URI การเปลี่ยนเส้นทาง
ขั้นตอนแรกของขั้นตอน OAuth เกี่ยวข้องกับการส่งชุดพารามิเตอร์ไปยังปลายทาง Google OAuth 2.0 หลังจากได้รับความยินยอมจากผู้ใช้แล้ว เซิร์ฟเวอร์ Google OAuth จะออกคำขอพร้อมรหัสการให้สิทธิ์ไปยัง URI การเปลี่ยนเส้นทางของคุณ
อัปเดตค่าคงที่ SERVER_URI (บรรทัดที่ 19) ด้วย URL ของโฮสติ้งของคุณเองใน scripts.js
const SERVER_URI = "https://[GCP-Project-Id].web.app";
การติดตั้งแอปใหม่โดยมีการเปลี่ยนแปลงนี้จะอัปเดต URI การเปลี่ยนเส้นทางที่ใช้สำหรับโปรเจ็กต์
$ firebase deploy
เปิดใช้ URI การเปลี่ยนเส้นทาง
เมื่ออัปเดต URI การเปลี่ยนเส้นทางในไฟล์สคริปต์แล้ว คุณต้องเพิ่ม URI การเปลี่ยนเส้นทางดังกล่าวลงในรายการ URI การเปลี่ยนเส้นทางที่อนุญาตสำหรับรหัสไคลเอ็นต์ที่คุณสร้างขึ้นสำหรับโปรเจ็กต์ด้วย ไปที่หน้าข้อมูลเข้าสู่ระบบใน Google Cloud Platform ซึ่งจะแสดงข้อมูลเข้าสู่ระบบทั้งหมดที่สร้างขึ้นสำหรับโปรเจ็กต์ของคุณ

ในส่วนรายการรหัสไคลเอ็นต์ OAuth 2.0 ให้เลือกรหัสไคลเอ็นต์ที่คุณสร้างในขั้นตอนการสร้างโปรเจ็กต์ เพิ่ม URI การเปลี่ยนเส้นทางของแอปไปยังรายการ URI การเปลี่ยนเส้นทางที่ได้รับอนุญาตสำหรับโปรเจ็กต์

ลองลงชื่อเข้าใช้
ไปที่ URL ของโฮสติ้งที่คุณตั้งค่าด้วย Firebase ป้อนข้อมูลเข้าสู่ระบบของพาร์ทเนอร์ แล้วคลิกปุ่มลงชื่อเข้าใช้ รหัสไคลเอ็นต์และข้อมูลลับไคลเอ็นต์คือข้อมูลเข้าสู่ระบบที่คุณได้รับจาก Google Cloud Platform ส่วนรหัสโปรเจ็กต์มาจาก Device Access Console

ปุ่มลงชื่อเข้าใช้จะนำผู้ใช้ผ่านขั้นตอน OAuth สำหรับองค์กร โดยเริ่มจากหน้าจอเข้าสู่ระบบไปยังบัญชี Google เมื่อเข้าสู่ระบบแล้ว ระบบจะขอให้ผู้ใช้ให้สิทธิ์โปรเจ็กต์ของคุณในการเข้าถึงอุปกรณ์ Nest ของผู้ใช้

เนื่องจากนี่เป็นแอปจำลอง Google จะออกคำเตือนก่อนที่จะเปลี่ยนเส้นทาง

คลิก "ขั้นสูง" แล้วเลือก "ไปที่ web.app (ไม่ปลอดภัย)" เพื่อเปลี่ยนเส้นทางไปยังแอปให้เสร็จสมบูรณ์

ซึ่งจะให้รหัส OAuth เป็นส่วนหนึ่งของคำขอ GET ขาเข้า จากนั้นแอปจะแลกรหัสดังกล่าวเป็นโทเค็นเพื่อการเข้าถึงและโทเค็นการรีเฟรช
6. ควบคุมอุปกรณ์
แอปตัวอย่างการเข้าถึงอุปกรณ์ใช้การเรียก REST API การจัดการอุปกรณ์อัจฉริยะเพื่อควบคุมอุปกรณ์ Google Nest การเรียกเหล่านี้เกี่ยวข้องกับการส่งโทเค็นเพื่อการเข้าถึงในส่วนหัวของคำขอ GET หรือ POST พร้อมกับเพย์โหลดที่จำเป็นสำหรับคำสั่งบางอย่าง
เราได้เขียนฟังก์ชันคำขอเข้าถึงทั่วไปเพื่อจัดการการเรียกเหล่านี้ อย่างไรก็ตาม คุณจะต้องระบุปลายทางที่ถูกต้อง รวมถึงออบเจ็กต์เพย์โหลดเมื่อจำเป็น ให้กับฟังก์ชันนี้
function deviceAccessRequest(method, call, localpath, payload = null) {...}
- method - ประเภทคำขอ HTTP (
GETหรือPOST) - call - สตริงที่แสดงการเรียก API ของเรา ซึ่งใช้ในการกำหนดเส้นทางการตอบกลับ (
listDevices,thermostatMode,temperatureSetpoint) - localpath - ปลายทางที่ส่งคำขอ ซึ่งมีรหัสโปรเจ็กต์และรหัสอุปกรณ์ (ต่อท้าย
https://smartdevicemanagement.googleapis.com/v1) - payload (*) - ข้อมูลเพิ่มเติมที่จำเป็นสำหรับการเรียก API (เช่น ค่าตัวเลขที่แสดงอุณหภูมิสำหรับจุดตั้งค่า)
เราจะสร้างตัวควบคุม UI ตัวอย่าง (List Devices, Set Mode, Set Temp) เพื่อควบคุม Nest Thermostat ดังนี้

การควบคุม UI เหล่านี้จะเรียกฟังก์ชันที่เกี่ยวข้อง (listDevices(), postThermostatMode(), postTemperatureSetpoint()) จาก scripts.js โดยเราจะเว้นว่างไว้เพื่อให้คุณนำไปใช้ได้ เป้าหมายคือการเลือกวิธีการ/เส้นทางที่ถูกต้องและส่งเพย์โหลดไปยังฟังก์ชัน deviceAccessRequest(...)
แสดงรายการอุปกรณ์
การเรียกใช้ Device Access ที่ง่ายที่สุดคือ listDevices โดยใช้คำขอ GET และไม่จำเป็นต้องมีเพย์โหลด ต้องจัดโครงสร้างปลายทางโดยใช้ projectId เขียนฟังก์ชัน listDevices() ให้เสร็จสมบูรณ์ดังนี้
function listDevices() {
var endpoint = "/enterprises/" + projectId + "/devices";
deviceAccessRequest('GET', 'listDevices', endpoint);
}
บันทึกการเปลี่ยนแปลงและติดตั้งใช้งานโปรเจ็กต์ Firebase อีกครั้งด้วยคำสั่งต่อไปนี้
$ firebase deploy
เมื่อติดตั้งใช้งานแอปเวอร์ชันใหม่แล้ว ให้ลองโหลดหน้าเว็บซ้ำ แล้วคลิกแสดงอุปกรณ์ ซึ่งควรจะแสดงรายการในส่วนการควบคุมอุปกรณ์ และคุณควรเห็นรหัสของตัวควบคุมอุณหภูมิ

การเลือกอุปกรณ์จากรายการจะอัปเดตฟิลด์ deviceId ในไฟล์ scripts.js สำหรับการควบคุม 2 รายการถัดไป เราจะต้องระบุ deviceId สำหรับอุปกรณ์ที่ต้องการควบคุม
การควบคุมตัวควบคุมอุณหภูมิ
Smart Device Management API มีลักษณะ 2 อย่างสำหรับการควบคุมพื้นฐานของตัวควบคุมอุณหภูมิ Nest ThermostatMode และ TemperatureSetpoint ThermostatMode จะตั้งค่าโหมดสำหรับตัวควบคุมอุณหภูมิ Nest เป็นหนึ่งใน 4 โหมดที่เป็นไปได้ ได้แก่ {Off, Heat, Cool, HeatCool} จากนั้นเราต้องระบุโหมดที่เลือกเป็นส่วนหนึ่งของเพย์โหลด
แทนที่ฟังก์ชัน postThermostatMode() ใน scripts.js ด้วยฟังก์ชันต่อไปนี้
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);
}
ฟังก์ชันถัดไป postTemperatureSetpoint() จะจัดการการตั้งค่าอุณหภูมิ (เป็นเซลเซียส) สำหรับ Nest Thermostat มีพารามิเตอร์ 2 รายการที่ตั้งค่าได้ในเพย์โหลด ได้แก่ heatCelsius และ coolCelsius โดยขึ้นอยู่กับโหมดตัวควบคุมอุณหภูมิที่เลือก
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. เซิร์ฟเวอร์ Node.js (ไม่บังคับ)
ยินดีด้วย คุณได้สร้างเว็บแอปพลิเคชันฝั่งไคลเอ็นต์ที่สามารถส่งคำขอ Smart Device Management API จากเบราว์เซอร์ได้ สำหรับผู้ที่ต้องการสร้างในฝั่งเซิร์ฟเวอร์ เราต้องการช่วยให้คุณเริ่มต้นได้อย่างรวดเร็วด้วยพร็อกซีเซิร์ฟเวอร์ที่เปลี่ยนเส้นทางคำขอจากเบราว์เซอร์ได้
สำหรับพร็อกซีเซิร์ฟเวอร์นี้ เราจะใช้ฟังก์ชัน Cloud ของ Firebase, Node.js และ Express
เริ่มต้น Cloud Functions
เปิดหน้าต่างเทอร์มินัลใหม่ ไปที่ไดเรกทอรีโปรเจ็กต์ แล้วเรียกใช้คำสั่งต่อไปนี้
$ firebase init functions
Firebase จะถามคำถามชุดหนึ่งเพื่อเริ่มต้น Cloud Functions ดังนี้
- คุณต้องการใช้ภาษาใดในการเขียน Cloud Functions — JavaScript
- คุณต้องการใช้ ESLint เพื่อตรวจหาข้อบกพร่องที่อาจเกิดขึ้นและบังคับใช้รูปแบบไหม — ไม่
- คุณต้องการติดตั้งการอ้างอิงด้วย npm ตอนนี้ไหม — ใช่
การดำเนินการนี้จะเริ่มต้นโฟลเดอร์ functions ในโปรเจ็กต์ของคุณ รวมถึงติดตั้งการอ้างอิงที่จำเป็น คุณจะเห็นว่าโฟลเดอร์โปรเจ็กต์มีไดเรกทอรีฟังก์ชันที่มีไฟล์ index.js เพื่อกำหนดฟังก์ชันระบบคลาวด์ package.json เพื่อกำหนดการตั้งค่า และไดเรกทอรี node_modules เพื่อเก็บทรัพยากร Dependency
เราจะใช้ไลบรารี 2 รายการ ได้แก่ express และ xmlhttprequest เพื่อสร้างฟังก์ชันการทำงานฝั่งเซิร์ฟเวอร์npm คุณจะต้องเพิ่มรายการต่อไปนี้ลงในรายการทรัพยากร Dependency ในไฟล์ package.json
"xmlhttprequest": "^1.8.0", "express": "^4.17.0"
จากนั้นการเรียกใช้ npm install จากไดเรกทอรีฟังก์ชันควรติดตั้งทรัพยากร Dependency สำหรับโปรเจ็กต์ของคุณ
$ npm install
ในกรณีที่ npm พบปัญหาในการดาวน์โหลดแพ็กเกจ คุณสามารถลองบันทึก xmlhttprequest และ express อย่างชัดเจนด้วยคำสั่งต่อไปนี้
$ npm install express xmlhttprequest --save
อัปเกรดเป็นแพ็กเกจ Blaze
การใช้คำสั่ง firebase deploy จะกำหนดให้คุณต้องอัปเกรดเป็นแพ็กเกจ Blaze ซึ่งกำหนดให้คุณต้องเพิ่มวิธีการชำระเงินลงในบัญชี ไปที่ภาพรวมของโปรเจ็กต์ > การใช้งานและการเรียกเก็บเงิน แล้วตรวจสอบว่าได้เลือกแพ็กเกจ Blaze สำหรับโปรเจ็กต์แล้ว

สร้างเซิร์ฟเวอร์ Express
เซิร์ฟเวอร์ Express ใช้เฟรมเวิร์กที่เรียบง่ายเพื่อตอบสนองต่อคำขอ GET และ POST ที่เข้ามา เราได้สร้างเซอร์วิลิตที่รอรับคำขอ POST ส่งคำขอไปยัง URL ปลายทางที่ระบุในเพย์โหลด และตอบกลับด้วยการตอบกลับที่ได้รับจากการโอน
แก้ไขไฟล์ index.js ในไดเรกทอรีฟังก์ชันให้มีลักษณะดังนี้
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);
ในการกำหนดเส้นทางคำขอไปยังเซิร์ฟเวอร์ เราต้องปรับการเขียนใหม่จาก firebase.json ดังนี้
{
"hosting": {
"public": "public",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [{
"source": "/proxy**",
"function": "app"
},{
"source": "**",
"destination": "/index.html"
}
]
}
}
ซึ่งจะกำหนดเส้นทาง URL ที่ขึ้นต้นด้วย /proxy ไปยังเซิร์ฟเวอร์ Express ของเรา และ URL ที่เหลือจะยังคงไปที่ index.html ของเรา
การเรียก API ของพร็อกซี
เมื่อเซิร์ฟเวอร์พร้อมแล้ว ให้กำหนด URI ของพร็อกซีใน scripts.js เพื่อให้เบราว์เซอร์ส่งคำขอไปยังที่อยู่นี้
const PROXY_URI = SERVER_URI + "/proxy";
จากนั้นเพิ่มฟังก์ชัน proxyRequest function is scripts.js ซึ่งมีลายเซ็นเดียวกับฟังก์ชัน deviceAccessRequest(...) สำหรับการเรียกใช้การเข้าถึงอุปกรณ์โดยอ้อม
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();
}
ขั้นตอนสุดท้ายคือการแทนที่การเรียกใช้ deviceAccessRequest(...) ด้วยฟังก์ชัน proxyRequest(...) ในฟังก์ชัน postThermostatMode() และ postTemperatureSetpoint() ภายใน scripts.js
เรียกใช้ firebase deploy เพื่ออัปเดตแอป
$ firebase deploy
ตอนนี้คุณมีพร็อกซีเซิร์ฟเวอร์ Node.js ที่ทำงานโดยใช้ Express ใน Cloud Functions แล้ว
ให้สิทธิ์ Cloud Functions
ขั้นตอนสุดท้ายคือการตรวจสอบสิทธิ์การเข้าถึงสำหรับ Cloud Functions และตรวจสอบว่าแอปพลิเคชันฝั่งไคลเอ็นต์จะเรียกใช้ฟังก์ชันเหล่านั้นได้
จาก Google Cloud Platform ให้ไปที่แท็บ Cloud Functions จากเมนู แล้วเลือกฟังก์ชันระบบคลาวด์

คลิกสิทธิ์ แล้วคลิกเพิ่มสมาชิก เขียน allUsers ลงในช่องสมาชิกใหม่ แล้วเลือกฟังก์ชันระบบคลาวด์ > ผู้เรียกใช้ฟังก์ชันระบบคลาวด์เป็นบทบาท การคลิกบันทึกจะแสดงข้อความเตือนต่อไปนี้

การเลือก "อนุญาตการเข้าถึงแบบสาธารณะ" จะทำให้แอปพลิเคชันฝั่งไคลเอ็นต์ใช้ Cloud Function ได้
ขอแสดงความยินดี คุณทำตามขั้นตอนทั้งหมดเรียบร้อยแล้ว ตอนนี้คุณสามารถไปที่เว็บแอปและลองใช้การควบคุมอุปกรณ์ที่กำหนดเส้นทางผ่านพร็อกซีเซิร์ฟเวอร์ได้แล้ว
ขั้นตอนถัดไป
หากกำลังมองหาวิธีขยายความเชี่ยวชาญด้านการเข้าถึงอุปกรณ์ ดูข้อมูลเพิ่มเติมเกี่ยวกับการควบคุมอุปกรณ์ Nest อื่นๆ ได้ในเอกสารประกอบเกี่ยวกับลักษณะ และดูขั้นตอนการเปิดตัวผลิตภัณฑ์สู่โลกได้ในกระบวนการรับรอง
พัฒนาทักษะของคุณให้ดียิ่งขึ้นด้วยแอปตัวอย่างเว็บแอปพลิเคชัน Device Access ซึ่งคุณจะได้ต่อยอดจากประสบการณ์ Codelab และทำให้เว็บแอปพลิเคชันที่ใช้งานได้ควบคุมกล้อง กริ่งประตู และตัวควบคุมอุณหภูมิ Nest