dev/nm17 #2
5 changed files with 116 additions and 67 deletions
|
@ -11,3 +11,6 @@
|
||||||
- Поля
|
- Поля
|
||||||
- `value`
|
- `value`
|
||||||
- `unit`
|
- `unit`
|
||||||
|
- `devices_{device_id}`
|
||||||
|
- Поля
|
||||||
|
- `exists`: bool
|
||||||
|
|
|
@ -12,7 +12,7 @@ use thiserror::Error;
|
||||||
|
|
||||||
|
|
||||||
use crate::insert_header;
|
use crate::insert_header;
|
||||||
use crate::web_server::old_devices_api::QSParserError;
|
use crate::web_server::old_device_sensor_api::QSParserError;
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ use fred::prelude::*;
|
||||||
|
|
||||||
pub(crate) mod app_error;
|
pub(crate) mod app_error;
|
||||||
pub mod old_app_api;
|
pub mod old_app_api;
|
||||||
mod old_devices_api;
|
mod old_device_sensor_api;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -14,7 +14,7 @@ pub struct NMAppState {
|
||||||
pub redis_client: RedisClient,
|
pub redis_client: RedisClient,
|
||||||
}
|
}
|
||||||
|
|
||||||
use crate::web_server::old_devices_api::device_handler;
|
use crate::web_server::old_device_sensor_api::device_handler;
|
||||||
|
|
||||||
use ntex::web;
|
use ntex::web;
|
||||||
|
|
||||||
|
|
105
src/web_server/old_device_sensor_api/mod.rs
Normal file
105
src/web_server/old_device_sensor_api/mod.rs
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
mod qs_parser;
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
|
use crate::ingest_protocol::{NMDeviceDataPacket, NMJsonPacket};
|
||||||
|
use crate::web_server::app_error::AppError;
|
||||||
|
|
||||||
|
|
||||||
|
use ntex::http::{HttpMessage, StatusCode};
|
||||||
|
use ntex::util::{Bytes, HashMap};
|
||||||
|
use ntex::{http, web};
|
||||||
|
use fred::prelude::*;
|
||||||
|
use hifitime::Epoch;
|
||||||
|
use thiserror::Error;
|
||||||
|
use ufmt::uwrite;
|
||||||
|
use crate::web_server::NMAppState;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Device not found")]
|
||||||
|
DeviceNotFound(String),
|
||||||
|
#[error("Time sent with the device is way to behind now")]
|
||||||
|
TimeIsLongBehindNow,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn device_handler<'a>(
|
||||||
|
request: web::HttpRequest,
|
||||||
|
body: Bytes,
|
||||||
|
app_state: &NMAppState,
|
||||||
|
) -> Result<web::HttpResponse, AppError> {
|
||||||
|
let mut real_body: Option<NMJsonPacket> = None;
|
||||||
|
let mut json_error = None;
|
||||||
|
let mut query_error = None;
|
||||||
|
|
||||||
|
dbg!(&request.content_type());
|
||||||
|
dbg!(&request.query_string());
|
||||||
|
|
||||||
|
if request.method() == http::Method::POST {
|
||||||
|
match request.content_type() {
|
||||||
|
"application/json" => match serde_json::from_slice::<NMJsonPacket>(body.as_ref()) {
|
||||||
|
Ok(json_body) => real_body = Some(json_body),
|
||||||
|
Err(error) => json_error = Some(error),
|
||||||
|
},
|
||||||
|
"application/x-www-form-urlencoded" => {
|
||||||
|
match serde_qs::from_bytes::<NMDeviceDataPacket>(body.as_ref()) {
|
||||||
|
Ok(qs_body) => {
|
||||||
|
real_body = Some(NMJsonPacket {
|
||||||
|
devices: Vec::from([qs_body]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(error) => query_error = Some(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
} else if request.method() == http::Method::GET {
|
||||||
|
match serde_qs::from_str::<NMDeviceDataPacket>(request.query_string()) {
|
||||||
|
Ok(qs_body) => {
|
||||||
|
real_body = Some(NMJsonPacket {
|
||||||
|
devices: Vec::from([qs_body]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Err(error) => query_error = Some(error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(real_body) = real_body {
|
||||||
|
for device in real_body.devices {
|
||||||
|
let mut device_key_str = String::new();
|
||||||
|
|
||||||
|
let device_tai_timestamp = device.time
|
||||||
|
.unwrap_or(Epoch::now().unwrap())
|
||||||
|
.to_duration_since_j1900()
|
||||||
|
.to_seconds();
|
||||||
|
|
||||||
|
uwrite!(&mut device_key_str, "devices_{}", device.mac)?;
|
||||||
|
|
||||||
|
|
||||||
|
let device_exists: bool = app_state.redis_client.hget(device_key_str.as_str(), "exists").await?;
|
||||||
|
|
||||||
|
if !device_exists {
|
||||||
|
return Err(Error::DeviceNotFound(device.mac))
|
||||||
|
}
|
||||||
|
|
||||||
|
// devices_{device_id}_{tai_timestamp}_{sensor_id}
|
||||||
|
for sensor in device.values {
|
||||||
|
let mut device_report_key_str = String::new();
|
||||||
|
uwrite!(&mut device_report_key_str, "devices_{}_{}_{}", device.mac, device_tai_timestamp, sensor.mac)?;
|
||||||
|
let mut device_report_key_str = String::new();
|
||||||
|
|
||||||
|
|
||||||
|
app_state.redis_client.hset(device_key_str.as_str(), HashMap::from([
|
||||||
|
// TODO
|
||||||
|
])).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(AppError::UnknownBody {
|
||||||
|
json_err: json_error,
|
||||||
|
query_error,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(web::HttpResponse::build(StatusCode::OK).finish())
|
||||||
|
}
|
|
@ -1,21 +1,14 @@
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::num::ParseFloatError;
|
use std::num::ParseFloatError;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use crate::ingest_protocol::error::Error;
|
|
||||||
use crate::ingest_protocol::parser::parse_mac_address;
|
|
||||||
use crate::ingest_protocol::{NMDeviceDataPacket, NMJsonPacket, SensorValue};
|
|
||||||
use crate::web_server::app_error::AppError;
|
|
||||||
|
|
||||||
|
|
||||||
use ntex::http::{HttpMessage, StatusCode};
|
|
||||||
use ntex::util::{Bytes, HashMap};
|
|
||||||
use ntex::{http, web};
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use fred::bytes_utils::Str;
|
|
||||||
use hifitime::efmt::consts::ISO8601;
|
|
||||||
use hifitime::Epoch;
|
use hifitime::Epoch;
|
||||||
|
use ntex::util::HashMap;
|
||||||
use rust_decimal::Decimal;
|
use rust_decimal::Decimal;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use crate::ingest_protocol::error::Error;
|
||||||
|
use crate::ingest_protocol::{NMDeviceDataPacket, SensorValue};
|
||||||
|
use crate::ingest_protocol::parser::parse_mac_address;
|
||||||
|
|
||||||
/// В иделае было бы хорошо сделать всё как у [serde_json::Error], но это слишком большая морока
|
/// В иделае было бы хорошо сделать всё как у [serde_json::Error], но это слишком большая морока
|
||||||
#[derive(Error, Clone, Debug)]
|
#[derive(Error, Clone, Debug)]
|
||||||
|
@ -119,55 +112,3 @@ pub async fn parse_nm_qs_format(input: &str) -> Result<NMDeviceDataPacket, QSPar
|
||||||
|
|
||||||
Ok(device_data)
|
Ok(device_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn device_handler<'a>(
|
|
||||||
request: web::HttpRequest,
|
|
||||||
body: Bytes,
|
|
||||||
) -> Result<web::HttpResponse, AppError> {
|
|
||||||
let mut real_body: Option<NMJsonPacket> = None;
|
|
||||||
let mut json_error = None;
|
|
||||||
let mut query_error = None;
|
|
||||||
|
|
||||||
dbg!(&request.content_type());
|
|
||||||
dbg!(&request.query_string());
|
|
||||||
|
|
||||||
if request.method() == http::Method::POST {
|
|
||||||
match request.content_type() {
|
|
||||||
"application/json" => match serde_json::from_slice::<NMJsonPacket>(body.as_ref()) {
|
|
||||||
Ok(json_body) => real_body = Some(json_body),
|
|
||||||
Err(error) => json_error = Some(error),
|
|
||||||
},
|
|
||||||
"application/x-www-form-urlencoded" => {
|
|
||||||
match serde_qs::from_bytes::<NMDeviceDataPacket>(body.as_ref()) {
|
|
||||||
Ok(qs_body) => {
|
|
||||||
real_body = Some(NMJsonPacket {
|
|
||||||
devices: Vec::from([qs_body]),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Err(error) => query_error = Some(error),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
} else if request.method() == http::Method::GET {
|
|
||||||
match serde_qs::from_str::<NMDeviceDataPacket>(request.query_string()) {
|
|
||||||
Ok(qs_body) => {
|
|
||||||
real_body = Some(NMJsonPacket {
|
|
||||||
devices: Vec::from([qs_body]),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Err(error) => query_error = Some(error),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(_body) = real_body {
|
|
||||||
// TODO
|
|
||||||
} else {
|
|
||||||
return Err(AppError::UnknownBody {
|
|
||||||
json_err: json_error,
|
|
||||||
query_error,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(web::HttpResponse::build(StatusCode::OK).finish())
|
|
||||||
}
|
|
Loading…
Reference in a new issue