Exddcutil

Elixir wrapper for the ddcutil tool to control monitor settings via DDC/CI. It assumes that ddcutil is already present on your machine.

Note: This library has only been tested with a Dell P2715Q monitor so far. Other DDC/CI compatible monitors should work, but YMMV.

Installation

Add exddcutil to your list of dependencies in mix.exs:

def deps do
  [
    {:exddcutil, "~> 0.1.0"}
  ]
end

Prerequisites

Usage

# Detect available displays
{:ok, displays} = Exddcutil.detect()
# => [%{index: 1, bus: 5, model: "DELL P2715Q", vendor: "DEL", serial: "ABC123"}, ...]

# Get display capabilities (returns a map)
{:ok, caps} = Exddcutil.capabilities(1)

# List available input sources
{:ok, sources} = Exddcutil.input_sources(1)
# => [%{code: "0x11", name: "HDMI-1"}, %{code: "0x0f", name: "DisplayPort-1"}, ...]

# List input sources with active flag
{:ok, sources} = Exddcutil.get_input_sources(1)
# => [%{code: "0x11", name: "HDMI-1", active: false},
#     %{code: "0x0f", name: "DisplayPort-1", active: true}, ...]

# Set and get brightness (0..100)
:ok = Exddcutil.set_brightness(1, 75)
{:ok, brightness} = Exddcutil.get_brightness(1)

# Set and get contrast (0..100)
:ok = Exddcutil.set_contrast(1, 50)
{:ok, contrast} = Exddcutil.get_contrast(1)

# Set and get RGB levels (0..100)
:ok = Exddcutil.set_red(1, 90)
:ok = Exddcutil.set_green(1, 90)
:ok = Exddcutil.set_blue(1, 90)
{:ok, red} = Exddcutil.get_red(1)
{:ok, green} = Exddcutil.get_green(1)
{:ok, blue} = Exddcutil.get_blue(1)

# Change input source (by name or code)
:ok = Exddcutil.set_input_source(1, "DisplayPort-1")
:ok = Exddcutil.set_input_source(1, "0x0f")
{:ok, source} = Exddcutil.get_input_source(1)

# Set color profile/preset
:ok = Exddcutil.set_color_profile(1, "sRGB")

# Use custom VCP codes
:ok = Exddcutil.set_vcp(1, 0x14, 6500)  # Color temperature
{:ok, value} = Exddcutil.get_vcp(1, 0x14)

# Use bus addressing (optional)
:ok = Exddcutil.set_brightness(1, 80, bus: 5)

API Documentation

The first argument to most functions is the display index (1-based), as returned by detect/1.

Display Detection

Capabilities

Setters (VCP Write)

Getters (VCP Read)

Testing

This library uses a behaviour-based runner system to allow testing without actual hardware:

# Inject a custom runner for testing
Exddcutil.capabilities(1, runner: MyMockRunner)
Exddcutil.set_brightness(1, 60, runner: MyMockRunner)
Exddcutil.detect(runner: MyMockRunner)

The runner must implement the Exddcutil.Runner behaviour with run(args) :: {:ok, stdout} | {:error, reason}.

Run tests with:

mix test

Compatibility

Tested on:

Should work with any DDC/CI compatible monitor, but behavior may vary depending on manufacturer implementation.

Documentation

Generate documentation with:

mix docs

License

MIT