Pārlūkot izejas kodu

Add connection to ha websocket

Lee Morgan 1 mēnesi atpakaļ
vecāks
revīzija
e8f6d674fe
11 mainītis faili ar 344 papildinājumiem un 19 dzēšanām
  1. 0 2
      .env
  2. 1 0
      .gitignore
  3. 267 11
      Cargo.lock
  4. 4 0
      Cargo.toml
  5. 2 0
      example.env
  6. 11 2
      src/main.rs
  7. 8 0
      src/users.rs
  8. 48 0
      src/websocket.rs
  9. 1 2
      ui/createHtml.js
  10. 2 0
      ui/index.html
  11. 0 2
      ui/index.js

+ 0 - 2
.env

@@ -1,2 +0,0 @@
-APP_ENV=development
-PORT=8000

+ 1 - 0
.gitignore

@@ -3,3 +3,4 @@
 *swo
 node_modules/
 build.html
+.env

+ 267 - 11
Cargo.lock

@@ -63,7 +63,7 @@ dependencies = [
  "foldhash",
  "futures-core",
  "h2",
- "http",
+ "http 0.2.12",
  "httparse",
  "httpdate",
  "itoa",
@@ -72,7 +72,7 @@ dependencies = [
  "mime",
  "percent-encoding",
  "pin-project-lite",
- "rand",
+ "rand 0.10.2",
  "sha1",
  "smallvec",
  "tokio",
@@ -99,7 +99,7 @@ checksum = "14f8c75c51892f18d9c46150c5ac7beb81c95f78c8b83a634d49f4ca32551fe7"
 dependencies = [
  "bytestring",
  "cfg-if",
- "http",
+ "http 0.2.12",
  "regex",
  "regex-lite",
  "serde",
@@ -143,6 +143,25 @@ dependencies = [
  "pin-project-lite",
 ]
 
+[[package]]
+name = "actix-tls"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6176099de3f58fbddac916a7f8c6db297e021d706e7a6b99947785fee14abe9f"
+dependencies = [
+ "actix-rt",
+ "actix-service",
+ "actix-utils",
+ "futures-core",
+ "http 0.2.12",
+ "http 1.5.0",
+ "impl-more 0.1.9",
+ "pin-project-lite",
+ "tokio",
+ "tokio-util",
+ "tracing",
+]
+
 [[package]]
 name = "actix-utils"
 version = "3.0.1"
@@ -177,7 +196,7 @@ dependencies = [
  "foldhash",
  "futures-core",
  "futures-util",
- "impl-more",
+ "impl-more 0.3.5",
  "itoa",
  "language-tags",
  "log",
@@ -238,6 +257,39 @@ dependencies = [
  "alloc-no-stdlib",
 ]
 
+[[package]]
+name = "awc"
+version = "3.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b7dc0207013c5059ddce268fe12045bd12b2e919318ee660c891bfe297a54f1f"
+dependencies = [
+ "actix-codec",
+ "actix-http",
+ "actix-rt",
+ "actix-service",
+ "actix-tls",
+ "actix-utils",
+ "base64",
+ "bytes",
+ "cfg-if",
+ "cookie",
+ "derive_more",
+ "futures-core",
+ "futures-util",
+ "h2",
+ "http 0.2.12",
+ "itoa",
+ "log",
+ "mime",
+ "percent-encoding",
+ "pin-project-lite",
+ "rand 0.9.5",
+ "serde",
+ "serde_json",
+ "serde_urlencoded",
+ "tokio",
+]
+
 [[package]]
 name = "base64"
 version = "0.22.1"
@@ -280,6 +332,12 @@ dependencies = [
  "alloc-stdlib",
 ]
 
+[[package]]
+name = "bumpalo"
+version = "3.20.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
+
 [[package]]
 name = "bytes"
 version = "1.12.1"
@@ -321,7 +379,7 @@ checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81"
 dependencies = [
  "cfg-if",
  "cpufeatures",
- "rand_core",
+ "rand_core 0.10.1",
 ]
 
 [[package]]
@@ -502,6 +560,17 @@ version = "0.3.33"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2cd50c473c80f6d7c3670a752354b8e569b1a7cbfdc0419ec88e5edad85e0dc7"
 
+[[package]]
+name = "futures-macro"
+version = "0.3.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2d6d3cde68c518367be28956066ddfef33813991b77a55005a69dae04bf3b10b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.119",
+]
+
 [[package]]
 name = "futures-sink"
 version = "0.3.33"
@@ -521,11 +590,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a77a90a256fce34da66415271e30f94ee91c57b04b8a2c042d9cf3220179deaa"
 dependencies = [
  "futures-core",
+ "futures-macro",
+ "futures-sink",
  "futures-task",
  "pin-project-lite",
  "slab",
 ]
 
+[[package]]
+name = "getrandom"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "r-efi 5.3.0",
+ "wasip2",
+]
+
 [[package]]
 name = "getrandom"
 version = "0.4.3"
@@ -534,8 +617,8 @@ checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099"
 dependencies = [
  "cfg-if",
  "libc",
- "r-efi",
- "rand_core",
+ "r-efi 6.0.0",
+ "rand_core 0.10.1",
 ]
 
 [[package]]
@@ -549,7 +632,7 @@ dependencies = [
  "futures-core",
  "futures-sink",
  "futures-util",
- "http",
+ "http 0.2.12",
  "indexmap",
  "slab",
  "tokio",
@@ -563,7 +646,11 @@ version = "0.1.0"
 dependencies = [
  "actix-files",
  "actix-web",
+ "awc",
  "dotenvy",
+ "futures-util",
+ "serde_json",
+ "uuid",
 ]
 
 [[package]]
@@ -583,6 +670,16 @@ dependencies = [
  "itoa",
 ]
 
+[[package]]
+name = "http"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0"
+dependencies = [
+ "bytes",
+ "itoa",
+]
+
 [[package]]
 name = "http-range"
 version = "0.1.5"
@@ -713,6 +810,12 @@ dependencies = [
  "icu_properties",
 ]
 
+[[package]]
+name = "impl-more"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2"
+
 [[package]]
 name = "impl-more"
 version = "0.3.5"
@@ -741,10 +844,21 @@ version = "0.1.35"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3"
 dependencies = [
- "getrandom",
+ "getrandom 0.4.3",
  "libc",
 ]
 
+[[package]]
+name = "js-sys"
+version = "0.3.103"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102"
+dependencies = [
+ "cfg-if",
+ "futures-util",
+ "wasm-bindgen",
+]
+
 [[package]]
 name = "language-tags"
 version = "0.3.2"
@@ -907,6 +1021,15 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
 
+[[package]]
+name = "ppv-lite86"
+version = "0.2.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
+dependencies = [
+ "zerocopy",
+]
+
 [[package]]
 name = "proc-macro2"
 version = "1.0.107"
@@ -925,12 +1048,28 @@ dependencies = [
  "proc-macro2",
 ]
 
+[[package]]
+name = "r-efi"
+version = "5.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+
 [[package]]
 name = "r-efi"
 version = "6.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
 
+[[package]]
+name = "rand"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41"
+dependencies = [
+ "rand_chacha",
+ "rand_core 0.9.5",
+]
+
 [[package]]
 name = "rand"
 version = "0.10.2"
@@ -938,8 +1077,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80"
 dependencies = [
  "chacha20",
- "getrandom",
- "rand_core",
+ "getrandom 0.4.3",
+ "rand_core 0.10.1",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.9.5",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
+dependencies = [
+ "getrandom 0.3.4",
 ]
 
 [[package]]
@@ -1001,6 +1159,12 @@ dependencies = [
  "semver",
 ]
 
+[[package]]
+name = "rustversion"
+version = "1.0.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
+
 [[package]]
 name = "ryu"
 version = "1.0.23"
@@ -1327,6 +1491,18 @@ version = "1.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
 
+[[package]]
+name = "uuid"
+version = "1.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239"
+dependencies = [
+ "getrandom 0.4.3",
+ "js-sys",
+ "serde_core",
+ "wasm-bindgen",
+]
+
 [[package]]
 name = "v_htmlescape"
 version = "0.15.8"
@@ -1345,6 +1521,60 @@ version = "0.11.1+wasi-snapshot-preview1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
 
+[[package]]
+name = "wasip2"
+version = "1.0.4+wasi-0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487"
+dependencies = [
+ "wit-bindgen",
+]
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.126"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "rustversion",
+ "wasm-bindgen-macro",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.126"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.126"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e"
+dependencies = [
+ "bumpalo",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.119",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.126"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24"
+dependencies = [
+ "unicode-ident",
+]
+
 [[package]]
 name = "windows-link"
 version = "0.2.1"
@@ -1433,6 +1663,12 @@ version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
 
+[[package]]
+name = "wit-bindgen"
+version = "0.57.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e"
+
 [[package]]
 name = "writeable"
 version = "0.6.3"
@@ -1462,6 +1698,26 @@ dependencies = [
  "synstructure",
 ]
 
+[[package]]
+name = "zerocopy"
+version = "0.8.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.56"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.119",
+]
+
 [[package]]
 name = "zerofrom"
 version = "0.1.8"

+ 4 - 0
Cargo.toml

@@ -6,7 +6,11 @@ edition = "2024"
 [dependencies]
 actix-files = "0.6.10"
 actix-web = "4.14.0"
+awc = "3.8.2"
 dotenvy = "0.15.7"
+futures-util = "0.3.33"
+serde_json = "1.0.151"
+uuid = { version = "1.24.0", features = ["v4", "serde"]}
 
 [profile.release]
 opt-level = 3

+ 2 - 0
example.env

@@ -1,2 +1,4 @@
 APP_ENV
 PORT
+HA_IP
+HA_TOKEN

+ 11 - 2
src/main.rs

@@ -2,14 +2,23 @@ use actix_web::{HttpServer, App, middleware};
 
 mod routes;
 mod controllers;
+mod websocket;
 
 #[actix_web::main]
-async fn main() -> std::io::Result<()> {
+async fn main() -> Result<(), std::io::Error> {
+    //Environment Variables
     dotenvy::from_filename(".env").expect("Failed to load .env file");
 
-    let app_env: String = env_var("APP_ENV");
     let port: u16 = env_var("PORT");
+    let ha_ip: String = env_var("HA_IP");
+    let ha_token: String = env_var("HA_TOKEN");
 
+    //Connect to HA
+    websocket::connect_to_ha(ha_ip, ha_token)
+        .await
+        .expect("Failed to start websocket");
+
+    //Create HTTP server
     HttpServer::new(move || {
         App::new()
             .wrap(middleware::Compress::default())

+ 8 - 0
src/users.rs

@@ -0,0 +1,8 @@
+use uuid::Uuid;
+
+pub struct User {
+    pub id: Uuid,
+    pub name: String,
+    pub email: String,
+    pub pass_hash: String,
+}

+ 48 - 0
src/websocket.rs

@@ -0,0 +1,48 @@
+use awc::{Client, ws::{Frame, Message}};
+use futures_util::{SinkExt, StreamExt};
+use serde_json::{Value, from_str, json};
+
+pub async fn connect_to_ha(ip: String, token: String) -> Result<(), Box<dyn std::error::Error>> {
+    let client = Client::new();
+    let (_resp, mut connection) = client
+        .ws(format!("ws://{}:8123/api/websocket", ip))
+        .connect()
+        .await?;
+    let mut message_id = 1;
+
+    while let Some(Ok(msg)) = connection.next().await {
+        if let Frame::Text(bytes) = msg {
+            let text = String::from_utf8(bytes.to_vec())?;
+            let parsed: Value = from_str(&text)?;
+
+            if parsed["type"] == "auth_required" {
+                let auth_msg = json!({
+                    "type": "auth",
+                    "access_token": token
+                });
+
+                connection.send(Message::Text(auth_msg.to_string().into())).await?;
+            }
+
+            if parsed["type"] == "auth_ok" {
+                let areas_msg = json!({"type": "config/area_registry/list", "id": message_id});
+                connection.send(Message::Text(areas_msg.to_string().into())).await?;
+                message_id += 1;
+
+                let devices_msg = json!({"type": "config/device_registry/list", "id": message_id});
+                connection.send(Message::Text(devices_msg.to_string().into())).await?;
+                message_id += 1;
+
+                let entities_msg = json!({"type": "config/entity_registry/list", "id": message_id});
+                connection.send(Message::Text(entities_msg.to_string().into())).await?;
+                message_id += 1;
+            }
+
+            if parsed["type"] == "result" {
+                println!("result");
+            }
+        }
+    }
+
+    Ok(())
+}

+ 1 - 2
ui/createHtml.js

@@ -33,9 +33,8 @@ let data = await htmlMinifier.minify(html, {
     noNewlinesBeforeTagClose: true,
     removeComments: true
 });
-console.log(data);
 
 data = data.replace('<script></script>', `<script>${js}</script>`);
-data = data.replace('<link rel="stylesheet">', `<style>${css}</style>`);
+data = data.replace('<style></style>', `<style>${css}</style>`);
 
 fs.writeFile(`${import.meta.dirname}/build.html`, data);

+ 2 - 0
ui/index.html

@@ -3,10 +3,12 @@
 <head>
     <meta charset="UTF-8">
     <title>My App</title>
+    <style></style>
 </head>
 <body>
     <h1>Hello!</h1>
     <p>This is a simple page.</p>
     <p id="something"></p>
+    <script></script>
 </body>
 </html>

+ 0 - 2
ui/index.js

@@ -1,2 +0,0 @@
-console.log("something");
-document.getElementById("something").textContent = "Something";