ups-esp32c3-rust/src/main.rs

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));
}
}