Thursday

19-06-2025 Vol 19

Ever wanted a clean way to adjust your external monitor’s brightness and contrast from the command line? Let’s build a simple yet beautiful Python CLI tool named monitor using the power of ddcutil and rich! #No_More_Monitor_Buttons

Ucapkan Selamat Tinggal Tombol Monitor: Bangun CLI Python yang Elegan untuk Kontrol Kecerahan dan Kontras

Apakah Anda pernah berharap ada cara yang lebih bersih untuk menyesuaikan kecerahan dan kontras monitor eksternal Anda langsung dari baris perintah? Frustrasi dengan menu monitor yang kikuk dan tombol yang susah ditekan? Kami juga! Itulah mengapa kami memutuskan untuk membuat solusi sederhana namun indah: alat CLI Python bernama monitor, yang menggunakan kekuatan ddcutil dan rich.

Dalam postingan blog ini, kami akan memandu Anda langkah demi langkah melalui proses pembuatan alat ini, sehingga Anda dapat mengontrol monitor Anda seperti seorang profesional hanya dengan beberapa perintah sederhana. Siapkan diri Anda untuk mengucapkan selamat tinggal pada hari-hari tombol monitor yang membuat frustrasi!

Mengapa Menggunakan CLI untuk Mengontrol Monitor Anda?

Mungkin Anda bertanya-tanya, mengapa repot-repot membuat alat CLI untuk mengontrol kecerahan dan kontras monitor? Toh, sebagian besar monitor memiliki tombol fisik untuk melakukan hal itu. Meskipun itu benar, ada beberapa keuntungan signifikan untuk memiliki alat CLI:

  1. Efisiensi: CLI memungkinkan Anda menyesuaikan pengaturan monitor Anda dengan cepat tanpa harus menavigasi menu yang kikuk. Cukup ketik perintah dan lihat perubahannya secara instan.
  2. Otomatisasi: Dengan CLI, Anda dapat mengotomatiskan penyesuaian monitor Anda. Misalnya, Anda dapat membuat skrip untuk menyesuaikan kecerahan secara otomatis berdasarkan waktu atau kondisi pencahayaan sekitar Anda.
  3. Konsistensi: Alat CLI memastikan bahwa Anda dapat mengontrol monitor Anda dengan cara yang sama di semua sistem operasi. Ini sangat berguna jika Anda bekerja dengan beberapa mesin.
  4. Kustomisasi: Alat CLI memberi Anda fleksibilitas untuk menyesuaikan pengaturan monitor Anda sesuai dengan kebutuhan spesifik Anda. Anda dapat membuat preset, menyesuaikan nilai secara bertahap, dan banyak lagi.
  5. Aksesibilitas: Bagi sebagian orang, tombol fisik pada monitor mungkin sulit digunakan. CLI menawarkan cara alternatif dan lebih mudah diakses untuk mengontrol monitor.

Prasyarat

Sebelum kita mulai membangun alat monitor kita, pastikan Anda memiliki prasyarat berikut yang terpasang:

  • Python 3.6 atau lebih tinggi: Anda dapat mengunduh Python dari situs web Python.
  • pip: pip adalah pengelola paket untuk Python. Sebagian besar instalasi Python sudah menyertakannya.
  • ddcutil: ddcutil adalah utilitas baris perintah yang memungkinkan Anda untuk berinteraksi dengan monitor Anda menggunakan protokol DDC/CI. Kami akan menggunakannya untuk membaca dan mengatur kecerahan dan kontras monitor. Anda dapat menginstalnya menggunakan pip:
  • pip install ddcutil
  • rich: rich adalah pustaka Python untuk teks dan tata letak yang kaya di terminal. Kami akan menggunakannya untuk membuat output CLI kita lebih indah dan mudah dibaca. Anda dapat menginstalnya menggunakan pip:
  • pip install rich

Catatan Penting: ddcutil mungkin memerlukan konfigurasi tambahan tergantung pada sistem operasi Anda. Lihat dokumentasi ddcutil untuk instruksi khusus tentang cara menyiapkan ddcutil di sistem Anda. Biasanya melibatkan memberikan izin yang sesuai ke perangkat monitor.

Membangun Alat CLI monitor

Sekarang setelah kita memiliki semua prasyarat kita, mari kita mulai membangun alat CLI monitor kita. Kita akan melakukan ini langkah demi langkah, menjelaskan setiap bagian kode saat kita pergi.

Langkah 1: Membuat Struktur File

Pertama, buat direktori untuk proyek kita dan buat file Python bernama monitor.py di dalam direktori itu. Ini akan menjadi tempat kita menempatkan semua kode kita.

mkdir monitor
cd monitor
touch monitor.py

Langkah 2: Mengimpor Pustaka yang Diperlukan

Buka monitor.py di editor teks Anda dan tambahkan baris berikut di bagian atas file untuk mengimpor pustaka yang akan kita gunakan:

import subprocess
import argparse
from rich.console import Console
from rich.table import Column, Table

Di sini, kita mengimpor:

  • subprocess: Untuk menjalankan perintah eksternal (ddcutil).
  • argparse: Untuk mengurai argumen baris perintah.
  • Console dari rich: Untuk output yang kaya dan diformat.
  • Column dan Table dari rich: Untuk menampilkan informasi dalam format tabel yang terstruktur.

Langkah 3: Menginisialisasi Konsol Kaya

Selanjutnya, kita akan membuat objek Console dari pustaka rich. Ini akan kita gunakan untuk mencetak output kita ke terminal dengan gaya:

console = Console()

Langkah 4: Mendefinisikan Fungsi untuk Menjalankan Perintah ddcutil

Sekarang, mari kita definisikan fungsi yang akan menjalankan perintah ddcutil dan mengembalikan outputnya. Ini akan membantu kita untuk menyederhanakan interaksi kita dengan ddcutil:

def run_ddcutil_command(command):
    try:
      result = subprocess.run(command, capture_output=True, text=True, check=True)
      return result.stdout.strip()
    except subprocess.CalledProcessError as e:
      console.print_exception()
      return None

Fungsi ini membutuhkan daftar string command sebagai masukan. Ia menjalankan perintah menggunakan subprocess.run, menangkap outputnya, dan mengembalikan output yang dipangkas. Ia juga menangani pengecualian apa pun yang mungkin terjadi selama eksekusi perintah dan mencetak jejak pengecualian menggunakan rich untuk informasi debugging yang lebih baik.

Langkah 5: Mendefinisikan Fungsi untuk Mendapatkan Kecerahan dan Kontras

Selanjutnya, kita akan mendefinisikan fungsi untuk mendapatkan nilai kecerahan dan kontras saat ini dari monitor. Kita akan menggunakan perintah ddcutil getvcp untuk ini:

def get_brightness():
    output = run_ddcutil_command(["ddcutil", "getvcp", "10"]) # 10 is the VCP code for brightness
    if output:
      try:
        return int(output.split("current value = ")[1].split(",")[0])
      except (IndexError, ValueError):
        console.print_exception()
        return None
    return None


def get_contrast():
    output = run_ddcutil_command(["ddcutil", "getvcp", "18"]) # 18 is the VCP code for contrast
    if output:
      try:
        return int(output.split("current value = ")[1].split(",")[0])
      except (IndexError, ValueError):
        console.print_exception()
        return None
    return None

Kedua fungsi ini berjalan hampir identik. Mereka menggunakan ddcutil getvcp dengan kode VCP yang berbeda untuk kecerahan (10) dan kontras (18). Mereka kemudian memproses output untuk mengekstrak nilai saat ini. Error handling disediakan untuk kasus di mana output tidak sesuai dengan format yang diharapkan.

Langkah 6: Mendefinisikan Fungsi untuk Mengatur Kecerahan dan Kontras

Sekarang, mari kita definisikan fungsi untuk mengatur nilai kecerahan dan kontras. Kita akan menggunakan perintah ddcutil setvcp untuk ini:

def set_brightness(value):
    output = run_ddcutil_command(["ddcutil", "setvcp", "10", str(value)])
    if output is not None:
        console.print(f"Brightness set to {value}")


def set_contrast(value):
    output = run_ddcutil_command(["ddcutil", "setvcp", "18", str(value)])
    if output is not None:
        console.print(f"Contrast set to {value}")

Sama seperti fungsi _get_, fungsi _set_ ini menggunakan kode VCP masing-masing (10 untuk kecerahan, 18 untuk kontras). Nilai diubah menjadi string sebelum ditambahkan ke perintah. Output sederhana menunjukkan bahwa operasi berhasil.

Langkah 7: Mendefinisikan Fungsi untuk Menampilkan Status

Kita juga ingin dapat menampilkan status kecerahan dan kontras saat ini. Mari kita definisikan fungsi untuk melakukan itu menggunakan tabel yang indah dari rich:

def show_status():
    brightness = get_brightness()
    contrast = get_contrast()

    if brightness is not None and contrast is not None:
      table = Table(show_header=True, header_style="bold magenta")
      table.add_column("Property", style="dim", width=12)
      table.add_column("Value", justify="right")

      table.add_row("Brightness", str(brightness))
      table.add_row("Contrast", str(contrast))

      console.print(table)
    else:
      console.print("[red]Could not retrieve brightness or contrast values.[/red]")

Fungsi ini pertama-tama mengambil nilai kecerahan dan kontras menggunakan fungsi yang telah kita definisikan sebelumnya. Jika pengambilan berhasil, ia membuat objek Table menggunakan rich, menambahkan dua kolom: “Property” dan “Value”. Kemudian menambahkan baris untuk kecerahan dan kontras, menampilkan nilai mereka. Akhirnya, ia mencetak tabel ke konsol. Jika pengambilan gagal, ia mencetak pesan kesalahan.

Langkah 8: Mengurai Argumen Baris Perintah

Sekarang, mari kita tambahkan kode untuk mengurai argumen baris perintah. Kita akan menggunakan modul argparse untuk ini:

def main():
    parser = argparse.ArgumentParser(description="Control monitor brightness and contrast.")
    parser.add_argument("--brightness", type=int, help="Set brightness value (0-100).")
    parser.add_argument("--contrast", type=int, help="Set contrast value (0-100).")
    parser.add_argument("--status", action="store_true", help="Show current brightness and contrast.")

    args = parser.parse_args()

    if args.brightness is not None:
      set_brightness(args.brightness)
    if args.contrast is not None:
      set_contrast(args.contrast)
    if args.status:
      show_status()

    if not any([args.brightness, args.contrast, args.status]):
        show_status() # Show status by default if no arguments are provided


if __name__ == "__main__":
    main()

Fungsi main mendefinisikan tiga argumen baris perintah:

  • --brightness: Mengatur nilai kecerahan. Membutuhkan bilangan bulat antara 0 dan 100.
  • --contrast: Mengatur nilai kontras. Membutuhkan bilangan bulat antara 0 dan 100.
  • --status: Menampilkan status kecerahan dan kontras saat ini.

Ia kemudian mengurai argumen menggunakan parser.parse_args(). Berdasarkan argumen yang disediakan, ia memanggil fungsi yang sesuai untuk mengatur kecerahan, mengatur kontras, atau menampilkan status. Jika tidak ada argumen yang disediakan, ia secara default menampilkan status.

Langkah 9: Membuat Skrip yang Dapat Dieksekusi

Untuk membuat skrip kita dapat dieksekusi dari baris perintah, kita perlu menambahkan shebang di bagian atas file:

#!/usr/bin/env python3

import subprocess
import argparse
from rich.console import Console
from rich.table import Column, Table

console = Console()

def run_ddcutil_command(command):
  try:
    result = subprocess.run(command, capture_output=True, text=True, check=True)
    return result.stdout.strip()
  except subprocess.CalledProcessError as e:
    console.print_exception()
    return None


def get_brightness():
  output = run_ddcutil_command(["ddcutil", "getvcp", "10"])
  if output:
    try:
      return int(output.split("current value = ")[1].split(",")[0])
    except (IndexError, ValueError):
      console.print_exception()
      return None
  return None


def get_contrast():
  output = run_ddcutil_command(["ddcutil", "getvcp", "18"])
  if output:
    try:
      return int(output.split("current value = ")[1].split(",")[0])
    except (IndexError, ValueError):
      console.print_exception()
      return None
  return None


def set_brightness(value):
  output = run_ddcutil_command(["ddcutil", "setvcp", "10", str(value)])
  if output is not None:
      console.print(f"Brightness set to {value}")


def set_contrast(value):
  output = run_ddcutil_command(["ddcutil", "setvcp", "18", str(value)])
  if output is not None:
      console.print(f"Contrast set to {value}")


def show_status():
  brightness = get_brightness()
  contrast = get_contrast()

  if brightness is not None and contrast is not None:
    table = Table(show_header=True, header_style="bold magenta")
    table.add_column("Property", style="dim", width=12)
    table.add_column("Value", justify="right")

    table.add_row("Brightness", str(brightness))
    table.add_row("Contrast", str(contrast))

    console.print(table)
  else:
    console.print("[red]Could not retrieve brightness or contrast values.[/red]")


def main():
  parser = argparse.ArgumentParser(description="Control monitor brightness and contrast.")
  parser.add_argument("--brightness", type=int, help="Set brightness value (0-100).")
  parser.add_argument("--contrast", type=int, help="Set contrast value (0-100).")
  parser.add_argument("--status", action="store_true", help="Show current brightness and contrast.")

  args = parser.parse_args()

  if args.brightness is not None:
    set_brightness(args.brightness)
  if args.contrast is not None:
    set_contrast(args.contrast)
  if args.status:
    show_status()

  if not any([args.brightness, args.contrast, args.status]):
      show_status() # Show status by default if no arguments are provided


if __name__ == "__main__":
  main()

Kemudian, buat file yang dapat dieksekusi:

chmod +x monitor.py

Anda sekarang dapat menjalankan skrip dari baris perintah menggunakan:

./monitor.py --status
./monitor.py --brightness 75
./monitor.py --contrast 60

Kode Lengkap

Berikut adalah kode lengkap untuk alat CLI monitor:

#!/usr/bin/env python3

import subprocess
import argparse
from rich.console import Console
from rich.table import Column, Table

console = Console()

def run_ddcutil_command(command):
  try:
    result = subprocess.run(command, capture_output=True, text=True, check=True)
    return result.stdout.strip()
  except subprocess.CalledProcessError as e:
    console.print_exception()
    return None


def get_brightness():
  output = run_ddcutil_command(["ddcutil", "getvcp", "10"])
  if output:
    try:
      return int(output.split("current value = ")[1].split(",")[0])
    except (IndexError, ValueError):
      console.print_exception()
      return None
  return None


def get_contrast():
  output = run_ddcutil_command(["ddcutil", "getvcp", "18"])
  if output:
    try:
      return int(output.split("current value = ")[1].split(",")[0])
    except (IndexError, ValueError):
      console.print_exception()
      return None
  return None


def set_brightness(value):
  output = run_ddcutil_command(["ddcutil", "setvcp", "10", str(value)])
  if output is not None:
      console.print(f"Brightness set to {value}")


def set_contrast(value):
  output = run_ddcutil_command(["ddcutil", "setvcp", "18", str(value)])
  if output is not None:
      console.print(f"Contrast set to {value}")


def show_status():
  brightness = get_brightness()
  contrast = get_contrast()

  if brightness is not None and contrast is not None:
    table = Table(show_header=True, header_style="bold magenta")
    table.add_column("Property", style="dim", width=12)
    table.add_column("Value", justify="right")

    table.add_row("Brightness", str(brightness))
    table.add_row("Contrast", str(contrast))

    console.print(table)
  else:
    console.print("[red]Could not retrieve brightness or contrast values.[/red]")


def main():
  parser = argparse.ArgumentParser(description="Control monitor brightness and contrast.")
  parser.add_argument("--brightness", type=int, help="Set brightness value (0-100).")
  parser.add_argument("--contrast", type=int, help="Set contrast value (0-100).")
  parser.add_argument("--status", action="store_true", help="Show current brightness and contrast.")

  args = parser.parse_args()

  if args.brightness is not None:
    set_brightness(args.brightness)
  if args.contrast is not None:
    set_contrast(args.contrast)
  if args.status:
    show_status()

  if not any([args.brightness, args.contrast, args.status]):
      show_status() # Show status by default if no arguments are provided


if __name__ == "__main__":
  main()

Peningkatan dan Pertimbangan Potensial

Meskipun alat CLI monitor berfungsi sebagaimana adanya, ada beberapa potensi peningkatan dan pertimbangan yang dapat dipertimbangkan:

  • Penanganan Kesalahan yang Lebih Baik: Saat ini, penanganan kesalahan cukup dasar. Kita dapat memperbaikinya dengan menangani pengecualian tertentu dan memberikan pesan kesalahan yang lebih bermakna kepada pengguna. Misalnya, jika ddcutil tidak terpasang atau tidak dikonfigurasi dengan benar, kita dapat memberikan pesan yang jelas yang menunjukkan bagaimana cara memperbaikinya.
  • Validasi Masukan: Saat ini, skrip tidak memvalidasi masukan yang disediakan oleh pengguna. Ini dapat menyebabkan masalah jika pengguna memasukkan nilai yang tidak valid (misalnya, kecerahan di luar rentang 0-100). Kita dapat menambahkan validasi masukan untuk memastikan bahwa nilai yang dimasukkan valid.
  • Dukungan untuk Beberapa Monitor: Saat ini, skrip hanya berfungsi dengan satu monitor. Kita dapat memperbaikinya dengan menambahkan dukungan untuk beberapa monitor. Ini dapat dilakukan dengan memungkinkan pengguna untuk menentukan monitor yang ingin mereka kontrol melalui argumen baris perintah. ddcutil dapat mendeteksi semua monitor yang terhubung.
  • Preset: Kita dapat menambahkan dukungan untuk preset. Ini akan memungkinkan pengguna untuk menyimpan dan memuat konfigurasi kecerahan dan kontras yang berbeda. Misalnya, pengguna dapat membuat preset untuk bekerja, bermain game, dan menonton film.
  • Otomatisasi Berbasis Waktu: Seperti disebutkan sebelumnya, salah satu keuntungan dari alat CLI adalah kemampuannya untuk mengotomatiskan penyesuaian monitor. Kita dapat menambahkan fitur untuk menyesuaikan kecerahan dan kontras secara otomatis berdasarkan waktu. Ini dapat berguna untuk mengurangi ketegangan mata di malam hari. Kita bisa menggunakan pustaka seperti schedule untuk melakukan ini.
  • Integrasi dengan Sensor Cahaya Ambient: Untuk otomatisasi yang lebih canggih, kita dapat mengintegrasikan alat CLI dengan sensor cahaya ambient. Ini akan memungkinkan kita untuk menyesuaikan kecerahan dan kontras secara otomatis berdasarkan kondisi pencahayaan sekitar.
  • Antarmuka Pengguna Grafis (GUI): Jika Anda tidak nyaman dengan baris perintah, kita dapat membuat GUI untuk alat tersebut menggunakan pustaka seperti Tkinter, PyQt, atau Kivy.

Kesimpulan

Dalam postingan blog ini, kita telah membangun alat CLI Python yang sederhana namun elegan untuk mengontrol kecerahan dan kontras monitor Anda. Kita telah menggunakan kekuatan ddcutil dan rich untuk membuat alat yang efisien, dapat disesuaikan, dan mudah diakses.

Kami harap Anda menikmati membangun alat ini bersama kami. Jangan ragu untuk bereksperimen dengan itu, menambahkan fitur baru, dan menyesuaikannya sesuai dengan kebutuhan Anda. Dan jangan lupa untuk membagikan kreasi Anda dengan kami!

Selamat tinggal pada hari-hari tombol monitor yang membuat frustrasi dan halo kontrol monitor yang mulus dan efisien dengan alat CLI monitor Anda sendiri!

“`

omcoding

Leave a Reply

Your email address will not be published. Required fields are marked *