Tworzenie aplikacji internetowej z dostępem do urządzenia

1. Wstęp

Program dostępu do urządzenia udostępnia interfejs Smart Device Management API, czyli interfejs API typu REST, który umożliwia deweloperom sterowanie urządzeniami Google Nest z poziomu ich aplikacji. Użytkownicy muszą wyrazić zgodę na dostęp innych firm do swoich urządzeń Nest.

52f77aa38cda13a6.png

Skuteczna integracja z dostępem do urządzenia składa się z 3 kluczowych kroków:

  1. Tworzenie projektu – utwórz projekt w Google Cloud Platform i zarejestruj się jako programista w Konsoli dostępu do urządzenia.
  2. Łączenie kont – zachęć użytkowników do łączenia kont i pozyskania kodu dostępu. Wymień kod na token dostępu.
  3. Sterowanie urządzeniami – wysyłaj żądania do interfejsu Smart Device Management API, aby sterować urządzeniami, wysyłając polecenia z tokenem dostępu.

W tym ćwiczeniu z programowania szczegółowo omówimy, jak działa dostęp do urządzenia – utworzymy aplikację internetową, która obsługuje uwierzytelnianie i wywołuje wywołania interfejsu Smart Device Management API. Zamierzamy też wdrożyć prosty serwer proxy wykorzystujący Node.js i Express, aby kierować żądania dostępu do urządzenia.

Zanim zaczniesz, warto przypomnieć sobie popularne technologie internetowe używane w tym ćwiczeniu z programowania, takie jak uwierzytelnianie za pomocą protokołu OAuth 2.0 lub tworzenie aplikacji internetowej za pomocą Node.js. Nie są to jednak wymagania wstępne.

Potrzebne elementy

  • Node.js w wersji 8 lub nowszej
  • Konto Google z połączonym urządzeniem Nest Thermostat

Czego się nauczysz

  • Konfigurowanie projektu Firebase hostującego statyczne strony internetowe i funkcje w Cloud Functions
  • Wydawanie żądań dostępu do urządzenia za pomocą aplikacji internetowej w przeglądarce
  • Tworzenie serwera proxy z użyciem Node.js i Express do kierowania żądań

2. Tworzenie projektu

Aby skonfigurować integrację dostępu do urządzenia, deweloperzy muszą utworzyć projekt Google Cloud Platform (GCP). W ramach procesu OAuth między aplikacją dewelopera a Google Cloud będą używane identyfikatory klienta i klucz klienta wygenerowane w projekcie GCP. Deweloperzy muszą też otworzyć konsolę dostępu urządzenia, aby utworzyć projekt i uzyskać dostęp do interfejsu Smart Device Management API.

Google Cloud Platform

Otwórz Google Cloud Platform. Kliknij Utwórz nowy projekt i podaj jego nazwę. Będzie też widoczny identyfikator projektu [GCP-Project-Id] dla Google Cloud. Zapisz go, ponieważ będziemy go używać podczas konfiguracji Firebase. (W tym ćwiczeniu z programowania będziemy określać ten identyfikator jako [GCP-Project-Id]).

585e926b21994ac9.png

Najpierw włącz niezbędną bibliotekę interfejsów API w projekcie. Kliknij Interfejsy API i usługi > Biblioteka, a następnie wyszukaj interfejs Smart Device Management API. Musisz włączyć ten interfejs API, aby autoryzować swój projekt do wysyłania żądań do wywołań interfejsu Device Access API.

14e7eabc422c7fda.png

Zanim przejdziemy do tworzenia danych logowania OAuth, musimy skonfigurować w naszym projekcie ekran zgody OAuth. Otwórz Interfejsy API i usługi > Ekran zgody OAuth. Jako Typ użytkownika wybierz external. Podaj nazwę i adres e-mail pomocy w sprawie aplikacji, a także informacje kontaktowe dewelopera. Gdy pojawi się pytanie o użytkowników testowych, podaj na tym etapie adresy e-mail połączonych urządzeń.

Gdy skonfigurujesz ekran zgody OAuth, otwórz Interfejsy API i usługi > Dane logowania. Kliknij +Utwórz dane logowania i wybierz Identyfikator klienta OAuth. Jako typ aplikacji wybierz Aplikacja internetowa.

5de534212d44fce7.png

Podaj nazwę klienta i kliknij UTWÓRZ. Później dodamy autoryzowane źródło JavaScript i identyfikator URI autoryzowanego przekierowania. Zakończenie tego procesu spowoduje wyświetlenie identyfikatorów [Client-Id] i [Client-Secret] powiązanych z tym klientem OAuth 2.0.

e6a670da18952f08.png

Konsola dostępu do urządzenia

Otwórz konsolę dostępu do urządzenia. Jeśli wcześniej nie korzystałeś(-aś) z Konsoli dostępu do urządzenia, zobaczysz Warunki korzystania z usługi i opłatę rejestracyjną w wysokości 5 USD.

Utwórz nowy projekt i nadaj mu nazwę. W następnym oknie podaj identyfikator [Client-Id] otrzymany od GCP w poprzednim kroku.

f8a3f27354bc2625.png

Jeśli włączysz zdarzenia i zakończysz tworzenie projektu, otworzy się jego strona główna. Twój [Project-Id] będzie widoczny pod nazwą projektu.

db7ba33d8b707148.png

Zapisz swój [Project-Id], ponieważ będziemy go używać podczas wysyłania żądań do interfejsu Smart Device Management API.

3. Konfiguracja Firebase

Firebase zapewnia programistom szybki i łatwy sposób wdrażania aplikacji internetowych. Będziemy tworzyć za pomocą Firebase aplikację internetową po stronie klienta na potrzeby integracji dostępu do urządzenia.

Utwórz projekt Firebase

Otwórz konsolę Firebase. Kliknij Dodaj projekt i wybierz projekt utworzony w kroku Tworzenie projektu. Spowoduje to utworzenie projektu Firebase, który zostanie połączony z Twoim projektem GCP [GCP-Project-Id].

Po utworzeniu projektu Firebase powinien pojawić się ten ekran:

dbb02bbacac093f5.png

Zainstaluj narzędzia Firebase

Firebase udostępnia zestaw narzędzi interfejsu wiersza poleceń do skompilowania i wdrożenia aplikacji. Aby zainstalować te narzędzia, otwórz nowe okno terminala i uruchom to polecenie. Spowoduje to zainstalowanie narzędzi Firebase na całym świecie.

$ npm i -g firebase-tools

Aby sprawdzić, czy narzędzia Firebase są prawidłowo zainstalowane, sprawdź informacje o wersji.

$ firebase --version

Możesz zalogować się w narzędziach wiersza poleceń Firebase za pomocą konta Google za pomocą polecenia logowania.

$ firebase login

Inicjowanie projektu Hostingu

Gdy możesz się zalogować, następnym krokiem jest zainicjowanie hostowanego projektu dla aplikacji internetowej. W terminalu przejdź do folderu, w którym chcesz utworzyć projekt, i uruchom to polecenie:

$ firebase init hosting

Firebase zada Ci zestaw pytań, aby rozpocząć pracę z hostingiem:

  1. Wybierz opcję – Użyj istniejącego projektu.
  2. Wybierz domyślny projekt Firebase dla tego katalogu – wybierz***[GCP-Project-Id]***
  3. Co ma być Twoim katalogiem publicznym? – Publiczny
  4. Skonfigurować aplikację jako aplikację na jednej stronie? — Tak
  5. Skonfigurować automatyczne kompilacje i wdrożenia za pomocą GitHuba? — Nie

Po zainicjowaniu projektu możesz wdrożyć go w Firebase za pomocą tego polecenia:

$ firebase deploy

Firebase przeskanuje Twój projekt i wdroży niezbędne pliki do hostingu w chmurze.

fe15cf75e985e9a1.png

Gdy otworzysz w przeglądarce adres URL Hostingu, powinna pojawić się wdrożona właśnie strona:

e40871238c22ebe2.png

Znasz już podstawy wdrażania stron internetowych za pomocą Firebase, więc czas wdrożyć nasz przykładowy program Codelabs.

4. Przykładowe ćwiczenia z programowania

Możesz skopiować repozytorium ćwiczeń z programowania hostowane na GitHubie za pomocą tego polecenia:

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

W tym repozytorium przykłady znajdują się w 2 osobnych folderach. Folder codelab-start zawiera pliki potrzebne do rozpoczęcia ćwiczenia od bieżącego punktu ćwiczenia. Folder codelab-done zawiera pełną wersję tego ćwiczenia z programowania oraz w pełni funkcjonalnego klienta i serwera Node.js.

W tym ćwiczeniu z programowania będziemy korzystać z plików z folderu codelab-start, ale jeśli w jakimś momencie napotkasz problemy, możesz też skorzystać z wersji stworzonej z programowania.

Przykładowe pliki ćwiczeń z programowania

Struktura pliku z folderem codelab-start jest taka:

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

Folder publiczny zawiera statyczne strony naszej aplikacji. firebase.json odpowiada za kierowanie żądań internetowych do naszej aplikacji. W wersji codelab-done widoczny jest też katalog functions zawierający logikę wdrażania serwera proxy (ekspresowego) w funkcjach Google Cloud.

Wdrażanie przykładowego ćwiczenia z programowania

Skopiuj pliki z codelab-start do katalogu projektu.

$ firebase deploy

Po wdrożeniu Firebase powinna pojawić się aplikacja Codelab:

e84c1049eb4cca92.png

Aby rozpocząć proces uwierzytelniania, wymagane są dane logowania partnera, które omówimy w następnej sekcji.

5. Obsługa protokołu OAuth

OAuth to internetowy standard przekazywania dostępu, często używany przez użytkowników do przyznawania aplikacjom innych firm dostępu do informacji o swoich kontach bez konieczności udostępniania hasła. Używamy protokołu OAuth 2.0, aby umożliwić deweloperom dostęp do urządzeń użytkowników przez dostęp do urządzeń.

7ee31f5d9c37f699.png

Podaj identyfikator URI przekierowania

Pierwszy krok procesu OAuth obejmuje przekazanie zestawu parametrów do punktu końcowego Google OAuth 2.0. Po uzyskaniu zgody użytkownika serwery Google OAuth wysyłają żądanie z kodem autoryzacji do identyfikatora URI przekierowania.

Zaktualizuj stałą SERVER_URI (wiersz 19) własnym adresem URL hostingu w polu scripts.js:

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

Ponowne wdrożenie aplikacji z tą zmianą spowoduje zaktualizowanie identyfikatora URI przekierowania używanego w projekcie.

$ firebase deploy

Włącz identyfikator URI przekierowania

Po zaktualizowaniu identyfikatora URI przekierowania w pliku skryptów musisz też dodać go do listy dozwolonych identyfikatorów URI przekierowania dla identyfikatora klienta utworzonego w Twoim projekcie. W Google Cloud Platform otwórz stronę danych logowania. Zobaczysz tam listę wszystkich danych logowania utworzonych w Twoim projekcie:

1a07b624b5e548da.png

Na liście Identyfikatory klienta OAuth 2.0 wybierz identyfikator klienta utworzony w kroku Tworzenie projektu. Dodaj identyfikator URI przekierowania aplikacji do listy Autoryzowane identyfikatory URI przekierowania w projekcie.

6d65b298e1f005e2.png

Spróbuj się zalogować.

Otwórz stronę Hostingu skonfigurowaną w Firebase, wpisz swoje dane logowania do partnera i kliknij przycisk ZALOGUJ SIĘ. Identyfikator klienta i tajny klucz klienta to dane logowania uzyskane z Google Cloud Platform. Identyfikator projektu pochodzi z Konsoli dostępu do urządzenia.

78b48906a2dd7c05.png

Przycisk ZALOGUJ SIĘ umożliwia użytkownikom przejście przez proces OAuth na potrzeby Twojej firmy, począwszy od ekranu logowania na konto Google. Po zalogowaniu się użytkownicy zostaną poproszeni o przyznanie w projekcie uprawnień dostępu do urządzeń Nest.

e9b7887c4ca420.png

Ponieważ jest to tylko przykładowa aplikacja, przed przekierowaniem użytkownika Google wyśle ostrzeżenie.

b227d510cb1df073.png

Kliknij „Zaawansowane”, a następnie wybierz „Otwórz stronę web.app (niebezpieczna)”, aby dokończyć przekierowywanie do aplikacji.

673a4fd217e24dad.png

Spowoduje to udostępnienie kodu OAuth jako części przychodzącego żądania GET, które aplikacja wymieni na token dostępu i token odświeżania.

6. Sterowanie urządzeniem

Przykładowa aplikacja do obsługi urządzeń Google Nest używa wywołań interfejsu API typu REST Smart Device Management do zarządzania urządzeniami. Wywołania te polegają na przekazaniu tokena dostępu w nagłówku żądania GET lub POST razem z ładunkiem wymaganym dla niektórych poleceń.

Opracowaliśmy ogólną funkcję żądania dostępu do obsługi tych wywołań. Musisz jednak podać w tej funkcji prawidłowy punkt końcowy oraz w razie potrzeby obiekt ładunku.

function deviceAccessRequest(method, call, localpath, payload = null) {...}
  • metoda – typ żądania HTTP (GET lub POST))
  • call – ciąg znaków reprezentujący wywołanie interfejsu API używany do kierowania odpowiedzi (listDevices, thermostatMode, temperatureSetpoint).
  • localpath – punkt końcowy, do którego wysyłane jest żądanie, zawierający identyfikator projektu i urządzenia (dołączane po https://smartdevicemanagement.googleapis.com/v1)
  • ładunek (*) – dodatkowe dane wymagane do wywołania interfejsu API (np. wartość liczbowa reprezentująca temperaturę nastawy).

W interfejsie stworzymy przykładowe elementy sterujące (wyświetlaj listę urządzeń, tryb, ustaw temperaturę), by sterować urządzeniem Nest Thermostat:

86f8a193aa397421.png

Te elementy sterujące interfejsu będą wywoływać odpowiednie funkcje (listDevices(), postThermostatMode(), postTemperatureSetpoint()) z poziomu scripts.js. Są puste, więc musisz je zaimplementować. Celem jest wybranie prawidłowej metody i ścieżki oraz przekazanie ładunku do funkcji deviceAccessRequest(...).

Wyświetlanie listy urządzeń

Najprostsze wywołanie w aplikacji Device Access to listDevices. Wykorzystuje żądanie GET i nie wymaga ładunku. Punkt końcowy musi mieć strukturę projectId. Wypełnij funkcję listDevices() w następujący sposób:

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

Zapisz zmiany i wdróż projekt Firebase ponownie za pomocą tego polecenia:

$ firebase deploy

Po wdrożeniu nowej wersji aplikacji odśwież stronę i kliknij LISTA URZĄDZEŃ. Powinna pojawić się lista w sekcji Sterowanie urządzeniem, na której powinien znajdować się identyfikator termostatu:

b64a198673ed289f.png

Wybranie urządzeń z listy spowoduje zaktualizowanie pola deviceId w pliku scripts.js. W przypadku 2 kolejnych elementów sterujących musimy określić deviceId dla konkretnego urządzenia, którym chcesz sterować.

Sterowanie termostatem

W interfejsie Smart Device Management API dostępne są 2 cechy podstawowych funkcji sterowania urządzeniem Nest Thermostat. ThermostatMode i TemperatureSetpoint. Tryb termostatu włącza tryb urządzenia Nest Thermostat w jednym z czterech dostępnych: {Off, Heat, Cool, HeatCool}. Następnie musimy udostępnić wybrany tryb jako część ładunku.

Zastąp funkcję postThermostatMode() w pliku scripts.js tym:

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);
}

Następna funkcja, postTemperatureSetpoint(), obsługuje ustawianie temperatury (w stopniach Celsjusza) na urządzeniu Nest Thermostat. W zależności od wybranego trybu termostatu można ustawić 2 parametry: heatCelsius i 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. Serwer Node.js (opcjonalnie)

Gratulacje! Masz utworzoną po stronie klienta aplikację internetową, która może wysyłać żądania do interfejsu Smart Device Management API z poziomu przeglądarki. Osoby, które chcą tworzyć strony po stronie serwera, mogą zacząć od serwera proxy, który może przekierowywać żądania z przeglądarki.

W przypadku tego serwera proxy użyjemy funkcji Firebase Cloud Functions, Node.js i Express.

Inicjowanie Cloud Functions

Otwórz nowe okno terminala, przejdź do katalogu projektu i uruchom to polecenie:

$ firebase init functions

Firebase zada Ci zestaw pytań, aby zainicjować funkcje w Cloud Functions:

  1. W jakim języku chcesz pisać funkcje w Cloud Functions? – JavaScript
  2. Czy chcesz używać ESLint, aby wychwytywać prawdopodobne błędy i egzekwować styl? — Nie
  3. Czy chcesz teraz zainstalować zależności przy użyciu npm? — Tak

Spowoduje to zainicjowanie folderu functions w projekcie oraz zainstalowanie niezbędnych zależności. Zobaczysz, że folder projektu zawiera katalog funkcji z plikiem index.js służącym do definiowania naszych funkcji w chmurze, plikiem package.json do zdefiniowania ustawień i katalogiem node_modules zawierającym zależności.

Do stworzenia funkcji po stronie serwera użyjemy 2 bibliotek npm: express i xmlhttprequest. Do listy zależności w pliku package.json musisz dodać te wpisy:

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

Następnie uruchomienie npm instalacji z katalogu funkcji powinno zainstalować zależności w projekcie:

$ npm install

Jeśli npm wystąpi problem z pobieraniem pakietów, możesz spróbować zapisać żądanie xmlhttprequest i wyraźnie określić to polecenie:

$ npm install express xmlhttprequest --save

Przejdź na abonament Blaze

Użycie polecenia firebase deploy wymaga przejścia na abonament Blaze, co wymaga dodania formy płatności do konta. Otwórz Omówienie projektu > Wykorzystanie i płatności i wybierz abonament Blaze dla swojego projektu.

c6a5e5a21397bef6.png

Tworzenie serwera Express

Serwer Express korzysta z prostej struktury do odpowiadania na przychodzące żądania GET i POST. Stworzyliśmy serwlet, który nasłuchuje żądań POST, przesyła je do docelowego adresu URL określonego w ładunku i odpowiada z odpowiedzią otrzymaną z transferu.

Zmodyfikuj plik index.js w katalogu funkcji, aby wyglądać tak:

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);

Aby przekierować żądania do naszego serwera, musimy zmienić przepisy dotyczące modyfikacji z firebase.json w ten sposób:

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

Spowoduje to przekierowanie adresów URL zaczynających się od /proxy na nasz serwer ekspresowy, a pozostałe adresy będą nadal przesyłane do index.html.

Wywołania interfejsu Proxy API

Skoro serwer jest gotowy, określmy w scripts.js identyfikator URI serwera proxy, aby nasza przeglądarka mogła wysyłać żądania na ten adres:

const PROXY_URI = SERVER_URI + "/proxy";

Następnie dodaj funkcję proxyRequest, która ma ten sam podpis co funkcja deviceAccessRequest(...), to scripts.js na potrzeby pośrednich wywołań dostępu do urządzenia.

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();
}

Ostatnim krokiem jest zastąpienie wywołań deviceAccessRequest(...) funkcją proxyRequest(...) w funkcjach postThermostatMode() i postTemperatureSetpoint() w obiekcie scripts.js.

Uruchom firebase deploy, aby zaktualizować aplikację.

$ firebase deploy

Dzięki temu masz teraz uruchomiony serwer proxy Node.js za pomocą Express w Cloud Functions.

Przyznawanie uprawnień funkcji w Cloud Functions

Ostatnim krokiem jest sprawdzenie uprawnień dostępu do funkcji w Cloud Functions i upewnienie się, że aplikacja po stronie klienta będzie mogła je wywoływać.

W Google Cloud Platform otwórz kartę Cloud Functions i wybierz swoją funkcję w Cloud Functions:

461e9bae74227fc1.png

Kliknij Uprawnienia, a następnie Dodaj użytkownika. W polu nowego użytkownika wpisz atrybut allUsers, a jako rolę wybierz Cloud Functions > Wywołujący funkcje w Cloud Functions. Kliknięcie Zapisz spowoduje wyświetlenie komunikatu z ostrzeżeniem:

3adb01644217578c.png

Wybranie opcji Zezwól na dostęp publiczny umożliwi aplikacjom po stronie klienta korzystanie z funkcji w Cloud Functions.

Gratulacje! Udało Ci się wykonać wszystkie czynności. Możesz teraz otworzyć aplikację internetową i skorzystać z opcji sterowania urządzeniami kierowanymi przez Twój serwer proxy.

Dalsze kroki

Szukasz sposobów na poszerzenie wiedzy o dostępie do urządzenia? Przeczytaj dokumentację dotyczącą cech, aby dowiedzieć się więcej o sterowaniu innymi urządzeniami Nest, oraz o procesie certyfikacji, aby dowiedzieć się, jak wprowadzić swój produkt na rynek.

Pogłębiaj swoje umiejętności i poznaj przykładową aplikację internetową Dostęp do urządzenia, w której wykorzystasz doświadczenie z programowania i wdrożysz działającą aplikację internetową do sterowania kamerami, dzwonkami i termostatami Nest.