使用Google Assistant管理智能家居传感器

您好,本指南的同事们将以ESP8266开发板和LED为例,介绍如何使用Google Assistant和mqtt协议控制智能家居传感器。我们还将使用21点和php脚本创建自己的助手应用程序。我向大家要猫。

为此,我们需要ESP8266控制器或具有Internet连接的其他控制器,以及具有有效ssl证书的服务器(代替有效的ssl,您可以使用已经具有一个的反向代理)和MQTT服务器(代理)。

为了与Google Assistant集成,我们将使用Google Actions服务和Dialogflow。所以,让我们开始吧。

图片

创建和设置项目


Google动作控制台


首先,您需要登录该服务并创建一个项目,选择一种语言和地区。

图片

之后需要选择范围。我选择了儿童与家庭。根据其他人的经验,我会说逻辑上合理的类别“智能家居”只能与Google的设备一起正常使用,对于具有自己传感器的项目,最好选择其他类别以进行正确操作。

图片

我们阅读并接受该协议。在“快速设置”类别中,转到“决定如何调用您的操作”。我们提出了我们的机器人将要调用的东西,并从可用的声音中选择一种声音,然后将其保存。

图片

转到“动作”标签,添加“自定义意图”动作

图片

对话流程


单击“构建”按钮后,我们将重定向到Dialogflow资源,我们也登录并继续创建项目:

  1. 选择默认语言和时区。
  2. Fulfillment Webhook. ( , ) Dialogflow POST .

    图片
  3. 3. .

    intets . . + Intents. .

图片

该页面本身可以分为三类:

训练短语是助手与团队响应的词。对于一个团队,它们可以不同。例如,发光的单词,切开灯,打开灯等。

图片

动作 -动作本身,或者传感器可以理解的单词,这是一个具体的动作。

响应是执行命令后助手的回答。这只是创造力的领域。

图片

托管设置


作为服务器,我购买了最便宜的($ 5)Droplet,并在其上安装了Debian 10.2。您选择的主机无所谓。

配置反向代理和DNS


如果您的主机托管了有效的证书,则可以跳过此部分。

Cloudflare服务本身提供了许多较低级别的名称,因此,如果您在第4步中遇到问题,则可能需要在www ***,https // www ***(***是您的域)附近的内容列中指定您的ip而不是默认值。 。

要与Dialogflow交互,您需要一个SSL证书。我没有将其安装在服务器上,而是使用了DNS代理Cloudflare(免费-基本)。为此,在配置Cloudflare时,我添加了先前购买的域名,并向其添加了服务器的IP地址(“内容”列)。在名称提供者的设置中还添加了两个A记录(在图片中为Value)。值得注意的是,添加记录不是几秒钟的事情,并且可能需要花费几个工作日。

图片

软件安装


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服务了解更多这里

在浏览器栏中输入域名成功完成上述步骤后,您将收到Apache2欢迎页面。

图片

如果这没有发生,请检查命令是否正确执行,以及页面是否在不安全的http连接下工作。如果工作正常,则服务器可能正在侦听端口80,而不是端口443。或某些服务已在其上运行。更多细节在这里

4.安装用于PHP的Mosquitto库

物联网设备可以使用不同的协议来实现互操作性。一种基于发布者-订阅者的MQTT在这种情况下,订阅者可以从许多发布者那里接收信息。但是由于该协议仅理解某些类型的消息,因此它需要一个转换器(代理)。在这里,我们进行设置。

5.如果尚未安装PECL,请安装它

apt install pecl

成为经纪人之后

pecl install Mosquitto-alpha

然后将extension = mosquitto.so添加到您的php.ini中。而且不要忘记客户

apt install mosquitto mosquitto-clients

更多细节在这里

设置php脚本,订阅主题


实际上是脚本本身。其目的是接受Dialogflow的发布请求,将其与操作隔离开,并将其作为消息发送给主题中的代理,代理的名称在脚本末尾指示。你怎么称呼脚本没关系。顺便说一句,这是我们在“实现”选项卡中指示的脚本。将脚本放在/ var / www / html

主题由订户创建。要创建主题,请使用以下命令:

mosquitto_sub -h localhost - t /test/light

除了本地主机,您还可以指定要在其中创建发布者(pub)的任何其他地址或域。

您可以指定任何主题来代替/ test / light。在我们的例子中,最主要的是在脚本中指出它。

邮件是由发布者创建的。要创建消息,可以使用命令。

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

但是我们不需要它,因为我们的发布者(pub)将成为我们的应用程序。方案是这样的,当我们的应用程序收到命令时,它将请求发送到我们的脚本。该脚本用于代理,代理用于订户(esp8266)。

我们将通过“测试操作控制台”选项卡检查消息的发送。

图片

图片

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 Mosquitto\Client(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。在Tools >> board >> board manager中,您需要安装esp8266软件包。

在const char * ssid之后的草图中,您应该指定Wi-Fi网络的名称。输入const char *密码后,输入她的密码。在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 Assistant中并管理传感器的应用程序。我使用的是Web应用程序,而不是智能手机,但在Android上进行了测试-结果是相同的。最主要的是,如果您正在使用智能手机进行测试,请不要忘记说:“与应用程序交谈***”。

图片

图片


All Articles