(二 -3-1) 天猫精灵接入Home Assistant-自动发现Mqtt设备--灯系列 实战

本片教程介绍了具体如何实现天猫精灵控制一个灯。

前提:

HASS平台

  1. 你已经搭建一个可以在公网IP访问到的HASS平台--- 我用的是租了阿里云服务器,买了个域名,ubuntu1604系统
  2. 你已经搭建一个可以在公网IP访问到的MQTT服务器----没有好的话也可以使用官方测试用的服务器凑合下
  3. 在HASS论坛注册一个账户和密码---- 一般人不给注册,你需要给管理员发送邮件证明你会基本的HASS搭建(这都不会玩个蛇)

天猫精灵

  1. 花60元在咸鱼买个二手的 天猫精灵-方糖  (官网89元新的)
  2. 下载天猫精灵手机APP,绑定自己的 天猫精灵-方糖

ESP8266模块

  1. 随便找个能够使用arduino ide 开发的ESP8266(这里使用的是  esp8266 d1 pro min  14元)
  2. 一个继电器,控制台灯开和关

一 HASS配置-发现灯设备

目的:告诉HASS平台,现在有一个新的设备---灯要被你控制管理

手动添加模式

0 打开配置文件手动配置HASS要连接的MQTT服务器

# configuration.yaml配置样例
mqtt:
  # MQTT Broker的IP地址或者域名,这里蹭的官网测试服务器
  broker: broker.mqtt-dashboard.com
  # MQTT Broker的端口号,缺省为1883
  port: 1883
  #client_id: home-assistant-1
  # 用户名 不用设置
  #username: homeassistant
  # 密码  不用设置
  #password: 123456

  

1 打开配置文件手动增加一个设备

platform: mqtt
    name: "Office Light RGB"
    state_topic: "hachina/rgb1/light/status"
    command_topic: "hachina/rgb1/light/switch"
    brightness_state_topic: "hachina/rgb1/brightness/status"
    brightness_command_topic: "hachina/rgb1/brightness/set"
    rgb_state_topic: "hachina/rgb1/rgb/status"
    rgb_command_topic: "hachina/rgb1/rgb/set"
    state_value_template: "{{ value_json.state }}"
    brightness_value_template: "{{ value_json.brightness }}"
    rgb_value_template: "{{ value_json.rgb | join(',') }}"
    qos: 0
    payload_on: "ON"
    payload_off: "OFF"
    optimistic: false

  

自动添加模式

0 HASS配置要连接的MQTT服务器

1 HASS配置文件中开启自动发现设备。

# configuration.yaml配置样例
mqtt:
  # MQTT Broker的IP地址或者域名
  broker: broker.mqtt-dashboard.com
  # MQTT Broker的端口号,缺省为1883
  port: 1883
  #client_id: home-assistant-1
  # 用户名
  #username: homeassistant
  # 密码
  #password: 123456
  # 配置自动发现
  discovery: true
  # 自动发现使用的主题位置前缀,缺省为homeassistant
  discovery_prefix: homeassistant

  

2 ESP8266 WIFI模块(灯)发送自己的配置信息给HASS的配置话题。

hass配置话题 位置

homeassistant/light/garden/config

garden可以随意换--设备ID

发送的配置信息

{"name": "RGBlight", "command_topic": "hachina/rgb1/light/switch", "state_topic": "hachina/rgb1/light/status","brightness_command_topic": "hachina/rgb1/brightness/set", "brightness_state_topic": "hachina/rgb1/brightness/status","rgb_command_topic": "hachina/rgb1/rgb/set","rgb_state_topic": "hachina/rgb1/rgb/status","state_value_template": "{{ value_json.state }}","brightness_value_template": "{{ value_json.brightness }}","rgb_value_template": "{{ value_json.rgb | join(',') }}","optimistic": false}

  

 然后可以看到 HASS平台上多了一个灯--RGBlight(其他两个设备忽略)

 可以直接用HASS来控制灯

电脑HASS网页版

普通的灯点击是不会出现颜色版的

手机HASS app

编辑--添加设备--里面有个我们自定义的灯设备RGBlight--添加进来

短按开关,长按跳出颜色控制板块

下一步,接入天猫精灵,使用语音间接控制HASS的设备(HASS自带语音识别和播放服务,也可使用)

二 天猫精灵添加灯设备--将HASS上发现的灯设备添加到天猫精灵上,从而确保猫精间接通过HASS来控制灯

疑问: 为何猫精不直接控制灯?

世界灯种类千千万,鬼知道你这是什么灯,所以具体控制业务由专门开发智能家居的公司来搞,猫精只负责把语音控制解析信息给智能家居平台公司,由他们自己去控制自己平台下的灯。

1 登陆hass论坛,注册账户和密码   

https://bbs.hassbian.com

2打开天猫精灵APP,在智能家居---绑定平台账号----绑定HASS账户和密码

  这样猫精就和HASS这个具体的智能家居公司对接起来了(然而HASS不是一个公司,是一个开源项目,申请成为开发合作者)

3将HASS上已有的设备同步到天猫精灵手机APP-智能家居控制列表里,从而使得猫精间接通过HASS控制我们的灯

具体过程:

打开HASS论坛架设的配置网址

https://bbs.hassbian.com/tmall/discovery.php

输入自己的HASS信息,进入自己的HASS设备管理

将第一步HASS发现的ID为RGBlight的灯添加到天猫精灵设备管理中。

选择增加--真实设备

设置灯的信息

设备ID  : 选择 

设备类型:灯

设备名称:彩灯  (这地方随意取名,但是到天猫精灵手机APP那里,要以那里的名称为准)

。。。

支持属性:  颜色  亮度 开关

支持操作:( 所有和属性相关的操作都加进去)  打开 关闭  设置颜色 设置亮度 查询电源状态 查询颜色  查询亮度 。。。。。

 完成后,多出一个彩灯设备

 打开天猫精灵APP,在智能家居中发现,多出一个彩灯设备

为了提高语音识别准确度,我按照天猫精灵APP的设置重新取了名字 --- 卧室的灯。

就这样,语音告诉猫精开灯,猫精解析语音后告诉HASS平台,去开哪盏灯。

-------------------------------------------------------------------------

hass是个智能家居管理平台,可以介入各种设备,具体怎么控制灯,这里需要借助MQTT通信协议和服务。

MQTT服务典型: 我想和女朋友说“我爱你”,并不是我直接告诉她,而是我在 “love”这个话题下,发布了“我爱你”这个消息,她订阅“love”话题,这样每次从“love”这个话题下,接收到“我爱你”的消息

这种服务好在哪: 凡是订阅这个话题的人,都能收到同样的消息,反之,也都可以往这个话题发消息。就像QQ和微信讨论组一样。

-------------------------------------------------------------------------

HASS接收到开哪个灯命令后,找到这个灯的信息,把开关,颜色,亮度控制命令通过MQTT放在指定话题上,等待灯来这个话题上取消息。

这个灯如何取到消息?

1能联网----这里选择ESP8266  wifi模块

2能使用MQTT--  esp8266 在 aruino ide开发平台 下有现成的MQTT通信库。使用这个库可以很轻易从对应话题拿到想要的数据。

3能当单片机控制-- ESP8266可以当一块单片机 开发,外接继电器可以控制220V的开和关。

三 对接现实世界------ESP8266程序

 烧录时板型选择信息(根据自己使用的ESP866  wifi板类型)

两种控制模式:

1 使用HASS网页版或者手机APP直接控制

开关

亮度

颜色

2 天猫精灵语音控制hass,间接控制灯

天猫精灵 打开卧室的的灯

天猫精灵 关闭卧室的的灯

天猫精灵 将卧室的的灯颜色调成红色

天猫精灵 将卧室的的灯亮度调为60

ESP8266串口打印输出:

 

程序功能:

  1. 连接指定MQTT服务器
  2. 在hass约定好的配置话题上发送ESP8266自己的配置信息,从而HASS注册这个灯设备
  3. HASS注册设备后,将开灯关闭,颜色,亮度等控制信息发送到对应约定好的话题上,ESP8266wifi模块到对应话题取出命令,控制继电器开关台灯

未来扩展:

  1. 增加一键配网,可灵活修改WIFI信息
  2. 增加flash保存WIFI联网信息,断后电重新自动连接上次记录的WIFI信息
  3. 增加触摸开关,从而开关本身+HASS软件+天猫语音三者都能独立控制开关,同时彼此更新开关状态
  4. 完善电路,可控硅代替继电器,电路微薄化处理,做成玻璃面板,好看美观

目前bug

 无法直接发送自身配置信息

if (! hass_config.publish("sssssssssss")) {  // 这是个bug  应该发送的是 自身配置信息  但是 *char和string 在这个函数不兼容,就随便发送个 “ssssss“ ,可以正常收到

esp8266烧录代码

/***************************************************

 ****************************************************/
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"

/************************* WiFi Access Point *********************************/

#define WLAN_SSID       "dongdong"
#define WLAN_PASS       "ldd123456"

/************************* Adafruit.io Setup *********************************/

//#define AIO_SERVER      "io.adafruit.com"
#define AIO_SERVER      "broker.mqtt-dashboard.com"
#define AIO_SERVERPORT  1883                   // use 8883 for SSL
#define AIO_USERNAME    ""
#define AIO_KEY         ""


int Light_d1 = D4; 


/************ Global State (you don't need to change this!) ******************/

// Create an ESP8266 WiFiClient class to connect to the MQTT server.
WiFiClient client;

// Setup the MQTT client class by passing in the WiFi client and MQTT server and login details.
Adafruit_MQTT_Client mqtt(&client, AIO_SERVER, AIO_SERVERPORT, AIO_USERNAME, AIO_USERNAME, AIO_KEY);

/****************************** Feeds ***************************************/
// 发布自己的配置信息
Adafruit_MQTT_Publish hass_config = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "homeassistant/light/garden/config");

const char *my_config = "{\"name\":\"RGBlight\", \"command_topic\": \"hachina/rgb1/light/switch\",\"state_topic\": \"hachina/rgb1/light/status\",\"brightness_command_topic\": \"hachina/rgb1/brightness/set\",\"brightness_state_topic\": \"hachina/rgb1/brightness/status\",\"rgb_command_topic\": \"hachina/rgb1/rgb/set\",\"rgb_state_topic\": \"hachina/rgb1/rgb/status\",\"state_value_template\": \"{{ value_json.state }}\",\"brightness_value_template\": \"{{ value_json.brightness }}\",\"rgb_value_template\": \"{{ value_json.rgb | join(',') }}\",\"optimistic\": false}"
;
// 发布自己的开关信息
Adafruit_MQTT_Publish state_topic = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "hachina/rgb1/light/status");

//发布自己的亮度信息
Adafruit_MQTT_Publish brightness_state_topic = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "hachina/rgb1/brightness/status");

//发布自己的颜色信息
Adafruit_MQTT_Publish rgb_state_topic = Adafruit_MQTT_Publish(&mqtt, AIO_USERNAME "hachina/rgb1/rgb/status");

//订阅开关命令
Adafruit_MQTT_Subscribe command_topic = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "hachina/rgb1/light/switch", MQTT_QOS_1);
//订阅亮度命令
Adafruit_MQTT_Subscribe brightness_command_topic = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "hachina/rgb1/brightness/set", MQTT_QOS_1);
//订阅颜色命令
Adafruit_MQTT_Subscribe rgb_command_topic = Adafruit_MQTT_Subscribe(&mqtt, AIO_USERNAME "hachina/rgb1/rgb/set", MQTT_QOS_1);

/*************************** Sketch Code ************************************/


void command_topic_call(char *data, uint16_t len) {
  Serial.print("the button value is: ");
  Serial.println(data);


  String msg=String(data);
  
  if(msg=="ON") { Serial.println("light is open");
  digitalWrite(Light_d1, HIGH);}
  
  if(msg=="OFF") {  Serial.println("light is close");
  digitalWrite(Light_d1, LOW);}

  
}

void brightness_command_topic_call(double x) {
  Serial.print("Hey we're in a slider callback, the slider value is: ");
  Serial.println(x);
}

void rgb_command_topic_call(char *data, uint16_t len) {
  Serial.print("the button value is: ");
  Serial.println(data);

}


void setup() {
  
 pinMode(Light_d1, OUTPUT);
 digitalWrite(Light_d1, LOW);
   
  Serial.begin(115200);
  delay(10);

  Serial.println(F("Adafruit MQTT demo"));

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.begin(WLAN_SSID, WLAN_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println();

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




// 回掉函数
  command_topic.setCallback(command_topic_call);
  brightness_command_topic.setCallback(brightness_command_topic_call);
  rgb_command_topic.setCallback(rgb_command_topic_call);
 // 订阅话题注册

  mqtt.subscribe(&command_topic);
  mqtt.subscribe(&brightness_command_topic);
  mqtt.subscribe(&rgb_command_topic);
  



}

uint32_t x=0;

void loop() {

  MQTT_connect();



  // this is our 'wait for incoming subscription packets and callback em' busy subloop
  // try to spend your time here:
  mqtt.processPackets(10000);
  
  // ping the server to keep the mqtt connection alive
  // NOT required if you are publishing once every KEEPALIVE seconds
  
  if(! mqtt.ping()) {
    mqtt.disconnect();
  }
}

// Function to connect and reconnect as necessary to the MQTT server.
// Should be called in the loop function and it will take care if connecting.
void MQTT_connect() {
  int8_t ret;

  // Stop if already connected.
  if (mqtt.connected()) {
    return;
  }

  Serial.print("Connecting to MQTT... ");

  uint8_t retries = 3;
  while ((ret = mqtt.connect()) != 0) { // connect will return 0 for connected
       Serial.println(mqtt.connectErrorString(ret));
       Serial.println("Retrying MQTT connection in 3 seconds...");
       mqtt.disconnect();
       delay(3000);  // wait 10 seconds
       retries--;
       if (retries == 0) {
         // basically die and wait for WDT to reset me
         while (1);
       }
  }
  Serial.println("MQTT Connected!");

  if (! hass_config.publish("sssssssssss")) {  // 这是个bug  应该发送的是 自身配置信息  但是 *char和string 在这个函数不兼容
    Serial.println(F("Failed"));
  } else {
    Serial.println(F("OK!"));
  }

  
}

  

猜你喜欢

转载自www.cnblogs.com/kekeoutlook/p/9484859.html
今日推荐