chore: 改为单独 task 推送灯条颜色。
This commit is contained in:
parent
7a87748cf1
commit
3deb14823d
@ -1,4 +1,4 @@
|
|||||||
use std::{borrow::Borrow, collections::HashMap, io::Read, sync::Arc, time::Duration};
|
use std::{collections::HashMap, sync::Arc, time::Duration};
|
||||||
|
|
||||||
use paris::warn;
|
use paris::warn;
|
||||||
use tauri::async_runtime::RwLock;
|
use tauri::async_runtime::RwLock;
|
||||||
@ -10,7 +10,7 @@ use tokio::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ambient_light::{config, ConfigManager},
|
ambient_light::{config, ConfigManager},
|
||||||
rpc::MqttRpc,
|
led_color::LedColor,
|
||||||
screenshot::LedSamplePoints,
|
screenshot::LedSamplePoints,
|
||||||
screenshot_manager::{self, ScreenshotManager},
|
screenshot_manager::{self, ScreenshotManager},
|
||||||
};
|
};
|
||||||
@ -103,52 +103,24 @@ impl LedColorsPublisher {
|
|||||||
|
|
||||||
let colors: Vec<crate::led_color::LedColor> = colors.unwrap();
|
let colors: Vec<crate::led_color::LedColor> = colors.unwrap();
|
||||||
|
|
||||||
// let color_len = colors.len();
|
let colors_copy = colors.clone();
|
||||||
let display_led_offset = mappers
|
|
||||||
.clone()
|
|
||||||
.iter()
|
|
||||||
.flat_map(|mapper| [mapper.start, mapper.end])
|
|
||||||
.min()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
for group in mappers.clone() {
|
let mappers = mappers.clone();
|
||||||
if (group.start.abs_diff(group.end)) > colors.len() {
|
|
||||||
warn!(
|
|
||||||
"get_sorted_colors: color_index out of range. color_index: {}, strip len: {}, colors.len(): {}",
|
|
||||||
group.pos,
|
|
||||||
group.start.abs_diff(group.end),
|
|
||||||
colors.len()
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let group_size = group.start.abs_diff(group.end);
|
tokio::spawn(async move {
|
||||||
let mut buffer = Vec::<u8>::with_capacity(group_size * 3);
|
match Self::send_colors_by_display(colors, mappers).await {
|
||||||
|
Ok(_) => {
|
||||||
if group.end > group.start {
|
log::info!("sent colors: #{: >15}", display_id);
|
||||||
for i in group.pos-display_led_offset..group_size + group.pos-display_led_offset {
|
|
||||||
let bytes = colors[i].as_bytes();
|
|
||||||
buffer.append(&mut bytes.to_vec());
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
for i in (group.pos-display_led_offset..group_size + group.pos-display_led_offset).rev() {
|
|
||||||
let bytes = colors[i].as_bytes();
|
|
||||||
buffer.append(&mut bytes.to_vec());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match Self::send_colors((group.start.min(group.end)) as u16, buffer).await {
|
|
||||||
Ok(_) => {}
|
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("Failed to send colors: {}", err);
|
warn!("Failed to send colors: #{: >15}\t{}", display_id, err);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
log::info!("sent colors: #{: >15} {:?}", display_id, colors.len());
|
|
||||||
|
|
||||||
match display_colors_tx.send((
|
match display_colors_tx.send((
|
||||||
display_id,
|
display_id,
|
||||||
colors
|
colors_copy
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|color| color.get_rgb())
|
.map(|color| color.get_rgb())
|
||||||
.flatten()
|
.flatten()
|
||||||
@ -292,27 +264,6 @@ impl LedColorsPublisher {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// let rx = self.sorted_colors_rx.clone();
|
|
||||||
// tokio::spawn(async move {
|
|
||||||
// let mut rx = rx.read().await.clone();
|
|
||||||
// loop {
|
|
||||||
// if let Err(err) = rx.changed().await {
|
|
||||||
// warn!("rx changed error: {}", err);
|
|
||||||
// sleep(Duration::from_millis(1000)).await;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let colors = rx.borrow().clone();
|
|
||||||
|
|
||||||
// match Self::send_colors(colors).await {
|
|
||||||
// Ok(_) => {}
|
|
||||||
// Err(err) => {
|
|
||||||
// warn!("colors send failed: {}", err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_colors(offset: u16, mut payload: Vec<u8>) -> anyhow::Result<()> {
|
pub async fn send_colors(offset: u16, mut payload: Vec<u8>) -> anyhow::Result<()> {
|
||||||
@ -329,6 +280,65 @@ impl LedColorsPublisher {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn send_colors_by_display(
|
||||||
|
colors: Vec<LedColor>,
|
||||||
|
mappers: Vec<SamplePointMapper>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
// let color_len = colors.len();
|
||||||
|
let display_led_offset = mappers
|
||||||
|
.clone()
|
||||||
|
.iter()
|
||||||
|
.flat_map(|mapper| [mapper.start, mapper.end])
|
||||||
|
.min()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let socket = UdpSocket::bind("0.0.0.0:0").await?;
|
||||||
|
for group in mappers.clone() {
|
||||||
|
if (group.start.abs_diff(group.end)) > colors.len() {
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"get_sorted_colors: color_index out of range. color_index: {}, strip len: {}, colors.len(): {}",
|
||||||
|
group.pos,
|
||||||
|
group.start.abs_diff(group.end),
|
||||||
|
colors.len()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let group_size = group.start.abs_diff(group.end);
|
||||||
|
let mut buffer = Vec::<u8>::with_capacity(group_size * 3);
|
||||||
|
|
||||||
|
if group.end > group.start {
|
||||||
|
for i in group.pos - display_led_offset..group_size + group.pos - display_led_offset
|
||||||
|
{
|
||||||
|
let bytes = colors[i].as_bytes();
|
||||||
|
buffer.append(&mut bytes.to_vec());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i in (group.pos - display_led_offset
|
||||||
|
..group_size + group.pos - display_led_offset)
|
||||||
|
.rev()
|
||||||
|
{
|
||||||
|
let bytes = colors[i].as_bytes();
|
||||||
|
buffer.append(&mut bytes.to_vec());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let offset = group.start.min(group.end);
|
||||||
|
let mut tx_buffer = vec![2];
|
||||||
|
tx_buffer.push((offset >> 8) as u8);
|
||||||
|
tx_buffer.push((offset & 0xff) as u8);
|
||||||
|
tx_buffer.append(&mut buffer);
|
||||||
|
socket.send_to(&tx_buffer, "192.168.31.206:23042").await?;
|
||||||
|
match Self::send_colors((group.start.min(group.end)) as u16, buffer).await {
|
||||||
|
Ok(_) => {}
|
||||||
|
Err(err) => {
|
||||||
|
warn!("Failed to send colors: {}", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn clone_sorted_colors_receiver(&self) -> watch::Receiver<Vec<u8>> {
|
pub async fn clone_sorted_colors_receiver(&self) -> watch::Receiver<Vec<u8>> {
|
||||||
self.sorted_colors_rx.read().await.clone()
|
self.sorted_colors_rx.read().await.clone()
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::ops::Index;
|
|
||||||
|
|
||||||
use color_space::{Hsv, Rgb};
|
use color_space::{Hsv, Rgb};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ mod screenshot_manager;
|
|||||||
use ambient_light::{Border, ColorCalibration, LedStripConfig, LedStripConfigGroup};
|
use ambient_light::{Border, ColorCalibration, LedStripConfig, LedStripConfigGroup};
|
||||||
use display_info::DisplayInfo;
|
use display_info::DisplayInfo;
|
||||||
use paris::{error, info, warn};
|
use paris::{error, info, warn};
|
||||||
|
use rpc::MqttRpc;
|
||||||
use screenshot::Screenshot;
|
use screenshot::Screenshot;
|
||||||
use screenshot_manager::ScreenshotManager;
|
use screenshot_manager::ScreenshotManager;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -197,6 +198,8 @@ async fn main() {
|
|||||||
let led_color_publisher = ambient_light::LedColorsPublisher::global().await;
|
let led_color_publisher = ambient_light::LedColorsPublisher::global().await;
|
||||||
led_color_publisher.start();
|
led_color_publisher.start();
|
||||||
|
|
||||||
|
let _mqtt = MqttRpc::global().await;
|
||||||
|
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
greet,
|
greet,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use paho_mqtt as mqtt;
|
use paho_mqtt as mqtt;
|
||||||
use paris::{error, info, warn};
|
use paris::{info, warn};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use time::{format_description, OffsetDateTime};
|
use time::{format_description, OffsetDateTime};
|
||||||
@ -9,8 +9,6 @@ use crate::ambient_light::{ColorCalibration, ConfigManager};
|
|||||||
|
|
||||||
const DISPLAY_TOPIC: &'static str = "display-ambient-light/display";
|
const DISPLAY_TOPIC: &'static str = "display-ambient-light/display";
|
||||||
const DESKTOP_TOPIC: &'static str = "display-ambient-light/desktop";
|
const DESKTOP_TOPIC: &'static str = "display-ambient-light/desktop";
|
||||||
const DISPLAY_BRIGHTNESS_TOPIC: &'static str = "display-ambient-light/board/brightness";
|
|
||||||
const BOARD_SEND_CMD: &'static str = "display-ambient-light/board/cmd";
|
|
||||||
const COLOR_CALIBRATION: &'static str = "display-ambient-light/desktop/color-calibration";
|
const COLOR_CALIBRATION: &'static str = "display-ambient-light/desktop/color-calibration";
|
||||||
|
|
||||||
pub struct MqttRpc {
|
pub struct MqttRpc {
|
||||||
@ -43,7 +41,7 @@ impl MqttRpc {
|
|||||||
|
|
||||||
client.subscribe(format!("{}/#", DISPLAY_TOPIC), mqtt::QOS_1);
|
client.subscribe(format!("{}/#", DISPLAY_TOPIC), mqtt::QOS_1);
|
||||||
});
|
});
|
||||||
client.set_connection_lost_callback(|client| {
|
client.set_connection_lost_callback(|_| {
|
||||||
info!("MQTT server connection lost.");
|
info!("MQTT server connection lost.");
|
||||||
});
|
});
|
||||||
client.set_disconnected_callback(|_, a1, a2| {
|
client.set_disconnected_callback(|_, a1, a2| {
|
||||||
@ -91,101 +89,12 @@ impl MqttRpc {
|
|||||||
Ok(Self { client })
|
Ok(Self { client })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn listen(&self) {
|
|
||||||
// let change_display_brightness_tx2 = self.change_display_brightness_tx.clone();
|
|
||||||
// let message_tx_cloned = self.message_tx.clone();
|
|
||||||
|
|
||||||
// let mut stream = self.client.to_owned().get_stream(100);
|
|
||||||
|
|
||||||
// while let Some(notification) = stream.next().await {
|
|
||||||
// match notification {
|
|
||||||
// Some(notification) => match notification.topic() {
|
|
||||||
// DISPLAY_BRIGHTNESS_TOPIC => {
|
|
||||||
// let payload_text = String::from_utf8(notification.payload().to_vec());
|
|
||||||
// match payload_text {
|
|
||||||
// Ok(payload_text) => {
|
|
||||||
// let display_brightness: Result<display::DisplayBrightness, _> =
|
|
||||||
// serde_json::from_str(payload_text.as_str());
|
|
||||||
// match display_brightness {
|
|
||||||
// Ok(display_brightness) => {
|
|
||||||
// match change_display_brightness_tx2.send(display_brightness)
|
|
||||||
// {
|
|
||||||
// Ok(_) => {}
|
|
||||||
// Err(err) => {
|
|
||||||
// warn!(
|
|
||||||
// "can not send display brightness to channel. {:?}",
|
|
||||||
// err
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Err(err) => {
|
|
||||||
// warn!(
|
|
||||||
// "can not parse display brightness from payload. {:?}",
|
|
||||||
// err
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Err(err) => {
|
|
||||||
// warn!("can not parse display brightness from payload. {:?}", err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// BOARD_SEND_CMD => {
|
|
||||||
// let payload_text = String::from_utf8(notification.payload().to_vec());
|
|
||||||
// match payload_text {
|
|
||||||
// Ok(payload_text) => {
|
|
||||||
// let message: Result<models::CmdMqMessage, _> =
|
|
||||||
// serde_json::from_str(payload_text.as_str());
|
|
||||||
// match message {
|
|
||||||
// Ok(message) => match message_tx_cloned.send(message) {
|
|
||||||
// Ok(_) => {}
|
|
||||||
// Err(err) => {
|
|
||||||
// warn!("can not send message to channel. {:?}", err);
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// Err(err) => {
|
|
||||||
// warn!("can not parse message from payload. {:?}", err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Err(err) => {
|
|
||||||
// warn!("can not parse message from payload. {:?}", err);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// _ => {}
|
|
||||||
// },
|
|
||||||
// _ => {
|
|
||||||
// warn!("can not get notification from MQTT server.");
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn initialize(&self) -> anyhow::Result<()> {
|
pub async fn initialize(&self) -> anyhow::Result<()> {
|
||||||
// self.subscribe_board()?;
|
|
||||||
// self.subscribe_display()?;
|
|
||||||
self.broadcast_desktop_online();
|
self.broadcast_desktop_online();
|
||||||
Self::publish_color_calibration_worker();
|
Self::publish_color_calibration_worker();
|
||||||
anyhow::Ok(())
|
anyhow::Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subscribe_board(&self) -> anyhow::Result<()> {
|
|
||||||
self.client
|
|
||||||
.subscribe("display-ambient-light/board/#", mqtt::QOS_1)
|
|
||||||
.wait()
|
|
||||||
.map_err(|err| anyhow::anyhow!("subscribe board failed. {:?}", err))
|
|
||||||
.map(|_| ())
|
|
||||||
}
|
|
||||||
fn subscribe_display(&self) -> anyhow::Result<()> {
|
|
||||||
self.client
|
|
||||||
.subscribe(format!("{}/#", DISPLAY_TOPIC), mqtt::QOS_1)
|
|
||||||
.wait()
|
|
||||||
.map_err(|err| anyhow::anyhow!("subscribe board failed. {:?}", err))
|
|
||||||
.map(|_| ())
|
|
||||||
}
|
|
||||||
fn publish_color_calibration_worker() {
|
fn publish_color_calibration_worker() {
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mqtt = Self::global().await;
|
let mqtt = Self::global().await;
|
||||||
@ -241,34 +150,7 @@ impl MqttRpc {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn publish_led_sub_pixels(&self, payload: Vec<u8>) -> anyhow::Result<()> {
|
pub async fn publish_color_calibration(&self, payload: ColorCalibration) -> anyhow::Result<()> {
|
||||||
self.client
|
|
||||||
.publish(mqtt::Message::new(
|
|
||||||
"display-ambient-light/desktop/colors",
|
|
||||||
payload,
|
|
||||||
mqtt::QOS_1,
|
|
||||||
))
|
|
||||||
.await
|
|
||||||
.map_err(|error| anyhow::anyhow!("mqtt publish failed. {}", error))
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn subscribe_change_display_brightness_rx(
|
|
||||||
// &self,
|
|
||||||
// ) -> broadcast::Receiver<display::DisplayBrightness> {
|
|
||||||
// self.change_display_brightness_tx.subscribe()
|
|
||||||
// }
|
|
||||||
pub async fn publish_desktop_cmd(&self, field: &str, payload: Vec<u8>) -> anyhow::Result<()> {
|
|
||||||
self.client
|
|
||||||
.publish(mqtt::Message::new(
|
|
||||||
format!("{}/{}", DESKTOP_TOPIC, field),
|
|
||||||
payload,
|
|
||||||
mqtt::QOS_1,
|
|
||||||
))
|
|
||||||
.await
|
|
||||||
.map_err(|error| anyhow::anyhow!("mqtt publish failed. {}", error))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn publish_color_calibration(&self, payload: ColorCalibration) -> anyhow::Result<()> {
|
|
||||||
self.client
|
self.client
|
||||||
.publish(mqtt::Message::new(
|
.publish(mqtt::Message::new(
|
||||||
COLOR_CALIBRATION,
|
COLOR_CALIBRATION,
|
||||||
|
Loading…
Reference in New Issue
Block a user