[Home Assistant] Door门

前言

在智能家居系统中,门的开关状态检测是一项重要的功能。这不仅可以帮助用户了解家中的情况,还可以与其他智能设备联动,实现更加便捷的生活体验。例如,当门被打开时,可以触发警报系统,或者通知用户有访客到来。

实验目的

核桃派HA主机添加一个自定义船型二档开关,判断门是否被打开

实验讲解

开关需要用到HA MQTT组件中的binary_sensor。实验的关键是搞清楚发现MQTT设备的主题信息以及控制方法,具体说明如下:

MQTT主题

下面这个主题用于HA主机通过MQTT发现该设备:

homeassistant/binary_sensor/picow_door/config
  • homeassistant:默认的前缀
  • binary_sensor: 温度传感器使用的MQTT元件为binary_sensor
  • picow_door: 实体的ID,需要唯一,这里自定义的内容,表示核桃派PicoW的温度传感器;
  • config:默认的后缀

MQTT消息

"""{
    "name": "Picow Door",
    "device_class": "door",
    "state_topic": "homeassistant/binary_sensor/picow_door/contact",
    
    "unique_id": "picow_door",

    

    "device": {
        "identifiers": ["picow_door"],
        "name": "Picow Door",
        "model": "picow_alert", 
        "manufacturer": "WalnutPi-PicoW)" 
    }
}"""

实体

  • "name":"Picow Door": 实体名称,自定义填写;
  • "device_class":"door": 组件类型,跟前面主题配置信息相关,不能填错,比如这里的door是组件binary_sensor下的一个可用实体;
  • "state_topic":"homeassistant/binary_sensor/picow_door/contact": 用于注册实体后发布相关属性主题,这里用来开关状态,主题内容自定义,保证不同实体的主题不一样即可;
  • "unique_id":"picow_door": 实体ID,自定义,务必保证每个实体唯一;

设备

告知HA实体对应的设备。

  • "identifiers":"picow_door": 识别标识符,每个设备唯一。
  • "name":"Picow Door: 设备名称,自定义;
  • "manufacturer": "WalnutPi-PicoW":设备制造厂商,自定义;

更多MQTT sensor内容可查阅官方文档:MQTT Sensor - Home Assistant
代码编写流程如下:
1:导入相关模块
2:构建switch对象
3:连接wifii
4:连接MQTT服务器
5:注册switch实体和设备
6:采集开关状态
7:MQTT发送开关状态信息
8:延时1秒采集开关状态

基于核桃派PicoW实现

本实验使用核桃派PicoW(ESP32-S3)连接KCD1船型开关\2档,保证核桃派PicoW和核桃派1B连接到同一个路由器下即可:

参考代码

'''
实验名称:Home Assistant Door门
实验平台:核桃派1B  核桃派picow
说明:编程实现Home Assistant 检测Door门开与关状态。
'''
import network,time
from simple import MQTTClient #导入MQTT板块
from machine import Pin,Timer

LED=Pin(46, Pin.OUT) #初始化WIFI指示灯

#WIFI连接函数
def WIFI_Connect():

    global LED

    wlan = network.WLAN(network.STA_IF) #STA模式
    wlan.active(True)                   #激活接口
    start_time=time.time()              #记录时间做超时判断

    if not wlan.isconnected():
        print('connecting to network...')
        wlan.connect('01Studio', '88888888') #输入WIFI账号密码

        while not wlan.isconnected():

            #LED闪烁提示
            LED.value(1)
            time.sleep_ms(300)
            LED.value(0)
            time.sleep_ms(300)

            #超时判断,15秒没连接成功判定为超时
            if time.time()-start_time > 15 :
                print('WIFI Connected Timeout!')
                break

    if wlan.isconnected():
        #LED点亮
        LED.value(1)

        #串口打印信息
        print('network information:', wlan.ifconfig())

        return True

    else:
        return False


#设置MQTT回调函数,有信息时候执行
def MQTT_callback(topic, msg):
    
    print('topic: {}'.format(topic))
    print('msg: {}'.format(msg))
    
    if msg == b'ON' :
        
        LED.value(1)
    
    if msg == b'OFF' :
        
        LED.value(0)

#接收数据任务·
def MQTT_Rev(tim):
    client.check_msg()

#执行WIFI连接函数并判断是否已经连接成功
if WIFI_Connect():
    CLIENT_ID = 'WalnutPi-PicoW' # 客户端ID
    SERVER = '192.168.1.1' # MQTT服务器地址
    PORT = 1883   
    USER='pi'
    PASSWORD='pi'
    
    client = MQTTClient(CLIENT_ID, SERVER, PORT, USER, PASSWORD) # 建立客户端对象
    client.set_callback(MQTT_callback) # 配置回调函数
    client.connect()
    
     # 注册设备
    TOPIC = "homeassistant/binary_sensor/picow_door/config"
    message = """{
    "name": "Picow Door",
    "device_class": "door",
    "state_topic": "homeassistant/binary_sensor/picow_door/contact",
    
    "unique_id": "picow_door",

    

    "device": {
        "identifiers": ["picow_door"],
        "name": "Picow Door",
        "model": "picow_alert", 
        "manufacturer": "WalnutPi-PicoW" 
    }
}"""

    client.publish(TOPIC, message)

    # 订阅主题
    TOPIC = 'homeassistant/binary_sensor/picow_door/config'  # 订阅传感器状态的MQTT主题
    client.subscribe(TOPIC)
    
    
    #开启RTOS定时器,编号为1,周期100ms,执行socket通信接收任务
    tim = Timer(1)
    tim.init(period=100, mode=Timer.PERIODIC,callback=MQTT_Rev)

    
    
# 初始化开关引脚# 假设 switch 是一个可以检测门状态的引脚
switch = Pin(42, Pin.IN, Pin.PULL_UP)

# 定义一个函数来检查门的状态
def check_door_status():
    global last_switch_state  # 声明last_switch_state为全局变量
    current_switch_state = switch.value()  # 获取当前的开关状态
    if current_switch_state != last_switch_state:  # 如果当前状态与上次状态不同
        if current_switch_state == 0:
            print("门被打开了!")
            client.publish("homeassistant/binary_sensor/picow_door/contact", "ON")
        else:
            print("门关了!")
            client.publish("homeassistant/binary_sensor/picow_door/contact", "OFF")
        last_switch_state = current_switch_state  # 更新最后的状态

# 在主循环中定期检查门的状态
last_switch_state = None  # 初始化last_switch_state
while True:
    check_door_status()
    time.sleep(1)  # 每秒检查一次

实验结果

根据上诉代码将KCD1船型二档开关连接到核桃派PicoW的引脚42,接线图如下:


使用Thonny IDE连接核桃派PicoW开发板,运行上面代码:

运行成功后可以在MQTT集成找到自定义的swit门开关检测设备:


可以添加到首页仪表盘:

1 个赞