commit 6088c11940f34735146be3bd2f044faa31b7522b
parent 24940929b64b27b5f7970e23792819449ae3aa7c
Author: MTRNord <mtrnord1@gmail.com>
Date: Thu, 5 Aug 2021 15:03:32 +0200
add multiple datarefs
Diffstat:
4 files changed, 89 insertions(+), 28 deletions(-)
diff --git a/Cargo.toml b/Cargo.toml
@@ -1,4 +1,4 @@
-cargo-features = ["edition2021"]
+cargo-features = ["edition2021","strip"]
[package]
name = "xplane-datamonitor"
@@ -14,6 +14,12 @@ crate-type = ["cdylib"]
xplm = "0.3.1"
anyhow = "1.0.42"
thiserror = "1.0.26"
+influxdb-client = "0.1.4"
+tokio = { version = "1", default-features = false, features = ["rt-multi-thread"] }
[profile.release]
-lto = true
-\ No newline at end of file
+codegen-units = 1
+opt-level = 'z'
+lto = true
+strip = true
+panic = 'abort'
+\ No newline at end of file
diff --git a/src/energy.rs b/src/energy.rs
@@ -7,6 +7,7 @@ use crate::error::Error;
pub(crate) struct EnergyRefs {
pub(crate) gpu_on: DataRef<bool, ReadWrite>,
pub(crate) battery: DataRef<[i32], ReadWrite>,
+ pub(crate) apu_on: DataRef<bool, ReadWrite>,
}
#[derive(Clone)]
@@ -20,6 +21,7 @@ impl Energy {
inner: Rc::new(EnergyRefs {
gpu_on: DataRef::find("sim/cockpit/electrical/gpu_on")?.writeable()?,
battery: DataRef::find("sim/cockpit2/electrical/battery_on")?.writeable()?,
+ apu_on: DataRef::find("sim/cockpit2/electrical/APU_generator_on")?.writeable()?,
}),
})
}
@@ -31,15 +33,20 @@ impl Energy {
pub(crate) fn battery_on(&self) -> bool {
self.inner.battery.as_vec().contains(&1)
}
+
+ pub(crate) fn apu_on(&self) -> bool {
+ self.inner.apu_on.get()
+ }
}
impl Display for Energy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
- "GPU enabled: {}, Battery enabled: {}",
- self.inner.gpu_on.get(),
- self.inner.battery.as_vec().contains(&1),
+ "GPU enabled: {}, Battery enabled: {}, APU Gen enabled: {}",
+ self.gpu_on(),
+ self.battery_on(),
+ self.apu_on(),
)
}
}
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,7 +1,11 @@
#[deny(unused_imports)]
#[deny(missing_docs)]
-use std::thread;
-use std::time::{Duration, SystemTime};
+use influxdb_client::{Client, Point, Precision, TimestampOptions};
+use std::{
+ sync::Arc,
+ time::{Duration, Instant, SystemTime, UNIX_EPOCH},
+};
+use tokio::runtime::{self, Runtime};
use xplm::{
debug,
flight_loop::{FlightLoop, FlightLoopCallback},
@@ -25,27 +29,50 @@ struct DataMonitorPlugin {
struct LoopHandler {
location: Location,
energy: Energy,
- last_run: SystemTime,
+ last_run: Instant,
+ start_time: SystemTime,
+ leg_started: bool,
+ influx: Arc<influxdb_client::Client>,
+ rt: Arc<Runtime>,
}
impl FlightLoopCallback for LoopHandler {
fn flight_loop(&mut self, state: &mut xplm::flight_loop::LoopState) {
- if self.last_run.elapsed().unwrap() >= Duration::from_secs(5) {
- let battery_on = self.energy.battery_on();
- let gpu_on = self.energy.gpu_on();
- let location = self.location.to_string();
- let energy = self.energy.to_string();
- let thread = thread::spawn(move || {
- // Do stuff with location
- if battery_on || gpu_on {
- debug(format!("[DATAMONITOR] {}\n", location));
- debug(format!("[DATAMONITOR] {}\n", energy));
- }
+ let battery_on = self.energy.battery_on();
+ let gpu_on = self.energy.gpu_on();
+ let apu_on = self.energy.apu_on();
+ if (battery_on || gpu_on || apu_on) && !self.leg_started {
+ // TODO reset on FP change
+ self.leg_started = true;
+ }
+ if self.last_run.elapsed() >= Duration::from_secs(1) && self.leg_started {
+ let latitude = self.location.lat();
+ let longitude = self.location.lon();
+ let altitude = self.location.alt();
+ let timestamp = self
+ .start_time
+ .duration_since(UNIX_EPOCH)
+ .expect("Time went backwards")
+ .as_secs() as i64;
+
+ let client = self.influx.clone();
+ self.rt.spawn(async move {
+ let location_point = Point::new("location")
+ .tag("start_time", timestamp)
+ .field("latitude", latitude)
+ .field("longitude", longitude)
+ .field("altitude_feet", altitude);
+ let status_point = Point::new("status")
+ .tag("start_time", timestamp)
+ .field("battery_on", battery_on)
+ .field("gpu_on", gpu_on)
+ .field("apu_on", apu_on);
+ let points = vec![&location_point, &status_point];
+ if let Err(e) = client.insert_points(points, TimestampOptions::None).await {
+ debug(format!("[DATAMONITOR][ERROR] Sending Points: {:#?}\n", e));
+ };
});
- if let Err(e) = thread.join() {
- debug(format!("[DATAMONITOR][ERROR] {:?}\n", e));
- }
- self.last_run = SystemTime::now();
+ self.last_run = Instant::now();
}
state.call_next_loop()
}
@@ -74,10 +101,25 @@ impl Plugin for DataMonitorPlugin {
debug(format!("[DATAMONITOR][ERROR] Energy init: {:?}\n", e));
}
+ let influx_client = Client::new("http://10.0.0.1:8086",
+ "wuL5_5sg_zlaQdkDWhmiFZ9r-Fx1rWgNR407czXOeQmYU1PHlp0nwpmjjW270PzEgEctx0AqD_K7K-h9Ein6Pg==")
+ .with_org("Nordgedanken")
+ .with_bucket("flightdata")
+ .with_precision(Precision::MS);
+
+ let rt = runtime::Runtime::new();
+ if let Err(ref e) = rt {
+ debug(format!("[DATAMONITOR][ERROR] Creating runtime: {:#?}\n", e));
+ }
+
let loophandler = LoopHandler {
location: location.unwrap(),
energy: energy.unwrap(),
- last_run: SystemTime::now(),
+ last_run: Instant::now(),
+ influx: Arc::new(influx_client),
+ start_time: SystemTime::now(),
+ leg_started: false,
+ rt: Arc::new(rt.unwrap()),
};
let plugin = DataMonitorPlugin {
loophandler,
diff --git a/src/location.rs b/src/location.rs
@@ -7,6 +7,7 @@ use crate::error::Error;
pub(crate) struct LocationRefs {
pub(crate) latitude: DataRef<f64, ReadOnly>,
pub(crate) longitude: DataRef<f64, ReadOnly>,
+ pub(crate) altitude: DataRef<f32, ReadOnly>,
}
#[derive(Clone)]
@@ -20,6 +21,7 @@ impl Location {
inner: Rc::new(LocationRefs {
latitude: DataRef::find("sim/flightmodel/position/latitude")?,
longitude: DataRef::find("sim/flightmodel/position/longitude")?,
+ altitude: DataRef::find("sim/cockpit2/gauges/indicators/altitude_ft_pilot")?,
}),
})
}
@@ -30,15 +32,19 @@ impl Location {
pub(crate) fn lon(&self) -> f64 {
self.inner.longitude.get()
}
+ pub(crate) fn alt(&self) -> f64 {
+ self.inner.altitude.get() as f64
+ }
}
impl Display for Location {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
- "Latitude: {}, Longitude: {}",
- self.inner.latitude.get(),
- self.inner.longitude.get()
+ "Latitude: {}, Longitude: {}, Altitude: {}",
+ self.lat(),
+ self.lon(),
+ self.alt()
)
}
}