Jay
Jay

ESP8266 接入Home Assistant&HomeKit

前篇文章实现了下雨自动报警,今天尝试将ESP8266接入HA,实现苹果HomeKit接入。ESP8266通过MQTT协议将传感器信息发送到指定话题上,HA通过订阅话题获取信息,并通过其插件HomeBridge实现与HomeKit的连接。

MQTT Sever可以使用HA自带的插件实现,或者用第三方的服务实现。这里我选择的是国人制作的EMQX,界面非常的友好,功能丰富。当然,实现本文的功能是绰绰有余的。

部署 Home Assistant&EMQX

这里选择docker-compose来部署服务

version: '3'

services:
  HomeAssistant:
    image: homeassistant/home-assistant
    restart: always
    ports:
      - 8123:8123
    volumes:
      - './HomeAssistant:/config'
    network_mode: "host"
  emq:
    image: emqx/emqx
    container_name: emqx
    ports:
      - "18083:18083"
      - "1883:1883"
      - "8084:8084"
      - "8883:8883"
      - "8083:8083"
    restart: always
    network_mode: "host"

这里的network_mode必须选择host,否则会导致HomeKit无法连接。EMQX的配置文件也建议挂载出来,由于实现的功能比较简单,这里就不操作了。

配置Home Assistant

添加插件

点击集成,添加HomeKit插件,完成后在通知中会出现二维码和PIN码,打开HomeKit可联接。接着添加MQTT插件,输入IP地址直接提交即可。

添加传感器

打开上面你映射的HA文件夹路径,修改configuration.yaml。

注意:文件需要使用UTF-8保存,否则会报错

# Configure a default setup of Home Assistant (frontend, api, etc)
default_config:

# Text to speech
tts:
  - platform: google_translate
group: !include groups.yaml
automation: !include automations.yaml
script: !include scripts.yaml
scene: !include scenes.yaml
sensor: !include sensors.yaml
mobile_app:

添加了sensor和mobile_app

Mobile_app是因为接入三星ST非常的麻烦,干脆用他官方的APP更方便。

然后再在目录下新建sensors.yaml

  - platform: mqtt
    state_topic: "ha/tmp"
    name: "温度"
    unit_of_measurement: '°C'
    icon: mdi:thermometer
    value_template: '{{ value }}'
    device_class: temperature
    expire_after: 5

  - platform: mqtt
    state_topic: "ha/hum"
    name: "湿度"
    unit_of_measurement: "%"
    icon: mdi:thermometer
    value_template: '{{ value }}'
    device_class: humidity
    expire_after: 5  

变量说明:

  • name (可选): 名称,英文。默认 MQTT Binary Sensor.
  • state_topic (必填): 获取设备值的MQTT topic
  • qos (可选): 最大 QoS 值,默认 0
  • value_template (可选): 定制数据生成的模板
  • unit_of_measurement (可选): 单位
  • expire_after (可选): 数据有效时间,以秒为单位,默认 0
  • force_update (可选): 强制更新数据,默认 false
  • icon(可选):图标
  • device_class(可选):设备类型,不添加HomeKit可能无法正常识别

记住上面设置的topic,等会往上面发消息就完事了。

重启HA以保存修改。

添加卡片-传感器-实体里应该能看到你添加的传感器,否则请确认配置文件是否正确。

ESP8266代码编写

在Arduino库管理器中安装Pubsubclient以支持MQTT。DHT11已安装过依赖,详情请看上一篇。

完整代码

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "DHTesp.h"
// Update these with values suitable for your network.
#define LED 2
const char* ssid = "WIFI名";
const char* password = "密码";
const char* mqtt_server = "mqtt服务器地址";
char *buffer=new char[30];
char *buffern=new char[30];
DHTesp dht;
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
#define MSG_BUFFER_SIZE  (50)
char msg[MSG_BUFFER_SIZE];
int value = 0;

void setup_wifi() {
  WiFi.mode(WIFI_STA);
  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());
  digitalWrite(LED, 1);
}

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

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is active low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

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");
      // Once connected, publish an announcement...
      client.publish("ha/tmp", "0");
      client.publish("ha/hum", "0");
      // ... and resubscribe
      client.subscribe("homeassistant/in");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void push()
{
  
  if(client.connected())
  {
    delay(dht.getMinimumSamplingPeriod());
    float humidity = dht.getHumidity();
    float temperature = dht.getTemperature();
    sprintf( buffer , "%.1f", temperature );//将float转换为char
    sprintf( buffern , "%.1f",  humidity);
    client.publish("ha/tmp", buffer);//发布的话题在这里修改,内容用逗号分割
    client.publish("ha/hum", buffern);
    Serial.println(buffer);
    Serial.println(buffern);
    delay(2000);
  }
  else
  {
    reconnect();
  }
  
}
void setup() {
  pinMode(LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  digitalWrite(LED, 0);
  dht.setup(14, DHTesp::DHT11); // Connect DHT sensor to GPIO 17
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

void loop() {
  push();
}

输入ESP8266表现为,开机LED常亮,连接上WIFI LED熄灭,接收到订阅话题的消息闪烁。此时,HA面板里应该有你的传感器数据了。

在集成界面点击HomeKit的选项,加入sensor配置

提交保存,你的苹果设备上应该就出现传感器了!

发表评论

textsms
account_circle
email

Jay

ESP8266 接入Home Assistant&HomeKit
前篇文章实现了下雨自动报警,今天尝试将ESP8266接入HA,实现苹果HomeKit接入。ESP8266通过MQTT协议将传感器信息发送到指定话题上,HA通过订阅话题获取信息,并通过其插件HomeBridge实现…
扫描二维码继续阅读
2020-06-13