jetzt mit Header, 3 Tabellen
This commit is contained in:
1 parent
f2417ec65d
commit
220161a70a
10 files changed
+636
-102
No files matched your search
+138
-28
@@ -1,6 +1,7 @@
|
||||
use actix_web::{web, App, HttpResponse, HttpServer, Result};
|
||||
use actix_files as fs;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
use std::fs as std_fs;
|
||||
use std::sync::Mutex;
|
||||
use tera::{Context, Tera};
|
||||
|
||||
@@ -15,16 +16,38 @@ struct TableRow {
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
struct TableData {
|
||||
rows: Vec<TableRow>,
|
||||
struct Settings {
|
||||
mqtt_broker: String,
|
||||
mqtt_port: String,
|
||||
influxdb_url: String,
|
||||
influxdb_token: String,
|
||||
}
|
||||
|
||||
impl Default for TableData {
|
||||
impl Default for Settings {
|
||||
fn default() -> Self {
|
||||
TableData {
|
||||
rows: vec![
|
||||
Settings {
|
||||
mqtt_broker: "localhost".to_string(),
|
||||
mqtt_port: "1883".to_string(),
|
||||
influxdb_url: "http://localhost:8086".to_string(),
|
||||
influxdb_token: "".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
struct AppConfig {
|
||||
table1: Vec<TableRow>,
|
||||
table2: Vec<TableRow>,
|
||||
table3: Vec<TableRow>,
|
||||
settings: Settings,
|
||||
}
|
||||
|
||||
impl Default for AppConfig {
|
||||
fn default() -> Self {
|
||||
AppConfig {
|
||||
table1: vec![
|
||||
TableRow {
|
||||
bezeichnung: "Sensor 1".to_string(),
|
||||
bezeichnung: "Temp Sensor 1".to_string(),
|
||||
adresse: "192.168.1.100".to_string(),
|
||||
r#type: "Temperatur".to_string(),
|
||||
faktor: "1.0".to_string(),
|
||||
@@ -32,39 +55,52 @@ impl Default for TableData {
|
||||
influxdb: false,
|
||||
},
|
||||
TableRow {
|
||||
bezeichnung: "Sensor 2".to_string(),
|
||||
bezeichnung: "Temp Sensor 2".to_string(),
|
||||
adresse: "192.168.1.101".to_string(),
|
||||
r#type: "Luftfeuchtigkeit".to_string(),
|
||||
faktor: "0.5".to_string(),
|
||||
r#type: "Temperatur".to_string(),
|
||||
faktor: "1.0".to_string(),
|
||||
mqtt: false,
|
||||
influxdb: true,
|
||||
},
|
||||
],
|
||||
table2: vec![
|
||||
TableRow {
|
||||
bezeichnung: "Sensor 3".to_string(),
|
||||
adresse: "192.168.1.102".to_string(),
|
||||
r#type: "Druck".to_string(),
|
||||
faktor: "2.0".to_string(),
|
||||
bezeichnung: "Humidity Sensor 1".to_string(),
|
||||
adresse: "192.168.1.200".to_string(),
|
||||
r#type: "Luftfeuchtigkeit".to_string(),
|
||||
faktor: "0.5".to_string(),
|
||||
mqtt: true,
|
||||
influxdb: true,
|
||||
},
|
||||
],
|
||||
table3: vec![
|
||||
TableRow {
|
||||
bezeichnung: "Pressure Sensor 1".to_string(),
|
||||
adresse: "192.168.1.300".to_string(),
|
||||
r#type: "Druck".to_string(),
|
||||
faktor: "2.0".to_string(),
|
||||
mqtt: true,
|
||||
influxdb: false,
|
||||
},
|
||||
],
|
||||
settings: Settings::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AppState {
|
||||
table: Mutex<TableData>,
|
||||
config: Mutex<AppConfig>,
|
||||
config_path: String,
|
||||
templates: Tera,
|
||||
}
|
||||
|
||||
impl AppState {
|
||||
fn load_or_create(config_path: &str) -> Self {
|
||||
let table = match fs::read_to_string(config_path) {
|
||||
let config = match std_fs::read_to_string(config_path) {
|
||||
Ok(content) => serde_json::from_str(&content).unwrap_or_default(),
|
||||
Err(_) => {
|
||||
let default = TableData::default();
|
||||
let _ = fs::write(config_path, serde_json::to_string_pretty(&default).unwrap());
|
||||
let default = AppConfig::default();
|
||||
let _ = std_fs::write(config_path, serde_json::to_string_pretty(&default).unwrap());
|
||||
default
|
||||
}
|
||||
};
|
||||
@@ -78,24 +114,26 @@ impl AppState {
|
||||
};
|
||||
|
||||
AppState {
|
||||
table: Mutex::new(table),
|
||||
config: Mutex::new(config),
|
||||
config_path: config_path.to_string(),
|
||||
templates: tera,
|
||||
}
|
||||
}
|
||||
|
||||
fn save(&self) -> Result<(), std::io::Error> {
|
||||
let table = self.table.lock().unwrap();
|
||||
let json = serde_json::to_string_pretty(&*table)?;
|
||||
fs::write(&self.config_path, json)
|
||||
let config = self.config.lock().unwrap();
|
||||
let json = serde_json::to_string_pretty(&*config)?;
|
||||
std_fs::write(&self.config_path, json)
|
||||
}
|
||||
}
|
||||
|
||||
async fn index(data: web::Data<AppState>) -> Result<HttpResponse> {
|
||||
let table = data.table.lock().unwrap();
|
||||
let config = data.config.lock().unwrap();
|
||||
|
||||
let mut context = Context::new();
|
||||
context.insert("rows", &table.rows);
|
||||
context.insert("rows", &config.table1);
|
||||
context.insert("table_id", "table1");
|
||||
context.insert("active_page", "table1");
|
||||
|
||||
let html = data.templates.render("index.html", &context)
|
||||
.map_err(|e| {
|
||||
@@ -106,13 +144,81 @@ async fn index(data: web::Data<AppState>) -> Result<HttpResponse> {
|
||||
Ok(HttpResponse::Ok().content_type("text/html").body(html))
|
||||
}
|
||||
|
||||
async fn table_page(data: web::Data<AppState>, path: web::Path<String>) -> Result<HttpResponse> {
|
||||
let table_id = path.into_inner();
|
||||
let config = data.config.lock().unwrap();
|
||||
|
||||
let rows = match table_id.as_str() {
|
||||
"table1" => &config.table1,
|
||||
"table2" => &config.table2,
|
||||
"table3" => &config.table3,
|
||||
_ => return Ok(HttpResponse::NotFound().body("Table not found")),
|
||||
};
|
||||
|
||||
let mut context = Context::new();
|
||||
context.insert("rows", rows);
|
||||
context.insert("table_id", &table_id);
|
||||
context.insert("active_page", &table_id);
|
||||
|
||||
let html = data.templates.render("index.html", &context)
|
||||
.map_err(|e| {
|
||||
eprintln!("Template error: {}", e);
|
||||
actix_web::error::ErrorInternalServerError("Template error")
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Ok().content_type("text/html").body(html))
|
||||
}
|
||||
|
||||
async fn settings_page(data: web::Data<AppState>) -> Result<HttpResponse> {
|
||||
let config = data.config.lock().unwrap();
|
||||
|
||||
let mut context = Context::new();
|
||||
context.insert("settings", &config.settings);
|
||||
context.insert("active_page", "settings");
|
||||
|
||||
let html = data.templates.render("settings.html", &context)
|
||||
.map_err(|e| {
|
||||
eprintln!("Template error: {}", e);
|
||||
actix_web::error::ErrorInternalServerError("Template error")
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Ok().content_type("text/html").body(html))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct SaveTableRequest {
|
||||
table_id: String,
|
||||
rows: Vec<TableRow>,
|
||||
}
|
||||
|
||||
async fn save_table(
|
||||
data: web::Data<AppState>,
|
||||
table_data: web::Json<TableData>,
|
||||
req: web::Json<SaveTableRequest>,
|
||||
) -> Result<HttpResponse> {
|
||||
let mut table = data.table.lock().unwrap();
|
||||
*table = table_data.into_inner();
|
||||
drop(table);
|
||||
let mut config = data.config.lock().unwrap();
|
||||
|
||||
match req.table_id.as_str() {
|
||||
"table1" => config.table1 = req.rows.clone(),
|
||||
"table2" => config.table2 = req.rows.clone(),
|
||||
"table3" => config.table3 = req.rows.clone(),
|
||||
_ => return Ok(HttpResponse::BadRequest().json(serde_json::json!({"status": "error", "message": "Invalid table_id"}))),
|
||||
}
|
||||
|
||||
drop(config);
|
||||
|
||||
match data.save() {
|
||||
Ok(_) => Ok(HttpResponse::Ok().json(serde_json::json!({"status": "success"}))),
|
||||
Err(_) => Ok(HttpResponse::InternalServerError().json(serde_json::json!({"status": "error"}))),
|
||||
}
|
||||
}
|
||||
|
||||
async fn save_settings(
|
||||
data: web::Data<AppState>,
|
||||
settings: web::Json<Settings>,
|
||||
) -> Result<HttpResponse> {
|
||||
let mut config = data.config.lock().unwrap();
|
||||
config.settings = settings.into_inner();
|
||||
drop(config);
|
||||
|
||||
match data.save() {
|
||||
Ok(_) => Ok(HttpResponse::Ok().json(serde_json::json!({"status": "success"}))),
|
||||
@@ -131,7 +237,11 @@ async fn main() -> std::io::Result<()> {
|
||||
App::new()
|
||||
.app_data(app_state.clone())
|
||||
.route("/", web::get().to(index))
|
||||
.route("/table/{id}", web::get().to(table_page))
|
||||
.route("/settings", web::get().to(settings_page))
|
||||
.route("/api/save", web::post().to(save_table))
|
||||
.route("/api/save-settings", web::post().to(save_settings))
|
||||
.service(fs::Files::new("/static", "./static"))
|
||||
})
|
||||
.bind("0.0.0.0:8080")?
|
||||
.run()
|
||||
|
||||
Reference in new issue
Block a user