diff --git a/Cargo.lock b/Cargo.lock index 918d53b..1b93e18 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,7 +112,7 @@ dependencies = [ [[package]] name = "badgemagic" -version = "0.1.0" +version = "0.2.0" dependencies = [ "anyhow", "base64", diff --git a/Cargo.toml b/Cargo.toml index 86272cd..3fa0df4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "badgemagic" -version = "0.1.0" -authors = ["Martin Michaelis "] +version = "0.2.0" +authors = ["Martin Michaelis ", "Valentin Weber "] edition = "2021" description = "Badge Magic with LEDs - Library and CLI" homepage = "https://badgemagic.fossasia.org" diff --git a/LICENSE-MIT b/LICENSE-MIT index dd968bb..8b49e53 100644 --- a/LICENSE-MIT +++ b/LICENSE-MIT @@ -1,4 +1,5 @@ Copyright 2024 Martin Michaelis +Copyright 2025 Valentin Weber Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal diff --git a/examples/hello-world.rs b/examples/hello-world.rs index aa316b6..9360985 100644 --- a/examples/hello-world.rs +++ b/examples/hello-world.rs @@ -5,13 +5,13 @@ use badgemagic::{ embedded_graphics::{ geometry::Point, mono_font::MonoTextStyle, pixelcolor::BinaryColor, text::Text, }, - protocol::{Mode, PayloadBuffer, Style}, + protocol::{Brightness, Mode, PayloadBuffer, Style}, usb_hid::Device, util::DrawableLayoutExt, }; fn main() -> Result<()> { - let mut payload = PayloadBuffer::new(); + let mut payload = PayloadBuffer::new(Brightness::default()); payload.add_message_drawable( Style::default().mode(Mode::Center), diff --git a/src/main.rs b/src/main.rs index fcbe5ff..298c676 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,7 @@ use std::{fs, path::PathBuf}; use anyhow::{Context, Result}; use badgemagic::{ ble::Device as BleDevice, - protocol::{Mode, PayloadBuffer, Speed, Style}, + protocol::{Brightness, Mode, PayloadBuffer, Speed, Style}, usb_hid::Device as UsbDevice, }; use base64::Engine; @@ -43,6 +43,10 @@ struct Args { #[clap(long)] transport: TransportProtocol, + /// Brightness of the panel + #[clap(long)] + brightness: Option, + /// List all devices visible to a transport and exit #[clap(long)] list_devices: bool, @@ -146,7 +150,7 @@ fn gnerate_payload(args: &mut Args) -> Result { } }; - let mut payload = PayloadBuffer::new(); + let mut payload = PayloadBuffer::new(args.brightness.unwrap_or_default()); for message in config.messages { let mut style = Style::default(); @@ -164,6 +168,7 @@ fn gnerate_payload(args: &mut Args) -> Result { Point::new(0, 7), MonoTextStyle::new(&FONT_6X9, BinaryColor::On), ); + payload.add_message_drawable(style, &text); } Content::Bitstring { bitstring } => { diff --git a/src/protocol.rs b/src/protocol.rs index 706b55e..2a05dfb 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -1,7 +1,5 @@ //! Protocol used to update the badge -use std::num::TryFromIntError; - #[cfg(feature = "embedded-graphics")] use embedded_graphics::{ draw_target::DrawTarget, @@ -11,6 +9,7 @@ use embedded_graphics::{ primitives::Rectangle, Drawable, }; +use std::num::TryFromIntError; use time::OffsetDateTime; use zerocopy::{BigEndian, FromBytes, Immutable, IntoBytes, KnownLayout, U16}; @@ -54,7 +53,7 @@ impl Style { self } - /// Show a dotted border arround the display. + /// Show a dotted border around the display. /// ``` /// use badgemagic::protocol::Style; /// # ( @@ -161,7 +160,7 @@ impl TryFrom for Speed { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))] pub enum Mode { - /// Scroll thorugh the message from left to right + /// Scroll through the message from left to right #[default] Left, @@ -193,14 +192,39 @@ pub enum Mode { Laser, } +/// Display Brightness +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "cli", derive(clap::ValueEnum))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "PascalCase"))] +pub enum Brightness { + #[default] + Full, + ThreeQuarters, + Half, + OneQuarter, +} + +impl From for u8 { + fn from(value: Brightness) -> Self { + match value { + Brightness::Full => 0x00, + Brightness::ThreeQuarters => 0x10, + Brightness::Half => 0x20, + Brightness::OneQuarter => 0x30, + } + } +} + const MSG_PADDING_ALIGN: usize = 64; -const MAGIC: [u8; 6] = *b"wang\0\0"; +const MAGIC: [u8; 5] = *b"wang\0"; #[derive(FromBytes, IntoBytes, Immutable, KnownLayout)] #[repr(C)] struct Header { - magic: [u8; 6], + magic: [u8; 5], + brightness: u8, blink: u8, border: u8, speed_and_mode: [u8; 8], @@ -241,7 +265,7 @@ impl Timestamp { /// Buffer to create a payload /// -/// A payload consits of up to 8 messages +/// A payload consists of up to 8 messages /// ``` /// # #[cfg(feature = "embedded-graphics")] /// # fn main() { @@ -252,7 +276,7 @@ impl Timestamp { /// primitives::{PrimitiveStyle, Rectangle, Styled}, /// }; /// -/// let mut buffer = PayloadBuffer::new(); +/// let mut buffer = PayloadBuffer::default(); /// buffer.add_message_drawable( /// Style::default(), /// &Styled::new( @@ -271,18 +295,19 @@ pub struct PayloadBuffer { impl Default for PayloadBuffer { fn default() -> Self { - Self::new() + Self::new(Brightness::Full) } } impl PayloadBuffer { /// Create a new empty buffer #[must_use] - pub fn new() -> Self { + pub fn new(brightness: Brightness) -> Self { Self { num_messages: 0, data: Header { magic: MAGIC, + brightness: brightness.into(), blink: 0, border: 0, speed_and_mode: [0; 8], @@ -368,7 +393,7 @@ impl PayloadBuffer { &self.data } - /// Convert the payload buffe into bytes (with padding) + /// Convert the payload buffer into bytes (with padding) #[allow(clippy::missing_panics_doc)] // should never panic #[must_use] pub fn into_padded_bytes(self) -> impl AsRef<[u8]> {