diff --git a/Cargo.toml b/Cargo.toml index 61520a8..ca0464a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ chrono = "0.4.26" config = "0.13.3" ctrlc = "3.4.0" env_logger = "0.10.0" +ether-dream = "0.2.5" helios-dac = { version = "0.1", default-features = false, features = ["native"] } log = "0.4.18" diff --git a/copyme.settings.toml b/copyme.settings.toml index 5f9eaff..19182bb 100644 --- a/copyme.settings.toml +++ b/copyme.settings.toml @@ -29,3 +29,8 @@ y = 2000 [[transformers]] [transformers.replicate] Until = 48 + +# Never remove this : this is mandatory +[[transformers]] +[transformers.intensity] + diff --git a/src/device.rs b/src/device.rs index c97276c..91027d8 100644 --- a/src/device.rs +++ b/src/device.rs @@ -1,6 +1,7 @@ mod helios; mod dummy; +mod etherdream; use std::fmt; use crate::conf::{Conf, DacFamily /*EtherDreamConf, HeliosConf*/}; @@ -35,7 +36,7 @@ impl fmt::Display for PlaybackState { } } -#[derive(Debug)] +#[derive(Debug, Default )] pub struct Status { pub last_traced_at: String, pub properties: Vec, diff --git a/src/device/etherdream.rs b/src/device/etherdream.rs new file mode 100644 index 0000000..fec964e --- /dev/null +++ b/src/device/etherdream.rs @@ -0,0 +1,108 @@ +use ether_dream::{dac}; + + + +use crate::conf::EtherDreamConf; +use crate::device::{Device, Status, PlaybackState}; +use crate::errors::{LJError, LJResult}; +use crate::point::Point; +use chrono::Utc; + +pub struct EtherdreamDevice { + pub conf: EtherDreamConf, + dac: dac, + sent_points: u16, + state: PlaybackState, + lack: String, + last_traced_at : String +} + +impl EtherdreamDevice { + pub fn new(conf: &EtherDreamConf) -> LJResult { + let id = conf.id; + + // // Todo : use the config + // let (dac_broadcast, source_addr) = ether_dream::recv_dac_broadcasts() + // .expect("failed to bind to UDP socket") + // .filter_map(Result::ok) + // .next() + // .unwrap(); + // let mac_address = dac::MacAddress(dac_broadcast.mac_address); + // + // println!( + // "Discovered DAC \"{}\" at \"{}\"! Connecting...", + // mac_address, source_addr + // ); + + + // Establish the TCP connection. + let mut stream = dac::stream::connect(&dac_broadcast, source_addr.ip().clone()).unwrap(); + + // If we want to create an animation (in our case a moving sine wave) we need a frame rate. + let frames_per_second = 60.0; + // Lets use the DAC at an eighth the maximum scan rate. + let points_per_second = stream.dac().max_point_rate / 32; + // Determine the number of points per frame given our target frame and point rates. + let points_per_frame = (points_per_second as f32 / frames_per_second) as u16; + + // Prepare the DAC's playback engine and await the repsonse. + stream + .queue_commands() + .prepare_stream() + .submit() + .err() + .map(|err| { + eprintln!( + "err occurred when submitting PREPARE_STREAM \ + command and listening for response: {}", + err + ); + }); + + println!("Ready for playback!"); + + Ok(Self { + conf: (*conf).clone(), + dac, + sent_points: 0, + state: PlaybackState::PREPARE, + lack: "".to_string(), + last_traced_at: "1985-04-12T23:20:50.52Z".to_string() + }) + } +} + +impl Device for EtherdreamDevice { + fn status(&self) -> Status { + + let lack = self.lack.clone(); + Status { + last_traced_at: self.last_traced_at.clone(), + properties: vec!["foo".to_string()], + playback_state: self.state, + capacity: self.sent_points, + lack, + } + } + + fn draw(&mut self, + line: Vec, + speed: u32, + ) -> LJResult<()> { + self.state = PlaybackState::IDLE; + while let Ok(DeviceStatus::NotReady) = self.dac.status() {} + self.state = PlaybackState::PLAYING; + + let points: Vec = line.into_iter().map(|p| p.into()).collect(); + let frame = Frame::new(speed, points.clone()); + self.dac.write_frame(frame.clone())?; + self.sent_points = points.len() as u16; + self.last_traced_at = Utc::now().to_rfc3339(); + Ok(()) + } + + fn stop(&mut self) -> LJResult<()> { + self.dac.stop()?; + Ok(()) + } +}