Erste Version

This commit is contained in:
Eric Neuber committed 2025-11-20 20:11:48 +01:00
1 parent 7e133d55de
commit f2417ec65d
8 files changed
+2729 -1

No files matched your search

+139
View File
@@ -0,0 +1,139 @@
use actix_web::{web, App, HttpResponse, HttpServer, Result};
use serde::{Deserialize, Serialize};
use std::fs;
use std::sync::Mutex;
use tera::{Context, Tera};
#[derive(Debug, Serialize, Deserialize, Clone)]
struct TableRow {
bezeichnung: String,
adresse: String,
r#type: String,
faktor: String,
mqtt: bool,
influxdb: bool,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
struct TableData {
rows: Vec<TableRow>,
}
impl Default for TableData {
fn default() -> Self {
TableData {
rows: vec![
TableRow {
bezeichnung: "Sensor 1".to_string(),
adresse: "192.168.1.100".to_string(),
r#type: "Temperatur".to_string(),
faktor: "1.0".to_string(),
mqtt: true,
influxdb: false,
},
TableRow {
bezeichnung: "Sensor 2".to_string(),
adresse: "192.168.1.101".to_string(),
r#type: "Luftfeuchtigkeit".to_string(),
faktor: "0.5".to_string(),
mqtt: false,
influxdb: true,
},
TableRow {
bezeichnung: "Sensor 3".to_string(),
adresse: "192.168.1.102".to_string(),
r#type: "Druck".to_string(),
faktor: "2.0".to_string(),
mqtt: true,
influxdb: true,
},
],
}
}
}
struct AppState {
table: Mutex<TableData>,
config_path: String,
templates: Tera,
}
impl AppState {
fn load_or_create(config_path: &str) -> Self {
let table = match 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());
default
}
};
let tera = match Tera::new("templates/**/*") {
Ok(t) => t,
Err(e) => {
println!("Template parsing error: {}", e);
std::process::exit(1);
}
};
AppState {
table: Mutex::new(table),
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)
}
}
async fn index(data: web::Data<AppState>) -> Result<HttpResponse> {
let table = data.table.lock().unwrap();
let mut context = Context::new();
context.insert("rows", &table.rows);
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 save_table(
data: web::Data<AppState>,
table_data: web::Json<TableData>,
) -> Result<HttpResponse> {
let mut table = data.table.lock().unwrap();
*table = table_data.into_inner();
drop(table);
match data.save() {
Ok(_) => Ok(HttpResponse::Ok().json(serde_json::json!({"status": "success"}))),
Err(_) => Ok(HttpResponse::InternalServerError().json(serde_json::json!({"status": "error"}))),
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let config_path = "table_config.json";
let app_state = web::Data::new(AppState::load_or_create(config_path));
println!("Server läuft auf http://0.0.0.0:8080");
HttpServer::new(move || {
App::new()
.app_data(app_state.clone())
.route("/", web::get().to(index))
.route("/api/save", web::post().to(save_table))
})
.bind("0.0.0.0:8080")?
.run()
.await
}