implement mac address stuff

This commit is contained in:
Mika 2024-10-13 20:29:05 +02:00
parent ec8859b59c
commit a696a05595
3 changed files with 84 additions and 24 deletions

17
Cargo.lock generated
View file

@ -546,6 +546,7 @@ dependencies = [
"chrono", "chrono",
"dotenvy", "dotenvy",
"entity", "entity",
"eui48",
"futures", "futures",
"jsonwebtoken", "jsonwebtoken",
"sea-orm", "sea-orm",
@ -1111,6 +1112,16 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "eui48"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "887418ac5e8d57c2e66e04bdc2fe15f9a5407be20b54a82c86bd0e368b709701"
dependencies = [
"regex",
"rustc-serialize",
]
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "2.5.3" version = "2.5.3"
@ -2316,6 +2327,12 @@ version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-serialize"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.4.1" version = "0.4.1"

View file

@ -19,3 +19,4 @@ dotenvy = "*"
jsonwebtoken = "*" jsonwebtoken = "*"
futures = "*" futures = "*"
chrono = "*" chrono = "*"
eui48 = "*"

View file

@ -11,7 +11,7 @@ use uuid::Uuid;
#[derive(Serialize)] #[derive(Serialize)]
struct NodeWithSensorData { struct NodeWithSensorData {
node: node::Model, node: NodeWithMac,
sensor_data: Vec<sensor_data::Model>, sensor_data: Vec<sensor_data::Model>,
} }
@ -20,29 +20,65 @@ pub struct CreateGroupWithoutId {
name: String, name: String,
} }
#[derive(Deserialize)] #[derive(Deserialize, Serialize)]
struct CreateNodeRequest { pub struct NodeWithMac {
id: u64, mac: String,
group: uuid::Uuid, group: uuid::Uuid,
} }
impl From<node::Model> for NodeWithMac {
fn from(value: node::Model) -> Self {
let mac_id_bytes = value.id.to_be_bytes();
let mut mac_bytes: [u8; 6] = [0; 6];
mac_bytes.copy_from_slice(&mac_id_bytes[2..]);
let mac = eui48::MacAddress::new(mac_bytes).to_string(eui48::MacAddressFormat::Canonical);
Self {
mac,
group: value.group,
}
}
}
impl TryInto<node::Model> for NodeWithMac {
type Error = eui48::ParseError;
fn try_into(self) -> Result<node::Model, Self::Error> {
let mac = eui48::MacAddress::parse_str(&self.mac)?;
let mac_bytes = mac.to_array();
let mut mac_id_bytes: [u8; 8] = [0; 8];
mac_id_bytes[2..].copy_from_slice(&mac_bytes);
let mac_id = i64::from_be_bytes(mac_id_bytes);
Ok(node::Model {
id: mac_id,
group: self.group,
})
}
}
#[derive(Serialize)] #[derive(Serialize)]
struct GroupWithNode { struct GroupWithNode {
#[serde(flatten)] #[serde(flatten)]
group: node_group::Model, group: node_group::Model,
node: Vec<node::Model>, node: Vec<NodeWithMac>,
} }
pub async fn get_nodes(state: web::Data<AppState>) -> actix_web::Result<impl Responder> { pub async fn get_nodes(state: web::Data<AppState>) -> actix_web::Result<impl Responder> {
let db = &state.db; let db = &state.db;
let result = node_group::Entity::find() let result: Vec<GroupWithNode> = node_group::Entity::find()
.find_with_related(entity::prelude::Node) .find_with_related(entity::prelude::Node)
.all(db) .all(db)
.await .await
.map_err(ErrorInternalServerError)? .map_err(ErrorInternalServerError)?
.into_iter() .into_iter()
.map(|(group, node)| GroupWithNode { group, node }) .map(|(group, nodes)| {
let nodes = nodes
.into_iter()
.map(|n| n.into())
.collect::<Vec<NodeWithMac>>();
GroupWithNode { group, node: nodes }
})
.collect::<Vec<_>>(); .collect::<Vec<_>>();
Ok(web::Json(result)) Ok(web::Json(result))
@ -61,15 +97,17 @@ pub async fn get_data(state: web::Data<AppState>) -> actix_web::Result<impl Resp
let mut result: Vec<NodeWithSensorData> = Vec::new(); let mut result: Vec<NodeWithSensorData> = Vec::new();
for node in nodes { for node in nodes {
let node_id = node.id.clone();
let sensor_data = sensor_data::Entity::find() let sensor_data = sensor_data::Entity::find()
.filter(sensor_data::Column::NodeId.eq(node_id)) .filter(sensor_data::Column::NodeId.eq(node.id))
.filter(sensor_data::Column::Timestamp.gt(one_hour_ago)) .filter(sensor_data::Column::Timestamp.gt(one_hour_ago))
.all(db) .all(db)
.await .await
.map_err(ErrorInternalServerError)?; .map_err(ErrorInternalServerError)?;
result.push(NodeWithSensorData { node, sensor_data }); result.push(NodeWithSensorData {
node: node.into(),
sensor_data,
});
} }
Ok(web::Json(result)) Ok(web::Json(result))
@ -95,16 +133,28 @@ pub async fn create_group(
pub async fn create_node( pub async fn create_node(
state: web::Data<AppState>, state: web::Data<AppState>,
node_request: web::Json<CreateNodeRequest>, node_request: web::Json<NodeWithMac>,
) -> actix_web::Result<impl Responder> { ) -> actix_web::Result<impl Responder> {
let db = &state.db; let db = &state.db;
let node = node_request.into_inner(); let node: NodeWithMac = node_request.into_inner();
let node = entity::node::ActiveModel { println!("Checking group ID: {:?}", node.group);
id: ActiveValue::Set(node.id),
group: ActiveValue::Set(node_request.group), let group_exists = entity::node_group::Entity::find_by_id(node.group)
}; .one(db)
.await
.map_err(ErrorInternalServerError)?
.is_some();
if !group_exists {
return Err(ErrorInternalServerError("Group ID does not exist"));
}
let node: node::Model = node
.try_into()
.map_err(|_| ErrorBadRequest("Invalid Mac Address"))?;
let node = node.into_active_model();
let result = node.insert(db).await.map_err(ErrorInternalServerError)?; let result = node.insert(db).await.map_err(ErrorInternalServerError)?;
@ -128,11 +178,3 @@ pub async fn delete_node(
Ok(HttpResponse::Ok().finish()) Ok(HttpResponse::Ok().finish())
} }
*/ */
fn mac_to_i32(mac: &str) -> Result<i32, std::num::ParseIntError> {
// Remove non-hexadecimal characters
let sanitized_mac: String = mac.chars().filter(|c| c.is_digit(16)).collect();
// Parse the sanitized string as a hexadecimal number
i32::from_str_radix(&sanitized_mac, 16)
}