| Crates.io | dutchdutch-ascend |
| lib.rs | dutchdutch-ascend |
| version | 0.1.0 |
| created_at | 2026-01-20 17:30:18.176023+00 |
| updated_at | 2026-01-20 17:30:18.176023+00 |
| description | Rust library for controlling Dutch and Dutch Ascend networked speakers |
| homepage | |
| repository | |
| max_upload_size | |
| id | 2057077 |
| size | 135,845 |
A Rust library for controlling Dutch and Dutch networked speakers.
Add this to your Cargo.toml:
[dependencies]
dutchdutch-ascend = "0.1.0"
The simplest way to get started is using the discovery API, which automatically finds Dutch and Dutch speakers on your network:
use dutchdutch_ascend::Discovery;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Start discovery
let mut discovery = Discovery::new();
discovery.start().await?;
// Wait for rooms to be discovered
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
// Get discovered rooms
let rooms = discovery.rooms();
if let Some(discovered_room) = rooms.first() {
println!("Found room: {}", discovered_room.name());
// Connect to the room (already connected via discovery)
let room = discovered_room;
// Control the room
room.set_gain(-20.0).await?;
room.set_mute(false).await?;
println!("Volume: {:.1} dB", room.gain().global);
println!("Muted: {}", room.mute().global);
}
discovery.stop().await;
Ok(())
}
If you know the IP address of your speaker, you can connect directly:
use dutchdutch_ascend::AscendClient;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = AscendClient::connect("192.168.1.100", 8768).await?;
let rooms = client.rooms().await?;
if let Some(room) = rooms.first() {
room.set_gain(-15.0).await?;
println!("Volume set to -15.0 dB");
}
Ok(())
}
Subscribe to state changes from the speakers:
use dutchdutch_ascend::Discovery;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut discovery = Discovery::new();
let mut updates = discovery.subscribe_updates();
discovery.start().await?;
// Listen for room updates
while let Ok(room_id) = updates.recv().await {
println!("Room {} updated", room_id);
// Get the updated room
let rooms = discovery.rooms();
if let Some(room) = rooms.iter().find(|r| r.id() == room_id) {
println!("New volume: {:.1} dB", room.gain().global);
}
}
Ok(())
}
The library includes a full-featured terminal UI example that demonstrates all functionality:
cargo run --example discover
This interactive application allows you to:
Discovery Screen:
j/k or arrow keys: Select roomEnter: Connect to roomq: QuitRoom Control Screen:
+/-: Adjust volumem: Toggle mutes: Toggle standbyi: Cycle input modex: Cycle XLR modep: Toggle linear phasej/k: Scroll JSON viewEsc: Back to discoveryq: Quitlet mut discovery = Discovery::new();
discovery.start().await?;
let rooms = discovery.rooms();
discovery.stop().await;
// Volume control
room.set_gain(-20.0).await?;
let current_volume = room.gain().global;
// Mute control
room.set_mute(true).await?;
let is_muted = room.mute().global;
// Standby control
room.set_standby(true).await?;
let is_asleep = room.sleep();
// Input selection
let inputs = room.input_modes();
room.set_input(&inputs[0]).await?;
// XLR mode selection
let xlr_modes = room.xlr_input_modes();
room.set_xlr_mode(&xlr_modes[0]).await?;
// Linear phase
room.set_linear_phase(true).await?;
let linear_phase = room.linear_phase();
// Voicing profiles
let voicings = room.voicing_profiles();
if let Some((id, profile)) = voicings.iter().next() {
room.set_voicing_profile(id).await?;
}
// Room state snapshot
let state = room.state_snapshot();
println!("Room: {}", state.name);
println!("Volume: {:.1} dB", state.gain.global);
This library communicates with Dutch and Dutch speakers using:
wss://api.ascend.audio/MIT License - see LICENSE file for details.
This is an unofficial, community-developed library and is not affiliated with or endorsed by Dutch and Dutch. Use at your own risk.