Add self-creation for controller
This commit is contained in:
		
							parent
							
								
									d193000aec
								
							
						
					
					
						commit
						4e3df272c3
					
				
					 10 changed files with 105 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -20,4 +20,6 @@ serde = "1.0"
 | 
			
		|||
serde_json = "1.0"
 | 
			
		||||
serde_derive = "1.0"
 | 
			
		||||
 | 
			
		||||
sqlx = { version = "0.7", features = ["sqlite", "runtime-async-std", "macros", "chrono"] }
 | 
			
		||||
 | 
			
		||||
futures = "0.3"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										18
									
								
								emgauwa-controller/src/driver.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								emgauwa-controller/src/driver.rs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,18 @@
 | 
			
		|||
use serde::{Deserialize, Deserializer};
 | 
			
		||||
 | 
			
		||||
#[derive(Debug, Clone, Copy)]
 | 
			
		||||
pub enum Driver {
 | 
			
		||||
    Gpio,
 | 
			
		||||
    Piface,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<'de> Deserialize<'de> for Driver {
 | 
			
		||||
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
 | 
			
		||||
        match String::deserialize(deserializer)?.as_str() {
 | 
			
		||||
            "gpio" => Ok(Driver::Gpio),
 | 
			
		||||
            "piface" => Ok(Driver::Piface),
 | 
			
		||||
            _ => Err(serde::de::Error::custom("invalid driver")),
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,19 +1,50 @@
 | 
			
		|||
use std::str;
 | 
			
		||||
 | 
			
		||||
use futures::{future, pin_mut, StreamExt};
 | 
			
		||||
use futures::{future, pin_mut, SinkExt, StreamExt};
 | 
			
		||||
use futures::channel::mpsc;
 | 
			
		||||
use sqlx::pool::PoolConnection;
 | 
			
		||||
use sqlx::Sqlite;
 | 
			
		||||
use tokio::io::AsyncReadExt;
 | 
			
		||||
use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
 | 
			
		||||
use tokio_tungstenite::tungstenite::Error;
 | 
			
		||||
use emgauwa_lib::db;
 | 
			
		||||
use emgauwa_lib::db::Controller;
 | 
			
		||||
use emgauwa_lib::db::types::ControllerUid;
 | 
			
		||||
use crate::settings::Settings;
 | 
			
		||||
 | 
			
		||||
mod settings;
 | 
			
		||||
mod driver;
 | 
			
		||||
 | 
			
		||||
fn create_this_controller(conn: &mut PoolConnection<Sqlite>, settings: &Settings) -> Controller {
 | 
			
		||||
	futures::executor::block_on(async {
 | 
			
		||||
		Controller::create(
 | 
			
		||||
			conn,
 | 
			
		||||
			&ControllerUid::new(),
 | 
			
		||||
			&settings.name,
 | 
			
		||||
			i64::try_from(settings.relays.len()).expect("Too many relays"),
 | 
			
		||||
			true
 | 
			
		||||
		).await.expect("Failed to create controller")
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[tokio::main]
 | 
			
		||||
async fn main() {
 | 
			
		||||
	let settings = settings::init();
 | 
			
		||||
 | 
			
		||||
	let _pool = db::init(&settings.database).await;
 | 
			
		||||
	let pool = db::init(&settings.database).await;
 | 
			
		||||
 | 
			
		||||
	let mut conn = pool.acquire().await.unwrap();
 | 
			
		||||
 | 
			
		||||
	let this = Controller::get_all(&mut conn)
 | 
			
		||||
		.await
 | 
			
		||||
		.expect("Failed to get controller from database")
 | 
			
		||||
		.pop()
 | 
			
		||||
		.unwrap_or_else(|| create_this_controller(&mut conn, &settings));
 | 
			
		||||
 | 
			
		||||
	let this_json = serde_json::to_string(&this).unwrap();
 | 
			
		||||
 | 
			
		||||
	println!("{:?}", this);
 | 
			
		||||
	println!("{:?}", this_json);
 | 
			
		||||
 | 
			
		||||
	let url = format!(
 | 
			
		||||
		"ws://{}:{}/api/v1/ws/controllers",
 | 
			
		||||
| 
						 | 
				
			
			@ -26,13 +57,14 @@ async fn main() {
 | 
			
		|||
 | 
			
		||||
	let (ws_stream, _) = connect_async(url).await.expect("Failed to connect");
 | 
			
		||||
 | 
			
		||||
	let (write, read) = ws_stream.split();
 | 
			
		||||
	let (mut write, read) = ws_stream.split();
 | 
			
		||||
 | 
			
		||||
	let stdin_to_ws = stdin_rx.map(Ok).forward(write);
 | 
			
		||||
	write.send(Message::text(this_json)).await.unwrap();
 | 
			
		||||
	let ws_to_stdout = read.for_each(handle_message);
 | 
			
		||||
 | 
			
		||||
	pin_mut!(stdin_to_ws, ws_to_stdout);
 | 
			
		||||
	future::select(stdin_to_ws, ws_to_stdout).await;
 | 
			
		||||
	ws_to_stdout.await;
 | 
			
		||||
	//pin_mut!(stdin_to_ws, ws_to_stdout);
 | 
			
		||||
	//future::select(stdin_to_ws, ws_to_stdout).await;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Our helper method which will read data from stdin and send it along the
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
use emgauwa_lib::{constants, utils};
 | 
			
		||||
use serde_derive::Deserialize;
 | 
			
		||||
use crate::driver::Driver;
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Deserialize)]
 | 
			
		||||
#[serde(default)]
 | 
			
		||||
| 
						 | 
				
			
			@ -17,6 +18,15 @@ pub struct Logging {
 | 
			
		|||
	pub file: String,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Deserialize)]
 | 
			
		||||
#[serde(default)]
 | 
			
		||||
#[allow(unused)]
 | 
			
		||||
pub struct Relay {
 | 
			
		||||
	pub driver: Driver,
 | 
			
		||||
	pub pin: u8,
 | 
			
		||||
	pub inverted: bool,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Clone, Debug, Deserialize)]
 | 
			
		||||
#[serde(default)]
 | 
			
		||||
#[allow(unused)]
 | 
			
		||||
| 
						 | 
				
			
			@ -24,6 +34,8 @@ pub struct Settings {
 | 
			
		|||
	pub core: Core,
 | 
			
		||||
	pub database: String,
 | 
			
		||||
	pub logging: Logging,
 | 
			
		||||
	pub name: String,
 | 
			
		||||
	pub relays: Vec<Relay>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for Settings {
 | 
			
		||||
| 
						 | 
				
			
			@ -32,6 +44,18 @@ impl Default for Settings {
 | 
			
		|||
			core: Core::default(),
 | 
			
		||||
			database: String::from("sqlite://emgauwa-controller.sqlite"),
 | 
			
		||||
			logging: Logging::default(),
 | 
			
		||||
			name: String::from("Emgauwa Controller"),
 | 
			
		||||
			relays: Vec::new(),
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Default for Relay {
 | 
			
		||||
	fn default() -> Self {
 | 
			
		||||
		Relay {
 | 
			
		||||
			driver: Driver::Gpio,
 | 
			
		||||
			pin: 0,
 | 
			
		||||
			inverted: false,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue