1. Zanim zaczniesz
Integracje typu cloud-to-cloud używają typów urządzeń, aby informować Asystenta Google, jakiej gramatyki należy używać w przypadku danego urządzenia. Cechy urządzenia określają możliwości danego typu urządzenia. Urządzenie dziedziczy stany każdego atrybutu urządzenia dodanego do integracji.
Możesz połączyć dowolne obsługiwane cechy z wybranym typem urządzenia, aby dostosować funkcje urządzeń użytkowników. Jeśli chcesz wdrożyć w swoich działaniach niestandardowe cechy, które nie są obecnie dostępne w schemacie urządzenia, cechy Modes i Toggles umożliwiają sterowanie określonymi ustawieniami za pomocą zdefiniowanej przez Ciebie niestandardowej nazwy.
Oprócz podstawowych możliwości sterowania zapewnianych przez typy i cechy interfejs Smart Home API ma dodatkowe funkcje, które zwiększają wygodę użytkowników. Odpowiedzi o błędach zawierają szczegółowe informacje zwrotne dla użytkownika, gdy intencje nie zostaną zrealizowane. Weryfikacja dodatkowego użytkownika rozszerza te odpowiedzi i dodaje dodatkowe zabezpieczenia do wybranej cechy urządzenia. Wysyłając do bloków weryfikacyjnych wydanych przez Asystenta konkretne odpowiedzi o błędach, integracja typu Cloud-to-cloud może wymagać dodatkowej autoryzacji do wykonania polecenia.
Wymagania wstępne
- Tworzenie integracji typu chmura-chmura – przewodnik dla deweloperów
- Ćwiczenia z programowania Smart Home Washer
- Typy i cechy urządzeń Przewodnik dla deweloperów
Co utworzysz
W tym module dowiesz się, jak wdrożyć gotową integrację inteligentnego domu z Firebase, a potem dodawać niestandardowe cechy do pralki inteligentnego domu, takie jak rozmiar wsadu i tryb turbo. Wdrożysz też raportowanie błędów i wyjątków oraz nauczysz się wymuszać potwierdzenie głosowe, aby włączyć pralkę za pomocą weryfikacji dodatkowej.
Czego się nauczysz
- Jak dodać do integracji cechy Tryby i Przełączniki
- Jak zgłaszać błędy i wyjątki
- Jak zastosować dodatkową weryfikację użytkownika
Czego potrzebujesz
- przeglądarka, np. Google Chrome;
- Urządzenie z iOS lub Androidem z zainstalowaną aplikacją Google Home
- Node.js w wersji 10.16 lub nowszej
- konto Google,
- konto rozliczeniowe Google Cloud;
2. Pierwsze kroki
Włączanie zarządzania aktywnością
Aby korzystać z Asystenta Google, musisz udostępniać Google określone dane o aktywności. Asystent Google potrzebuje tych danych do prawidłowego działania, ale wymóg udostępniania danych nie jest specyficzny dla pakietu SDK. Aby udostępnić te dane, utwórz konto Google, jeśli jeszcze go nie masz. Możesz użyć dowolnego konta Google, nie musi to być Twoje konto dewelopera.
Otwórz stronę Zarządzanie aktywnością na koncie Google, którego chcesz używać z Asystentem.
Upewnij się, że te przełączniki są włączone:
- Aktywność w internecie i aplikacjach – dodatkowo zaznacz pole Uwzględnij historię Chrome i aktywność na stronach, urządzeniach i w aplikacjach, które używają usług Google.
- Informacje o urządzeniu
- Aktywność związana z głosem i dźwiękiem
Tworzenie projektu integracji typu chmura-chmura
- Otwórz Developer Console.
- Kliknij Utwórz projekt, wpisz nazwę projektu i kliknij Utwórz projekt.
Wybierz integrację typu chmura-chmura
Na stronie Strona główna projektu w konsoli dewelopera w sekcji Cloud-to-cloud kliknij Add cloud-to-cloud integration (Dodaj integrację cloud-to-cloud).
Instalowanie wiersza poleceń Firebase
Wiersz poleceń Firebase umożliwia lokalne udostępnianie aplikacji internetowych i wdrażanie ich w Hostingu Firebase.
Aby zainstalować interfejs wiersza poleceń, uruchom to polecenie npm w terminalu:
npm install -g firebase-tools
Aby sprawdzić, czy interfejs CLI został prawidłowo zainstalowany, uruchom to polecenie:
firebase --version
Autoryzuj wiersz poleceń Firebase za pomocą konta Google, uruchamiając to polecenie:
firebase login
Dodawanie Firebase do projektu w konsoli programisty Google Home
Metoda 1. W konsoli Firebase
- Otwórz Firebase.
- Kliknij Utwórz projekt Firebase.
- Na ekranie Utwórz projekt kliknij Dodaj Firebase do projektu Google Cloud.
- Na ekranie Rozpocznij wybierz projekt Google Cloud, który został utworzony w konsoli Google Home Developer, a następnie kliknij Dalej.
Metoda 2. Za pomocą wiersza poleceń Firebase
firebase projects:addfirebase
Aby dodać Firebase, wybierz utworzony projekt w Konsoli dewelopera Google Home.
Gdy dodasz Firebase do projektu w Google Home Developer Console, pojawi się on w konsoli Firebase. Identyfikator projektu Firebase będzie zgodny z identyfikatorem projektu w konsoli dewelopera Google Home.
Włączanie interfejsu HomeGraph API
HomeGraph API umożliwia przechowywanie urządzeń i ich stanów w Home Graph użytkownika oraz wysyłanie zapytań dotyczących tych informacji. Aby korzystać z tego interfejsu API, musisz najpierw otworzyć konsolę Google Cloud i włączyć HomeGraph API.
W konsoli Google Cloud wybierz projekt, który pasuje do Twoich działań <firebase-project-id>.
Następnie na ekranie Biblioteka interfejsów API dla HomeGraph API kliknij Włącz.
3. Uruchamianie aplikacji wyjściowej
Po skonfigurowaniu środowiska programistycznego możesz wdrożyć projekt początkowy, aby sprawdzić, czy wszystko jest prawidłowo skonfigurowane.
Pobieranie kodu źródłowego
Kliknij ten link, aby pobrać na komputer, którego używasz do programowania, przykładowy kod do tego laboratorium:
…lub możesz sklonować repozytorium GitHub z wiersza poleceń:
git clone https://github.com/google-home/smarthome-traits.git
Rozpakuj pobrany plik ZIP.
Informacje o projekcie
Projekt początkowy zawiera te podkatalogi:
public:
Interfejs użytkownika, który umożliwia łatwe sterowanie stanem inteligentnej pralki i jego monitorowanie.functions:
W pełni wdrożona usługa w chmurze, która zarządza inteligentną pralką za pomocą Cloud Functions dla Firebase i Bazy danych czasu rzeczywistego Firebase.
Dostarczona realizacja w chmurze obejmuje te funkcje w index.js
:
fakeauth
: punkt końcowy autoryzacji do łączenia kont,faketoken
: punkt końcowy tokena do łączenia kont.smarthome
: punkt końcowy realizacji intencji dotyczących inteligentnego domureportstate
: wywołuje interfejs Home Graph API w przypadku zmian stanu urządzenia.requestsync
: umożliwia aktualizowanie urządzeń użytkowników bez konieczności ponownego łączenia kont
Łączenie Analytics z Firebase
Otwórz katalog washer-start
, a potem skonfiguruj wiersz poleceń Firebase za pomocą projektu integracji:
cd washer-start firebase use <project-id>
Skonfiguruj projekt Firebase
Zainicjuj projekt Firebase.
firebase init
Wybierz funkcje interfejsu CLI, Realtime Database i Functions.
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed) >( ) Data Connect: Set up a Firebase Data Connect service ( ) Firestore: Configure security rules and indexes files for Firestore ( ) Genkit: Setup a new Genkit project with Firebase (*) Functions: Configure a Cloud Functions directory and its files ( ) App Hosting: Configure an apphosting.yaml file for App Hosting ( ) Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys ( ) Storage: Configure a security rules file for Cloud Storage ( ) Emulators: Set up local emulators for Firebase products ( ) Remote Config: Configure a template file for Remote Config ( ) Extensions: Set up an empty Extensions manifest (*) Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance ( ) Data Connect: Set up a Firebase Data Connect service ( ) Firestore: Configure security rules and indexes files for Firestore
Spowoduje to zainicjowanie niezbędnych interfejsów API i funkcji w projekcie.
Gdy pojawi się odpowiedni komunikat, zainicjuj bazę danych czasu rzeczywistego. Możesz użyć domyślnej lokalizacji instancji bazy danych.
? It seems like you haven't initialized Realtime Database in your project yet. Do you want to set it up? Yes ? Please choose the location for your default Realtime Database instance: us-central1
Ponieważ używasz kodu projektu początkowego, wybierz domyślny plik reguł zabezpieczeń i upewnij się, że nie zastąpisz istniejącego pliku reguł bazy danych.
? File database.rules.json already exists. Do you want to overwrite it with the Realtime Database Security Rules for <project-ID>-default-rtdb from the Firebase Console? No
Jeśli ponownie inicjujesz projekt, gdy pojawi się pytanie, czy chcesz zainicjować lub zastąpić bazę kodu, kliknij Zastąp.
? Would you like to initialize a new codebase, or overwrite an existing one? Overwrite
Podczas konfigurowania funkcji używaj domyślnych plików i upewnij się, że nie zastępujesz istniejących plików index.js i package.json w przykładowym projekcie.
? What language would you like to use to write Cloud Functions? JavaScript ? Do you want to use ESLint to catch probable bugs and enforce style? No ? File functions/package.json already exists. Overwrite? No ? File functions/index.js already exists. Overwrite? No
Jeśli ponownie inicjujesz projekt, na pytanie, czy chcesz zainicjować lub zastąpić plik functions/.gitignore, wybierz Nie.
? File functions/.gitignore already exists. Overwrite? No
? Do you want to install dependencies with npm now? Yes
Jeśli ESLint został przypadkowo włączony, można go wyłączyć na 2 sposoby:
- W GUI przejdź do folderu
../functions
w projekcie, wybierz ukryty plik.eslintrc.js
i usuń go. Nie myl go z podobnie nazwanym.eslintrc.json
. - W wierszu poleceń:
cd functions rm .eslintrc.js
Wdrażanie w Firebase
Po zainstalowaniu zależności i skonfigurowaniu projektu możesz po raz pierwszy uruchomić aplikację.
firebase deploy
Oto dane wyjściowe, które powinny się wyświetlić w konsoli:
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<project-id>/overview Hosting URL: https://<project-id>.web.app
To polecenie wdraża aplikację internetową wraz z kilkoma Cloud Functions dla Firebase.
Otwórz adres URL hostingu w przeglądarce (https://<firebase-project-id>.web.app
), aby wyświetlić aplikację internetową. Zobaczysz ten interfejs:
Ten interfejs internetowy to platforma innej firmy, która umożliwia wyświetlanie i modyfikowanie stanów urządzeń. Aby rozpocząć wypełnianie bazy danych informacjami o urządzeniach, kliknij AKTUALIZUJ. Na stronie nie zobaczysz żadnych zmian, ale bieżący stan pralki zostanie zapisany w bazie danych.
Teraz musisz połączyć wdrożoną usługę w chmurze z Asystentem Google za pomocą konsoli dewelopera.
Konfigurowanie projektu w Konsoli programisty
Na karcie Opracowywanie dodaj wyświetlaną nazwę interakcji. Ta nazwa będzie widoczna w aplikacji Google Home.
W sekcji Branding aplikacji prześlij plik png
z ikoną aplikacji o rozmiarach 144 x 144 pikseli i nazwie
.
Aby włączyć łączenie kont, użyj tych ustawień łączenia kont:
Identyfikator klienta |
|
Tajny klucz klienta |
|
Adres URL autoryzacji |
|
URL tokena |
|
W sekcji Adres URL realizacji w chmurze wpisz adres URL funkcji w Cloud Functions, która zapewnia realizację intencji związanych z inteligentnym domem.
https://us-central1-<project-id>.cloudfunctions.net/smarthome
Aby zapisać konfigurację projektu, kliknij Zapisz, a potem Dalej: testowanie, aby włączyć testowanie w projekcie.
Teraz możesz zacząć wdrażać elementy webhook, które są niezbędne do połączenia stanu urządzenia z Asystentem.
Łączenie z Asystentem Google
Aby przetestować integrację typu cloud-to-cloud, musisz połączyć projekt z kontem Google. Umożliwia to testowanie na urządzeniach z Asystentem Google i w aplikacji Google Home, na których zalogowano się na to samo konto.
- Otwórz ustawienia Asystenta Google na telefonie. Pamiętaj, aby zalogować się na to samo konto co w konsoli.
- Wybierz Asystent Google > Ustawienia > Sterowanie domem (w sekcji Asystent).
- W prawym górnym rogu kliknij ikonę wyszukiwania.
- Wyszukaj aplikację testową, używając prefiksu [test].
- Wybierz ten element. Asystent Google uwierzytelni się w usłudze i wyśle żądanie
SYNC
, prosząc o podanie listy urządzeń użytkownika.
Otwórz aplikację Google Home i sprawdź, czy widzisz urządzenie do prania.
Sprawdź, czy możesz sterować pralką za pomocą poleceń głosowych w aplikacji Google Home. Powinna też być widoczna zmiana stanu urządzenia w interfejsie internetowym usługi realizacji w chmurze.
Po wdrożeniu podstawowej pralki możesz dostosować tryby dostępne na urządzeniu.
4. Dodawanie trybów
Cechą action.devices.traits.Modes
jest to, że urządzenie może mieć dowolną liczbę ustawień trybu, z których tylko jedno może być ustawione w danym momencie. Dodasz do pralki tryb, który określa wielkość załadunku: mały, średni lub duży.
Aktualizowanie odpowiedzi SYNC
Musisz dodać informacje o nowym atrybucie do odpowiedzi SYNC
w functions/index.js
. Te dane są wyświetlane w traits
tablicy i attributes
obiekcie, jak pokazano w poniższym fragmencie kodu.
index.js
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
payload: {
agentUserId: USER_ID,
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
// Add Modes trait
'action.devices.traits.Modes',
],
name: { ... },
deviceInfo: { ... },
attributes: {
pausable: true,
//Add availableModes
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en',
}],
settings: [{
setting_name: 'small',
setting_values: [{
setting_synonym: ['small'],
lang: 'en',
}]
}, {
setting_name: 'medium',
setting_values: [{
setting_synonym: ['medium'],
lang: 'en',
}]
}, {
setting_name: 'large',
setting_values: [{
setting_synonym: ['large'],
lang: 'en',
}]
}],
ordered: true,
}],
},
}],
},
};
});
Dodawanie nowych poleceń intencji EXECUTE
W intencji EXECUTE
dodaj polecenie action.devices.commands.SetModes
, jak pokazano w tym fragmencie kodu.
index.js
const updateDevice = async (execution,deviceId) => {
const {params,command} = execution;
let state, ref;
switch (command) {
case 'action.devices.commands.OnOff':
state = {on: params.on};
ref = firebaseRef.child(deviceId).child('OnOff');
break;
case 'action.devices.commands.StartStop':
state = {isRunning: params.start};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.PauseUnpause':
state = {isPaused: params.pause};
ref = firebaseRef.child(deviceId).child('StartStop');
Break;
// Add SetModes command
case 'action.devices.commands.SetModes':
state = {load: params.updateModeSettings.load};
ref = firebaseRef.child(deviceId).child('Modes');
break;
}
};
Aktualizowanie odpowiedzi na zapytanie
Następnie zaktualizuj odpowiedź QUERY
, aby zgłosić bieżący stan pralki.
Dodaj zaktualizowane zmiany do funkcji queryFirebase
i queryDevice
, aby uzyskać stan przechowywany w bazie danych czasu rzeczywistego.
index.js
const queryFirebase = async (deviceId) => {
const snapshot = await firebaseRef.child(deviceId).once('value');
const snapshotVal = snapshot.val();
return {
on: snapshotVal.OnOff.on,
isPaused: snapshotVal.StartStop.isPaused,
isRunning: snapshotVal.StartStop.isRunning,
// Add Modes snapshot
load: snapshotVal.Modes.load,
};
};
const queryDevice = async (deviceId) => {
const data = await queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{ ... }],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
// Add currentModeSettings
currentModeSettings: {
load: data.load,
},
};
};
Aktualizowanie stanu raportu
Na koniec zaktualizuj funkcję reportstate
, aby zgłaszać do Home Graph bieżące ustawienie wsadu pralki.
index.js
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of your washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
// Add currentModeSettings
currentModeSettings: {
load: snapshot.Modes.load,
},
},
},
},
},
};
Wdrażanie w Firebase
Aby wdrożyć zaktualizowaną integrację, uruchom to polecenie:
firebase deploy --only functions
Po zakończeniu wdrażania otwórz interfejs internetowy i na pasku narzędzi kliknij przycisk Odśwież . Spowoduje to wysłanie żądania synchronizacji, dzięki czemu Asystent otrzyma zaktualizowane dane odpowiedzi
SYNC
.
Teraz możesz wydać polecenie, aby ustawić tryb pralki, np.:
„OK Google, ustaw duży wsad pralki”.
Możesz też zadawać pytania dotyczące pralki, np.:
„OK Google, jakie jest obciążenie pralki?”
5. Dodawanie przełączników
Cechą action.devices.traits.Toggles
są nazwane aspekty urządzenia, które mogą mieć stan prawda lub fałsz, np. czy pralka jest w trybie turbo.
Aktualizowanie odpowiedzi SYNC
W odpowiedzi SYNC
musisz dodać informacje o nowym atrybucie urządzenia. Pojawi się w tablicy traits
i obiekcie attributes
, jak pokazano w tym fragmencie kodu.
index.js
app.onSync(body => {
return {
requestId: 'ff36a3cc-ec34-11e6-b1a0-64510650abcf',
payload: {
agentUserId: USER_ID,
devices: [{
id: 'washer',
type: 'action.devices.types.WASHER',
traits: [
'action.devices.traits.OnOff',
'action.devices.traits.StartStop',
'action.devices.traits.RunCycle',
'action.devices.traits.Modes',
// Add Toggles trait
'action.devices.traits.Toggles',
],
name: { ... },
deviceInfo: { ... },
attributes: {
pausable: true,
availableModes: [{
name: 'load',
name_values: [{
name_synonym: ['load'],
lang: 'en'
}],
settings: [{ ... }],
ordered: true,
}],
//Add availableToggles
availableToggles: [{
name: 'Turbo',
name_values: [{
name_synonym: ['turbo'],
lang: 'en',
}],
}],
},
}],
},
};
});
Dodawanie nowych poleceń intencji EXECUTE
W intencji EXECUTE
dodaj polecenie action.devices.commands.SetToggles
, jak pokazano w tym fragmencie kodu.
index.js
const updateDevice = async (execution,deviceId) => {
const {params,command} = execution;
let state, ref;
switch (command) {
case 'action.devices.commands.OnOff':
state = {on: params.on};
ref = firebaseRef.child(deviceId).child('OnOff');
break;
case 'action.devices.commands.StartStop':
state = {isRunning: params.start};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.PauseUnpause':
state = {isPaused: params.pause};
ref = firebaseRef.child(deviceId).child('StartStop');
break;
case 'action.devices.commands.SetModes':
state = {load: params.updateModeSettings.load};
ref = firebaseRef.child(deviceId).child('Modes');
break;
// Add SetToggles command
case 'action.devices.commands.SetToggles':
state = {Turbo: params.updateToggleSettings.Turbo};
ref = firebaseRef.child(deviceId).child('Toggles');
break;
}
Aktualizowanie odpowiedzi na zapytanie
Na koniec musisz zaktualizować odpowiedź QUERY
, aby zgłosić tryb turbo pralki. Dodaj zaktualizowane zmiany do funkcji queryFirebase
i queryDevice
, aby uzyskać stan przełącznika zapisany w bazie danych czasu rzeczywistego.
index.js
const queryFirebase = async (deviceId) => {
const snapshot = await firebaseRef.child(deviceId).once('value');
const snapshotVal = snapshot.val();
return {
on: snapshotVal.OnOff.on,
isPaused: snapshotVal.StartStop.isPaused,
isRunning: snapshotVal.StartStop.isRunning,
load: snapshotVal.Modes.load,
// Add Toggles snapshot
Turbo: snapshotVal.Toggles.Turbo,
};
}
const queryDevice = async (deviceId) => {
const data = queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{ ... }],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
currentModeSettings: {
load: data.load,
},
// Add currentToggleSettings
currentToggleSettings: {
Turbo: data.Turbo,
},
};
};
Aktualizowanie stanu raportu
Na koniec zaktualizuj funkcję reportstate
, aby zgłaszać do Home Graph, czy pralka jest ustawiona na tryb turbo.
index.js
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of your washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
currentModeSettings: {
load: snapshot.Modes.load,
},
// Add currentToggleSettings
currentToggleSettings: {
Turbo: snapshot.Toggles.Turbo,
},
},
},
},
},
};
Wdrażanie w Firebase
Aby wdrożyć zaktualizowane funkcje, uruchom to polecenie:
firebase deploy --only functions
Po zakończeniu wdrażania kliknij przycisk Odśwież w interfejsie internetowym, aby wywołać synchronizację.
Możesz teraz wydać polecenie, aby ustawić pralkę w trybie turbo, mówiąc:
„OK Google, ustaw pralkę w trybie turbo”.
Możesz też sprawdzić, czy pralka jest już w trybie turbo, zadając pytanie:
„OK Google, czy moja pralka jest w trybie turbo?”
6. Zgłaszanie błędów i wyjątków
Obsługa błędów w integracji typu chmura-chmura umożliwia informowanie użytkowników o problemach, które powodują niepowodzenie odpowiedzi EXECUTE
i QUERY
. Powiadomienia zapewniają użytkownikom lepsze wrażenia podczas korzystania z urządzenia inteligentnego i integracji.
Za każdym razem, gdy żądanie EXECUTE
lub QUERY
zakończy się niepowodzeniem, integracja powinna zwracać kod błędu. Jeśli na przykład chcesz zgłosić błąd, gdy użytkownik próbuje włączyć pralkę przy otwartej pokrywie, odpowiedź EXECUTE
będzie wyglądać jak ten fragment kodu:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"commands": [
{
"ids": [
"456"
],
"status": "ERROR",
"errorCode": "deviceLidOpen"
}
]
}
}
Gdy użytkownik poprosi o włączenie pralki, Asystent odpowie:
„Pokrywa pralki jest otwarta. Zamknij ją i spróbuj jeszcze raz”.
Wyjątki są podobne do błędów, ale wskazują, kiedy z poleceniem jest powiązany alert, który może blokować lub nie blokować pomyślnego wykonania. Wyjątek może zawierać powiązane informacje za pomocą cechy StatusReport
, takie jak poziom baterii lub ostatnia zmiana stanu. Kody wyjątków nieblokujących są zwracane ze stanem SUCCESS
, a kody wyjątków blokujących – ze stanem EXCEPTIONS
.
Przykładowa odpowiedź z wyjątkiem znajduje się w tym fragmencie kodu:
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"payload": {
"commands": [{
"ids": ["123"],
"status": "SUCCESS",
"states": {
"online": true,
"isPaused": false,
"isRunning": false,
"exceptionCode": "runCycleFinished"
}
}]
}
}
Asystent odpowiada:
„Pralka skończyła pracę”.
Aby dodać raportowanie błędów w przypadku pralki, otwórz functions/index.js
i dodaj definicję klasy błędu, jak w tym fragmencie kodu:
index.js
app.onQuery(async (body) => {...});
// Add SmartHome error handling
class SmartHomeError extends Error {
constructor(errorCode, message) {
super(message);
this.name = this.constructor.name;
this.errorCode = errorCode;
}
}
Zaktualizuj odpowiedź dotyczącą wykonania, aby zwracać kod błędu i stan błędu:
index.js
const executePromises = [];
const intent = body.inputs[0];
for (const command of intent.payload.commands) {
for (const device of command.devices) {
for (const execution of command.execution) {
executePromises.push(
updateDevice(execution, device.id)
.then((data) => {
...
})
//Add error response handling
.catch((error) => {
functions.logger.error('EXECUTE', device.id, error);
result.ids.push(device.id);
if (error instanceof SmartHomeError) {
result.status = 'ERROR';
result.errorCode = error.errorCode;
}
})
);
}
}
}
Asystent może teraz informować użytkowników o każdym zgłoszonym przez Ciebie kodzie błędu. W następnej sekcji znajdziesz konkretny przykład.
7. Dodawanie dodatkowej weryfikacji użytkownika
Jeśli urządzenie ma tryby, które wymagają zabezpieczenia lub powinny być ograniczone do określonej grupy autoryzowanych użytkowników, np. aktualizacja oprogramowania lub wyłączenie blokady, w integracji należy wdrożyć dodatkową weryfikację użytkownika.
Dodatkową weryfikację użytkownika możesz wdrożyć na wszystkich typach i cechach urządzeń, dostosowując, czy wyzwanie związane z bezpieczeństwem ma się pojawiać za każdym razem, czy tylko wtedy, gdy zostaną spełnione określone kryteria.
Istnieją 3 obsługiwane typy testów:
No
challenge
– żądanie i odpowiedź, które nie używają testu zabezpieczającego (jest to zachowanie domyślne).ackNeeded
– dodatkowa weryfikacja użytkownika, która wymaga wyraźnego potwierdzenia (tak lub nie);pinNeeded
– dodatkowa weryfikacja użytkownika, która wymaga podania osobistego numeru identyfikacyjnego (PIN);
W tym samouczku dodaj ackNeeded
wyzwanie do polecenia włączania pralki oraz funkcję zwracania błędu, jeśli dodatkowa weryfikacja się nie powiedzie.
Otwórz functions/index.js
i dodaj definicję klasy błędu, która zwraca kod błędu i typ weryfikacji, jak w tym fragmencie kodu:
index.js
class SmartHomeError extends Error { ... }
// Add secondary user verification error handling
class ChallengeNeededError extends SmartHomeError {
/**
* Create a new ChallengeNeededError
* @param {string} suvType secondary user verification challenge type
*/
constructor(suvType) {
super('challengeNeeded', suvType);
this.suvType = suvType;
}
}
Musisz też zaktualizować odpowiedź wykonania, aby zwracała błąd challengeNeeded
w ten sposób:
index.js
const executePromises = [];
const intent = body.inputs[0];
for (const command of intent.payload.commands) {
for (const device of command.devices) {
for (const execution of command.execution) {
executePromises.push(
updateDevice(execution, device.id)
.then((data) => {
...
})
.catch((error) => {
functions.logger.error('EXECUTE', device.id, error);
result.ids.push(device.id);
if (error instanceof SmartHomeError) {
result.status = 'ERROR';
result.errorCode = error.errorCode;
//Add error response handling
if (error instanceof ChallengeNeededError) {
result.challengeNeeded = {
type: error.suvType
};
}
}
})
);
}
}
}
Na koniec zmień updateDevice
, aby włączenie lub wyłączenie pralki wymagało wyraźnego potwierdzenia.
index.js
const updateDevice = async (execution,deviceId) => {
const {challenge,params,command} = execution; //Add secondary user challenge
let state, ref;
switch (command) {
case 'action.devices.commands.OnOff':
//Add secondary user verification challenge
if (!challenge || !challenge.ack) {
throw new ChallengeNeededError('ackNeeded');
}
state = {on: params.on};
ref = firebaseRef.child(deviceId).child('OnOff');
break;
...
}
return ref.update(state)
.then(() => state);
};
Wdrażanie w Firebase
Aby wdrożyć zaktualizowaną funkcję, uruchom to polecenie:
firebase deploy --only functions
Po wdrożeniu zaktualizowanego kodu musisz potwierdzić działanie, gdy poprosisz Asystenta o włączenie lub wyłączenie pralki, np. w ten sposób:
Ty: „OK Google, włącz pralkę”.
Asystent: „Czy na pewno chcesz włączyć pralkę?”
Ty: „Tak”.
Szczegółową odpowiedź dotyczącą każdego etapu procesu weryfikacji użytkownika dodatkowego możesz też sprawdzić, otwierając dzienniki Firebase.
8. Gratulacje
Gratulacje! Rozszerzyliśmy funkcje integracji typu chmura-chmura za pomocą cech Modes
i Toggles
oraz zabezpieczyliśmy ich wykonywanie za pomocą weryfikacji dodatkowej użytkownika.
Więcej informacji
Oto kilka pomysłów, które pomogą Ci pogłębić wiedzę:
- Dodaj do urządzeń funkcje lokalnego wykonywania.
- Aby zmienić stan urządzenia, użyj innego typu wyzwania związanego z dodatkową weryfikacją użytkownika.
- Zaktualizuj odpowiedź na zapytanie o cechę
RunCycle
, aby była dynamicznie aktualizowana. - Zapoznaj się z tym przykładem na GitHubie.