use sonos_event_manager::SonosEventManager;
use sonos_state::property::SonosProperty;
use sonos_state::{
GroupId, GroupInfo, GroupVolume, Property, SpeakerId, StateManager, Topology, Volume,
};
use std::sync::Arc;
use std::time::Duration;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("1. Initializing StateManager with event manager...");
let event_manager = Arc::new(SonosEventManager::new()?);
let manager = StateManager::builder()
.with_event_manager(Arc::clone(&event_manager))
.build()?;
println!(" StateManager initialized");
println!("2. Discovering devices...");
let devices = sonos_discovery::get();
if devices.is_empty() {
println!(" No Sonos devices found on network");
return Err("No Sonos devices found".into());
}
println!(" Found {} devices", devices.len());
println!("3. Adding devices to StateManager...");
manager.add_devices(devices.clone())?;
println!(" Devices added successfully");
let groups: Vec<GroupInfo> = devices
.iter()
.map(|d| {
let sid = SpeakerId::new(&d.id);
GroupInfo::new(GroupId::new(format!("{}:1", d.id)), sid.clone(), vec![sid])
})
.collect();
let topology = Topology::new(manager.speaker_infos(), groups);
manager.initialize(topology);
println!(" Topology initialized");
let speaker_id = SpeakerId::new(&devices[0].id);
let speaker_ip: std::net::IpAddr = devices[0].ip_address.parse()?;
println!("Using speaker: {} ({})", devices[0].name, speaker_ip);
println!("\n4. Getting current values (from cache)...");
if let Some(vol) = manager.get_property::<Volume>(&speaker_id) {
println!(" Current volume: {}%", vol.0);
} else {
println!(" No volume data available yet (cache empty)");
}
println!("\n5. Setting up property watches + UPnP subscriptions...");
manager.register_watch(&speaker_id, Volume::KEY);
event_manager.ensure_service_subscribed(speaker_ip, Volume::SERVICE)?;
println!(" Watching speaker volume (RenderingControl)");
manager.register_watch(&speaker_id, GroupVolume::KEY);
event_manager.ensure_service_subscribed(speaker_ip, GroupVolume::SERVICE)?;
println!(" Watching group volume (GroupRenderingControl)");
println!(" (Change volume within 30s to see events)");
println!("\n6. Listening for change events...");
let iter = manager.iter();
let mut event_count = 0;
for event in iter.timeout_iter(Duration::from_secs(30)) {
event_count += 1;
println!(
" [{}] Property '{}' changed on {} (service: {:?})",
event_count, event.property_key, event.speaker_id, event.service
);
match event.property_key {
"volume" => {
if let Some(vol) = manager.get_property::<Volume>(&event.speaker_id) {
println!(" New speaker volume: {}%", vol.0);
}
}
"group_volume" => {
if let Some(group_info) = manager.get_group_for_speaker(&event.speaker_id) {
if let Some(gv) = manager.get_group_property::<GroupVolume>(&group_info.id) {
println!(" New group volume: {}%", gv.0);
}
} else {
println!(" (no group mapping for this speaker)");
}
}
other => {
println!(" (unhandled property: {other})");
}
}
if event_count >= 10 {
println!(" Received 10 events, stopping");
break;
}
}
if event_count > 0 {
println!("\n Received {event_count} change event(s)");
} else {
println!("\n No state changes detected within timeout");
}
println!("\nExample completed!");
Ok(())
}