fix(ingest_protocol): slight rework
This commit is contained in:
parent
1559122219
commit
7e024a79fa
5 changed files with 83 additions and 24 deletions
|
@ -1,7 +1,7 @@
|
||||||
use snafu::Snafu;
|
use snafu::Snafu;
|
||||||
|
|
||||||
/// Тип ошибки Ingest протокола
|
/// Тип ошибки Ingest протокола
|
||||||
#[derive(Debug, Snafu)]
|
#[derive(Debug, Snafu, PartialEq)]
|
||||||
#[snafu(visibility(pub))]
|
#[snafu(visibility(pub))]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Incomplete,
|
Incomplete,
|
||||||
|
|
|
@ -30,9 +30,9 @@ use std::hash::{Hash, Hasher};
|
||||||
/// NarodMon, `mac` может означать EUI-48 совместимый MAC адрес, или же просто
|
/// NarodMon, `mac` может означать EUI-48 совместимый MAC адрес, или же просто
|
||||||
/// уникальный идентификатор.
|
/// уникальный идентификатор.
|
||||||
///
|
///
|
||||||
/// Парсинг этих данных отличается в разных транспортных протоколах.
|
/// Парсинг этих данных отличается в разных транспортных протоколах.
|
||||||
/// Для HTTP /post или /get: см. [crate::web_server::old_device_sensor_api]
|
/// Для HTTP /post или /get: см. [crate::web_server::old_device_sensor_api]
|
||||||
/// Для TCP/UDP: TODO
|
/// Для TCP/UDP: см. [crate::ingest_protocol]
|
||||||
/// Для MQTT: TODO
|
/// Для MQTT: TODO
|
||||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct SensorValue {
|
pub struct SensorValue {
|
||||||
|
@ -74,6 +74,10 @@ pub struct NMDeviceDataPacket {
|
||||||
|
|
||||||
pub values: HashSet<SensorValue>,
|
pub values: HashSet<SensorValue>,
|
||||||
|
|
||||||
|
/// Владелец датчика
|
||||||
|
///
|
||||||
|
/// Будет игнорироваться, так как в данном значении нет смысла, одни проблемы.
|
||||||
|
/// Автором датчика может быть только тот, кто его создал.
|
||||||
pub owner: Option<String>,
|
pub owner: Option<String>,
|
||||||
|
|
||||||
pub lat: Option<Decimal>,
|
pub lat: Option<Decimal>,
|
||||||
|
|
|
@ -40,7 +40,7 @@ pub fn parse_packet(input: impl AsRef<[u8]>) -> Result<NMDeviceDataPacket, Error
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
(&input[idx_lf..], mac, name)
|
(&input[idx_lf+1..], mac, name)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut packet = NMDeviceDataPacket {
|
let mut packet = NMDeviceDataPacket {
|
||||||
|
@ -53,12 +53,14 @@ pub fn parse_packet(input: impl AsRef<[u8]>) -> Result<NMDeviceDataPacket, Error
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
// TODO: searching for # and \n duplicates code above
|
// TODO: searching for # and \n duplicates code above
|
||||||
|
|
||||||
if input.first().ok_or(Error::Incomplete)? != &b'#' {
|
if input.first().ok_or(Error::Incomplete)? != &b'#' {
|
||||||
return Err(Error::PacketParseError { msg: "# expected" })?;
|
return Err(Error::PacketParseError { msg: "# expected" })?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// end of packet marker
|
input = &input[1..];
|
||||||
|
|
||||||
|
// If we see another #, this means we hit a end of packet marker
|
||||||
// ##
|
// ##
|
||||||
if input.first() == Some(&b'#') {
|
if input.first() == Some(&b'#') {
|
||||||
break;
|
break;
|
||||||
|
@ -138,7 +140,7 @@ pub fn parse_packet(input: impl AsRef<[u8]>) -> Result<NMDeviceDataPacket, Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input = &input[idx_lf..];
|
input = &input[idx_lf+1..];
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(packet)
|
Ok(packet)
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
use crate::ingest_protocol::{
|
use std::collections::HashSet;
|
||||||
parser::{parse_mac_address, parse_packet},
|
|
||||||
SensorValue,
|
use crate::{ingest_protocol::{
|
||||||
};
|
parser::{parse_mac_address, parse_packet}, NMDeviceDataPacket, SensorValue
|
||||||
|
}, utils::EpochUTC};
|
||||||
use hifitime::Epoch;
|
use hifitime::Epoch;
|
||||||
|
use rust_decimal_macros::dec;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_asd() {
|
fn test_asd() {
|
||||||
let asd = r#"
|
let asd = r#"#A2-C6-47-01-DF-E1#Метео
|
||||||
#A2-C6-47-01-DF-E1#Метео
|
|
||||||
#OWNER#unknown
|
#OWNER#unknown
|
||||||
#T1#13.44#1000000#Outdoor
|
#T1#13.44#1000000#Outdoor
|
||||||
#T2#27.74#Indoor
|
#T2#27.74#Indoor
|
||||||
|
@ -15,14 +16,69 @@ fn test_asd() {
|
||||||
#LAT#55.738178
|
#LAT#55.738178
|
||||||
#LON#37.6068
|
#LON#37.6068
|
||||||
#ALT#38
|
#ALT#38
|
||||||
##
|
##"#
|
||||||
"#
|
|
||||||
.trim()
|
.trim()
|
||||||
.as_bytes();
|
.as_bytes();
|
||||||
let packet = parse_packet(asd).unwrap();
|
let packet = parse_packet(asd).unwrap();
|
||||||
assert!(serde_json::to_string_pretty(&packet)
|
|
||||||
.unwrap()
|
dbg!(&packet);
|
||||||
.contains(r#""time": 1000000.0"#));
|
|
||||||
|
let real_packet = NMDeviceDataPacket {
|
||||||
|
mac: [162, 198, 71, 1, 223, 225],
|
||||||
|
name: Some(
|
||||||
|
"Метео".to_owned(),
|
||||||
|
),
|
||||||
|
values: HashSet::from_iter([
|
||||||
|
SensorValue {
|
||||||
|
mac: "T2".to_owned(),
|
||||||
|
value: dec!(27.74),
|
||||||
|
time: None,
|
||||||
|
unit: None,
|
||||||
|
name: Some(
|
||||||
|
"Indoor".to_owned(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
SensorValue {
|
||||||
|
mac: "P1".to_owned(),
|
||||||
|
value: dec!(691.02),
|
||||||
|
time: None,
|
||||||
|
unit: None,
|
||||||
|
name: Some(
|
||||||
|
"Barometer".to_owned(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
SensorValue {
|
||||||
|
mac: "T1".to_owned(),
|
||||||
|
value: dec!(13.44),
|
||||||
|
time: Some(
|
||||||
|
EpochUTC(Epoch::from_unix_seconds(1000000.0)),
|
||||||
|
),
|
||||||
|
unit: None,
|
||||||
|
name: Some(
|
||||||
|
"Outdoor".to_owned(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
].into_iter()),
|
||||||
|
owner: Some(
|
||||||
|
"unknown".to_owned(),
|
||||||
|
),
|
||||||
|
lat: Some(
|
||||||
|
dec!(55.738178),
|
||||||
|
),
|
||||||
|
lon: Some(
|
||||||
|
dec!(37.6068),
|
||||||
|
),
|
||||||
|
alt: Some(
|
||||||
|
dec!(38),
|
||||||
|
),
|
||||||
|
commands: None,
|
||||||
|
time: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
packet,
|
||||||
|
real_packet
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -8,7 +8,6 @@ use crate::web_server::old_app_api::handlers::{app_init, version};
|
||||||
use crate::web_server::old_app_api::types::{AppInitRequest, MandatoryParams};
|
use crate::web_server::old_app_api::types::{AppInitRequest, MandatoryParams};
|
||||||
use crate::web_server::utils::redis::is_api_key_valid;
|
use crate::web_server::utils::redis::is_api_key_valid;
|
||||||
use crate::web_server::NMAppState;
|
use crate::web_server::NMAppState;
|
||||||
use bstr::ByteSlice;
|
|
||||||
use ntex::util::Bytes;
|
use ntex::util::Bytes;
|
||||||
use ntex::web;
|
use ntex::web;
|
||||||
use ntex::web::types::State;
|
use ntex::web::types::State;
|
||||||
|
@ -30,10 +29,8 @@ pub async fn old_api_handler(
|
||||||
return Err(AppError::RequestTooLarge);
|
return Err(AppError::RequestTooLarge);
|
||||||
}
|
}
|
||||||
|
|
||||||
let body_bytes = body_bytes.as_bstr();
|
|
||||||
|
|
||||||
let mandatory_params: MandatoryParams<'_> =
|
let mandatory_params: MandatoryParams<'_> =
|
||||||
serde_json::from_slice(body_bytes).context(app_error::JsonSnafu {})?; // TODO: Simd-JSON
|
serde_json::from_slice(&body_bytes).context(app_error::JsonSnafu {})?; // TODO: Simd-JSON
|
||||||
|
|
||||||
// Ignore clippy singlematch
|
// Ignore clippy singlematch
|
||||||
if mandatory_params.cmd.as_ref() == "version" {
|
if mandatory_params.cmd.as_ref() == "version" {
|
||||||
|
@ -45,7 +42,7 @@ pub async fn old_api_handler(
|
||||||
match mandatory_params.cmd.as_ref() {
|
match mandatory_params.cmd.as_ref() {
|
||||||
"appInit" => {
|
"appInit" => {
|
||||||
let body: AppInitRequest =
|
let body: AppInitRequest =
|
||||||
serde_json::from_slice(body_bytes).context(app_error::JsonSnafu {})?;
|
serde_json::from_slice(&body_bytes).context(app_error::JsonSnafu {})?;
|
||||||
|
|
||||||
app_init(body, &app_state).await
|
app_init(body, &app_state).await
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue