diff --git a/backend/src/lib.rs b/backend/src/lib.rs index c21c150..6a366b3 100644 --- a/backend/src/lib.rs +++ b/backend/src/lib.rs @@ -1,6 +1,7 @@ use std::{collections::HashMap, sync::Arc}; use color_eyre::eyre; +use serde::{Deserialize, Serialize}; use tokio::sync::RwLock; use tokio::net::TcpListener; @@ -16,6 +17,19 @@ pub mod web; pub struct Registration { pub ip: [u8; 4], pub port: u16, + pub mode: Mode, + pub color: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub enum Mode { + #[default] + #[serde(rename = "color")] + Color, + #[serde(rename = "sun")] + Sun, + #[serde(rename = "off")] + Off, } #[derive(Clone, Default)] diff --git a/backend/src/tcp/mod.rs b/backend/src/tcp/mod.rs index a4754f2..14640b2 100644 --- a/backend/src/tcp/mod.rs +++ b/backend/src/tcp/mod.rs @@ -8,7 +8,7 @@ use tokio::{ }; use tracing::{info, warn}; -use crate::{AppState, Registration}; +use crate::{AppState, Mode, Registration}; pub async fn receive_register_events(listener: TcpListener, state: AppState) -> eyre::Result<()> { let mut buf = [0u8; 4096]; @@ -26,7 +26,12 @@ pub async fn receive_register_events(listener: TcpListener, state: AppState) -> match packet { Packet::Register { ip, port, id } => { let id = id.to_string(); - let registration = Registration { ip, port }; + let registration = Registration { + ip, + port, + mode: Mode::Color, + color: "#ffffffcc".to_string(), + }; info!( "Received registration for device: {} - {:?}", diff --git a/backend/src/web/mod.rs b/backend/src/web/mod.rs index a97e840..47c76a9 100644 --- a/backend/src/web/mod.rs +++ b/backend/src/web/mod.rs @@ -2,10 +2,10 @@ use axum::{ Json, Router, extract::State, http::header::{ACCEPT, AUTHORIZATION, CONTENT_TYPE}, - routing::get, + routing::{get, post}, }; use color_eyre::eyre; -use serde::Serialize; +use serde::{Deserialize, Serialize}; use tower::ServiceBuilder; use tower_http::{ cors::{Any, CorsLayer}, @@ -13,12 +13,13 @@ use tower_http::{ trace::TraceLayer, }; -use crate::AppState; +use crate::{AppState, Mode}; pub async fn app(state: AppState) -> eyre::Result { let app = Router::new() .route("/api/health", get(health_check)) .route("/api/devices", get(get_devices)) + .route("/api/device", post(update_device)) .with_state(state) .fallback_service(ServeDir::new("../frontend/dist")) .layer( @@ -35,37 +36,35 @@ pub async fn app(state: AppState) -> eyre::Result { Ok(app) } -#[derive(Debug, Clone, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Device { pub id: String, pub mode: Mode, pub color: String, } -#[derive(Debug, Clone, Serialize)] -pub enum Mode { - #[serde(rename = "off")] - Off, - #[serde(rename = "color")] - Color, - #[serde(rename = "sun")] - Sun, -} - async fn get_devices(state: State) -> Json> { let devices = state.registered_devices.read().await; let devices = devices .iter() - .map(|(id, _)| Device { + .map(|(id, data)| Device { id: id.clone(), - mode: Mode::Off, - color: "#ffffffcc".to_string(), + mode: data.mode.clone(), + color: data.color.to_string(), }) .collect(); Json(devices) } +async fn update_device(state: State, Json(device): Json) { + let mut devices = state.registered_devices.write().await; + devices.entry(device.id).and_modify(|entry| { + entry.mode = device.mode; + entry.color = device.color + }); +} + async fn health_check() -> &'static str { "ok" } diff --git a/frontend/src/components/DeviceEntry.vue b/frontend/src/components/DeviceEntry.vue index 8531190..b9373b1 100644 --- a/frontend/src/components/DeviceEntry.vue +++ b/frontend/src/components/DeviceEntry.vue @@ -15,12 +15,16 @@ get: () => props.device.color, set: (value) => (props.device.color = value), }); + + async function onApply() { + await fetch("/api/device", {method: "POST", body: JSON.stringify(props.device), headers:{'content-type': 'application/json'}, }) + }