Buluttan buluta entegrasyonlarınızı iyileştirin ve güvenliğini sağlayın

1. Başlamadan önce

Buluttan buluta entegrasyonlar, Google Asistan'a bir cihazla hangi dilbilgisinin kullanılması gerektiğini bildirmek için cihaz türlerini kullanır. Cihaz özellikleri, bir cihaz türünün özelliklerini tanımlar. Bir cihaz, entegrasyona eklenen her cihaz özelliğinin durumunu devralır.

dc8dce0dea87cd5c.png

Kullanıcılarınızın cihazlarının işlevselliğini özelleştirmek için desteklenen tüm özellikleri seçtiğiniz cihaz türüne bağlayabilirsiniz. İşlemlerinizde şu anda cihaz şemasında bulunmayan özel özellikler uygulamak istiyorsanız Modlar ve Açma/Kapatma özellikleri, tanımladığınız özel bir adla belirli ayarların kontrol edilmesine olanak tanır.

Türler ve özellikler tarafından sağlanan temel kontrol özelliğinin ötesinde, Smart Home API'de kullanıcı deneyimini geliştirmeye yönelik ek özellikler bulunur. Hata yanıtları, amaçlar başarıya ulaşmadığında ayrıntılı kullanıcı geri bildirimi sağlar. İkincil kullanıcı doğrulaması, bu yanıtları genişletir ve seçtiğiniz cihaz özelliğine ek güvenlik sağlar. Asistan'dan verilen sorgu bloklarına belirli hata yanıtları göndererek, Cloud-to-Cloud entegrasyonunuzun bir komutu tamamlamak için ek yetkilendirme gerektirmesine neden olabilirsiniz.

Ön koşullar

Ne oluşturacaksınız?

Bu codelab'de Firebase ile önceden oluşturulmuş bir akıllı ev entegrasyonunu dağıtacak, ardından yük boyutu ve turbo modu için akıllı ev çamaşır makinesine standart olmayan özellikleri nasıl ekleyeceğinizi öğreneceksiniz. Ayrıca hata ve istisna raporlaması uygulayacak, ikincil kullanıcı doğrulaması kullanarak çamaşır makinesini açmak için sözlü onay almayı öğreneceksiniz.

Neler öğreneceksiniz?

  • Entegrasyonunuza Modlar ve Açma/Kapatma özellikleri ekleme
  • Hataları ve istisnaları bildirme
  • İkincil kullanıcı doğrulaması uygulama

İhtiyacınız olanlar

2. Başlarken

Etkinlik kontrollerini etkinleştirme

Google Asistan'ı kullanmak için belirli etkinlik verilerini Google ile paylaşmanız gerekir. Google Asistan'ın düzgün çalışması için bu verilere ihtiyacı vardır ancak verilerin paylaşılması zorunluluğu SDK'ya özgü değildir. Bu verileri paylaşmak için henüz bir Google Hesabınız yoksa oluşturun. Herhangi bir Google Hesabı'nı kullanabilirsiniz. Geliştirici hesabınız olması gerekmez.

Asistan ile kullanmak istediğiniz Google Hesabı'nın Etkinlik Kontrolleri sayfasını açın.

Aşağıdaki açma/kapatma düğmelerinin etkinleştirildiğinden emin olun:

  • Web ve Uygulama Etkinliği: Ayrıca Chrome geçmişini ve Google hizmetlerini kullanan site, uygulama ve cihazlardaki etkinlikleri ekle onay kutusunu işaretlediğinizden emin olun.
  • Cihaz bilgileri
  • Konuşma ve Ses Etkinliği

Buluttan buluta entegrasyon projesi oluşturma

  1. Developer Console'a gidin.
  2. Proje Oluştur'u tıklayın, proje için bir ad girin ve Proje Oluştur'u tıklayın.

Projeyi adlandırma

Buluttan buluta entegrasyonu seçin

Geliştirici Konsolu'ndaki Proje Ana Sayfası'nda, Cloud'dan Cloud'a bölümünde Cloud'dan Cloud'a entegrasyon ekle'yi seçin.

Buluttan buluta entegrasyon ekleme

Firebase CLI'yı yükleme

Firebase komut satırı arayüzü (KSA), web uygulamalarınızı yerel olarak sunmanıza ve web uygulamanızı Firebase Hosting'e dağıtmanıza olanak tanır.

CLI'yı yüklemek için terminalden aşağıdaki npm komutunu çalıştırın:

npm install -g firebase-tools

CLI'nın doğru şekilde yüklendiğini doğrulamak için şunu çalıştırın:

firebase --version

Aşağıdaki komutu çalıştırarak Firebase CLI'yı Google Hesabınızla yetkilendirin:

firebase login

Firebase'i Google Home Developer Console projenize ekleme

1. yöntem: Firebase konsolu üzerinden

  1. Firebase'e gidin.
  2. Firebase projesi oluştur'u tıklayın.
    Firebase projesi oluşturun
  3. Proje oluşturun ekranında Firebase'i Google Cloud projesine ekle'yi tıklayın.
    Firebase'i Google Cloud projesine ekleme
  4. Başlayın ekranında, Google Home Developer Console'da yeni oluşturduğunuz Google Cloud projesini seçin ve Devam'ı tıklayın.
    Google Cloud projesi seçin

2. yöntem: Firebase CLI aracılığıyla

firebase projects:addfirebase

Firebase'i eklemek için az önce oluşturduğunuz Google Home Developer Console projesini seçin.

Firebase, Google Home Developer Console projenize eklendiğinde Firebase Console'da görünür. Firebase projesinin proje kimliği, Google Home Developer Console proje kimliğinizle eşleşir.

Cloud projesi eklendi

HomeGraph API'yi etkinleştirme

HomeGraph API, cihazların ve durumlarının kullanıcının Home Graph'inde depolanmasını ve sorgulanmasını sağlar. Bu API'yi kullanmak için önce Google Cloud Console'u açıp HomeGraph API'yi etkinleştirmeniz gerekir.

Google Cloud Console'da, işlemlerinizle eşleşen projeyi seçtiğinizden emin olun. <firebase-project-id>. Ardından, HomeGraph API'nin API kitaplığı ekranında Etkinleştir'i tıklayın.

ee198858a6eac112.png

3. Başlangıç uygulamasını çalıştırma

Geliştirme ortamınızı kurduğunuza göre, her şeyin doğru şekilde yapılandırıldığını doğrulamak için başlangıç projesini dağıtabilirsiniz.

Kaynak kodu alma

Bu codelab'in örneğini geliştirme makinenize indirmek için aşağıdaki bağlantıyı tıklayın:

...veya GitHub deposunu komut satırından klonlayabilirsiniz:

git clone https://github.com/google-home/smarthome-traits.git

İndirilen ZIP dosyasını açın.

Proje hakkında

Başlangıç projesi aşağıdaki alt dizinleri içerir:

  • public: Akıllı çamaşır makinesinin durumunu kolayca kontrol edip izlemek için bir ön uç kullanıcı arayüzü.
  • functions: Firebase için Cloud Functions ve Firebase Realtime Database ile akıllı çamaşır makinesini yöneten, tam olarak uygulanmış bir bulut hizmeti.

Sağlanan bulut istek karşılama, index.js'da aşağıdaki işlevleri içerir:

  • fakeauth: Hesap bağlama için yetkilendirme uç noktası
  • faketoken: Hesap bağlama için jeton uç noktası
  • smarthome: Akıllı ev amacını yerine getirme uç noktası
  • reportstate: Cihaz durumu değişikliklerinde Home Graph API'yi çağırır.
  • requestsync: Hesap yeniden bağlama gerektirmeden kullanıcı cihazı güncellemelerini etkinleştirir.

Firebase'e bağlanma

washer-start dizinine gidin, ardından Firebase CLI'yi entegrasyon projenizle birlikte ayarlayın:

cd washer-start
firebase use <project-id>

Firebase projesini yapılandırma

Bir Firebase projesi başlatın.

firebase init

CLI özelliklerini, Realtime Database'i ve Functions özelliğini seçin.

? 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

Bu işlem, projeniz için gerekli API'leri ve özellikleri başlatır.

İstendiğinde Realtime Database'i başlatın. Veritabanı örneği için varsayılan konumu kullanabilirsiniz.

? 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

Başlangıç projesi kodunu kullandığınız için güvenlik kuralları için varsayılan dosyayı seçin ve mevcut veritabanı kuralları dosyasının üzerine yazmadığınızdan emin olun.

? 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

Projenizi yeniden başlatıyorsanız kod tabanını başlatmak mı yoksa üzerine yazmak mı istediğiniz sorulduğunda Üzerine yaz'ı seçin.

? Would you like to initialize a new codebase, or overwrite an existing one?
Overwrite

İşlevlerinizi yapılandırırken varsayılan dosyaları kullanmalı ve proje örneğindeki mevcut index.js ve package.json dosyalarının üzerine yazmadığınızdan emin olmalısınız.

? 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

Projenizi yeniden başlatıyorsanız functions/.gitignore dosyasını başlatmak veya üzerine yazmak isteyip istemediğiniz sorulduğunda Hayır'ı seçin.

? File functions/.gitignore already exists. Overwrite?
No
? Do you want to install dependencies with npm now?
Yes

ESLint yanlışlıkla etkinleştirildiyse devre dışı bırakmak için iki yöntem vardır:

  1. GUI'yi kullanarak projenin altındaki ../functions klasörüne gidin, gizli dosyayı .eslintrc.js seçin ve silin. Bunu, benzer ada sahip .eslintrc.json ile karıştırmayın.
  2. Komut satırını kullanma:
    cd functions
    rm .eslintrc.js
    

Firebase'e dağıtma

Bağımlılıkları yükleyip projenizi yapılandırdığınıza göre artık uygulamayı ilk kez çalıştırmaya hazırsınız.

firebase deploy

Görmeniz gereken konsol çıkışı şudur:

...

✔ Deploy complete!

Project Console: https://console.firebase.google.com/project/<project-id>/overview
Hosting URL: https://<project-id>.web.app

Bu komut, bir web uygulamasının yanı sıra çeşitli Cloud Functions for Firebase işlevlerini dağıtır.

Web uygulamasını görüntülemek için tarayıcınızda Hosting URL'yi (https://<firebase-project-id>.web.app) açın. Aşağıdaki arayüzü görürsünüz:

5845443e94705557.png

Bu web kullanıcı arayüzü, cihaz durumlarını görüntülemek veya değiştirmek için kullanılan bir üçüncü taraf platformunu temsil eder. Veritabanınızı cihaz bilgileriyle doldurmaya başlamak için GÜNCELLE'yi tıklayın. Sayfada herhangi bir değişiklik görmezsiniz ancak çamaşır makinenizin mevcut durumu veritabanında saklanır.

Şimdi, dağıttığınız bulut hizmetini Geliştirici Konsolu'nu kullanarak Google Asistan'a bağlama zamanı.

Developer Console projenizi yapılandırma

Geliştir sekmesinde etkileşiminiz için bir Görünen Ad ekleyin. Bu ad, Google Home uygulamasında görünür.

Görünen ad ekleme

Uygulama markalama bölümünde, uygulama simgesi için 144 x 144 piksel boyutunda ve .png adlı bir png dosyası yükleyin.

Uygulama simgesi ekleme

Hesap bağlama'yı etkinleştirmek için şu hesap bağlama ayarlarını kullanın:

Müşteri Kimliği

ABC123

İstemci gizli anahtarı

DEF456

Yetkilendirme URL'si

https://us-central1-<project-id>.cloudfunctions.net/fakeauth

Jeton URL'si

https://us-central1-<project-id>.cloudfunctions.net/faketoken

Hesap bağlama URL&#39;lerini güncelleme

Cloud fulfillment URL altında, akıllı ev amaçları için istek karşılama sağlayan Cloud Functions işlevinizin URL'sini girin.

https://us-central1-<project-id>.cloudfunctions.net/smarthome

Cloud Functions URL&#39;si ekleme

Proje yapılandırmanızı kaydetmek için Kaydet'i, projenizde testi etkinleştirmek için Sonraki: Test'i tıklayın.

Buluttan buluta entegrasyonunuzu test etme

Artık cihaz durumunu Asistan'a bağlamak için gereken webhook'ları uygulamaya başlayabilirsiniz.

Buluttan buluta entegrasyonunuzu test etmek için projenizi bir Google Hesabı'na bağlamanız gerekir. Bu, aynı hesapta oturum açılmış Google Asistan yüzeyleri ve Google Home uygulaması üzerinden test yapmanızı sağlar.

  1. Telefonunuzda Google Asistan ayarlarını açın. Konsolda oturum açtığınız hesapla giriş yapmanız gerektiğini unutmayın.
  2. Google Asistan > Ayarlar > Ev Kontrolü'ne (Asistan bölümünde) gidin.
  3. Sağ üstteki arama simgesini tıklayın.
  4. Belirli test uygulamanızı bulmak için [test] önekini kullanarak test uygulamanızı arayın.
  5. İlgili öğeyi seçin. Ardından Google Asistan, hizmetinizde kimlik doğrulaması yapar ve hizmetinizden kullanıcıya ait cihazların listesini sağlamasını isteyen bir SYNC isteği gönderir.

Google Home uygulamasını açıp çamaşır makinenizi görüp göremediğinizi doğrulayın.

ae252220753726f6.png

Google Home uygulamasında sesli komutları kullanarak çamaşır makinesini kontrol edebildiğinizi doğrulayın. Ayrıca, cihaz durumunun bulut üzerinden karşılama hizmetinizin ön uç web kullanıcı arayüzünde değiştiğini görmeniz gerekir.

Temel bir yıkayıcı dağıttığınıza göre artık cihazınızda kullanılabilen modları özelleştirebilirsiniz.

4. Mod ekleme

action.devices.traits.Modes özelliği, bir cihazın bir mod için rastgele sayıda ayara sahip olmasını sağlar. Bu ayarlardan yalnızca biri aynı anda ayarlanabilir. Çamaşır yükünün boyutunu (küçük, orta veya büyük) tanımlamak için çamaşır makinesine bir mod ekleyeceksiniz.

Senkronizasyon yanıtını güncelleme

Yeni özellik hakkında bilgileri functions/index.js içindeki SYNC yanıtınıza eklemeniz gerekir. Bu veriler, aşağıdaki kod snippet'inde gösterildiği gibi traits dizisinde ve attributes nesnesinde görünür.

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

Yeni EXECUTE amaç komutları ekleme

EXECUTE amacınıza, aşağıdaki kod snippet'inde gösterildiği gibi action.devices.commands.SetModes komutunu ekleyin.

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

QUERY yanıtını güncelleme

Ardından, çamaşır makinesinin mevcut durumunu bildirmek için QUERY yanıtınızı güncelleyin.

Durumu Realtime Database'de depolandığı şekilde elde etmek için güncellenen değişiklikleri queryFirebase ve queryDevice işlevlerine ekleyin.

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

Rapor Durumunu Güncelleme

Son olarak, çamaşır makinesinin mevcut yük ayarını Home Graph'a bildirmek için reportstate işlevinizi güncelleyin.

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

Firebase'e dağıtma

Güncellenen entegrasyonu dağıtmak için aşağıdaki komutu çalıştırın:

firebase deploy --only functions

Dağıtım tamamlandıktan sonra web kullanıcı arayüzüne gidin ve araç çubuğunda Yenile ae8d3b25777a5e30.png düğmesini tıklayın. Bu işlem, Asistan'ın güncellenmiş SYNC yanıt verilerini alması için bir senkronizasyon isteğini tetikler.

bf4f6a866160a982.png

Artık çamaşır makinesinin modunu ayarlamak için komut verebilirsiniz. Örneğin:

"Ok Google, çamaşır makinesinin yükünü büyük olarak ayarla."

Ayrıca, çamaşır makinenizle ilgili şu gibi sorular da sorabilirsiniz:

"Ok Google, çamaşır makinesinin yükü nedir?"

5. Açma/kapatma düğmeleri ekleme

action.devices.traits.Toggles özelliği, cihazın adlandırılmış ve doğru ya da yanlış durumuna sahip yönlerini (ör. çamaşır makinesinin turbo modda olup olmadığı) temsil eder.

Senkronizasyon yanıtını güncelleme

SYNC yanıtınıza yeni cihaz özelliğiyle ilgili bilgileri eklemeniz gerekir. Aşağıdaki kod snippet'inde gösterildiği gibi traits dizisinde ve attributes nesnesinde görünür.

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',
            }],
          }],
        },
      }],
    },
  };
});

Yeni EXECUTE amaç komutları ekleme

EXECUTE amacınıza, aşağıdaki kod snippet'inde gösterildiği gibi action.devices.commands.SetToggles komutunu ekleyin.

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

QUERY yanıtını güncelleme

Son olarak, çamaşır makinesinin turbo modunu bildirmek için QUERY yanıtınızı güncellemeniz gerekir. Gerçek Zamanlı Veritabanı'nda depolanan açma/kapatma durumunu elde etmek için queryFirebase ve queryDevice işlevlerine güncellenen değişiklikleri ekleyin.

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

Rapor Durumunu Güncelleme

Son olarak, çamaşır makinesinin turbo moduna ayarlanıp ayarlanmadığını Home Graph'a bildirmek için reportstate işlevinizi güncelleyin.

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

Firebase'e dağıtma

Güncellenen işlevleri dağıtmak için aşağıdaki komutu çalıştırın:

firebase deploy --only functions

Dağıtım tamamlandıktan sonra Senkronizasyon İsteği'ni tetiklemek için web kullanıcı arayüzünde Yenile ae8d3b25777a5e30.png düğmesini tıklayın.

Artık şu komutu vererek çamaşır makinesini turbo moduna ayarlayabilirsiniz:

"Ok Google, çamaşır makinesini turbo moduna ayarla."

Ayrıca, aşağıdaki soruları sorarak çamaşır makinenizin turbo modunda olup olmadığını da kontrol edebilirsiniz:

"Ok Google, çamaşır makinem turbo modunda mı?"

6. Hataları ve istisnaları bildirme

Buluttan buluta entegrasyonunuzdaki hata işleme özelliği, sorunlar EXECUTE ve QUERY yanıtlarının başarısız olmasına neden olduğunda kullanıcıları bilgilendirmenize olanak tanır. Bildirimler, kullanıcılarınız akıllı cihazınız ve entegrasyonunuzla etkileşimde bulunduğunda daha olumlu bir kullanıcı deneyimi oluşturur.

EXECUTE veya QUERY isteği her başarısız olduğunda entegrasyonunuz bir hata kodu döndürmelidir. Örneğin, bir kullanıcı çamaşır makinesini kapağı açıkken çalıştırmaya çalıştığında hata vermek istiyorsanız EXECUTE yanıtınız aşağıdaki kod snippet'i gibi görünür:

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [
      {
        "ids": [
          "456"
        ],
        "status": "ERROR",
        "errorCode": "deviceLidOpen"
      }
    ]
  }
}

Artık bir kullanıcı çamaşır makinesini başlatmak istediğinde Asistan şu yanıtı veriyor:

"Çamaşır makinesinin kapağı açık. Lütfen kapatıp tekrar deneyin."

İstisnalar hatalara benzer ancak bir uyarının bir komutla ilişkilendirildiği zamanı gösterir. Bu komut, başarılı yürütmeyi engelleyebilir veya engellemeyebilir. Bir istisna, StatusReport özelliği kullanılarak pil seviyesi veya son durum değişikliği gibi ilgili bilgileri sağlayabilir. Engelleyici olmayan istisna kodları SUCCESS durumuyla, engelleyici istisna kodları ise EXCEPTIONS durumuyla birlikte döndürülür.

İstisna içeren bir örnek yanıtı aşağıdaki kod snippet'inde bulabilirsiniz:

{
  "requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
  "payload": {
    "commands": [{
      "ids": ["123"],
      "status": "SUCCESS",
      "states": {
        "online": true,
        "isPaused": false,
        "isRunning": false,
        "exceptionCode": "runCycleFinished"
      }
    }]
  }
}

Asistan şu yanıtı verir:

"Çamaşır makinesinin çalışması bitti."

Çamaşır makineniz için hata raporlaması eklemek üzere functions/index.js dosyasını açın ve aşağıdaki kod snippet'inde gösterildiği gibi hata sınıfı tanımını ekleyin:

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

Hata kodunu ve hata durumunu döndürmek için yürütme yanıtını güncelleyin:

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

Asistan artık kullanıcılarınıza bildirdiğiniz hata kodları hakkında bilgi verebilir. Sonraki bölümde bu konuyla ilgili bir örnek verilmiştir.

7. İkincil kullanıcı doğrulaması ekleme

Cihazınızda yazılım güncelleme veya kilit açma gibi güvenli hale getirilmesi gereken ya da belirli bir yetkili kullanıcı grubuyla sınırlandırılması gereken modlar varsa entegrasyonunuza ikincil kullanıcı doğrulaması eklemeniz gerekir.

İkincil kullanıcı doğrulamasını tüm cihaz türlerinde ve özelliklerinde uygulayabilir, güvenlik sorgulamasının her seferinde mi yoksa belirli kriterler karşılandığında mı gerçekleşeceğini özelleştirebilirsiniz.

Desteklenen üç doğrulama türü vardır:

  • No challenge: Kimlik doğrulama meydan okuması kullanmayan bir istek ve yanıt (varsayılan davranış budur)
  • ackNeeded—Açıkça onay (evet veya hayır) gerektiren ikincil bir kullanıcı doğrulaması
  • pinNeeded—Kişisel kimlik numarası (PIN) gerektiren ikincil bir kullanıcı doğrulaması

Bu codelab'de, çamaşır makinesini açma komutuna bir ackNeeded zorluğu ekleyin ve ikincil doğrulama zorluğu başarısız olursa hata döndürme işlevini kullanın.

functions/index.js dosyasını açın ve aşağıdaki kod snippet'inde gösterildiği gibi hata kodunu ve sorgu türünü döndüren bir hata sınıfı tanımı ekleyin:

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

Ayrıca, yürütme yanıtını challengeNeeded hatasını aşağıdaki şekilde döndürecek şekilde güncellemeniz gerekir:

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

Son olarak, çamaşır makinesini açmak veya kapatmak için açıkça onay verilmesini zorunlu kılmak üzere updateDevice öğesini değiştirin.

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

Firebase'e dağıtma

Güncellenen işlevi dağıtmak için aşağıdaki komutu çalıştırın:

firebase deploy --only functions

Güncellenen kodu dağıttıktan sonra, Asistan'dan çamaşır makinenizi açmasını veya kapatmasını istediğinizde işlemi sözlü olarak onaylamanız gerekir. Örneğin:

Siz: "Ok Google, çamaşır makinesini aç."

Asistan: "Çamaşır makinesini açmak istediğinizden emin misiniz?"

Siz: "Evet."

Firebase günlüklerinizi açarak ikincil kullanıcı doğrulama akışının her adımıyla ilgili ayrıntılı yanıtı da görebilirsiniz.

289dbe48f4bb8106.png

8. Tebrikler

674c4f4392e98c1.png

Tebrikler! Modes ve Toggles özellikleri aracılığıyla buluttan buluta entegrasyonların özelliklerini genişlettiniz ve ikincil kullanıcı doğrulamasıyla yürütülmelerini güvenli hale getirdiniz.

Daha fazla bilgi

Daha ayrıntılı bilgi edinmek için uygulayabileceğiniz bazı fikirler:

  • Cihazlarınıza yerel yürütme özellikleri ekleyin.
  • Cihaz durumunuzu değiştirmek için farklı bir ikincil kullanıcı doğrulama zorluğu türü kullanın.
  • RunCycle özelliği QUERY yanıtını dinamik olarak güncellenecek şekilde güncelleyin.
  • Bu GitHub örneğini inceleyin.