Màn hình dashboard giám sát PC chạy ESP32 CYD hiển thị thông số khởi động, RAM và CPU
Máy Tính

Hướng Dẫn Biến Màn Hình ESP32 Thành Dashboard Giám Sát PC Mạnh Mẽ

Trong thế giới công nghệ hiện đại, việc tối ưu hóa trải nghiệm sử dụng máy tính không chỉ dừng lại ở hiệu năng phần cứng mà còn mở rộng sang các giải pháp giám sát thông minh. Gần đây, tôi đã trải nghiệm chiếc màn hình Cheap Yellow Display (CYD) chạy ESP32 – một thiết bị nhỏ gọn với giá khoảng 20 USD nhưng mang lại nhiều khả năng thú vị. Với ESP32 tích hợp, màn hình LCD, khe cắm thẻ SD và một số chân GPIO mở rộng, CYD là nền tảng lý tưởng cho các dự án DIY. Dù ESPHome đã có sẵn các công cụ để xây dựng giao diện người dùng, việc hỗ trợ thư viện đồ họa Light and Versatile Graphics Library (LVGL) đã mở ra một chân trời mới. LVGL, với kho tiện ích (widget) phong phú và giao diện bắt mắt hơn hẳn những gì tôi có thể tạo ra bằng ESPHome thông thường, đã trở thành công cụ đắc lực để tôi phát triển một dashboard giám sát PC.

Ban đầu, dự án chỉ nhằm mục đích điều khiển đèn và phát nhạc trong nhà. Nhưng khi nhận thấy chiếc màn hình này luôn nằm trên bàn làm việc, ngay cạnh PC của mình, tôi nảy ra ý tưởng biến nó thành một dashboard giám sát PC. Giờ đây, tôi có thể theo dõi thời gian khởi động gần nhất, cửa sổ đang hoạt động, mức sử dụng RAM và CPU, tất cả đều hiển thị rõ ràng trên màn hình nhỏ bé này. Mặc dù việc hiển thị cửa sổ đang hoạt động có vẻ không quá cần thiết khi PC của tôi ở ngay trước mặt, đây chỉ là một bằng chứng khái niệm (proof of concept) để minh họa khả năng thu thập dữ liệu đa dạng. Bạn đọc có thể tìm thấy những ứng dụng thực tế hơn cho việc hiển thị thông tin này. Hơn nữa, nó cũng là một cách tuyệt vời để minh họa một phương pháp hiển thị văn bản khác trên màn hình.

Để hiện thực hóa dự án này, tôi sử dụng HASS.Agent trên Windows để gửi dữ liệu đến máy chủ MQTT, kết hợp với ESPHome như một tiện ích bổ sung trong Home Assistant. Luồng dữ liệu diễn ra như sau: từ PC của tôi đến máy chủ MQTT, sau đó đến Home Assistant, và cuối cùng là đến CYD. Đây là một quy trình tinh tế và khả năng kết hợp giữa Home Assistant và ESPHome dường như là vô tận, cho phép tạo ra các hệ thống tự động hóa và giám sát cực kỳ linh hoạt.

Cấu Trúc Code ESPHome và Cách Triển Khai Hiển Thị Dữ Liệu PC

Để bắt đầu, bạn cần đảm bảo rằng HASS.Agent đã được cài đặt và kết nối với một MQTT broker, đồng thời ESPHome cũng đã được cài đặt như một tiện ích bổ sung (add-on) trong 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 và sau đó cài đặt tích hợp ESPHome trong Home Assistant để liên kết mọi thứ.

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 đã cung cấp nguồn tài liệu vô giá và giúp tôi rất nhiều trong quá trình phát triển dashboard. Tôi đã tích hợp thành công các điều khiển đèn và điều khiển đa phương tiện, và bước tiếp theo là lấy dữ liệu từ Home Assistant để hiển thị trong các thẻ thông tin như bạn thấy. Các chỉ 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 nút mũi tên ở dưới cùng để di chuyển qua lại giữa các trang.

Đọc Dữ Liệu Thời Gian Khởi Động PC từ Home Assistant

Để đọc thời gian khởi động gần nhất của PC, tôi tạo một text_sensor trong ESPHome để đọc cảm biến “lastboot” từ thực thể MQTT của mình. Dưới đây là đoạn mã ví dụ, bạn hãy đảm bảo sử dụng đúng định dạng 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". Lý do cần có phần này là 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ế, vì nó khởi động nhanh hơn 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 của tôi. Phần "lvgl.widget.refresh" đảm bảo rằng widget "pc_last_boot_raw_on" sẽ được làm mới khi có dữ liệu mới, điều này tôi sẽ giải thích chi tiết hơn ngay sau đây.

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

Màn hình dashboard giám sát PC chạy ESP32 CYD hiển thị thông số khởi động, RAM và CPUMàn hình dashboard giám sát PC chạy ESP32 CYD hiển thị thông số khởi động, RAM và CPU

Đoạn mã trên có thể hơi khó theo dõi, vì vậy tôi sẽ giải thích cách hoạt động của nó từ đầu đến cuối. width (chiều rộng) và height (chiều cao) của nút được lấy từ các widget nút 320×240 của Ewen, vì chúng đã được tính toán để vừa vặn 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 ghép 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 đầy đủ 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. Trong khi các cấu hình ESPHome được viết bằng YAML, các 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 |-, vì nó báo cho 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ứ mình 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ử.

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à tôi có thể tinh chỉnh tốt hơn, nhưng HASS.Agent báo cáo thời gian khởi động theo định dạng 2025-06-20T10:12:29, có độ dài 19 ký tự. Về cơ bản, chúng ta đang kiểm tra phản hồi để đảm bảo nó khớp với độ dài của kết quả dự kiến. Sẽ tốt hơn nếu 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.

Cận cảnh màn hình ESP32 CYD hiển thị định dạng ngày và giờ khởi động PC được xử lý bằng lambdaCận cảnh màn hình ESP32 CYD hiển thị định dạng ngày và giờ khởi động PC được xử lý bằng lambda

Tuy nhiên, nếu điều kiện 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ộ, được gọi là ts. Trong C++ (và 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 chuẩn, vị trí của các ký tự 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, chỉ định bắt đầu từ vị trí 0 và lấy 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, chỉ định substring bắt đầu từ vị trí 11 (bỏ qua ký tự “T” trong chuỗi) và lấy 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 tách datetime mà không có dấu ngoặc kép vì các biến đó đã đại diện cho các 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 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ể.”

Bởi vì tất cả điều này nằm trong khối "text", ESPHome về cơ bản tạo nút với thông tin cho biết, “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 động, thay vì cần đặt giá trị tĩnh hoặc cố gắng đặt giá trị động từ bên ngoài nơi chúng được tạo ban đầu.

Nhưng còn về "lvgl.widget.refresh: pc_last_boot_raw_on"? Chúng ta đã đặt tên cho 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. Cảm biến ngày và giờ khởi động là cảm biến phức tạp nhất trong tất cả, vì vậy nếu bạn đã theo dõi đến đây, mọi thứ sẽ dễ dàng hơn rất nhiều.

Cấu Hình Hiển Thị RAM, CPU và Cửa Sổ Đang Hoạt Động

Các cảm biến này đơn giản hơn nhiều

Màn hình dashboard ESP32 CYD trình bày thông tin sử dụng RAM và CPU của máy tínhMàn hình dashboard ESP32 CYD trình bày thông tin sử dụng RAM và CPU của máy tính

Chúng ta định nghĩa các text_sensor trong ESPHome để lấy dữ liệu từ Home Assistant theo cách tương tự như khi lấy ngày và giờ khởi động. Vì vậy, bạn chỉ cần sửa đổi text_sensor đó để lấy các biến khác mà bạn cần. Sau 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

Hầu hết đoạn mã này chúng ta đã tìm hiểu qua, với những thay đổi duy nhất bên ngoài khối lambda là chiều rộng 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 mình. Cuối cùng, chúng ta trả về "Mem: " + mem + "%". Bạn có thể thấy cú pháp trả về của chúng ta hoạt động như thế nào và lưu ý 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 cạnh ký tự dấu hai chấm.

Chúng ta có thể lặp lại 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 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 như nút thời gian khởi động của chúng ta.

Sức Mạnh Vô Hạn của ESPHome và Hệ Sinh Thái Home Assistant

Thiết bị Cheap Yellow Display (CYD) với ESP32 chạy dashboard giám sát PC qua ESPHome và Home AssistantThiết bị Cheap Yellow Display (CYD) với ESP32 chạy dashboard giám sát PC qua ESPHome và Home Assistant

Tôi vẫn đang học cách sử dụng ESPHome, và các thư viện như LVGL hoàn toàn mới đố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 đã giú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. Tôi vô cùng ấn tượng với sự liền mạch của toàn bộ trải nghiệm này.

Tất nhiên, có nhiều 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 là đủ để hiển thị một nguyên mẫu hoạt động của loại dữ liệu mà tôi có thể thu thập và hiển thị. Nếu bạn thiết lập hệ thống này và sau đó quyết định muốn thay đổi nguồn dữ liệu, 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 sửa đổ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 số thiết bị ESP32 nhàn rỗi, bạn có thể bắt đầu sử dụng ESPHome ngay lập tức. Hãy 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 thiết lập cơ bản, mặc định sẽ kết nối ESP32 với Wi-Fi của bạn và bật cập nhật OTA (qua mạng). Từ đó, bạn có thể làm bất cứ điều gì mình muốn, và những thiết bị nhỏ bé này có thể làm được 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 của mình. Thật thú vị và bạn cũng sẽ học hỏi được rất nhiều điều!

Related posts

Làm thế nào để bán máy tính cũ hiệu quả? 5 sai lầm cần tránh để bảo vệ dữ liệu và tối ưu giá trị

Administrator

StartAllBack: Vì Sao Đây Là Lựa Chọn Tối Ưu Hơn Start11 cho Windows 11?

Administrator

Phân tích Dữ liệu Dễ Dàng: Khám phá IBM SPSS Statistics – Công Cụ Lý Tưởng Cho Người Không Chuyên Lập Trình

Administrator