Moved mqtt messages to a seperate file
This commit is contained in:
parent
8f515ccf75
commit
28ce9c9d82
|
@ -6,7 +6,7 @@ use tracing::warn;
|
||||||
use crate::{
|
use crate::{
|
||||||
config::MqttDeviceConfig,
|
config::MqttDeviceConfig,
|
||||||
devices::Device,
|
devices::Device,
|
||||||
mqtt::{DarknessMessage, PresenceMessage},
|
messages::{DarknessMessage, PresenceMessage},
|
||||||
traits::OnDarkness,
|
traits::OnDarkness,
|
||||||
traits::OnPresence,
|
traits::OnPresence,
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,7 +8,7 @@ use crate::{
|
||||||
config::{self, CreateDevice, MqttDeviceConfig},
|
config::{self, CreateDevice, MqttDeviceConfig},
|
||||||
error::CreateDeviceError,
|
error::CreateDeviceError,
|
||||||
event::EventChannel,
|
event::EventChannel,
|
||||||
mqtt::{RemoteAction, RemoteMessage},
|
messages::{RemoteAction, RemoteMessage},
|
||||||
traits::OnMqtt,
|
traits::OnMqtt,
|
||||||
traits::OnPresence,
|
traits::OnPresence,
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,7 +10,7 @@ use crate::{
|
||||||
config::{CreateDevice, MqttDeviceConfig},
|
config::{CreateDevice, MqttDeviceConfig},
|
||||||
error::{CreateDeviceError, MissingWildcard},
|
error::{CreateDeviceError, MissingWildcard},
|
||||||
event::EventChannel,
|
event::EventChannel,
|
||||||
mqtt::{ContactMessage, PresenceMessage},
|
messages::{ContactMessage, PresenceMessage},
|
||||||
presence,
|
presence,
|
||||||
traits::OnMqtt,
|
traits::OnMqtt,
|
||||||
traits::OnPresence,
|
traits::OnPresence,
|
||||||
|
|
|
@ -17,7 +17,7 @@ use crate::config::{CreateDevice, InfoConfig, MqttDeviceConfig};
|
||||||
use crate::devices::Device;
|
use crate::devices::Device;
|
||||||
use crate::error::CreateDeviceError;
|
use crate::error::CreateDeviceError;
|
||||||
use crate::event::EventChannel;
|
use crate::event::EventChannel;
|
||||||
use crate::mqtt::OnOffMessage;
|
use crate::messages::OnOffMessage;
|
||||||
use crate::traits::OnMqtt;
|
use crate::traits::OnMqtt;
|
||||||
use crate::traits::OnPresence;
|
use crate::traits::OnPresence;
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
config::{CreateDevice, InfoConfig, MqttDeviceConfig},
|
config::{CreateDevice, InfoConfig, MqttDeviceConfig},
|
||||||
error::CreateDeviceError,
|
error::CreateDeviceError,
|
||||||
event::EventChannel,
|
event::EventChannel,
|
||||||
mqtt::ActivateMessage,
|
messages::ActivateMessage,
|
||||||
traits::OnMqtt,
|
traits::OnMqtt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ pub mod error;
|
||||||
pub mod event;
|
pub mod event;
|
||||||
pub mod hue_bridge;
|
pub mod hue_bridge;
|
||||||
pub mod light_sensor;
|
pub mod light_sensor;
|
||||||
|
pub mod messages;
|
||||||
pub mod mqtt;
|
pub mod mqtt;
|
||||||
pub mod ntfy;
|
pub mod ntfy;
|
||||||
pub mod presence;
|
pub mod presence;
|
||||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
||||||
config::MqttDeviceConfig,
|
config::MqttDeviceConfig,
|
||||||
devices::Device,
|
devices::Device,
|
||||||
event::{self, Event, EventChannel},
|
event::{self, Event, EventChannel},
|
||||||
mqtt::BrightnessMessage,
|
messages::BrightnessMessage,
|
||||||
traits::OnMqtt,
|
traits::OnMqtt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
196
src/messages.rs
Normal file
196
src/messages.rs
Normal file
|
@ -0,0 +1,196 @@
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
|
use rumqttc::Publish;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::error::ParseError;
|
||||||
|
|
||||||
|
// Message used to turn on and off devices and receiving their state
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct OnOffMessage {
|
||||||
|
state: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OnOffMessage {
|
||||||
|
pub fn new(state: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
state: if state { "ON" } else { "OFF" }.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn state(&self) -> bool {
|
||||||
|
self.state == "ON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Publish> for OnOffMessage {
|
||||||
|
type Error = ParseError;
|
||||||
|
|
||||||
|
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
||||||
|
serde_json::from_slice(&message.payload)
|
||||||
|
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message send to request activating a device
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct ActivateMessage {
|
||||||
|
activate: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActivateMessage {
|
||||||
|
pub fn activate(&self) -> bool {
|
||||||
|
self.activate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Publish> for ActivateMessage {
|
||||||
|
type Error = ParseError;
|
||||||
|
|
||||||
|
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
||||||
|
serde_json::from_slice(&message.payload)
|
||||||
|
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Actions that can be performed by a remote
|
||||||
|
#[derive(Debug, Deserialize, Copy, Clone)]
|
||||||
|
#[serde(rename_all = "snake_case")]
|
||||||
|
pub enum RemoteAction {
|
||||||
|
On,
|
||||||
|
Off,
|
||||||
|
BrightnessMoveUp,
|
||||||
|
BrightnessMoveDown,
|
||||||
|
BrightnessStop,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message used to report the action performed by a remote
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct RemoteMessage {
|
||||||
|
action: RemoteAction,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RemoteMessage {
|
||||||
|
pub fn action(&self) -> RemoteAction {
|
||||||
|
self.action
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Publish> for RemoteMessage {
|
||||||
|
type Error = ParseError;
|
||||||
|
|
||||||
|
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
||||||
|
serde_json::from_slice(&message.payload)
|
||||||
|
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message used to report the current presence state
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct PresenceMessage {
|
||||||
|
state: bool,
|
||||||
|
updated: Option<u128>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PresenceMessage {
|
||||||
|
pub fn new(state: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
state,
|
||||||
|
updated: Some(
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.expect("Time is after UNIX EPOCH")
|
||||||
|
.as_millis(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn presence(&self) -> bool {
|
||||||
|
self.state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Publish> for PresenceMessage {
|
||||||
|
type Error = ParseError;
|
||||||
|
|
||||||
|
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
||||||
|
serde_json::from_slice(&message.payload)
|
||||||
|
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message use to report the state of a light sensor
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct BrightnessMessage {
|
||||||
|
illuminance: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BrightnessMessage {
|
||||||
|
pub fn illuminance(&self) -> isize {
|
||||||
|
self.illuminance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Publish> for BrightnessMessage {
|
||||||
|
type Error = ParseError;
|
||||||
|
|
||||||
|
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
||||||
|
serde_json::from_slice(&message.payload)
|
||||||
|
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message to report the state of a contact sensor
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct ContactMessage {
|
||||||
|
contact: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContactMessage {
|
||||||
|
pub fn is_closed(&self) -> bool {
|
||||||
|
self.contact
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Publish> for ContactMessage {
|
||||||
|
type Error = ParseError;
|
||||||
|
|
||||||
|
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
||||||
|
serde_json::from_slice(&message.payload)
|
||||||
|
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message used to report the current darkness state
|
||||||
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
pub struct DarknessMessage {
|
||||||
|
state: bool,
|
||||||
|
updated: Option<u128>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DarknessMessage {
|
||||||
|
pub fn new(state: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
state,
|
||||||
|
updated: Some(
|
||||||
|
SystemTime::now()
|
||||||
|
.duration_since(UNIX_EPOCH)
|
||||||
|
.expect("Time is after UNIX EPOCH")
|
||||||
|
.as_millis(),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_dark(&self) -> bool {
|
||||||
|
self.state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<Publish> for DarknessMessage {
|
||||||
|
type Error = ParseError;
|
||||||
|
|
||||||
|
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
||||||
|
serde_json::from_slice(&message.payload)
|
||||||
|
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
||||||
|
}
|
||||||
|
}
|
192
src/mqtt.rs
192
src/mqtt.rs
|
@ -1,14 +1,8 @@
|
||||||
use std::time::{SystemTime, UNIX_EPOCH};
|
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use tracing::{debug, warn};
|
use tracing::{debug, warn};
|
||||||
|
|
||||||
use rumqttc::{Event, EventLoop, Incoming, Publish};
|
use rumqttc::{Event, EventLoop, Incoming};
|
||||||
|
|
||||||
use crate::{
|
use crate::event::{self, EventChannel};
|
||||||
error::ParseError,
|
|
||||||
event::{self, EventChannel},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn start(mut eventloop: EventLoop, event_channel: &EventChannel) {
|
pub fn start(mut eventloop: EventLoop, event_channel: &EventChannel) {
|
||||||
let tx = event_channel.get_tx();
|
let tx = event_channel.get_tx();
|
||||||
|
@ -31,185 +25,3 @@ pub fn start(mut eventloop: EventLoop, event_channel: &EventChannel) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
|
||||||
pub struct OnOffMessage {
|
|
||||||
state: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OnOffMessage {
|
|
||||||
pub fn new(state: bool) -> Self {
|
|
||||||
Self {
|
|
||||||
state: if state { "ON" } else { "OFF" }.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn state(&self) -> bool {
|
|
||||||
self.state == "ON"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Publish> for OnOffMessage {
|
|
||||||
type Error = ParseError;
|
|
||||||
|
|
||||||
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
|
||||||
serde_json::from_slice(&message.payload)
|
|
||||||
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct ActivateMessage {
|
|
||||||
activate: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ActivateMessage {
|
|
||||||
pub fn activate(&self) -> bool {
|
|
||||||
self.activate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Publish> for ActivateMessage {
|
|
||||||
type Error = ParseError;
|
|
||||||
|
|
||||||
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
|
||||||
serde_json::from_slice(&message.payload)
|
|
||||||
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Copy, Clone)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub enum RemoteAction {
|
|
||||||
On,
|
|
||||||
Off,
|
|
||||||
BrightnessMoveUp,
|
|
||||||
BrightnessMoveDown,
|
|
||||||
BrightnessStop,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct RemoteMessage {
|
|
||||||
action: RemoteAction,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RemoteMessage {
|
|
||||||
pub fn action(&self) -> RemoteAction {
|
|
||||||
self.action
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Publish> for RemoteMessage {
|
|
||||||
type Error = ParseError;
|
|
||||||
|
|
||||||
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
|
||||||
serde_json::from_slice(&message.payload)
|
|
||||||
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
|
||||||
pub struct PresenceMessage {
|
|
||||||
state: bool,
|
|
||||||
updated: Option<u128>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PresenceMessage {
|
|
||||||
pub fn new(state: bool) -> Self {
|
|
||||||
Self {
|
|
||||||
state,
|
|
||||||
updated: Some(
|
|
||||||
SystemTime::now()
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.expect("Time is after UNIX EPOCH")
|
|
||||||
.as_millis(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn present(&self) -> bool {
|
|
||||||
self.state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Publish> for PresenceMessage {
|
|
||||||
type Error = ParseError;
|
|
||||||
|
|
||||||
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
|
||||||
serde_json::from_slice(&message.payload)
|
|
||||||
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct BrightnessMessage {
|
|
||||||
illuminance: isize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BrightnessMessage {
|
|
||||||
pub fn illuminance(&self) -> isize {
|
|
||||||
self.illuminance
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Publish> for BrightnessMessage {
|
|
||||||
type Error = ParseError;
|
|
||||||
|
|
||||||
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
|
||||||
serde_json::from_slice(&message.payload)
|
|
||||||
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
pub struct ContactMessage {
|
|
||||||
contact: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ContactMessage {
|
|
||||||
pub fn is_closed(&self) -> bool {
|
|
||||||
self.contact
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Publish> for ContactMessage {
|
|
||||||
type Error = ParseError;
|
|
||||||
|
|
||||||
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
|
||||||
serde_json::from_slice(&message.payload)
|
|
||||||
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
|
||||||
pub struct DarknessMessage {
|
|
||||||
state: bool,
|
|
||||||
updated: Option<u128>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl DarknessMessage {
|
|
||||||
pub fn new(state: bool) -> Self {
|
|
||||||
Self {
|
|
||||||
state,
|
|
||||||
updated: Some(
|
|
||||||
SystemTime::now()
|
|
||||||
.duration_since(UNIX_EPOCH)
|
|
||||||
.expect("Time is after UNIX EPOCH")
|
|
||||||
.as_millis(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn present(&self) -> bool {
|
|
||||||
self.state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TryFrom<Publish> for DarknessMessage {
|
|
||||||
type Error = ParseError;
|
|
||||||
|
|
||||||
fn try_from(message: Publish) -> Result<Self, Self::Error> {
|
|
||||||
serde_json::from_slice(&message.payload)
|
|
||||||
.or(Err(ParseError::InvalidPayload(message.payload.clone())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
||||||
config::MqttDeviceConfig,
|
config::MqttDeviceConfig,
|
||||||
devices::Device,
|
devices::Device,
|
||||||
event::{self, Event, EventChannel},
|
event::{self, Event, EventChannel},
|
||||||
mqtt::PresenceMessage,
|
messages::PresenceMessage,
|
||||||
traits::OnMqtt,
|
traits::OnMqtt,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ impl OnMqtt for Presence {
|
||||||
self.devices.remove(&device_name);
|
self.devices.remove(&device_name);
|
||||||
} else {
|
} else {
|
||||||
let present = match PresenceMessage::try_from(message) {
|
let present = match PresenceMessage::try_from(message) {
|
||||||
Ok(state) => state.present(),
|
Ok(state) => state.presence(),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!("Failed to parse message: {err}");
|
warn!("Failed to parse message: {err}");
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user