api: Rename time to gw_time. Add ns_time.

The gw_time defines the RX time by the gateway, the ns_time defines when
it was received by the NS. The latter could for example help to debug
latency between the GW <> NS.
This commit is contained in:
Orne Brocaar 2023-10-16 11:47:13 +01:00
parent 31ffb30201
commit b4845b5613
12 changed files with 34 additions and 21 deletions

View File

@ -317,10 +317,13 @@ message UplinkRxInfo {
// Uplink ID. // Uplink ID.
uint32 uplink_id = 2; uint32 uplink_id = 2;
// RX time (only set when the gateway has a GPS module). // Gateway RX time (set if the gateway has a GNSS module).
google.protobuf.Timestamp time = 3; google.protobuf.Timestamp gw_time = 3;
// RX time since GPS epoch (only set when the gateway has a GPS module). // Network Server RX time (set by the NS on receiving the uplink).
google.protobuf.Timestamp ns_time = 17;
// RX time as time since GPS epoch (set if the gateway has a GNSS module).
google.protobuf.Duration time_since_gps_epoch = 4; google.protobuf.Duration time_since_gps_epoch = 4;
// Fine-timestamp. // Fine-timestamp.

View File

@ -317,10 +317,13 @@ message UplinkRxInfo {
// Uplink ID. // Uplink ID.
uint32 uplink_id = 2; uint32 uplink_id = 2;
// RX time (only set when the gateway has a GPS module). // Gateway RX time (set if the gateway has a GNSS module).
google.protobuf.Timestamp time = 3; google.protobuf.Timestamp gw_time = 3;
// RX time since GPS epoch (only set when the gateway has a GPS module). // Network Server RX time (set by the NS on receiving the uplink).
google.protobuf.Timestamp ns_time = 17;
// RX time as time since GPS epoch (set if the gateway has a GNSS module).
google.protobuf.Duration time_since_gps_epoch = 4; google.protobuf.Duration time_since_gps_epoch = 4;
// Fine-timestamp. // Fine-timestamp.
@ -368,7 +371,7 @@ message DownlinkTxInfoLegacy {
// TX frequency (in Hz). // TX frequency (in Hz).
uint32 frequency = 5; uint32 frequency = 5;
// TX power (in dBm). // TX power (in dBm EIRP).
int32 power = 6; int32 power = 6;
// Modulation. // Modulation.
@ -411,7 +414,7 @@ message DownlinkTxInfo {
// TX frequency (in Hz). // TX frequency (in Hz).
uint32 frequency = 1; uint32 frequency = 1;
// TX power (in dBm). // TX power (in dBm EIRP).
int32 power = 2; int32 power = 2;
// Modulation. // Modulation.

View File

@ -106,6 +106,10 @@ message DeviceSession {
DeviceSession pending_rejoin_device_session = 29; DeviceSession pending_rejoin_device_session = 29;
// Uplink history for ADR (last 20 uplink transmissions). // Uplink history for ADR (last 20 uplink transmissions).
// This table is reset in case one of parameters has changed:
// * DR
// * TxPower
// * NbTrans
repeated UplinkAdrHistory uplink_adr_history = 30; repeated UplinkAdrHistory uplink_adr_history = 30;
// Mac-command error count. // Mac-command error count.

3
api/rust/src/gw.rs vendored
View File

@ -117,7 +117,8 @@ impl UplinkFrame {
self.rx_info = Some(UplinkRxInfo { self.rx_info = Some(UplinkRxInfo {
gateway_id: hex::encode(&rx_info.gateway_id), gateway_id: hex::encode(&rx_info.gateway_id),
uplink_id: rng.gen::<u32>(), uplink_id: rng.gen::<u32>(),
time: rx_info.time.clone(), gw_time: rx_info.time.clone(),
ns_time: None,
time_since_gps_epoch: rx_info.time_since_gps_epoch.clone(), time_since_gps_epoch: rx_info.time_since_gps_epoch.clone(),
fine_time_since_gps_epoch: None, fine_time_since_gps_epoch: None,
rssi: rx_info.rssi, rssi: rx_info.rssi,

View File

@ -8,6 +8,7 @@ use std::time::Duration;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use async_trait::async_trait; use async_trait::async_trait;
use chrono::Utc;
use futures::stream::StreamExt; use futures::stream::StreamExt;
use handlebars::Handlebars; use handlebars::Handlebars;
use paho_mqtt as mqtt; use paho_mqtt as mqtt;
@ -374,6 +375,7 @@ async fn message_callback(
if let Some(rx_info) = &mut event.rx_info { if let Some(rx_info) = &mut event.rx_info {
set_gateway_json(&rx_info.gateway_id, json); set_gateway_json(&rx_info.gateway_id, json);
rx_info.ns_time = Some(Utc::now().into());
rx_info rx_info
.metadata .metadata
.insert("region_config_id".to_string(), region_config_id.to_string()); .insert("region_config_id".to_string(), region_config_id.to_string());

View File

@ -46,7 +46,7 @@ pub async fn get_geoloc_buffer(
.iter() .iter()
.cloned() .cloned()
.filter(|rx_info| { .filter(|rx_info| {
let ts: DateTime<Utc> = match &rx_info.time { let ts: DateTime<Utc> = match &rx_info.gw_time {
None => { None => {
return false; return false;
} }

View File

@ -115,7 +115,7 @@ pub mod test {
}, },
tx_info: Default::default(), tx_info: Default::default(),
rx_info_set: vec![gw::UplinkRxInfo { rx_info_set: vec![gw::UplinkRxInfo {
time: Some(rx_time.into()), gw_time: Some(rx_time.into()),
..Default::default() ..Default::default()
}], }],
gateway_private_up_map: HashMap::new(), gateway_private_up_map: HashMap::new(),

View File

@ -65,7 +65,7 @@ pub mod test {
}, },
tx_info: Default::default(), tx_info: Default::default(),
rx_info_set: vec![gw::UplinkRxInfo { rx_info_set: vec![gw::UplinkRxInfo {
time: Some(rx_time.into()), gw_time: Some(rx_time.into()),
..Default::default() ..Default::default()
}], }],
gateway_private_up_map: HashMap::new(), gateway_private_up_map: HashMap::new(),

View File

@ -61,7 +61,7 @@ async fn test_fns_uplink() {
let mut rx_info = gw::UplinkRxInfo { let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(), gateway_id: gw.gateway_id.to_string(),
time: Some(recv_time.into()), gw_time: Some(recv_time.into()),
location: Some(common::Location { location: Some(common::Location {
latitude: 0.0, latitude: 0.0,
longitude: 0.0, longitude: 0.0,
@ -296,7 +296,7 @@ async fn test_sns_uplink() {
let mut rx_info = gw::UplinkRxInfo { let mut rx_info = gw::UplinkRxInfo {
gateway_id: "0302030405060708".to_string(), gateway_id: "0302030405060708".to_string(),
time: Some(recv_time.into()), gw_time: Some(recv_time.into()),
..Default::default() ..Default::default()
}; };
rx_info rx_info
@ -464,7 +464,7 @@ async fn test_sns_dev_not_found() {
let mut rx_info = gw::UplinkRxInfo { let mut rx_info = gw::UplinkRxInfo {
gateway_id: "0302030405060708".to_string(), gateway_id: "0302030405060708".to_string(),
time: Some(recv_time.into()), gw_time: Some(recv_time.into()),
..Default::default() ..Default::default()
}; };
rx_info rx_info

View File

@ -70,7 +70,7 @@ async fn test_fns() {
let mut rx_info = gw::UplinkRxInfo { let mut rx_info = gw::UplinkRxInfo {
gateway_id: gw.gateway_id.to_string(), gateway_id: gw.gateway_id.to_string(),
time: Some(recv_time.into()), gw_time: Some(recv_time.into()),
location: Some(Default::default()), location: Some(Default::default()),
..Default::default() ..Default::default()
}; };
@ -336,7 +336,7 @@ async fn test_sns() {
let mut rx_info = gw::UplinkRxInfo { let mut rx_info = gw::UplinkRxInfo {
gateway_id: "0302030405060708".to_string(), gateway_id: "0302030405060708".to_string(),
time: Some(recv_time.into()), gw_time: Some(recv_time.into()),
location: Some(Default::default()), location: Some(Default::default()),
..Default::default() ..Default::default()
}; };

View File

@ -68,7 +68,7 @@ pub fn get_rx_timestamp(rx_info: &[gw::UplinkRxInfo]) -> SystemTime {
// Then search for time. // Then search for time.
for rxi in rx_info { for rxi in rx_info {
if let Some(ts) = &rxi.time { if let Some(ts) = &rxi.gw_time {
let ts: Result<DateTime<Utc>> = ts.clone().try_into().map_err(anyhow::Error::msg); let ts: Result<DateTime<Utc>> = ts.clone().try_into().map_err(anyhow::Error::msg);
if let Ok(ts) = ts { if let Ok(ts) = ts {
return ts.into(); return ts.into();
@ -95,7 +95,7 @@ pub fn get_rx_timestamp_chrono(rx_info: &[gw::UplinkRxInfo]) -> DateTime<Utc> {
// Then search for time. // Then search for time.
for rxi in rx_info { for rxi in rx_info {
if let Some(ts) = &rxi.time { if let Some(ts) = &rxi.gw_time {
let ts: Result<DateTime<Utc>> = ts.clone().try_into().map_err(anyhow::Error::msg); let ts: Result<DateTime<Utc>> = ts.clone().try_into().map_err(anyhow::Error::msg);
if let Ok(ts) = ts { if let Ok(ts) = ts {
return ts; return ts;

View File

@ -91,8 +91,8 @@ impl TryFrom<&UplinkFrameSet> for api::UplinkFrameLog {
}; };
for rx_info in &ufl.rx_info { for rx_info in &ufl.rx_info {
if rx_info.time.is_some() { if rx_info.gw_time.is_some() {
let time = rx_info.time.as_ref().unwrap(); let time = rx_info.gw_time.as_ref().unwrap();
ufl.time = Some(prost_types::Timestamp { ufl.time = Some(prost_types::Timestamp {
seconds: time.seconds, seconds: time.seconds,
nanos: time.nanos, nanos: time.nanos,