Home Assistant

Home Assistant: sử dụng Google Calendar để tạo thông báo

Hass Google Calendar New Event Web

Thuận tiện tạo các sự kiện trên điện thoại rồi để Hass tự động nhắc nhở cho người dùng phù hợp

17 phút để đọc hết nội dung

Tiếp nối bài trước về Tích hợp lịch trên Google Calendar vào Hass, ở bài viết này, chúng ta sẽ tìm cách sử dụng lịch này linh hoạt và hiệu quả hơn, cho phép:

  • Lựa chọn người dùng/thiết bị nhận được thông báo khi tạo event và…
  • Tuỳ chọn thời điểm thông báo so với thời gian bắt đầu event (sớm hơn/trễ hơn) ngay khi tạo event – sự kiện (trên app/web)

Đây là tính năng được yêu cầu rất nhiều với Google Assistant nhưng hiện tại vẫn chưa có cách nào dễ dàng để thực hiện. Hass linh hoạt hơn nhiều.

! Yêu cầu tối thiểu/khuyến nghị

Yêu cầu là bạn đã liên kết thành công Google Calendar vào Hass và các lịch này đã xuất hiện như sensor trong Hass. Nếu chưa, bạn cần làm theo bài viết Tích hợp lịch trên Google Calendar vào Hass trước.
Nếu bạn muốn gửi thông báo đến thiết bị cá nhân của một user – thành viên, bạn phải cấu hình notify platform đó trước. Các notify platform thường dùng là mobile_app (qua app Home Assistant trên Android/iOS) và telegram.

Trước tiên, ta sẽ cần tinh chỉnh cấu hình mặc định được sử dụng bởi integration Google Calendar. Cấu hình này được tự động tạo ra và cập nhật tại file /config/google_calendars.yaml. Bạn sử dụng phương pháp tương tự như khi chỉnh sửa file configuration.yaml để chỉnh sửa file này.

Cấu hình các sensor Google Calendar

Bên dưới là cấu hình mẫu của file google_calendars.yaml, được tự động tạo ra trong bài viết trước.

- cal_id: [email protected]
  entities:
  - device_id: konnected_pi5_hass
    ignore_availability: true
    name: Konnected Pi5 Hass
    track: true

- cal_id: addressbook#[email protected]
  entities:
  - device_id: contacts
    ignore_availability: true
    name: Contacts
    track: true

- cal_id: vi.vietnamese#[email protected]
  entities:
  - device_id: ngay_le_o_viet_nam
    ignore_availability: true
    name: "Ng\xE0y l\u1EC5 \u1EDF Vi\u1EC7t Nam"
    track: true
    max_results: 31

Mỗi lịch trong Google Calendar (GCal) sẽ được tự động lấy về và tạo thành một cấu hình như trên. Trong đó:

  • cal_id: mã định danh của mỗi lịch, do Google Calendar tạo. Ta không thay đổi mã này.
  • entities: với mỗi lịch, bạn có thể tạo ra nhiều sensor, mỗi sensor sở hữu một bộ cấu hình như bên dưới. Tất cả đều dùng cùng dữ liệu sự kiện lấy từ GCal, chỉ khác nhau về cách xử lý.
  • device_id: mã của sensor (entity_id), bạn chọn tuỳ ý. Tốt nhất nên chọn sao cho gợi nhớ, dễ quản lý. Không dùng tiếng Việt có dấu.
  • name: tên của sensor, chọn tuỳ ý, có thể đặt sao cho có ý nghĩa, dễ hiển thị ra giao diện.
  • track: true/false, có tạo sensor này hay không. Chọn true để sử dụng nó.
  • search: sensor này chỉ lấy các sự kiện thoả mãn giá trị search này. Bạn xem ở dưới để dễ hiểu hơn.
  • offset: quy định cụm kí tự/chữ báo trước thời gian sớm hơn/trễ hơn để kích hoạt sensor so với thời gian bắt đầu của sự kiện.
  • max_results: số lượng events lấy về mỗi lần

Bạn xem cấu hình mẫu mình tạo ở dưới đây để dễ hiểu hơn. Phần giải thích ở bên dưới.

- cal_id: [email protected]
  entities:
  - device_id: lich_chung
    ignore_availability: true
    name: Lịch chung
    track: true
    offset: "!!"
  - device_id: lich_vo_yeu
    ignore_availability: true
    name: Lịch Của Vợ Yêu #Quái
    track: true
    search: "#Vo"
    offset: "!!"
  - device_id: lich_bo
    ignore_availability: true
    name: Lịch của bố
    track: true
    search: "#daddy"
    offset: "!!"

Bạn có thấy là một số cấu hình có thêm các tuỳ chọn offsetsearch? Lí do:

search: những event có tiêu đề chứa cụm từ trong tuỳ chọn search này mới được lấy bởi sensor này. Ví dụ khi mình tạo một event mà chỉ tác động đến calendar.lich_bo, mình sẽ tạo event với tiêu đề là “Mang rác đi đổ #daddy”.
Kí tự ‘#’ được chọn vì ít được sử dụng, bạn có thể chọn kí tự khác nếu có thói quen sử dụng kí tự ‘#’. Nếu chỉ cấu hình “daddy” thì có khả năng những event khác sẽ bị chọn nhầm.

Tuy nhiên, bạn có thể cấu hình cụm search kiểu “vợ “ để mọi event có từ này sẽ được lấy bởi calendar.lich_cua_vo. Ví dụ, sự kiện “Hôm nay vợ yêu sẽ nấu món ưa thích của cả nhà” sẽ được tự động lấy.

offset: "!!", quy định phần tiêu đề quy định số giờ, phút sớm hơn/chậm hơn để chuyển attributes offset_reached thành ‘true’ trước khi sự kiện thực sự xảy ra. Ví dụ, mình sẽ đặt tiêu đề như sau để chỉ kích hoạt calendar.lich_booffset_reached sẽ được kích hoạt trước 20 phút “Mang rác đi đổ #daddy !!-00:20” hoặc “#daddy Mang rác đi đổ !!-20“.
Lần nữa, cụm kí tự “!!” được sử dụng vì ít khi cần dùng đến. Đi sau cụm này là số giờ và phút ở định dạng HH:MM hoặc chỉ phút.
Dấu ‘-‘ để kích hoạt offset_reached sớm hơn, không có hoặc dấu ‘+’ để kích hoạt trễ hơn.

Ở đây mình còn tạo thêm một calendar.lich_chung nữa lấy toàn bộ event trong lịch bằng cách bỏ qua tuỳ chọn search:.

Sau khi cấu hình, bạn khởi động lại Hass để khởi tạo các sensor này.

! Thêm lịch mới vào Hass/Vô hiệu hoá một lịch

Hass chỉ nhận các Lịch (không phải event) mới khi khởi động lại. Vì vậy nếu bạn muốn thêm một lịch mới, sau khi thêm trong Google Calendar (xem bài viết trước), bạn cần khởi động lại Hass để nhận lịch này.

Nếu có lịch mà bạn không muốn Hass lấy về, cấu hình track: false cho tất cả entities: của lịch này.

Hass Google Calendar

Các lịch được tạo ra trong Hass sau khi khởi động lại, bạn để ý sự khác nhau của giá trị message, offset_reached giữa các lịch này.

Tạo automation thông báo

Thông báo đến một thành viên

Ta sẽ tạo các automation để gửi thông báo đến từng thành viên tuỳ theo lịch tương ứng. Để ví dụ, ta sẽ gửi notification đến điện thoại của thành viên ‘Vợ’ ngay khi attributes offset_reached chuyển thành ‘true’. Với các thành viên không sử dụng điện thoại, bạn có thể thông báo đến các loa thông minh thay vì gửi notification.

update Retina Cập nhật ngày 02/06/2020
Điều chỉnh template is_state_attr

Do cách xử lý của hàm is_state_attr, tất cả các value_template sử dụng hàm này trong các automation bên dưới được sửa như sau:
Cũ:
value_template: ‘{{is_state_attr(”calendar.lich_chung”,”offset_reached”,”true”)}}’
Mới:
value_template: '{{is_state_attr(''calendar.lich_chung'',''offset_reached'',true)}}'
Thay đổi: chuyển ”true” vốn là chuỗi kí tự thành kiểu giá trị boolean (kiểu logic)

- id: '1588819710680'
  alias: Notify Vo Yeu about Calendar event
  description: Gửi thông báo đến đt vợ khi có việc cần làm
  trigger:
  - platform: template
    value_template: '{{is_state_attr(''calendar.lich_vo_yeu'',''offset_reached'',true)}}'
  condition:
  - after: 06:00:00
    before: '23:00:00'
    condition: time
  action:
  - data_template:
      title: 'Sự kiện: {{-state_attr('calendar.lich_vo_yeu','message')|regex_replace('\s#\w+') }}'
      message: >
        Diễn ra lúc {{state_attr('calendar.lich_vo_yeu','start_time')}} tại {{state_attr('calendar.lich_vo_yeu','location')}}
    service: notify.mobile_app_vo_iphone

Thông báo ra loa chỉ với một số event nhất định

Ở đây ta sẽ sử dụng calendar.lich_chung để thông báo ra loa chỉ những event mà tiêu đề chứa cụm ‘#speaker‘. Có 2 cách để thực hiện:

  1. Tạo thêm một lịch riêng với tuỳ chọn search: "#speaker" rồi tạo automation tương tự như bước trước
  2. Tìm kiếm trong attributes message của calendar.lich_chung, nếu có cụm ‘#speaker’ mới phát ra loa

Bên dưới là cấu hình mẫu sử dụng cách 2, bạn thay thế các entity_idservice cho phù hợp với mình.
Dịch vụ chuyển chữ thành lời nói (TTS) sử dụng ở đây là Google Translate.

- id: '1588819710680'
  alias: Notify via Living Room about Calendar event
  description: Thông báo giọng nói ra loa phòng khách khi có Calendar event
  trigger:
  - platform: template
    value_template: '{{is_state_attr(''calendar.lich_chung'',''offset_reached'',true)}}'
  condition:
  - condition: template
    value_template: '{{state_attr(''calendar.lich_chung'',''message'')|regex_search(''#speaker'')}}'
  action:
  - data_template:
      language: 'vi'
      entity_id: media_player.living_room_speaker
      message: >
        {% set starttime = state_attr('calendar.lich_chung','start_time') %}
        {% set datetime = strptime(starttime,'%Y-%m-%d %H:%M:%S') -%}
        Chào mọi người, sự kiện sắp tới: {{state_attr('calendar.lich_chung','message')|regex_replace('\s#\w+') }} sẽ diễn ra lúc {{datetime.hour}} giờ {{datetime.minute}} phút.
    service: tts.google_say

Lưu ý: ở đây ta sử dụng hàm strptime() và để chuyển thời điểm xảy ra sự kiện từ dạng 2020-05-07 12:15:00 thành thời gian thật sự để có thể trích xuất giờ và phút. Nếu ngày giờ lấy về từ Google Calendar của bạn có dạng khác, cần thay đổi nội dung hàm strptime(starttime,’%Y-%m-%d %H:%M:%S’) cho phù hợp.
Tham khảo thêm tại đây: Home Assistant: template và các filter cơ bản

Một tình huống sử dụng cụ thể

Ở đây mình sẽ mô tả lại cách thức thực hiện một nhu cầu khá thường gặp khi xây dựng SmartHome điều khiển bởi Hass như sau:

Tôi muốn sử dụng hệ thống loa thông báo (Google Home) để nhắc nhở người ở nhà (chủ yếu là con cái) khi sắp đến giờ làm việc nhà như đổ rác, dắt chó đi dạo hay tưới cây v.v.. Những thông báo này thường vào giờ cố định và lặp lại một số lần trong tuần nhưng thường xuyên bị thay đổi tuỳ theo tháng, theo mùa.

Thông thường với nhu cầu này, mọi người sẽ nghĩ ngay đến automation (chuẩn rồi) kích hoạt theo thời điểm (platform: time). Điều này không sai nhưng có mấy cái bất tiện:

  1. Mỗi khi thay đổi nội dung nhắc nhở hoặc thời gian nhắc nhở, người dùng sẽ phải vào automation để chỉnh sửa và reload lại automation. Việc này không khó nhưng tương đối bực mình và khá chậm.
    Cá nhân mình cũng không thích việc reload lại automation thường xuyên (do có nhiều automation xen cài).
  2. Nếu không như bước 1 thì số lượng automation sẽ rất nhiều hoặc automation sẽ rất phức tạp.

Mình sẽ mô tả cách thức để thực hiện điều này sử dụng lịch Google Calendar và Hass như sau:

  1. Cấu hình tích hợp Google Calendar trong Hass như bài trước
  2. Cấu hình một lịch trong Hass như bước 1, ví dụ như calendar.lich_chung
  3. Tạo automation thông báo event trên lịch này tương tự Bước 2
  4. Tạo sự kiện lặp lại trên ứng dụng Calendar của điện thoại rồi để Hass tự động thông báo

Việc tạo event trên điện thoại cực kì dễ dàng với đầy đủ tuỳ chọn lặp lại theo ngày, tuần, tháng hay chỉ các thứ trong tuần. Nếu cần thêm thông báo ta chỉ cần tạo thêm trên điện thoại, nếu cần bỏ thông báo, chỉ cần xoá đi là xong.

Một số mô tả cách tạo event trên điện thoại chạy hệ điều hành iOS, sử dụng ứng dụng Calendar có sẵn.

previous arrow
next arrow
Slider

Một số hạn chế và lưu ý

Các sensor lịch làm việc không tốt lắm với các sự kiện chồng lên nhau (trong cùng sensor, khác sensor thì không sao cả), vì vậy bạn cần chú ý đến thời gian bắt đầu và kết thúc khi tạo sự kiện. Nếu chỉ cần nhắc nhở, chọn thời gian bắt đầu và kết thúc gần nhau (ví dụ sự kiện kéo dài 5p).

Lần nữa, cần lưu ý là Hass chỉ lấy các sự kiện mới mỗi 15 phút và khi khởi động, do vậy bạn không thể tạo các nhắc nhở quá gần thời điểm hiện tại.

Nếu đã tạo automation kích hoạt bằng attributes offset_reached, chỉ những event có offset (!!) mới kích hoạt automation.
Để khắc phục trường hợp quên thì có thể thêm trigger bằng state của sensor.

- id: '1588819710680'
  alias: Notify Vo Yeu about Calendar event
  description: Gửi thông báo đến đt vợ khi có việc cần làm
  trigger:
  - platform: template
    value_template: '{{is_state_attr(''calendar.lich_vo_yeu'',''offset_reached'',true)}}'
#Phần thêm vào
  - trigger: state
    entity_id: calendar.lich_vo_yeu
    state: 'on'
 ###
  condition:
  - after: 06:00:00
    before: '23:00:00'
    condition: time
  action:
  - data_template:
      title: 'Sự kiện: {{-state_attr('calendar.lich_vo_yeu','message')|regex_replace('\s#\w+') }}'
      message: >
        Diễn ra lúc {{state_attr('calendar.lich_vo_yeu','start_time')}} tại {{state_attr('calendar.lich_vo_yeu','location')}}
    service: notify.mobile_app_vo_iphone

Tuỳ vào loại thông báo, bạn nên chú ý khi đặt tênoffset (‘!!’) sự kiện cho phù hợp, đặc biệt khi thông báo bằng giọng nói.

Cuối cùng, khi tạo event để thông báo trên Hass, bạn nhớ chọn đúng Lịch trên ứng dụng. Có thể đặt lịch này làm mặc định, cách làm tuỳ vào ứng dụng và hệ điều hành.

! Về tạo sự kiện trực tiếp trên Hass

Điều này có thể làm được dễ dàng. Tuy nhiên để linh hoạt thì yêu cầu người thêm sự kiện phải nhập tương đối phức tạp theo một cú pháp quy định trước. Do vậy nên không thích hợp lắm nếu bạn muốn cung cấp khả năng này cho các thành viên khác như trẻ em trong gia đình.
Trừ phi bạn cài đặt theo hướng đơn giản hoá thao tác, ví dụ chỉ cần nhập “Uống sữa sau 20 phút” để tạo nhắc nhở trên Hass.

Nếu nhiều bạn có nhu cầu thì mình sẽ thực hiện trong một bài khác.

Cảm ơn bạn đã xem bài viết này!

konnectED Team.

Lên Đầu
  • Đăng ký
Bạn quên mất mật khẩu? Vui lòng nhập tên đăng nhập và địa chỉ email đã đăng ký. Bạn sẽ nhận được liên kết tạo mật khẩu mới qua email (bạn nhớ kiểm tra hộp spam trong trường hợp email đi lạc).