diff --git a/Cargo.toml b/Cargo.toml index eef2e6e..b564dad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,5 @@ futures = "0.3.28" tokio = { version = "1.33.0", features=["macros", "rt-multi-thread"] } chrono = "0.4.31" actix-web = "4.4.0" -actix-files = "0.6.2" midea = { git = "https://gavania.de/hodasemi/Midea.git" } actix-cors = "0.6.4" \ No newline at end of file diff --git a/build.sh b/build.sh index bf3bc68..5ae879c 100644 --- a/build.sh +++ b/build.sh @@ -9,5 +9,4 @@ cargo build --release mkdir -p server cp devices.conf server/ -cp target/release/home_server server/ -cp -r resources server/ \ No newline at end of file +cp target/release/home_server server/ \ No newline at end of file diff --git a/frontend/lib/devices.dart b/frontend/lib/devices.dart index 11e5e60..7922e47 100644 --- a/frontend/lib/devices.dart +++ b/frontend/lib/devices.dart @@ -21,44 +21,54 @@ class Category { final List categories = []; - print("debug print"); print(response.body); + print("body type: ${response.body.runtimeType}"); - final Map>> json = jsonDecode(response.body); + final json = jsonDecode(response.body); - for (MapEntry>> category_entry in json.entries) { - final Category category = Category(category_entry.key); + print(json); + print("json type: ${json.runtimeType}"); - for (List device_info in category_entry.value) { - final String device_id = device_info[0]; - final String? device_descriptor = device_info[1]; - final bool power_control = device_info[2]; + final Map>> test = jsonDecode(json); - final response = - await http.get(Uri.parse("$base_url/plug_state/$device_id")); + print(test); + print("test type: ${test.runtimeType}"); - if (response.statusCode != 200) { - throw Exception("Failed to fetch plug_state for $device_id"); - } + // final Map>> json = jsonDecode(response.body); - print(response.body); + // for (MapEntry>> category_entry in json.entries) { + // final Category category = Category(category_entry.key); - final Map device_state = jsonDecode(response.body); + // for (List device_info in category_entry.value) { + // final String device_id = device_info[0]; + // final String? device_descriptor = device_info[1]; + // final bool power_control = device_info[2]; - final Device device = Device( - device_id, - device_descriptor, - device_state["led"], - device_state["power"], - device_state["power_draw"], - power_control && device_state["power_draw"] < 15, - ); + // final response = + // await http.get(Uri.parse("$base_url/plug_state/$device_id")); - category.devices.add(device); - } + // if (response.statusCode != 200) { + // throw Exception("Failed to fetch plug_state for $device_id"); + // } - categories.add(category); - } + // print(response.body); + + // final Map device_state = jsonDecode(response.body); + + // final Device device = Device( + // device_id, + // device_descriptor, + // device_state["led"], + // device_state["power"], + // device_state["power_draw"], + // power_control && device_state["power_draw"] < 15, + // ); + + // category.devices.add(device); + // } + + // categories.add(category); + // } return categories; } diff --git a/frontend/lib/main.dart b/frontend/lib/main.dart index 95a0606..b2280c3 100644 --- a/frontend/lib/main.dart +++ b/frontend/lib/main.dart @@ -59,7 +59,8 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { @override Widget build(BuildContext context) { - final Future> fut = Category.fetch("smart.gavania.de"); + final Future> fut = Category.fetch("127.0.0.1:8062"); + // final Future> fut = Category.fetch("smart.gavania.de"); List children = List.empty(); diff --git a/resources/css/index.css b/resources/css/index.css deleted file mode 100644 index 05e06f7..0000000 --- a/resources/css/index.css +++ /dev/null @@ -1,3 +0,0 @@ -td>*:not(:last-child) { - margin-right: 5px; -} \ No newline at end of file diff --git a/resources/js/main.js b/resources/js/main.js deleted file mode 100644 index e54c967..0000000 --- a/resources/js/main.js +++ /dev/null @@ -1,263 +0,0 @@ -function group_name({ name }) { - return ( - - {name} - - ); -} - -function table_header() { - return ( - - Name - LED - Power - Power Draw - - ); -} - -function table_row({ row_data }) { - return ( - - {/* Name */} - - {row_data.device_name} - - - - {/* LED */} - - - - - - - {/* Power */} - - - { - row_data.power_control && - && - - } - - - {/* Power Draw */} - - - - - - ); -} - -function create_table(group, device_data) { - return ( - - - - -
- ); -} - -export default async function MyApp() { - const response = await fetch( - "/devices", - { - method: "GET" - } - ); - - let json = JSON.parse(await response.json()); - - for (const [group_name, devices] of Object.entries(json)) { - let device_infos = []; - - for (let i = 0; i < devices.length; i++) { - let device_id = devices[i][0]; - let device_descriptor; - - if (devices[i][1] == null) { - device_descriptor = device_id - } else { - device_descriptor = devices[i][1]; - } - - // get plug status - const device_status_response = await fetch( - "/plug_state/" + device_id, - { - method: "GET" - } - ); - - let device_state = JSON.parse(await device_status_response.json()); - - let device_info = { - device_id: device_id, - device_descriptor: device_descriptor, - led_state: device_state["led"], - power_state: device_state["power"], - power_control: devices[i][2] && device_state["power_draw"] < 15, - power_draw: device_state["power_draw"], - }; - - device_infos.push(device_info); - } - - document.getElementById("main").appendChild(create_table(group_name, device_infos)); - } -} - -async function change_name(device_id) { - let device_name = document.getElementById("name_" + device_id); - - if (device_name.readOnly) { - device_name.readOnly = false; - device_name.focus(); - } else { - device_name.readOnly = true; - await change_device_name(device_id, device_name.value); - } -} - -async function change_plug_state(plug, module, state) { - const response = await fetch( - "/plug/" + plug + "/" + module + "_" + state, - { - method: "POST" - } - ); - - if (response.ok) { - const device_status_response = await fetch( - "/plug_state/" + plug, - { - method: "GET" - } - ); - - let device_state = JSON.parse(await device_status_response.json()); - - document.getElementById(module + "_" + plug).innerHTML = device_state[module]; - } -} - -async function led_on(plug) { - await change_plug_state(plug, "led", "on") -} - -async function led_off(plug) { - await change_plug_state(plug, "led", "off") -} - -async function power_on(plug) { - await change_plug_state(plug, "power", "on") -} - -async function power_off(plug) { - // get plug status - const device_status_response = await fetch( - "/plug_state/" + device_id, - { - method: "GET" - } - ); - - let device_state = JSON.parse(await device_status_response.json()); - - if (device_state["power_draw"] < 15) { - await change_plug_state(plug, "power", "off") - } -} - -async function change_device_name(plug, name) { - const response = await fetch( - "/device_name/" + plug + "/" + name, - { - method: "POST" - } - ); - - if (!response.ok) { - console.error(response.body); - } -} - -async function render_graph(plug, name) { - // remove old graph, if present - let old = document.getElementById("chart"); - - if (old !== null) { - old.remove(); - } - - // get start date - let start_text = document.getElementById("start").value; - let start_date = parseInt(new Date(start_text).getTime() / 1000).toFixed(0); - - // get end date1 - let end_text = document.getElementById("end").value; - let end_date = parseInt(new Date(end_text).getTime() / 1000).toFixed(0); - - // create new chart div - let chart = document.createElement('canvas'); - chart.id = "chart"; - - const response = await fetch( - "/plug_data/" + plug + "/" + start_date + "/" + end_date + "/" + "hourly", - { - method: "GET" - } - ); - - const j = await response.json(); - const data = JSON.parse(j); - - let y = []; - let x = []; - - for (let i = 0; i < data.length; i++) { - let [time, watts] = data[i]; - - x.push(new Date(time * 1000)); - y.push(watts); - } - - const chart_data = { - labels: x, - datasets: [{ - label: name, - data: y, - fill: false, - borderColor: 'rgb(75, 192, 192)', - tension: 0.1 - }] - }; - - new Chart(chart, { - type: 'line', - data: chart_data, - options: { - scales: { - y: { - beginAtZero: true - }, - x: { - type: 'time', - time: { - displayFormats: { - } - } - } - }, - locale: 'de-DE' - } - }); - - document.getElementById("graph").appendChild(chart); -} \ No newline at end of file diff --git a/resources/static/index.html b/resources/static/index.html deleted file mode 100644 index fe588b1..0000000 --- a/resources/static/index.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - Smart Homeserver - - - - - - - - - - - - -
- - - - - - - - - -
-
- - - \ No newline at end of file diff --git a/src/devices.rs b/src/devices.rs index 596ec71..172021f 100644 --- a/src/devices.rs +++ b/src/devices.rs @@ -1,6 +1,6 @@ use std::fs; -use anyhow::Result; +use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; use serde_json::{from_str, to_string, to_string_pretty}; @@ -11,7 +11,9 @@ pub struct Devices { impl Devices { pub async fn read(file: &str) -> Result { - Ok(from_str(&fs::read_to_string(file)?)?) + Ok(from_str( + &fs::read_to_string(file).context(format!("{file}"))?, + )?) } #[allow(unused)] diff --git a/src/main.rs b/src/main.rs index 9790e21..a64b28a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,6 @@ mod tasmota; mod web_server; use actix_cors::Cors; -use actix_files::Files; use actix_web::{web::Data, App, HttpServer}; use anyhow::Result; use devices::Devices; @@ -72,10 +71,6 @@ async fn run_web_server( .app_data(Data::new(db.clone())) .app_data(Data::new(plugs.clone())) .app_data(Data::new(dishwasher.clone())) - .service(Files::new("/images", "resources/images/").show_files_listing()) - .service(Files::new("/css", "resources/css").show_files_listing()) - .service(Files::new("/js", "resources/js").show_files_listing()) - .service(index) .service(device_query) .service(plug_state) .service(change_plug_state) diff --git a/src/web_server.rs b/src/web_server.rs index 22acb7a..e064c85 100644 --- a/src/web_server.rs +++ b/src/web_server.rs @@ -1,4 +1,3 @@ -use actix_files::NamedFile; use actix_web::{ get, post, web::{Data, Json, Path}, @@ -65,11 +64,6 @@ impl Resolution { } } -#[get("/")] -async fn index() -> Result { - NamedFile::open("resources/static/index.html") -} - #[get("/devices")] async fn device_query( db: Data>>, @@ -272,25 +266,6 @@ mod test { use super::*; - #[actix_web::test] - async fn test_index_get() { - let app = test::init_service(App::new().service(index)).await; - let req = test::TestRequest::default() - .insert_header(ContentType::plaintext()) - .to_request(); - let resp = test::call_service(&app, req).await; - - let status = resp.status(); - let body = resp.into_body(); - - assert!( - status.is_success(), - "status: {:?}, error: {:?}", - status, - body - ); - } - #[actix_web::test] async fn test_led_on_off() { let app = test::init_service(