Home Assistant

Home Asistant: Hẹn giờ nhiều thiết bị với 1 script duy nhất

Smarthome hẹn giờ

Tạo vô số lịch hẹn với các thiết bị khác nhau, thao tác khác nhau một cách siêu đơn giản

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

Nhu cầu chuyển thiết bị về trạng thái nhất định (bật/tắt, mức sáng, màu sắc, nhiệt độ v.v..) vào một giờ nhất định và lặp đi lặp lại, trong smarthome, được giải quyết bởi Home AssistantHass rất đơn giản với công cụ automation.

Tuy nhiên, nếu bạn muốn sử dụng tính năng hẹn giờ tuỳ chỉnh dạng bật/tắt sau 30 phút từ hiện tại hoặc vào lúc 03:00 sáng hôm sau và chỉ thực hiện một lần duy nhất thì hiện Hass chưa có công cụ để làm việc này một cách thuận tiện.

Hass Bộ Hẹn Giờ Bật Tắt
Giao diện hẹn giờ trong bài viết trước đây

Nhu cầu trên đã từng được thực hiện một cách trực quan theo hướng dẫn trong bài biết Tạo thanh trượt hẹn giờ trong Hass (ảnh trên). Hôm nay, ta sẽ sử dụng những công cụ mới được giới thiệu gần đây để thực hiện cùng yêu cầu trên với một chút khác biệt, cụ thể như bên dưới.

Lưu ý: Hướng dẫn trong bài viết này chỉ áp dụng cho Home Assistant phiên bản 0.115 và mới hơn

Ưu và nhược điểm của phương pháp này

Ưu điểm

  • Đơn giản, rất dễ để thực hiện, đặc biệt là khi so với cách trước đây vốn sử dụng automation và bao gồm khá nhiều logic rắc rối
  • Chỉ cần rất ít thành phần và số lượng không phụ thuộc vào số các thiết bị cần hẹn giờ
  • Thao tác hẹn giờ linh hoạt

Nhược điểm

  • Kém trực quan hơn cách trước đây
  • Không thể biết được các lịch hẹn đã tạo (tên thiết bị, thời gian đã hẹn)
  • Không thể huỷ từng lịch cụ thể, chỉ có thể huỷ toàn bộ
  • Không tồn tại được khi Hass khởi động lại hoặc một vài component bị reload do lỗi hay chủ ý(1)

Giao diện hẹn giờ

Trong hướng dẫn này ta sẽ tạo ra 2 giao diện hẹn giờ đơn giản như ảnh dưới. Bạn có thể sử dụng cả 2 hoặc chọn cái phù hợp. Ngoài ra có thể tuỳ chỉnh để kết hợp tốt với thiết kế của riêng mình, tuỳ chỉnh giao diện không ảnh hưởng đến hoạt động thực tế.

Hass giao dien hen gio
2 giao diện hẹn giờ (trên và dưới)

Cấu hình các thành phần cần thiết

Bạn có thể tạo toàn bộ thành phần dưới đây như mẫu, không cần thiết thay đổi cấu hình (ngoại trừ các options của thành phần input_select(2)).

script chính

Ta sẽ dùng duy nhất một script – kịch bản để thực hiện hẹn giờ cho toàn bộ các lịch. Các tham số đầu vào của script này bao gồm:

  1. input_entity nhận entity_id của input_select chứa danh sách các thiết bị muốn hẹn giờ và bạn sẽ chọn trên danh sách này, ví dụ input_select.off_entity
  2. input_time nhận entity_id của input_datetime chứa giờ và phút mà ngay khi đến thời điểm đó, Hass sẽ thực hiện thao tác với thiết bị, ví dụ: input_datetime.on_off_timer
  3. service là dịch vụ bạn muốn thực hiện với thiết bị khi đến giờ hẹn, ví dụ: switch.turn_off

Cấu hình script mẫu

on_off_timer:
  alias: On Off timer
  description: Hẹn giờ bật tắt thiết bị
  mode: parallel
  max: 10
  icon: mdi:timer
  fields:
    input_entity:
      description: 'input_select.* chứa thiết bị cần tắt'
      example: 'input_select.off_entitiy'
    input_time:
      description: 'input_datetime.* chứa thời gian hẹn tắt'
      example: 'input_datetime.off_timer'
    service:
      description: 'dịch vụ được gọi khi đến giờ'
      example: 'homeassistant.turn_off'
  variables:
    entity_id: >
      {% if states(input_entity) == 'unknown' %}
        {{states(input_entity)}}
      {% else %}
        {%- set name = states(input_entity).strip() -%}
        {% for state in states if state.attributes.friendly_name == name -%}
          {{state.entity_id}},
        {% endfor -%}
      {% endif %}
    time: "{{states(input_time)[0:5]}}"
  sequence:
    - wait_template: "{{ states('sensor.time') == time }}"
      timeout: '24:00:00'
      continue_on_timeout: true
    - service: "{{service}}"
      data:
        entity_id: "{{ entity_id[:-1] }}"

Cách script hoạt động

Giải thích một số cấu hình quan trọng:

  • 4 mode: parallel được giới hiệu trong Home Assistant 0.113 cho phép nhiều phiên bản – instance của cùng một script chạy song song
  • 5 max: 10 hạn chế tối đa 10 phiên bản script (10 lịch) chạy cùng lúc
  • 7 fields: chứa các tham số đầu vào như giải thích ở trên
  • 17 variables: sau khi nhận tham số, ta tính toán lại các tham số này và gán vào các biến tương ứng, variables được giới thiệu trong Home Assistant 0.115
  • 29 wait_template chờ đến thời gian đã hẹn, tối đa 24g (24:00:00), sau 24g vẫn tiếp tục thực hiện hành động dù có đến giờ hay không

script này hoạt động bằng cách tạo ra các phiên bản của chính nó với mỗi lần được gọi. Các phiên bản này có cách hoạt động y hệt nhau nhưng với tham số đầu vào khác nhau do vậy có khả năng thực hiện thao tác riêng với các thiết bị vào những giờ hẹn trước riêng biệt.

Các thành phần hỗ trợ

Bạn cần thêm:

  • input_select với các lựa chọn là friendly_name hoặc entity_id của các thiết bị bạn muốn thao tác, có thể thuộc các domain switch, group, light, climate v.v..
    friendly_name nên được sử dụng để hiển thị giao diện đẹp và dễ hiểu hơn
    Các thiết bị này phải thao tác được với cùng một dịch vụ – service duy nhất, ví dụ homeassistant.turn_off
  • input_datetime để lựa chọn thời gian hẹn giờ
  • sensor.time hiển thị giờ địa phương để khớp với giờ hẹn

Bạn thêm các thành phần này vào cấu hình của Hass tại /config/configuration.yaml dưới mỗi mục tương ứng.

input_select để lựa chọn thiết bị(2)

Cấu hình mẫu của input_select này như bên dưới:

input_select:
  off_entity:
    name: Device to turn off by timer
    options:
      - Livingroom Light
      - Bedroom AC
      - Đèn bếp
      - fan.readingroom

Trong đó options chứa danh sách friendly_name hay entity_id của các thiết bị. Bạn cần thay đổi cho phù hợp, xem các thông tin này từ Công cụ nhà phát triển > TRẠNG THÁI.

Friendly name của thiết bị trong Hass
Attributes friendly_name của các entity trong Hass

input_datetime để chọn giờ

Cấu hình mẫu của input_datetime này như bên dưới:

input_datetime:
  on_off_timer:
    name: On Off Timer
    has_time: true

Ở đây ta chỉ sử dụng giờ, không dùng phần ngày tháng giúp đơn giản hoá quá trình thao tác của người sử dụng.

sensor.time để khớp giờ

sensor.time này có trạng thái như ảnh dưới:

Hass cảm biến thời gian
Cảm biến cần tạo có trạng thái như ảnh

Nếu bạn đã có sensor này rồi thì không cần tạo nữa, nếu chưa thì cần thêm cấu hình mẫu bên dưới:

sensor:
  - platform: time_date
    display_options:
      - 'time'

Khởi tạo tất cả thành phần cần thiết

Sau khi đã cấu hình 3 thành phần trên, bao gồm script.on_off_timer, input_select.off_entityinput_datetime.on_off_timer bạn khởi tạo tất cả các thành phần này mà không cần khởi động lại Home Assistant bằng cách Tải lại, vào mục Cấu hình > Điều khiển máy chủ > TẢI LẠI INPUT *TẢI LẠI KỊCH BẢN.

Tải lại input trong Hass
Tải lại các INPUT để khởi tạo

Riêng sensor.time, nếu tạo mới, bạn cần khởi động lại Hass (khi đó không cần thực hiện các bước TẢI LẠI như trên nữa).

Tạo giao diện điều khiển

Lúc này khi đã có đủ các entity bao gồm: script.on_off_timer, input_datetime.on_off_timer, input_select.off_entity & sensor.time, bạn chỉ cần đơn giản đưa chúng ra giao diện theo cách thuận tiện nhất để điều khiển và đẹp nhất để thể hiện.

Ở đây ta sẽ thử tạo 2 giao diện điều khiển đơn giản, dễ dàng nhất cho giao diện trên điện thoại thông minh. Sau khi có ý tưởng về việc thao tác, bạn nên chủ động tinh chỉnh hoặc tinh gọn cho tiện dùng và phù hợp với thẩm mỹ của mình.

HOAN NGHÊNH bạn chia sẻ cách mình thực hiện với chúng tôi và cộng đồng qua mục BÌNH LUẬN hoặc các kênh khác.

! Về custom componentcustom card

Là các component hay Lovelace card/module được phát triển bởi cộng đồng nhưng không/chưa được thông qua chính thức bởi nhóm phát triển Home Assistant. Việc cập nhật hay hỗ trợ hoàn toàn phụ thuộc vào tác giả và cộng đồng người dùng.
Bạn cũng sẽ phải tự chịu trách nhiệm và tự quản lý các custom component/custom card này.

Chúng tôi khuyến nghị bạn chỉ cài đặt những component hay card thực sự cần thiết để tránh lỗi, giảm nguy cơ bảo mật và đảm bảo hiệu suất máy chủ Hass. Trên một số thiết bị hay trình duyệt, các custom card có thể gây lỗi hoặc làm chậm đáng kể hiệu suất tải giao diện.
Hãy thận trọng khi cài đặt một custom mới trên máy chủ Hass chính của bạn vì có thể gây ra lỗi nghiêm trọng làm gián đoạn hoạt động bình thường của máy chủ và các thiết bị khác.

Giao diện kiểu horizontal-stack

Giao diện tương đối thích hợp khi sử dụng trên màn hình nhỏ, sử dụng thao tác vuốt và trượt. Ít phải bấm và không cần phải nhập liệu.

Video: thao tác hẹn giờ với card này trên màn hình điện thoại

Các thành phần cần thiết

Giao diện này sử dụng cách sắp xếp các card thành hàng dọc và ngang (dạng bảng) để thể hiện các thành phần điều khiển lên giao diện Lovelace.

Các card – thẻ giao diện sẽ được sử dụng bao gồm:

  1. horizontal-stack, vertical-stack để sắp xếp các card
  2. button để gọi dịch vụ khởi động script và markdown để hiển thị số lịch đang kích hoạt
  3. custom:select-list-card để chọn thiết bị (https://github.com/mattieha/select-list-card)
  4. custom:time-picker-card để chọn thời gian (https://github.com/GeorgeSG/lovelace-time-picker-card)
  5. custom:card-mod để tinh chỉnh nền và viền của các card nhỏ bên trong, tạo cảm giác liền mạch hơn (https://github.com/thomasloven/lovelace-card-mod)

Tất cả các custom card này đều có thể được cài đặt và quản lý, cập nhật sử dụng HACS. Bạn cần cài đặt trước qua HACS hay thủ công theo các đường dẫn bên trên trước khi thực hiện tạo giao diện theo mẫu bên dưới.

Cấu hình của giao diện

Tất cả các card cần tạo được giữ bên trong một card horizontal-stack – card Xếp ngang lớn. Để sử dụng, bạn chọn chế độ Chỉnh sửa giao diện, tạo một card mới loại Manual rồi thay thế nội dung sẵn có bằng nội dung bên dưới. (lưu ý cần cài đặt các card custom như trên trước)

type: horizontal-stack
cards:
  - type: 'custom:select-list-card'
    title: Thiết bị
    icon: ''
    max_options: 1
    scroll_to_selected: true
    show_toggle: false
    truncate: false
    entity: input_select.off_entity
    style: |
      ha-card {
        height: 100%;
        background: none;
        box-shadow: none;
      }
  - type: 'custom:time-picker-card'
    entity: input_datetime.on_off_timer
    hour_mode: 24
    hour_step: 1
    minute_step: 5
    name: OFF Timer
    layout:
      name: header
      align_controls: center
      hour_mode: double
    link_values: true
    hide:
      name: true
    style: |
      ha-card {
        height: 100%;
        background: none;
        box-shadow: none;
      }
  - type: vertical-stack
    cards:
      - type: markdown
        content: 'Đang hẹn: {{state_attr(''script.on_off_timer'',''current'')}}'
        style: |
          ha-card {
            height: 100%;
            background: none;
            box-shadow: none;
          }
      - type: button
        name: Hẹn giờ Tắt
        icon: 'mdi:timer'
        show_icon: false
        tap_action:
          action: call-service
          service: script.turn_on
          confirmation:
            text: Xác nhận thêm lịch hẹn giờ?
          service_data:
            entity_id: script.on_off_timer
            variables:
              input_entity: input_select.off_entity
              input_time: input_datetime.on_off_timer
              service: homeassistant.turn_off
        style: |
          ha-card {
            height: 100%;
            background: red;
            box-shadow: none;
          }
      - type: button
        name: Huỷ
        icon: 'mdi:timer'
        show_icon: false
        tap_action:
          action: call-service
          service: script.turn_off
          confirmation:
            text: Bạn muốn huỷ toàn bộ lịch hẹn giờ?
          service_data:
            entity_id: script.on_off_timer
        style: |
          ha-card {
            height:red0%;
            background: none;
            box-shadow: none;
          }

Giải thích:

  • Tất cả mục style: | ... } được sử dụng để “làm trong” phần nền của card và làm mất hiệu ứng đổ bóng, có thể xoá bỏ toàn bộ nếu bạn không cần
  • Các dòng 58, 59, 60 cung cấp tham số đầu vào cho script như đã nói ở các bước đầu
  • 56 cung cấp tên script đã tạo, nếu bạn tạo nhiều script, có thể tuỳ chỉnh ở đây
  • 39 là card markdown để thể hiện các lịch đã tạo, lấy từ attributes current của entity script
  • Dòng 5354 dùng để xác nhận lại là bạn muốn hẹn giờ, xoá bỏ 2 dòng này để bỏ qua bước xác nhận
  • Dòng 21 quy định số phút tăng/giảm (5) mỗi lần ấn lên xuống, bạn có thể chọn số khác nếu muốn chọn với bước nhỏ hơn
  • Từ trên xuống dưới của mã YAML trên tương ứng với vị trí các card trên giao diện từ trái sang và trên xuống

Giao diện đơn giản “một dòng”

Giao diện này hiển thị gọn gàng trong một card duy nhất trên một “dòng” duy nhất. Nhược điểm chính là bạn phải bấm vào từng thành phần để chọn trước rồi mới thao tác với nó.

Hẹn giờ thiết bị trên Hass

Các thành phần cần thiết

Để tạo giao diện như trên, ta chỉ cần duy nhất một card: custom:multiple-entity-row. Bạn có thể cài card này từ HACS hoặc cài đặt thủ công, theo liên kết sau: https://github.com/benct/lovelace-multiple-entity-row.

Cấu hình của giao diện

Cấu hình mẫu như bên dưới, để sử dụng, bạn chọn chế độ Chỉnh sửa giao diện, tạo một card mới loại Manual rồi thay thế nội dung sẵn có bằng nội dung bên dưới. (lưu ý cần cài đặt card custom như trên trước)

entity: script.on_off_timer
name: Hẹn giờ tắt
icon: 'mdi:timer'
type: 'custom:multiple-entity-row'
entities:
  - entity: input_select.off_entity
    name: Thiết bị
  - entity: input_datetime.on_off_timer
    name: Giờ
  - icon: 'mdi:calendar-multiple-check'
    name: ''
    tap_action:
      action: call-service
      service: script.turn_on
      confirmation: true
      service_data:
        entity_id: script.on_off_timer
        variables:
          input_entity: input_select.off_entity
          input_time: input_datetime.on_off_timer
          service: homeassistant.turn_off
  - attribute: current

Giải thích:

  • Các dòng 19, 20, 21 cung cấp tham số đầu vào cho script như đã nói ở các bước đầu
  • Dòng 15 dùng để xác nhận lại là bạn muốn hẹn giờ, xoá bỏ dòng này để bỏ qua bước xác nhận

Lưu ý

  • Với cả 2 dạng giao diện trên, mục đích cuối cùng là gọi script với các thông số cần thiết
  • Nếu bạn muốn sử dụng dịch vụ khác, thay thế homeassistant.turn_off bằng tên dịch vụ đó nhưng phải phù hợp với các thiết bị được chọn, ví dụ: switch.turn_on
  • Bạn có thể lên nhiều lịch với cùng một thiết bị, sử dụng một hay nhiều service khác nhau, TẤT CẢ các lịch này sẽ được thực hiện tuần tự theo thứ tự thời gian (không phải thứ tự đặt lịch)
  • Bạn có thể tinh chỉnh các dịch vụ này bằng cách tạo nhiều card khác nhau hay thậm chí thêm input_select để chọn loại service ngay khi đặt lịch
  • Lưu ý không nên sắp xếp quá nhiều thiết bị hoặc quá nhiều service vào cùng một card, sẽ gây khó khăn hoặc bối rối khi thao tác
  • Cách này phù hợp nhất với các lịch sẽ diễn ra trong một khoảng thời gian tương đối từ hiện tại, hẹn giờ trong vài phút tới là không phù hợp
  • Bạn có thể huỷ toàn bộ (và phải huỷ toàn bộ) lịch đã tạo bằng dịch vụ script.turn_off áp dụng cho script đã dùng đặt (thậm chí có thể tạo một button để thực hiện việc này)
  • Bạn có thể không sử dụng giao diện và gọi script trực tiếp, khi đó cần sửa lại cấu hình các variables để nhận giá trị trực tiếp thay vì nhận state của các entity (vốn được sử dụng để hỗ trợ giao diện)
  • Cuối cùng: các lịch này không tồn tại được khi Hass khởi động lại hoặc thành phần scripts bị tải lại(1)

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