openrgb2

Crates.ioopenrgb2
lib.rsopenrgb2
version0.3.0
created_at2025-07-11 20:22:28.176633+00
updated_at2025-08-31 08:18:46.836804+00
descriptionOpenRGB SDK client, successor to openrgb
homepagehttps://github.com/Achtuur/openrgb-rs2
repositoryhttps://github.com/Achtuur/openrgb-rs2
max_upload_size
id1748413
size229,164
Arthur de Groot (Achtuur)

documentation

https://docs.rs/openrgb2

README

openrgb-rs2 crates.io tests

Rust client library for the OpenRGB SDK.

OpenRGB is an RGB Lighting control app that doesn't depend on manufacturer software.

See documentation and examples.

use openrgb2::{OpenRgbClient, OpenRgbResult};

#[tokio::main]
async fn main() -> OpenRgbResult<()> {
    // connect to local server
    let client = OpenRgbClient::connect().await?;

    let controllers = client.get_all_controllers().await?;
    for c in controllers {
        println!("controller {}: {:#?}", c.id(), c.name());
        // the LEDs should now be a rainbow
        c.init().await?;
    }

    Ok(())
}

Performance

The OpenRGB SDK provides a few ways to write colors to devices: per led, per zone, or all leds (set_leds). From my testing it seemed that when updating large number of LEDs, set_leds is the fastest one. It's inconvenient to update in this way, as some controllers have multiple unrelated zones, such as motherboards, meaninig you have to keep track of the zone offset.

Command API

To ease this, the crate has a Command API, which translates arbitrary LED updates to a single all_leds update, ensuring both user friendliness and maximum performance. The entire API is sync, with only one asynchronous api call at the end.

use openrgb2::{OpenRgbClient, OpenRgbResult, Color};

#[tokio::main]
async fn main() -> OpenRgbResult<()> {
    // connect to local server
    let client = OpenRgbClient::connect().await?;

    // get a controller
    let controllers = client.get_all_controllers().await?;
    let controller = controllers
        .iter()
        .next()
        .expect("Must have at least one controller");
    controller.init().await?;

    let mut cmd = controller.cmd();
    // Set all LEDs to red
    cmd.set_leds(vec![Color::new(255, 0, 0); controller.num_leds()])?;
    // First half of first zone to green
    cmd.set_zone_leds(
        0,
        vec![Color::new(0, 255, 0); controller.get_zone(0)?.num_leds() / 2],
    )?;
    // First led to blue
    cmd.set_led(0, Color::new(0, 0, 255))?;
    // This is now equivalent to a single `controller.set_leds(...)` command
    cmd.execute().await?;
    Ok(())
}

Multiple devices

My case contains a few controllers that I would like to control in sync, like my RAM sticks and case fans. To make it easier to update those, the Command API also supports ControllerGroups.

use openrgb2::{Color, OpenRgbClient, OpenRgbResult};

const RAINBOW_COLORS: [Color; 7] = [
    Color::new(255, 0, 0),   // Red
    Color::new(255, 127, 0), // Orange
    Color::new(255, 255, 0), // Yellow
    Color::new(0, 255, 0),   // Green
    Color::new(0, 0, 255),   // Blue
    Color::new(85, 0, 180),  // Indigo
    Color::new(148, 0, 211), // Violet
];

#[tokio::main]
async fn main() -> OpenRgbResult<()> {
    // connect to local server
    let client = OpenRgbClient::connect().await?;
    let group = client.get_all_controllers().await?;
    group.init().await?;
    // sets each separate device to a color of the rainbow
    let mut cmd_group = group.cmd();
    for (idx, c) in group.iter().enumerate() {
        let color = RAINBOW_COLORS[idx % RAINBOW_COLORS.len()];
        cmd_group.set_controller_leds(c, vec![color; c.num_leds()])?;
    }
    // executes a `set_leds` for every controller
    cmd_group.execute().await?;
    Ok(())
}

Syncing controller data

Syncing controller data with the data in OpenRGB requires an additional API call, which could be unnecessary in a lot of cases. Most of the (important) data will not change over a Controllers lifetime and usually you just want to write colors as fast as possible. Therefore, I chose to make syncing the controller data a separate method (Controller::sync_controller_data) instead of being automatically called after any request.

Original openrgb-rs

This repository is a clone of the repo previously maintaed by nicoulaj. I have attempted to reach out to them, but received no response. As a result I decided to republish the OpenRGB SDK under a new name (openrgb-rs2).

Whats different?

Support for OpenRGB protocol versions 4 and 5 is added. There's also now a friendlier to use API than before.

Internally there's some changes in how serializing/deserializing the protocol is done. I decided it was easier to read/write to a buffer, rather than directly to a stream as was previously done. For the end user there should not be much visible change though. I have not done any benchmarking, so I'm not sure about the performance. I can update my entire rig at about 300 FPS at release mode, so I'm not too worried about performance anyway.

Commit count: 23

cargo fmt