Config additions, add racetimer
This commit is contained in:
parent
7759360045
commit
efb0bf0b08
@ -4,4 +4,6 @@ rssi_threshold = 100
|
|||||||
video_sources = [ "RX1", "RX2", "RX3" ]
|
video_sources = [ "RX1", "RX2", "RX3" ]
|
||||||
lap_sources = [ "RX1Lap", "RX2Lap", "RX3Lap" ]
|
lap_sources = [ "RX1Lap", "RX2Lap", "RX3Lap" ]
|
||||||
laptime_sources = [ "RX1LapTime", "RX2LapTime", "RX3LapTime" ]
|
laptime_sources = [ "RX1LapTime", "RX2LapTime", "RX3LapTime" ]
|
||||||
|
race_status_source = "RaceStatus"
|
||||||
|
race_time_source = "RaceTime"
|
||||||
|
|
||||||
|
117
src/main.rs
117
src/main.rs
@ -9,6 +9,8 @@ use std::io::Write;
|
|||||||
use serde_derive::Deserialize;
|
use serde_derive::Deserialize;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
use tokio::net::udp::SendHalf;
|
use tokio::net::udp::SendHalf;
|
||||||
@ -21,6 +23,8 @@ use url::Url;
|
|||||||
struct Conf {
|
struct Conf {
|
||||||
filemode: bool,
|
filemode: bool,
|
||||||
rssi_threshold: i32,
|
rssi_threshold: i32,
|
||||||
|
race_status_source: String,
|
||||||
|
race_time_source: String,
|
||||||
|
|
||||||
video_sources: Vec<String>,
|
video_sources: Vec<String>,
|
||||||
lap_sources: Vec<String>,
|
lap_sources: Vec<String>,
|
||||||
@ -34,6 +38,26 @@ async fn rssi_timer(udpchanneltx: futures::channel::mpsc::UnboundedSender<String
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn race_timer(
|
||||||
|
wschannel: futures::channel::mpsc::UnboundedSender<Message>,
|
||||||
|
source: String,
|
||||||
|
race_timer_state: Arc<AtomicBool>,
|
||||||
|
) {
|
||||||
|
loop {
|
||||||
|
Delay::new(Duration::from_millis(100)).await;
|
||||||
|
let now = Instant::now();
|
||||||
|
while race_timer_state.load(Ordering::Relaxed) {
|
||||||
|
Delay::new(Duration::from_millis(200)).await;
|
||||||
|
let request = json!({"request-type":"SetTextFreetype2Properties", "source":source,"message-id": random::<f64>().to_string(), "text": now.elapsed().as_millis().to_string() });
|
||||||
|
wschannel
|
||||||
|
.unbounded_send(Message::Text(request.to_string()))
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
|
eprintln!("Could not send to OBS: {}", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn programm_to_udp(
|
async fn programm_to_udp(
|
||||||
mut udpchannelrx: futures::channel::mpsc::UnboundedReceiver<String>,
|
mut udpchannelrx: futures::channel::mpsc::UnboundedReceiver<String>,
|
||||||
mut udptx: SendHalf,
|
mut udptx: SendHalf,
|
||||||
@ -47,11 +71,12 @@ async fn programm_to_udp(
|
|||||||
|
|
||||||
async fn udp_comm(appconf: &Conf, senddata: futures::channel::mpsc::UnboundedSender<Message>) {
|
async fn udp_comm(appconf: &Conf, senddata: futures::channel::mpsc::UnboundedSender<Message>) {
|
||||||
let mut drone_active = vec![false, false, false, false, false, false]; // There ia a maximum os 6 receivers
|
let mut drone_active = vec![false, false, false, false, false, false]; // There ia a maximum os 6 receivers
|
||||||
|
let race_timer_state = Arc::new(AtomicBool::new(false));
|
||||||
|
let race_timer_state_clone = race_timer_state.clone();
|
||||||
// Setup the UDP Socket
|
// Setup the UDP Socket
|
||||||
let mut udpsocket = UdpSocket::bind("0.0.0.0:0").await.unwrap();
|
let mut udpsocket = UdpSocket::bind("0.0.0.0:0").await.unwrap();
|
||||||
udpsocket
|
udpsocket
|
||||||
.connect("192.168.0.141:9000")
|
.connect("127.0.0.1:9000") //192.168.0.141
|
||||||
.await
|
.await
|
||||||
.expect("could not connect to udp ");
|
.expect("could not connect to udp ");
|
||||||
|
|
||||||
@ -63,6 +88,11 @@ async fn udp_comm(appconf: &Conf, senddata: futures::channel::mpsc::UnboundedSen
|
|||||||
let (udpchanneltx, udpchannelrx) = futures::channel::mpsc::unbounded();
|
let (udpchanneltx, udpchannelrx) = futures::channel::mpsc::unbounded();
|
||||||
tokio::spawn(programm_to_udp(udpchannelrx, udptx));
|
tokio::spawn(programm_to_udp(udpchannelrx, udptx));
|
||||||
tokio::spawn(rssi_timer(udpchanneltx.clone()));
|
tokio::spawn(rssi_timer(udpchanneltx.clone()));
|
||||||
|
tokio::spawn(race_timer(
|
||||||
|
senddata.clone(),
|
||||||
|
appconf.race_time_source.clone(),
|
||||||
|
race_timer_state_clone,
|
||||||
|
));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut buf: [u8; 500] = [0; 500];
|
let mut buf: [u8; 500] = [0; 500];
|
||||||
@ -73,25 +103,34 @@ async fn udp_comm(appconf: &Conf, senddata: futures::channel::mpsc::UnboundedSen
|
|||||||
let result_str = String::from_utf8(display_result).unwrap();
|
let result_str = String::from_utf8(display_result).unwrap();
|
||||||
|
|
||||||
if result_str.contains("S0R1") {
|
if result_str.contains("S0R1") {
|
||||||
/*
|
race_timer_state_my.store(true, Ordering::Relaxed);
|
||||||
TODO: We should start the racecounter here
|
println!("Set race bool");
|
||||||
let source_id = "LAPTIME";
|
|
||||||
let request = json!({"request-type":"SetTextFreetype2Properties", "source":appconf.la,"message-id": random::<f64>().to_string(), "text": now.elapsed().as_millis().to_string() });
|
|
||||||
now = Instant::now();
|
|
||||||
senddata
|
|
||||||
.unbounded_send(Message::Text(request.to_string()))
|
|
||||||
.unwrap();
|
|
||||||
*/
|
|
||||||
if appconf.filemode {
|
if appconf.filemode {
|
||||||
write_file("Race active".to_string(), "racestate.txt");
|
write_file("Race active".to_string(), "racestate.txt");
|
||||||
write_file("0".to_string(), "rx1.txt");
|
write_file("0".to_string(), "rx1.txt");
|
||||||
write_file("0".to_string(), "rx2.txt");
|
write_file("0".to_string(), "rx2.txt");
|
||||||
write_file("0".to_string(), "rx3.txt");
|
write_file("0".to_string(), "rx3.txt");
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
set_obs_text(
|
||||||
|
&senddata,
|
||||||
|
&appconf.race_status_source,
|
||||||
|
&"Race inactive".to_string(),
|
||||||
|
);
|
||||||
|
for i in 0..2 {
|
||||||
|
set_obs_text(&senddata, &appconf.lap_sources[i], &"0".to_string());
|
||||||
|
}
|
||||||
|
*/
|
||||||
} else if result_str.contains("S0R0") {
|
} else if result_str.contains("S0R0") {
|
||||||
|
race_timer_state_my.store(false, Ordering::Relaxed);
|
||||||
if appconf.filemode {
|
if appconf.filemode {
|
||||||
write_file("Race inactive".to_string(), "racestate.txt");
|
write_file("Race inactive".to_string(), "racestate.txt");
|
||||||
}
|
}
|
||||||
|
set_obs_text(
|
||||||
|
&senddata,
|
||||||
|
&appconf.race_status_source,
|
||||||
|
&"Race inactive".to_string(),
|
||||||
|
);
|
||||||
} else if result_str.contains("S0r") {
|
} else if result_str.contains("S0r") {
|
||||||
//S0r004A\nS1r0044\nS2r0044
|
//S0r004A\nS1r0044\nS2r0044
|
||||||
let rxes = result_str.split("\n");
|
let rxes = result_str.split("\n");
|
||||||
@ -133,16 +172,21 @@ async fn udp_comm(appconf: &Conf, senddata: futures::channel::mpsc::UnboundedSen
|
|||||||
if appconf.filemode {
|
if appconf.filemode {
|
||||||
write_file(lap_seconds.to_string(), "rx1_laptime.txt");
|
write_file(lap_seconds.to_string(), "rx1_laptime.txt");
|
||||||
}
|
}
|
||||||
// TODO: LapTime to OBS!
|
set_obs_text(
|
||||||
|
&senddata,
|
||||||
|
&appconf.laptime_sources[0],
|
||||||
|
&lap_seconds.to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if let Ok(intval) = &result_str[3..5].parse::<i32>() {
|
if let Ok(intval) = &result_str[3..5].parse::<i32>() {
|
||||||
if appconf.filemode {
|
if appconf.filemode {
|
||||||
write_file((intval + 1).to_string(), "rx1.txt");
|
write_file((intval + 1).to_string(), "rx1.txt");
|
||||||
}
|
}
|
||||||
let request = json!({"request-type":"SetTextFreetype2Properties", "source":appconf.lap_sources[0],"message-id": random::<f64>().to_string(), "text": (intval + 1).to_string() });
|
set_obs_text(
|
||||||
senddata
|
&senddata,
|
||||||
.unbounded_send(Message::Text(request.to_string()))
|
&appconf.lap_sources[0],
|
||||||
.unwrap();
|
&(intval + 1).to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if result_str.contains("S1L") {
|
} else if result_str.contains("S1L") {
|
||||||
if let Ok(lap_time) = i64::from_str_radix(&result_str[5..13], 16) {
|
if let Ok(lap_time) = i64::from_str_radix(&result_str[5..13], 16) {
|
||||||
@ -150,16 +194,22 @@ async fn udp_comm(appconf: &Conf, senddata: futures::channel::mpsc::UnboundedSen
|
|||||||
if appconf.filemode {
|
if appconf.filemode {
|
||||||
write_file(lap_seconds.to_string(), "rx2_laptime.txt");
|
write_file(lap_seconds.to_string(), "rx2_laptime.txt");
|
||||||
}
|
}
|
||||||
|
set_obs_text(
|
||||||
|
&senddata,
|
||||||
|
&appconf.laptime_sources[1],
|
||||||
|
&lap_seconds.to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(intval) = &result_str[3..5].parse::<i32>() {
|
if let Ok(intval) = &result_str[3..5].parse::<i32>() {
|
||||||
if appconf.filemode {
|
if appconf.filemode {
|
||||||
write_file((intval + 1).to_string(), "rx2.txt");
|
write_file((intval + 1).to_string(), "rx2.txt");
|
||||||
}
|
}
|
||||||
let request = json!({"request-type":"SetTextFreetype2Properties", "source":appconf.lap_sources[1],"message-id": random::<f64>().to_string(), "text": (intval + 1).to_string() });
|
set_obs_text(
|
||||||
senddata
|
&senddata,
|
||||||
.unbounded_send(Message::Text(request.to_string()))
|
&appconf.lap_sources[1],
|
||||||
.unwrap();
|
&(intval + 1).to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if result_str.contains("S2L") {
|
} else if result_str.contains("S2L") {
|
||||||
if let Ok(lap_time) = i64::from_str_radix(&result_str[5..13], 16) {
|
if let Ok(lap_time) = i64::from_str_radix(&result_str[5..13], 16) {
|
||||||
@ -167,16 +217,22 @@ async fn udp_comm(appconf: &Conf, senddata: futures::channel::mpsc::UnboundedSen
|
|||||||
if appconf.filemode {
|
if appconf.filemode {
|
||||||
write_file(lap_seconds.to_string(), "rx3_laptime.txt");
|
write_file(lap_seconds.to_string(), "rx3_laptime.txt");
|
||||||
}
|
}
|
||||||
|
set_obs_text(
|
||||||
|
&senddata,
|
||||||
|
&appconf.laptime_sources[2],
|
||||||
|
&lap_seconds.to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(intval) = &result_str[3..5].parse::<i32>() {
|
if let Ok(intval) = &result_str[3..5].parse::<i32>() {
|
||||||
if appconf.filemode {
|
if appconf.filemode {
|
||||||
write_file((intval + 1).to_string(), "rx3.txt");
|
write_file((intval + 1).to_string(), "rx3.txt");
|
||||||
}
|
}
|
||||||
let request = json!({"request-type":"SetTextFreetype2Properties", "source":appconf.lap_sources[2],"message-id": random::<f64>().to_string(), "text": (intval + 1).to_string() });
|
set_obs_text(
|
||||||
senddata
|
&senddata,
|
||||||
.unbounded_send(Message::Text(request.to_string()))
|
&appconf.lap_sources[2],
|
||||||
.unwrap();
|
&(intval + 1).to_string(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
println!("Received unknown message from Chorus: {:?}", result_str);
|
println!("Received unknown message from Chorus: {:?}", result_str);
|
||||||
@ -292,3 +348,16 @@ async fn main() {
|
|||||||
println!("Programm initialized!");
|
println!("Programm initialized!");
|
||||||
udp_comm(&appconf, obstx).await;
|
udp_comm(&appconf, obstx).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_obs_text(
|
||||||
|
wschannel: &futures::channel::mpsc::UnboundedSender<Message>,
|
||||||
|
source: &String,
|
||||||
|
text: &String,
|
||||||
|
) {
|
||||||
|
let request = json!({"request-type":"SetTextFreetype2Properties", "source":source,"message-id": random::<f64>().to_string(), "text": text });
|
||||||
|
wschannel
|
||||||
|
.unbounded_send(Message::Text(request.to_string()))
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
|
eprintln!("Could not send to OBS: {}", err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user