Image default
Máy Tính

Biến ESP32 CYD thành Dashboard Giám Sát PC: Hướng Dẫn Tích Hợp ESPHome và LVGL

Gần đây, tôi đã trải nghiệm một thiết bị hiển thị nhỏ gọn nhưng mạnh mẽ: Cheap Yellow Display (CYD) sử dụng chip ESP32. Với mức giá chỉ khoảng 20 USD, bạn sở hữu một màn hình tích hợp ESP32, khe cắm thẻ SD và một số chân GPIO để mở rộng các tính năng. Mặc dù ESPHome đã cung cấp một số công cụ khá tốt để xây dựng giao diện người dùng, nhưng vài tháng trước, thư viện đồ họa Light and Versatile Graphics Library (LVGL) đã được hỗ trợ. LVGL là một thư viện đồ họa phong phú với các widget dựng sẵn, mang lại giao diện đẹp mắt và chuyên nghiệp hơn rất nhiều so với những gì tôi có thể tạo ra bằng ESPHome thông thường.

Với niềm đam mê tự động hóa và mong muốn kiểm soát tốt hơn môi trường làm việc, tôi đã bắt tay vào xây dựng một dashboard điều khiển nhà thông minh tại chỗ bằng LVGL. Ban đầu, nó chỉ đơn thuần là công cụ để điều khiển đèn và phát nhạc trong nhà. Tuy nhiên, khi thiết bị này luôn nằm trên bàn làm việc, ngay cạnh PC của tôi, ý tưởng biến nó thành một dashboard giám sát PC dần hình thành và trở nên hợp lý. Giờ đây, tôi có thể dễ dàng theo dõi thời gian khởi động cuối cùng, cửa sổ đang hoạt động, mức sử dụng RAM và CPU của máy tính, tất cả chỉ trên một màn hình nhỏ gọn này. Đây không chỉ là một tiện ích thông thường mà còn là minh chứng cho khả năng vô hạn của việc kết hợp các công nghệ thông minh.

Tất nhiên, việc hiển thị cửa sổ đang hoạt động có thể không quá hữu ích khi máy tính của tôi “ngay trước mặt”. Tuy nhiên, đây chỉ là một phần của minh chứng khái niệm, cho thấy loại dữ liệu mà bạn có thể trích xuất. Có thể trong bối cảnh sử dụng của riêng bạn, việc hiển thị cửa sổ đang hoạt động trên một dashboard sẽ có ý nghĩa. Hơn nữa, nó yêu cầu một cách hiển thị dữ liệu hơi khác so với các cảm biến khác, do đó đây cũng là một cách để minh họa phương pháp hiển thị văn bản đa dạng trên màn hình ESP32 CYD.

Để hiện thực hóa ý tưởng này, tôi sử dụng HASS.Agent trên Windows để gửi dữ liệu đến máy chủ MQTT, cùng với ESPHome dưới dạng một tiện ích bổ sung (add-on) trong Home Assistant. Khi kết hợp lại, dữ liệu sẽ di chuyển từ máy tính của tôi đến máy chủ MQTT, sau đó đến Home Assistant và cuối cùng là đến màn hình CYD. Đây thực sự là một giải pháp ấn tượng và khả năng mở rộng dường như là vô tận khi kết hợp Home Assistant và ESPHome.

Bên trong hộp Home Assistant Voice PE, minh họa thiết bị điều khiển giọng nóiBên trong hộp Home Assistant Voice PE, minh họa thiết bị điều khiển giọng nói

Sức Mạnh Tổng Hợp: ESPHome, LVGL và Dữ Liệu PC Qua MQTT

Để triển khai dashboard giám sát PC này, chúng ta sẽ giả định bạn đã cài đặt HASS.Agent, kết nối với một MQTT broker, và bạn đã cài đặt ESPHome dưới dạng add-on cho Home Assistant. Nếu bạn đang sử dụng Home Assistant Container (thay vì HAOS), bạn có thể cài đặt ESPHome như một container riêng biệt, sau đó cài đặt tích hợp ESPHome trong Home Assistant để liên kết mọi thứ lại với nhau.

Nền tảng của dự án này dựa trên dự án ESPHome LVGL của Ryan Ewen trên GitHub. Dự án này đã chứng minh giá trị to lớn trong việc giúp tôi tìm hiểu LVGL và hỗ trợ đáng kể trong suốt quá trình phát triển dashboard. Tôi đã kết hợp thành công các điều khiển ánh sáng và điều khiển media, và bước tiếp theo là lấy dữ liệu từ Home Assistant để hiển thị trong các “thẻ” (card) như hình minh họa. Các thông số này được hiển thị trên một trang riêng biệt, và tôi có thể sử dụng các phím mũi tên ở phía dưới để chuyển đổi giữa các trang.

Để đọc thời gian khởi động cuối cùng, trước tiên tôi tạo một text_sensor trong ESPHome để đọc cảm biến “lastboot” từ thực thể MQTT của tôi. Đoạn mã sẽ trông như sau, hãy đảm bảo bạn sử dụng đúng cách thụt lề:

- platform: homeassistant
  id: pc_last_boot_raw
  entity_id: sensor.desktop_73d9nef_lastboot
  internal: true
  on_value:
    then:
      - lvgl.widget.refresh: pc_last_boot_raw_on

Đoạn mã này khá dễ hiểu, ngoại trừ phần “lvgl.widget.refresh”. Việc này được thực hiện vì màn hình sẽ vẽ các phần tử trước khi chúng được cung cấp giá trị thực tế. Điều này giúp thiết bị khởi động và hiển thị màn hình chính nhanh hơn so với việc kết nối vào mạng. Phần “lvgl.widget.refresh” đảm bảo rằng nó sẽ làm mới widget “pc_last_boot_raw_on”, mà tôi sẽ giải thích tiếp theo.

Giải Mã Các Đoạn Mã ESPHome: Bắt Đầu Với Thời Gian Khởi Động

Trong cấu hình ESPHome, sau khi định nghĩa text_sensor để lấy dữ liệu thô, chúng ta cần một widget để hiển thị nó. Đây là lúc LVGL và các lambda trong ESPHome phát huy tác dụng:

widgets:
  - button:
      width: 232
      height: 75
      widgets:
        - label:
            id: pc_last_boot_raw_on
            text: !lambda |-
              if (id(pc_last_boot_raw).state.length() < 19)
                return std::string("");

              std::string ts = id(pc_last_boot_raw).state;
              std::string date = ts.substr(0, 10);
              std::string time = ts.substr(11, 8);

              return date + "n" + time;
            text_font: roboto_md
            align: CENTER
        - label:
            id: pc_last_boot_raw_off
            text: "PC off"
            text_font: roboto_md
            align: BOTTOM_LEFT
            hidden: true

Đoạn mã trên có thể hơi phức tạp, vì vậy tôi sẽ giải thích cách nó hoạt động từ đầu đến cuối. widthheight được lấy từ các widget nút 320×240 của Ewen, vì chúng đã được tính toán để phù hợp với một “nút rộng” trên màn hình này, cho phép ba hàng nút. Tiếp theo, chúng ta tạo một widget lồng nhau chứa hai nhãn riêng biệt: pc_last_boot_raw_onpc_last_boot_raw_off. Tôi chưa tích hợp đúng logic cho nhãn thứ hai (và hidden: true ẩn nó khỏi màn hình), nhưng tôi sẽ giải thích chức năng của nó sau khi giải thích pc_last_boot_raw_on.

Trong pc_last_boot_raw_on, chúng ta sử dụng !lambda để xử lý văn bản từ text_sensor. Mặc dù các cấu hình ESPHome được viết bằng YAML, nhưng lambda báo cho ESPHome biết rằng khối văn bản tiếp theo là mã C++. Đây cũng là lý do tại sao chúng ta sử dụng |-, nó yêu cầu ESPHome xử lý khối thụt lề tiếp theo dưới dạng văn bản thuần túy. lambda rất mạnh mẽ trong ESPHome, vì bạn có thể cấu hình mọi thứ bạn muốn bằng cú pháp YAML, sau đó chèn mã C++ bên trong các khối cụ thể để tùy chỉnh hành vi hoặc thay đổi động các phần tử.

Màn hình ESP32 CYD hiển thị dashboard giám sát PC với các thông số RAM, CPU và cửa sổ hoạt độngMàn hình ESP32 CYD hiển thị dashboard giám sát PC với các thông số RAM, CPU và cửa sổ hoạt động

lambda này kiểm tra xem độ dài của khối có ngắn hơn 19 ký tự hay không. Đây là một cách làm hơi “hacky” và có thể được tối ưu tốt hơn, nhưng HASS.Agent báo cáo thời gian khởi động ở định dạng 2025-06-20T10:12:29, tức là 19 ký tự. Về cơ bản, chúng ta đang kiểm tra phản hồi để đảm bảo rằng nó khớp với độ dài của kết quả mong đợi. Tốt hơn là nên thay đổi trạng thái bên ngoài khối và phản ứng phù hợp, nhưng cách này vẫn hoạt động và đặt khối thành “” nếu chúng ta nhận được giá trị không mong muốn, giữ cho nó trống.

Tuy nhiên, nếu kiểm tra vượt qua, chúng ta sao chép giá trị của text_sensor (trạng thái “state”) vào một chuỗi tạm thời nội bộ, gọi là ts. Trong C++ (và trong C), một chuỗi là một mảng ký tự động, vì vậy chúng ta có thể sao chép các phần tử mảng sang một chuỗi khác (bằng cách tạo một chuỗi con – substring) để tạo lại các phần mà chúng ta muốn giữ. Chúng ta cũng biết, vì chuỗi sẽ luôn có độ dài tiêu chuẩn, vị trí của các ký tự mà chúng ta muốn trong mọi trường hợp. Chúng ta sử dụng phương thức substr để tạo một chuỗi con, yêu cầu nó bắt đầu từ vị trí 0 và thu thập 10 ký tự tiếp theo để lưu vào chuỗi date của chúng ta. Chúng ta làm tương tự để lấy thời gian, yêu cầu substr bắt đầu từ vị trí 11 (bỏ qua ký tự “T” trong chuỗi) và thu thập 8 ký tự tiếp theo để lưu vào chuỗi time của chúng ta.

Cuối cùng, chúng ta trả về:

date + "n" + time

"n" là ký tự xuống dòng, và chúng ta phân tách datetime mà không có dấu ngoặc kép vì các biến đó đã đại diện cho chuỗi. Dấu ngoặc kép biểu thị một chuỗi mà bạn đang nhập vào mã, vì vậy đoạn mã trên về cơ bản có nghĩa là “lấy biến từ date, thêm một ký tự xuống dòng vào đó, sau đó thêm biến từ time vào chuỗi tổng thể.”

Vì tất cả những điều này nằm bên trong khối “text”, ESPHome về cơ bản tạo nút với thông tin nói rằng, “tạo nút này, đặt giá trị ‘text’ mà nút yêu cầu thành đầu ra của bất kỳ mã nào thực hiện.” Bằng cách này, chúng ta có thể hiển thị văn bản một cách linh hoạt, thay vì phải đặt các giá trị tĩnh hoặc cố gắng đặt các giá trị động từ bên ngoài nơi chúng được tạo ban đầu.

Còn về lvgl.widget.refresh: pc_last_boot_raw_on thì sao? Chúng ta đã gắn nhãn nút là “pc_last_boot_raw_on”, vì vậy chúng ta về cơ bản vẽ lại nút nếu một giá trị mới được nhận. Điều này cho phép nó cập nhật sau khi khởi động và hoạt động tốt với các cảm biến khác mà chúng ta sẽ nói đến tiếp theo.

Màn hình hiển thị ESP32 CYD cận cảnh với thông tin thời gian khởi động PC được định dạng lạiMàn hình hiển thị ESP32 CYD cận cảnh với thông tin thời gian khởi động PC được định dạng lại

Cảm biến ngày và giờ khởi động là cảm biến phức tạp nhất trong số tất cả chúng, vì vậy nếu bạn đã theo dõi, mọi thứ sẽ trở nên dễ dàng hơn rất nhiều từ đây.

Cấu Hình Dữ Liệu RAM, CPU và Cửa Sổ Hoạt Động (Đơn Giản Hơn)

Chúng ta định nghĩa các text_sensor trong ESPHome để kéo dữ liệu từ Home Assistant theo cùng một cách chúng ta đã làm để lấy ngày và giờ khởi động. Vì vậy, bạn chỉ cần sửa đổi text_sensor đó để tìm nạp các biến khác mà bạn cần. Khi bạn đã tạo một text_sensor cho RAM, CPU và cửa sổ đang hoạt động (tham chiếu đến các thực thể chính xác), chúng ta có thể chuyển sang tạo các nút của mình.

- button:
    width: 114
    height: 75
    widgets:
      - label:
          id: pc_mem_on
          text: !lambda |-
            std::string mem = id(pc_mem_raw).state;
            return "Mem: " + mem + "%";
          text_font: roboto_md
          align: CENTER
      - label:
          id: pc_mem_off
          text: "PC off"
          text_font: roboto_md
          align: BOTTOM_LEFT
          hidden: true

Chúng ta đã xem xét hầu hết các phần này, với những thay đổi duy nhất bên ngoài khối lambdawidth của nút để cho phép hai nút trên một hàng. Trong lambda của chúng ta, chúng ta chỉ cần sao chép giá trị của pc_mem_raw vào biến “mem” của chúng ta. Cuối cùng, chúng ta trả về "Mem: " + mem + "%". Bạn có thể thấy cách cú pháp của lệnh trả về của chúng ta hoạt động và lưu ý có khoảng trắng sau dấu hai chấm. Nó sẽ trả về chính xác những gì bạn cung cấp, vì vậy nếu bạn không đặt khoảng trắng bên trong dấu ngoặc kép, nó sẽ dán giá trị của mem trực tiếp bên cạnh ký tự dấu hai chấm.

Chúng ta có thể lặp lại điều tương tự cho CPU và cửa sổ đang hoạt động, mặc dù cửa sổ đang hoạt động chỉ là một lệnh trả về thông thường mà không có bất kỳ nối chuỗi nào. Cửa sổ đang hoạt động trong ví dụ của tôi cũng là một nút rộng hơn giống như nút thời gian khởi động của chúng ta.

Giao diện dashboard giám sát PC trên ESP32 CYD hiển thị phần trăm sử dụng RAM và CPUGiao diện dashboard giám sát PC trên ESP32 CYD hiển thị phần trăm sử dụng RAM và CPU

Tiềm Năng Vô Hạn Của ESPHome và Nền Tảng IoT

Tôi vẫn đang trong quá trình học cách sử dụng ESPHome, và các thư viện như LVGL hoàn toàn mới mẻ đối với tôi. Đây có thể không phải là cách tốt nhất để đạt được những gì tôi đã xây dựng, nhưng nó hoạt động, và tôi có thể lặp lại và cải thiện nó trong tương lai. Những gì ESPHome đã cho phép tôi xây dựng một cách dễ dàng, từ trình duyệt của mình, với các bản cập nhật có thể được gửi không dây, thực sự rất tuyệt vời, và tôi vô cùng ấn tượng với trải nghiệm liền mạch mà nó mang lại.

Tất nhiên, cũng có những cách khác để gửi dữ liệu giám sát đến Home Assistant, nhưng tôi đã sử dụng HASS.Agent, và dữ liệu tôi nhận được ở đây đủ để hiển thị một nguyên mẫu hoạt động của loại dữ liệu tôi có thể thu thập và hiển thị. Nếu bạn thiết lập điều này và sau đó quyết định muốn thay đổi nguồn dữ liệu của mình, bạn chỉ cần thay đổi text_sensor để lấy dữ liệu từ thực thể mới. Bạn không cần phải thay đổi toàn bộ hệ thống, trừ khi định dạng dữ liệu thay đổi đáng kể và ảnh hưởng đến các lambda của bạn.

Nếu bạn có một vài thiết bị ESP32 nằm quanh, bạn có thể bắt đầu sử dụng ESPHome ngay lập tức. Kết nối nó với PC của bạn, mở trình xây dựng thiết bị ESPHome và nhấn cài đặt. Nó sẽ đẩy một cấu hình cơ bản, mặc định sẽ kết nối ESP32 với Wi-Fi của bạn và cho phép cập nhật OTA. Từ đó, bạn có thể làm bất cứ điều gì bạn muốn, và những thiết bị nhỏ bé này có thể làm mọi thứ, từ hiển thị thông tin thực sự hữu ích đến cho phép bạn vỗ bàn để bật PC. Điều này thật thú vị bạn sẽ học được rất nhiều điều bổ ích.

Thiết bị chạy Home Assistant Voice PE với giao diện điều khiển giọng nói thông minhThiết bị chạy Home Assistant Voice PE với giao diện điều khiển giọng nói thông minh


Kết luận:

Việc biến một chiếc ESP32 CYD thành một dashboard giám sát PC không chỉ là một dự án DIY thú vị mà còn mở ra vô vàn khả năng tùy biến và kiểm soát. Với sự kết hợp mạnh mẽ của ESPHome và thư viện đồ họa LVGL, cùng với khả năng tích hợp linh hoạt với Home Assistant và MQTT, bạn có thể tạo ra một hệ thống hiển thị thông tin PC theo cách độc đáo và phù hợp với nhu cầu của mình. Từ việc theo dõi các thông số cơ bản như RAM, CPU đến việc hiển thị thời gian khởi động và cửa sổ đang hoạt động, tiềm năng của các thiết bị ESP32 là không giới hạn. Hãy bắt tay vào thử nghiệm ngay hôm nay để khám phá thế giới IoT và tự động hóa với ESPHome, mang lại những trải nghiệm công nghệ đầy bất ngờ và hữu ích!

Related posts

4 Phần Mềm Quản Lý Mật Khẩu Tự Host Tốt Nhất Để Nắm Quyền Kiểm Soát Bảo Mật Cá Nhân

Administrator

Giải Mã 5 Lầm Tưởng Phổ Biến Về Quạt Tản Nhiệt PC: Tối Ưu Hiệu Năng và Giảm Độ Ồn

Administrator

Giải Phóng Thời Gian: Khám Phá Công Cụ Tự Động Hóa Mạnh Mẽ Cho Windows

Administrator