Moved mqtt messages to a seperate file

This commit is contained in:
Dreaded_X 2023-04-24 02:50:30 +02:00
parent 8f515ccf75
commit 28ce9c9d82
Signed by: Dreaded_X
GPG Key ID: FA5F485356B0D2D4
10 changed files with 207 additions and 198 deletions

View File

@ -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,
}; };

View File

@ -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,
}; };

View File

@ -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,

View File

@ -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;

View File

@ -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,
}; };

View File

@ -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;

View File

@ -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
View 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())))
}
}

View File

@ -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())))
}
}

View File

@ -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;