Allow pattern initialization
This commit is contained in:
parent
e4e69f4d51
commit
2fed645d22
@ -22,6 +22,7 @@ webui = { path = "./webui" }
|
|||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
clap = { version = "4.3.0", features = ["derive", "env"] }
|
clap = { version = "4.3.0", features = ["derive", "env"] }
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.37"
|
||||||
|
env_logger = "0.10.0"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
lto = true
|
lto = true
|
||||||
|
@ -37,3 +37,10 @@ xbps-install -y cross-armv7l-linux-gnueabihf
|
|||||||
rustup target add armv7-unknown-linux-gnueabihf
|
rustup target add armv7-unknown-linux-gnueabihf
|
||||||
make deploy
|
make deploy
|
||||||
----
|
----
|
||||||
|
|
||||||
|
== Notes
|
||||||
|
|
||||||
|
----
|
||||||
|
Car: 102
|
||||||
|
House: 89; skip 14
|
||||||
|
----
|
||||||
|
@ -10,3 +10,4 @@ serde_json = "1"
|
|||||||
parking_lot = "0.12"
|
parking_lot = "0.12"
|
||||||
crossbeam-channel = "0.5.6"
|
crossbeam-channel = "0.5.6"
|
||||||
strum = { version = "0.24.1", features = ["derive"] }
|
strum = { version = "0.24.1", features = ["derive"] }
|
||||||
|
tracing = "0.1.37"
|
||||||
|
@ -135,7 +135,7 @@ pub enum Parameters {
|
|||||||
|
|
||||||
impl Default for Parameters {
|
impl Default for Parameters {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Visualizer(VisualizerParams::default())
|
Self::MovingRainbow(Default::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ use super::{ColorIterator, FormRender, InputRender, Pattern, PatternError, Patte
|
|||||||
use crate::color::{self, Rgb, RAINBOW};
|
use crate::color::{self, Rgb, RAINBOW};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{collections::VecDeque, convert::TryFrom, iter};
|
use std::{collections::VecDeque, convert::TryFrom, iter};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||||
pub struct CarRainbowParams {
|
pub struct CarRainbowParams {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::pattern::Pattern;
|
use crate::pattern::Pattern;
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
ClearLights,
|
ClearLights,
|
||||||
ChangePattern(Box<dyn Pattern + Send>),
|
ChangePattern(Box<dyn Pattern + Send + Sync>),
|
||||||
SetNumLights(u16),
|
SetNumLights(u16),
|
||||||
SetTickTime(u64),
|
SetTickTime(u64),
|
||||||
Quit,
|
Quit,
|
||||||
|
@ -47,6 +47,7 @@ use ui::console_ui_loop;
|
|||||||
fn main() -> ProgramResult<()> {
|
fn main() -> ProgramResult<()> {
|
||||||
// Initialize any config
|
// Initialize any config
|
||||||
dotenv::dotenv().ok();
|
dotenv::dotenv().ok();
|
||||||
|
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info")).init();
|
||||||
|
|
||||||
// Use clap to parse the configuration
|
// Use clap to parse the configuration
|
||||||
let config = strip::Config::parse();
|
let config = strip::Config::parse();
|
||||||
@ -57,15 +58,18 @@ fn main() -> ProgramResult<()> {
|
|||||||
|
|
||||||
let (message_tx, message_rx) = channel::<error::Message>();
|
let (message_tx, message_rx) = channel::<error::Message>();
|
||||||
|
|
||||||
|
// The strip itself
|
||||||
make_child(message_tx.clone(), move |message_tx| -> ProgramResult<()> {
|
make_child(message_tx.clone(), move |message_tx| -> ProgramResult<()> {
|
||||||
let mut strip = LedStrip::new(config)?;
|
let mut strip = LedStrip::new(config)?;
|
||||||
strip.strip_loop(message_tx, &strip_rx)
|
strip.strip_loop(message_tx, &strip_rx)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Text user-interface
|
||||||
make_child(message_tx.clone(), move |message_tx| -> ProgramResult<()> {
|
make_child(message_tx.clone(), move |message_tx| -> ProgramResult<()> {
|
||||||
console_ui_loop(message_tx, &console_strip_tx)
|
console_ui_loop(message_tx, &console_strip_tx)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Webui user-interface
|
||||||
make_child(message_tx, move |message_tx| -> ProgramResult<()> {
|
make_child(message_tx, move |message_tx| -> ProgramResult<()> {
|
||||||
webui::start(message_tx.clone(), webui_strip_tx).map_err(ProgramError::IoError)
|
webui::start(message_tx.clone(), webui_strip_tx).map_err(ProgramError::IoError)
|
||||||
});
|
});
|
||||||
|
30
src/strip.rs
30
src/strip.rs
@ -9,6 +9,7 @@ use std::{
|
|||||||
cmp,
|
cmp,
|
||||||
ops::Add,
|
ops::Add,
|
||||||
process,
|
process,
|
||||||
|
str::FromStr,
|
||||||
sync::mpsc::{Receiver, Sender},
|
sync::mpsc::{Receiver, Sender},
|
||||||
thread,
|
thread,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
@ -52,13 +53,17 @@ pub struct Config {
|
|||||||
/// The default adapter
|
/// The default adapter
|
||||||
#[clap(long, default_value = "/dev/spidev0.0", help = "The serial interface")]
|
#[clap(long, default_value = "/dev/spidev0.0", help = "The serial interface")]
|
||||||
pub serial_interface: String,
|
pub serial_interface: String,
|
||||||
|
|
||||||
|
/// The initial pattern
|
||||||
|
#[clap(short, long, help = "The name of the initial pattern")]
|
||||||
|
pub initial_pattern: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::module_name_repetitions)]
|
#[allow(clippy::module_name_repetitions)]
|
||||||
pub struct LedStrip {
|
pub struct LedStrip {
|
||||||
pub adapter: Box<dyn Ws28xxAdapter>,
|
pub adapter: Box<dyn Ws28xxAdapter>,
|
||||||
pub config: Config,
|
pub config: Config,
|
||||||
pub pattern: Box<dyn Pattern>,
|
pub pattern: Box<dyn Pattern + Send + Sync>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LedStrip {
|
impl LedStrip {
|
||||||
@ -67,16 +72,33 @@ impl LedStrip {
|
|||||||
Ws28xxSpiAdapter::new(&config.serial_interface)
|
Ws28xxSpiAdapter::new(&config.serial_interface)
|
||||||
.map_err(|_| format!("Cannot start device {}!", config.serial_interface))?,
|
.map_err(|_| format!("Cannot start device {}!", config.serial_interface))?,
|
||||||
);
|
);
|
||||||
let pattern = Box::new(pattern::Solid::new(&pattern::SolidParams {
|
|
||||||
color: color::BLACK,
|
|
||||||
}));
|
|
||||||
let num_lights = config.num_lights;
|
let num_lights = config.num_lights;
|
||||||
|
|
||||||
|
// Initialize the pattern if they requested one; if there are any issues, initialize with black instead
|
||||||
|
let pattern = config
|
||||||
|
.initial_pattern
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|ip| {
|
||||||
|
pattern::Parameters::from_str(ip)
|
||||||
|
.as_ref()
|
||||||
|
.map(pattern::Parameters::to_pattern)
|
||||||
|
.map_err(|e| error!("Could not initialize with requested pattern {ip}: {e:?}"))
|
||||||
|
.ok()
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
info!("Using default black pattern");
|
||||||
|
Box::new(pattern::Solid::new(&pattern::SolidParams {
|
||||||
|
color: color::BLACK,
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
|
||||||
let mut ret = Self {
|
let mut ret = Self {
|
||||||
adapter,
|
adapter,
|
||||||
config,
|
config,
|
||||||
pattern,
|
pattern,
|
||||||
};
|
};
|
||||||
ret.set_num_lights(num_lights);
|
ret.set_num_lights(num_lights);
|
||||||
|
|
||||||
Ok(ret)
|
Ok(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ fn parse_color(r: &str, g: &str, b: &str) -> Result<Rgb, String> {
|
|||||||
|
|
||||||
fn change_pattern(
|
fn change_pattern(
|
||||||
strip_tx: &Sender<strip::Message>,
|
strip_tx: &Sender<strip::Message>,
|
||||||
pat: Box<dyn Pattern + Send>,
|
pat: Box<dyn Pattern + Send + Sync>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
strip_tx
|
strip_tx
|
||||||
.send(strip::Message::ChangePattern(pat))
|
.send(strip::Message::ChangePattern(pat))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user