zeevonk 0.2.0

A new lighting control system server, that serves as a hub for lighting communication, processing and interaction.
Documentation

Zeevonk

A modular lighting control system for modern DMX-based lighting setups.

⚠️ Warning

Zeevonk is currently in early development. APIs, features, and behavior may change frequently and without notice. It is not yet recommended for production use.

What is Zeevonk?

Zeevonk is a modular system for controlling lighting fixtures. It consists of a server and two types of client:

  • Server: Manages clients, processes triggers and attribute updates, and sends DMX data.
  • Processor Client: Calculates and sends fixture attribute values (like color, position, intensity) to the server.
  • Controller Client: Sends triggers (such as button presses or fader moves) to the server.

Processor and controller clients could even be combined into a single client. This can be useful if your program is not supposed to be modular.

Zeevonk system diagram

This project is the result of a deep rabbithole I went into, when creating Radiant. I realized I was writing the same DMX resolvers for GDTF files over and over again. Zeevonk is my way of consolidating all of my research into a hub for DMX lighting.

Some notable controllers:

Run the Zeevonk server

You can install zeevonk as a binary (called zv) using the following command:

cargo install --path crates/cli

Use as a library

Features

The crate has two main features you can enable:

server: Start and configure the server from your own code instead of the CLI.

client: Create a new client to communicate with the server.

Example: Starting the Server

use zeevonk::server::Server;
use zeevonk::project::file::ProjectFile;

// Create a project file.
let project_file = ProjectFile::default();

// Create and start the server.
let server = Server::new(project_file).unwrap();
server.start();

Example: Processor Client

use zeevonk::attr::Attribute;
use zeevonk::client::Client;
use zeevonk::ident::Identifier;
use zeevonk::project::stage::{FixtureId, FixtureIdPart};
use zeevonk::value::AttributeValues;

#[tokio::main]
async fn main() {
    let mut client = Client::new(Identifier::new("zv-example-processor").unwrap());
    client.on_trigger(|from_client, trigger| eprintln!("{from_client}: {trigger:?}"));
    client.connect("ws://127.0.0.1:7334").await.unwrap();

    let fid = FixtureId::new(FixtureIdPart::new(101).unwrap());

    let mut values = AttributeValues::new();
    
    // Set attribute values for your fixtures here...
    values.set(fid, Attribute::Dimmer, 1.0);
    
    client.update_attributes(values, false).await.unwrap();

    loop {}
}

Example: Controller Client

use zeevonk::client::Client;
use zeevonk::ident::Identifier;
use zeevonk::trigger::{Trigger, TriggerValue};

#[tokio::main]
async fn main() {
    pretty_env_logger::init();

    let mut client = Client::new(Identifier::new("zv-example-controller").unwrap());
    client.connect("ws://127.0.0.1:7334").await.unwrap();

    loop {
        client
            .send_trigger(Trigger::new(
                Identifier::new("button-1").unwrap(),
                TriggerValue::Boolean(true),
            ))
            .await
            .unwrap();

        std::thread::sleep(std::time::Duration::from_secs_f32(1.0 / 10.0));
    }
}

For more details, see the documentation for each module in the crate.

Licensing

This project is dual-licensed under:

  • MIT License
  • Apache License, Version 2.0

You may choose either license to govern your use of this project. See the LICENSE-MIT and LICENSE-APACHE files for details.