pub struct Remote { /* private fields */ }Expand description
A client on the MX Remote network.
Create one with Remote::new, then Remote::start it. Discovery runs
on threads this client owns until Remote::close, or until the Remote
is dropped.
Implementations§
Source§impl Remote
impl Remote
Sourcepub fn select_video_source(
&self,
sink: BayUid,
source_port: u16,
) -> Result<(), ControlError>
pub fn select_video_source( &self, sink: BayUid, source_port: u16, ) -> Result<(), ControlError>
Routes this V2IP sink’s video to the stream a source port advertises.
Sourcepub fn select_audio_source(
&self,
sink: BayUid,
source_port: u16,
) -> Result<(), ControlError>
pub fn select_audio_source( &self, sink: BayUid, source_port: u16, ) -> Result<(), ControlError>
Routes this V2IP sink’s audio to the stream a source port advertises.
Sourcepub fn select_video_source_by_name(
&self,
sink: BayUid,
name: &str,
) -> Result<(), ControlError>
pub fn select_video_source_by_name( &self, sink: BayUid, name: &str, ) -> Result<(), ControlError>
Routes this V2IP sink’s video to the input bay with the given user-assigned name.
Sourcepub fn select_audio_source_addr(
&self,
sink: BayUid,
audio_ip: Ipv4Addr,
audio_port: Option<u16>,
format: Option<V2ipAudioFormat>,
) -> Result<(), ControlError>
pub fn select_audio_source_addr( &self, sink: BayUid, audio_ip: Ipv4Addr, audio_port: Option<u16>, format: Option<V2ipAudioFormat>, ) -> Result<(), ControlError>
Routes this V2IP sink’s audio to a multicast address directly, leaving its video and ancillary streams alone.
An unset port is the standard V2IP audio port. A format overrides the sample rate and channel count the receiver would otherwise assume.
Sourcepub fn select_audio_source_by_name(
&self,
sink: BayUid,
name: &str,
format: Option<V2ipAudioFormat>,
) -> Result<(), ControlError>
pub fn select_audio_source_by_name( &self, sink: BayUid, name: &str, format: Option<V2ipAudioFormat>, ) -> Result<(), ControlError>
Routes this V2IP sink’s audio from the input bay with the given user-assigned name.
A format is carried on the manual switch frame, which is the only form that can override the receiver’s sample rate and channel count.
Sourcepub fn set_bay_name(&self, bay: BayUid, name: &str) -> Result<(), ControlError>
pub fn set_bay_name(&self, bay: BayUid, name: &str) -> Result<(), ControlError>
Renames a bay.
Hides a bay from the pickers that list it, or shows it again.
Sourcepub fn select_edid_profile(
&self,
bay: BayUid,
profile: EdidProfile,
) -> Result<(), ControlError>
pub fn select_edid_profile( &self, bay: BayUid, profile: EdidProfile, ) -> Result<(), ControlError>
Sets the EDID profile an input presents to the source attached to it.
Sourcepub fn send_action(
&self,
bay: BayUid,
action: RcAction,
) -> Result<(), ControlError>
pub fn send_action( &self, bay: BayUid, action: RcAction, ) -> Result<(), ControlError>
Sends a remote-control action to whatever is attached to a bay.
Sourcepub fn power_on(&self, bay: BayUid) -> Result<(), ControlError>
pub fn power_on(&self, bay: BayUid) -> Result<(), ControlError>
Powers on the device attached to a bay.
Sourcepub fn power_off(&self, bay: BayUid) -> Result<(), ControlError>
pub fn power_off(&self, bay: BayUid) -> Result<(), ControlError>
Powers off the device attached to a bay.
Sourcepub fn set_volume(
&self,
bay: BayUid,
volume: u8,
muted: Option<bool>,
) -> Result<(), ControlError>
pub fn set_volume( &self, bay: BayUid, volume: u8, muted: Option<bool>, ) -> Result<(), ControlError>
Sets a bay’s volume, as a percentage, and optionally its mute state.
Both channels are set together: the wire carries them separately, but nothing on this surface splits them.
A bay with no volume control of its own is set through its
linked_bay, so an output wired to an
amplifier zone reaches that zone. volume_up,
volume_down and set_muted
follow the same link, and read the volume they step from through it.
Sourcepub fn volume_up(&self, bay: BayUid) -> Result<(), ControlError>
pub fn volume_up(&self, bay: BayUid) -> Result<(), ControlError>
Raises a bay’s volume by one percent.
Sourcepub fn volume_down(&self, bay: BayUid) -> Result<(), ControlError>
pub fn volume_down(&self, bay: BayUid) -> Result<(), ControlError>
Lowers a bay’s volume by one percent.
Sourcepub fn set_muted(&self, bay: BayUid, muted: bool) -> Result<(), ControlError>
pub fn set_muted(&self, bay: BayUid, muted: bool) -> Result<(), ControlError>
Mutes or unmutes a bay, keeping the volume it is set to.
Sourcepub fn set_amp_zone_settings(
&self,
bay: BayUid,
settings: AmpZoneSettings,
) -> Result<(), ControlError>
pub fn set_amp_zone_settings( &self, bay: BayUid, settings: AmpZoneSettings, ) -> Result<(), ControlError>
Applies amplifier settings to a zone.
Sourcepub fn set_audio_endpoint_muted(
&self,
device: DeviceUid,
endpoint: u16,
muted: bool,
) -> Result<(), ControlError>
pub fn set_audio_endpoint_muted( &self, device: DeviceUid, endpoint: u16, muted: bool, ) -> Result<(), ControlError>
Mutes or unmutes an audio endpoint.
Sourcepub fn set_audio_endpoint_trigger(
&self,
device: DeviceUid,
endpoint: u16,
active: bool,
) -> Result<(), ControlError>
pub fn set_audio_endpoint_trigger( &self, device: DeviceUid, endpoint: u16, active: bool, ) -> Result<(), ControlError>
Sets an audio endpoint’s trigger output.
Sourcepub fn set_audio_endpoint_volume(
&self,
device: DeviceUid,
endpoint: u16,
volume: u32,
) -> Result<(), ControlError>
pub fn set_audio_endpoint_volume( &self, device: DeviceUid, endpoint: u16, volume: u32, ) -> Result<(), ControlError>
Sets an audio endpoint’s volume.
Sourcepub fn select_audio_endpoint_input(
&self,
sink: DeviceUid,
sink_endpoint: u16,
source: DeviceUid,
source_endpoint: u16,
) -> Result<(), ControlError>
pub fn select_audio_endpoint_input( &self, sink: DeviceUid, sink_endpoint: u16, source: DeviceUid, source_endpoint: u16, ) -> Result<(), ControlError>
Routes a source endpoint on one device to a sink endpoint on another.
Sourcepub fn subscribe_v2ip_stats(
&self,
device: DeviceUid,
subscribe: bool,
) -> Result<(), ControlError>
pub fn subscribe_v2ip_stats( &self, device: DeviceUid, subscribe: bool, ) -> Result<(), ControlError>
Starts or stops a V2IP device reporting its transport statistics.
Sourcepub fn reboot(&self, device: DeviceUid) -> Result<(), ControlError>
pub fn reboot(&self, device: DeviceUid) -> Result<(), ControlError>
Reboots a device.
The device is marked as rebooting once the frame is away, so the silence that follows does not read as one that went offline.
Sourcepub fn send_monitoring_pulse(&self) -> Result<(), ControlError>
pub fn send_monitoring_pulse(&self) -> Result<(), ControlError>
Asks every peer to report its monitoring data now rather than on its own schedule.
Sourcepub fn set_multiviewer_view_mode(
&self,
device: DeviceUid,
mode: MultiviewerViewMode,
) -> Result<(), ControlError>
pub fn set_multiviewer_view_mode( &self, device: DeviceUid, mode: MultiviewerViewMode, ) -> Result<(), ControlError>
Sets the window layout.
Sourcepub fn set_multiviewer_video_source(
&self,
device: DeviceUid,
screen: u8,
source: MultiviewerSource,
) -> Result<(), ControlError>
pub fn set_multiviewer_video_source( &self, device: DeviceUid, screen: u8, source: MultiviewerSource, ) -> Result<(), ControlError>
Assigns a source to one window.
Sourcepub fn set_multiviewer_audio_source(
&self,
device: DeviceUid,
source: MultiviewerSource,
) -> Result<(), ControlError>
pub fn set_multiviewer_audio_source( &self, device: DeviceUid, source: MultiviewerSource, ) -> Result<(), ControlError>
Selects which window’s audio is output.
Sourcepub fn set_multiviewer_audio_volume(
&self,
device: DeviceUid,
volume: u8,
muted: bool,
) -> Result<(), ControlError>
pub fn set_multiviewer_audio_volume( &self, device: DeviceUid, volume: u8, muted: bool, ) -> Result<(), ControlError>
Sets the output volume and mute state.
Sourcepub fn set_multiviewer_edid_template(
&self,
device: DeviceUid,
template: MultiviewerEdidTemplate,
) -> Result<(), ControlError>
pub fn set_multiviewer_edid_template( &self, device: DeviceUid, template: MultiviewerEdidTemplate, ) -> Result<(), ControlError>
Sets the EDID template presented to the sources.
Sourcepub fn set_multiviewer_remote_control(
&self,
device: DeviceUid,
source: MultiviewerSource,
) -> Result<(), ControlError>
pub fn set_multiviewer_remote_control( &self, device: DeviceUid, source: MultiviewerSource, ) -> Result<(), ControlError>
Selects which window receives remote-control passthrough.
Sourcepub fn set_multiviewer_pip_size(
&self,
device: DeviceUid,
size: MultiviewerPipSize,
) -> Result<(), ControlError>
pub fn set_multiviewer_pip_size( &self, device: DeviceUid, size: MultiviewerPipSize, ) -> Result<(), ControlError>
Sets how large the picture-in-picture window is.
Sourcepub fn set_multiviewer_pip_position(
&self,
device: DeviceUid,
position: MultiviewerPipPosition,
) -> Result<(), ControlError>
pub fn set_multiviewer_pip_position( &self, device: DeviceUid, position: MultiviewerPipPosition, ) -> Result<(), ControlError>
Sets which corner the picture-in-picture window sits in.
Sourcepub fn set_multiviewer_aspect_ratio(
&self,
device: DeviceUid,
aspect: MultiviewerAspectRatio,
) -> Result<(), ControlError>
pub fn set_multiviewer_aspect_ratio( &self, device: DeviceUid, aspect: MultiviewerAspectRatio, ) -> Result<(), ControlError>
Sets the aspect ratio the windows are scaled to.
Sourcepub fn set_multiviewer_auto_switch(
&self,
device: DeviceUid,
enable: bool,
) -> Result<(), ControlError>
pub fn set_multiviewer_auto_switch( &self, device: DeviceUid, enable: bool, ) -> Result<(), ControlError>
Enables or disables switching windows on its own.
Sourcepub fn set_multiviewer_output_mode(
&self,
device: DeviceUid,
mode: MultiviewerOutputMode,
) -> Result<(), ControlError>
pub fn set_multiviewer_output_mode( &self, device: DeviceUid, mode: MultiviewerOutputMode, ) -> Result<(), ControlError>
Sets the output resolution and refresh rate.
Sourcepub fn set_multiviewer_output_itc(
&self,
device: DeviceUid,
mode: MultiviewerItcMode,
) -> Result<(), ControlError>
pub fn set_multiviewer_output_itc( &self, device: DeviceUid, mode: MultiviewerItcMode, ) -> Result<(), ControlError>
Sets the IT-content flag on the output.
Sourcepub fn set_multiviewer_hdcp_mode(
&self,
device: DeviceUid,
mode: MultiviewerHdcpMode,
) -> Result<(), ControlError>
pub fn set_multiviewer_hdcp_mode( &self, device: DeviceUid, mode: MultiviewerHdcpMode, ) -> Result<(), ControlError>
Sets the HDCP version negotiated on the output.
Sourcepub fn set_multiviewer_input_source(
&self,
device: DeviceUid,
input: u8,
source: DeviceUid,
) -> Result<(), ControlError>
pub fn set_multiviewer_input_source( &self, device: DeviceUid, input: u8, source: DeviceUid, ) -> Result<(), ControlError>
Maps a source device onto one of the multiviewer’s inputs.
The zero identifier clears the mapping.
Sourcepub fn multiviewer_auto_route(
&self,
device: DeviceUid,
) -> Result<(), ControlError>
pub fn multiviewer_auto_route( &self, device: DeviceUid, ) -> Result<(), ControlError>
Asks the multiviewer to route its sources itself.
Source§impl Remote
impl Remote
Sourcepub fn new(config: Config, handler: Arc<dyn EventHandler>) -> Result<Self>
pub fn new(config: Config, handler: Arc<dyn EventHandler>) -> Result<Self>
Builds a client, loading or generating its identifier.
Nothing is sent and no socket is opened until Remote::start.
Examples found in repository?
59fn main() -> std::io::Result<()> {
60 let mut config = Config::default();
61 config.name = Some("discover".to_owned());
62 if let Some(address) = std::env::args().nth(1) {
63 config.local_ip = Some(address.parse().map_err(|_| {
64 std::io::Error::new(std::io::ErrorKind::InvalidInput, "not an IPv4 address")
65 })?);
66 }
67
68 let remote = Arc::new(Remote::new(config, Arc::new(Printer))?);
69 let _ = CLIENT.set(Arc::clone(&remote));
70 remote.start()?;
71
72 if let Some(target) = remote.target() {
73 println!("listening, sending to {target}. Ctrl-C to stop.");
74 }
75
76 let running = Arc::new(AtomicBool::new(true));
77 let stop = Arc::clone(&running);
78 ctrl_c(move || stop.store(false, Ordering::Relaxed));
79 while running.load(Ordering::Relaxed) {
80 std::thread::sleep(Duration::from_millis(200));
81 }
82
83 let devices = remote.devices();
84 println!("\n{} device(s):", devices.len());
85 for device in devices {
86 Printer.on_device_update(device);
87 }
88
89 remote.close();
90 Ok(())
91}Sourcepub fn start(&self) -> Result<()>
pub fn start(&self) -> Result<()>
Opens the socket, announces this client and begins discovery.
Returns once the receive thread is running; discovery continues in the background.
Examples found in repository?
59fn main() -> std::io::Result<()> {
60 let mut config = Config::default();
61 config.name = Some("discover".to_owned());
62 if let Some(address) = std::env::args().nth(1) {
63 config.local_ip = Some(address.parse().map_err(|_| {
64 std::io::Error::new(std::io::ErrorKind::InvalidInput, "not an IPv4 address")
65 })?);
66 }
67
68 let remote = Arc::new(Remote::new(config, Arc::new(Printer))?);
69 let _ = CLIENT.set(Arc::clone(&remote));
70 remote.start()?;
71
72 if let Some(target) = remote.target() {
73 println!("listening, sending to {target}. Ctrl-C to stop.");
74 }
75
76 let running = Arc::new(AtomicBool::new(true));
77 let stop = Arc::clone(&running);
78 ctrl_c(move || stop.store(false, Ordering::Relaxed));
79 while running.load(Ordering::Relaxed) {
80 std::thread::sleep(Duration::from_millis(200));
81 }
82
83 let devices = remote.devices();
84 println!("\n{} device(s):", devices.len());
85 for device in devices {
86 Printer.on_device_update(device);
87 }
88
89 remote.close();
90 Ok(())
91}Sourcepub fn close(&self)
pub fn close(&self)
Stops discovery, closes the socket and waits for the threads to finish.
Calling it more than once, or before Remote::start, does nothing.
Examples found in repository?
59fn main() -> std::io::Result<()> {
60 let mut config = Config::default();
61 config.name = Some("discover".to_owned());
62 if let Some(address) = std::env::args().nth(1) {
63 config.local_ip = Some(address.parse().map_err(|_| {
64 std::io::Error::new(std::io::ErrorKind::InvalidInput, "not an IPv4 address")
65 })?);
66 }
67
68 let remote = Arc::new(Remote::new(config, Arc::new(Printer))?);
69 let _ = CLIENT.set(Arc::clone(&remote));
70 remote.start()?;
71
72 if let Some(target) = remote.target() {
73 println!("listening, sending to {target}. Ctrl-C to stop.");
74 }
75
76 let running = Arc::new(AtomicBool::new(true));
77 let stop = Arc::clone(&running);
78 ctrl_c(move || stop.store(false, Ordering::Relaxed));
79 while running.load(Ordering::Relaxed) {
80 std::thread::sleep(Duration::from_millis(200));
81 }
82
83 let devices = remote.devices();
84 println!("\n{} device(s):", devices.len());
85 for device in devices {
86 Printer.on_device_update(device);
87 }
88
89 remote.close();
90 Ok(())
91}Sourcepub fn target(&self) -> Option<SocketAddrV4>
pub fn target(&self) -> Option<SocketAddrV4>
The address frames are being sent to, once started.
Examples found in repository?
59fn main() -> std::io::Result<()> {
60 let mut config = Config::default();
61 config.name = Some("discover".to_owned());
62 if let Some(address) = std::env::args().nth(1) {
63 config.local_ip = Some(address.parse().map_err(|_| {
64 std::io::Error::new(std::io::ErrorKind::InvalidInput, "not an IPv4 address")
65 })?);
66 }
67
68 let remote = Arc::new(Remote::new(config, Arc::new(Printer))?);
69 let _ = CLIENT.set(Arc::clone(&remote));
70 remote.start()?;
71
72 if let Some(target) = remote.target() {
73 println!("listening, sending to {target}. Ctrl-C to stop.");
74 }
75
76 let running = Arc::new(AtomicBool::new(true));
77 let stop = Arc::clone(&running);
78 ctrl_c(move || stop.store(false, Ordering::Relaxed));
79 while running.load(Ordering::Relaxed) {
80 std::thread::sleep(Duration::from_millis(200));
81 }
82
83 let devices = remote.devices();
84 println!("\n{} device(s):", devices.len());
85 for device in devices {
86 Printer.on_device_update(device);
87 }
88
89 remote.close();
90 Ok(())
91}Sourcepub fn devices(&self) -> Vec<DeviceUid>
pub fn devices(&self) -> Vec<DeviceUid>
Every device heard from, in no particular order.
Examples found in repository?
59fn main() -> std::io::Result<()> {
60 let mut config = Config::default();
61 config.name = Some("discover".to_owned());
62 if let Some(address) = std::env::args().nth(1) {
63 config.local_ip = Some(address.parse().map_err(|_| {
64 std::io::Error::new(std::io::ErrorKind::InvalidInput, "not an IPv4 address")
65 })?);
66 }
67
68 let remote = Arc::new(Remote::new(config, Arc::new(Printer))?);
69 let _ = CLIENT.set(Arc::clone(&remote));
70 remote.start()?;
71
72 if let Some(target) = remote.target() {
73 println!("listening, sending to {target}. Ctrl-C to stop.");
74 }
75
76 let running = Arc::new(AtomicBool::new(true));
77 let stop = Arc::clone(&running);
78 ctrl_c(move || stop.store(false, Ordering::Relaxed));
79 while running.load(Ordering::Relaxed) {
80 std::thread::sleep(Duration::from_millis(200));
81 }
82
83 let devices = remote.devices();
84 println!("\n{} device(s):", devices.len());
85 for device in devices {
86 Printer.on_device_update(device);
87 }
88
89 remote.close();
90 Ok(())
91}Sourcepub fn device(&self, uid: DeviceUid) -> Option<DeviceInfo>
pub fn device(&self, uid: DeviceUid) -> Option<DeviceInfo>
A snapshot of one device.
Examples found in repository?
28 fn on_device_update(&self, device: DeviceUid) {
29 let Some(remote) = CLIENT.get() else { return };
30 let Some(info) = remote.device(device) else {
31 return;
32 };
33 println!(
34 " {device} {:<16} {:<12} {:<16} protocol {:#04x}, {} bays{}",
35 info.model,
36 info.serial,
37 info.name,
38 info.supported_protocol,
39 info.bays.len(),
40 if info.online { "" } else { " (offline)" },
41 );
42 }Sourcepub fn device_by_serial(&self, serial: &str) -> Option<DeviceUid>
pub fn device_by_serial(&self, serial: &str) -> Option<DeviceUid>
The device with the given serial number.
Sourcepub fn resolve_device(&self, name: &str) -> Option<DeviceUid>
pub fn resolve_device(&self, name: &str) -> Option<DeviceUid>
Resolves a device from its dotted-hex identifier, falling back to a serial-number match.
Sourcepub fn bay(&self, uid: BayUid) -> Option<BayInfo>
pub fn bay(&self, uid: BayUid) -> Option<BayInfo>
A snapshot of one bay.
Examples found in repository?
44 fn on_bay_update(&self, bay: BayUid) {
45 let Some(remote) = CLIENT.get() else { return };
46 let Some(info) = remote.bay(bay) else { return };
47 println!(
48 " bay {} {:<16} {}",
49 bay.port,
50 info.user_name,
51 match info.signal_detected {
52 Some(true) => "signal",
53 _ => "no signal",
54 },
55 );
56 }Sourcepub fn bay_by_name(&self, device: DeviceUid, port_name: &str) -> Option<BayUid>
pub fn bay_by_name(&self, device: DeviceUid, port_name: &str) -> Option<BayUid>
The bay on device with the given port name, such as Output 1.
Sourcepub fn bay_by_stream_ip(&self, ip: Ipv4Addr, audio: bool) -> Option<BayUid>
pub fn bay_by_stream_ip(&self, ip: Ipv4Addr, audio: bool) -> Option<BayUid>
The source bay advertising the given multicast group, for the video or the audio stream.
Sourcepub fn v2ip_sources(&self, uid: DeviceUid) -> Option<Vec<V2ipStreamSources>>
pub fn v2ip_sources(&self, uid: DeviceUid) -> Option<Vec<V2ipStreamSources>>
The V2IP streams a device advertises.
Sourcepub fn v2ip_details(&self, uid: DeviceUid) -> Option<DeviceV2ipDetails>
pub fn v2ip_details(&self, uid: DeviceUid) -> Option<DeviceV2ipDetails>
A V2IP device’s own encoder configuration.
Sourcepub fn v2ip_sink(&self, uid: DeviceUid) -> Option<DeviceV2ipSink>
pub fn v2ip_sink(&self, uid: DeviceUid) -> Option<DeviceV2ipSink>
The streams a V2IP sink is subscribed to.
Sourcepub fn v2ip_stats(&self, uid: DeviceUid) -> Option<V2ipDeviceStats>
pub fn v2ip_stats(&self, uid: DeviceUid) -> Option<V2ipDeviceStats>
Transport statistics a V2IP device reports.
Sourcepub fn v2ip_tiling(&self, uid: DeviceUid) -> Option<V2ipTilingConfig>
pub fn v2ip_tiling(&self, uid: DeviceUid) -> Option<V2ipTilingConfig>
The video-wall tiling a V2IP device is configured for.
Sourcepub fn audio_endpoints(&self, uid: DeviceUid) -> Option<AudioEndpoints>
pub fn audio_endpoints(&self, uid: DeviceUid) -> Option<AudioEndpoints>
The audio endpoint tree a device exposes.
Sourcepub fn multiviewer_status(&self, uid: DeviceUid) -> Option<MultiviewerStatus>
pub fn multiviewer_status(&self, uid: DeviceUid) -> Option<MultiviewerStatus>
The multiviewer layout a device is showing.
Sourcepub fn dolby_settings(&self, uid: DeviceUid) -> Option<AmpDolbySettings>
pub fn dolby_settings(&self, uid: DeviceUid) -> Option<AmpDolbySettings>
An amplifier’s Dolby decoder settings.
Sourcepub fn pdu_state(&self, uid: DeviceUid) -> Option<PduState>
pub fn pdu_state(&self, uid: DeviceUid) -> Option<PduState>
A device’s power-distribution state.
Sourcepub fn rc_settings(&self, uid: DeviceUid) -> Option<RcSettings>
pub fn rc_settings(&self, uid: DeviceUid) -> Option<RcSettings>
A device’s remote-control settings.
Sourcepub fn network_status(&self, uid: DeviceUid) -> Vec<NetworkPortStatus>
pub fn network_status(&self, uid: DeviceUid) -> Vec<NetworkPortStatus>
Every network port a device reports, in port order.
Sourcepub fn topology(&self, uid: DeviceUid) -> Vec<TopologyEntry>
pub fn topology(&self, uid: DeviceUid) -> Vec<TopologyEntry>
The mesh topology a device reports.
Sourcepub fn firmware(&self, uid: DeviceUid) -> Vec<(FirmwareType, FirmwareVersion)>
pub fn firmware(&self, uid: DeviceUid) -> Vec<(FirmwareType, FirmwareVersion)>
Every firmware image a device reports a version for.