1786285862
This commit is contained in:
@@ -6,12 +6,12 @@ use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::AppError,
|
error::AppError,
|
||||||
messages::{C2sMessage, S2cMessage},
|
messages::{CommandMessage, EventMessage},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub async fn hass(
|
pub async fn hass(
|
||||||
s2c_tx: UnboundedSender<S2cMessage>,
|
s2c_tx: UnboundedSender<EventMessage>,
|
||||||
mut c2s_rx: UnboundedReceiver<C2sMessage>,
|
mut c2s_rx: UnboundedReceiver<CommandMessage>,
|
||||||
) -> Result<(), AppError> {
|
) -> Result<(), AppError> {
|
||||||
let Ok(url) = var("HASS_URL") else {
|
let Ok(url) = var("HASS_URL") else {
|
||||||
return Err(AppError::MissingUrl);
|
return Err(AppError::MissingUrl);
|
||||||
@@ -48,7 +48,7 @@ pub async fn hass(
|
|||||||
|
|
||||||
let mut initial_state = state.values().cloned().collect::<Vec<_>>();
|
let mut initial_state = state.values().cloned().collect::<Vec<_>>();
|
||||||
initial_state.sort_by(|a, b| a.entity_id.cmp(&b.entity_id));
|
initial_state.sort_by(|a, b| a.entity_id.cmp(&b.entity_id));
|
||||||
s2c_tx.send(S2cMessage::InitialState(initial_state)).ok();
|
s2c_tx.send(EventMessage::InitialState(initial_state)).ok();
|
||||||
|
|
||||||
let mut event_receiver = client
|
let mut event_receiver = client
|
||||||
.subscribe_event("state_changed")
|
.subscribe_event("state_changed")
|
||||||
@@ -62,17 +62,17 @@ pub async fn hass(
|
|||||||
(None, Some(entity)) => {
|
(None, Some(entity)) => {
|
||||||
// New Entity Added
|
// New Entity Added
|
||||||
state.insert(entity.entity_id.clone(), entity.clone());
|
state.insert(entity.entity_id.clone(), entity.clone());
|
||||||
s2c_tx.send(S2cMessage::EntityUpdated(entity.clone())).ok();
|
s2c_tx.send(EventMessage::EntityUpdated(entity.clone())).ok();
|
||||||
}
|
}
|
||||||
(Some(entity), None) => {
|
(Some(entity), None) => {
|
||||||
// Entity Removed
|
// Entity Removed
|
||||||
state.remove(&entity.entity_id);
|
state.remove(&entity.entity_id);
|
||||||
s2c_tx.send(S2cMessage::EntityRemoved(entity.clone())).ok();
|
s2c_tx.send(EventMessage::EntityRemoved(entity.clone())).ok();
|
||||||
}
|
}
|
||||||
(Some(_), Some(entity)) => {
|
(Some(_), Some(entity)) => {
|
||||||
// Entity Updated
|
// Entity Updated
|
||||||
state.insert(entity.entity_id.clone(), entity.clone());
|
state.insert(entity.entity_id.clone(), entity.clone());
|
||||||
s2c_tx.send(S2cMessage::EntityUpdated(entity.clone())).ok();
|
s2c_tx.send(EventMessage::EntityUpdated(entity.clone())).ok();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ pub async fn hass(
|
|||||||
|
|
||||||
Some(message) = c2s_rx.recv() => {
|
Some(message) = c2s_rx.recv() => {
|
||||||
if let Err(err) = match message {
|
if let Err(err) = match message {
|
||||||
C2sMessage::ToggleLight { entity_id } => {
|
CommandMessage::ToggleLight { entity_id } => {
|
||||||
if let Some(entity) = state.get(&entity_id) {
|
if let Some(entity) = state.get(&entity_id) {
|
||||||
let payload = json!({
|
let payload = json!({
|
||||||
"entity_id": entity_id
|
"entity_id": entity_id
|
||||||
@@ -95,7 +95,7 @@ pub async fn hass(
|
|||||||
Err(AppError::NoEntity(entity_id))
|
Err(AppError::NoEntity(entity_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
C2sMessage::ToggleThermostat { entity_id } => {
|
CommandMessage::ToggleThermostat { entity_id } => {
|
||||||
if let Some(entity) = state.get(&entity_id) {
|
if let Some(entity) = state.get(&entity_id) {
|
||||||
let payload = json!({
|
let payload = json!({
|
||||||
"entity_id": entity_id
|
"entity_id": entity_id
|
||||||
@@ -110,7 +110,7 @@ pub async fn hass(
|
|||||||
Err(AppError::NoEntity(entity_id))
|
Err(AppError::NoEntity(entity_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
C2sMessage::SetTemperature {
|
CommandMessage::SetTemperature {
|
||||||
entity_id,
|
entity_id,
|
||||||
temperature,
|
temperature,
|
||||||
} => {
|
} => {
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ use tokio::sync::mpsc::unbounded_channel;
|
|||||||
|
|
||||||
use slint::ComponentHandle;
|
use slint::ComponentHandle;
|
||||||
|
|
||||||
use crate::error::AppError;
|
use crate::{
|
||||||
|
error::AppError,
|
||||||
|
messages::{CommandMessage, EventMessage},
|
||||||
|
};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), AppError> {
|
async fn main() -> Result<(), AppError> {
|
||||||
@@ -19,8 +22,8 @@ async fn main() -> Result<(), AppError> {
|
|||||||
|
|
||||||
let app = ui::AppWindow::new()?;
|
let app = ui::AppWindow::new()?;
|
||||||
|
|
||||||
let (c2s_tx, c2s_rx) = unbounded_channel::<messages::C2sMessage>();
|
let (c2s_tx, c2s_rx) = unbounded_channel::<CommandMessage>();
|
||||||
let (s2c_tx, s2c_rx) = unbounded_channel::<messages::S2cMessage>();
|
let (s2c_tx, s2c_rx) = unbounded_channel::<EventMessage>();
|
||||||
|
|
||||||
ui::bind_buttons(&app, c2s_tx);
|
ui::bind_buttons(&app, c2s_tx);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use hass_rs::HassEntity;
|
use hass_rs::HassEntity;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum C2sMessage {
|
pub enum CommandMessage {
|
||||||
ToggleLight { entity_id: String },
|
ToggleLight { entity_id: String },
|
||||||
|
|
||||||
ToggleThermostat { entity_id: String },
|
ToggleThermostat { entity_id: String },
|
||||||
@@ -10,7 +10,7 @@ pub enum C2sMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum S2cMessage {
|
pub enum EventMessage {
|
||||||
InitialState(Vec<HassEntity>),
|
InitialState(Vec<HassEntity>),
|
||||||
EntityUpdated(HassEntity),
|
EntityUpdated(HassEntity),
|
||||||
EntityRemoved(HassEntity),
|
EntityRemoved(HassEntity),
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ slint::include_modules!();
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ha_ext::*,
|
ha_ext::*,
|
||||||
messages::{C2sMessage, S2cMessage},
|
messages::{CommandMessage, EventMessage},
|
||||||
};
|
};
|
||||||
|
|
||||||
use hass_rs::HassEntity;
|
use hass_rs::HassEntity;
|
||||||
@@ -109,14 +109,14 @@ pub fn apply_state(app: &Weak<AppWindow>, entities: Vec<HassEntity>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bind_buttons(app: &AppWindow, c2s_tx: UnboundedSender<C2sMessage>) {
|
pub fn bind_buttons(app: &AppWindow, c2s_tx: UnboundedSender<CommandMessage>) {
|
||||||
// Button Bindings
|
// Button Bindings
|
||||||
app.on_toggle_light({
|
app.on_toggle_light({
|
||||||
let c2s_tx = c2s_tx.clone();
|
let c2s_tx = c2s_tx.clone();
|
||||||
move |entity_id| {
|
move |entity_id| {
|
||||||
let id = entity_id.to_string();
|
let id = entity_id.to_string();
|
||||||
|
|
||||||
if let Err(err) = c2s_tx.send(C2sMessage::ToggleLight { entity_id: id }) {
|
if let Err(err) = c2s_tx.send(CommandMessage::ToggleLight { entity_id: id }) {
|
||||||
eprintln!("Failed to send message to server.\n\t{:?}", err);
|
eprintln!("Failed to send message to server.\n\t{:?}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ pub fn bind_buttons(app: &AppWindow, c2s_tx: UnboundedSender<C2sMessage>) {
|
|||||||
app.on_set_temperature({
|
app.on_set_temperature({
|
||||||
let c2s_tx = c2s_tx.clone();
|
let c2s_tx = c2s_tx.clone();
|
||||||
move |entity_id, value| {
|
move |entity_id, value| {
|
||||||
if let Err(err) = c2s_tx.send(C2sMessage::SetTemperature {
|
if let Err(err) = c2s_tx.send(CommandMessage::SetTemperature {
|
||||||
entity_id: entity_id.to_string(),
|
entity_id: entity_id.to_string(),
|
||||||
temperature: value,
|
temperature: value,
|
||||||
}) {
|
}) {
|
||||||
@@ -139,23 +139,26 @@ pub fn bind_buttons(app: &AppWindow, c2s_tx: UnboundedSender<C2sMessage>) {
|
|||||||
move |entity_id| {
|
move |entity_id| {
|
||||||
let id = entity_id.to_string();
|
let id = entity_id.to_string();
|
||||||
|
|
||||||
if let Err(err) = c2s_tx.send(C2sMessage::ToggleThermostat { entity_id: id }) {
|
if let Err(err) = c2s_tx.send(CommandMessage::ToggleThermostat { entity_id: id }) {
|
||||||
eprintln!("Failed to send message to server.\n\t{:?}", err);
|
eprintln!("Failed to send message to server.\n\t{:?}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_listener(app_weak: Weak<AppWindow>, mut s2c_rx: UnboundedReceiver<S2cMessage>) {
|
pub async fn update_listener(
|
||||||
|
app_weak: Weak<AppWindow>,
|
||||||
|
mut s2c_rx: UnboundedReceiver<EventMessage>,
|
||||||
|
) {
|
||||||
while let Some(message) = s2c_rx.recv().await {
|
while let Some(message) = s2c_rx.recv().await {
|
||||||
match message {
|
match message {
|
||||||
S2cMessage::InitialState(items) => {
|
EventMessage::InitialState(items) => {
|
||||||
apply_state(&app_weak, items);
|
apply_state(&app_weak, items);
|
||||||
}
|
}
|
||||||
S2cMessage::EntityUpdated(hass_entity) => {
|
EventMessage::EntityUpdated(hass_entity) => {
|
||||||
apply_state(&app_weak, vec![hass_entity]);
|
apply_state(&app_weak, vec![hass_entity]);
|
||||||
}
|
}
|
||||||
S2cMessage::EntityRemoved(hass_entity) => {
|
EventMessage::EntityRemoved(hass_entity) => {
|
||||||
apply_state(&app_weak, vec![hass_entity]);
|
apply_state(&app_weak, vec![hass_entity]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user