feat: 支持定期向板子发送显示器亮度信息。
This commit is contained in:
parent
3a23e1760b
commit
98d2f7891a
@ -1,8 +1,4 @@
|
|||||||
use std::{
|
use std::{env::current_dir, sync::Arc, time::Duration};
|
||||||
env::current_dir,
|
|
||||||
sync::Arc,
|
|
||||||
time::{Duration, SystemTime},
|
|
||||||
};
|
|
||||||
|
|
||||||
use ddc_hi::Display;
|
use ddc_hi::Display;
|
||||||
use paris::{error, info, warn};
|
use paris::{error, info, warn};
|
||||||
@ -60,12 +56,28 @@ impl DisplayManager {
|
|||||||
loop {
|
loop {
|
||||||
tokio::time::sleep(Duration::from_secs(10)).await;
|
tokio::time::sleep(Duration::from_secs(10)).await;
|
||||||
Self::save_states(displays.clone()).await;
|
Self::save_states(displays.clone()).await;
|
||||||
|
Self::send_displays_changed(displays.clone()).await;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.auto_save_state_handler = Some(handler);
|
self.auto_save_state_handler = Some(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn send_displays_changed(displays: Arc<RwLock<Vec<Arc<RwLock<DisplayHandler>>>>>) {
|
||||||
|
let mut states = Vec::new();
|
||||||
|
|
||||||
|
for display in displays.read().await.iter() {
|
||||||
|
let state = display.read().await.state.read().await.clone();
|
||||||
|
states.push(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
let channel = BoardMessageChannels::global().await;
|
||||||
|
let tx = channel.displays_changed_sender.clone();
|
||||||
|
if let Err(err) = tx.send(states) {
|
||||||
|
error!("Failed to send displays changed: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async fn fetch_displays(&self) {
|
async fn fetch_displays(&self) {
|
||||||
let mut displays = self.displays.write().await;
|
let mut displays = self.displays.write().await;
|
||||||
displays.clear();
|
displays.clear();
|
||||||
@ -244,7 +256,7 @@ impl DisplayManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
log::info!(
|
log::debug!(
|
||||||
"save display config. store displays: {}, online displays: {}",
|
"save display config. store displays: {}, online displays: {}",
|
||||||
wrapper.states.len(),
|
wrapper.states.len(),
|
||||||
displays.len()
|
displays.len()
|
||||||
|
@ -3,7 +3,7 @@ use std::{sync::Arc, time::Duration};
|
|||||||
use paris::{error, info, warn};
|
use paris::{error, info, warn};
|
||||||
use tokio::{io, net::UdpSocket, sync::RwLock, task::yield_now, time::timeout};
|
use tokio::{io, net::UdpSocket, sync::RwLock, task::yield_now, time::timeout};
|
||||||
|
|
||||||
use crate::{rpc::DisplaySettingRequest, volume::VolumeManager};
|
use crate::{rpc::DisplaySettingRequest, volume::{VolumeManager, self}};
|
||||||
|
|
||||||
use super::{BoardConnectStatus, BoardInfo, BoardMessageChannels};
|
use super::{BoardConnectStatus, BoardInfo, BoardMessageChannels};
|
||||||
|
|
||||||
@ -13,6 +13,7 @@ pub struct Board {
|
|||||||
socket: Option<Arc<UdpSocket>>,
|
socket: Option<Arc<UdpSocket>>,
|
||||||
listen_handler: Option<tokio::task::JoinHandle<()>>,
|
listen_handler: Option<tokio::task::JoinHandle<()>>,
|
||||||
volume_changed_subscriber_handler: Option<tokio::task::JoinHandle<()>>,
|
volume_changed_subscriber_handler: Option<tokio::task::JoinHandle<()>>,
|
||||||
|
state_of_displays_changed_subscriber_handler: Option<tokio::task::JoinHandle<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Board {
|
impl Board {
|
||||||
@ -22,6 +23,7 @@ impl Board {
|
|||||||
socket: None,
|
socket: None,
|
||||||
listen_handler: None,
|
listen_handler: None,
|
||||||
volume_changed_subscriber_handler: None,
|
volume_changed_subscriber_handler: None,
|
||||||
|
state_of_displays_changed_subscriber_handler: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +82,7 @@ impl Board {
|
|||||||
self.listen_handler = Some(handler);
|
self.listen_handler = Some(handler);
|
||||||
|
|
||||||
self.subscribe_volume_changed().await;
|
self.subscribe_volume_changed().await;
|
||||||
|
self.state_of_displays_changed().await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -91,7 +94,23 @@ impl Board {
|
|||||||
let socket = self.socket.clone();
|
let socket = self.socket.clone();
|
||||||
|
|
||||||
let handler = tokio::spawn(async move {
|
let handler = tokio::spawn(async move {
|
||||||
while let Ok(volume) = volume_changed_rx.recv().await {
|
loop {
|
||||||
|
let volume: Result<f32, tokio::sync::broadcast::error::RecvError> = volume_changed_rx.recv().await;
|
||||||
|
if let Err(err) = volume {
|
||||||
|
match err {
|
||||||
|
tokio::sync::broadcast::error::RecvError::Closed => {
|
||||||
|
log::error!("volume changed channel closed");
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
tokio::sync::broadcast::error::RecvError::Lagged(_) => {
|
||||||
|
log::info!("volume changed channel lagged");
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let volume = volume.unwrap();
|
||||||
|
|
||||||
let info = info.read().await;
|
let info = info.read().await;
|
||||||
if socket.is_none() || info.connect_status != BoardConnectStatus::Connected {
|
if socket.is_none() || info.connect_status != BoardConnectStatus::Connected {
|
||||||
log::info!("board is not connected, skip send volume changed");
|
log::info!("board is not connected, skip send volume changed");
|
||||||
@ -125,6 +144,56 @@ impl Board {
|
|||||||
self.volume_changed_subscriber_handler = Some(handler);
|
self.volume_changed_subscriber_handler = Some(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn state_of_displays_changed(&mut self) {
|
||||||
|
let channel: &BoardMessageChannels = BoardMessageChannels::global().await;
|
||||||
|
let mut state_of_displays_changed_rx = channel.displays_changed_sender.subscribe();
|
||||||
|
let info = self.info.clone();
|
||||||
|
let socket = self.socket.clone();
|
||||||
|
|
||||||
|
let handler = tokio::spawn(async move {
|
||||||
|
loop {
|
||||||
|
let states: Result<Vec<crate::display::DisplayState>, tokio::sync::broadcast::error::RecvError> = state_of_displays_changed_rx.recv().await;
|
||||||
|
if let Err(err) = states {
|
||||||
|
match err {
|
||||||
|
tokio::sync::broadcast::error::RecvError::Closed => {
|
||||||
|
log::error!("state of displays changed channel closed");
|
||||||
|
break;
|
||||||
|
},
|
||||||
|
tokio::sync::broadcast::error::RecvError::Lagged(_) => {
|
||||||
|
log::info!("state of displays changed channel lagged");
|
||||||
|
continue;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let info = info.read().await;
|
||||||
|
if socket.is_none() || info.connect_status != BoardConnectStatus::Connected {
|
||||||
|
log::info!("board is not connected, skip send state of displays changed");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let socket = socket.as_ref().unwrap();
|
||||||
|
|
||||||
|
let mut buf = [0u8; 3];
|
||||||
|
let states = states.unwrap();
|
||||||
|
for (index, state) in states.iter().enumerate() {
|
||||||
|
buf[0] = 3;
|
||||||
|
buf[1] = index as u8;
|
||||||
|
buf[2] = state.brightness as u8;
|
||||||
|
|
||||||
|
log::info!("send state of displays changed: {:?}", &buf[..]);
|
||||||
|
|
||||||
|
if let Err(err) = socket.send(&buf).await {
|
||||||
|
log::warn!("send state of displays changed failed: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.state_of_displays_changed_subscriber_handler = Some(handler);
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn send_colors(&self, buf: &[u8]) {
|
pub async fn send_colors(&self, buf: &[u8]) {
|
||||||
let info = self.info.read().await;
|
let info = self.info.read().await;
|
||||||
if self.socket.is_none() || info.connect_status != BoardConnectStatus::Connected {
|
if self.socket.is_none() || info.connect_status != BoardConnectStatus::Connected {
|
||||||
@ -204,5 +273,10 @@ impl Drop for Board {
|
|||||||
if let Some(handler) = self.volume_changed_subscriber_handler.take() {
|
if let Some(handler) = self.volume_changed_subscriber_handler.take() {
|
||||||
handler.abort();
|
handler.abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(handler) = self.state_of_displays_changed_subscriber_handler.take() {
|
||||||
|
handler.abort();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,15 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use tokio::sync::{broadcast, OnceCell};
|
use tokio::sync::{broadcast, OnceCell};
|
||||||
|
|
||||||
|
use crate::display::DisplayState;
|
||||||
|
|
||||||
use super::DisplaySettingRequest;
|
use super::DisplaySettingRequest;
|
||||||
|
|
||||||
pub struct BoardMessageChannels {
|
pub struct BoardMessageChannels {
|
||||||
pub display_setting_request_sender: Arc<broadcast::Sender<DisplaySettingRequest>>,
|
pub display_setting_request_sender: Arc<broadcast::Sender<DisplaySettingRequest>>,
|
||||||
pub volume_setting_request_sender: Arc<broadcast::Sender<f32>>,
|
pub volume_setting_request_sender: Arc<broadcast::Sender<f32>>,
|
||||||
pub volume_changed_sender: Arc<broadcast::Sender<f32>>,
|
pub volume_changed_sender: Arc<broadcast::Sender<f32>>,
|
||||||
|
pub displays_changed_sender: Arc<broadcast::Sender<Vec<DisplayState>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BoardMessageChannels {
|
impl BoardMessageChannels {
|
||||||
@ -27,10 +30,14 @@ impl BoardMessageChannels {
|
|||||||
let (volume_changed_sender, _) = broadcast::channel(2);
|
let (volume_changed_sender, _) = broadcast::channel(2);
|
||||||
let volume_changed_sender = Arc::new(volume_changed_sender);
|
let volume_changed_sender = Arc::new(volume_changed_sender);
|
||||||
|
|
||||||
|
let (displays_changed_sender, _) = broadcast::channel(2);
|
||||||
|
let displays_changed_sender = Arc::new(displays_changed_sender);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
display_setting_request_sender,
|
display_setting_request_sender,
|
||||||
volume_setting_request_sender,
|
volume_setting_request_sender,
|
||||||
volume_changed_sender,
|
volume_changed_sender,
|
||||||
|
displays_changed_sender,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user