mirror of
https://github.com/Djeeberjr/fw-anwesenheit.git
synced 2025-07-03 01:24:17 +00:00
refactored hardware components
detach trait from mock and hardware implementation
This commit is contained in:
parent
dc8fd22f0f
commit
efd096a149
@ -4,10 +4,10 @@ use smart_leds::colors::{GREEN, RED};
|
|||||||
use std::{error::Error, time::Duration};
|
use std::{error::Error, time::Duration};
|
||||||
use tokio::{join, time::sleep};
|
use tokio::{join, time::sleep};
|
||||||
|
|
||||||
use crate::{
|
use crate::hardware::{Buzzer, StatusLed};
|
||||||
buzzer::{Buzzer, GPIOBuzzer},
|
|
||||||
led::{SpiLed, StatusLed},
|
#[cfg(not(feature = "mock_pi"))]
|
||||||
};
|
use crate::{gpio_buzzer::GPIOBuzzer, spi_led::SpiLed};
|
||||||
|
|
||||||
#[cfg(feature = "mock_pi")]
|
#[cfg(feature = "mock_pi")]
|
||||||
use crate::mock::{MockBuzzer, MockLed};
|
use crate::mock::{MockBuzzer, MockLed};
|
||||||
|
@ -1,23 +1,17 @@
|
|||||||
use rppal::pwm::{Channel, Error, Polarity, Pwm};
|
use rppal::pwm::{Channel, Polarity, Pwm};
|
||||||
use std::{future::Future, time::Duration};
|
use std::{error::Error, time::Duration};
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
const DEFAULT_PWM_CHANNEL_BUZZER: Channel = Channel::Pwm0; //PWM0 = GPIO18/Physical pin 12
|
use crate::hardware::Buzzer;
|
||||||
|
|
||||||
pub trait Buzzer {
|
const DEFAULT_PWM_CHANNEL_BUZZER: Channel = Channel::Pwm0; //PWM0 = GPIO18/Physical pin 12
|
||||||
fn modulated_tone(
|
|
||||||
&mut self,
|
|
||||||
frequency_hz: f64,
|
|
||||||
duration: Duration,
|
|
||||||
) -> impl Future<Output = Result<(), Error>> + std::marker::Send;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GPIOBuzzer {
|
pub struct GPIOBuzzer {
|
||||||
pwm: Pwm,
|
pwm: Pwm,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GPIOBuzzer {
|
impl GPIOBuzzer {
|
||||||
pub fn new_from_channel(channel: Channel) -> Result<Self, Error> {
|
pub fn new_from_channel(channel: Channel) -> Result<Self, rppal::pwm::Error> {
|
||||||
// Enable with dummy values; we'll set frequency/duty in the tone method
|
// Enable with dummy values; we'll set frequency/duty in the tone method
|
||||||
let duty_cycle: f64 = 0.5;
|
let duty_cycle: f64 = 0.5;
|
||||||
let pwm = Pwm::with_frequency(channel, 1000.0, duty_cycle, Polarity::Normal, true)?;
|
let pwm = Pwm::with_frequency(channel, 1000.0, duty_cycle, Polarity::Normal, true)?;
|
||||||
@ -26,13 +20,17 @@ impl GPIOBuzzer {
|
|||||||
Ok(GPIOBuzzer { pwm })
|
Ok(GPIOBuzzer { pwm })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_default() -> Result<Self, Error> {
|
pub fn new_default() -> Result<Self, rppal::pwm::Error> {
|
||||||
Self::new_from_channel(DEFAULT_PWM_CHANNEL_BUZZER)
|
Self::new_from_channel(DEFAULT_PWM_CHANNEL_BUZZER)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Buzzer for GPIOBuzzer {
|
impl Buzzer for GPIOBuzzer {
|
||||||
async fn modulated_tone(&mut self, frequency_hz: f64, duration: Duration) -> Result<(), Error> {
|
async fn modulated_tone(
|
||||||
|
&mut self,
|
||||||
|
frequency_hz: f64,
|
||||||
|
duration: Duration,
|
||||||
|
) -> Result<(), Box<dyn Error>> {
|
||||||
self.pwm.set_frequency(frequency_hz, 0.5)?; // 50% duty cycle (square wave)
|
self.pwm.set_frequency(frequency_hz, 0.5)?; // 50% duty cycle (square wave)
|
||||||
self.pwm.enable()?;
|
self.pwm.enable()?;
|
||||||
sleep(duration).await;
|
sleep(duration).await;
|
47
src/hardware.rs
Normal file
47
src/hardware.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use std::{error::Error, time::Duration};
|
||||||
|
|
||||||
|
use crate::hotspot::{HotspotError};
|
||||||
|
|
||||||
|
#[cfg(feature = "mock_pi")]
|
||||||
|
use crate::mock::MockHotspot;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_pi"))]
|
||||||
|
use crate::hotspot::NMHotspot;
|
||||||
|
|
||||||
|
pub trait StatusLed {
|
||||||
|
fn turn_off(&mut self) -> Result<(), Box<dyn Error>>;
|
||||||
|
|
||||||
|
fn turn_on(&mut self, color: rgb::RGB8) -> Result<(), Box<dyn Error>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Buzzer {
|
||||||
|
fn modulated_tone(
|
||||||
|
&mut self,
|
||||||
|
frequency_hz: f64,
|
||||||
|
duration: Duration,
|
||||||
|
) -> impl Future<Output = Result<(), Box<dyn Error>>> + std::marker::Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Hotspot {
|
||||||
|
fn enable_hotspot(
|
||||||
|
&self,
|
||||||
|
) -> impl std::future::Future<Output = Result<(), HotspotError>> + std::marker::Send;
|
||||||
|
|
||||||
|
fn disable_hotspot(
|
||||||
|
&self,
|
||||||
|
) -> impl std::future::Future<Output = Result<(), HotspotError>> + std::marker::Send;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a struct to manage the hotspot
|
||||||
|
/// Respects the `mock_pi` flag.
|
||||||
|
pub fn create_hotspot() -> Result<impl Hotspot, HotspotError> {
|
||||||
|
#[cfg(feature = "mock_pi")]
|
||||||
|
{
|
||||||
|
Ok(MockHotspot {})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "mock_pi"))]
|
||||||
|
{
|
||||||
|
NMHotspot::new_from_env()
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,8 @@ use std::{
|
|||||||
};
|
};
|
||||||
use tokio::process::Command;
|
use tokio::process::Command;
|
||||||
|
|
||||||
|
use crate::hardware::Hotspot;
|
||||||
|
|
||||||
const SSID: &str = "fwa";
|
const SSID: &str = "fwa";
|
||||||
const CON_NAME: &str = "fwa-hotspot";
|
const CON_NAME: &str = "fwa-hotspot";
|
||||||
const PASSWORD: &str = "a9LG2kUVrsRRVUo1";
|
const PASSWORD: &str = "a9LG2kUVrsRRVUo1";
|
||||||
@ -41,16 +43,6 @@ impl fmt::Display for HotspotError {
|
|||||||
|
|
||||||
impl std::error::Error for HotspotError {}
|
impl std::error::Error for HotspotError {}
|
||||||
|
|
||||||
pub trait Hotspot {
|
|
||||||
fn enable_hotspot(
|
|
||||||
&self,
|
|
||||||
) -> impl std::future::Future<Output = Result<(), HotspotError>> + std::marker::Send;
|
|
||||||
|
|
||||||
fn disable_hotspot(
|
|
||||||
&self,
|
|
||||||
) -> impl std::future::Future<Output = Result<(), HotspotError>> + std::marker::Send;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// NetworkManager Hotspot
|
/// NetworkManager Hotspot
|
||||||
pub struct NMHotspot {
|
pub struct NMHotspot {
|
||||||
ssid: String,
|
ssid: String,
|
||||||
|
26
src/main.rs
26
src/main.rs
@ -1,6 +1,8 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use activity_fairing::{ActivityNotifier, spawn_idle_watcher};
|
use activity_fairing::{ActivityNotifier, spawn_idle_watcher};
|
||||||
use feedback::{Feedback, FeedbackImpl};
|
use feedback::{Feedback, FeedbackImpl};
|
||||||
use hotspot::{Hotspot, HotspotError, NMHotspot};
|
use hardware::{Hotspot, create_hotspot};
|
||||||
use id_store::IDStore;
|
use id_store::IDStore;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use pm3::run_pm3;
|
use pm3::run_pm3;
|
||||||
@ -16,39 +18,23 @@ use tokio::{
|
|||||||
};
|
};
|
||||||
use webserver::start_webserver;
|
use webserver::start_webserver;
|
||||||
|
|
||||||
#[cfg(feature = "mock_pi")]
|
|
||||||
use mock::MockHotspot;
|
|
||||||
|
|
||||||
mod activity_fairing;
|
mod activity_fairing;
|
||||||
mod buzzer;
|
|
||||||
mod feedback;
|
mod feedback;
|
||||||
|
mod gpio_buzzer;
|
||||||
|
mod hardware;
|
||||||
mod hotspot;
|
mod hotspot;
|
||||||
mod id_mapping;
|
mod id_mapping;
|
||||||
mod id_store;
|
mod id_store;
|
||||||
mod led;
|
|
||||||
mod logger;
|
mod logger;
|
||||||
mod mock;
|
mod mock;
|
||||||
mod parser;
|
mod parser;
|
||||||
mod pm3;
|
mod pm3;
|
||||||
|
mod spi_led;
|
||||||
mod tally_id;
|
mod tally_id;
|
||||||
mod webserver;
|
mod webserver;
|
||||||
|
|
||||||
const STORE_PATH: &str = "./data.json";
|
const STORE_PATH: &str = "./data.json";
|
||||||
|
|
||||||
/// Create a struct to manage the hotspot
|
|
||||||
/// Respects the `mock_pi` flag.
|
|
||||||
fn create_hotspot() -> Result<impl Hotspot, HotspotError> {
|
|
||||||
#[cfg(feature = "mock_pi")]
|
|
||||||
{
|
|
||||||
Ok(MockHotspot {})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "mock_pi"))]
|
|
||||||
{
|
|
||||||
NMHotspot::new_from_env()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn run_webserver<H>(
|
async fn run_webserver<H>(
|
||||||
store: Arc<Mutex<IDStore>>,
|
store: Arc<Mutex<IDStore>>,
|
||||||
id_channel: Sender<String>,
|
id_channel: Sender<String>,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
use std::time::Duration;
|
use std::{error::Error, time::Duration};
|
||||||
|
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
use crate::{buzzer::Buzzer, hotspot::Hotspot, led::StatusLed};
|
use crate::hardware::{Buzzer, Hotspot, StatusLed};
|
||||||
|
|
||||||
pub struct MockBuzzer {}
|
pub struct MockBuzzer {}
|
||||||
|
|
||||||
@ -12,7 +12,7 @@ impl Buzzer for MockBuzzer {
|
|||||||
&mut self,
|
&mut self,
|
||||||
frequency_hz: f64,
|
frequency_hz: f64,
|
||||||
duration: Duration,
|
duration: Duration,
|
||||||
) -> Result<(), rppal::pwm::Error> {
|
) -> Result<(), Box<dyn Error>> {
|
||||||
debug!("MockBuzzer: modulte tone: {frequency_hz} Hz");
|
debug!("MockBuzzer: modulte tone: {frequency_hz} Hz");
|
||||||
sleep(duration).await;
|
sleep(duration).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -3,14 +3,10 @@ use smart_leds::SmartLedsWrite;
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use ws2812_spi::Ws2812;
|
use ws2812_spi::Ws2812;
|
||||||
|
|
||||||
|
use crate::hardware::StatusLed;
|
||||||
|
|
||||||
const SPI_CLOCK_SPEED: u32 = 3_800_000;
|
const SPI_CLOCK_SPEED: u32 = 3_800_000;
|
||||||
|
|
||||||
pub trait StatusLed {
|
|
||||||
fn turn_off(&mut self) -> Result<(), Box<dyn Error>>;
|
|
||||||
|
|
||||||
fn turn_on(&mut self, color: rgb::RGB8) -> Result<(), Box<dyn Error>>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SpiLed {
|
pub struct SpiLed {
|
||||||
controller: Ws2812<Spi>,
|
controller: Ws2812<Spi>,
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user