Google Home용 «스마트 장치» 구축
44696 단어 phplaravelgooglehome
Google 홈 프로젝트 생성
Cloud-to-cloud 통합 방법을 사용합니다. 따라서 Actions on Google 콘솔로 이동하여 새 프로젝트를 생성해야 합니다.
그리고 Smart Home Action의 이름을 지정해야 합니다.
OAuth2 및 백엔드 서버 설정
Cloud-to-cloud 통합이 필요합니다OAuth2 스마트 장치 서비스를 Google Home 애플리케이션에 연결하기 위한 서버. 이 기사에서는 Laravel framework 및 Passport package 으로 구현합니다. Laravel 및 Passport 설치, 데이터베이스 설정과 같은 기본 단계를 통과하고 가짜 사용자를 만들거나 예제 코드here를 찾을 수 있습니다. 모든 추가 작업은 다음에 설명합니다.
계정 연결
Laravel 프로젝트로 이동하고 명령을 실행하여 Google Home용 OAuth 클라이언트 정보를 생성합니다.
$ php artisan passport:client
Which user ID should the client be assigned to?:
> 1
What should we name the client?:
> Google
Where should we redirect the request after authorization?:
> https://oauth-redirect.googleusercontent.com/r/{your project id}
New client created successfully.
Client ID: 9700039b-92b7-4a79-a421-152747b9a257
Client secret: 813PEwdTAq7kf7vRXuyd75dJEaSzAIZ1GDWjIyRM
수신된 데이터 및 oauth2 끝점을 프로젝트의 계정 연결 설정에 전달합니다.
백엔드 구현
기기 상태에 대해 Google Home에 알리려면 Google Home이 Fulfillment URL로 데이터를 요청했을 때 데이터를 반환해야 합니다. Google Home은 SYNC, QUERY 및 EXECUTE의 세 가지 유형으로 데이터를 전송합니다.
동기화 요청에 대한 응답은 모든 장치 및 해당 기능 목록을 반환합니다.
# Request example
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"inputs": [{
"intent": "action.devices.SYNC"
}]
}
# Response example
{
"requestId": "6894439706274654512",
"payload": {
"agentUserId": "user123",
"devices": [
{
"id": 1,
"type": "action.devices.types.THERMOSTAT",
"traits": [
"action.devices.traits.TemperatureSetting"
],
"name": {
"name": "Thermostat"
},
"willReportState": true,
"attributes": {
"availableThermostatModes": [
"off",
"heat",
"cool"
],
"thermostatTemperatureRange": {
"minThresholdCelsius": 18,
"maxThresholdCelsius": 30
},
"thermostatTemperatureUnit": "C"
},
"deviceInfo": {
"manufacturer": "smart-home-inc"
}
}
]
}
}
쿼리 요청에 대한 응답에는 요청된 장치에서 지원하는 각 특성에 대한 전체 상태 세트가 포함되어야 합니다.
# Request example
{
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
"inputs": [{
"intent": "action.devices.QUERY",
"payload": {
"devices": [{
"id": "1"
}]
}
}]
}
# Response example
{
"requestId": "6894439706274654514",
"payload": {
"agentUserId": "user123",
"devices": {
"1": {
"status": "SUCCESS",
"online": true,
"thermostatMode": "cool",
"thermostatTemperatureSetpoint": 23,
"thermostatTemperatureAmbient": 10,
"thermostatHumidityAmbient": 10
}
}
}
}
실행 요청은 Query와 동일한 데이터를 포함하지만 장치 그룹에 주어진 명령을 포함할 수 있습니다(응답은 Query와 동일).
# request example
{
"inputs": [
{
"context": {
"locale_country": "US",
"locale_language": "en"
},
"intent": "action.devices.EXECUTE",
"payload": {
"commands": [
{
"devices": [
{
"id": "1"
}
],
"execution": [
{
"command": "action.devices.commands.ThermostatTemperatureSetpoint",
"params": {
"thermostatTemperatureSetpoint": 25.5
}
}
]
}
]
}
}
],
"requestId": "15039538743185198388"
}
장치 개체 이해
동기화 요청의 장치 개체는 이름, 장치 정보(특성 포함), 포함된 열차를 기반으로 하는 속성과 같은 장치에 대한 정보를 포함해야 합니다.
# Device object on sync request
{
"id": 1,
"type": "action.devices.types.THERMOSTAT",
"traits": [
"action.devices.traits.TemperatureSetting"
],
"name": {
"name": "Thermostat"
},
"willReportState": true,
"attributes": {
"availableThermostatModes": [
"off",
"heat",
"cool"
],
"thermostatTemperatureRange": {
"minThresholdCelsius": 18,
"maxThresholdCelsius": 30
},
"thermostatTemperatureUnit": "C"
},
"deviceInfo": {
"manufacturer": "smart-home-inc"
}
}
그리고 Quest 또는 Execute의 기기 상태를 포함해야 합니다.
# Device object on Query or Execute request
{
"status": "SUCCESS",
"online": true,
"thermostatMode": "cool",
"thermostatTemperatureSetpoint": 24,
"thermostatTemperatureAmbient": 10,
"thermostatHumidityAmbient": 10
}
장치 상태 반환 및 저장
Laravel 프로젝트로 이동하여 온도 조절기 모델을 만듭니다.
php artisan make:model Thermostat -m
# database/migrations/2022_08_11_154357_create_thermostats_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up()
{
Schema::create('thermostats', function (Blueprint $table) {
$table->id();
$table->boolean('online')->default(false);
$table->string('mode');
$table->unsignedInteger('current_temperature')->default(0);
$table->unsignedInteger('expected_temperature')->default(15);
$table->unsignedInteger('humidity')->default(0);
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('thermostats');
}
};
# app/Models/Thermostate.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Thermostat extends Model
{
protected $fillable = [
'online',
'mode',
'current_temperature',
'expected_temperature',
'humidity',
];
protected $casts = [
'online' => 'boolean',
];
}
php artisan migrate
처리 URL 경로 구현
# routes/api.php
<?php
use App\Http\Controllers\FulfillmentController;
use Illuminate\Support\Facades\Route;
Route::post('/', FulfillmentController::class);
<?php
namespace App\Http\Controllers;
use App\Models\Thermostat;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
class FulfillmentController extends Controller
{
public function __invoke(Request $request)
{
$response = null;
// Extract request type
switch ($request->input('inputs.0.intent')) {
case 'action.devices.QUERY':
$response = $this->queryResponse();
break;
case 'action.devices.SYNC':
$response = $this->syncRequest();
break;
case 'action.devices.EXECUTE':
$response = $this->syncExecute($this->syncExecute($request->input('inputs.0.payload.commands'))); // Extract list of commands
break;
}
return $response;
}
private function queryResponse()
{
$devices = [];
// Extract our devices states
foreach (Thermostat::all() as $thermostat) {
$devices[$thermostat->id] = [
'status' => 'SUCCESS',
'online' => $thermostat->online,
'thermostatMode' => $thermostat->mode,
'thermostatTemperatureSetpoint' => $thermostat->expected_temperature,
'thermostatTemperatureAmbient' => $thermostat->current_temperature,
'thermostatHumidityAmbient' => $thermostat->humidity,
];
}
return response([
'requestId' => "6894439706274654514",
'payload' => [
"agentUserId" => "user123",
'devices' => $devices,
],
]);
}
private function syncRequest()
{
$devices = [];
// Define our devices
foreach (Thermostat::all() as $thermostat) {
$devices[] = [
'id' => $thermostat->id,
'type' => "action.devices.types.THERMOSTAT",
'traits' => [
"action.devices.traits.TemperatureSetting"
],
'name' => [
'name' => 'Thermostat'
],
'willReportState' => true,
'attributes' => [
'availableThermostatModes' => [
'off',
'heat',
'cool',
],
'thermostatTemperatureRange' => [
'minThresholdCelsius' => 18,
'maxThresholdCelsius' => 30,
],
'thermostatTemperatureUnit' => 'C'
],
'deviceInfo' => [
'manufacturer' => 'smart-home-inc',
],
];
}
return response([
'requestId' => "6894439706274654512",
'payload' => [
"agentUserId" => "user123",
'devices' => $devices,
],
]);
}
private function syncExecute(array $commands)
{
foreach ($commands as $command) {
// Get devices for execute command
$thermostats = Thermostat::whereIn('id', Arr::pluck($command['devices'], 'id'))->get();
foreach ($command['execution'] as $executionItem) {
switch ($executionItem['command']) {
// Handle set point command and save it in our model
case 'action.devices.commands.ThermostatTemperatureSetpoint':
foreach ($thermostats as $thermostat) {
$thermostat->update([
'expected_temperature' => $executionItem['params']['thermostatTemperatureSetpoint'],
]);
}
break;
// Handle set set mode command and save it in our model
case 'action.devices.commands.ThermostatSetMode':
foreach ($thermostats as $thermostat) {
$thermostat->update([
'mode' => $executionItem['params']['thermostatMode'],
]);
}
break;
}
}
}
// It not necessary to return data for command request
return response([]);
}
}
콘솔 작업으로 돌아가서 프로젝트 설정에서 이행 URL을 설정합니다.
그리고 데이터베이스에 장치를 생성합니다.
인증 프로세스 간소화:
우리는 인증 세부 사항에 관심이 없기 때문에 구현 로그인 페이지를 건너뛰고 인증된 사용자를 강제할 수 있습니다.
# app/Providers/AppServiceProvider.php
<?php
namespace App\Providers;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
//
}
public function boot()
{
Auth::setUser(User::first());
}
}
Google Home과 백엔드 연결
이전 작업 후에는 Actions Console 프로젝트를 만드는 데 사용된 것과 동일한 계정으로 인증된 Google Home 앱으로 백엔드를 테스트할 수 있습니다.
연결하면 기기가 Google Home에 표시됩니다.
이제 "장치"를 제어할 수 있으며 해당 상태가 데이터베이스에 저장됩니다. 동기화(계정 다시 연결), 쿼리(스와이프 업데이트 제스처) 및 실행(모드 변경 시도)을 트리거할 수 있습니다.
사용 가능한 장치 유형 및 특성에 대해 자세히 알아볼 수 있습니다Here.
Reference
이 문제에 관하여(Google Home용 «스마트 장치» 구축), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/davidnadejdin/build-your-for-google-home-2b2a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)