189 lines
6.5 KiB
Rust
189 lines
6.5 KiB
Rust
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));
|
|
}
|
|
}
|