Home Assistant

Home Assistant: template và các filter cơ bản

Hass Template Tools

Sử dụng Templating trong Hass linh hoạt và hiệu quả

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

Templating – khuôn mẫu/hình mẫu, là một trong những tính năng nâng cao rất hữu dụng của Home Assistant (Home Assistant). Nội dung bài viết này sẽ làm rõ cách sử dụng Template trong Home Assistant và danh sách thường dùng.

Hiểu đơn giản, templating sẽ giúp bạnchế biến” thông tin trong Hass, vào Hass và ra khỏi Hass theo ý mình, như:

Di chuyển nhanh: các filter và cấu trúc thường dùng

  1. Tuỳ chỉnh các thông điệp – message trong thông báo – notification, cả bằng chữ và lời nói
  2. Trích xuất và thay đổi các thông tin mà Hass nhận được từ nguồn bên ngoài như mqtt, websocket, rest
  3. Điều khiển tự động hoá – automation thông qua các cấu trúc rẽ nhánh, vòng lặp
  4. Tuỳ chỉnh giao diện theo thông tin trong Hass hay ngữ cảnh

Cấu trúc thông tin của một entity

States Object – đối tượng cơ bản để lấy thông tin từ các Thực thể – Entity

Để sử dụng Template hiệu quả, bạn cần nắm được cấu trúc cơ bản của một đối tượng States, chứa thông tin của tất cả các entity trong Home Assistant. Đối tượng States có các attribute – thuộc tính cơ bản như ảnh trên.
Ví dụ, states của entity home thuộc domain zone bao gồm:

– entity_id: zone.home
– domain: zone
– name (hay friendly_name): my home (tên bạn tuỳ chọn)
– state: zoning (mặc định)
– attributes: [‘hidden’, ‘latitude’, ‘longitude’, ‘radius’, ‘passive’, ‘editable’, ‘friendly_name’, ‘icon’]
– last_changed
– last_updated

Ta có thể truy xuất từng thuộc tính này qua template bằng . (dấu chấm) hay [ ]. Để truy xuất trạng thái – state của một entity, ta dùng cấu trúc states.entity_id.state hoặc state.domain.entity[‘state’] (với một chút khác biệt nhưng không quá quan trọng). Ví dụ, truy xuất trạng thái của entity_id zone.home, ta dùng cấu trúc states.zone.home.state [zone chính là domain].

Hoặc ta cũng có thể truy xuất stateattributes bằng cấu trúc mở rộng riêng của Home Assistant là states('entity_id')state_attr('entity_id','attributes_name'). Nên sử dụng cấu trúc này nếu được để tránh một số thông báo lỗi khi vì lí do nào đó, states của các entity_id này chưa có sẵn.

Như vậy:

Để lấy trạng thái của entity zone.home sử dụng Home Assistant template, ta có thể dùng states.zone.home.state hoặc states.zone.home['state'] hoặc states('zone.home') (khuyên dùng).

Để lấy dữ liệu icon nằm trong thuộc tính attributes của entity zone.home ta có thể sử dụng states.zone.home.attributes.icon hoặc states.zone.home.attributes['icon'] hoặc state_attr('zone.home','icon') (khuyên dùng).

! Lưu ý về dấu ‘.

Dấu . không chỉ dùng để truy xuất các thuộc tính, nó còn được sử dụng để gọi một phương thức – method của một đối tượng. Bạn cần ghi nhớ điều này để tránh nhầm lẫn.

Làm sao Hass phân biệt được giữa câu từ thông thường và template?

Bằng cả 2 yếu tố:

  1. Trong hầu hết trường hợp, bạn phải báo trước cho Home Assistant rằng từ thời điểm này, cần sử dụng Templating bằng cách sử dụng từ khoá data_template: hoặc value_template: (tuỳ vào tình huống sử dụng) thay vì data: hoặc value: như bình thường. (cập nhật: từ Home Assistant 0.115, riêng với data:service: templating sẽ được chấp nhận tự động, tức bạn không cần khai báo thêm _template đằng sau nữa)
  2. Đặt các dấu định nghĩa – delimiters khi muốn Home Assistant thực hiện template. Bao gồm:
    {{ ... }} khi muốn hiển thị giá trị của biểu thức bên trong. Bạn dùng cấu trúc states(‘zone.home’) để lấy giá trị state của entity zone.home rồi đặt nó bên trong như {{ states('zone.home') }} để hiển thị.
    {% ... %} khi muốn thực hiện một câu lệnh, có thể là các cấu trúc điều khiển như if hay for.

Kết hợp 2 điều trên, ta có ví dụ Template kiểu như sau cho ra giá trị ở nhà nếu entity person.me có trạng thái home và vắng nhà từ lúc <thời điểm> khi person.me có bất cứ trạng thái nào mà không phải là home (có thể là away, not_home hay tên một zone nào đó).
<thời điểm> vắng nhà được lấy từ mốc thời gian cuối cùng sensor này chuyển trạng thái. Đây chỉ là ví dụ mẫu nên ta không xử lý tất cả các trường hợp có thể xảy ra mà chỉ lấy tương đối.

value_template: > #dấu '>' để báo hiệu rằng bạn sẽ thể hiện template trên nhiều dòng
  {% if states('person.me') == 'home' %}
    ở nhà
  {% else %}
    vắng nhà từ lúc {{ states.person.me.last_changed }}
  {% endif %}
! Lưu ý

Trong gần như tất cả các trường hợp, kết quả trả về bởi templating trong Home Assistant sẽ ở dạng chuỗi kí tự – String, bất kể bạn nhìn thấy nó là số, từ điển, danh sách, mảng, hay unknown (không biết), undefined (không xác định) v.v…
Chuỗi kí tự ‘123’ có thể trông chẳng khác gì với số 123 nhưng trong ngôn ngữ máy tính, nó rất khác biệt, như là a và A vậy.

Cập nhật: từ Home Assistant 0.117, công cụ Template đã hỗ trợ các kiểu dữ liệu có sẵn của ngôn ngữ Python như số nguyên, số thập phân, từ điển, danh sách v.v… chứ không còn luôn xuất ra chuỗi kí tự nữa.

Trích dữ liệu đến dạng JSON trong Template

JSON là một dạng cấu trúc dữ liệu mở, đặc trưng bởi cụm key:value (khoá:dữ liệu). Json được dùng khá phổ biến trong Home Assistant và các dịch vụ bên thứ 3 có liên quan (như Tasmota, các Web API).

Nếu bạn có dữ liệu dạng: {"abc":123,"xyz":"789"} thì 99% nó là chính là dạng JSON. Bạn có thể kiểm tra một JSON có hợp lệ hay không và xem các key:value ở dạng đơn thuần bằng trang web này: https://jsonparseronline.com.

JSON từ mqtt payload thể hiện cấu hình của Zigbee2mqtt addon trong Hass

Với JSON trên ta có các key “version”, “commit” hay “coordinator”, “log_level” v.v…

Để trích xuất dữ liệu dạng này trong Home Assistant Template, ta sẽ dùng từ khoá value_json thay vì value. Ví dụ để hiển thị data của key “permit_join” ta sẽ dùng cấu trúc: {{ value_json.permit_join }}. Còn với key mà data lại là dạng JSON (JSON trong JSON) như key “coordinator”, ta sẽ dùng cấu trúc như sau {{ value_json.coordinator.meta.revision }} để lấy data của key “revision” bên trong data của key “meta” bên trong data của key “coordinator”.

Filter và Format

Nếu bạn có thể lấy thông tin của một entity bằng dấu . thì bạn có thể thay đổi thông tin này bằng các bộ lọc – filter hay bằng cách định dạng – format. Trong Home Assistant Template, để sử dụng các filter, ta đặt filter đằng sau kí tự | (pipe). Ở dưới ta sẽ tìm hiểu rõ hơn về filter.

Các cấu trúc, filter, format, method thông dụng trong Hass

Chung

  1. {{ states(‘entity_id’) }}
    – thể hiện (thường có nghĩa là in ra, đọc ra) ra trạng thái của entity.
  2. {{ state_attr(‘entity_id’,’xyz’ }}
    – thể hiện thuộc tính xyz của entity.
  3. {{ is_state(‘entity_id’,’123′) }}
    – thể hiện kết quả so sánh state của entity và giá trị ‘123’ (lần nữa bạn cần chú ý đây là chuỗi kí tự).
  4. {{ is_state_attr(‘entity_id’,’xyz’,’123′) }}
    – thể hiện kết quả so sánh thuộc tính ‘xyz’ với giá trị ‘123’.

Thời gian

  1. now()
    – trả về thời gian hiện tại theo múi giờ địa phương.
  2. now().hour, now().min, now().second
    – trả về giờ, phút, giây hiện tại.
  3. now().year, now().month, now().day
    trả về năm, tháng, ngày hiện tại.
  4. now().weekday()
    trả về ngày trong tuần (CN = 0).
  5. utcnow()
    – trả về thời gian theo múi giờ 0.
  6. utcnow().hour, utcnow().min v.v..
    – như mục 2, 3 và 4.
  7. as_timestamp(now())
    trả về số giây từ hiện tại lùi về thời điểm 00:00:00 01/01/1970 – Unix Timestamp hay Epoch time (1).
  8. as_timestamp(‘thời gian’)
    – như trên nhưng có thể dùng với bất cứ thời gian nào theo chuẩn ISO 8601.
  9. now().strftime(‘%a %A %b %B %d %H %I %m %M %y %Y %j %p %S %U %w %W %z %Z’)
    – cần ít nhất một trong các tham số bên trong cặp dấu ‘ ‘, thể hiện một thông số theo thời gian hiện tại (2)
    Xem danh sách giải thích ở dưới.
  10. ‘thời gian’.strftime()
    như trên, cho bất cứ thời gian nào theo chuẩn ISO 8601.
  11. strptime(‘thời gian’,’%a %A %b %B %d %H %I %m %M %y %Y %j %p %S %U %w %W %z %Z’)
    chuyển một chuỗi kí tự thành dạng dữ liệu thời gian, ví dụ chuỗi ‘Tuesday 12 May 2020’ được chuyển bởi strptime(‘Tuesday 12 May 2020′,’%A %d %b %Y’).
    Ý nghĩa các tham số giống hàm strftime().
%athứ rút gọn%Ynăm dạng đầy đủ
%Athứ đầy đủ%jngày trong năm
%btháng rút gọn%pAM/PM
%Btháng đầy đủ%Sgiây từ 0-61
%dngày dạng số%Utuần trong năm 0-53, CN là đầu tuần
%Hgiờ kiểu 24%wthứ dạng số
%Igiờ kiểu 12%Wtuần trong năm 0-53, T2 là đầu tuần
%mtháng dạng số%zsố giờ bù trừ của múi giờ
%Mphút%Ztên của múi giờ
%y2 số cuối của năm

Ví dụ sau sẽ in ra giờ, phútgiây hiện tại bằng cả 2 cách khác nhau, và cũng in ra số giây từ lúc entity sun.sun thay đổi lần cuối đến hiện tại:

Giờ: {{now().hour}} Phút: {{now().min}} Giây: {{now().second}}
Thời gian hiện tại: {{now().strftime('%H:%M:%S')}}
Lần cuối cảm biến thay đổi: {{as_timestamp(now()) - as_timestamp(states.sun.sun.last_changed)}} giây trước

Filter

  1. int, float
    chuyển sang dạng số nguyên, thập phân
  2. round(x)
    – làm tròn đến x số sau dấu thập phân
  3. random()
    – lấy ngẫu nhiên
  4. sum(), max(), min()
    – lấy tổng, số lớn nhất, số nhỏ nhất
  5. length()
    – số kí tự của chuỗi hay số phần tử của một danh sách
  6. upper(), lower(), capitalize()
    – viết hoa hết, thường hết hay chỉ viết hoa chữ cái đầu
  7. replace(‘abc’,’xyz’)
    – thay tất cả ‘abc’ bằng ‘xyz’ trong chuỗi kí tự
  8. split(‘ab.c.defgh’,’.’)[0]
    – chia một chuỗi kí tự thành các phần, phân cách bởi một kí tự (.) rồi lấy phần đầu tiên ([0])
  9. ‘abcdefgh'[3:5]
    – lấy các kí tự từ vị trí 3 đến vị trí 5 của một chuỗi kí tự

Lệnh – statement

  1. {% if <điều kiện 1> %}
    kết quả 1
    {% elif <điều kiện 2> %}
    kết quả 2
    {% else %}
    kết quả 3
    {% endif %}

    Nguyên tắc:
    – chỉ có duy nhất 1 if, 1 else và 1 endif
    – if và endif là bắt buộc
  1. {% set var1 = <giá trị> %} – tạo biến var1 có <giá trị> để dùng lặp lại nhiều lần trong cùng 1 template.
  2. {% for biến in <chuỗi> %} – lặp một vòng từ đầu đến cuối một chuỗi (danh sách)
    kết quả
    {% endfor %}

    Ví dụ, in ra thứ tự và entity_id của tất cả sensor hiện có:
{% for cambien in states.sensor %}
  {{loop.index}}: {{ cambien.entity_id }}
{% endfor %}

Như trên nhưng loại bỏ tất cả dấu xuống dòng cùng khoảng trắng thừa và khi kết thúc vòng lặp, in ra tổng số sensor hiện có:
Lưu ý kí tự ‘

{%- for cambien in states.sensor -%}
{{loop.index0}}: {{ cambien.entity_id }}
{% if loop.last %}Tổng số: {{loop.length}}{% endif %}
{%- endfor -%}
! Vẫn còn rất nhiều

Trên đây chỉ là danh sách hay dùng trong Hass, vẫn còn rất nhiều và chúng tôi sẽ cập nhật thêm. Bạn cũng có thể xem ở danh sách tham khảo dưới đây.

Về Bài viết

Bài viết chưa đầy đủ hoặc bạn còn có ý kiến khác? Bạn có thắc mắc và cần thêm thông tin. Vui lòng đăng ý kiến vào mục bình luận để tác giả và Team có thêm thông tin cải thiện chất lượng bài viết. Chúng tôi sẽ giải đáp các thắc mắc ngay trong mục bình luận để giúp được nhiều đọc giả với cùng vấn đề hơn hoặc chúng tôi sẽ trả lời trong một bài viết riêng. Trân trọng cảm ơn bạn!

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).