Refactor Models for InfluxDB (#1)
Update to InfluxDB 2.0 and update all interfaces to work with it. MAC has been deprecated, since current `influxdb2` doesn't support non built-in types for read/write into the DB. Co-authored-by: Felipe Diniello <felipediniello@pm.me> Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
76
kairo-common/src/models/antenna.rs
Normal file
76
kairo-common/src/models/antenna.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use std::f64::consts::PI;
|
||||
|
||||
use crate::{unit_conversion::UnitsConversion, Point};
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct Antenna {
|
||||
pub id: String,
|
||||
pub tssi: f64,
|
||||
pub coord: Point,
|
||||
pub comment: Option<String>,
|
||||
}
|
||||
|
||||
impl Antenna {
|
||||
const C: f64 = 2.99e8;
|
||||
const F: f64 = 2.4e9;
|
||||
const λ: f64 = Self::C / Self::F;
|
||||
|
||||
pub fn new(id: &str, tssi: f64, coord: Point) -> Antenna {
|
||||
Antenna {
|
||||
id: id.into(),
|
||||
comment: None,
|
||||
coord,
|
||||
tssi,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_rssi(&self, distance: f64) -> f64 {
|
||||
#[allow(non_snake_case)]
|
||||
// Free Space Path Loss
|
||||
let FSPL = (((distance * 4.0 * PI) / Self::λ).powi(2)).to_dB();
|
||||
self.tssi - FSPL
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn get_distance_with_dBm(&self, rssi_dBm: f64) -> f64 {
|
||||
let loss = self.tssi.dBm_to_W() / rssi_dBm.dBm_to_W();
|
||||
let distance = (loss.sqrt() * Self::λ) / (4.0 * PI);
|
||||
distance.abs()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
pub fn get_distance_with_W(&self, rssi_W: f64) -> f64 {
|
||||
let loss = self.tssi.dBm_to_W() / rssi_W;
|
||||
let distance = (loss.sqrt() * Self::λ) / (4.0 * PI);
|
||||
distance.abs()
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let tssi = 0.0; // dBm
|
||||
let a = Antenna::new("AB:CD:EF:12:34:56", tssi, Point { x: 0.0, y: 0.0 });
|
||||
|
||||
// Known Attenuation values for 2.4GHz
|
||||
// 5 meter = 54.02 dB = 3.96e-9 W
|
||||
// 10 meter = 60.04 dB = 9.91e-10 W
|
||||
// 20 meter = 66.06 dB = 2.48e-10 W
|
||||
|
||||
print!("Testing Antenna::get_rssi()");
|
||||
assert!(f64::abs(-54.02 - a.get_rssi(5.0)) < 0.1);
|
||||
assert!(f64::abs(-60.04 - a.get_rssi(10.0)) < 0.1);
|
||||
assert!(f64::abs(-66.06 - a.get_rssi(20.0)) < 0.1);
|
||||
println!(" ... ok");
|
||||
|
||||
print!("Testing Antenna::get_distance_with_dBm()");
|
||||
assert!(f64::abs(5.0 - a.get_distance_with_dBm(-54.02)) < 0.5);
|
||||
assert!(f64::abs(10.0 - a.get_distance_with_dBm(-60.04)) < 0.5);
|
||||
assert!(f64::abs(20.0 - a.get_distance_with_dBm(-66.06)) < 0.5);
|
||||
println!(" ... ok");
|
||||
|
||||
print!("Testing Antenna::get_distance_with_W()");
|
||||
assert!(f64::abs(5.0 - a.get_distance_with_W(3.98e-9)) < 0.5);
|
||||
assert!(f64::abs(10.0 - a.get_distance_with_W(9.91e-10)) < 0.5);
|
||||
assert!(f64::abs(20.0 - a.get_distance_with_W(2.48e-10)) < 0.5);
|
||||
println!(" ... ok");
|
||||
}
|
||||
68
kairo-common/src/models/beacon_measure.rs
Normal file
68
kairo-common/src/models/beacon_measure.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use influxdb2_derive::{FromDataPoint, WriteDataPoint};
|
||||
|
||||
#[derive(
|
||||
Debug, Default, PartialEq, Clone, Serialize, Deserialize, FromDataPoint, WriteDataPoint,
|
||||
)]
|
||||
#[measurement = "beacon_measures"]
|
||||
pub struct BeaconMeasure {
|
||||
#[influxdb(tag)]
|
||||
pub device_id: String,
|
||||
#[influxdb(tag)]
|
||||
pub beacon_id: String,
|
||||
pub rssi: f64,
|
||||
#[influxdb(timestamp)]
|
||||
pub time: i64,
|
||||
}
|
||||
|
||||
impl BeaconMeasure {
|
||||
#[allow(non_snake_case)]
|
||||
pub fn new(device_id: &str, beacon_id: &str, rssi_W: f64) -> BeaconMeasure {
|
||||
BeaconMeasure {
|
||||
device_id: device_id.into(),
|
||||
beacon_id: beacon_id.to_owned(),
|
||||
rssi: rssi_W,
|
||||
time: chrono::Utc::now().timestamp_nanos(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::influx::{Bucket, Client};
|
||||
use crate::BeaconMeasure;
|
||||
|
||||
#[tokio::test]
|
||||
async fn influx_test() {
|
||||
let device_id = String::from("AB:CD:EF:01:23:45");
|
||||
let beacon_id = String::from("01:23:45:AB:CD:EF");
|
||||
let rssi_w = 0.001;
|
||||
|
||||
let bm = BeaconMeasure::new(&device_id, &beacon_id, rssi_w);
|
||||
|
||||
let res = Client::get()
|
||||
.write(Bucket::Tmp, futures::stream::iter([bm]))
|
||||
.await;
|
||||
assert!(res.is_ok());
|
||||
|
||||
let query = format!(
|
||||
"
|
||||
|> range(start: -1s)
|
||||
|> filter(fn: (r) => r[\"_measurement\"] == \"beacon_measures\")
|
||||
|> filter(fn: (r) => r[\"beacon_id\"] == \"{}\" )
|
||||
",
|
||||
beacon_id
|
||||
);
|
||||
|
||||
let r = Client::get()
|
||||
.query::<BeaconMeasure>(Bucket::Tmp, query)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert!(r.len() > 0);
|
||||
assert_eq!(r[0].beacon_id, beacon_id);
|
||||
assert_eq!(r[0].device_id, device_id);
|
||||
assert_eq!(r[0].rssi, rssi_w);
|
||||
}
|
||||
}
|
||||
10
kairo-common/src/models/dynamic_device_status.rs
Normal file
10
kairo-common/src/models/dynamic_device_status.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
|
||||
pub struct DynamicDeviceStatus {
|
||||
id: String,
|
||||
pos_x: f64,
|
||||
pos_y: f64,
|
||||
pos_z: f64,
|
||||
speed_x: f64,
|
||||
speed_y: f64,
|
||||
pub last_seen: chrono::DateTime<chrono::Utc>,
|
||||
}
|
||||
31
kairo-common/src/models/known_position.rs
Normal file
31
kairo-common/src/models/known_position.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use influxdb2_derive::{FromDataPoint, WriteDataPoint};
|
||||
|
||||
use crate::Point;
|
||||
|
||||
#[derive(
|
||||
Debug, Default, PartialEq, Clone, Serialize, Deserialize, FromDataPoint, WriteDataPoint,
|
||||
)]
|
||||
#[measurement = "known_positions"]
|
||||
pub struct KnownPosition {
|
||||
#[influxdb(tag)]
|
||||
pub id: String,
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
pub z: f64,
|
||||
#[influxdb(timestamp)]
|
||||
pub time: i64,
|
||||
}
|
||||
|
||||
impl KnownPosition {
|
||||
pub fn new(device_id: &str, pos: Point) -> KnownPosition {
|
||||
KnownPosition {
|
||||
id: device_id.into(),
|
||||
time: chrono::Utc::now().timestamp_nanos(),
|
||||
x: pos.x,
|
||||
y: pos.y,
|
||||
z: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
9
kairo-common/src/models/mod.rs
Normal file
9
kairo-common/src/models/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
pub mod antenna;
|
||||
pub mod beacon_measure;
|
||||
pub mod dynamic_device_status;
|
||||
pub mod known_position;
|
||||
|
||||
#[derive(Debug, serde::Serialize, serde::Deserialize)]
|
||||
pub struct DeviceReport {
|
||||
pub data: Vec<crate::models::beacon_measure::BeaconMeasure>,
|
||||
}
|
||||
Reference in New Issue
Block a user