Control light#
Hardware is required. The Rust SDK is the primary control surface for host applications.
Built-in blackbody target#
use enody::environment::Environment;
use enody::message::{Configuration, Flux};
use enody::usb::UsbEnvironment;
#[tokio::main]
async fn main() -> Result<(), enody::Error> {
let env = UsbEnvironment::new();
let runtime = env
.runtimes()
.into_iter()
.next()
.ok_or(enody::Error::InsufficientData)?;
let host = runtime.host().await?;
let fixture = host
.fixtures()
.await?
.into_iter()
.next()
.ok_or(enody::Error::InsufficientData)?;
fixture
.display(Configuration::Blackbody(3000.0), Flux::Relative(0.75))
.await?;
Ok(())
}
Manual per-emitter output#
use enody::environment::Environment;
use enody::message::{Configuration, Flux};
use enody::usb::UsbEnvironment;
#[tokio::main]
async fn main() -> Result<(), enody::Error> {
let env = UsbEnvironment::new();
let runtime = env
.runtimes()
.into_iter()
.next()
.ok_or(enody::Error::InsufficientData)?;
let host = runtime.host().await?;
let fixture = host
.fixtures()
.await?
.into_iter()
.next()
.ok_or(enody::Error::InsufficientData)?;
let source = fixture
.sources()
.await?
.into_iter()
.next()
.ok_or(enody::Error::InsufficientData)?;
for (index, emitter) in source.emitters().await?.iter().enumerate() {
let value = if index == 0 { 1.0 } else { 0.0 };
emitter.set_flux(Flux::Relative(value)).await?;
}
fixture
.display(Configuration::Manual, Flux::Relative(1.0))
.await?;
Ok(())
}
Manual mode is useful for experiments and optimization. Built-in display modes are better for ordinary application control.
Source-level display#
Fixtures and sources both expose display:
use enody::environment::Environment;
use enody::message::{Configuration, Flux};
use enody::usb::UsbEnvironment;
#[tokio::main]
async fn main() -> Result<(), enody::Error> {
let env = UsbEnvironment::new();
let runtime = env
.runtimes()
.into_iter()
.next()
.ok_or(enody::Error::InsufficientData)?;
let host = runtime.host().await?;
let fixture = host
.fixtures()
.await?
.into_iter()
.next()
.ok_or(enody::Error::InsufficientData)?;
let source = fixture
.sources()
.await?
.into_iter()
.next()
.ok_or(enody::Error::InsufficientData)?;
source
.display(Configuration::Blackbody(4000.0), Flux::Relative(0.5))
.await?;
Ok(())
}
Use fixture-level display when you want the whole fixture to follow the same intent. Use source-level display when a device exposes multiple independently controllable source regions.