1. Başlamadan önce
Nesnelerin İnterneti (IoT) geliştiricisi olarak kullanıcılarınıza Google Home uygulamasındaki dokunma kontrolleri ve Asistan'la sesli komutlar kullanarak cihazlarını kontrol etmelerine olanak tanıyan akıllı ev İşlemleri oluşturabilirsiniz.
Akıllı ev İşlemleri, ev ve cihazları hakkında bağlamsal veriler sağlamak için Home Graph'ten yararlanır ve evin mantıksal bir haritasını oluşturur. Bu bağlamda Asistan, kullanıcının evdeki konumuna göre isteklerini daha doğal bir şekilde anlayabilir. Örneğin, Home Graph farklı üreticilerin termostat, lamba, fan ve elektrik süpürgesi gibi birden fazla cihaz türünü içeren bir oturma odası konseptini saklayabilir.
Ön koşullar
- Akıllı ev işlemi oluşturma Geliştirici Kılavuzu
Neler derleyeceksiniz?
Bu codelab'de sanal bir akıllı çamaşır makinesini yöneten bir bulut hizmeti yayınlayacak, ardından akıllı ev Action'ı derleyip Asistan'a bağlayacaksınız.
Neler öğreneceksiniz?
- Akıllı ev bulut hizmeti dağıtma
- Hizmetinizi Asistan'a bağlama
- Cihaz durumu değişiklikleri Google'da nasıl yayınlanır?
Gerekenler
- Google Chrome gibi bir web tarayıcısı
- Google Home uygulamasının yüklü olduğu bir iOS veya Android cihaz
- Node.js 10.16 veya sonraki sürümler
- Google Cloud faturalandırma hesabı
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 veri paylaşma şartı SDK'ya özel değildir. Bu verileri paylaşmak için, henüz yoksa bir Google Hesabı oluşturun. Herhangi bir Google Hesabını kullanabilirsiniz, geliştirici hesabınız olması gerekmez.
Asistan'la kullanmak istediğiniz Google Hesabı'nın Etkinlik kontrolleri sayfasını açın.
Aşağıdaki açma/kapatma anahtarlarının etkin olduğundan 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
Actions projesi oluşturma
- Actions on Google Geliştirici Konsolu'na gidin.
- Yeni Proje'yi tıklayın, proje için bir ad girin ve PROJE OLUŞTUR'u tıklayın.
Akıllı Ev uygulamasını seçme
Actions Console'daki Genel Bakış ekranında Akıllı ev'i seçin.
Akıllı ev deneyim kartını seçip Derlemeye Başla'yı tıkladığınızda proje konsolunuza yönlendirilirsiniz.
Firebase CLI'yı yükleme
Firebase Komut Satırı Arayüzü (CLI), web uygulamalarınızı yerel olarak sunmanızı ve web uygulamanızı Firebase barındırmaya dağıtmanızı sağlar.
CLI'yi yüklemek için terminalden aşağıdaki npm komutunu çalıştırın:
npm install -g firebase-tools
KSA'nın doğru şekilde yüklendiğini doğrulamak için şu komutu çalıştırın:
firebase --version
Aşağıdaki komutu çalıştırarak Firebase CLI'yı Google Hesabınızla yetkilendirin:
firebase login
3. Başlangıç uygulamasını çalıştırın
Geliştirme ortamınızı ayarladığınıza göre artık başlangıç projesini dağıtarak her şeyin doğru şekilde yapılandırıldığını doğrulayabilirsiniz.
Kaynak kodunu alma
Bu codelab örneğini geliştirme makinenize indirmek için aşağıdaki bağlantıyı tıklayın:
...veya komut satırından GitHub deposunu klonlayabilirsiniz:
git clone https://github.com/google-home/smarthome-washer.git
Proje hakkında
Başlangıç projesi aşağıdaki alt dizinleri içerir:
public:
Akıllı çamaşır makinesinin durumunu kolayca kontrol etmenizi ve izlemenizi sağlayan ön uç kullanıcı arayüzü.functions:
Cloud Functions for Firebase ve Firebase Realtime Database ile akıllı çamaşır makinesini yöneten, eksiksiz bir bulut hizmeti.
Firebase'e bağlanma
washer-start
dizinine gidin, ardından Actions projenizle Firebase CLI'ı ayarlayın:
cd washer-start firebase use <project-id>
Firebase projesini yapılandırın
Bir Firebase projesini başlatın.
firebase init
CLI özellikleri, Gerçek Zamanlı Veritabanı, İşlevler ve Firebase Hosting'i içeren Barındırma özelliğini seçin.
? Which Firebase CLI features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. ❯◉ Realtime Database: Configure a security rules file for Realtime Database and (optionally) provision default instance ◯ Firestore: Configure security rules and indexes files for Firestore ◉ Functions: Configure a Cloud Functions directory and its files ◉ Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys ◯ Hosting: 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
Bu işlem, projeniz için gerekli API'leri ve özellikleri ilk kullanıma hazırlar.
İ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ıç proje kodunu kullandığınızdan, 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 bir kod tabanını başlatmak mı yoksa üzerine yazmak mı istediğiniz sorulduğunda Üzerine yaz seçeneğini belirleyin.
? Would you like to initialize a new codebase, or overwrite an existing one? Overwrite
İşlevlerinizi yapılandırırken varsayılan dosyaları kullanmanız ve proje örneğindeki mevcut index.js ve package.json dosyalarının üzerine yazmadığınızdan emin olun.
? 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 işlevleri başlatmak mı yoksa işlevlerin üzerine yazmak mı istediğiniz sorulduğunda Hayır'ı seçin.
? File functions/.gitignore already exists. Overwrite? No
? Do you want to install dependencies with npm now? Yes
Son olarak, Hosting kurulumunuzu proje kodunda public
dizinini kullanacak şekilde yapılandırın ve mevcut index.html dosyasını kullanın. ESLint'i kullanmanız istendiğinde Hayır'ı seçin.
? What do you want to use as your public directory? public ? Configure as a single-page app (rewrite all urls to /index.html)? Yes ? Set up automatic builds and deploys with GitHub? No ? File public/index.html already exists. Overwrite? No
ESLint yanlışlıkla etkinleştirildiyse bunu devre dışı bırakmak için kullanılabilecek iki yöntem vardır:
- GUI'yi kullanarak projenin altındaki
../functions
klasörüne gidin,.eslintrc.js
gizli dosyasını seçin ve silin. Bunu benzer şekilde adlandırılmış.eslintrc.json
ile karıştırmayın. - Komut satırını kullanma:
cd functions rm .eslintrc.js
Firebase yapılandırmanızın doğru ve eksiksiz olduğundan emin olmak için firebase.json
dosyasını app-done
dizininden app-start
dizinine kopyalayıp app-start
'deki dosyanın üzerine yazın.
app-start
dizininde:
cp -vp ../app-done/firebase.json .
Firebase'e dağıtma
Bağımlılıkları yüklediğinize ve projenizi yapılandırdığınıza göre, uygulamayı ilk kez çalıştırmaya hazırsınız.
firebase deploy
Aşağıdaki konsol çıkışını görürsünüz:
... ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/<project-id>/overview Hosting URL: https://<project-id>.web.app
Bu komut, birkaç Cloud Functions for Firebase ile birlikte bir web uygulamasını dağıtır.
Web uygulamasını görüntülemek için tarayıcınızda (https://<project-id>.web.app
) Hosting URL'yi (Barındırma URL'si) açın. Aşağıdaki arayüzü görürsünüz:
Bu web kullanıcı arayüzü, cihaz durumlarını görüntülemek veya değiştirmek için kullanılan üçüncü taraf platformu 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 Actions konsolunu kullanarak Google Asistan'a bağlama zamanı.
Actions Console projenizi yapılandırma
Genel Bakış > İşleminizi Derleme bölümünde, İşlem Ekle'yi seçin. Akıllı ev amaçları için istek karşılama sağlayan Cloud Functions işlevinizin URL'sini girip Kaydet'i tıklayın.
https://us-central1-<project-id>.cloudfunctions.net/smarthome
Geliştirme > Çağrı sekmesinde İşleminiz için bir Görünen Ad ekleyip Kaydet'i tıklayın. Bu ad Google Home uygulamasında görünecektir.
Hesap bağlamayı etkinleştirmek için sol gezinme menüsünde Geliştirme > Hesap bağlama'yı seçin. Şu hesap bağlama ayarlarını kullanın:
İstemci Kimliği |
|
İstemci gizli anahtarı |
|
Yetkilendirme URL'si |
|
Jeton URL'si |
|
Hesap bağlama yapılandırmanızı kaydetmek için Kaydet'i tıklayın, ardından projenizde testi etkinleştirmek için Test'i tıklayın.
Simulator sayfasına yönlendirilirsiniz. "Test şimdi etkin " seçeneğini görmüyorsanız testin etkinleştirildiğini doğrulamak için Testi Sıfırla'yı tıklayın.
Artık cihazın durumunu Asistan'a bağlamak için gereken webhook'ları uygulamaya başlayabilirsiniz.
4. Çamaşır makinesi oluştur
İşleminizi yapılandırdığınıza göre cihaz ekleyebilir ve veri gönderebilirsiniz. Bulut hizmetinizin aşağıdaki amaçları işlemesi gerekir:
- Asistan, kullanıcının hangi cihazları bağladığını bilmek istediğinde
SYNC
amacı oluşur. Bu, kullanıcı bir hesap bağladığında hizmetinize gönderilir. Kullanıcının tüm cihazlarını ve özelliklerini içeren bir JSON yükü ile yanıt vermelisiniz. - Asistan, bir cihazın mevcut durumunu veya durumunu öğrenmek istediğinde
QUERY
amacı oluşur. İstenen her cihazın durumunu içeren bir JSON yüküyle yanıt vermelisiniz. - Asistan, bir cihazı kullanıcı adına kontrol etmek istediğinde
EXECUTE
amacı oluşur. İstenen her cihazın yürütme durumunu içeren bir JSON yüküyle yanıt vermelisiniz. - Kullanıcı, hesabının Asistan'la bağlantısını kaldırdığında
DISCONNECT
amacı oluşur. Bu kullanıcının cihazları için Asistan'a etkinlik göndermeyi durdurmanız gerekir.
Bu amaçları işlemek için daha önce dağıttığınız işlevleri aşağıdaki bölümlerde güncelleyeceksiniz.
SENKRONİZASYON yanıtını güncelle
Asistan'dan gelen isteklere yanıt vermek için gereken kodu içeren functions/index.js
uygulamasını açın.
Cihaz meta verilerini ve özelliklerini döndürerek bir SYNC
intent'i işlemeniz gerekir. onSync
dizisindeki JSON dosyasını, cihaz bilgilerini ve çamaşır makinesi için önerilen özellikleri içerecek şekilde güncelleyin.
index.js
app.onSync((body) => {
return {
requestId: body.requestId,
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',
],
name: {
defaultNames: ['My Washer'],
name: 'Washer',
nicknames: ['Washer'],
},
deviceInfo: {
manufacturer: 'Acme Co',
model: 'acme-washer',
hwVersion: '1.0',
swVersion: '1.0.1',
},
willReportState: true,
attributes: {
pausable: true,
},
}],
},
};
});
Firebase'e dağıtma
Güncellenen bulut istek karşılama isteğini Firebase CLI kullanarak dağıtın:
firebase deploy --only functions
Google Asistan'a bağlama
Akıllı ev İşleminizi test etmek için projenizi bir Google Hesabı'na bağlamanız gerekir. Böylece, aynı hesapta oturum açmış olan Google Asistan yüzeyleri ve Google Home uygulaması üzerinden test yapılabilir.
- Telefonunuzda Google Asistan ayarlarını açın. Konsolda kullandığınız hesapla giriş yapmanız gerektiğini unutmayın.
- Google Asistan > Ayarlar > Ev Kontrolü'ne (Asistan'ın altında) gidin.
- Sağ üstteki arama simgesini tıklayın.
- Spesifik test uygulamanızı bulmak için [test] önekini kullanarak test uygulamanızı arayın.
- O öğeyi seçin. Ardından Google Asistan, hizmetinizle kimlik doğrulaması yapar ve bir
SYNC
isteği göndererek hizmetinizden kullanıcı için cihaz listesini sağlamasını ister.
Google Home uygulamasını aç ve çamaşır makinesi cihazını görebildiğini doğrula.
5. Komutları ve sorguları işleme
Bulut hizmetiniz artık çamaşır makinesi cihazını Google'a düzgün bir şekilde raporladığına göre cihaz durumunu isteme ve komut gönderme özelliklerini eklemeniz gerekir.
QUERY amacını işleme
QUERY
amacı bir cihaz grubu içerir. Her cihazın mevcut durumuyla yanıt vermeniz gerekir.
functions/index.js
politikasında, amaç isteğinde yer alan hedef cihazların listesini işlemek için QUERY
işleyicisini düzenleyin.
index.js
app.onQuery(async (body) => {
const {requestId} = body;
const payload = {
devices: {},
};
const queryPromises = [];
const intent = body.inputs[0];
for (const device of intent.payload.devices) {
const deviceId = device.id;
queryPromises.push(queryDevice(deviceId)
.then((data) => {
// Add response to device payload
payload.devices[deviceId] = data;
}
));
}
// Wait for all promises to resolve
await Promise.all(queryPromises);
return {
requestId: requestId,
payload: payload,
};
});
İstekte yer alan her cihaz için Realtime Database'de depolanan mevcut durumu döndürün. Çamaşır makinesinin durum verilerini döndürmek için queryFirebase
ve queryDevice
işlevlerini güncelleyin.
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,
};
};
const queryDevice = async (deviceId) => {
const data = await queryFirebase(deviceId);
return {
on: data.on,
isPaused: data.isPaused,
isRunning: data.isRunning,
currentRunCycle: [{
currentCycle: 'rinse',
nextCycle: 'spin',
lang: 'en',
}],
currentTotalRemainingTime: 1212,
currentCycleRemainingTime: 301,
};
};
Yürütme amacını işleme
Cihaz durumunu güncellemek için komutları EXECUTE
amacı işler. Yanıt, her bir komutun durumunu (örneğin, SUCCESS
, ERROR
veya PENDING
) ve yeni cihaz durumunu döndürür.
functions/index.js
ürününde, güncelleme gerektiren özelliklerin listesini ve her komutla ilgili hedef cihaz grubunu işlemek için EXECUTE
işleyicisini düzenleyin:
index.js
app.onExecute(async (body) => {
const {requestId} = body;
// Execution results are grouped by status
const result = {
ids: [],
status: 'SUCCESS',
states: {
online: true,
},
};
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) => {
result.ids.push(device.id);
Object.assign(result.states, data);
})
.catch(() => functions.logger.error('EXECUTE', device.id)));
}
}
}
await Promise.all(executePromises);
return {
requestId: requestId,
payload: {
commands: [result],
},
};
});
Her komut ve hedef cihaz için Gerçek Zamanlı Veritabanı'nda istenen özelliğe karşılık gelen değerleri güncelleyin. Uygun Firebase referansını güncellemek ve güncellenmiş cihaz durumunu döndürmek için updateDevice
işlevini değiştirin.
index.js
const updateDevice = async (execution, deviceId) => {
const {params, command} = execution;
let state; let 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;
}
return ref.update(state)
.then(() => state);
};
6. İşleminizi test etme
Üç amacı da uyguladıktan sonra İşleminizin çamaşır makinesini kontrol edip etmediğini test edebilirsiniz.
Firebase'e dağıtma
Güncellenen bulut istek karşılama isteğini Firebase CLI kullanarak dağıtın:
firebase deploy --only functions
Çamaşır makinesini test etme
Artık aşağıdaki sesli komutlardan herhangi birini telefonunuzdan denediğinizde değerin değiştiğini görebilirsiniz:
"Ok Google, çamaşır makinemi aç."
"Ok Google, çamaşır makinemi duraklat."
"Ok Google, çamaşır makinemi durdur."
Sorular sorarak çamaşır makinenizin mevcut durumunu da görebilirsiniz.
"Ok Google, çamaşır makinem açık mı?"
"Ok Google, çamaşır makinem çalışıyor mu?"
"Ok Google, çamaşır makinem hangi devirde?"
Bu sorguları ve komutları, Firebase Konsolu'nun İşlevler bölümündeki işlevinizin altında görünen günlüklerde görüntüleyebilirsiniz. Firebase günlükleri hakkında daha fazla bilgi edinmek için Günlükleri yazma ve görüntüleme başlıklı makaleyi inceleyin.
Bu sorguları ve komutları, Google Cloud Console'da Günlük Kaydı > Günlük Gezgini'ne giderek de bulabilirsiniz. Google Cloud günlük kaydı hakkında daha fazla bilgi için Cloud Logging ile olay günlüklerine erişme başlıklı makaleyi inceleyin.
7. Güncellemeleri Google'a bildir
Bulut hizmetinizi akıllı ev amaçlarıyla tamamen entegre ederek kullanıcıların, cihazlarının mevcut durumunu kontrol edip sorgulamasını sağladınız. Ancak bu uygulamada yine de hizmetinizin, cihazın varlığı veya durumundaki değişiklikler gibi etkinlik bilgilerini proaktif şekilde Asistan'a göndermesini sağlayacak bir yöntem bulunmamaktadır.
Senkronizasyon İste'yi kullanarak, kullanıcılar cihaz eklediğinde veya kaldırdığında ya da cihaz özellikleri değiştiğinde yeni bir senkronizasyon isteğini tetikleyebilirsiniz. Rapor Durumu sayesinde bulut hizmetiniz, kullanıcılar fiziksel olarak bir cihazın durumunu değiştirdiğinde (ör. bir ışık anahtarını açtığında) veya durumu başka bir hizmet kullanarak değiştirdiğinde bulut hizmetiniz proaktif olarak bir cihazın durumunu Home Graph'e gönderebilir.
Bu bölümde, bu yöntemleri ön uç web uygulamasından çağırmak için kod ekleyeceksiniz.
HomeGraph API'yi etkinleştirme
HomeGraph API, bir kullanıcının Home Graph'inde cihazların ve cihaz durumlarının depolanmasını ve sorgulanmasını sağlar. Bu API'yi kullanmak için önce Google Cloud konsolunu açıp HomeGraph API'yi etkinleştirmeniz gerekir.
Google Cloud konsolunda İşlemlerinizle eşleşen projeyi seçtiğinizden emin olun <project-id>.
Ardından, HomeGraph API'nin API Kitaplığı ekranında Etkinleştir'i tıklayın.
Rapor Durumunu Etkinleştir
Realtime Database'e yazma işlemleri başlangıç projesindeki reportstate
işlevini tetikler. Veritabanına yazılan verileri yakalamak ve Rapor Durumu aracılığıyla Home Graph'te yayınlamak için functions/index.js
içinde reportstate
işlevini güncelleyin.
index.js
exports.reportstate = functions.database.ref('{deviceId}').onWrite(
async (change, context) => {
functions.logger.info('Firebase write event triggered Report State');
const snapshot = change.after.val();
const requestBody = {
requestId: 'ff36a3cc', /* Any unique ID */
agentUserId: USER_ID,
payload: {
devices: {
states: {
/* Report the current state of our washer */
[context.params.deviceId]: {
on: snapshot.OnOff.on,
isPaused: snapshot.StartStop.isPaused,
isRunning: snapshot.StartStop.isRunning,
},
},
},
},
};
const res = await homegraph.devices.reportStateAndNotification({
requestBody,
});
functions.logger.info('Report state response:', res.status, res.data);
});
Senkronizasyon İsteğini Etkinleştir
Ön uç web kullanıcı arayüzündeki simgenin yenilenmesi, başlangıç projesinde requestsync
işlevini tetikler. HomeGraph API'yi çağırmak için functions/index.js
içinde requestsync
işlevini uygulayın.
index.js
exports.requestsync = functions.https.onRequest(async (request, response) => {
response.set('Access-Control-Allow-Origin', '*');
functions.logger.info(`Request SYNC for user ${USER_ID}`);
try {
const res = await homegraph.devices.requestSync({
requestBody: {
agentUserId: USER_ID,
},
});
functions.logger.info('Request sync response:', res.status, res.data);
response.json(res.data);
} catch (err) {
functions.logger.error(err);
response.status(500).send(`Error requesting sync: ${err}`);
}
});
Firebase'e dağıtma
Firebase CLI'yi kullanarak güncellenmiş kodu dağıtın:
firebase deploy --only functions
Uygulamanızı test etme
Web kullanıcı arayüzünde Yenile düğmesini tıklayın ve Firebase konsol günlüğünde bir senkronizasyon isteği gördüğünüzü doğrulayın.
Ardından, ön uç web kullanıcı arayüzünde çamaşır makinesinin özelliklerini ayarlayın ve Güncelle'yi tıklayın. Firebase konsolu günlüklerinizde Google'a bildirilen durum değişikliğini görebildiğinizi doğrulayın.
8. Tebrikler
Tebrikler! Akıllı ev İşlemleri'ni kullanarak Asistan'ı bir cihazın bulut hizmetiyle başarıyla entegre ettiniz.
Daha fazla bilgi
Daha derine inmek için uygulayabileceğiniz bazı fikirler:
- Cihazınıza modes ve geçiş seçenekleri ekleyin.
- Cihazınıza daha fazla desteklenen özellik ekleyin.
- Akıllı ev için yerel uygulamaları keşfedin.
- Daha fazla bilgi edinmek için GitHub örneğimize göz atın.
Ayrıca, İşleminizi kullanıcılara yayınlamak için sertifikasyon süreci de dahil olmak üzere bir İşlemi test etme ve incelemeye gönderme hakkında daha fazla bilgi edinebilirsiniz.