diff --git a/Cargo.lock b/Cargo.lock index d4125cd..8e9a0ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -41,6 +41,61 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + [[package]] name = "autocfg" version = "1.4.0" @@ -126,10 +181,17 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-targets", ] +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "core-foundation" version = "0.9.4" @@ -196,6 +258,29 @@ dependencies = [ "syn", ] +[[package]] +name = "env_filter" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + [[package]] name = "errno" version = "0.3.9" @@ -384,6 +469,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + [[package]] name = "iana-time-zone" version = "0.1.61" @@ -550,14 +641,23 @@ dependencies = [ name = "ielet3109-websocket-data-logger" version = "0.1.0" dependencies = [ + "anyhow", "chrono", "csv", + "env_logger", + "log", "serde", "serde_json", "tokio", "websockets", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itoa" version = "1.0.11" @@ -1102,7 +1202,7 @@ dependencies = [ "fastrand", "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1209,6 +1309,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "vcpkg" version = "0.2.15" diff --git a/Cargo.toml b/Cargo.toml index 96220bb..f13d0a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,11 @@ version = "0.1.0" edition = "2021" [dependencies] -chrono = "0.4.38" +anyhow = "1.0.93" +chrono = { version = "0.4.38", features = ["serde"] } csv = "1.3.1" +env_logger = "0.11.5" +log = "0.4.22" serde = { version = "1.0.215", features = ["derive"] } serde_json = "1.0.133" tokio = { version = "1.41.1", features = ["full"] } diff --git a/src/main.rs b/src/main.rs index e7a11a9..96030a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,80 @@ -fn main() { - println!("Hello, world!"); +use std::{ + path::{Path, PathBuf}, + time::{Duration, Instant}, +}; + +use chrono::{self, Utc}; +use log::*; +use serde::{self, Deserialize, Serialize}; +use websockets::WebSocket; + +#[derive(Serialize, Deserialize, Debug, Clone)] +struct ECGData { + value: f32, + time: chrono::DateTime, +} + +fn store_data(file_path: &Path, data: Vec) -> Result<(), anyhow::Error> { + let file = std::fs::File::create_new(file_path)?; + let mut writer = csv::Writer::from_writer(file); + + for entry in data { + writer.serialize(entry)?; + } + writer.flush()?; + + Ok(()) +} + +async fn get_ws_data( + uri: &str, + duration: std::time::Duration, +) -> Result, anyhow::Error> { + // Create a vector to hold our results + let mut data: Vec = Vec::with_capacity(2048); + + // Create the websockts connection + let mut ws = WebSocket::connect(uri).await?; + + // Get the current time and store data for the next n amount of seconds + let start_time = Instant::now(); + while start_time.elapsed() <= duration { + match ws.receive().await { + Ok(frame) => { + if let Some((frame_data, _, _)) = frame.into_text() { + debug!("Got text frame: {}", frame_data); + + let string_of_interest = &frame_data[7..15]; + debug!("Chopped frame data down to: {}", string_of_interest); + + let voltage: f32 = string_of_interest.parse::()?; + + data.push(ECGData { + value: voltage, + time: Utc::now(), + }) + } + } + Err(e) => { + error!("Websocket error when receiving: {:#?}", e); + } + } + } + ws.close(None).await?; + + Ok(data) +} + +#[tokio::main] +async fn main() -> anyhow::Result<(), anyhow::Error> { + ::env_logger::init(); + + info!("Hello, world!"); + + let data: Vec = get_ws_data("ws://192.168.128.50:81", Duration::from_secs(5)).await?; + + let output_path: PathBuf = Path::new(&format!("{}.csv", Utc::now().to_rfc3339())).to_path_buf(); + store_data(&output_path, data)?; + + Ok(()) }