automatically save data to database

This commit is contained in:
Mika Bomm 2024-10-14 00:08:02 +02:00
parent aab15384d3
commit bc8a300305
5 changed files with 63 additions and 18 deletions

View file

@ -13,6 +13,10 @@ post {
body:json { body:json {
{ {
"id":"04-7c-16-06-b3-53", "id":"04-7c-16-06-b3-53",
"group":"22da4165-582c-4df9-a911-dfd5573ae468" "coord_la":1,
"coord_lo":2,
"battery_minimum":3,
"battery_maximum":4,
"group":"20abe318-7238-4f63-908f-a484955ee3bc"
} }
} }

View file

@ -1,12 +1,15 @@
use crate::AppState; use crate::AppState;
use actix_web::{ use actix_web::{
error::{ErrorBadRequest, ErrorInternalServerError}, error::{ErrorBadRequest, ErrorInternalServerError},
web, Responder, web,
web::Path,
Responder,
}; };
use chrono::Utc; use chrono::Utc;
use entity::{node, node_group, sensor_data}; use entity::{node, node_group, sensor_data};
use sea_orm::{entity::*, query::*, ActiveModelTrait, ActiveValue, EntityTrait}; use sea_orm::{entity::*, query::*, ActiveModelTrait, ActiveValue, EntityTrait};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use uuid::Uuid;
#[derive(Serialize)] #[derive(Serialize)]
struct NodeWithSensorData { struct NodeWithSensorData {
@ -21,7 +24,7 @@ pub struct CreateGroupWithoutId {
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct NodeWithMac { pub struct NodeWithMac {
mac: String, id: String,
coord_la: f64, coord_la: f64,
coord_lo: f64, coord_lo: f64,
battery_minimum: f64, battery_minimum: f64,
@ -37,7 +40,7 @@ impl From<node::Model> for NodeWithMac {
let mac = eui48::MacAddress::new(mac_bytes).to_string(eui48::MacAddressFormat::Canonical); let mac = eui48::MacAddress::new(mac_bytes).to_string(eui48::MacAddressFormat::Canonical);
Self { Self {
mac, id: mac,
coord_la: value.coord_la, coord_la: value.coord_la,
coord_lo: value.coord_lo, coord_lo: value.coord_lo,
battery_minimum: value.battery_minimum, battery_minimum: value.battery_minimum,
@ -51,7 +54,7 @@ impl TryInto<node::Model> for NodeWithMac {
type Error = eui48::ParseError; type Error = eui48::ParseError;
fn try_into(self) -> Result<node::Model, Self::Error> { fn try_into(self) -> Result<node::Model, Self::Error> {
let mac = eui48::MacAddress::parse_str(&self.mac)?; let mac = eui48::MacAddress::parse_str(&self.id)?;
let mac_bytes = mac.to_array(); let mac_bytes = mac.to_array();
let mut mac_id_bytes: [u8; 8] = [0; 8]; let mut mac_id_bytes: [u8; 8] = [0; 8];
mac_id_bytes[2..].copy_from_slice(&mac_bytes); mac_id_bytes[2..].copy_from_slice(&mac_bytes);
@ -172,6 +175,28 @@ pub async fn create_node(
Ok(web::Json(result)) Ok(web::Json(result))
} }
/*
pub async fn update_node(
state: web::Data<AppState>,
node: web::Json<NodeWithMac>,
path: Path<Uuid>,
) -> actix_web::Result<impl Responder> {
let db = &state.db;
let node: NodeWithMac = node.into_inner();
let id = path.into_inner();
let node: = entity::node::ActiveModel {
id: ActiveValue::NotSet,
coord_la: ActiveValue::Set(node.coord_la),
coord_lo: ActiveValue::Set(node.coord_lo),
battery_minimum: ActiveValue::Set(node.battery_minimum),
battery_maximum: ActiveValue::Set(node.battery_maximum),
group: ActiveValue::Set(node.group),
};
Ok(web::Json(node))
}
*/
/* /*
pub async fn delete_node( pub async fn delete_node(
state: web::Data<AppState>, state: web::Data<AppState>,

View file

@ -1,6 +1,7 @@
use actix_web::{web, App, HttpServer}; use actix_web::{web, App, HttpServer};
use deku::prelude::*; use deku::prelude::*;
use sea_orm::{Database, DatabaseConnection}; use entity::{node::ActiveModel, sensor_data};
use sea_orm::{ActiveModelTrait, ActiveValue, Database, DatabaseConnection};
use std::env; use std::env;
use tokio::{io::AsyncReadExt, net::TcpListener}; use tokio::{io::AsyncReadExt, net::TcpListener};
@ -59,9 +60,27 @@ async fn main() -> std::io::Result<()> {
loop { loop {
if let Ok(size) = stream.read(&mut buffer).await { if let Ok(size) = stream.read(&mut buffer).await {
println!("{:#x?}", &buffer); println!("{:#x?}", &buffer);
if let Ok((data, value)) = Data::from_bytes((&buffer, 0)) { if let Ok((data, mut value)) = Data::from_bytes((&buffer, 0)) {
println!("Received: {:#?}", value); println!("Received: {:#?}", value);
// Process the data or save it to the database
value.mac.rotate_right(2);
let mac = i64::from_be_bytes(value.mac);
let sensor_data = entity::sensor_data::ActiveModel {
id: ActiveValue::Set(mac),
timestamp: ActiveValue::Set(chrono::Utc::now().naive_utc()),
temperature: ActiveValue::Set(value.temp),
voltage: ActiveValue::Set(value.battery_voltage),
uptime: ActiveValue::Set(value.up_time as i64),
};
let result = sensor_data.insert(&db).await;
match result {
Err(_) => println!("Failed to insert data"),
_ => (),
}
} else { } else {
println!("Failed to parse data"); println!("Failed to parse data");
} }

View file

@ -7,22 +7,21 @@ use serde::{Deserialize, Serialize};
#[sea_orm(table_name = "sensor_data")] #[sea_orm(table_name = "sensor_data")]
pub struct Model { pub struct Model {
#[sea_orm(primary_key, auto_increment = false)] #[sea_orm(primary_key, auto_increment = false)]
pub id: i32, pub id: i64,
#[sea_orm(primary_key, auto_increment = false)] #[sea_orm(primary_key, auto_increment = false)]
pub timestamp: DateTime, pub timestamp: DateTime,
#[sea_orm(column_type = "Float")] #[sea_orm(column_type = "Float")]
pub temperature: f32, pub temperature: f32,
#[sea_orm(column_type = "Double")] #[sea_orm(column_type = "Float")]
pub voltage: f64, pub voltage: f32,
pub uptime: i64, pub uptime: i64,
pub node_id: i64,
} }
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)] #[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation { pub enum Relation {
#[sea_orm( #[sea_orm(
belongs_to = "super::node::Entity", belongs_to = "super::node::Entity",
from = "Column::NodeId", from = "Column::Id",
to = "super::node::Column::Id", to = "super::node::Column::Id",
on_update = "Cascade", on_update = "Cascade",
on_delete = "Cascade" on_delete = "Cascade"

View file

@ -12,7 +12,7 @@ impl MigrationTrait for Migration {
Table::create() Table::create()
.table(SensorData::Table) .table(SensorData::Table)
.if_not_exists() .if_not_exists()
.col(integer(Node::Id)) .col(big_unsigned(Node::Id))
.col(timestamp(SensorData::Timestamp)) .col(timestamp(SensorData::Timestamp))
.primary_key( .primary_key(
Index::create() Index::create()
@ -20,13 +20,12 @@ impl MigrationTrait for Migration {
.col(SensorData::Timestamp), .col(SensorData::Timestamp),
) )
.col(float(SensorData::Temperature).default(-127)) .col(float(SensorData::Temperature).default(-127))
.col(double(SensorData::Voltage).default(-127)) .col(float(SensorData::Voltage).default(-127))
.col(big_unsigned(SensorData::Uptime).default(0)) .col(big_unsigned(SensorData::Uptime).default(0))
.col(big_unsigned(SensorData::NodeId))
.foreign_key( .foreign_key(
ForeignKey::create() ForeignKey::create()
.name("fk-data-node_id") .name("fk-data-node_id")
.from(SensorData::Table, SensorData::NodeId) .from(SensorData::Table, SensorData::Id)
.to(Node::Table, Node::Id) .to(Node::Table, Node::Id)
.on_update(ForeignKeyAction::Cascade) .on_update(ForeignKeyAction::Cascade)
.on_delete(ForeignKeyAction::Cascade), .on_delete(ForeignKeyAction::Cascade),
@ -53,5 +52,4 @@ enum SensorData {
Temperature, // def: -127 Temperature, // def: -127
Voltage, // def: -127 Voltage, // def: -127
Uptime, // def: 0 Uptime, // def: 0
NodeId,
} }