Added Air Filter support
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::traits::AvailableSpeeds;
|
||||
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Attributes {
|
||||
@@ -9,4 +11,10 @@ pub struct Attributes {
|
||||
pub query_only_on_off: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub scene_reversible: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub reversible: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub command_only_fan_speed: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub available_fan_speeds: Option<AvailableSpeeds>,
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use crate::{
|
||||
errors::{DeviceError, ErrorCode},
|
||||
request::execute::CommandType,
|
||||
response,
|
||||
traits::{OnOff, Scene, Trait},
|
||||
traits::{FanSpeed, OnOff, Scene, Trait},
|
||||
types::Type,
|
||||
};
|
||||
|
||||
@@ -44,7 +44,7 @@ where
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[impl_cast::device(As: OnOff + Scene)]
|
||||
#[impl_cast::device(As: OnOff + Scene + FanSpeed)]
|
||||
pub trait GoogleHomeDevice: AsGoogleHomeDevice + Sync + Send + 'static {
|
||||
fn get_device_type(&self) -> Type;
|
||||
fn get_device_name(&self) -> Name;
|
||||
@@ -90,6 +90,13 @@ pub trait GoogleHomeDevice: AsGoogleHomeDevice + Sync + Send + 'static {
|
||||
device.attributes.scene_reversible = scene.is_scene_reversible();
|
||||
}
|
||||
|
||||
// FanSpeed
|
||||
if let Some(fan_speed) = As::<dyn FanSpeed>::cast(self) {
|
||||
traits.push(Trait::FanSpeed);
|
||||
device.attributes.command_only_fan_speed = fan_speed.command_only_fan_speed();
|
||||
device.attributes.available_fan_speeds = Some(fan_speed.available_speeds());
|
||||
}
|
||||
|
||||
device.traits = traits;
|
||||
|
||||
device
|
||||
@@ -110,25 +117,35 @@ pub trait GoogleHomeDevice: AsGoogleHomeDevice + Sync + Send + 'static {
|
||||
.ok();
|
||||
}
|
||||
|
||||
// FanSpeed
|
||||
if let Some(fan_speed) = As::<dyn FanSpeed>::cast(self) {
|
||||
device.state.current_fan_speed_setting = Some(fan_speed.current_speed().await);
|
||||
}
|
||||
|
||||
device
|
||||
}
|
||||
|
||||
async fn execute(&mut self, command: &CommandType) -> Result<(), ErrorCode> {
|
||||
match command {
|
||||
CommandType::OnOff { on } => {
|
||||
if let Some(on_off) = As::<dyn OnOff>::cast_mut(self) {
|
||||
on_off.set_on(*on).await?;
|
||||
if let Some(t) = As::<dyn OnOff>::cast_mut(self) {
|
||||
t.set_on(*on).await?;
|
||||
} else {
|
||||
return Err(DeviceError::ActionNotAvailable.into());
|
||||
}
|
||||
}
|
||||
CommandType::ActivateScene { deactivate } => {
|
||||
if let Some(scene) = As::<dyn Scene>::cast(self) {
|
||||
scene.set_active(!deactivate).await?;
|
||||
if let Some(t) = As::<dyn Scene>::cast(self) {
|
||||
t.set_active(!deactivate).await?;
|
||||
} else {
|
||||
return Err(DeviceError::ActionNotAvailable.into());
|
||||
}
|
||||
}
|
||||
CommandType::SetFanSpeed { fan_speed } => {
|
||||
if let Some(t) = As::<dyn FanSpeed>::cast(self) {
|
||||
t.set_speed(fan_speed).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -20,13 +20,15 @@ pub struct Device {
|
||||
// customData
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Clone, Copy)]
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[serde(tag = "command", content = "params")]
|
||||
pub enum CommandType {
|
||||
#[serde(rename = "action.devices.commands.OnOff")]
|
||||
OnOff { on: bool },
|
||||
#[serde(rename = "action.devices.commands.ActivateScene")]
|
||||
ActivateScene { deactivate: bool },
|
||||
#[serde(rename = "action.devices.commands.SetFanSpeed")]
|
||||
SetFanSpeed { fan_speed: String },
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -33,4 +33,7 @@ pub enum ResponsePayload {
|
||||
pub struct State {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub on: Option<bool>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub current_fan_speed_setting: Option<String>,
|
||||
}
|
||||
|
||||
@@ -96,7 +96,10 @@ mod tests {
|
||||
fn serialize() {
|
||||
let mut execute_resp = Payload::new();
|
||||
|
||||
let state = State { on: Some(true) };
|
||||
let state = State {
|
||||
on: Some(true),
|
||||
current_fan_speed_setting: None,
|
||||
};
|
||||
let mut command = Command::new(Status::Success);
|
||||
command.states = Some(States {
|
||||
online: true,
|
||||
|
||||
@@ -9,6 +9,8 @@ pub enum Trait {
|
||||
OnOff,
|
||||
#[serde(rename = "action.devices.traits.Scene")]
|
||||
Scene,
|
||||
#[serde(rename = "action.devices.traits.FanSpeed")]
|
||||
FanSpeed,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -36,3 +38,37 @@ pub trait Scene {
|
||||
|
||||
async fn set_active(&self, activate: bool) -> Result<(), ErrorCode>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct SpeedValues {
|
||||
pub speed_synonym: Vec<String>,
|
||||
pub lang: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Speed {
|
||||
pub speed_name: String,
|
||||
pub speed_values: Vec<SpeedValues>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct AvailableSpeeds {
|
||||
pub speeds: Vec<Speed>,
|
||||
pub ordered: bool,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
#[impl_cast::device_trait]
|
||||
pub trait FanSpeed {
|
||||
fn reversible(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
fn command_only_fan_speed(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
fn available_speeds(&self) -> AvailableSpeeds;
|
||||
async fn current_speed(&self) -> String;
|
||||
async fn set_speed(&self, speed: &str) -> Result<(), ErrorCode>;
|
||||
}
|
||||
|
||||
@@ -10,4 +10,6 @@ pub enum Type {
|
||||
Light,
|
||||
#[serde(rename = "action.devices.types.SCENE")]
|
||||
Scene,
|
||||
#[serde(rename = "action.devices.types.AIRPURIFIER")]
|
||||
AirPurifier,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user