tests for time stamp provider
This commit is contained in:
parent
6fe3086575
commit
88af155490
@ -17,6 +17,7 @@ serde = "1.0.137"
|
|||||||
zerocopy = "0.6.1"
|
zerocopy = "0.6.1"
|
||||||
crc = "3.0.0"
|
crc = "3.0.0"
|
||||||
delegate = "0.7.0"
|
delegate = "0.7.0"
|
||||||
|
chrono = "0.4.19"
|
||||||
|
|
||||||
[dependencies.heapless]
|
[dependencies.heapless]
|
||||||
version = "0.7.14"
|
version = "0.7.14"
|
||||||
|
@ -474,6 +474,7 @@ impl PusTcSecondaryHeader for PusTc<'_> {
|
|||||||
fn ack_flags(&self) -> u8;
|
fn ack_flags(&self) -> u8;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::ecss::{PusError, PusPacket};
|
use crate::ecss::{PusError, PusPacket};
|
||||||
|
126
src/time.rs
126
src/time.rs
@ -1,4 +1,6 @@
|
|||||||
use crate::PacketError;
|
use crate::PacketError;
|
||||||
|
use chrono::{DateTime, TimeZone, Utc};
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
|
||||||
@ -34,8 +36,8 @@ pub const fn unix_to_ccsds_days(unix_days: i32) -> i32 {
|
|||||||
///
|
///
|
||||||
/// - CCSDS epoch: 1958 January 1
|
/// - CCSDS epoch: 1958 January 1
|
||||||
/// - UNIX Epoch: 1970 January 1
|
/// - UNIX Epoch: 1970 January 1
|
||||||
pub const fn ccsds_to_unix_days(unix_days: i32) -> i32 {
|
pub const fn ccsds_to_unix_days(ccsds_days: i32) -> i32 {
|
||||||
unix_days + DAYS_CCSDS_TO_UNIX
|
ccsds_days + DAYS_CCSDS_TO_UNIX
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for generic CCSDS time providers
|
/// Trait for generic CCSDS time providers
|
||||||
@ -48,26 +50,55 @@ trait CcsdsTimeProvider {
|
|||||||
/// in big endian format.
|
/// in big endian format.
|
||||||
fn p_field(&self) -> (usize, [u8; 2]);
|
fn p_field(&self) -> (usize, [u8; 2]);
|
||||||
fn ccdsd_time_code(&self) -> CcsdsTimeCodes;
|
fn ccdsd_time_code(&self) -> CcsdsTimeCodes;
|
||||||
fn as_unix_seconds(&self) -> u64;
|
fn unix_seconds(&self) -> i64;
|
||||||
|
fn date_time(&self) -> DateTime<Utc>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct CdsShortTimeProvider {
|
pub struct CdsShortTimeProvider {
|
||||||
pfield: u8,
|
pfield: u8,
|
||||||
ccsds_days: u16,
|
ccsds_days: u16,
|
||||||
ms_of_day: u32,
|
ms_of_day: u32,
|
||||||
unix_seconds: u64,
|
unix_seconds: i64,
|
||||||
|
date_time: Option<DateTime<Utc>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CdsShortTimeProvider {
|
impl CdsShortTimeProvider {
|
||||||
pub fn new(ccsds_days: u16, ms_of_day: u32) -> Self {
|
pub fn new(ccsds_days: u16, ms_of_day: u32) -> Self {
|
||||||
let mut provider = Self {
|
let provider = Self {
|
||||||
pfield: (CcsdsTimeCodes::Cds as u8) << 4,
|
pfield: (CcsdsTimeCodes::Cds as u8) << 4,
|
||||||
ccsds_days,
|
ccsds_days,
|
||||||
ms_of_day,
|
ms_of_day,
|
||||||
unix_seconds: 0,
|
unix_seconds: 0,
|
||||||
|
date_time: None,
|
||||||
};
|
};
|
||||||
provider.calc_unix_seconds();
|
let unix_days_seconds = ccsds_to_unix_days(ccsds_days as i32) as i64 * (24 * 60 * 60);
|
||||||
provider
|
provider.setup(unix_days_seconds as i64, ms_of_day.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
pub fn from_now() -> Self {
|
||||||
|
let now = SystemTime::now()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
|
.expect("Error retrieving UNIX epoch");
|
||||||
|
let epoch = now.as_secs();
|
||||||
|
let secs_of_day = epoch % SECONDS_PER_DAY as u64;
|
||||||
|
let unix_days_seconds = epoch - secs_of_day;
|
||||||
|
let ms_of_day = secs_of_day * 1000 + now.subsec_millis() as u64;
|
||||||
|
let provider = Self {
|
||||||
|
pfield: (CcsdsTimeCodes::Cds as u8) << 4,
|
||||||
|
ccsds_days: unix_to_ccsds_days((unix_days_seconds / SECONDS_PER_DAY as u64) as i32) as u16,
|
||||||
|
ms_of_day: ms_of_day as u32,
|
||||||
|
unix_seconds: 0,
|
||||||
|
date_time: None,
|
||||||
|
};
|
||||||
|
provider.setup(unix_days_seconds as i64, ms_of_day.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn setup(mut self, unix_days_seconds: i64, ms_of_day: u64) -> Self {
|
||||||
|
self.calc_unix_seconds(unix_days_seconds, ms_of_day);
|
||||||
|
self.calc_date_time(unix_days_seconds, (ms_of_day % 1000) as u32);
|
||||||
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
@ -83,13 +114,23 @@ impl CdsShortTimeProvider {
|
|||||||
ms_of_day
|
ms_of_day
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calc_unix_seconds(&mut self) {
|
fn calc_unix_seconds(&mut self, unix_days_seconds: i64, ms_of_day: u64) {
|
||||||
let unix_days = ccsds_to_unix_days(self.ccsds_days as i32);
|
self.unix_seconds = unix_days_seconds;
|
||||||
self.unix_seconds = unix_days as u64 * (24 * 60 * 60);
|
let seconds_of_day = (ms_of_day / 1000) as i64;
|
||||||
let seconds_of_day = (self.ms_of_day as f32 / 1000.0).floor() as u64;
|
if self.unix_seconds < 0 {
|
||||||
|
self.unix_seconds -= seconds_of_day;
|
||||||
|
} else {
|
||||||
self.unix_seconds += seconds_of_day;
|
self.unix_seconds += seconds_of_day;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn calc_date_time(&mut self, unix_days_seconds: i64, ms_since_last_second: u32) {
|
||||||
|
assert!(ms_since_last_second < 1000, "Invalid MS since last second");
|
||||||
|
let ns_since_last_sec = ms_since_last_second * 1e6 as u32;
|
||||||
|
self.date_time = Some(Utc.timestamp(unix_days_seconds, ns_since_last_sec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl CcsdsTimeProvider for CdsShortTimeProvider {
|
impl CcsdsTimeProvider for CdsShortTimeProvider {
|
||||||
fn len(&self) -> usize {
|
fn len(&self) -> usize {
|
||||||
CDS_SHORT_LEN
|
CDS_SHORT_LEN
|
||||||
@ -114,7 +155,68 @@ impl CcsdsTimeProvider for CdsShortTimeProvider {
|
|||||||
CcsdsTimeCodes::Cds
|
CcsdsTimeCodes::Cds
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_unix_seconds(&self) -> u64 {
|
fn unix_seconds(&self) -> i64 {
|
||||||
self.unix_seconds
|
self.unix_seconds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn date_time(&self) -> DateTime<Utc> {
|
||||||
|
self.date_time.expect("Invalid date time")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use chrono::{Datelike, Timelike};
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
use std::println;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_creation() {
|
||||||
|
assert_eq!(unix_to_ccsds_days(DAYS_CCSDS_TO_UNIX), 0);
|
||||||
|
assert_eq!(ccsds_to_unix_days(0), DAYS_CCSDS_TO_UNIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
#[test]
|
||||||
|
fn test_get_current_time() {
|
||||||
|
let sec_floats = seconds_since_epoch();
|
||||||
|
assert!(sec_floats > 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_time_stamp_zero_args() {
|
||||||
|
let time_stamper = CdsShortTimeProvider::new(0, 0);
|
||||||
|
assert_eq!(
|
||||||
|
time_stamper.unix_seconds(),
|
||||||
|
(DAYS_CCSDS_TO_UNIX * 24 * 60 * 60) as i64
|
||||||
|
);
|
||||||
|
let date_time = time_stamper.date_time();
|
||||||
|
assert_eq!(date_time.year(), 1958);
|
||||||
|
assert_eq!(date_time.month(), 1);
|
||||||
|
assert_eq!(date_time.day(), 1);
|
||||||
|
assert_eq!(date_time.hour(), 0);
|
||||||
|
assert_eq!(date_time.minute(), 0);
|
||||||
|
assert_eq!(date_time.second(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_time_stamp_unix_epoch() {
|
||||||
|
let time_stamper = CdsShortTimeProvider::new((-DAYS_CCSDS_TO_UNIX) as u16, 0);
|
||||||
|
assert_eq!(time_stamper.unix_seconds(), 0);
|
||||||
|
let date_time = time_stamper.date_time();
|
||||||
|
assert_eq!(date_time.year(), 1970);
|
||||||
|
assert_eq!(date_time.month(), 1);
|
||||||
|
assert_eq!(date_time.day(), 1);
|
||||||
|
assert_eq!(date_time.hour(), 0);
|
||||||
|
assert_eq!(date_time.minute(), 0);
|
||||||
|
assert_eq!(date_time.second(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
#[test]
|
||||||
|
fn test_time_now() {
|
||||||
|
let timestamp_now = CdsShortTimeProvider::from_now();
|
||||||
|
println!("{}", timestamp_now.date_time());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user