1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
//! # Roku ECP //! //! This crate provides a wrapper over the [Roku External Control //! Protocol](https://developer.roku.com/docs/developer-program/debugging/external-control-api.md) //! which enables a Roku device to be controlled over a local area network //! through a RESTful API. //! //! # Example Usage //! The crate is fairly straightforward since all relevant methods revolve //! around the [Device](crate::Device) struct. //! //! For a full code representation, view the [examples folder](https://github.com/Hermitter/roku-ecp-rs/tree/main/examples). //! ```ignore //! use roku_ecp::{Device, Key, SearchRequest, SearchType}; //! let roku = Device::new("192.168.1.138").unwrap(); // remember to change the IP. //! //! // Print information on the Roku device //! println!("{:?}", roku.device_info().await.unwrap()); //! //! // Press the play button //! roku.key_press(Key::Play).await.unwrap(); //! //! // Search for something //! let search = SearchRequest::new("The Mandalorian") //! .search_type(SearchType::TvShow) //! .season(2) //! //! roku.search(search).await.unwrap(); //! ``` //! //! # Features //! Currently Implemented: //! - Queries for device, media player, and app information. //! - Key press/down/up events for various [keys](crate::Key). //! - Launching/Installing Applications. //! - Searching through Roku's Search UI. //! //! Possible Features for the Future: //! - Scanning the local network for Roku devices. //! - Inputs for accelerometer, orientation, gyroscope, magnetometer, touch, //! and multi-touch. //! - Roku TV commands for queries and inputs. //! //! # Dependencies //! //! **Operating Systems** //! //! Windows and macOS: None //! //! Linux: OpenSSL + headers > v1.0.1 //! - Debian: `sudo apt install libssl-dev` //! - Fedora: `sudo dnf install openssl-devel` //! //! **Async Runtime** //! //! This crate requires an asynchronous runtime such as //! [tokio](https://github.com/tokio-rs/tokio) or //! [async-std](https://github.com/async-rs/async-std). //! //! pub use error::Error; use surf::Client; mod api; mod error; pub use api::keys::Key; pub use api::search::{SearchRequest, SearchType}; use url::Url; /// Default port for communicating with the ECP RESTful service. pub const ECP_PORT: u16 = 8060; /// An HTTP client that communicates with a Roku device. #[derive(Debug)] pub struct Device { /// Base URL of the Roku device's IP and port. url: url::Url, /// Http client for communicating with Roku device. http: Client, } impl Device { /// Create an HTTP client to communicate with a Roku device. This assumes /// the device URL is `http://ROKU_IP_HERE:8060`. pub fn new<T>(ip: T) -> Result<Device, Error> where T: std::net::ToSocketAddrs + std::fmt::Display, { Ok(Device { url: Url::parse(&format!("http://{}:{}", ip, ECP_PORT))?, http: Client::new(), }) } /// Creates an HTTP client with a specified URL to communicate with a Roku /// device. Use this if the default URL /// (`http://ROKU_IP_HERE:8060`) is not usable to you. pub fn from_url(url: &str) -> Result<Device, Error> { Ok(Device { url: Url::parse(url)?, http: Client::new(), }) } /// Pings the Roku device to check if the device is online. pub async fn ping(&self) -> Result<(), Error> { self.http.get(&self.url).send().await?; Ok(()) } }