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_source_addr(
&self,
sink: BayUid,
route: V2ipRoute,
format: Option<V2ipAudioFormat>,
) -> Result<(), ControlError>
pub fn select_source_addr( &self, sink: BayUid, route: V2ipRoute, format: Option<V2ipAudioFormat>, ) -> Result<(), ControlError>
Routes this V2IP sink’s video, audio and ancillary streams to multicast groups the caller names.
This is the only way to reach a stream no device on the mesh advertises, such as one the host is transmitting itself; a route by source port can only name a stream some bay has announced.
Set all three groups. The firmware decides whether a sink has a manual route by looking at the video and ancillary groups, so a route that leaves either unset does not register as one and the sink falls back to the audio source its mesh picks.
An unset format sends V2ipAudioFormat::STANDARD rather than
omitting the trailer. The firmware stores whatever this frame carries
and hands it to the FPGA unexamined, so a frame without one leaves a
zero rate and zero channel count there, which the FPGA rejects and
which takes the switch down with it.
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 send_key(&self, bay: BayUid, key: RcKey) -> Result<(), ControlError>
pub fn send_key(&self, bay: BayUid, key: RcKey) -> Result<(), ControlError>
Sends a remote-control key press to whatever is attached to a bay.
The device forwards it over CEC, infrared or IP, whichever that bay is
configured for; the caller does not choose. An action from
Remote::send_action names an outcome instead, and the device
decides which keys reach it.
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.
There is no free-running mode: a device reports only while a subscription is live, at 1Hz, and the subscription lapses after a minute. A caller that wants a continuous feed re-sends inside the minute; nothing here re-arms it.
Reports reach crate::EventHandler::on_v2ip_stats_changed and read
back through Remote::v2ip_stats. A device new enough to send it also
carries what the sink’s decoder recovered, in
crate::V2ipDeviceStats::decoder.
Sourcepub fn request_edid(
&self,
device: DeviceUid,
output: bool,
) -> Result<(), ControlError>
pub fn request_edid( &self, device: DeviceUid, output: bool, ) -> Result<(), ControlError>
Asks a device for an EDID: the one the display on its output publishes, or the one it presents to the source on its input.
The device answers with a frame the receive path decodes, so the bytes
arrive at crate::EventHandler::on_edid_received and stay readable
through Remote::edid.
Only V2IP hardware handles this opcode. A matrix or an amplifier accepts the frame and answers nothing, at any protocol version, so the silence that follows is permanent rather than a reply still to come. This call cannot tell the two apart and does not try: it reports what was sent, and a caller polling for an EDID should ask a device that can answer rather than wait on one that cannot.
Sourcepub fn request_signal_status(
&self,
device: Option<DeviceUid>,
) -> Result<(), ControlError>
pub fn request_signal_status( &self, device: Option<DeviceUid>, ) -> Result<(), ControlError>
Asks for a detailed signal report from every bay of one device, or - with no device named - from every bay on the network.
Devices report on their own when a signal changes, so this is what a client that has just started needs: without it, a bay that has been showing the same picture for an hour says nothing until it changes.
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 preview_video_wall(
&self,
sink: DeviceUid,
window: VideoWallWindow,
) -> Result<(), ControlError>
pub fn preview_video_wall( &self, sink: DeviceUid, window: VideoWallWindow, ) -> Result<(), ControlError>
Shows a window on a sink’s video wall without persisting it.
The window survives until the sink is told otherwise or restarts.
Remote::revert_video_wall puts back whatever was stored.
Pass crate::VIDEO_WALL_CLEARED to show the whole frame again.
Sourcepub fn store_video_wall(
&self,
sink: DeviceUid,
window: VideoWallWindow,
) -> Result<(), ControlError>
pub fn store_video_wall( &self, sink: DeviceUid, window: VideoWallWindow, ) -> Result<(), ControlError>
Persists a window as a sink’s video wall.
The geometry is checked here, before anything is sent, because the sink is not guaranteed to check it. A sink running a video-wall module older than 2026083100 writes the window to its configuration before asking its video processor to apply it, and the processor’s refusal does not undo that write - so an out-of-spec window survives a reboot and is re-offered on every stream restart until something else replaces it. A power cycle does not clear it.
Nothing acknowledges this frame either way, so an Ok says only that
it was sent. Read the sink’s state back to learn what it did.
Pass crate::VIDEO_WALL_CLEARED to store “show the whole frame”.
Sourcepub fn revert_video_wall(&self, sink: DeviceUid) -> Result<(), ControlError>
pub fn revert_video_wall(&self, sink: DeviceUid) -> Result<(), ControlError>
Restores the window a sink has stored, discarding a preview.
Carries no window of its own: the sink already holds the one this puts back.
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, counting windows from zero.
A window index the multiviewer is not currently showing is refused rather than sent: firmware accepts an index one past the last window and writes through the end of the array it indexes, so the frame that would carry it is the one frame this library must never put on the wire. The bound comes from the layout in the multiviewer’s last status report, so a multiviewer that has reported none can only be given window zero, which every layout has.
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, as a percentage, and the mute state.
A volume above 100 is refused rather than sent. What a multiviewer does with one depends on its module version: from 2026083100 it drops the whole frame, and before that it dropped the volume alone and still acted on the mute beside it. Neither is what the caller asked for, and neither is reported back.
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, counting inputs from zero.
DeviceUid::ZERO clears the mapping on a multiviewer running module
version 2026083100 or newer, and is stored as a mapping like any other
on anything older. No version checks that a mapping names a device on
the mesh.
Which of the two happened shows in mappings on a later status report,
where a cleared input reads as DeviceUid::ZERO only from that same
version. It will not be the next frame this multiviewer sends: this is
one of the two settings that schedule no status broadcast of their own,
so the answer arrives whenever something else prompts one.
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 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 edid(&self, uid: DeviceUid, output: bool) -> Option<Vec<u8>>
pub fn edid(&self, uid: DeviceUid, output: bool) -> Option<Vec<u8>>
The EDID a device last reported: the display on its output, or the one it presents to the source on its input.
Filled in by a device’s answer to Remote::request_edid, and by any
answer to a peer’s request that this client happened to hear.
Sourcepub fn frames_received(&self) -> u64
pub fn frames_received(&self) -> u64
How many frames from other senders have parsed since this client started.
It separates a mesh with nothing on it from an interface nothing is on:
a client that has discovered no device but is counting frames is
hearing traffic it cannot get answers from, which on a multi-homed host
is what a wrong Config::local_ip looks like. Frames this client
sent are not counted, because the host loops its own multicast back
whichever interface was selected.
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.