Streaming data works!

This commit is contained in:
Sebastian H. Gabrielli 2024-11-18 16:45:46 +01:00
parent 4498d914ad
commit e766b560c7
3 changed files with 34 additions and 19 deletions

View File

@ -52,12 +52,8 @@ fn random_data() -> Vec<ECGData> {
data data
} }
#[tauri::command] fn create_data_listener(websockets_uri: String, data: Arc<Mutex<Vec<ECGData>>>) {
fn create_data_listener(websockets_uri: String, app: tauri::AppHandle) {
tokio::spawn(async move { tokio::spawn(async move {
// Variable to hold the ECG data
let mut ecg_data: Vec<ECGData> = Vec::with_capacity(2 ^ 16);
// Create the websockts connection // Create the websockts connection
let mut ws = match websockets::WebSocket::connect(websockets_uri.as_str()).await { let mut ws = match websockets::WebSocket::connect(websockets_uri.as_str()).await {
Ok(k) => k, Ok(k) => k,
@ -83,12 +79,15 @@ fn create_data_listener(websockets_uri: String, app: tauri::AppHandle) {
debug!("Got ECG voltage: {}", voltage); debug!("Got ECG voltage: {}", voltage);
// Filter out so we discard ol data let mut ecg_data = data.lock().expect("Failed to get lock");
ecg_data = ecg_data
// Filter out so we discard old data
*ecg_data = ecg_data
.clone()
.into_iter() .into_iter()
.filter(|data| { .filter(|data| {
Utc::now().signed_duration_since(data.timestamp) Utc::now().signed_duration_since(data.timestamp)
<= Duration::seconds(10) <= Duration::seconds(5)
}) })
.collect(); .collect();
@ -97,8 +96,7 @@ fn create_data_listener(websockets_uri: String, app: tauri::AppHandle) {
timestamp: Utc::now(), timestamp: Utc::now(),
}); });
app.emit("ecg-data", ecg_data.clone()) drop(ecg_data);
.expect("Failed to emit app event");
} }
} }
Err(e) => { Err(e) => {
@ -109,17 +107,25 @@ fn create_data_listener(websockets_uri: String, app: tauri::AppHandle) {
}); });
} }
#[tauri::command]
async fn get_ecg_data(data: State<'_, Arc<Mutex<Vec<ECGData>>>>) -> Result<Vec<ECGData>, Error> {
Ok(data.lock().expect("Failed to get lock").clone())
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
::env_logger::init(); ::env_logger::init();
// Variable to hold the ECG data
let ecg_data: Arc<Mutex<Vec<ECGData>>> = Arc::new(Mutex::new(Vec::with_capacity(2 ^ 13)));
// Create the websockets listener
create_data_listener("ws://192.168.128.50:81".to_string(), ecg_data.clone());
tauri::Builder::default() tauri::Builder::default()
.plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![greet, random_data, get_ecg_data])
greet, .manage(ecg_data)
random_data,
create_data_listener
])
.run(tauri::generate_context!()) .run(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application");
} }

View File

@ -3,6 +3,7 @@
// Check out https://vuejs.org/api/sfc-script-setup.html#script-setup // Check out https://vuejs.org/api/sfc-script-setup.html#script-setup
import Greet from "./components/Greet.vue"; import Greet from "./components/Greet.vue";
import Graph from "./components/Graph.vue"; import Graph from "./components/Graph.vue";
/*
import { invoke } from "@tauri-apps/api/core"; import { invoke } from "@tauri-apps/api/core";
import { onMounted } from "vue"; import { onMounted } from "vue";
@ -11,6 +12,7 @@ onMounted(async () => {
websocketsUri: "ws://192.168.128.50:81", websocketsUri: "ws://192.168.128.50:81",
}); });
}); });
*/
</script> </script>
<template> <template>

View File

@ -36,7 +36,7 @@ export default {
data: [], // Initial data data: [], // Initial data
fill: false, // Set to true if you want the area under the line to be filled fill: false, // Set to true if you want the area under the line to be filled
borderColor: "blue", // Set the line color borderColor: "blue", // Set the line color
tension: 0.1, // Adjust the tension for smoothness //tension: 0.1, // Adjust the tension for smoothness
}, },
], ],
}); });
@ -58,10 +58,13 @@ export default {
}, },
}, },
}, },
animation: {
duration: 0,
},
}; };
const updateData = async () => { const updateData = async () => {
const my_data = await invoke("random_data"); const my_data = await invoke("get_ecg_data");
const values = my_data.map((point: { value: number }) => point.value); const values = my_data.map((point: { value: number }) => point.value);
const timestamps = my_data.map( const timestamps = my_data.map(
@ -76,7 +79,8 @@ export default {
data: values, // Access the data property data: values, // Access the data property
fill: false, // Set to true if you want the area under the line to be filled fill: false, // Set to true if you want the area under the line to be filled
borderColor: "green", // Set the line color borderColor: "green", // Set the line color
tension: 0.1, // Adjust the tension for smoothness //tension: 0.1, // Adjust the tension for smoothness
pointRadius: 0.0, // Remove the dots from the graph
}, },
], ],
}; };
@ -112,6 +116,10 @@ export default {
onMounted(async () => { onMounted(async () => {
// Set up the event listener // Set up the event listener
unlisten = await listen("ecg-data", handleEcgData); unlisten = await listen("ecg-data", handleEcgData);
setInterval(() => {
updateData();
}, 10);
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
@ -132,5 +140,4 @@ export default {
<template> <template>
<Line id="my-chart-id" :options="chartOptions" :data="chartData" /> <Line id="my-chart-id" :options="chartOptions" :data="chartData" />
<button @click="updateData">Click me</button>
</template> </template>