use embedded_svc::event_bus::{EventBus}; use esp_idf_svc::eventloop::{EspBackgroundEventLoop}; use esp_idf_sys::{self as _}; use log::*; use std::{ env, thread::{self, sleep}, time::Duration, }; mod beep; mod blink; mod dc_out_controller; mod message_queue; mod time; mod voltage_detection; mod wifi; mod charge_controller; use crate::{ beep::{ringtone, Beep}, dc_out_controller::{DcOutController, DcOutControllerState, DC_OUT_STATE_EVENT_LOOP}, message_queue::MqDto, voltage_detection::{VoltageDetectionWorker, VOLTAGE_EVENTLOOP}, charge_controller::{CHARGE_STATE_EVENT_LOOP, ChargeControllerState, ChargeController}, }; use crate::{ message_queue::MessageQueue, time::Time, voltage_detection::VoltageDetection, wifi::Internet, }; fn main() { env::set_var("DEFMT_LOG", "trace"); env::set_var("RUST_BACKTRACE", "1"); env::set_var("RUST_LOG", "trace"); env_logger::init(); // Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once, // or else some patches to the runtime implemented by esp-idf-sys might not link properly. esp_idf_sys::link_patches(); info!("Hello, world!"); let peripherals = esp_idf_hal::peripherals::Peripherals::take().unwrap(); let blink_pin = peripherals.pins.gpio5; match EspBackgroundEventLoop::new(&Default::default()) { Ok(eventloop) => unsafe { VOLTAGE_EVENTLOOP = Some(eventloop) }, Err(err) => error!("Init Event Loop failed. {:?}", err), }; thread::spawn(move || { let mut blink = blink::Blink::new( blink_pin .into_output() .expect("Failed to set GPIO5 as output"), ); blink.play(); }); let voltage_detection = VoltageDetection::new(); voltage_detection.unwrap() .watching() .expect("Can not watch voltages."); let _wifi = Internet::new().unwrap(); let mut time = Time::new(); time.sync().unwrap(); sleep(Duration::from_millis(100)); let mut beep = Beep::new().unwrap(); let mut dc_out_controller = DcOutController::new().expect("Can not get DcOutController instance"); dc_out_controller .watch() .expect("Can not watch for dc_out_controller"); let mut charge_controller = ChargeController::new().expect("Can not get ChargeController instance"); charge_controller .watch() .expect("Can not watch for charge_controller"); sleep(Duration::from_millis(100)); let mut _mq = MessageQueue::new(); let _mq_subscription; match _mq.watch() { Err(err) => { error!("Can not watch MessageQueue. {}", err); } Ok(subscription) => _mq_subscription = subscription, } let _mq_tx_for_voltage = _mq.tx.clone(); let _mq_tx_for_dc_out_state = _mq.tx.clone(); let _mq_tx_for_charge_state = _mq.tx.clone(); let _voltage_subscription; if let Some(voltage_event_loop) = unsafe { VOLTAGE_EVENTLOOP.as_mut() } { _voltage_subscription = voltage_event_loop .subscribe(move |message: &VoltageDetectionWorker| { if let Ok(json_str) = serde_json::to_string(&message) { match _mq_tx_for_voltage.lock() { Ok(tx) => { let result = tx.send(MqDto { topic: "voltage".to_string(), message: json_str, }); if let Err(err) = result { warn!("send voltage to mq message failed. {}", err) } } Err(err) => warn!("send voltage to mq message failed. {}", err), } } }) .expect(" Listening Event Loop Failed"); } else { panic!("VOLTAGE_EVENTLOOP is undefined!"); } let _dc_out_state_subscription; if let Some(dc_state_event_loop) = unsafe { DC_OUT_STATE_EVENT_LOOP.as_mut() } { _dc_out_state_subscription = dc_state_event_loop .subscribe(move |message: &DcOutControllerState| { match message.status { dc_out_controller::DcOutStatus::WaitingOff => { beep.play(ringtone::ADAPTER_DOWN).expect("Can not beep.") } dc_out_controller::DcOutStatus::WaitingOn(_) => { beep.play(ringtone::BATTERY_LOW).expect("Can not beep.") } dc_out_controller::DcOutStatus::TurningOff(_) => { beep.play(ringtone::SHUTDOWN).expect("Can not beep.") } _ => beep.play(ringtone::SILENCE).expect("Can not beep."), } match _mq_tx_for_dc_out_state.lock() { Ok(tx) => { let result = tx.send(MqDto { topic: "dc_out_state".to_string(), message: message.to_json(), }); if let Err(err) = result { warn!("send dc_out_state message failed. {}", err) } } Err(err) => warn!("send dc_out_state to mq message failed. {}", err), } }) .expect(" Listening Event Loop Failed"); } else { panic!("DC_OUT_STATE_EVENT_LOOP is undefined!"); } let _charge_state_subscription; if let Some(charge_state_event_loop) = unsafe { CHARGE_STATE_EVENT_LOOP.as_mut() } { _charge_state_subscription = charge_state_event_loop .subscribe(move |message: &ChargeControllerState| { match _mq_tx_for_charge_state.lock() { Ok(tx) => { let result = tx.send(MqDto { topic: "charge_state".to_string(), message: message.to_json(), }); if let Err(err) = result { warn!("send charge_state message failed. {}", err) } } Err(err) => warn!("send charge_state to mq message failed. {}", err), } }) .expect(" Listening Event Loop Failed"); } else { panic!("CHARGE_STATE_EVENT_LOOP is undefined!"); } loop { sleep(Duration::from_millis(100)); } }