From 7d7048b671ce2689a4947891ef099f3d5310057f Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sat, 10 Sep 2022 17:35:10 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20DC=20OUT=20?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E4=BF=A1=E5=8F=B7=E8=BE=93=E5=87=BA=E6=8A=96?= =?UTF-8?q?=E5=8A=A8=E3=80=82Closed=20#4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/dc_out_controller.rs | 102 ++++++++++++++++++++------------------- src/main.rs | 2 +- 2 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/dc_out_controller.rs b/src/dc_out_controller.rs index 43e0a84..3f14c06 100644 --- a/src/dc_out_controller.rs +++ b/src/dc_out_controller.rs @@ -1,4 +1,8 @@ -use std::sync::{Arc, Mutex}; +use std::{ + sync::{ + Arc, Mutex, MutexGuard, + }, +}; use embedded_hal::digital::v2::{OutputPin, PinState}; use embedded_svc::event_bus::{EventBus, Postbox}; @@ -11,7 +15,7 @@ use esp_idf_sys::c_types; use log::{info, warn}; use serde_json::json; -use crate::{voltage_detection::{VoltageDetectionWorker, VOLTAGE_EVENTLOOP}}; +use crate::voltage_detection::{VoltageDetectionWorker, VOLTAGE_EVENTLOOP}; const WAITING_OFF_SECONDS: u8 = 60; @@ -132,8 +136,7 @@ impl DcOutControllerState { DcOutStatus::TurningOff(seconds) => seconds.into(), _ => -1, }; - json!({ "status": status, "pin_state": pin_state, "seconds": seconds }) - .to_string() + json!({ "status": status, "pin_state": pin_state, "seconds": seconds }).to_string() } } @@ -161,67 +164,67 @@ impl EspTypedEventDeserializer for DcOutControllerState { } } +type DcOutPin = Gpio6; + pub struct DcOutController { pub state: DcOutControllerState, voltage_subscription: Option>>, + pin: Arc>, } impl DcOutController { - fn new() -> Self { - Self { - state: DcOutControllerState::new(), - voltage_subscription: None, - } - } + pub fn new() -> anyhow::Result { + let mut pin = unsafe { Gpio6::::new() } + .into_output() + .map_err(|err| anyhow::anyhow!("Make Gpio6 Into output Failed. {}", err))?; - pub fn get_instance() -> anyhow::Result { - // if let Some(instance) = unsafe { &mut INSTANCE } { - // anyhow::Ok(*instance) - // } else { - let instance = Self::new(); - // unsafe { INSTANCE = Some(instance) }; match EspBackgroundEventLoop::new(&Default::default()) { Ok(eventloop) => unsafe { DC_OUT_STATE_EVENT_LOOP = Some(eventloop) }, Err(err) => anyhow::bail!("Init Event Loop failed. {:?}", err), } - anyhow::Ok(instance) - // } + + anyhow::Ok(Self { + state: DcOutControllerState::new(), + voltage_subscription: None, + pin: Arc::new(Mutex::new(pin)), + }) } pub fn watch(&mut self) -> anyhow::Result<()> { - let state = Arc::new(Mutex::new(self.state)); + let mut state = self.state.to_owned(); + let pin = self.pin.to_owned(); if let Some(event_loop) = unsafe { VOLTAGE_EVENTLOOP.as_mut() } { let voltage_subscription = event_loop - .subscribe( - move |obj: &VoltageDetectionWorker| match state.lock().as_mut() { - Ok(state) => { - if obj.adapter_voltage < 1000 { - if obj.battery_voltage < 1000 { - state.turn_off(); - } else { - state.handle_adapter_down(); - } - } else { - state.turn_on(); - } - let ref state = **state; - if let Err(err) = Self::output_ctl(*state) { + .subscribe(move |obj: &VoltageDetectionWorker| { + if obj.adapter_voltage < 1000 { + if obj.battery_voltage < 1000 { + state.turn_off(); + } else { + state.handle_adapter_down(); + } + } else { + state.turn_on(); + } + + match pin.lock() { + Ok(pin) => { + if let Err(err) = Self::output_ctl(state, pin) { warn!("Put Control Pin State Failed. {}", err); } - - if let Some(event_loop) = unsafe { DC_OUT_STATE_EVENT_LOOP.as_mut() } { - if let Err(err) = event_loop.post(state, None) { - warn!("Post DC Out Status Failed. {}", err); - } - } else { - warn!("DC_OUT_STATE_EVENT_LOOP is None"); - } - info!("status: {:?}", state); } - Err(err) => warn!("Can not lock state. {}", err), - }, - ) + Err(_) => todo!(), + } + + if let Some(event_loop) = unsafe { DC_OUT_STATE_EVENT_LOOP.as_mut() } { + if let Err(err) = event_loop.post(&state, None) { + warn!("Post DC Out Status Failed. {}", err); + } + } else { + warn!("DC_OUT_STATE_EVENT_LOOP is None"); + } + info!("status: {:?}", state); + }) .map_err(|err| anyhow::anyhow!("Subscribe Voltage Failed. {}", err))?; self.voltage_subscription = Some(voltage_subscription); } else { @@ -229,11 +232,10 @@ impl DcOutController { } anyhow::Ok(()) } - fn output_ctl(mut state: DcOutControllerState) -> anyhow::Result<()> { - let mut pin = unsafe { Gpio6::::new() } - .into_output() - .map_err(|err| anyhow::anyhow!("Make Gpio6 Into output Failed. {}", err))?; - + fn output_ctl( + mut state: DcOutControllerState, + mut pin: MutexGuard, + ) -> anyhow::Result<()> { if DcOutStatus::Off == state.status && state.pin_state == PinState::Low { pin.set_high() .map_err(|err| anyhow::anyhow!("Set DC Output Control Pin High Failed. {}", err))?; diff --git a/src/main.rs b/src/main.rs index bf05b10..40249ec 100644 --- a/src/main.rs +++ b/src/main.rs @@ -74,7 +74,7 @@ fn main() { let mut beep = Beep::new().unwrap(); let mut dc_out_controller = - DcOutController::get_instance().expect("Can not get DcOutController instance"); + DcOutController::new().expect("Can not get DcOutController instance"); dc_out_controller .watch() .expect("Can not watch for dc_out_controller");