Trang chủ › Hướng dẫn sử dụng › Home Automation › Bảng điều khiển
Home Assistant · từng bước một

Dựng dashboard Home Assistant này trong khoảng một giờ

Mười bước, YAML của từng thẻ, và một view hoàn chỉnh để dán một lần là xong. Được dựng và chụp ảnh trên một chiếc Marantz CINEMA 30 thật. Đổi hai chuỗi là có ngay dashboard của riêng bạn.

Dashboard hoàn chỉnh: khu vực đang phát, âm lượng với các mức dB cài sẵn, lưới nguồn vào, chế độ surround, hiệu chỉnh phòng nghe, các Cảnh và biểu đồ âm lượng
Bạn sẽ dựng gì
Đang vội? Chuyển thẳng đến bước 10, tải về view hoàn chỉnh, đổi hai chuỗi rồi dán vào. Các bước ở giữa giải thích từng phần hoạt động ra sao để bạn tự chỉnh sửa.

Trước khi bắt đầu

Dashboard này được nuôi bởi hai nguồn, và sự khác biệt giữa chúng quan trọng ở mọi bước bên dưới.

Đến từCho bạn
Các tập lệnh đã đồng bộ của AVR MaestroMọi điều khiển. Nguồn vào, chế độ surround, Audyssey, Dirac, Smart Select, preset, độ sáng, eco, các Cảnh của bạn.
Thực thể media player của tích hợp Denon AVRTrạng thái trực tiếp. Nguồn điện, nguồn đang chọn, chế độ surround, âm lượng, tắt tiếng.
Bước 1

Cài bốn thẻ từ HACS

Cả bốn đều có trong kho HACS mặc định. Trong Home Assistant: HACS › Frontend › Explore & Download Repositories, tìm theo tên, bấm Download, rồi tải lại trình duyệt.

TìmDùng choNếu bỏ qua
MushroomMọi ô điều khiển và thanh trượt âm lượngDùng thẻ button thông thường. Vẫn chạy, nhưng trông vuông vức hơn.
button-cardTiêu đề từng khu vực kèm nhãn trực tiếpDùng thẻ markdown, hoặc tiêu đề thường.
card-modMàu sắc và trạng thái sáng của ô đang hoạt độngMọi thứ vẫn chạy. Chỉ là không có gì sáng lên.
apexcharts-cardCác biểu đồ lịch sửDùng thẻ history-graph có sẵn.
Không thẻ nào trong số này là bắt buộc để mọi thứ hoạt động. Mọi điều khiển bên dưới đều chạy được bằng thẻ nút gốc của Home Assistant trỏ đến cùng một tập lệnh. Các thẻ tùy chỉnh chỉ là lớp trang điểm, không phải đường ống.
Bước 2

Tìm hai ID thực thể của bạn

Mọi đoạn mã trên trang này dùng hai chỗ giữ chỗ. Chỉ cần tìm ID của bạn một lần, phần còn lại là sao chép và dán.

Phần giữa của mọi ID tập lệnh là địa chỉ MAC của receiver, gồm mười hai ký tự viết thường, giống nhau ở tất cả. Sao chép một lần. Mọi nơi trang này ghi MAC, hãy điền giá trị của bạn.

Bỏ qua những mục có ghi unavailable. Các bản cũ đặt tên tập lệnh theo tên receiver thay vì địa chỉ MAC. Nếu bạn đã đồng bộ từ thời đó, những mục cũ vẫn còn trong danh sách và đã không còn dùng được. Các mục còn sống là những mục đặt tên theo MAC.
Bước 3

Tạo view

  1. 1. Settings › Dashboards › Add Dashboard › New dashboard from scratch. Đặt tên tùy ý.
  2. 2. Mở nó, rồi bấm biểu tượng bút chì ở góc trên bên phải để chỉnh sửa.
  3. 3. Thêm một view và chọn bố cục Sections. Không chọn Masonry. Sections giúp giao diện tự sắp xếp lại gọn gàng trên điện thoại.
  4. 4. Trong cài đặt view, đặt Max columns là 3 và bật Dense section placement.

Từ đây trở đi, mỗi bước đều là: thêm một section rồi dán các thẻ vào đó. Để dán YAML, dùng menu ba chấm trên thẻ và chọn Edit in YAML, hoặc dùng menu ba chấm của dashboard để vào Raw configuration editor và dán toàn bộ một lần.

# The view's own settings, if you prefer to type them
type: sections
title: AVR Maestro
icon: mdi:audio-video
max_columns: 3
dense_section_placement: true
Bước 4

Thêm một điều khiển

Bắt đầu với thứ đơn giản nhất trên bảng để biết chắc các ID thực thể của bạn đúng trước khi dựng bất cứ thứ gì phức tạp. Thêm một section, thêm một thẻ, chọn Edit in YAML rồi dán:

type: button
name: Pure Direct
icon: mdi:speaker
tap_action:
  action: perform-action
  perform_action: script.turn_on
  target:
    entity_id: script.avr_maestro_MAC_mode_pure_direct

Home Assistant gốc. Không cần HACS.

Bấm vào nó. Nếu receiver thay đổi, ID của bạn đúng và mọi thứ bên dưới sẽ chạy. Nếu không có gì xảy ra, hãy quay lại bước 2.

Bước 5

Cho nó sáng lên khi đó là mục đang dùng

Đây là mẫu đáng học nhất, và mọi ô nguồn vào lẫn surround trên bảng đều là bản sao của nó. Thẻ gửi một tập lệnh, rồi tự tô màu dựa trên thực thể receiver, nhờ đó nguồn vào bạn đang dùng sẽ sáng còn các nguồn còn lại thì không.

Lưới nguồn vào với Nvidia Shield sáng màu cam và mười hai nguồn còn lại tối
Một ô sáng, mười hai ô tối
type: custom:mushroom-template-card
entity: script.avr_maestro_MAC_input_cd
icon: mdi:disc
primary: CD
icon_color: >-
  {{ 'orange' if (state_attr('media_player.your_receiver','source') or '')|lower
     == 'cd' else 'grey' }}
layout: vertical
fill_container: true
tap_action:
  action: perform-action
  perform_action: script.turn_on
  target:
    entity_id: script.avr_maestro_MAC_input_cd
card_mod:
  style: |
    ha-card {
      border-radius: 14px;
    {% if (state_attr('media_player.your_receiver','source') or '')|lower == 'cd' %}
      background: linear-gradient(160deg, rgba(226,86,10,0.34), rgba(15,15,17,0.88));
      border: 1px solid rgba(255,122,24,0.80);
    {% else %}
      background: rgba(15,15,17,0.72);
      border: 1px solid rgba(255,122,24,0.14);
    {% endif %}
    }

Mỗi nguồn vào chỉ cần đổi ba thứ: tập lệnh, biểu tượng và chuỗi dùng để so sánh.

Cần làm đúng hai điều, nếu không ô sẽ không bao giờ sáng:

Các chế độ surround dùng cùng một thẻ, với sound_mode thay cho source.

Bước 6

Cho mỗi section một tiêu đề trực tiếp

Một tiêu đề trơn là khoảng trống vô ích. Đặt giá trị trực tiếp bên dưới và “Sources” sẽ thành “Sources / Now on Nvidia Shield”.

type: custom:button-card
name: Sources
icon: mdi:video-input-hdmi
color_type: label-card
entity: media_player.your_receiver
show_label: true
label: >-
  [[[ var v = states["media_player.your_receiver"].attributes.source;
      return v ? ("Now on " + v) : "Receiver in standby"; ]]]
tap_action:
  action: none
styles:
  grid:
    - grid-template-areas: '"i n" "i l"'
    - grid-template-columns: min-content auto
  name:
    - font-size: 13px
    - letter-spacing: 3px
    - text-transform: uppercase
    - justify-self: start
  label:
    - font-size: 11px
    - justify-self: start

Lưới hai dòng là thứ đặt nhãn bên dưới tiêu đề thay vì bên cạnh.

Thay attributes.source bằng attributes.sound_mode ở tiêu đề Surround, và tương tự cho các mục khác.

Bước 7

Hiển thị âm lượng theo dB

Home Assistant báo âm lượng dưới dạng phân số. Chẳng ai chỉnh receiver về “0.67” cả. Một dòng phép tính sẽ giải quyết chuyện đó và cả khu vực này bắt đầu đọc như một chiếc receiver thực thụ.

Khu vực âm lượng: thanh trượt, tăng, giảm, tắt tiếng và bốn mức dB cài sẵn
Night, Dialog, Movie và Loud, mỗi mức ghi rõ số dB mà nó đặt
Công thức quy đổi. Home Assistant công bố volume_level bằng âm lượng master chia cho 100, và trên các receiver Denon và Marantz, MV 80 là mốc tham chiếu 0 dB. Vì vậy dB = volume_level × 100 − 80. Giá trị volume_level 0.67 tương ứng âm lượng master 67, tức là −13.0 dB.
# The readout
type: custom:mushroom-template-card
entity: media_player.your_receiver
icon: mdi:volume-high
primary: >-
  {% set v = state_attr('media_player.your_receiver','volume_level') %}
  {% if v is not none %}{{ (v * 100 - 80) | round(1) }} dB{% else %}Standby{% endif %}
secondary: Master volume
layout: vertical
# The slider. media_controls must be empty or the bar becomes a power button
type: custom:mushroom-media-player-card
entity: media_player.your_receiver
volume_controls:
  - volume_set
media_controls: []
show_volume_level: true
# A preset. 0.50 is master volume 50, which is -30 dB
type: custom:mushroom-template-card
entity: media_player.your_receiver
icon: mdi:weather-night
primary: Night
secondary: "-30 dB"
tap_action:
  action: perform-action
  perform_action: media_player.volume_set
  target:
    entity_id: media_player.your_receiver
  data:
    volume_level: 0.50
Hãy chọn mức preset lớn nhất của bạn một cách có chủ đích. Bộ trên dừng ở −10 dB. Bấm nhầm trên dashboard dễ hơn nhiều so với trên điều khiển từ xa, và mức tham chiếu trên một chiếc receiver lớn thực sự rất to.
Bước 8

Thêm các Cảnh của bạn

Đọc tên từ tập lệnh thay vì gõ tay, và khi bạn đổi tên một Cảnh trong AVR Maestro, ô tương ứng tự đổi tên mà không cần sửa dashboard.

Bốn ô Cảnh, mỗi ô liệt kê các cài đặt mà Cảnh đó khôi phục
Mỗi ô cho biết Cảnh của nó thực sự khôi phục những gì
type: custom:mushroom-template-card
entity: script.avr_maestro_MAC_scene_1234567890123
icon: mdi:theater
primary: >-
  {{ state_attr('script.avr_maestro_MAC_scene_1234567890123','friendly_name')
     | replace('AVR Maestro - ', '') | replace(' (Your Receiver)', '') }}
secondary: >-
  {% set t = states.script['avr_maestro_MAC_scene_1234567890123'].attributes.last_triggered %}
  {{ 'recalled ' ~ relative_time(t) ~ ' ago' if t else 'not run yet' }}
multiline_secondary: true
tap_action:
  action: perform-action
  perform_action: script.turn_on
  target:
    entity_id: script.avr_maestro_MAC_scene_1234567890123

Hai lệnh replace() cắt tiền tố và tên receiver ra khỏi tên thân thiện.

Một dòng thứ hai rất đáng bỏ thêm một phút. Một bức tường nút đặt tên bay bổng chẳng cho bạn biết gì lúc 11 giờ đêm; một dòng nói rõ mỗi nút khôi phục điều gì sẽ cho bạn biết nên bấm nút nào.

Bước 9

Thêm lịch sử

Thực thể media player của receiver được Home Assistant ghi lại như mọi thực thể khác, nên bạn có sẵn lịch sử nghe mà không tốn công. Mọi thứ bên dưới đều lấy từ một thực thể duy nhất: không cần thêm cảm biến, không cần helper, không phải cấu hình gì trước.

Năm biểu đồ lịch sử: nguồn điện và hoạt động, âm lượng master theo dB, âm lượng theo ngày, nguồn vào đang dùng và chế độ surround
Năm biểu đồ, một thực thể, bảy ngày

Dòng thời gian trạng thái đơn giản không cần thẻ tùy chỉnh nào, và là biểu đồ đáng có nhất:

type: history-graph
hours_to_show: 168
entities:
  - entity: media_player.your_receiver
    name: Receiver

Bật, tắt và nó đã làm gì, trong suốt một tuần.

Âm lượng theo dB dùng cùng công thức quy đổi như ở bước 7:

type: custom:apexcharts-card
graph_span: 7d
header:
  show: true
  title: Master volume, last 7 days
series:
  - entity: media_player.your_receiver
    attribute: volume_level
    name: Master volume
    type: line
    curve: smooth
    unit: dB
    float_precision: 1
    transform: "return x == null ? null : Number(x) * 100 - 80;"
    extend_to: now
    group_by:
      duration: 1h
      func: last
      fill: last
apex_config:
  chart:
    height: 240
  yaxis:
    min: -60
    max: 0

group_by với fill: last biến các sự kiện thưa thớt thành một đường liền mạch. Trục y phải được đặt trong apex_config thì mới có hiệu lực.

Trung bình và đỉnh theo ngày biến một đường gấp khúc thành thứ có hình dạng rõ ràng:

type: custom:apexcharts-card
graph_span: 7d
span:
  end: day
header:
  show: true
  title: Master volume by day in dB, average and peak
series:
  - entity: media_player.your_receiver
    attribute: volume_level
    name: Day average
    type: column
    float_precision: 1
    transform: "return x == null ? null : Number(x) * 100;"
    group_by: {duration: 1d, func: avg, fill: 'null'}
  - entity: media_player.your_receiver
    attribute: volume_level
    name: Day peak
    type: line
    curve: smooth
    float_precision: 1
    transform: "return x == null ? null : Number(x) * 100;"
    group_by: {duration: 1d, func: max, fill: 'null'}
apex_config:
  yaxis:
    min: 0
    max: 80
    labels:
      formatter: "EVAL:function (v) { return (v - 80).toFixed(0); }"
  tooltip:
    y:
      formatter: "EVAL:function (v) { return v == null ? '' : (v - 80).toFixed(1) + ' dB'; }"

Hai chuỗi từ cùng một thuộc tính, nhóm theo ngày.

Vì sao biểu đồ này vẽ từ 0 đến 80 và định dạng thành dB, thay vì vẽ trực tiếp dB. Các cột mọc lên từ đáy trục. Vẽ thẳng dB thì mọi cột đều treo xuống từ 0, nên cột dài nghĩa là yên tĩnh, đọc ngược hẳn. Hãy vẽ giá trị âm lượng master thô rồi trừ 80 trong bộ định dạng của trục và tooltip, khi đó các cột mọc lên trên còn mọi thứ người xem thấy vẫn là dB. fill: 'null' nghĩa là ngày không có số liệu sẽ không có cột, thay vì kéo giá trị của hôm qua sang.

Và hai biểu đồ trả lời câu hỏi “thực ra tôi xem bằng nguồn nào, ở chế độ nào”: nguồn vào và chế độ surround, vẽ thành dòng thời gian cho biết mục nào đã được chọn.

type: custom:apexcharts-card
graph_span: 7d
span:
  end: day
header:
  show: true
  title: Source in use, last 7 days
series:
  - entity: media_player.your_receiver
    attribute: source
    name: Source
    type: line
    curve: stepline
    stroke_width: 3
    extend_to: now
    float_precision: 0
    transform: |
      if (x == null) return null;
      var m = ["Phono", "NET", "Xbox", "Nvidia Shield"];
      var i = m.indexOf(x);
      return i < 0 ? 0 : i + 1;
apex_config:
  yaxis:
    min: 0
    max: 4
    tickAmount: 4
    labels:
      formatter: >-
        EVAL:function (v) { return ["Other", "Phono", "HEOS Net", "Xbox",
        "Shield"][Math.round(v)] || ''; }
  tooltip:
    y:
      formatter: >-
        EVAL:function (v) { return v == null ? 'off' : ["Other", "Phono",
        "HEOS Net", "Xbox", "Shield"][Math.round(v)] || 'Other'; }

Hãy đặt các nguồn vào của riêng bạn trong mảng transform và trong cả hai mảng formatter. Giữ chỉ số 0 là “Other”.

Trục biểu đồ cần số, nên transform ánh xạ mỗi tên nguồn vào một vị trí và các formatter ánh xạ ngược lại để hiển thị nhãn và tooltip. Hãy làm cho ánh xạ này đầy đủ: null (receiver tắt) vẫn là một khoảng trống, và bất cứ thứ gì không có trong danh sách của bạn sẽ rơi vào “Other”, nên hai trường hợp không bao giờ bị nhầm lẫn. Cùng thẻ đó với sound_mode cho bạn chế độ surround, với các chuỗi viết hoa đúng như receiver của bạn báo về.

Giữ stepline cho hai biểu đồ cuối. Nguồn vào hay chế độ surround là một hạng mục, không phải một con số. Làm mượt đường cong thì đường sẽ lượn từ Shield sang Xbox qua bất cứ thứ gì nằm giữa chúng trên trục, vẽ ra một nguồn vào chưa từng được chọn. Âm lượng là đại lượng thực nên làm mượt vẫn trung thực; còn hạng mục thì không.
Hãy kiểm tra thời gian lưu giữ của recorder trước. Home Assistant mặc định giữ mười ngày, nên bảy ngày là mức hợp lý nhất bạn có thể yêu cầu. Muốn xem xa hơn, bạn cần một cảm biến mẫu state_class: measurement, mà Home Assistant lưu thành thống kê dài hạn trong nhiều năm.
Thiếu một ngày thường là đúng. Home Assistant ghi lại các thay đổi, không phải các mẫu đo. Để receiver ở một nguồn vào, một mức âm lượng suốt hai ngày thì nó không ghi gì cả, nên ngày đó không có cột. Trông như mất dữ liệu nhưng thực ra ngược lại: không có gì xảy ra.
Bước 10

Hoặc lấy trọn bộ

View hoàn chỉnh, mọi section và mọi thẻ, với chỗ giữ chỗ thay cho ID thực thể.

  1. 1. Tải về YAML của giao diện.
  2. 2. Mở nó bằng bất kỳ trình soạn thảo văn bản nào và thay hai chuỗi ở mọi nơi chúng xuất hiện: YOUR_RECEIVER bằng tên thực thể media player của bạn, và YOURMAC bằng mười hai ký tự của receiver bạn lấy ở bước 2.
  3. 3. Trong Home Assistant, mở dashboard của bạn, bấm biểu tượng bút chì, menu ba chấm, Raw configuration editor, rồi dán vào dưới dạng một view.
ID các Cảnh của bạn sẽ không khớp. Tập lệnh Cảnh được đặt tên theo thời điểm Cảnh được tạo, nên bốn Cảnh trong tệp không tồn tại trên hệ thống của bạn: các thẻ đó vẫn hiển thị nhưng không làm gì. Hãy thay ID thực thể của chúng bằng ID của bạn ở bước 2, hoặc xóa section Cảnh và dựng lại theo bước 8.
Còn hai điều nữa cần lưu ý. Biểu đồ nguồn vào và surround mang tên nguồn từ receiver dùng để dựng bản này, nên hãy sửa các mảng đó như bước 9 mô tả. Và nhãn của các ô là tiếng Anh; không có gì trong tệp được dịch.

Nếu một ô không bao giờ sáng

Trước khi cho rằng bạn dựng sai: một số ô không thể sáng lên, và nên biết đó là những ô nào.

Một ô chỉ hiển thị được trạng thái nếu Home Assistant đọc được nó, và Home Assistant đọc receiver của bạn từ hai nơi. Tích hợp Denon AVR công bố những thông tin cơ bản trên thực thể media player. AVR Maestro công bố phần còn lại: nó tạo một cảm biến Status Bridge, sensor.avr_maestro_your_receiver, và ghi các số đọc mà nó đang có vào đó dưới dạng thuộc tính.

Trên thực thể media playerTrên cảm biến Status Bridge
Nguồn điệnĐường cong Audyssey MultEQ
Nguồn vào đang chọnDynamic Volume và mức tham chiếu
Chế độ surroundSlot Dirac nào đang được nạp
Âm lượng và tắt tiếngĐộ sáng bảng mặt trước, chế độ Eco
Dynamic EQ, đôi khiSpeaker preset, âm sắc và hàng chục thứ khác

Giờ cả hai cột đều đọc được. Lấy giá trị media player từ states['media_player.your_receiver'].attributes, và giá trị Status Bridge bằng state_attr('sensor.avr_maestro_your_receiver','dirac_slot'), để ô sáng lên theo cài đặt đang thực sự hoạt động thay vì chỉ kích hoạt tập lệnh thay đổi nó.

Đo trên chiếc receiver dùng để dựng bản này: thực thể media player có khoảng hai mươi trong số sáu mươi điều khiển, và cảm biến Status Bridge công bố thêm khoảng bốn mươi điều khiển nữa. Gộp lại, một dashboard có thể đọc gần như mọi thứ nó có thể thay đổi - khác biệt giữa một bức tường nút bấm và một bề mặt điều khiển thực thụ.

Nếu một giá trị có thể mang hai nghĩa, hãy nói rõ. Dynamic EQ trả về true, false, hoặc không trả về gì cả. Coi “không có gì” là “tắt” sẽ đặt một câu trả lời sai mà đầy tự tin lên bức tường của bạn.
icon_color: >-
  {% set d = state_attr('media_player.your_receiver','dynamic_eq') %}
  {{ 'orange' if d is true else 'grey' }}
secondary: >-
  {% set d = state_attr('media_player.your_receiver','dynamic_eq') %}
  {% if d is none %}state not published{% elif d %}on{% else %}off{% endif %}

Ba trạng thái, không phải hai.

Một số điều khác đáng biết

Cùng dashboard đó ở chiều rộng điện thoại, sắp xếp lại thành một cột
Cùng dashboard ở chiều rộng điện thoại: ba cột thành một, và không phải cấu hình gì để điều đó xảy ra
Câu hỏi thường gặp

Giải đáp về dashboard

Tôi có cần thẻ tùy chỉnh từ HACS để dựng cái này không?
Không cần để nó hoạt động. Mọi nút điều khiển trên trang này đều chạy từ thẻ nút thuần của Home Assistant. Mushroom, button-card, card-mod và apexcharts-card là những thứ giúp nó trông như trong ảnh chụp màn hình, và mỗi phần bên dưới đều cho biết nó dùng thẻ nào và bạn mất gì nếu không có.
Vì sao một số nút sáng lên còn số khác thì không?
Một nút sáng lên khi Home Assistant đọc được trạng thái tương ứng từ receiver của bạn. Nguồn vào, chế độ surround, âm lượng và tắt tiếng được trả về từ thực thể media player của chính receiver, nên các mục đó được làm nổi bật. Đường cong Audyssey, slot Dirac, độ sáng, chế độ eco và speaker preset không được tích hợp Denon công bố, nên Home Assistant không có cách nào biết mục nào đang hoạt động và các nút sẽ không sáng cho đến khi bạn bấm một nút.
Tôi có thể hiển thị âm lượng dB thực thay vì phần trăm không?
Có. Home Assistant công bố volume_level bằng âm lượng master của receiver chia cho 100, và trên các receiver Denon và Marantz, MV 80 là mốc tham chiếu 0 dB. Vì vậy dB bằng volume_level nhân 100, trừ 80. Giá trị volume_level 0.67 tương ứng âm lượng master 67, tức là -13.0 dB.
ID thực thể của tôi có giống với các ID trong hướng dẫn này không?
Phần đầu và phần cuối thì giống, phần giữa thì không. AVR Maestro đặt tên các tập lệnh theo địa chỉ MAC của receiver để khi đổi tên, tập lệnh cũ được cập nhật thay vì bị tách thành bản sao. Tên của bạn sẽ có dạng script.avr_maestro_ rồi đến mười hai ký tự riêng của bạn, sau đó là tên điều khiển. Hãy mở Developer Tools rồi States trong Home Assistant và lọc theo avr_maestro để xem danh sách của bạn.
Xem thêm trong hướng dẫn

Các hướng dẫn khác về AVR Maestro

Bắt đầu · Màn hình chính · Cảnh · Biểu tượng tùy chỉnh · Âm thanh · Graphic EQ · Loa · Vì sao một điều khiển bị khóa · Trợ lý · Home Automation · Vùng · Điều khiển từ xa · Radio (FM/AM) · Hiển thị trên màn hình · Cài đặt · Ngôn ngữ · Điều khiển âm lượng · Sao lưu & Khôi phục · Đang phát & HEOS

Toàn bộ receiver của bạn, trên một bức tường

Home Automation là tính năng trả phí duy nhất trong AVR Maestro. Mọi thứ khác, kể cả trợ lý AI chạy trên thiết bị, đều được bao gồm.

Tải trên Google Play Tải trên App Store Tải trên Mac App Store Tải trên Microsoft Store

Quay lại Home Automation → · Toàn bộ Hướng dẫn sử dụng →