Bỏ qua đến nội dung
Gửi cảnh báo Telegram kèm ảnh camera và mô tả AI khi có người trước cổng bằng Home Assistant

Gửi cảnh báo Telegram kèm ảnh camera và mô tả AI khi có người trước cổng bằng Home Assistant

Cách mình dùng Home Assistant, Frigate, AI Task và Telegram để gửi cảnh báo có người trước cổng kèm ảnh/video và mô tả ngắn bằng tiếng Việt.

Mình muốn cảnh báo camera ở nhà không chỉ dừng ở kiểu "có chuyển động". Cảnh báo kiểu đó dễ gây mệt vì lúc nào cũng phải mở app, tua clip, tự xem có gì đáng chú ý hay không.

Flow mình đang dùng hiện tại là:

  1. Frigate phát hiện người hoặc sự kiện ở khu vực cổng.
  2. Home Assistant nhận event qua MQTT.
  3. Home Assistant chụp snapshot hoặc lấy clip từ Frigate.
  4. AI Task phân tích hình từ camera.
  5. Telegram nhận ảnh/video/GIF kèm mô tả ngắn bằng tiếng Việt.
Automation gửi cảnh báo camera trong Home Assistant

Kiến trúc tổng thể

Frigate camera event
    |
    v
MQTT topic: frigate/events
    |
    v
Home Assistant automation
    |
    +--> camera.snapshot / Frigate clip
    |         |
    |         v
    |     AI Task Gemini
    |         |
    |         v
    +----> Telegram alert

Trong cấu hình thật của mình, phần này dùng:

  • Frigate camera: camera.gate_camera, camera.garage_camera
  • Occupancy sensors: binary_sensor.doorbell_person_occupancy, binary_sensor.gate_camera_person_occupancy, binary_sensor.garage_camera_person_occupancy
  • AI Task: ai_task.gemini_flash hoặc ai_task.gemini_image_3
  • Telegram actions: telegram_bot.send_video, telegram_bot.send_animation, telegram_bot.send_photo
  • Shell command tạo GIF: shell_command.create_gate_gif, shell_command.create_gif

Cấu hình Telegram trong Home Assistant

Phần notifier Telegram nằm trong configuration.yaml. Khi viết lại cho người khác dùng, chỉ nên để dạng mẫu như sau:

notify:
  - platform: telegram
    name: telegram_home_notifications
    chat_id: YOUR_TELEGRAM_CHAT_ID

  - platform: telegram
    name: telegram_home_alerts
    chat_id: YOUR_TELEGRAM_ALERT_CHAT_ID

Không nên đưa bot token, chat id thật, webhook thật hoặc private URL vào bài viết. Những giá trị đó nên để trong secrets.yaml, biến môi trường, hoặc cấu hình riêng của hệ thống.

Tạo shell command để ghép GIF từ nhiều snapshot

Mình vẫn giữ cách chụp nhiều ảnh liên tiếp rồi ghép thành GIF. Nó giúp xem nhanh chuyện gì vừa xảy ra mà không cần mở cả clip dài.

Trong configuration.yaml:

shell_command:
  create_gate_gif: >-
    python3 /config/python_scripts/create_gif.py
    /media/snapshots/gate_snapshot1.jpg
    /media/snapshots/gate_snapshot2.jpg
    /media/snapshots/gate_snapshot3.jpg
    /media/snapshots/gate_motion.gif

  create_gif: >-
    python3 /config/python_scripts/create_gif.py
    /media/snapshots/garage_snapshot1.jpg
    /media/snapshots/garage_snapshot2.jpg
    /media/snapshots/garage_snapshot3.jpg
    /media/snapshots/garage_motion.gif

Script Python tối giản:

from PIL import Image
import sys

image_paths = sys.argv[1:-1]
output_path = sys.argv[-1]

images = [Image.open(path) for path in image_paths]
images[0].save(
    output_path,
    save_all=True,
    append_images=images[1:],
    duration=500,
    loop=0,
)

Automation chính: có người ở khu vực chuông cửa

Automation thật trong hệ của mình có alias Human at doorbell area. Nó nhận event từ MQTT topic frigate/events, nhưng chỉ chạy khi sensor người ở khu vực doorbell đang bật.

Automation editor trong Home Assistant

Phiên bản đã rút gọn và ẩn thông tin riêng:

alias: Human at doorbell area
description: Người bấm chuông trước cổng
trigger:
  - platform: mqtt
    topic: frigate/events
condition:
  - condition: state
    entity_id: binary_sensor.doorbell_person_occupancy
    state: "on"
action:
  - service: camera.snapshot
    target:
      entity_id: camera.gate_camera
    data:
      filename: /media/snapshots/gate_snapshot.jpg

  - alias: Nhận diện người trong khung hình
    service: ai_task.generate_data
    data:
      entity_id: ai_task.gemini_flash
      task_name: Nhận diện người
      instructions: >
        Phát hiện chuyển động và mô tả ngắn gọn bằng tiếng Việt.
        Nếu có người hoặc xe, mô tả người đang làm gì, đi bộ hay đi xe,
        màu áo nổi bật nếu thấy rõ.
        Không mô tả vật thể đứng yên hoặc tòa nhà.
        Nếu không thấy nguyên nhân rõ ràng, trả lời:
        Camera phát hiện chuyển động ở cổng.
      attachments:
        media_content_id: media-source://camera/camera.gate_camera
        media_content_type: application/vnd.apple.mpegurl
    response_variable: generated_content

  - service: telegram_bot.send_video
    data:
      url: YOUR_HASS_URL/api/frigate/notifications/{{ trigger.payload_json["after"]["id"] }}/clip.mp4
      caption: "{{ generated_content['data'] }}"
      target: YOUR_TELEGRAM_CHAT_ID
      inline_keyboard: >
        Tắt thông báo:/automation.human_in_doorbell,
        Gửi hình ảnh hiện tại:/snapshot

  - delay: "00:10:00"
mode: single

Điểm quan trọng ở đây là không gửi cảnh báo ngay khi MQTT có event. Automation còn kiểm tra binary_sensor.doorbell_person_occupancy. Nhờ vậy cảnh báo tập trung vào người trước cổng, giảm bớt nhiễu từ các event không liên quan.

Script phụ: chụp nhiều ảnh, AI mô tả, gửi GIF lên Telegram

Mình cũng có script Gate - Snapshot, AI & Notification. Script này phù hợp khi muốn gửi một GIF ngắn thay vì chỉ gửi clip Frigate.

Script chụp snapshot, gọi AI và gửi Telegram trong Home Assistant

Flow của script:

  1. Chạy song song AI Task và chuỗi snapshot.
  2. Chụp 3 ảnh từ camera.gate_camera.
  3. Ghép 3 ảnh thành gate_motion.gif.
  4. Nếu AI không thấy bất thường thì dừng.
  5. Nếu có nội dung đáng chú ý thì gửi animation lên Telegram.

Phiên bản rút gọn:

alias: Gate - Snapshot, AI & Notification
sequence:
  - parallel:
      - service: ai_task.generate_data
        data:
          entity_id: ai_task.gemini_image_3
          task_name: Nhận diện
          instructions: >
            Phân tích ảnh từ camera lối vào.
            Nếu thấy người hoặc phương tiện, trả về mô tả cực ngắn gọn.
            Không mô tả vật thể đứng yên, tòa nhà, hoặc chi tiết không liên quan.
            Nếu không xác định được nguyên nhân, trả về:
            Không phát hiện bất thường
          attachments:
            media_content_id: media-source://camera/camera.gate_camera
            media_content_type: image/jpeg
        response_variable: generated_content

      - sequence:
          - service: camera.snapshot
            target:
              entity_id: camera.gate_camera
            data:
              filename: /media/snapshots/gate_snapshot1.jpg
          - delay: "00:00:01.5"
          - service: camera.snapshot
            target:
              entity_id: camera.gate_camera
            data:
              filename: /media/snapshots/gate_snapshot2.jpg
          - delay: "00:00:03.5"
          - service: camera.snapshot
            target:
              entity_id: camera.gate_camera
            data:
              filename: /media/snapshots/gate_snapshot3.jpg
          - service: shell_command.create_gate_gif

  - if:
      - condition: template
        value_template: "{{ generated_content['data'] == 'Không phát hiện bất thường' }}"
    then:
      - stop: ""
    else:
      - service: telegram_bot.send_animation
        data:
          file: /media/snapshots/gate_motion.gif
          target: YOUR_TELEGRAM_CHAT_ID
          caption: "{{ generated_content['data'] }}"
mode: single

Trong thực tế, AI prompt nên càng ngắn càng tốt. Nếu prompt dài và mơ hồ, AI dễ mô tả cả cây, tường, bóng đổ, hoặc vật đứng yên. Với camera an ninh, mình chỉ cần câu ngắn kiểu:

Một người mặc áo sáng đang đứng trước cổng.

Biến thể cho garage

Garage dùng cùng ý tưởng nhưng đổi camera và file output:

  • camera.garage_camera
  • /media/snapshots/garage_snapshot1.jpg
  • /media/snapshots/garage_motion.gif
  • shell_command.create_gif
  • script.garage_snapshot_ai_notification_duplicate

Automation Ghi lại chuyển động khu vực nhà xe đang làm nhiệm vụ route:

  • Nếu binary_sensor.gate_camera_person_occupancy bật thì gọi script cổng.
  • Nếu binary_sensor.garage_camera_person_occupancy bật trong khung giờ đêm thì gọi script garage.

Đây là cách mình tách phần "khi nào chạy" khỏi phần "chụp, phân tích và gửi".

Biến thể nâng cấp: nhận diện shipper

Sau này mình thêm một flow riêng cho shipper. Ý tưởng là AI không chỉ hỏi "có người không", mà hỏi cụ thể:

Có bao nhiêu shipper đang đứng trước cổng?

Automation đầu tiên đọc Frigate event, dùng AI Task để đếm shipper, rồi set counter:

alias: Đếm shipper trước cổng
trigger:
  - platform: mqtt
    topic: frigate/events
condition:
  - condition: template
    value_template: "{{ trigger.payload_json['after']['label'] == 'person' }}"
action:
  - service: ai_task.generate_data
    response_variable: shipper_count
    data:
      entity_id: ai_task.gemini_flash
      task_name: Camera AI
      instructions: >
        Đếm số shipper đang đứng trước cổng trong hình.
        Chỉ dựa vào dấu hiệu như đồng phục giao hàng, mũ bảo hiểm,
        túi giao hàng, thùng hàng, xe máy giao hàng.
        Không nhận diện danh tính cá nhân.
        Trả về đúng một dòng dạng số.
      attachments:
        media_content_id: media-source://camera/camera.gate_camera
        media_content_type: application/vnd.apple.mpegurl

  - if:
      - condition: template
        value_template: >
          {{ (shipper_count['data'] | regex_findall_index('([0-9]+)', 0) | int(0)) > 0 }}
    then:
      - service: counter.set_value
        target:
          entity_id: counter.shipper_count
        data:
          value: >
            {{ shipper_count['data'] | regex_findall_index('([0-9]+)', 0) | int(0) }}
      - service: camera.snapshot
        target:
          entity_id: camera.gate_camera
        data:
          filename: /media/snapshots/gate_snapshot1.jpg

Automation thứ hai chỉ lo gửi Telegram khi counter lớn hơn 0:

alias: Thông báo shipper đứng trước cổng
trigger:
  - platform: numeric_state
    entity_id: counter.shipper_count
    above: 0
action:
  - service: telegram_bot.send_photo
    data:
      file: /media/snapshots/gate_snapshot1.jpg
      caption: AI nhận diện được có shipper đứng trước cổng
      inline_keyboard:
        - Chụp lại camera cổng và garage:/snapshot

Cách này hay hơn khi mình muốn các automation khác cũng dùng lại trạng thái counter.shipper_count, ví dụ bật loa báo, hiện card trên dashboard, hoặc gửi thông báo khác cho người đang ở nhà.

Kiểm tra trong Developer Tools

Sau khi cấu hình xong, vào Developer Tools -> States kiểm tra các entity:

camera.gate_camera
camera.garage_camera
binary_sensor.doorbell_person_occupancy
binary_sensor.gate_camera_person_occupancy
binary_sensor.garage_camera_person_occupancy
automation.human_in_doorbell
script.garage_snapshot_ai_notification_duplicate
counter.shipper_count

Trong lần kiểm tra live state ngày 13/06/2026, automation Human at doorbell area, automation nhận diện shipper và automation gửi thông báo shipper đều đang bật. script.new_scriptscript.garage_snapshot_ai_notification_duplicate đang ở trạng thái off, đúng với kỳ vọng vì script chỉ chạy khi có trigger. counter.shipper_count đang là 0, còn các sensor hiện diện người ở doorbell, gate và garage đều đang off.

Điểm đáng chú ý là camera.gate_camera tại thời điểm kiểm tra đang unavailable, trong khi camera.garage_camera vẫn recording. Đây là lý do mình luôn kiểm tra Developer Tools trước khi debug YAML: nhiều lỗi cảnh báo không đến từ automation, mà đến từ camera, entity hoặc integration phía sau đang unavailable.

Một số lưu ý vận hành

  1. Không gửi ảnh nếu AI không thấy gì rõ ràng
    Thêm một câu fallback cố định như Không phát hiện bất thường, rồi dùng if để dừng script.
  2. Không đưa URL nội bộ hoặc token vào message
    Nếu cần gửi clip Frigate, dùng URL đã được Home Assistant bảo vệ và tránh hardcode secret.
  3. Đừng để AI nhận diện danh tính cá nhân
    Prompt nên chỉ mô tả hành động, trang phục, xe, số lượng người, hoặc dấu hiệu shipper. Không nên yêu cầu AI đoán người đó là ai.
  4. Chụp nhiều frame sẽ tốt hơn một frame
    Một ảnh đơn có thể bị mờ hoặc đúng lúc người đi ra khỏi khung hình. Ba ảnh cách nhau 1-3 giây thường đủ để AI mô tả tốt hơn.
  5. Tách automation và script
    Automation quyết định khi nào chạy. Script quyết định chạy những bước nào. Cách này dễ debug và dễ tái sử dụng.

Kết luận

Điểm hay của Home Assistant là mình không bị khóa trong app camera hay app AI nào. Frigate lo phát hiện, Home Assistant lo điều phối, Gemini/AI Task lo mô tả, Telegram lo gửi cảnh báo.

Khi ghép lại, cảnh báo an ninh trở nên hữu ích hơn nhiều: mở Telegram lên là biết trước cổng đang có người, có clip hoặc ảnh kèm theo, và có một câu mô tả đủ ngắn để quyết định có cần mở camera xem kỹ hay không.

Bạn thấy bài viết hữu ích?

Đăng ký để nhận thông báo khi có bài viết mới.

Kiểm tra hộp thư để xác nhận email!
Bạn đã đăng ký thành công vào Geek Playground
Tuyệt vời! Tiếp theo, hoàn tất thanh toán để có quyền truy cập đầy đủ vào Geek Playground
Chào mừng trở lại! Bạn đã đăng nhập thành công.
Thành công! Tài khoản của bạn đã được kích hoạt đầy đủ, bạn hiện có quyền truy cập vào tất cả nội dung.
Thành công! Thông tin thanh toán của bạn đã được cập nhật.
Cập nhật thông tin thanh toán không thành công.