Started working on google home implementation
This commit is contained in:
parent
c9bbc35f74
commit
6627174c6f
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -13,6 +13,7 @@ name = "automation"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dotenv",
|
||||
"google-home",
|
||||
"rumqttc",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -191,6 +192,15 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "google-home"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.4"
|
||||
|
@ -609,6 +619,16 @@ version = "0.7.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
|
|
|
@ -10,3 +10,4 @@ rumqttc = "0.18"
|
|||
serde = { version ="1.0.149", features = ["derive"] }
|
||||
serde_json = "1.0.89"
|
||||
dotenv = "0.15.0"
|
||||
google-home = {path = "./google-home"}
|
||||
|
|
1
google-home/.gitignore
vendored
Normal file
1
google-home/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/target
|
129
google-home/Cargo.lock
generated
Normal file
129
google-home/Cargo.lock
generated
Normal file
|
@ -0,0 +1,129 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "google-home"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.149"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
17
google-home/Cargo.toml
Normal file
17
google-home/Cargo.toml
Normal file
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "google-home"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde = { version ="1.0.149", features = ["derive"] }
|
||||
serde_json = "1.0.89"
|
||||
|
||||
[dependencies.uuid]
|
||||
version = "1.2.2"
|
||||
features = [
|
||||
"v4",
|
||||
"serde",
|
||||
]
|
4
google-home/src/lib.rs
Normal file
4
google-home/src/lib.rs
Normal file
|
@ -0,0 +1,4 @@
|
|||
pub mod request;
|
||||
pub mod response;
|
||||
pub mod types;
|
||||
pub mod traits;
|
43
google-home/src/request.rs
Normal file
43
google-home/src/request.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use serde::Deserialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Deserialize)]
|
||||
#[serde(tag = "intent")]
|
||||
enum Intent {
|
||||
#[serde(rename = "action.devices.SYNC")]
|
||||
Sync,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
struct Request {
|
||||
request_id: Uuid,
|
||||
inputs: Vec<Intent>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn deserialize_sync_request() {
|
||||
|
||||
let json = r#"{
|
||||
"requestId": "ff36a3cc-ec34-11e6-b1a0-64510650abcf",
|
||||
"inputs": [
|
||||
{
|
||||
"intent": "action.devices.SYNC"
|
||||
}
|
||||
]
|
||||
}"#;
|
||||
|
||||
let req: Request = serde_json::from_str(json).unwrap();
|
||||
|
||||
assert_eq!(req.request_id, Uuid::from_str("ff36a3cc-ec34-11e6-b1a0-64510650abcf").unwrap());
|
||||
assert_eq!(req.inputs.len(), 1);
|
||||
assert_eq!(req.inputs[0], Intent::Sync);
|
||||
}
|
||||
}
|
||||
|
44
google-home/src/response.rs
Normal file
44
google-home/src/response.rs
Normal file
|
@ -0,0 +1,44 @@
|
|||
pub mod sync;
|
||||
|
||||
use serde::Serialize;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Response {
|
||||
request_id: Uuid,
|
||||
payload: ResponsePayload,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ResponsePayload {
|
||||
Sync(sync::Payload)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::{response::sync::Device, types::Type, traits::Trait};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialize_sync_response() {
|
||||
let mut sync_resp = sync::Payload::new("Dreaded_X");
|
||||
|
||||
let mut device = Device::new("kitchen/kettle", "Kettle", Type::Kettle);
|
||||
device.traits.push(Trait::OnOff);
|
||||
device.room_hint = "Kitchen".into();
|
||||
sync_resp.add_device(device);
|
||||
|
||||
let resp = Response{ request_id: Uuid::from_str("ff36a3cc-ec34-11e6-b1a0-64510650abcf").unwrap(), payload: ResponsePayload::Sync(sync_resp) };
|
||||
|
||||
println!("{:?}", resp);
|
||||
|
||||
let json = serde_json::to_string(&resp).unwrap();
|
||||
|
||||
println!("{}", json);
|
||||
}
|
||||
}
|
67
google-home/src/response/sync.rs
Normal file
67
google-home/src/response/sync.rs
Normal file
|
@ -0,0 +1,67 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::types::Type;
|
||||
use crate::traits::Trait;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Payload {
|
||||
user_agent_id: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
error_code: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
debug_string: Option<String>,
|
||||
devices: Vec<Device>,
|
||||
}
|
||||
|
||||
impl Payload {
|
||||
pub fn new(user_agent_id: &str) -> Self {
|
||||
Self { user_agent_id: user_agent_id.into(), error_code: None, debug_string: None, devices: Vec::new() }
|
||||
}
|
||||
|
||||
pub fn add_device(&mut self, device: Device) {
|
||||
self.devices.push(device);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Device {
|
||||
pub id: String,
|
||||
#[serde(rename = "type")]
|
||||
pub device_type: Type,
|
||||
pub traits: Vec<Trait>,
|
||||
pub name: DeviceName,
|
||||
pub will_report_state: bool,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub notification_supported_by_agent: Option<bool>,
|
||||
#[serde(skip_serializing_if = "String::is_empty")]
|
||||
pub room_hint: String,
|
||||
}
|
||||
|
||||
impl Device {
|
||||
pub fn new(id: &str, name: &str, device_type: Type) -> Self {
|
||||
Self {
|
||||
id: id.into(),
|
||||
device_type,
|
||||
traits: Vec::new(),
|
||||
name: DeviceName {
|
||||
default_name: Vec::new(),
|
||||
name: name.into(),
|
||||
nicknames: Vec::new() },
|
||||
will_report_state: true,
|
||||
notification_supported_by_agent: None,
|
||||
room_hint: "".into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DeviceName {
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
pub default_name: Vec<String>,
|
||||
pub name: String,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
pub nicknames: Vec<String>,
|
||||
}
|
9
google-home/src/traits.rs
Normal file
9
google-home/src/traits.rs
Normal file
|
@ -0,0 +1,9 @@
|
|||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum Trait {
|
||||
#[serde(rename = "action.devices.traits.OnOff")]
|
||||
OnOff,
|
||||
#[serde(rename = "action.devices.traits.Scene")]
|
||||
Scene,
|
||||
}
|
11
google-home/src/types.rs
Normal file
11
google-home/src/types.rs
Normal file
|
@ -0,0 +1,11 @@
|
|||
use serde::Serialize;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub enum Type {
|
||||
#[serde(rename = "action.devices.types.KETTLE")]
|
||||
Kettle,
|
||||
#[serde(rename = "action.devices.types.OUTLET")]
|
||||
Outlet,
|
||||
#[serde(rename = "action.devices.types.SCENE")]
|
||||
Scene,
|
||||
}
|
Loading…
Reference in New Issue
Block a user