Started actually using the google home trait macro
This commit is contained in:
parent
d84ff8ec8e
commit
9aa16e3ef8
|
@ -299,7 +299,7 @@ fn get_command_enum(traits: &Punctuated<Trait, Token![,]>) -> proc_macro2::Token
|
|||
});
|
||||
|
||||
quote! {
|
||||
#[derive(Debug, serde::Deserialize)]
|
||||
#[derive(Debug, Clone, serde::Deserialize)]
|
||||
#[serde(tag = "command", content = "params", rename_all = "camelCase")]
|
||||
pub enum Command {
|
||||
#(#items,)*
|
||||
|
@ -520,7 +520,7 @@ pub fn google_home_traits(item: TokenStream) -> TokenStream {
|
|||
|
||||
Some(quote! {
|
||||
Command::#command_name {#(#parameters,)*} => {
|
||||
if let Some(t) = self.cast() as Option<&dyn #ident> {
|
||||
if let Some(t) = self.cast_mut() as Option<&mut dyn #ident> {
|
||||
t.#f_name(#(#parameters,)*) #asyncness #errors;
|
||||
serde_json::to_value(t.get_state().await?)?
|
||||
} else {
|
||||
|
@ -547,7 +547,7 @@ pub fn google_home_traits(item: TokenStream) -> TokenStream {
|
|||
pub trait #fulfillment: Sync + Send {
|
||||
async fn sync(&self) -> Result<(Vec<Trait>, serde_json::Value), Box<dyn ::std::error::Error>>;
|
||||
async fn query(&self) -> Result<serde_json::Value, Box<dyn ::std::error::Error>>;
|
||||
async fn execute(&self, command: Command) -> Result<serde_json::Value, Box<dyn std::error::Error>>;
|
||||
async fn execute(&mut self, command: Command) -> Result<serde_json::Value, Box<dyn std::error::Error>>;
|
||||
}
|
||||
|
||||
#(#structs)*
|
||||
|
@ -575,7 +575,7 @@ pub fn google_home_traits(item: TokenStream) -> TokenStream {
|
|||
Ok(state)
|
||||
}
|
||||
|
||||
async fn execute(&self, command: Command) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
|
||||
async fn execute(&mut self, command: Command) -> Result<serde_json::Value, Box<dyn std::error::Error>> {
|
||||
let value = match command {
|
||||
#(#execute)*
|
||||
};
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::traits::AvailableSpeeds;
|
||||
|
||||
#[derive(Debug, Default, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Attributes {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub command_only_on_off: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
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>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub query_only_humidity_setting: Option<bool>,
|
||||
}
|
|
@ -1,17 +1,13 @@
|
|||
use async_trait::async_trait;
|
||||
use automation_cast::Cast;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::errors::{DeviceError, ErrorCode};
|
||||
use crate::request::execute::CommandType;
|
||||
use crate::errors::ErrorCode;
|
||||
use crate::response;
|
||||
use crate::traits::{FanSpeed, HumiditySetting, OnOff, Scene, Trait};
|
||||
use crate::traits::{Command, GoogleHomeDeviceFulfillment};
|
||||
use crate::types::Type;
|
||||
|
||||
#[async_trait]
|
||||
pub trait GoogleHomeDevice:
|
||||
Sync + Send + Cast<dyn OnOff> + Cast<dyn Scene> + Cast<dyn FanSpeed> + Cast<dyn HumiditySetting>
|
||||
{
|
||||
pub trait GoogleHomeDevice: GoogleHomeDeviceFulfillment {
|
||||
fn get_device_type(&self) -> Type;
|
||||
fn get_device_name(&self) -> Name;
|
||||
fn get_id(&self) -> String;
|
||||
|
@ -41,35 +37,10 @@ pub trait GoogleHomeDevice:
|
|||
}
|
||||
device.device_info = self.get_device_info();
|
||||
|
||||
let mut traits = Vec::new();
|
||||
|
||||
// OnOff
|
||||
if let Some(on_off) = self.cast() as Option<&dyn OnOff> {
|
||||
traits.push(Trait::OnOff);
|
||||
device.attributes.command_only_on_off = on_off.is_command_only();
|
||||
device.attributes.query_only_on_off = on_off.is_query_only();
|
||||
}
|
||||
|
||||
// Scene
|
||||
if let Some(scene) = self.cast() as Option<&dyn Scene> {
|
||||
traits.push(Trait::Scene);
|
||||
device.attributes.scene_reversible = scene.is_scene_reversible();
|
||||
}
|
||||
|
||||
// FanSpeed
|
||||
if let Some(fan_speed) = self.cast() as Option<&dyn FanSpeed> {
|
||||
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());
|
||||
}
|
||||
|
||||
if let Some(humidity_setting) = self.cast() as Option<&dyn HumiditySetting> {
|
||||
traits.push(Trait::HumiditySetting);
|
||||
device.attributes.query_only_humidity_setting =
|
||||
humidity_setting.query_only_humidity_setting();
|
||||
}
|
||||
let (traits, attributes) = GoogleHomeDeviceFulfillment::sync(self).await.unwrap();
|
||||
|
||||
device.traits = traits;
|
||||
device.attributes = attributes;
|
||||
|
||||
device
|
||||
}
|
||||
|
@ -80,50 +51,15 @@ pub trait GoogleHomeDevice:
|
|||
device.set_offline();
|
||||
}
|
||||
|
||||
// OnOff
|
||||
if let Some(on_off) = self.cast() as Option<&dyn OnOff> {
|
||||
device.state.on = on_off
|
||||
.is_on()
|
||||
.await
|
||||
.map_err(|err| device.set_error(err))
|
||||
.ok();
|
||||
}
|
||||
|
||||
// FanSpeed
|
||||
if let Some(fan_speed) = self.cast() as Option<&dyn FanSpeed> {
|
||||
device.state.current_fan_speed_setting = Some(fan_speed.current_speed().await);
|
||||
}
|
||||
|
||||
if let Some(humidity_setting) = self.cast() as Option<&dyn HumiditySetting> {
|
||||
device.state.humidity_ambient_percent =
|
||||
Some(humidity_setting.humidity_ambient_percent().await);
|
||||
}
|
||||
device.state = GoogleHomeDeviceFulfillment::query(self).await.unwrap();
|
||||
|
||||
device
|
||||
}
|
||||
|
||||
async fn execute(&mut self, command: &CommandType) -> Result<(), ErrorCode> {
|
||||
match command {
|
||||
CommandType::OnOff { on } => {
|
||||
if let Some(t) = self.cast_mut() as Option<&mut dyn OnOff> {
|
||||
t.set_on(*on).await?;
|
||||
} else {
|
||||
return Err(DeviceError::ActionNotAvailable.into());
|
||||
}
|
||||
}
|
||||
CommandType::ActivateScene { deactivate } => {
|
||||
if let Some(t) = self.cast_mut() as Option<&mut dyn Scene> {
|
||||
t.set_active(!deactivate).await?;
|
||||
} else {
|
||||
return Err(DeviceError::ActionNotAvailable.into());
|
||||
}
|
||||
}
|
||||
CommandType::SetFanSpeed { fan_speed } => {
|
||||
if let Some(t) = self.cast_mut() as Option<&mut dyn FanSpeed> {
|
||||
t.set_speed(fan_speed).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn execute(&mut self, command: Command) -> Result<(), ErrorCode> {
|
||||
GoogleHomeDeviceFulfillment::execute(self, command.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use tokio::sync::{Mutex, RwLock};
|
|||
|
||||
use crate::errors::{DeviceError, ErrorCode};
|
||||
use crate::request::{self, Intent, Request};
|
||||
use crate::response::{self, execute, query, sync, Response, ResponsePayload, State};
|
||||
use crate::response::{self, execute, query, sync, Response, ResponsePayload};
|
||||
use crate::GoogleHomeDevice;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -66,7 +66,7 @@ impl GoogleHome {
|
|||
let mut resp_payload = sync::Payload::new(&self.user_id);
|
||||
let f = devices.iter().map(|(_, device)| async move {
|
||||
if let Some(device) = device.read().await.as_ref().cast() {
|
||||
Some(device.sync().await)
|
||||
Some(GoogleHomeDevice::sync(device).await)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
@ -91,7 +91,7 @@ impl GoogleHome {
|
|||
let device = if let Some(device) = devices.get(id.as_str())
|
||||
&& let Some(device) = device.read().await.as_ref().cast()
|
||||
{
|
||||
device.query().await
|
||||
GoogleHomeDevice::query(device).await
|
||||
} else {
|
||||
let mut device = query::Device::new();
|
||||
device.set_offline();
|
||||
|
@ -121,12 +121,12 @@ impl GoogleHome {
|
|||
let mut success = response::execute::Command::new(execute::Status::Success);
|
||||
success.states = Some(execute::States {
|
||||
online: true,
|
||||
state: State::default(),
|
||||
state: Default::default(),
|
||||
});
|
||||
let mut offline = response::execute::Command::new(execute::Status::Offline);
|
||||
offline.states = Some(execute::States {
|
||||
online: false,
|
||||
state: State::default(),
|
||||
state: Default::default(),
|
||||
});
|
||||
let mut errors: HashMap<ErrorCode, response::execute::Command> = HashMap::new();
|
||||
|
||||
|
@ -147,7 +147,8 @@ impl GoogleHome {
|
|||
// NOTE: We can not use .map here because async =(
|
||||
let mut results = Vec::new();
|
||||
for cmd in &execution {
|
||||
results.push(device.execute(cmd).await);
|
||||
results
|
||||
.push(GoogleHomeDevice::execute(device, cmd.clone()).await);
|
||||
}
|
||||
|
||||
// Convert vec of results to a result with a vec and the first
|
||||
|
|
|
@ -7,7 +7,6 @@ mod fulfillment;
|
|||
mod request;
|
||||
mod response;
|
||||
|
||||
mod attributes;
|
||||
pub mod errors;
|
||||
pub mod traits;
|
||||
pub mod types;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
use crate::traits;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Payload {
|
||||
|
@ -10,7 +12,7 @@ pub struct Payload {
|
|||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Command {
|
||||
pub devices: Vec<Device>,
|
||||
pub execution: Vec<CommandType>,
|
||||
pub execution: Vec<traits::Command>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
|
@ -20,20 +22,6 @@ pub struct Device {
|
|||
// customData
|
||||
}
|
||||
|
||||
#[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",
|
||||
rename_all = "camelCase"
|
||||
)]
|
||||
SetFanSpeed { fan_speed: String },
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -74,7 +62,7 @@ mod tests {
|
|||
assert_eq!(payload.commands[0].devices.len(), 0);
|
||||
assert_eq!(payload.commands[0].execution.len(), 1);
|
||||
match &payload.commands[0].execution[0] {
|
||||
CommandType::SetFanSpeed { fan_speed } => assert_eq!(fan_speed, "Test"),
|
||||
traits::Command::SetFanSpeed { fan_speed } => assert_eq!(fan_speed, "Test"),
|
||||
_ => panic!("Expected SetFanSpeed"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,16 +27,3 @@ pub enum ResponsePayload {
|
|||
Query(query::Payload),
|
||||
Execute(execute::Payload),
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Serialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
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>,
|
||||
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub humidity_ambient_percent: Option<isize>,
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::errors::ErrorCode;
|
||||
use crate::response::State;
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -72,7 +71,7 @@ pub struct States {
|
|||
pub online: bool,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub state: State,
|
||||
pub state: serde_json::Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Clone)]
|
||||
|
@ -87,19 +86,19 @@ pub enum Status {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
|
||||
use super::*;
|
||||
use crate::errors::DeviceError;
|
||||
use crate::response::{Response, ResponsePayload, State};
|
||||
use crate::response::{Response, ResponsePayload};
|
||||
|
||||
#[test]
|
||||
fn serialize() {
|
||||
let mut execute_resp = Payload::new();
|
||||
|
||||
let state = State {
|
||||
on: Some(true),
|
||||
current_fan_speed_setting: None,
|
||||
humidity_ambient_percent: None,
|
||||
};
|
||||
let state = json!({
|
||||
"on": true,
|
||||
});
|
||||
let mut command = Command::new(Status::Success);
|
||||
command.states = Some(States {
|
||||
online: true,
|
||||
|
|
|
@ -3,7 +3,6 @@ use std::collections::HashMap;
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::errors::ErrorCode;
|
||||
use crate::response::State;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
|
@ -53,7 +52,7 @@ pub struct Device {
|
|||
error_code: Option<ErrorCode>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub state: State,
|
||||
pub state: serde_json::Value,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
|
@ -62,7 +61,7 @@ impl Device {
|
|||
online: true,
|
||||
status: Status::Success,
|
||||
error_code: None,
|
||||
state: State::default(),
|
||||
state: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +87,8 @@ impl Default for Device {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use serde_json::json;
|
||||
|
||||
use super::*;
|
||||
use crate::response::{Response, ResponsePayload};
|
||||
|
||||
|
@ -96,11 +97,15 @@ mod tests {
|
|||
let mut query_resp = Payload::new();
|
||||
|
||||
let mut device = Device::new();
|
||||
device.state.on = Some(true);
|
||||
device.state = json!({
|
||||
"on": true,
|
||||
});
|
||||
query_resp.add_device("123", device);
|
||||
|
||||
let mut device = Device::new();
|
||||
device.state.on = Some(false);
|
||||
device.state = json!({
|
||||
"on": true,
|
||||
});
|
||||
query_resp.add_device("456", device);
|
||||
|
||||
let resp = Response::new(
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::attributes::Attributes;
|
||||
use crate::device;
|
||||
use crate::errors::ErrorCode;
|
||||
use crate::traits::Trait;
|
||||
|
@ -47,7 +46,7 @@ pub struct Device {
|
|||
pub room_hint: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub device_info: Option<device::Info>,
|
||||
pub attributes: Attributes,
|
||||
pub attributes: serde_json::Value,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
|
@ -61,7 +60,7 @@ impl Device {
|
|||
notification_supported_by_agent: None,
|
||||
room_hint: None,
|
||||
device_info: None,
|
||||
attributes: Attributes::default(),
|
||||
attributes: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,42 +1,39 @@
|
|||
use async_trait::async_trait;
|
||||
use automation_cast::Cast;
|
||||
use automation_macro::google_home_traits;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::errors::ErrorCode;
|
||||
use crate::GoogleHomeDevice;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum Trait {
|
||||
#[serde(rename = "action.devices.traits.OnOff")]
|
||||
OnOff,
|
||||
#[serde(rename = "action.devices.traits.Scene")]
|
||||
Scene,
|
||||
#[serde(rename = "action.devices.traits.FanSpeed")]
|
||||
FanSpeed,
|
||||
#[serde(rename = "action.devices.traits.HumiditySetting")]
|
||||
HumiditySetting,
|
||||
}
|
||||
google_home_traits! {
|
||||
GoogleHomeDevice,
|
||||
"action.devices.traits.OnOff" => trait OnOff {
|
||||
command_only_on_off: Option<bool>,
|
||||
query_only_on_off: Option<bool>,
|
||||
async fn on(&self) -> Result<bool, ErrorCode>,
|
||||
"action.devices.commands.OnOff" => async fn set_on(&mut self, on: bool) -> Result<(), ErrorCode>,
|
||||
},
|
||||
"action.devices.traits.Scene" => trait Scene {
|
||||
scene_reversible: Option<bool>,
|
||||
|
||||
#[async_trait]
|
||||
pub trait OnOff: Sync + Send {
|
||||
fn is_command_only(&self) -> Option<bool> {
|
||||
None
|
||||
"action.devices.commands.ActivateScene" => async fn set_active(&mut self, activate: bool) -> Result<(), ErrorCode>,
|
||||
},
|
||||
"action.devices.traits.FanSpeed" => trait FanSpeed {
|
||||
reversible: Option<bool>,
|
||||
command_only_fan_speed: Option<bool>,
|
||||
available_fan_speeds: AvailableSpeeds,
|
||||
|
||||
fn current_fan_speed_setting(&self) -> Result<String, ErrorCode>,
|
||||
|
||||
// TODO: Figure out some syntax for optional command?
|
||||
// Probably better to just force the user to always implement commands?
|
||||
"action.devices.commands.SetFanSpeed" => async fn set_fan_speed(&mut self, fan_speed: String) -> Result<(), ErrorCode>,
|
||||
},
|
||||
"action.devices.traits.HumiditySetting" => trait HumiditySetting {
|
||||
query_only_humidity_setting: Option<bool>,
|
||||
|
||||
fn humidity_ambient_percent(&self) -> Result<isize, ErrorCode>,
|
||||
}
|
||||
|
||||
fn is_query_only(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
// TODO: Implement correct error so we can handle them properly
|
||||
async fn is_on(&self) -> Result<bool, ErrorCode>;
|
||||
async fn set_on(&mut self, on: bool) -> Result<(), ErrorCode>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait Scene: Sync + Send {
|
||||
fn is_scene_reversible(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
async fn set_active(&self, activate: bool) -> Result<(), ErrorCode>;
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -56,28 +53,3 @@ pub struct AvailableSpeeds {
|
|||
pub speeds: Vec<Speed>,
|
||||
pub ordered: bool,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait FanSpeed: Sync + Send {
|
||||
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>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait HumiditySetting: Sync + Send {
|
||||
// TODO: This implementation is not complete, I have only implemented what I need right now
|
||||
fn query_only_humidity_setting(&self) -> Option<bool> {
|
||||
None
|
||||
}
|
||||
|
||||
async fn humidity_ambient_percent(&self) -> isize;
|
||||
}
|
||||
|
|
|
@ -134,7 +134,7 @@ impl GoogleHomeDevice for AirFilter {
|
|||
|
||||
#[async_trait]
|
||||
impl OnOff for AirFilter {
|
||||
async fn is_on(&self) -> Result<bool, ErrorCode> {
|
||||
async fn on(&self) -> Result<bool, ErrorCode> {
|
||||
Ok(self.last_known_state.state != AirFilterFanState::Off)
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ impl OnOff for AirFilter {
|
|||
|
||||
#[async_trait]
|
||||
impl FanSpeed for AirFilter {
|
||||
fn available_speeds(&self) -> AvailableSpeeds {
|
||||
fn available_fan_speeds(&self) -> AvailableSpeeds {
|
||||
AvailableSpeeds {
|
||||
speeds: vec![
|
||||
Speed {
|
||||
|
@ -189,7 +189,7 @@ impl FanSpeed for AirFilter {
|
|||
}
|
||||
}
|
||||
|
||||
async fn current_speed(&self) -> String {
|
||||
fn current_fan_speed_setting(&self) -> Result<String, ErrorCode> {
|
||||
let speed = match self.last_known_state.state {
|
||||
AirFilterFanState::Off => "off",
|
||||
AirFilterFanState::Low => "low",
|
||||
|
@ -197,17 +197,18 @@ impl FanSpeed for AirFilter {
|
|||
AirFilterFanState::High => "high",
|
||||
};
|
||||
|
||||
speed.into()
|
||||
Ok(speed.into())
|
||||
}
|
||||
|
||||
async fn set_speed(&self, speed: &str) -> Result<(), ErrorCode> {
|
||||
let state = if speed == "off" {
|
||||
async fn set_fan_speed(&mut self, fan_speed: String) -> Result<(), ErrorCode> {
|
||||
let fan_speed = fan_speed.as_str();
|
||||
let state = if fan_speed == "off" {
|
||||
AirFilterFanState::Off
|
||||
} else if speed == "low" {
|
||||
} else if fan_speed == "low" {
|
||||
AirFilterFanState::Low
|
||||
} else if speed == "medium" {
|
||||
} else if fan_speed == "medium" {
|
||||
AirFilterFanState::Medium
|
||||
} else if speed == "high" {
|
||||
} else if fan_speed == "high" {
|
||||
AirFilterFanState::High
|
||||
} else {
|
||||
return Err(google_home::errors::DeviceError::TransientError.into());
|
||||
|
@ -225,7 +226,7 @@ impl HumiditySetting for AirFilter {
|
|||
Some(true)
|
||||
}
|
||||
|
||||
async fn humidity_ambient_percent(&self) -> isize {
|
||||
self.last_known_state.humidity.round() as isize
|
||||
fn humidity_ambient_percent(&self) -> Result<isize, ErrorCode> {
|
||||
Ok(self.last_known_state.humidity.round() as isize)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ impl OnMqtt for AudioSetup {
|
|||
) {
|
||||
match action {
|
||||
RemoteAction::On => {
|
||||
if mixer.is_on().await.unwrap() {
|
||||
if mixer.on().await.unwrap() {
|
||||
speakers.set_on(false).await.unwrap();
|
||||
mixer.set_on(false).await.unwrap();
|
||||
} else {
|
||||
|
@ -101,9 +101,9 @@ impl OnMqtt for AudioSetup {
|
|||
}
|
||||
},
|
||||
RemoteAction::BrightnessMoveUp => {
|
||||
if !mixer.is_on().await.unwrap() {
|
||||
if !mixer.on().await.unwrap() {
|
||||
mixer.set_on(true).await.unwrap();
|
||||
} else if speakers.is_on().await.unwrap() {
|
||||
} else if speakers.on().await.unwrap() {
|
||||
speakers.set_on(false).await.unwrap();
|
||||
} else {
|
||||
speakers.set_on(true).await.unwrap();
|
||||
|
|
|
@ -155,7 +155,7 @@ impl OnMqtt for ContactSensor {
|
|||
for (light, previous) in &mut trigger.devices {
|
||||
let mut light = light.write().await;
|
||||
if let Some(light) = light.as_mut().cast_mut() as Option<&mut dyn OnOff> {
|
||||
*previous = light.is_on().await.unwrap();
|
||||
*previous = light.on().await.unwrap();
|
||||
light.set_on(true).await.ok();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -152,7 +152,7 @@ impl OnOff for HueGroup {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn is_on(&self) -> Result<bool, ErrorCode> {
|
||||
async fn on(&self) -> Result<bool, ErrorCode> {
|
||||
let res = reqwest::Client::new()
|
||||
.get(self.url_get_state())
|
||||
.send()
|
||||
|
|
|
@ -205,7 +205,7 @@ impl GoogleHomeDevice for IkeaOutlet {
|
|||
|
||||
#[async_trait]
|
||||
impl traits::OnOff for IkeaOutlet {
|
||||
async fn is_on(&self) -> Result<bool, ErrorCode> {
|
||||
async fn on(&self) -> Result<bool, ErrorCode> {
|
||||
Ok(self.last_known_state)
|
||||
}
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ impl Response {
|
|||
|
||||
#[async_trait]
|
||||
impl traits::OnOff for KasaOutlet {
|
||||
async fn is_on(&self) -> Result<bool, errors::ErrorCode> {
|
||||
async fn on(&self) -> Result<bool, errors::ErrorCode> {
|
||||
let mut stream = TcpStream::connect(self.config.addr)
|
||||
.await
|
||||
.or::<DeviceError>(Err(DeviceError::DeviceOffline))?;
|
||||
|
|
|
@ -103,7 +103,7 @@ impl GoogleHomeDevice for WakeOnLAN {
|
|||
|
||||
#[async_trait]
|
||||
impl traits::Scene for WakeOnLAN {
|
||||
async fn set_active(&self, activate: bool) -> Result<(), ErrorCode> {
|
||||
async fn set_active(&mut self, activate: bool) -> Result<(), ErrorCode> {
|
||||
if activate {
|
||||
debug!(
|
||||
id = Device::get_id(self),
|
||||
|
|
Loading…
Reference in New Issue
Block a user