- PVSM.RU - https://www.pvsm.ru -

Управление датчиками умного дома при помощи Google Assistant

Здравствуйте, коллеги в этом руководстве расскажу как при помощи Google Assistant и протокола mqtt управлять датчиками умного дома, на примере платы ESP8266 и светодиода. Также создадим свое приложение для Assistant с блэкджеком и php скриптами. Всех желающих прошу под кат.

Для этого всего нам понадобится контроллер ESP8266, либо другие контроллеры с подключением к интернету а также сервер c валидным ssl сертификатом (вместо валидного ssl можно использовать обратный proxy у которого таковой уже имеется) и MQTT сервер (broker).
Для интеграции с google assistant будем использовать сервис Google Actions и Dialogflow. Итак начнем.
image

Создание и настройка проекта

Google Action Console

Для начала нужно авторизоваться на сервисе [1] и создать проект, выбрать язык и регион.

image

После нужно выбрать сферу применения. Я выбрал Kids&Family. Из чужого опыта скажу, что логически напрашивающаяся категория Smart Home работает корректно только с устройствами от Google, для проектов со своими датчиками для корректной работы лучше выбрать другую категорию.
image

Читаем и принимаем соглашения. В категории Quick setup переходим к пункту Decide how your Action is invoked. Придумываем как будут звать нашего бота и выбираем голос из доступных, сохраняем.

image

Переходим в вкладку Actions, добавляем действие Custom Intent

image

Dialogflow

После нажатия кнопки Build нас перенаправляет на ресурс Dialogflow, тоже авторизируемся и переходим к созданию проекта:
1.Выбираем язык по умолчанию и часовой пояс.
2.Переходим в вкладку Fulfillment включаем пункт Webhook. Здесь вы должны указать адрес скрипта (о том что это за скрипт, читайте далее) на который Dialogflow будет отсылаться POST запрос.
image
3. Настройка команд и ответов
Вкладка intets имеет несколько стандартных заготовленых команд и ответов на них. В нашем случае нужно создать новую команду. Для этого нужно нажать на + во вкладке Intents. Придумать отображаемое имя команды и нажать сохранить.

image
Саму страницу можно условно разделить на три категории:
Training phrases — это слова, на которые assistant реагирует командой. Они могут быть разными для одной команды. Например слова посвети, вруби свет, включи лампу и т. п.
image
Action — само действие, или слово, которое будет понимать датчик, оно одно и конкретное.
Responses это ответы assistant после выполнения команды. Здесь просто поле для творчества.
image

Настройка хостинга

В качестве сервера приобрел самый дешевый (5$) дроплет и установил на него Debian 10.2. Какой вы хостинг [2] выберете значение не имеет.

Настройка обратного proxy и DNS

Эту часть можно пропустить, если у вас есть хостинг [2] с валидным сертификатом.
Сам сервис Cloudflare предлагает множество имен нижних уровней, потому если вы испытываете проблемы с выполнением пункта 4, возможно стоит в колонке content возле www***, https//www*** указать свой ip вместо дефолтного (*** это ваш домен).

Для взаимодействия с Dialogflow нужен SSL сертификат. Я не стал устанавливать его на сервер, вместо этого я использовал DNS proxy Cloudflare (бесплатный — basic). Для этого при настройке Cloudflare я добавил свое ранее приобретенное доменное имя и добавил к нему ip адрес своего сервера (колонка Content). Также добавил две A записи (на картинке это Value) в настройках провайдера имен. Стоит отметить, что добавление записи это не секундное дело и может занять до нескольких рабочих дней.

image

Установка программ

1.Первым делом после первого запуска сервера не забудьте обновить базу данных пакетов

apt update

, а потом обновить установленные пакеты

apt upgrade

2. После установим LAMP
Apache

apt install apache2 

PHP/Mysql

apt-get install php libapache2-mod-php php-mcrypt php-mysql

.Добавьте адрес сервера в apache2.conf. Это можно выполнить командой nano /etc/apache2/apache2.conf указав в конце файла ServerName *** в конце вашего файла, где вместо звездочек нужно подставить ip сервера. Проверьте синтаксис и перезапустите службу Apach Подробнее тут [3].
После успешного выполнения действий описанных выше при вводе вашего доменного имени в строку браузера вы получите страницу приветствия Apache2.

image

Если этого не случилось проверьте корректно ли выполнялись команды, а также работает ли страница при не защищенном http соединении. Если все же работает возможно сервер слушает 80, а не 443 порт. Или на нем уже запущена какая то служба. Подробнее тут [4].
4.Установка Библиотеки Mosquitto для PHP
Устройства интернета вещей могут использовать разные протоколы для взаимодействия. Один из таких MQTT (https://habr.com/ru/post/463669/), который работает по принципу издатель-подписчик. В таком случае подписчики могут получать информацию от многих издателей. Но поскольку протокол понимает только определенные типы сообщений, для него нужен преобразователь (broker). на Вот его мы и настраиваем.
5.Если у вас не установлен PECL, установите его

apt install pecl

После становим брокер

pecl install Mosquitto-alpha

Затем добавьте extension = mosquitto.so к вашему php.ini. И не забудьте клиент

apt install mosquitto mosquitto-clients

Подробнее тут [5]

Настройка php скрипта, подписка на topic

Собственно сам скрипт. Его назначение принимать post запрос от Dialogflow, вычленять из него action и передавать его как сообщение на брокер в тему, название которой указано в конце скрипта. Как вы назовете скрипт значения не имеет. Кстати это и есть скрипт, который мы указывали в вкладке Fulfillment. Поместите скрипт по адресу /var/www/html

Топики создаются подписчиками.Чтобы создать топик воспользуйтесь командой:

mosquitto_sub -h localhost - t /test/light

Вместо localhost вы можете задать любой другой адрес, или домен, где вы хотите создать издателя (pub)
Вместо /test/light вы можете задать любую тему. В нашем случае главное, чтобы она была указана в скрипте.

Сообщения создаются издателями. Чтобы создать сообщение можно воспользоваться командой.

mosquitto_pub -h localhost - t /test/light -m “light”

Но она нам не понадобится, поскольку нашим издателем (pub) будет наше приложение. Схема такая, когда наше приложение получает команду, оно отправляет запрос на наш скрипт. Скрипт на брокера, а брокер на подписчика (esp8266).
Проверять отправку сообщений мы будем через вкладку Test Action Console.

image

image

Скрипт php

<?php


//Make sure that it is a POST request.
if(strcasecmp($_SERVER['REQUEST_METHOD'], 'POST') != 0){
    throw new Exception('Request method must be POST!');
}

//Make sure that the content type of the POST request has been set to application/json
$contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"])                                                                                                              : '';
if(strcasecmp($contentType, 'application/json') != 0){
    throw new Exception('Content type must be: application/json');
}

//Receive the RAW post data.
$content = trim(file_get_contents("php://input"));

//Attempt to decode the incoming RAW post data from JSON.
$decoded = json_decode($content);

//file_put_contents($filename, $data);
var_dump($decoded);

echo $decoded->queryResult->action;



define('BROKER', 'localhost');
define('PORT', 1883);
define('CLIENT_ID',  getmypid());
 ити 
$client = new MosquittoClient(CLIENT_ID);
$client->connect(BROKER, PORT, 60);

        $message = $decoded->queryResult->action;
        $client->publish('/test/light', $message, 0, false);
        $client->loop();





?>

Прошивка ESP8266

Для прошивки будем использовать Arduino IDE. Если кто то будет устанавливать IDE впервые не забудьте про драйвер ch340. По дефолту в arduino єтой платі нет. В Файл>>Настройки вам нужно указать адрес дополнительніх плат: arduino.esp8266.com/stable/package_esp8266com_index.json. В Инструменты>>плата>>менеджер плат вам нужно установить пакет esp8266.
В скетче после const char* ssid вы должны указать название своей wi-fi сети. После const char* password ее пароль. После const char* mqtt_server указать ip адрес своего сервера.

Скетч Arduino IDE

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "***";
const char* password = "********";
const char* mqtt_server = "**.**.*.*";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

int led = D5;

void setup_wifi() {

delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

randomSeed(micros());

Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
String msg="";
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
msg+=(char)payload[i];
}
Serial.println();

// Switch on the LED if an 1 was received as first character
// if ((char)payload[0] == '1') {
if (msg == "light") {
digitalWrite(led, HIGH); // Turn the LED on
} else {
digitalWrite(led, LOW); // Turn the LED off
}

}

void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// ... and resubscribe
client.subscribe("/test/light");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}

void setup() {
pinMode(led, OUTPUT); // Initialize the led pin as an output
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}

void loop() {

if (!client.connected()) {
reconnect();
}
client.loop();

}

Результат

В результате, после компиляции скетча мы получаем приложение, которе интегрировано в google асистент и управляет датчиками. Вместо смартфона я использовал web приложение, но тестировал на Android — результат одинаковый. Главное, если вы тестируете с смартфона не забудь сказать: “Говорить с приложением ***”

image

image

Автор: Свердлюк Богдан

Источник [6]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/internet-veshhej-2/348192

Ссылки в тексте:

[1] сервисе: https://console.actions.google.com/

[2] хостинг: https://www.reg.ru/?rlink=reflink-717

[3] тут: https://www.digitalocean.com/community/tutorials/linux-apache-mysql-php-lamp-ubuntu-16-04-ru

[4] тут: https://losst.ru/pochemu-apache-ne-zapuskaetsya

[5] тут: https://readthedocs.org/projects/mosquitto-php/downloads/pdf/latest/

[6] Источник: https://habr.com/ru/post/490484/?utm_source=habrahabr&utm_medium=rss&utm_campaign=490484