Home Assistant与Ubiquiti结合AI实现家庭自动化魔法

本文详细介绍了如何将Home Assistant家庭自动化平台与Ubiquiti网络设备及AI技术结合,实现智能垃圾桶检测、邮件包裹识别和访客描述等高级自动化场景,包含完整的技术架构和代码实现。

Home Assistant + Ubiquiti + AI = 家庭自动化魔法

如今,似乎每个生产家用电器设备的制造商都想加入物联网的故事。更重要的是,他们都想要自己的应用程序,这意味着你必须使用无数个定制软件产品来控制你的设备。而且它们——除了极少数例外——都很糟糕:

那是我用来控制办公室和主卧室窗帘的应用,但集线器(你需要两个,因为信号范围很差)已经停止通信了。

那个是用于水疗设备的,但看起来它应该认证的服务已经消失了,所以现在无法使用。

还有我最近最喜欢的Advantage Air,它控制着我们刚刚安装的价值数万美元的空调系统。是的,我在同一个网络上,是的,触摸屏有电并且连接到网络。我知道这一点,因为它看起来像这样:

看起来可能像是我在2013年拍的照片,但不对,这是当前一代的应用,还配有一个现在固定在墙上的安卓平板。幸运的是,我可以愉快地忽略它,因为所有实体现在都暴露在Home Assistant(HA)中,然后通过HomeKit Bridge持久化到Apple Home,在那里它们出现在我们的iThings上。(这也意味着我可以用运行Apple Home的漂亮iPad Mini替换那个平板,并将安卓设备放入服务器机架,在那里它仍然需要充当系统的控制器。)

总之,重点是当你全力投入物联网时,你会处理很多垃圾应用,它们都做着非常基本的事情:打开东西、关闭东西、关闭东西等等。HA很棒,因为它抽象掉了这些糟糕的应用,而且现在,它还能做一些比所有这些基本功能更酷得多的事情……

首先将整个物联网生态系统简单地视为触发器和动作。触发器可以基于明确的活动(例如按下按钮)、可观察的条件(例如房间温度)、日程安排、事件以及一系列其他可以用来启动动作的事物。然后动作包括关闭车库门、在扬声器上播放语音公告、向移动设备推送警报,以及像触发器一样,还有许多其他事情。这些都是显而易见的东西,但当你开始考虑这样的设备时,你可以变得非常有创意:

那是一个Sonoff物联网水阀,是的,它有自己的应用🤦‍♂️ 但由于它基于Zigbee,很容易将其集成到HA中,这意味着现在我可以使用的"动作"包括打开软管。很酷,但如果你只是给花园浇水,那就很无聊。让我们做一些更有趣的事情吧:

阀门与软管串联,软管向上指向,正好在面向道路的墙上方,墙上安装了一个这样的设备:

那是一个Ubiquiti G4 Pro门铃(完整披露:Ubiquiti发送了我在这篇文章中使用的所有设备),并且扩展之前使用的术语,它有许多不同的事件HA可以用作触发器,包括按下按钮。将所有东西联系在一起,你就会得到这个:

不仅按下门铃在万圣节会触发软管,它还触发了Lenny Troll,他有点难听清,所以你得靠得非常近🤣 来吧,他们提供了"恶作剧"作为选项之一!

玩够了,让我们进入严肃的部分,根据标题,是AI组件。我正在阅读HA 2025.8的新功能(他们每月以这种形式发布一次),并认为小鸡计数器的例子非常棒。用传统传感器计算鸡舍里鸡的数量是一个难以解决的问题,但如果你有一个能拍出像样照片的摄像头和一个解释照片的AI服务,突然之间你就有了一些很酷的选择。这让我想到了我的垃圾桶:

红色的那个必须在每周二大约07:00前推到路边(那是一般垃圾),黄色的那个每隔一个周二推出(那是可回收垃圾)。有时,我们只在最后一刻才记得,其他时候,我们正好在垃圾车经过时才记得,这可能意味着又要在接下来的两周里过度填充垃圾桶。但我已经有一个Ubiquiti G6 Bullet指向房子的那一侧(配置了隐私遮挡以避免记录邻居),所以现在只需要一个简单的自动化:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
- id: bin_presence_check
  alias: Bin presence check
  mode: single
  trigger:
    - platform: state
      entity_id: binary_sensor.laundry_side_motion
      to: "off"
      for:
        minutes: 1
  condition:
    - condition: time
      weekday:
        - mon
        - tue
  action:
    - service: ai_task.generate_data
      data:
        task_name: Bin presence check
        instructions: >-
          Look at the image and answer ONLY in JSON with EXACTLY these keys:
          - bin_yellow_present: true if a rubbish bin with a yellow lid is visible, else false
          - bin_red_present: true if a rubbish bin with a red lid is visible, else false
          Do not include any other keys or text.
        structure:
          bin_yellow_present:
            selector:
              boolean:
          bin_red_present:
            selector:
              boolean:
        attachments:
          media_content_id: media-source://camera/camera.laundry_side_medium
          media_content_type: image/jpeg
      response_variable: result
    - service: "input_boolean.turn_{{ 'on' if result.data.bin_yellow_present else 'off' }}"
      target:
        entity_id: input_boolean.yellow_bin_present
    - service: "input_boolean.turn_{{ 'on' if result.data.bin_red_present else 'off' }}"
      target:
        entity_id: input_boolean.red_bin_present

好的,这是一个40行的自动化,但它也相当人类可读:

  • 当运动停止一分钟时…
  • 并且是周一或周二…
  • 创建一个AI任务,请求一个指示黄色和红色垃圾桶存在的JSON响应…
  • 并附加一个指向它们的摄像头快照…
  • 然后设置两个输入布尔量的值

由此,我可以在正确的垃圾桶仍然存在而它应该被推到路边时创建一个警报。太神奇了!我一直想做一些这样的效果,但曾假设这需要在垃圾桶本身上安装传感器。但有了AI就不需要了😊

然后我开始得意忘形了。我车道上已经有一个Ubiquiti AI LPR(那是"车牌读取器")摄像头,而它正好指向信箱。现在,我早已在信箱上安装了基于Zigbee的Aqara门窗传感器(它们实际上是簧片开关)(一个用于信件投入的地方,一个用于包裹),它们通过房子天花板内的Sonos扬声器宣布邮件的存在。这真的很有用,而现在,它甚至更好了:

我在外出购物时在Apple Watch上截取了那个屏幕,尽管很难看清我手腕上的小图片,但我毫不费力地阅读了警报的内容。以下是它的工作原理:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
- id: letterbox_and_package_alert
  alias: Letterbox/Package alerts
  mode: single
  trigger:
    - id: letter
      platform: state
      entity_id: binary_sensor.letterbox
      to: "on"
    - id: package
      platform: state
      entity_id: binary_sensor.package_box
      to: "on"
  variables:
    event: "{{ trigger.id }}"  # "letter" or "package"
    title: >-
      {{ "You've got mail" if event == "letter" else "Package delivery" }}
    message: >-
      {{ "Someone just left you a letter" if event == "letter" else "Someone just dropped a package" }}
    tts_message: >-
      {{ "You've got mail" if event == "letter" else "You've got a package" }}
    file_prefix: "{{ 'letterbox' if event == 'letter' else 'package_box' }}"
    file_name: "{{ file_prefix }}_{{ now().strftime('%Y%m%d_%H%M%S') }}"
    snapshot_path: "/config/www/snapshots/{{ file_name }}.jpg"
    snapshot_url: "/local/snapshots/{{ file_name }}.jpg"
  action:
    - service: camera.snapshot
      target:
        entity_id: camera.driveway_medium
      data:
        filename: "{{ snapshot_path }}"
    - service: script.hunt_tts
      data:
        message: "{{ tts_message }}"
    - service: ai_task.generate_data
      data:
        task_name: "Mailbox person/vehicle description"
        instructions: >-
          Look at the image and briefly describe any person
          and/or vehicle standing near the mailbox. They must
          be immediately next to the mailbox, and describe
          what they look like and what they're wearing.
          Keep it under 20 words.
        attachments:
          media_content_id: media-source://camera/camera.driveway_medium
          media_content_type: image/jpeg
      response_variable: description
    - service: notify.adult_iphones
      data:
        title: "{{ title }}"
        message: "{{ (description | default({})).data | default('no description') }}"
        data:
          image: "{{ snapshot_url }}"

这对于弄清楚我们似乎收到的无休止的送货中哪些值得"放下工具"出去取邮件真的很有帮助。同样有用的是最近使用AI任务的情况,就在今天记录的(并获得了当事人的许可):

像包裹一样,我们似乎接待了无休止的访客,在靠近门之前了解谁在门口是相当方便的。我们确实在手机上收到视频(而且,如你所见,iPad上也有),但那不一定总是在手边,这样孩子们也能知道是谁。以下是代码(这是一个播放门铃铃声的单独自动化):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- id: doorbell_ring_play_ai
  alias: The doorbell is ringing, use AI to describe the person
  trigger:
    platform: state
    entity_id: binary_sensor.doorbell_ring
    to: 'on'
  action:
  - service: ai_task.generate_data
    data:
      task_name: "Doorbell visitor description"
      instructions: >-
        Look at the image and briefly describe how many people you see and what they're wearing, but don't refer to "the image" in your response.
        If they're carrying something, also explain that but don't mention it if they're not.
        If you can recognise what job they might, please include this information too, but don't mention it if you don't know.
        If you can tell their gender or if they're a child, mention that too.
        Don't tell me anything you don't know, only what you do know.
        This will be broadcast inside a house so should be conversational, preferably summarised into a single sentence.
      attachments:
        media_content_id: media-source://camera/camera.doorbell
        media_content_type: image/jpeg
    response_variable: description
  - service: script.hunt_tts
    data:
      message: "{{ (description | default({})).data | default('I have no idea who is at the door') }}"

我一直在逐步改进那个提示,目前它做得相当不错。听到回应中如何提到他参与" detailing"了吗?那是因为他衬衫上的公司标志包含了这个词,而且确实,他是来这里给汽车做细节处理的。

这些都是书呆子的好东西,表面上看起来微不足道,却花费了我数小时的时间。但正是通过玩弄这样的技术并为它们找到不寻常的用例,我们最终构建了意义重大得多的东西。回到我开头的观点,物联网开始远远超越本文开头的垃圾应用,我们很快就会看到真正有用、改善生活的实现。为2025年万圣节带来更多AI驱动的好东西!

编辑:我本应将其包含在原始文章中,但ai_task服务使用的是OpenAI,因此所有处理都在云端完成,而不是在HA本地。这需要API密钥和付费,尽管我认为定价相当合理(而且绝大多数请求来自测试)。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计